diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/AbstractComposableFunctionRegistry.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/AbstractComposableFunctionRegistry.java index 6228ce54f..66a658c9c 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/AbstractComposableFunctionRegistry.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/AbstractComposableFunctionRegistry.java @@ -66,15 +66,15 @@ public abstract class AbstractComposableFunctionRegistry implements FunctionRegistry, FunctionInspector, ApplicationEventPublisherAware, EnvironmentAware { - private Map suppliers = new ConcurrentHashMap<>(); + private final Map suppliers = new ConcurrentHashMap<>(); - private Map functions = new ConcurrentHashMap<>(); + private final Map functions = new ConcurrentHashMap<>(); - private Map consumers = new ConcurrentHashMap<>(); + private final Map consumers = new ConcurrentHashMap<>(); - private Map names = new ConcurrentHashMap<>(); + private final Map names = new ConcurrentHashMap<>(); - private Map types = new ConcurrentHashMap<>(); + private final Map types = new ConcurrentHashMap<>(); private Environment environment = new StandardEnvironment(); @@ -133,15 +133,15 @@ public abstract class AbstractComposableFunctionRegistry } public boolean hasSuppliers() { - return !CollectionUtils.isEmpty(this.suppliers); + return !CollectionUtils.isEmpty(getSupplierNames()); } public boolean hasFunctions() { - return !CollectionUtils.isEmpty(this.functions); + return !CollectionUtils.isEmpty(getFunctionNames()); } public boolean hasConsumers() { - return !CollectionUtils.isEmpty(this.consumers); + return !CollectionUtils.isEmpty(getConsumerNames()); } /** @@ -149,7 +149,7 @@ public abstract class AbstractComposableFunctionRegistry * @return the count of all Suppliers, Function and Consumers currently registered. */ public int size() { - return this.suppliers.size() + this.functions.size() + this.consumers.size(); + return getSupplierNames().size() + getFunctionNames().size() + getConsumerNames().size(); } public FunctionType getFunctionType(String name) { @@ -167,21 +167,6 @@ public abstract class AbstractComposableFunctionRegistry return this.names.containsKey(function) ? this.names.get(function) : null; } - public void addSupplier(String name, Object supplier) { - this.suppliers.put(name, supplier); - this.addName(supplier, name); - } - - public void addFunction(String name, Object function) { - this.functions.put(name, function); - this.addName(function, name); - } - - public void addConsumer(String name, Object consumer) { - this.consumers.put(name, consumer); - this.addName(consumer, name); - } - protected void wrap(FunctionRegistration registration, String key) { Object target = registration.getTarget(); this.addName(target, key); @@ -189,7 +174,7 @@ public abstract class AbstractComposableFunctionRegistry this.addType(key, registration.getType()); } else { - FunctionType functionType = findType(target); + FunctionType functionType = findType(registration); this.addType(key, functionType); registration.type(functionType.getType()); } @@ -199,19 +184,19 @@ public abstract class AbstractComposableFunctionRegistry if (target instanceof Supplier) { type = Supplier.class; for (String name : registration.getNames()) { - this.addSupplier(name, registration.getTarget()); + this.addSupplier(name, (Supplier) registration.getTarget()); } } else if (target instanceof Consumer) { type = Consumer.class; for (String name : registration.getNames()) { - this.addConsumer(name, registration.getTarget()); + this.addConsumer(name, (Consumer) registration.getTarget()); } } else if (target instanceof Function) { type = Function.class; for (String name : registration.getNames()) { - this.addFunction(name, registration.getTarget()); + this.addFunction(name, (Function) registration.getTarget()); } } else { @@ -224,10 +209,26 @@ public abstract class AbstractComposableFunctionRegistry } } - protected FunctionType findType(Object function) { - throw new UnsupportedOperationException("There is no default " - + "implementation of this operation. It must be overriden " - + "by the implementation of FunctionRegistry."); + protected FunctionType findType(FunctionRegistration functionRegistration) { + FunctionType functionType = functionRegistration.getType(); + if (functionType != null) { + return functionType; + } + throw new IllegalStateException("Unless FunctionType is already available in FunctionRegistration, " + + "this operation must be overriden " + + "by the implementation of the FunctionRegistry."); + } + + protected void addSupplier(String name, Supplier supplier) { + this.suppliers.put(name, supplier); + } + + protected void addFunction(String name, Function function) { + this.functions.put(name, function); + } + + protected void addConsumer(String name, Consumer consumer) { + this.consumers.put(name, consumer); } @SuppressWarnings({ "unchecked", "rawtypes" }) @@ -302,16 +303,16 @@ public abstract class AbstractComposableFunctionRegistry && this.types.containsKey(stages[stages.length - 1])) { FunctionType input = this.types.get(stages[0]); FunctionType output = this.types.get(stages[stages.length - 1]); - this.types.put(name, FunctionType.compose(input, output)); - this.names.put(composedFunction, name); + this.addType(name, FunctionType.compose(input, output)); + this.addName(composedFunction, name); if (composedFunction instanceof Function) { - this.functions.put(name, composedFunction); + this.addFunction(name, (Function) composedFunction); } else if (composedFunction instanceof Consumer) { - this.consumers.put(name, composedFunction); + this.addConsumer(name, (Consumer) composedFunction); } else if (composedFunction instanceof Supplier) { - this.suppliers.put(name, composedFunction); + this.addSupplier(name, (Supplier) composedFunction); } } } @@ -325,7 +326,8 @@ public abstract class AbstractComposableFunctionRegistry } private boolean contains(String name) { - return suppliers.containsKey(name) || functions.containsKey(name) || consumers.containsKey(name); + return getSupplierNames().contains(name) + || getFunctionNames().contains(name) || getConsumerNames().contains(name); } private Object find(String name) { diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/InMemoryFunctionCatalog.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/InMemoryFunctionCatalog.java index cf6a69fa3..75e5c8478 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/InMemoryFunctionCatalog.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/InMemoryFunctionCatalog.java @@ -52,34 +52,44 @@ public class InMemoryFunctionCatalog extends AbstractComposableFunctionRegistry } @Override - public void register(FunctionRegistration registration) { - Assert.notEmpty(registration.getNames(), + public void register(FunctionRegistration functionRegistration) { + Assert.notEmpty(functionRegistration.getNames(), "'registration' must contain at least one name before it is registered in catalog."); + // TODO should we just delegate to wrap(..)???? + //wrap(functionRegistration, functionRegistration.getNames().iterator().next()); Class type = Object.class; - if (registration.getTarget() instanceof Function) { + if (functionRegistration.getTarget() instanceof Function) { type = Function.class; } - else if (registration.getTarget() instanceof Supplier) { + else if (functionRegistration.getTarget() instanceof Supplier) { type = Supplier.class; } - else if (registration.getTarget() instanceof Consumer) { + else if (functionRegistration.getTarget() instanceof Consumer) { type = Consumer.class; } FunctionRegistrationEvent event = new FunctionRegistrationEvent(this, type, - registration.getNames()); + functionRegistration.getNames()); - this.registrations.put(registration.getTarget(), registration); - FunctionRegistration wrapped = registration.wrap(); - if (wrapped != registration) { - registration = wrapped; + this.registrations.put(functionRegistration.getTarget(), functionRegistration); + FunctionRegistration wrapped = functionRegistration.wrap(); + if (wrapped != functionRegistration) { + functionRegistration = wrapped; this.registrations.put(wrapped.getTarget(), wrapped); if (type == Consumer.class) { type = Function.class; } } - for (String name : registration.getNames()) { - this.addFunction(name, registration.getTarget()); + for (String name : functionRegistration.getNames()) { + if (functionRegistration.getTarget() instanceof Function) { + this.addFunction(name, (Function) functionRegistration.getTarget()); + } + else if (functionRegistration.getTarget() instanceof Consumer) { + this.addConsumer(name, (Consumer) functionRegistration.getTarget()); + } + else { + this.addSupplier(name, (Supplier) functionRegistration.getTarget()); + } } this.publishEvent(event); } diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfiguration.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfiguration.java index fe1c34c0a..cdb15d856 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfiguration.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfiguration.java @@ -96,12 +96,14 @@ public class ContextFunctionCatalogAutoConfiguration { private ConfigurableListableBeanFactory beanFactory; + //@SuppressWarnings("unchecked") @Override public FunctionRegistration getRegistration(Object function) { String functionName = this.lookupFunctionName(function); if (StringUtils.hasText(functionName)) { - return new FunctionRegistration<>(function, functionName) - .type(findType(function).getType()); + FunctionRegistration registration = new FunctionRegistration(function, functionName); + FunctionType functionType = this.findType(registration); + return registration.type(functionType.getType()); } return null; } @@ -158,13 +160,16 @@ public class ContextFunctionCatalogAutoConfiguration { } @Override - protected FunctionType findType(Object function) { - String name = this.lookupFunctionName(function); + protected FunctionType findType(FunctionRegistration functionRegistration) { + if (functionRegistration.getType() != null) { + return functionRegistration.getType(); + } + String name = this.lookupFunctionName(functionRegistration.getTarget()); FunctionType functionType = this.getFunctionType(name); if (functionType == null) { functionType = functionByNameExist(name) - ? new FunctionType(function.getClass()) : new FunctionType( + ? new FunctionType(functionRegistration.getTarget().getClass()) : new FunctionType( FunctionContextUtils.findType(name, this.beanFactory)); } @@ -195,68 +200,6 @@ public class ContextFunctionCatalogAutoConfiguration { return names; } -// private void wrap(FunctionRegistration registration, String key) { -// Object target = registration.getTarget(); -//// this.addName(target, key); -// if (registration.getType() != null) { -// this.addType(key, registration.getType()); -// } -// else { -// registration.type(findType(target).getType()); -// } -// Class type; -// registration = isolated(registration).wrap(); -// target = registration.getTarget(); -// if (target instanceof Supplier) { -// type = Supplier.class; -// for (String name : registration.getNames()) { -// this.addSupplier(name, registration.getTarget()); -// } -// } -// else if (target instanceof Consumer) { -// type = Consumer.class; -// for (String name : registration.getNames()) { -// this.addConsumer(name, registration.getTarget()); -// } -// } -// else if (target instanceof Function) { -// type = Function.class; -// for (String name : registration.getNames()) { -// this.addFunction(name, registration.getTarget()); -// } -// } -// else { -// return; -// } -// //this.addName(registration.getTarget(), key); -// if (this.applicationEventPublisher != null) { -// this.applicationEventPublisher.publishEvent(new FunctionRegistrationEvent( -// registration.getTarget(), type, registration.getNames())); -// } -// } - -// @SuppressWarnings({ "rawtypes", "unchecked" }) -// private FunctionRegistration isolated(FunctionRegistration input) { -// FunctionRegistration registration = (FunctionRegistration) input; -// Object target = registration.getTarget(); -// boolean isolated = getClass().getClassLoader() != target.getClass() -// .getClassLoader(); -// if (isolated) { -// if (target instanceof Supplier && isolated) { -// target = new IsolatedSupplier((Supplier) target); -// } -// else if (target instanceof Function) { -// target = new IsolatedFunction((Function) target); -// } -// else if (target instanceof Consumer) { -// target = new IsolatedConsumer((Consumer) target); -// } -// } -// -// registration.target(target); -// return registration; -// } - private String getQualifier(String key) { if (this.beanFactory != null && this.beanFactory.containsBeanDefinition(key)) {