Fix indentation to use tabs in Kotlin source files
Closes gh-33840
This commit is contained in:
		
							parent
							
								
									6bd4687706
								
							
						
					
					
						commit
						0beb56a58c
					
				| 
						 | 
				
			
			@ -56,33 +56,33 @@ import kotlin.annotation.AnnotationTarget.TYPE
 | 
			
		|||
@SpringJUnitConfig(InterceptorConfig::class)
 | 
			
		||||
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
 | 
			
		||||
class AspectJAutoProxyInterceptorKotlinIntegrationTests(
 | 
			
		||||
    @Autowired val echo: Echo,
 | 
			
		||||
    @Autowired val firstAdvisor: TestPointcutAdvisor,
 | 
			
		||||
    @Autowired val secondAdvisor: TestPointcutAdvisor,
 | 
			
		||||
    @Autowired val countingAspect: CountingAspect,
 | 
			
		||||
    @Autowired val reactiveTransactionManager: ReactiveCallCountingTransactionManager) {
 | 
			
		||||
	@Autowired val echo: Echo,
 | 
			
		||||
	@Autowired val firstAdvisor: TestPointcutAdvisor,
 | 
			
		||||
	@Autowired val secondAdvisor: TestPointcutAdvisor,
 | 
			
		||||
	@Autowired val countingAspect: CountingAspect,
 | 
			
		||||
	@Autowired val reactiveTransactionManager: ReactiveCallCountingTransactionManager) {
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `Multiple interceptors with regular function`() {
 | 
			
		||||
        assertThat(firstAdvisor.interceptor.invocations).isEmpty()
 | 
			
		||||
        assertThat(secondAdvisor.interceptor.invocations).isEmpty()
 | 
			
		||||
        val value = "Hello!"
 | 
			
		||||
        assertThat(echo.echo(value)).isEqualTo(value)
 | 
			
		||||
	@Test
 | 
			
		||||
	fun `Multiple interceptors with regular function`() {
 | 
			
		||||
		assertThat(firstAdvisor.interceptor.invocations).isEmpty()
 | 
			
		||||
		assertThat(secondAdvisor.interceptor.invocations).isEmpty()
 | 
			
		||||
		val value = "Hello!"
 | 
			
		||||
		assertThat(echo.echo(value)).isEqualTo(value)
 | 
			
		||||
		assertThat(firstAdvisor.interceptor.invocations).singleElement().matches { String::class.java.isAssignableFrom(it) }
 | 
			
		||||
		assertThat(secondAdvisor.interceptor.invocations).singleElement().matches { String::class.java.isAssignableFrom(it) }
 | 
			
		||||
    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `Multiple interceptors with suspending function`() {
 | 
			
		||||
        assertThat(firstAdvisor.interceptor.invocations).isEmpty()
 | 
			
		||||
        assertThat(secondAdvisor.interceptor.invocations).isEmpty()
 | 
			
		||||
        val value = "Hello!"
 | 
			
		||||
        runBlocking {
 | 
			
		||||
            assertThat(echo.suspendingEcho(value)).isEqualTo(value)
 | 
			
		||||
        }
 | 
			
		||||
	@Test
 | 
			
		||||
	fun `Multiple interceptors with suspending function`() {
 | 
			
		||||
		assertThat(firstAdvisor.interceptor.invocations).isEmpty()
 | 
			
		||||
		assertThat(secondAdvisor.interceptor.invocations).isEmpty()
 | 
			
		||||
		val value = "Hello!"
 | 
			
		||||
		runBlocking {
 | 
			
		||||
			assertThat(echo.suspendingEcho(value)).isEqualTo(value)
 | 
			
		||||
		}
 | 
			
		||||
		assertThat(firstAdvisor.interceptor.invocations).singleElement().matches { Mono::class.java.isAssignableFrom(it) }
 | 
			
		||||
		assertThat(secondAdvisor.interceptor.invocations).singleElement().matches { Mono::class.java.isAssignableFrom(it) }
 | 
			
		||||
    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test // gh-33095
 | 
			
		||||
	fun `Aspect and reactive transactional with suspending function`() {
 | 
			
		||||
| 
						 | 
				
			
			@ -113,17 +113,17 @@ class AspectJAutoProxyInterceptorKotlinIntegrationTests(
 | 
			
		|||
		assertThat(countingAspect.counter).`as`("aspect applied once per key").isEqualTo(2)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Configuration
 | 
			
		||||
    @EnableAspectJAutoProxy
 | 
			
		||||
    @EnableTransactionManagement
 | 
			
		||||
	@Configuration
 | 
			
		||||
	@EnableAspectJAutoProxy
 | 
			
		||||
	@EnableTransactionManagement
 | 
			
		||||
	@EnableCaching
 | 
			
		||||
    open class InterceptorConfig {
 | 
			
		||||
	open class InterceptorConfig {
 | 
			
		||||
 | 
			
		||||
        @Bean
 | 
			
		||||
        open fun firstAdvisor() = TestPointcutAdvisor().apply { order = 0 }
 | 
			
		||||
		@Bean
 | 
			
		||||
		open fun firstAdvisor() = TestPointcutAdvisor().apply { order = 0 }
 | 
			
		||||
 | 
			
		||||
        @Bean
 | 
			
		||||
        open fun secondAdvisor() = TestPointcutAdvisor().apply { order = 1 }
 | 
			
		||||
		@Bean
 | 
			
		||||
		open fun secondAdvisor() = TestPointcutAdvisor().apply { order = 1 }
 | 
			
		||||
 | 
			
		||||
		@Bean
 | 
			
		||||
		open fun countingAspect() = CountingAspect()
 | 
			
		||||
| 
						 | 
				
			
			@ -138,34 +138,34 @@ class AspectJAutoProxyInterceptorKotlinIntegrationTests(
 | 
			
		|||
			return ConcurrentMapCacheManager()
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        @Bean
 | 
			
		||||
        open fun echo(): Echo {
 | 
			
		||||
            return Echo()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
		@Bean
 | 
			
		||||
		open fun echo(): Echo {
 | 
			
		||||
			return Echo()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    class TestMethodInterceptor: MethodInterceptor {
 | 
			
		||||
	class TestMethodInterceptor: MethodInterceptor {
 | 
			
		||||
 | 
			
		||||
        var invocations: MutableList<Class<*>> = mutableListOf()
 | 
			
		||||
		var invocations: MutableList<Class<*>> = mutableListOf()
 | 
			
		||||
 | 
			
		||||
        @Suppress("RedundantNullableReturnType")
 | 
			
		||||
        override fun invoke(invocation: MethodInvocation): Any? {
 | 
			
		||||
            val result = invocation.proceed()
 | 
			
		||||
            invocations.add(result!!.javaClass)
 | 
			
		||||
            return result
 | 
			
		||||
        }
 | 
			
		||||
		@Suppress("RedundantNullableReturnType")
 | 
			
		||||
		override fun invoke(invocation: MethodInvocation): Any? {
 | 
			
		||||
			val result = invocation.proceed()
 | 
			
		||||
			invocations.add(result!!.javaClass)
 | 
			
		||||
			return result
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    class TestPointcutAdvisor : StaticMethodMatcherPointcutAdvisor(TestMethodInterceptor()) {
 | 
			
		||||
	class TestPointcutAdvisor : StaticMethodMatcherPointcutAdvisor(TestMethodInterceptor()) {
 | 
			
		||||
 | 
			
		||||
        val interceptor: TestMethodInterceptor
 | 
			
		||||
            get() = advice as TestMethodInterceptor
 | 
			
		||||
		val interceptor: TestMethodInterceptor
 | 
			
		||||
			get() = advice as TestMethodInterceptor
 | 
			
		||||
 | 
			
		||||
        override fun matches(method: Method, targetClass: Class<*>): Boolean {
 | 
			
		||||
            return targetClass == Echo::class.java && method.name.lowercase().endsWith("echo")
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
		override fun matches(method: Method, targetClass: Class<*>): Boolean {
 | 
			
		||||
			return targetClass == Echo::class.java && method.name.lowercase().endsWith("echo")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Target(CLASS, FUNCTION, ANNOTATION_CLASS, TYPE)
 | 
			
		||||
	@Retention(AnnotationRetention.RUNTIME)
 | 
			
		||||
| 
						 | 
				
			
			@ -185,16 +185,16 @@ class AspectJAutoProxyInterceptorKotlinIntegrationTests(
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    open class Echo {
 | 
			
		||||
	open class Echo {
 | 
			
		||||
 | 
			
		||||
        open fun echo(value: String): String {
 | 
			
		||||
            return value
 | 
			
		||||
        }
 | 
			
		||||
		open fun echo(value: String): String {
 | 
			
		||||
			return value
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        open suspend fun suspendingEcho(value: String): String {
 | 
			
		||||
            delay(1)
 | 
			
		||||
            return value
 | 
			
		||||
        }
 | 
			
		||||
		open suspend fun suspendingEcho(value: String): String {
 | 
			
		||||
			delay(1)
 | 
			
		||||
			return value
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		@Transactional
 | 
			
		||||
		@Counting
 | 
			
		||||
| 
						 | 
				
			
			@ -212,6 +212,6 @@ class AspectJAutoProxyInterceptorKotlinIntegrationTests(
 | 
			
		|||
			return "$value ${cacheCounter++}"
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,17 +31,17 @@ import kotlin.coroutines.Continuation
 | 
			
		|||
 */
 | 
			
		||||
class AopUtilsKotlinTests {
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `Invoking suspending function should return Mono`() {
 | 
			
		||||
        val value = "foo"
 | 
			
		||||
        val method = ReflectionUtils.findMethod(WithoutInterface::class.java, "handle",
 | 
			
		||||
	@Test
 | 
			
		||||
	fun `Invoking suspending function should return Mono`() {
 | 
			
		||||
		val value = "foo"
 | 
			
		||||
		val method = ReflectionUtils.findMethod(WithoutInterface::class.java, "handle",
 | 
			
		||||
			String::class. java, Continuation::class.java)!!
 | 
			
		||||
        val continuation = Continuation<Any>(CoroutineName("test")) { }
 | 
			
		||||
		val continuation = Continuation<Any>(CoroutineName("test")) { }
 | 
			
		||||
		val result = AopUtils.invokeJoinpointUsingReflection(WithoutInterface(), method, arrayOf(value, continuation))
 | 
			
		||||
        assertThat(result).isInstanceOfSatisfying(Mono::class.java) {
 | 
			
		||||
            assertThat(it.block()).isEqualTo(value)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
		assertThat(result).isInstanceOfSatisfying(Mono::class.java) {
 | 
			
		||||
			assertThat(it.block()).isEqualTo(value)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	fun `Invoking suspending function on bridged method should return Mono`() {
 | 
			
		||||
| 
						 | 
				
			
			@ -54,11 +54,11 @@ class AopUtilsKotlinTests {
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Suppress("unused")
 | 
			
		||||
    suspend fun suspendingFunction(value: String): String {
 | 
			
		||||
        delay(1)
 | 
			
		||||
        return value
 | 
			
		||||
    }
 | 
			
		||||
	@Suppress("unused")
 | 
			
		||||
	suspend fun suspendingFunction(value: String): String {
 | 
			
		||||
		delay(1)
 | 
			
		||||
		return value
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	class WithoutInterface {
 | 
			
		||||
		suspend fun handle(value: String): String {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,99 +45,99 @@ import javax.lang.model.element.Modifier
 | 
			
		|||
 */
 | 
			
		||||
class InstanceSupplierCodeGeneratorKotlinTests {
 | 
			
		||||
 | 
			
		||||
    private val generationContext = TestGenerationContext()
 | 
			
		||||
	private val generationContext = TestGenerationContext()
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun generateWhenHasDefaultConstructor() {
 | 
			
		||||
        val beanDefinition: BeanDefinition = RootBeanDefinition(KotlinTestBean::class.java)
 | 
			
		||||
        val beanFactory = DefaultListableBeanFactory()
 | 
			
		||||
        compile(beanFactory, beanDefinition) { instanceSupplier, compiled ->
 | 
			
		||||
            val bean = getBean<KotlinTestBean>(beanFactory, beanDefinition, instanceSupplier)
 | 
			
		||||
            Assertions.assertThat(bean).isInstanceOf(KotlinTestBean::class.java)
 | 
			
		||||
            Assertions.assertThat(compiled.sourceFile).contains("InstanceSupplier.using(KotlinTestBean::new)")
 | 
			
		||||
        }
 | 
			
		||||
        Assertions.assertThat(getReflectionHints().getTypeHint(KotlinTestBean::class.java))
 | 
			
		||||
            .satisfies(hasConstructorWithMode(ExecutableMode.INTROSPECT))
 | 
			
		||||
    }
 | 
			
		||||
	@Test
 | 
			
		||||
	fun generateWhenHasDefaultConstructor() {
 | 
			
		||||
		val beanDefinition: BeanDefinition = RootBeanDefinition(KotlinTestBean::class.java)
 | 
			
		||||
		val beanFactory = DefaultListableBeanFactory()
 | 
			
		||||
		compile(beanFactory, beanDefinition) { instanceSupplier, compiled ->
 | 
			
		||||
			val bean = getBean<KotlinTestBean>(beanFactory, beanDefinition, instanceSupplier)
 | 
			
		||||
			Assertions.assertThat(bean).isInstanceOf(KotlinTestBean::class.java)
 | 
			
		||||
			Assertions.assertThat(compiled.sourceFile).contains("InstanceSupplier.using(KotlinTestBean::new)")
 | 
			
		||||
		}
 | 
			
		||||
		Assertions.assertThat(getReflectionHints().getTypeHint(KotlinTestBean::class.java))
 | 
			
		||||
			.satisfies(hasConstructorWithMode(ExecutableMode.INTROSPECT))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun generateWhenConstructorHasOptionalParameter() {
 | 
			
		||||
        val beanDefinition: BeanDefinition = RootBeanDefinition(KotlinTestBeanWithOptionalParameter::class.java)
 | 
			
		||||
        val beanFactory = DefaultListableBeanFactory()
 | 
			
		||||
        compile(beanFactory, beanDefinition) { instanceSupplier, compiled ->
 | 
			
		||||
                val bean: KotlinTestBeanWithOptionalParameter = getBean(beanFactory, beanDefinition, instanceSupplier)
 | 
			
		||||
                Assertions.assertThat(bean).isInstanceOf(KotlinTestBeanWithOptionalParameter::class.java)
 | 
			
		||||
                Assertions.assertThat(compiled.sourceFile)
 | 
			
		||||
                    .contains("return BeanInstanceSupplier.<KotlinTestBeanWithOptionalParameter>forConstructor();")
 | 
			
		||||
            }
 | 
			
		||||
        Assertions.assertThat<TypeHint>(getReflectionHints().getTypeHint(KotlinTestBeanWithOptionalParameter::class.java))
 | 
			
		||||
            .satisfies(hasMemberCategory(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS))
 | 
			
		||||
    }
 | 
			
		||||
	@Test
 | 
			
		||||
	fun generateWhenConstructorHasOptionalParameter() {
 | 
			
		||||
		val beanDefinition: BeanDefinition = RootBeanDefinition(KotlinTestBeanWithOptionalParameter::class.java)
 | 
			
		||||
		val beanFactory = DefaultListableBeanFactory()
 | 
			
		||||
		compile(beanFactory, beanDefinition) { instanceSupplier, compiled ->
 | 
			
		||||
				val bean: KotlinTestBeanWithOptionalParameter = getBean(beanFactory, beanDefinition, instanceSupplier)
 | 
			
		||||
				Assertions.assertThat(bean).isInstanceOf(KotlinTestBeanWithOptionalParameter::class.java)
 | 
			
		||||
				Assertions.assertThat(compiled.sourceFile)
 | 
			
		||||
					.contains("return BeanInstanceSupplier.<KotlinTestBeanWithOptionalParameter>forConstructor();")
 | 
			
		||||
			}
 | 
			
		||||
		Assertions.assertThat<TypeHint>(getReflectionHints().getTypeHint(KotlinTestBeanWithOptionalParameter::class.java))
 | 
			
		||||
			.satisfies(hasMemberCategory(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private fun getReflectionHints(): ReflectionHints {
 | 
			
		||||
        return generationContext.runtimeHints.reflection()
 | 
			
		||||
    }
 | 
			
		||||
	private fun getReflectionHints(): ReflectionHints {
 | 
			
		||||
		return generationContext.runtimeHints.reflection()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private fun hasConstructorWithMode(mode: ExecutableMode): ThrowingConsumer<TypeHint> {
 | 
			
		||||
        return ThrowingConsumer {
 | 
			
		||||
            Assertions.assertThat(it.constructors()).anySatisfy(hasMode(mode))
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
	private fun hasConstructorWithMode(mode: ExecutableMode): ThrowingConsumer<TypeHint> {
 | 
			
		||||
		return ThrowingConsumer {
 | 
			
		||||
			Assertions.assertThat(it.constructors()).anySatisfy(hasMode(mode))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private fun hasMemberCategory(category: MemberCategory): ThrowingConsumer<TypeHint> {
 | 
			
		||||
        return ThrowingConsumer {
 | 
			
		||||
            Assertions.assertThat(it.memberCategories).contains(category)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
	private fun hasMemberCategory(category: MemberCategory): ThrowingConsumer<TypeHint> {
 | 
			
		||||
		return ThrowingConsumer {
 | 
			
		||||
			Assertions.assertThat(it.memberCategories).contains(category)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private fun hasMode(mode: ExecutableMode): ThrowingConsumer<ExecutableHint> {
 | 
			
		||||
        return ThrowingConsumer {
 | 
			
		||||
            Assertions.assertThat(it.mode).isEqualTo(mode)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
	private fun hasMode(mode: ExecutableMode): ThrowingConsumer<ExecutableHint> {
 | 
			
		||||
		return ThrowingConsumer {
 | 
			
		||||
			Assertions.assertThat(it.mode).isEqualTo(mode)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Suppress("UNCHECKED_CAST")
 | 
			
		||||
    private fun <T> getBean(beanFactory: DefaultListableBeanFactory, beanDefinition: BeanDefinition,
 | 
			
		||||
                            instanceSupplier: InstanceSupplier<*>): T {
 | 
			
		||||
        (beanDefinition as RootBeanDefinition).instanceSupplier = instanceSupplier
 | 
			
		||||
        beanFactory.registerBeanDefinition("testBean", beanDefinition)
 | 
			
		||||
        return beanFactory.getBean("testBean") as T
 | 
			
		||||
    }
 | 
			
		||||
	@Suppress("UNCHECKED_CAST")
 | 
			
		||||
	private fun <T> getBean(beanFactory: DefaultListableBeanFactory, beanDefinition: BeanDefinition,
 | 
			
		||||
							instanceSupplier: InstanceSupplier<*>): T {
 | 
			
		||||
		(beanDefinition as RootBeanDefinition).instanceSupplier = instanceSupplier
 | 
			
		||||
		beanFactory.registerBeanDefinition("testBean", beanDefinition)
 | 
			
		||||
		return beanFactory.getBean("testBean") as T
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private fun compile(beanFactory: DefaultListableBeanFactory, beanDefinition: BeanDefinition,
 | 
			
		||||
                        result: BiConsumer<InstanceSupplier<*>, Compiled>) {
 | 
			
		||||
	private fun compile(beanFactory: DefaultListableBeanFactory, beanDefinition: BeanDefinition,
 | 
			
		||||
						result: BiConsumer<InstanceSupplier<*>, Compiled>) {
 | 
			
		||||
 | 
			
		||||
        val freshBeanFactory = DefaultListableBeanFactory(beanFactory)
 | 
			
		||||
        freshBeanFactory.registerBeanDefinition("testBean", beanDefinition)
 | 
			
		||||
        val registeredBean = RegisteredBean.of(freshBeanFactory, "testBean")
 | 
			
		||||
        val typeBuilder = DeferredTypeBuilder()
 | 
			
		||||
        val generateClass = generationContext.generatedClasses.addForFeature("TestCode", typeBuilder)
 | 
			
		||||
        val generator = InstanceSupplierCodeGenerator(
 | 
			
		||||
            generationContext, generateClass.name,
 | 
			
		||||
            generateClass.methods, false
 | 
			
		||||
        )
 | 
			
		||||
        val instantiationDescriptor = registeredBean.resolveInstantiationDescriptor()
 | 
			
		||||
        Assertions.assertThat(instantiationDescriptor).isNotNull()
 | 
			
		||||
        val generatedCode = generator.generateCode(registeredBean, instantiationDescriptor)
 | 
			
		||||
        typeBuilder.set { type: TypeSpec.Builder ->
 | 
			
		||||
            type.addModifiers(Modifier.PUBLIC)
 | 
			
		||||
            type.addSuperinterface(
 | 
			
		||||
                ParameterizedTypeName.get(
 | 
			
		||||
                    Supplier::class.java,
 | 
			
		||||
                    InstanceSupplier::class.java
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
            type.addMethod(
 | 
			
		||||
                MethodSpec.methodBuilder("get")
 | 
			
		||||
                    .addModifiers(Modifier.PUBLIC)
 | 
			
		||||
                    .returns(InstanceSupplier::class.java)
 | 
			
		||||
                    .addStatement("return \$L", generatedCode).build()
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
        generationContext.writeGeneratedContent()
 | 
			
		||||
        TestCompiler.forSystem().with(generationContext).compile {
 | 
			
		||||
            result.accept(it.getInstance(Supplier::class.java).get() as InstanceSupplier<*>, it)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
		val freshBeanFactory = DefaultListableBeanFactory(beanFactory)
 | 
			
		||||
		freshBeanFactory.registerBeanDefinition("testBean", beanDefinition)
 | 
			
		||||
		val registeredBean = RegisteredBean.of(freshBeanFactory, "testBean")
 | 
			
		||||
		val typeBuilder = DeferredTypeBuilder()
 | 
			
		||||
		val generateClass = generationContext.generatedClasses.addForFeature("TestCode", typeBuilder)
 | 
			
		||||
		val generator = InstanceSupplierCodeGenerator(
 | 
			
		||||
			generationContext, generateClass.name,
 | 
			
		||||
			generateClass.methods, false
 | 
			
		||||
		)
 | 
			
		||||
		val instantiationDescriptor = registeredBean.resolveInstantiationDescriptor()
 | 
			
		||||
		Assertions.assertThat(instantiationDescriptor).isNotNull()
 | 
			
		||||
		val generatedCode = generator.generateCode(registeredBean, instantiationDescriptor)
 | 
			
		||||
		typeBuilder.set { type: TypeSpec.Builder ->
 | 
			
		||||
			type.addModifiers(Modifier.PUBLIC)
 | 
			
		||||
			type.addSuperinterface(
 | 
			
		||||
				ParameterizedTypeName.get(
 | 
			
		||||
					Supplier::class.java,
 | 
			
		||||
					InstanceSupplier::class.java
 | 
			
		||||
				)
 | 
			
		||||
			)
 | 
			
		||||
			type.addMethod(
 | 
			
		||||
				MethodSpec.methodBuilder("get")
 | 
			
		||||
					.addModifiers(Modifier.PUBLIC)
 | 
			
		||||
					.returns(InstanceSupplier::class.java)
 | 
			
		||||
					.addStatement("return \$L", generatedCode).build()
 | 
			
		||||
			)
 | 
			
		||||
		}
 | 
			
		||||
		generationContext.writeGeneratedContent()
 | 
			
		||||
		TestCompiler.forSystem().with(generationContext).compile {
 | 
			
		||||
			result.accept(it.getInstance(Supplier::class.java).get() as InstanceSupplier<*>, it)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,45 +36,45 @@ import org.springframework.validation.beanvalidation.BeanValidationBeanRegistrat
 | 
			
		|||
 */
 | 
			
		||||
class BeanValidationBeanRegistrationAotProcessorKotlinTests {
 | 
			
		||||
 | 
			
		||||
    private val processor = BeanValidationBeanRegistrationAotProcessor()
 | 
			
		||||
	private val processor = BeanValidationBeanRegistrationAotProcessor()
 | 
			
		||||
 | 
			
		||||
    private val generationContext: GenerationContext = TestGenerationContext()
 | 
			
		||||
	private val generationContext: GenerationContext = TestGenerationContext()
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun shouldProcessMethodParameterLevelConstraint() {
 | 
			
		||||
        process(MethodParameterLevelConstraint::class.java)
 | 
			
		||||
        Assertions.assertThat(
 | 
			
		||||
            RuntimeHintsPredicates.reflection().onType(ExistsValidator::class.java)
 | 
			
		||||
                .withMemberCategory(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)
 | 
			
		||||
        ).accepts(generationContext.runtimeHints)
 | 
			
		||||
    }
 | 
			
		||||
	@Test
 | 
			
		||||
	fun shouldProcessMethodParameterLevelConstraint() {
 | 
			
		||||
		process(MethodParameterLevelConstraint::class.java)
 | 
			
		||||
		Assertions.assertThat(
 | 
			
		||||
			RuntimeHintsPredicates.reflection().onType(ExistsValidator::class.java)
 | 
			
		||||
				.withMemberCategory(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)
 | 
			
		||||
		).accepts(generationContext.runtimeHints)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun shouldSkipMethodParameterLevelConstraintWihExtension() {
 | 
			
		||||
        process(MethodParameterLevelConstraintWithExtension::class.java)
 | 
			
		||||
        Assertions.assertThat(generationContext.runtimeHints.reflection().typeHints()).isEmpty()
 | 
			
		||||
    }
 | 
			
		||||
	@Test
 | 
			
		||||
	fun shouldSkipMethodParameterLevelConstraintWihExtension() {
 | 
			
		||||
		process(MethodParameterLevelConstraintWithExtension::class.java)
 | 
			
		||||
		Assertions.assertThat(generationContext.runtimeHints.reflection().typeHints()).isEmpty()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private fun process(beanClass: Class<*>) {
 | 
			
		||||
        val contribution = createContribution(beanClass)
 | 
			
		||||
        contribution?.applyTo(generationContext, Mockito.mock())
 | 
			
		||||
    }
 | 
			
		||||
	private fun process(beanClass: Class<*>) {
 | 
			
		||||
		val contribution = createContribution(beanClass)
 | 
			
		||||
		contribution?.applyTo(generationContext, Mockito.mock())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private fun createContribution(beanClass: Class<*>): BeanRegistrationAotContribution? {
 | 
			
		||||
        val beanFactory = DefaultListableBeanFactory()
 | 
			
		||||
        beanFactory.registerBeanDefinition(beanClass.name, RootBeanDefinition(beanClass))
 | 
			
		||||
        return processor.processAheadOfTime(RegisteredBean.of(beanFactory, beanClass.name))
 | 
			
		||||
    }
 | 
			
		||||
	private fun createContribution(beanClass: Class<*>): BeanRegistrationAotContribution? {
 | 
			
		||||
		val beanFactory = DefaultListableBeanFactory()
 | 
			
		||||
		beanFactory.registerBeanDefinition(beanClass.name, RootBeanDefinition(beanClass))
 | 
			
		||||
		return processor.processAheadOfTime(RegisteredBean.of(beanFactory, beanClass.name))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    internal class MethodParameterLevelConstraintWithExtension {
 | 
			
		||||
	internal class MethodParameterLevelConstraintWithExtension {
 | 
			
		||||
 | 
			
		||||
        @Suppress("unused")
 | 
			
		||||
        fun hello(name: @Exists String): String {
 | 
			
		||||
            return name.toHello()
 | 
			
		||||
        }
 | 
			
		||||
		@Suppress("unused")
 | 
			
		||||
		fun hello(name: @Exists String): String {
 | 
			
		||||
			return name.toHello()
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        private fun String.toHello() =
 | 
			
		||||
            "Hello $this"
 | 
			
		||||
    }
 | 
			
		||||
		private fun String.toHello() =
 | 
			
		||||
			"Hello $this"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,4 +22,4 @@ package org.springframework.core
 | 
			
		|||
 * @author Sebastien Deleuze
 | 
			
		||||
 */
 | 
			
		||||
class KotlinReflectionParameterNameDiscovererTests :
 | 
			
		||||
    AbstractReflectionParameterNameDiscovererKotlinTests(KotlinReflectionParameterNameDiscoverer())
 | 
			
		||||
	AbstractReflectionParameterNameDiscovererKotlinTests(KotlinReflectionParameterNameDiscoverer())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,142 +51,142 @@ class SimpAnnotationMethodMessageHandlerKotlinTests {
 | 
			
		|||
 | 
			
		||||
	lateinit var testController: TestController
 | 
			
		||||
 | 
			
		||||
    val channel = mockk<SubscribableChannel>(relaxed = true)
 | 
			
		||||
	val channel = mockk<SubscribableChannel>(relaxed = true)
 | 
			
		||||
 | 
			
		||||
    val converter = mockk<MessageConverter>(relaxed = true)
 | 
			
		||||
	val converter = mockk<MessageConverter>(relaxed = true)
 | 
			
		||||
 | 
			
		||||
    @BeforeEach
 | 
			
		||||
    fun setup() {
 | 
			
		||||
        val brokerTemplate = SimpMessagingTemplate(channel)
 | 
			
		||||
        brokerTemplate.messageConverter = converter
 | 
			
		||||
        messageHandler = TestSimpAnnotationMethodMessageHandler(brokerTemplate, channel, channel)
 | 
			
		||||
        messageHandler.applicationContext = StaticApplicationContext()
 | 
			
		||||
        messageHandler.afterPropertiesSet()
 | 
			
		||||
        testController = TestController()
 | 
			
		||||
    }
 | 
			
		||||
	@BeforeEach
 | 
			
		||||
	fun setup() {
 | 
			
		||||
		val brokerTemplate = SimpMessagingTemplate(channel)
 | 
			
		||||
		brokerTemplate.messageConverter = converter
 | 
			
		||||
		messageHandler = TestSimpAnnotationMethodMessageHandler(brokerTemplate, channel, channel)
 | 
			
		||||
		messageHandler.applicationContext = StaticApplicationContext()
 | 
			
		||||
		messageHandler.afterPropertiesSet()
 | 
			
		||||
		testController = TestController()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun nullableHeaderWithHeader() {
 | 
			
		||||
        val message = createMessage("/nullableHeader", Collections.singletonMap("foo", "bar"))
 | 
			
		||||
        messageHandler.registerHandler(testController)
 | 
			
		||||
        messageHandler.handleMessage(message)
 | 
			
		||||
        assertThat(testController.exception).isNull()
 | 
			
		||||
	@Test
 | 
			
		||||
	fun nullableHeaderWithHeader() {
 | 
			
		||||
		val message = createMessage("/nullableHeader", Collections.singletonMap("foo", "bar"))
 | 
			
		||||
		messageHandler.registerHandler(testController)
 | 
			
		||||
		messageHandler.handleMessage(message)
 | 
			
		||||
		assertThat(testController.exception).isNull()
 | 
			
		||||
		assertThat(testController.header).isEqualTo("bar")
 | 
			
		||||
    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun nullableHeaderWithoutHeader() {
 | 
			
		||||
        val message = createMessage("/nullableHeader", Collections.emptyMap())
 | 
			
		||||
        messageHandler.registerHandler(testController)
 | 
			
		||||
        messageHandler.handleMessage(message)
 | 
			
		||||
	@Test
 | 
			
		||||
	fun nullableHeaderWithoutHeader() {
 | 
			
		||||
		val message = createMessage("/nullableHeader", Collections.emptyMap())
 | 
			
		||||
		messageHandler.registerHandler(testController)
 | 
			
		||||
		messageHandler.handleMessage(message)
 | 
			
		||||
		assertThat(testController.exception).isNull()
 | 
			
		||||
		assertThat(testController.header).isNull()
 | 
			
		||||
    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun nonNullableHeaderWithHeader() {
 | 
			
		||||
        val message = createMessage("/nonNullableHeader", Collections.singletonMap("foo", "bar"))
 | 
			
		||||
        messageHandler.registerHandler(testController)
 | 
			
		||||
        messageHandler.handleMessage(message)
 | 
			
		||||
	@Test
 | 
			
		||||
	fun nonNullableHeaderWithHeader() {
 | 
			
		||||
		val message = createMessage("/nonNullableHeader", Collections.singletonMap("foo", "bar"))
 | 
			
		||||
		messageHandler.registerHandler(testController)
 | 
			
		||||
		messageHandler.handleMessage(message)
 | 
			
		||||
		assertThat(testController.header).isEqualTo("bar")
 | 
			
		||||
    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun nonNullableHeaderWithoutHeader() {
 | 
			
		||||
        val message = createMessage("/nonNullableHeader", Collections.emptyMap())
 | 
			
		||||
        messageHandler.registerHandler(testController)
 | 
			
		||||
        messageHandler.handleMessage(message)
 | 
			
		||||
        assertThat(testController.exception).isNotNull()
 | 
			
		||||
        assertThat(testController.exception).isInstanceOf(MessageHandlingException::class.java)
 | 
			
		||||
    }
 | 
			
		||||
	@Test
 | 
			
		||||
	fun nonNullableHeaderWithoutHeader() {
 | 
			
		||||
		val message = createMessage("/nonNullableHeader", Collections.emptyMap())
 | 
			
		||||
		messageHandler.registerHandler(testController)
 | 
			
		||||
		messageHandler.handleMessage(message)
 | 
			
		||||
		assertThat(testController.exception).isNotNull()
 | 
			
		||||
		assertThat(testController.exception).isInstanceOf(MessageHandlingException::class.java)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun nullableHeaderNotRequiredWithHeader() {
 | 
			
		||||
        val message = createMessage("/nullableHeaderNotRequired", Collections.singletonMap("foo", "bar"))
 | 
			
		||||
        messageHandler.registerHandler(testController)
 | 
			
		||||
        messageHandler.handleMessage(message)
 | 
			
		||||
	@Test
 | 
			
		||||
	fun nullableHeaderNotRequiredWithHeader() {
 | 
			
		||||
		val message = createMessage("/nullableHeaderNotRequired", Collections.singletonMap("foo", "bar"))
 | 
			
		||||
		messageHandler.registerHandler(testController)
 | 
			
		||||
		messageHandler.handleMessage(message)
 | 
			
		||||
		assertThat(testController.exception).isNull()
 | 
			
		||||
		assertThat(testController.header).isEqualTo("bar")
 | 
			
		||||
    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun nullableHeaderNotRequiredWithoutHeader() {
 | 
			
		||||
        val message = createMessage("/nullableHeaderNotRequired", Collections.emptyMap())
 | 
			
		||||
        messageHandler.registerHandler(testController)
 | 
			
		||||
        messageHandler.handleMessage(message)
 | 
			
		||||
	@Test
 | 
			
		||||
	fun nullableHeaderNotRequiredWithoutHeader() {
 | 
			
		||||
		val message = createMessage("/nullableHeaderNotRequired", Collections.emptyMap())
 | 
			
		||||
		messageHandler.registerHandler(testController)
 | 
			
		||||
		messageHandler.handleMessage(message)
 | 
			
		||||
		assertThat(testController.exception).isNull()
 | 
			
		||||
		assertThat(testController.header).isNull()
 | 
			
		||||
    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun nonNullableHeaderNotRequiredWithHeader() {
 | 
			
		||||
        val message = createMessage("/nonNullableHeaderNotRequired", Collections.singletonMap("foo", "bar"))
 | 
			
		||||
        messageHandler.registerHandler(testController)
 | 
			
		||||
        messageHandler.handleMessage(message)
 | 
			
		||||
	@Test
 | 
			
		||||
	fun nonNullableHeaderNotRequiredWithHeader() {
 | 
			
		||||
		val message = createMessage("/nonNullableHeaderNotRequired", Collections.singletonMap("foo", "bar"))
 | 
			
		||||
		messageHandler.registerHandler(testController)
 | 
			
		||||
		messageHandler.handleMessage(message)
 | 
			
		||||
		assertThat(testController.header).isEqualTo("bar")
 | 
			
		||||
    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun nonNullableHeaderNotRequiredWithoutHeader() {
 | 
			
		||||
        val message = createMessage("/nonNullableHeaderNotRequired", Collections.emptyMap())
 | 
			
		||||
        messageHandler.registerHandler(testController)
 | 
			
		||||
        messageHandler.handleMessage(message)
 | 
			
		||||
        assertThat(testController.exception).isNotNull()
 | 
			
		||||
	@Test
 | 
			
		||||
	fun nonNullableHeaderNotRequiredWithoutHeader() {
 | 
			
		||||
		val message = createMessage("/nonNullableHeaderNotRequired", Collections.emptyMap())
 | 
			
		||||
		messageHandler.registerHandler(testController)
 | 
			
		||||
		messageHandler.handleMessage(message)
 | 
			
		||||
		assertThat(testController.exception).isNotNull()
 | 
			
		||||
		assertThat(testController.exception).isInstanceOf(NullPointerException::class.java)
 | 
			
		||||
    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private fun createMessage(destination: String, headers: Map<String, String?>): Message<ByteArray> {
 | 
			
		||||
        val accessor = SimpMessageHeaderAccessor.create()
 | 
			
		||||
        accessor.sessionId = "session1"
 | 
			
		||||
        accessor.sessionAttributes = HashMap()
 | 
			
		||||
        accessor.destination = destination
 | 
			
		||||
        for (entry in headers.entries) accessor.setHeader(entry.key, entry.value)
 | 
			
		||||
	private fun createMessage(destination: String, headers: Map<String, String?>): Message<ByteArray> {
 | 
			
		||||
		val accessor = SimpMessageHeaderAccessor.create()
 | 
			
		||||
		accessor.sessionId = "session1"
 | 
			
		||||
		accessor.sessionAttributes = HashMap()
 | 
			
		||||
		accessor.destination = destination
 | 
			
		||||
		for (entry in headers.entries) accessor.setHeader(entry.key, entry.value)
 | 
			
		||||
 | 
			
		||||
        return MessageBuilder.withPayload(ByteArray(0)).setHeaders(accessor).build()
 | 
			
		||||
    }
 | 
			
		||||
		return MessageBuilder.withPayload(ByteArray(0)).setHeaders(accessor).build()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    class TestSimpAnnotationMethodMessageHandler(brokerTemplate: SimpMessageSendingOperations,
 | 
			
		||||
                                                         clientInboundChannel: SubscribableChannel,
 | 
			
		||||
                                                         clientOutboundChannel: MessageChannel) :
 | 
			
		||||
            SimpAnnotationMethodMessageHandler(clientInboundChannel, clientOutboundChannel, brokerTemplate) {
 | 
			
		||||
	class TestSimpAnnotationMethodMessageHandler(brokerTemplate: SimpMessageSendingOperations,
 | 
			
		||||
														 clientInboundChannel: SubscribableChannel,
 | 
			
		||||
														 clientOutboundChannel: MessageChannel) :
 | 
			
		||||
			SimpAnnotationMethodMessageHandler(clientInboundChannel, clientOutboundChannel, brokerTemplate) {
 | 
			
		||||
 | 
			
		||||
        fun registerHandler(handler: Any) {
 | 
			
		||||
            super.detectHandlerMethods(handler)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
		fun registerHandler(handler: Any) {
 | 
			
		||||
			super.detectHandlerMethods(handler)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Suppress("unused")
 | 
			
		||||
    @Controller
 | 
			
		||||
    @MessageMapping
 | 
			
		||||
    class TestController {
 | 
			
		||||
	@Suppress("unused")
 | 
			
		||||
	@Controller
 | 
			
		||||
	@MessageMapping
 | 
			
		||||
	class TestController {
 | 
			
		||||
 | 
			
		||||
        var header: String? = null
 | 
			
		||||
        var exception: Throwable? = null
 | 
			
		||||
		var header: String? = null
 | 
			
		||||
		var exception: Throwable? = null
 | 
			
		||||
 | 
			
		||||
        @MessageMapping("/nullableHeader")
 | 
			
		||||
        fun nullableHeader(@Header("foo") foo: String?) {
 | 
			
		||||
            header = foo
 | 
			
		||||
        }
 | 
			
		||||
		@MessageMapping("/nullableHeader")
 | 
			
		||||
		fun nullableHeader(@Header("foo") foo: String?) {
 | 
			
		||||
			header = foo
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        @MessageMapping("/nonNullableHeader")
 | 
			
		||||
        fun nonNullableHeader(@Header("foo") foo: String) {
 | 
			
		||||
            header = foo
 | 
			
		||||
        }
 | 
			
		||||
		@MessageMapping("/nonNullableHeader")
 | 
			
		||||
		fun nonNullableHeader(@Header("foo") foo: String) {
 | 
			
		||||
			header = foo
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        @MessageMapping("/nullableHeaderNotRequired")
 | 
			
		||||
        fun nullableHeaderNotRequired(@Header("foo", required = false) foo: String?) {
 | 
			
		||||
            header = foo
 | 
			
		||||
        }
 | 
			
		||||
		@MessageMapping("/nullableHeaderNotRequired")
 | 
			
		||||
		fun nullableHeaderNotRequired(@Header("foo", required = false) foo: String?) {
 | 
			
		||||
			header = foo
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        @MessageMapping("/nonNullableHeaderNotRequired")
 | 
			
		||||
        fun nonNullableHeaderNotRequired(@Header("foo", required = false) foo: String) {
 | 
			
		||||
            header = foo
 | 
			
		||||
        }
 | 
			
		||||
		@MessageMapping("/nonNullableHeaderNotRequired")
 | 
			
		||||
		fun nonNullableHeaderNotRequired(@Header("foo", required = false) foo: String) {
 | 
			
		||||
			header = foo
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        @MessageExceptionHandler
 | 
			
		||||
        fun handleIllegalArgumentException(exception: Throwable) {
 | 
			
		||||
            this.exception = exception
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
		@MessageExceptionHandler
 | 
			
		||||
		fun handleIllegalArgumentException(exception: Throwable) {
 | 
			
		||||
			this.exception = exception
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,4 +66,4 @@ suspend fun ServerWebExchange.awaitSession(): WebSession =
 | 
			
		|||
 * @since 6.1
 | 
			
		||||
 */
 | 
			
		||||
fun ServerWebExchange.Builder.principal(supplier: suspend () -> Principal): ServerWebExchange.Builder
 | 
			
		||||
        = principal(mono(Dispatchers.Unconfined) { supplier.invoke() })
 | 
			
		||||
		= principal(mono(Dispatchers.Unconfined) { supplier.invoke() })
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,139 +49,139 @@ import java.util.*
 | 
			
		|||
 */
 | 
			
		||||
class KotlinRestTemplateHttpServiceProxyTests {
 | 
			
		||||
 | 
			
		||||
    private lateinit var server: MockWebServer
 | 
			
		||||
	private lateinit var server: MockWebServer
 | 
			
		||||
 | 
			
		||||
    private lateinit var testService: TestService
 | 
			
		||||
	private lateinit var testService: TestService
 | 
			
		||||
 | 
			
		||||
	private lateinit var anotherServer: MockWebServer
 | 
			
		||||
 | 
			
		||||
    @BeforeEach
 | 
			
		||||
    fun setUp() {
 | 
			
		||||
        server = MockWebServer()
 | 
			
		||||
        prepareResponse()
 | 
			
		||||
	@BeforeEach
 | 
			
		||||
	fun setUp() {
 | 
			
		||||
		server = MockWebServer()
 | 
			
		||||
		prepareResponse()
 | 
			
		||||
		anotherServer = anotherServer()
 | 
			
		||||
        testService = initTestService()
 | 
			
		||||
    }
 | 
			
		||||
		testService = initTestService()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private fun initTestService(): TestService {
 | 
			
		||||
        val restTemplate = RestTemplate()
 | 
			
		||||
        restTemplate.uriTemplateHandler = DefaultUriBuilderFactory(server.url("/").toString())
 | 
			
		||||
        return HttpServiceProxyFactory.builder()
 | 
			
		||||
                .exchangeAdapter(RestTemplateAdapter.create(restTemplate))
 | 
			
		||||
                .build()
 | 
			
		||||
                .createClient(TestService::class.java)
 | 
			
		||||
    }
 | 
			
		||||
	private fun initTestService(): TestService {
 | 
			
		||||
		val restTemplate = RestTemplate()
 | 
			
		||||
		restTemplate.uriTemplateHandler = DefaultUriBuilderFactory(server.url("/").toString())
 | 
			
		||||
		return HttpServiceProxyFactory.builder()
 | 
			
		||||
				.exchangeAdapter(RestTemplateAdapter.create(restTemplate))
 | 
			
		||||
				.build()
 | 
			
		||||
				.createClient(TestService::class.java)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @AfterEach
 | 
			
		||||
    fun shutDown() {
 | 
			
		||||
        server.shutdown()
 | 
			
		||||
	@AfterEach
 | 
			
		||||
	fun shutDown() {
 | 
			
		||||
		server.shutdown()
 | 
			
		||||
		anotherServer.shutdown()
 | 
			
		||||
    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    @Throws(InterruptedException::class)
 | 
			
		||||
    fun getRequest() {
 | 
			
		||||
        val response = testService.request
 | 
			
		||||
	@Test
 | 
			
		||||
	@Throws(InterruptedException::class)
 | 
			
		||||
	fun getRequest() {
 | 
			
		||||
		val response = testService.request
 | 
			
		||||
 | 
			
		||||
        val request = server.takeRequest()
 | 
			
		||||
        assertThat(response).isEqualTo("Hello Spring!")
 | 
			
		||||
        assertThat(request.method).isEqualTo("GET")
 | 
			
		||||
        assertThat(request.path).isEqualTo("/test")
 | 
			
		||||
    }
 | 
			
		||||
		val request = server.takeRequest()
 | 
			
		||||
		assertThat(response).isEqualTo("Hello Spring!")
 | 
			
		||||
		assertThat(request.method).isEqualTo("GET")
 | 
			
		||||
		assertThat(request.path).isEqualTo("/test")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    @Throws(InterruptedException::class)
 | 
			
		||||
    fun getRequestWithPathVariable() {
 | 
			
		||||
        val response = testService.getRequestWithPathVariable("456")
 | 
			
		||||
	@Test
 | 
			
		||||
	@Throws(InterruptedException::class)
 | 
			
		||||
	fun getRequestWithPathVariable() {
 | 
			
		||||
		val response = testService.getRequestWithPathVariable("456")
 | 
			
		||||
 | 
			
		||||
        val request = server.takeRequest()
 | 
			
		||||
        assertThat(response.statusCode).isEqualTo(HttpStatus.OK)
 | 
			
		||||
        assertThat(response.body).isEqualTo("Hello Spring!")
 | 
			
		||||
        assertThat(request.method).isEqualTo("GET")
 | 
			
		||||
        assertThat(request.path).isEqualTo("/test/456")
 | 
			
		||||
    }
 | 
			
		||||
		val request = server.takeRequest()
 | 
			
		||||
		assertThat(response.statusCode).isEqualTo(HttpStatus.OK)
 | 
			
		||||
		assertThat(response.body).isEqualTo("Hello Spring!")
 | 
			
		||||
		assertThat(request.method).isEqualTo("GET")
 | 
			
		||||
		assertThat(request.path).isEqualTo("/test/456")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    @Throws(InterruptedException::class)
 | 
			
		||||
    fun getRequestWithDynamicUri() {
 | 
			
		||||
        val dynamicUri = server.url("/greeting/123").uri()
 | 
			
		||||
	@Test
 | 
			
		||||
	@Throws(InterruptedException::class)
 | 
			
		||||
	fun getRequestWithDynamicUri() {
 | 
			
		||||
		val dynamicUri = server.url("/greeting/123").uri()
 | 
			
		||||
 | 
			
		||||
        val response = testService.getRequestWithDynamicUri(dynamicUri, "456")
 | 
			
		||||
		val response = testService.getRequestWithDynamicUri(dynamicUri, "456")
 | 
			
		||||
 | 
			
		||||
        val request = server.takeRequest()
 | 
			
		||||
        assertThat(response.orElse("empty")).isEqualTo("Hello Spring!")
 | 
			
		||||
        assertThat(request.method).isEqualTo("GET")
 | 
			
		||||
        assertThat(request.requestUrl.uri()).isEqualTo(dynamicUri)
 | 
			
		||||
    }
 | 
			
		||||
		val request = server.takeRequest()
 | 
			
		||||
		assertThat(response.orElse("empty")).isEqualTo("Hello Spring!")
 | 
			
		||||
		assertThat(request.method).isEqualTo("GET")
 | 
			
		||||
		assertThat(request.requestUrl.uri()).isEqualTo(dynamicUri)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    @Throws(InterruptedException::class)
 | 
			
		||||
    fun postWithRequestHeader() {
 | 
			
		||||
        testService.postRequestWithHeader("testHeader", "testBody")
 | 
			
		||||
	@Test
 | 
			
		||||
	@Throws(InterruptedException::class)
 | 
			
		||||
	fun postWithRequestHeader() {
 | 
			
		||||
		testService.postRequestWithHeader("testHeader", "testBody")
 | 
			
		||||
 | 
			
		||||
        val request = server.takeRequest()
 | 
			
		||||
        assertThat(request.method).isEqualTo("POST")
 | 
			
		||||
        assertThat(request.path).isEqualTo("/test")
 | 
			
		||||
        assertThat(request.headers["testHeaderName"]).isEqualTo("testHeader")
 | 
			
		||||
        assertThat(request.body.readUtf8()).isEqualTo("testBody")
 | 
			
		||||
    }
 | 
			
		||||
		val request = server.takeRequest()
 | 
			
		||||
		assertThat(request.method).isEqualTo("POST")
 | 
			
		||||
		assertThat(request.path).isEqualTo("/test")
 | 
			
		||||
		assertThat(request.headers["testHeaderName"]).isEqualTo("testHeader")
 | 
			
		||||
		assertThat(request.body.readUtf8()).isEqualTo("testBody")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    @Throws(Exception::class)
 | 
			
		||||
    fun formData() {
 | 
			
		||||
        val map: MultiValueMap<String, String> = LinkedMultiValueMap()
 | 
			
		||||
        map.add("param1", "value 1")
 | 
			
		||||
        map.add("param2", "value 2")
 | 
			
		||||
	@Test
 | 
			
		||||
	@Throws(Exception::class)
 | 
			
		||||
	fun formData() {
 | 
			
		||||
		val map: MultiValueMap<String, String> = LinkedMultiValueMap()
 | 
			
		||||
		map.add("param1", "value 1")
 | 
			
		||||
		map.add("param2", "value 2")
 | 
			
		||||
 | 
			
		||||
        testService.postForm(map)
 | 
			
		||||
		testService.postForm(map)
 | 
			
		||||
 | 
			
		||||
        val request = server.takeRequest()
 | 
			
		||||
        assertThat(request.headers["Content-Type"])
 | 
			
		||||
                .isEqualTo("application/x-www-form-urlencoded;charset=UTF-8")
 | 
			
		||||
        assertThat(request.body.readUtf8()).isEqualTo("param1=value+1¶m2=value+2")
 | 
			
		||||
    }
 | 
			
		||||
		val request = server.takeRequest()
 | 
			
		||||
		assertThat(request.headers["Content-Type"])
 | 
			
		||||
				.isEqualTo("application/x-www-form-urlencoded;charset=UTF-8")
 | 
			
		||||
		assertThat(request.body.readUtf8()).isEqualTo("param1=value+1¶m2=value+2")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    // gh-30342
 | 
			
		||||
    @Test
 | 
			
		||||
    @Throws(InterruptedException::class)
 | 
			
		||||
    fun multipart() {
 | 
			
		||||
        val fileName = "testFileName"
 | 
			
		||||
        val originalFileName = "originalTestFileName"
 | 
			
		||||
        val file: MultipartFile = MockMultipartFile(fileName, originalFileName, MediaType.APPLICATION_JSON_VALUE,
 | 
			
		||||
                "test".toByteArray())
 | 
			
		||||
	// gh-30342
 | 
			
		||||
	@Test
 | 
			
		||||
	@Throws(InterruptedException::class)
 | 
			
		||||
	fun multipart() {
 | 
			
		||||
		val fileName = "testFileName"
 | 
			
		||||
		val originalFileName = "originalTestFileName"
 | 
			
		||||
		val file: MultipartFile = MockMultipartFile(fileName, originalFileName, MediaType.APPLICATION_JSON_VALUE,
 | 
			
		||||
				"test".toByteArray())
 | 
			
		||||
 | 
			
		||||
        testService.postMultipart(file, "test2")
 | 
			
		||||
		testService.postMultipart(file, "test2")
 | 
			
		||||
 | 
			
		||||
        val request = server.takeRequest()
 | 
			
		||||
        assertThat(request.headers["Content-Type"]).startsWith("multipart/form-data;boundary=")
 | 
			
		||||
        assertThat(request.body.readUtf8()).containsSubsequence(
 | 
			
		||||
                "Content-Disposition: form-data; name=\"file\"; filename=\"originalTestFileName\"",
 | 
			
		||||
                "Content-Type: application/json", "Content-Length: 4", "test",
 | 
			
		||||
                "Content-Disposition: form-data; name=\"anotherPart\"", "Content-Type: text/plain;charset=UTF-8",
 | 
			
		||||
                "Content-Length: 5", "test2")
 | 
			
		||||
    }
 | 
			
		||||
		val request = server.takeRequest()
 | 
			
		||||
		assertThat(request.headers["Content-Type"]).startsWith("multipart/form-data;boundary=")
 | 
			
		||||
		assertThat(request.body.readUtf8()).containsSubsequence(
 | 
			
		||||
				"Content-Disposition: form-data; name=\"file\"; filename=\"originalTestFileName\"",
 | 
			
		||||
				"Content-Type: application/json", "Content-Length: 4", "test",
 | 
			
		||||
				"Content-Disposition: form-data; name=\"anotherPart\"", "Content-Type: text/plain;charset=UTF-8",
 | 
			
		||||
				"Content-Length: 5", "test2")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    @Throws(InterruptedException::class)
 | 
			
		||||
    fun putRequestWithCookies() {
 | 
			
		||||
        testService.putRequestWithCookies("test1", "test2")
 | 
			
		||||
	@Test
 | 
			
		||||
	@Throws(InterruptedException::class)
 | 
			
		||||
	fun putRequestWithCookies() {
 | 
			
		||||
		testService.putRequestWithCookies("test1", "test2")
 | 
			
		||||
 | 
			
		||||
        val request = server.takeRequest()
 | 
			
		||||
        assertThat(request.method).isEqualTo("PUT")
 | 
			
		||||
        assertThat(request.getHeader("Cookie"))
 | 
			
		||||
                .isEqualTo("firstCookie=test1; secondCookie=test2")
 | 
			
		||||
    }
 | 
			
		||||
		val request = server.takeRequest()
 | 
			
		||||
		assertThat(request.method).isEqualTo("PUT")
 | 
			
		||||
		assertThat(request.getHeader("Cookie"))
 | 
			
		||||
				.isEqualTo("firstCookie=test1; secondCookie=test2")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    @Throws(InterruptedException::class)
 | 
			
		||||
    fun putRequestWithSameNameCookies() {
 | 
			
		||||
        testService.putRequestWithSameNameCookies("test1", "test2")
 | 
			
		||||
	@Test
 | 
			
		||||
	@Throws(InterruptedException::class)
 | 
			
		||||
	fun putRequestWithSameNameCookies() {
 | 
			
		||||
		testService.putRequestWithSameNameCookies("test1", "test2")
 | 
			
		||||
 | 
			
		||||
        val request = server.takeRequest()
 | 
			
		||||
        assertThat(request.method).isEqualTo("PUT")
 | 
			
		||||
        assertThat(request.getHeader("Cookie"))
 | 
			
		||||
                .isEqualTo("testCookie=test1; testCookie=test2")
 | 
			
		||||
    }
 | 
			
		||||
		val request = server.takeRequest()
 | 
			
		||||
		assertThat(request.method).isEqualTo("PUT")
 | 
			
		||||
		assertThat(request.getHeader("Cookie"))
 | 
			
		||||
				.isEqualTo("testCookie=test1; testCookie=test2")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	@Throws(InterruptedException::class)
 | 
			
		||||
| 
						 | 
				
			
			@ -237,11 +237,11 @@ class KotlinRestTemplateHttpServiceProxyTests {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private fun prepareResponse() {
 | 
			
		||||
        val response = MockResponse()
 | 
			
		||||
        response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!")
 | 
			
		||||
        server.enqueue(response)
 | 
			
		||||
    }
 | 
			
		||||
	private fun prepareResponse() {
 | 
			
		||||
		val response = MockResponse()
 | 
			
		||||
		response.setHeader("Content-Type", "text/plain").setBody("Hello Spring!")
 | 
			
		||||
		server.enqueue(response)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private fun anotherServer(): MockWebServer {
 | 
			
		||||
		val anotherServer = MockWebServer()
 | 
			
		||||
| 
						 | 
				
			
			@ -251,34 +251,34 @@ class KotlinRestTemplateHttpServiceProxyTests {
 | 
			
		|||
		return anotherServer
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private interface TestService {
 | 
			
		||||
	private interface TestService {
 | 
			
		||||
 | 
			
		||||
        @get:GetExchange("/test")
 | 
			
		||||
        val request: String
 | 
			
		||||
		@get:GetExchange("/test")
 | 
			
		||||
		val request: String
 | 
			
		||||
 | 
			
		||||
        @GetExchange("/test/{id}")
 | 
			
		||||
        fun getRequestWithPathVariable(@PathVariable id: String): ResponseEntity<String>
 | 
			
		||||
		@GetExchange("/test/{id}")
 | 
			
		||||
		fun getRequestWithPathVariable(@PathVariable id: String): ResponseEntity<String>
 | 
			
		||||
 | 
			
		||||
        @GetExchange("/test/{id}")
 | 
			
		||||
        fun getRequestWithDynamicUri(@Nullable uri: URI, @PathVariable id: String): Optional<String>
 | 
			
		||||
		@GetExchange("/test/{id}")
 | 
			
		||||
		fun getRequestWithDynamicUri(@Nullable uri: URI, @PathVariable id: String): Optional<String>
 | 
			
		||||
 | 
			
		||||
        @PostExchange("/test")
 | 
			
		||||
        fun postRequestWithHeader(@RequestHeader("testHeaderName") testHeader: String,
 | 
			
		||||
                                  @RequestBody requestBody: String)
 | 
			
		||||
		@PostExchange("/test")
 | 
			
		||||
		fun postRequestWithHeader(@RequestHeader("testHeaderName") testHeader: String,
 | 
			
		||||
								  @RequestBody requestBody: String)
 | 
			
		||||
 | 
			
		||||
        @PostExchange(contentType = "application/x-www-form-urlencoded")
 | 
			
		||||
        fun postForm(@RequestParam params: MultiValueMap<String, String>)
 | 
			
		||||
		@PostExchange(contentType = "application/x-www-form-urlencoded")
 | 
			
		||||
		fun postForm(@RequestParam params: MultiValueMap<String, String>)
 | 
			
		||||
 | 
			
		||||
        @PostExchange
 | 
			
		||||
        fun postMultipart(file: MultipartFile, @RequestPart anotherPart: String)
 | 
			
		||||
		@PostExchange
 | 
			
		||||
		fun postMultipart(file: MultipartFile, @RequestPart anotherPart: String)
 | 
			
		||||
 | 
			
		||||
        @PutExchange
 | 
			
		||||
        fun putRequestWithCookies(@CookieValue firstCookie: String,
 | 
			
		||||
                                  @CookieValue secondCookie: String)
 | 
			
		||||
		@PutExchange
 | 
			
		||||
		fun putRequestWithCookies(@CookieValue firstCookie: String,
 | 
			
		||||
								  @CookieValue secondCookie: String)
 | 
			
		||||
 | 
			
		||||
        @PutExchange
 | 
			
		||||
        fun putRequestWithSameNameCookies(@CookieValue("testCookie") firstCookie: String,
 | 
			
		||||
                                          @CookieValue("testCookie") secondCookie: String)
 | 
			
		||||
		@PutExchange
 | 
			
		||||
		fun putRequestWithSameNameCookies(@CookieValue("testCookie") firstCookie: String,
 | 
			
		||||
										  @CookieValue("testCookie") secondCookie: String)
 | 
			
		||||
 | 
			
		||||
		@GetExchange("/greeting")
 | 
			
		||||
		fun getWithUriBuilderFactory(uriBuilderFactory: UriBuilderFactory?): ResponseEntity<String>
 | 
			
		||||
| 
						 | 
				
			
			@ -289,6 +289,6 @@ class KotlinRestTemplateHttpServiceProxyTests {
 | 
			
		|||
 | 
			
		||||
		@GetExchange("/greeting")
 | 
			
		||||
		fun getWithIgnoredUriBuilderFactory(uri: URI?, uriBuilderFactory: UriBuilderFactory?): ResponseEntity<String>
 | 
			
		||||
    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -69,43 +69,43 @@ class KotlinHttpServiceMethodTests {
 | 
			
		|||
		verifyClientInvocation("exchangeForEntityFlux", object : ParameterizedTypeReference<String>() {})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun blockingServiceWithExchangeResponseFunction() {
 | 
			
		||||
        val service = proxyFactory.createClient(BlockingFunctionsService::class.java)
 | 
			
		||||
	@Test
 | 
			
		||||
	fun blockingServiceWithExchangeResponseFunction() {
 | 
			
		||||
		val service = proxyFactory.createClient(BlockingFunctionsService::class.java)
 | 
			
		||||
 | 
			
		||||
        val stringBody = service.stringBodyBlocking()
 | 
			
		||||
        assertThat(stringBody).isEqualTo("exchangeForBody")
 | 
			
		||||
        verifyTemplateInvocation("exchangeForBody", object : ParameterizedTypeReference<String>() {})
 | 
			
		||||
		val stringBody = service.stringBodyBlocking()
 | 
			
		||||
		assertThat(stringBody).isEqualTo("exchangeForBody")
 | 
			
		||||
		verifyTemplateInvocation("exchangeForBody", object : ParameterizedTypeReference<String>() {})
 | 
			
		||||
 | 
			
		||||
        val listBody = service.listBodyBlocking()
 | 
			
		||||
        assertThat(listBody.size).isEqualTo(1)
 | 
			
		||||
        verifyTemplateInvocation("exchangeForBody", object : ParameterizedTypeReference<MutableList<String>>() {})
 | 
			
		||||
		val listBody = service.listBodyBlocking()
 | 
			
		||||
		assertThat(listBody.size).isEqualTo(1)
 | 
			
		||||
		verifyTemplateInvocation("exchangeForBody", object : ParameterizedTypeReference<MutableList<String>>() {})
 | 
			
		||||
 | 
			
		||||
        val stringEntity = service.stringEntityBlocking()
 | 
			
		||||
        assertThat(stringEntity).isEqualTo(ResponseEntity.ok<String>("exchangeForEntity"))
 | 
			
		||||
        verifyTemplateInvocation("exchangeForEntity", object : ParameterizedTypeReference<String>() {})
 | 
			
		||||
		val stringEntity = service.stringEntityBlocking()
 | 
			
		||||
		assertThat(stringEntity).isEqualTo(ResponseEntity.ok<String>("exchangeForEntity"))
 | 
			
		||||
		verifyTemplateInvocation("exchangeForEntity", object : ParameterizedTypeReference<String>() {})
 | 
			
		||||
 | 
			
		||||
        service.listEntityBlocking()
 | 
			
		||||
        verifyTemplateInvocation("exchangeForEntity", object : ParameterizedTypeReference<MutableList<String>>() {})
 | 
			
		||||
    }
 | 
			
		||||
		service.listEntityBlocking()
 | 
			
		||||
		verifyTemplateInvocation("exchangeForEntity", object : ParameterizedTypeReference<MutableList<String>>() {})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun coroutineServiceWithExchangeResponseFunction() {
 | 
			
		||||
        assertThatIllegalStateException().isThrownBy {
 | 
			
		||||
            proxyFactory.createClient(FunctionsService::class.java)
 | 
			
		||||
        }
 | 
			
		||||
	@Test
 | 
			
		||||
	fun coroutineServiceWithExchangeResponseFunction() {
 | 
			
		||||
		assertThatIllegalStateException().isThrownBy {
 | 
			
		||||
			proxyFactory.createClient(FunctionsService::class.java)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
        assertThatIllegalStateException().isThrownBy {
 | 
			
		||||
            proxyFactory.createClient(SuspendingFunctionsService::class.java)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
		assertThatIllegalStateException().isThrownBy {
 | 
			
		||||
			proxyFactory.createClient(SuspendingFunctionsService::class.java)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private fun verifyTemplateInvocation(methodReference: String, expectedBodyType: ParameterizedTypeReference<*>) {
 | 
			
		||||
        assertThat(exchangeAdapter.invokedMethodName).isEqualTo(methodReference)
 | 
			
		||||
        assertThat(exchangeAdapter.bodyType).isEqualTo(expectedBodyType)
 | 
			
		||||
    }
 | 
			
		||||
	private fun verifyTemplateInvocation(methodReference: String, expectedBodyType: ParameterizedTypeReference<*>) {
 | 
			
		||||
		assertThat(exchangeAdapter.invokedMethodName).isEqualTo(methodReference)
 | 
			
		||||
		assertThat(exchangeAdapter.bodyType).isEqualTo(expectedBodyType)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private fun verifyClientInvocation(methodReference: String, expectedBodyType: ParameterizedTypeReference<*>) {
 | 
			
		||||
	private fun verifyClientInvocation(methodReference: String, expectedBodyType: ParameterizedTypeReference<*>) {
 | 
			
		||||
		assertThat(reactorExchangeAdapter.invokedMethodName).isEqualTo(methodReference)
 | 
			
		||||
		assertThat(reactorExchangeAdapter.bodyType).isEqualTo(expectedBodyType)
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -119,35 +119,35 @@ class KotlinHttpServiceMethodTests {
 | 
			
		|||
		fun flowEntity(): ResponseEntity<Flow<String>>
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private interface SuspendingFunctionsService : BlockingFunctionsService {
 | 
			
		||||
	private interface SuspendingFunctionsService : BlockingFunctionsService {
 | 
			
		||||
 | 
			
		||||
        @GetExchange
 | 
			
		||||
        suspend fun stringBody(): String
 | 
			
		||||
		@GetExchange
 | 
			
		||||
		suspend fun stringBody(): String
 | 
			
		||||
 | 
			
		||||
        @GetExchange
 | 
			
		||||
        suspend fun listBody(): MutableList<String>
 | 
			
		||||
		@GetExchange
 | 
			
		||||
		suspend fun listBody(): MutableList<String>
 | 
			
		||||
 | 
			
		||||
        @GetExchange
 | 
			
		||||
        suspend fun stringEntity(): ResponseEntity<String>
 | 
			
		||||
		@GetExchange
 | 
			
		||||
		suspend fun stringEntity(): ResponseEntity<String>
 | 
			
		||||
 | 
			
		||||
        @GetExchange
 | 
			
		||||
        suspend fun listEntity(): ResponseEntity<MutableList<String>>
 | 
			
		||||
    }
 | 
			
		||||
		@GetExchange
 | 
			
		||||
		suspend fun listEntity(): ResponseEntity<MutableList<String>>
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private interface BlockingFunctionsService {
 | 
			
		||||
	private interface BlockingFunctionsService {
 | 
			
		||||
 | 
			
		||||
        @GetExchange
 | 
			
		||||
        fun stringBodyBlocking(): String
 | 
			
		||||
		@GetExchange
 | 
			
		||||
		fun stringBodyBlocking(): String
 | 
			
		||||
 | 
			
		||||
        @GetExchange
 | 
			
		||||
        fun listBodyBlocking(): MutableList<String>
 | 
			
		||||
		@GetExchange
 | 
			
		||||
		fun listBodyBlocking(): MutableList<String>
 | 
			
		||||
 | 
			
		||||
        @GetExchange
 | 
			
		||||
        fun stringEntityBlocking(): ResponseEntity<String>
 | 
			
		||||
		@GetExchange
 | 
			
		||||
		fun stringEntityBlocking(): ResponseEntity<String>
 | 
			
		||||
 | 
			
		||||
        @GetExchange
 | 
			
		||||
        fun listEntityBlocking(): ResponseEntity<MutableList<String>>
 | 
			
		||||
		@GetExchange
 | 
			
		||||
		fun listEntityBlocking(): ResponseEntity<MutableList<String>>
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -90,8 +90,8 @@ suspend fun RequestHeadersSpec<out RequestHeadersSpec<*>>.awaitExchange(): Clien
 | 
			
		|||
 * @since 5.3
 | 
			
		||||
 */
 | 
			
		||||
suspend fun <T: Any> RequestHeadersSpec<out RequestHeadersSpec<*>>.awaitExchange(responseHandler: suspend (ClientResponse) -> T): T {
 | 
			
		||||
    val context = currentCoroutineContext().minusKey(Job.Key)
 | 
			
		||||
    return exchangeToMono { mono(context) { responseHandler.invoke(it) } }.awaitSingle()
 | 
			
		||||
	val context = currentCoroutineContext().minusKey(Job.Key)
 | 
			
		||||
	return exchangeToMono { mono(context) { responseHandler.invoke(it) } }.awaitSingle()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -100,7 +100,7 @@ suspend fun <T: Any> RequestHeadersSpec<out RequestHeadersSpec<*>>.awaitExchange
 | 
			
		|||
 * @since 5.3.8
 | 
			
		||||
 */
 | 
			
		||||
suspend fun <T: Any> RequestHeadersSpec<out RequestHeadersSpec<*>>.awaitExchangeOrNull(responseHandler: suspend (ClientResponse) -> T?): T? {
 | 
			
		||||
    val context = currentCoroutineContext().minusKey(Job.Key)
 | 
			
		||||
	val context = currentCoroutineContext().minusKey(Job.Key)
 | 
			
		||||
	return exchangeToMono { mono(context) { responseHandler.invoke(it) } }.awaitSingleOrNull()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -88,4 +88,4 @@ suspend fun ServerWebExchange.awaitSession(): WebSession =
 | 
			
		|||
	ReplaceWith("principal(supplier)", "org.springframework.web.server.principal"),
 | 
			
		||||
)
 | 
			
		||||
fun ServerWebExchange.Builder.principal(supplier: suspend () -> Principal): ServerWebExchange.Builder
 | 
			
		||||
        = principal(mono(Dispatchers.Unconfined) { supplier.invoke() })
 | 
			
		||||
		= principal(mono(Dispatchers.Unconfined) { supplier.invoke() })
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue