GH-413 Fix type discovery logic in BeanFactoryAwareFunctionRegistry

- added 'discoverFunctionTypeFromFunctionalObject' method to FunctionTypeUtils
- added tests to reproduce and validate the issue
This commit is contained in:
Oleg Zhurakousky
2019-10-02 11:37:08 -04:00
parent 08c194e14f
commit 38e06a9dd0
3 changed files with 51 additions and 5 deletions

View File

@@ -219,23 +219,21 @@ public class BeanFactoryAwareFunctionRegistry
*/
List<String> names = Stream
.concat(Stream.of(functionNames), Stream.concat(Stream.of(consumerNames), Stream.of(supplierNames))).collect(Collectors.toList());
Object fnObject = null;
if (!ObjectUtils.isEmpty(names)) {
Assert.isTrue(names.size() == 1, "Found more then one function in BeanFactory: " + names
+ ". Consider providing 'spring.cloud.function.definition' property.");
definition = names.get(0);
fnObject = this.applicationContext.getBean(definition);
}
else {
if (this.registrationsByName.size() > 0) {
Assert.isTrue(this.registrationsByName.size() == 1, "Found more then one function in local registry");
definition = this.registrationsByName.keySet().iterator().next();
fnObject = this.registrationsByName.values().iterator().next().getTarget();
}
}
if (StringUtils.hasText(definition)) {
Type functionType = discoverFunctionType(fnObject, definition);
if (StringUtils.hasText(definition) && this.applicationContext.containsBean(definition)) {
Type functionType = discoverFunctionType(this.applicationContext.getBean(definition), definition);
if (!FunctionTypeUtils.isSupplier(functionType) && !FunctionTypeUtils.isFunction(functionType) && !FunctionTypeUtils.isConsumer(functionType)) {
logger.info("Discovered functional instance of bean '" + definition + "' as a default function, however its "
+ "function argument types can not be determined. Discarding.");

View File

@@ -34,6 +34,7 @@ import org.reactivestreams.Publisher;
import reactor.util.function.Tuple2;
import org.springframework.cloud.function.context.FunctionRegistration;
import org.springframework.cloud.function.context.catalog.BeanFactoryAwareFunctionRegistry.FunctionInvocationWrapper;
import org.springframework.core.ResolvableType;
import org.springframework.messaging.Message;
import org.springframework.util.Assert;
@@ -105,6 +106,15 @@ public final class FunctionTypeUtils {
return methods.get(0);
}
public static Type discoverFunctionTypeFromFunctionalObject(Object functionalObject) {
if (functionalObject instanceof FunctionInvocationWrapper) {
return ((FunctionInvocationWrapper) functionalObject).getFunctionType();
}
else {
return discoverFunctionTypeFromClass(functionalObject.getClass());
}
}
public static Type discoverFunctionTypeFromClass(Class<?> functionalClass) {
Assert.isTrue(isFunctional(functionalClass), "Type must be one of Supplier, Function or Consumer");
Type[] generics = functionalClass.getGenericInterfaces();