GH-632 Fix type discovery on Kotlin function

Fix the way FunctionTypeUtils deals with Kotllin function when it attempts to discover their type.
Basically it checks if function-name + '_registration' nean exists and if so it skip discovery and uses the types available in FunctionRegistration which for Kotlin scenarios will always exist.

Resolves #632
This commit is contained in:
Oleg Zhurakousky
2021-01-26 12:04:05 +01:00
parent ed99439f0b
commit 2a356812ac
2 changed files with 38 additions and 5 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2019-2020 the original author or authors.
* Copyright 2019-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -242,6 +242,12 @@ public final class FunctionTypeUtils {
else if (function instanceof FunctionRegistration) {
return ((FunctionRegistration) function).getType().getType();
}
if (applicationContext.containsBean(functionName + FunctionRegistration.REGISTRATION_NAME_SUFFIX)) { // for Kotlin primarily
FunctionRegistration fr = applicationContext
.getBean(functionName + FunctionRegistration.REGISTRATION_NAME_SUFFIX, FunctionRegistration.class);
return fr.getType().getType();
}
boolean beanDefinitionExists = false;
String functionBeanDefinitionName = discoverDefinitionName(functionName, applicationContext);
beanDefinitionExists = applicationContext.getBeanFactory().containsBeanDefinition(functionBeanDefinitionName);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2019-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package org.springframework.cloud.function.kotlin;
import java.lang.reflect.ParameterizedType;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -29,9 +30,9 @@ import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.function.context.FunctionCatalog;
import org.springframework.cloud.function.context.catalog.FunctionTypeUtils;
import org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry.FunctionInvocationWrapper;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
@@ -40,7 +41,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
public class ContextFunctionCatalogAutoConfigurationKotlinTests {
private ConfigurableApplicationContext context;
private GenericApplicationContext context;
private FunctionCatalog catalog;
@@ -51,6 +52,32 @@ public class ContextFunctionCatalogAutoConfigurationKotlinTests {
}
}
@Test
public void typeDiscoveryTests() {
create(new Class[] { KotlinLambdasConfiguration.class,
SimpleConfiguration.class });
Object function = this.context.getBean("kotlinFunction");
ParameterizedType functionType = (ParameterizedType) FunctionTypeUtils.discoverFunctionType(function, "kotlinFunction", this.context);
assertThat(functionType.getRawType().getTypeName()).isEqualTo(Function.class.getName());
assertThat(functionType.getActualTypeArguments().length).isEqualTo(2);
assertThat(functionType.getActualTypeArguments()[0].getTypeName()).isEqualTo(String.class.getName());
assertThat(functionType.getActualTypeArguments()[1].getTypeName()).isEqualTo(String.class.getName());
function = this.context.getBean("kotlinConsumer");
functionType = (ParameterizedType) FunctionTypeUtils.discoverFunctionType(function, "kotlinConsumer", this.context);
assertThat(functionType.getRawType().getTypeName()).isEqualTo(Function.class.getName());
assertThat(functionType.getActualTypeArguments().length).isEqualTo(2);
assertThat(functionType.getActualTypeArguments()[0].getTypeName()).isEqualTo(String.class.getName());
assertThat(functionType.getActualTypeArguments()[1].getTypeName()).isEqualTo("kotlin.Unit");
function = this.context.getBean("kotlinSupplier");
functionType = (ParameterizedType) FunctionTypeUtils.discoverFunctionType(function, "kotlinSupplier", this.context);
assertThat(functionType.getRawType().getTypeName()).isEqualTo(Supplier.class.getName());
assertThat(functionType.getActualTypeArguments().length).isEqualTo(1);
assertThat(functionType.getActualTypeArguments()[0].getTypeName()).isEqualTo(String.class.getName());
}
@Test
public void kotlinLambdas() {
create(new Class[] { KotlinLambdasConfiguration.class,
@@ -85,7 +112,7 @@ public class ContextFunctionCatalogAutoConfigurationKotlinTests {
}
private void create(Class<?>[] types, String... props) {
this.context = new SpringApplicationBuilder(types).properties(props).run();
this.context = (GenericApplicationContext) new SpringApplicationBuilder(types).properties(props).run();
this.catalog = this.context.getBean(FunctionCatalog.class);
}