From 182317dbe92fa2208043dcc4605b789cd6a7f8a6 Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Wed, 12 Jul 2017 08:44:14 -0500 Subject: [PATCH] Minor polishing of InMemoryFunctionCatalog - Removed constructor in InMemoryFunctionCatalog that creates empty maps and no registrations since there is no way to register anything after catalog is created. - Refactored registration logic a bit more functional/concise in the FunctionRegistration constructor of InMemoryFunctionCatalog - Added additional assertions in tests rebased and removed the assertion that was causing certain test failures --- .../context/InMemoryFunctionCatalog.java | 48 +++++++------------ ...FunctionCatalogAutoConfigurationTests.java | 26 +++++++++- 2 files changed, 41 insertions(+), 33 deletions(-) diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/InMemoryFunctionCatalog.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/InMemoryFunctionCatalog.java index c143dd0b6..0d3efb15e 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/InMemoryFunctionCatalog.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/InMemoryFunctionCatalog.java @@ -22,13 +22,16 @@ import java.util.Set; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; +import java.util.stream.Stream; import org.springframework.cloud.function.registry.FunctionCatalog; +import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** * @author Dave Syer * @author Mark Fisher + * @author Oleg Zhurakousky */ public class InMemoryFunctionCatalog implements FunctionCatalog { @@ -38,34 +41,22 @@ public class InMemoryFunctionCatalog implements FunctionCatalog { private final Map> suppliers; - public InMemoryFunctionCatalog(Map> suppliers, - Map> functions, Map> consumers) { - this.suppliers = suppliers; - this.functions = functions; - this.consumers = consumers; - } - public InMemoryFunctionCatalog(Set> registrations) { + Assert.notNull(registrations, "'registrations' must not be null"); this.suppliers = new HashMap<>(); this.functions = new HashMap<>(); this.consumers = new HashMap<>(); - for (FunctionRegistration registration : registrations) { - if (registration.getTarget() instanceof Consumer) { - for (String name : registration.getNames()) { - consumers.put(name, (Consumer) registration.getTarget()); - } + registrations.stream().forEach(reg -> reg.getNames().stream().forEach(name -> { + if (reg.getTarget() instanceof Consumer){ + consumers.put(name, (Consumer) reg.getTarget()); } - if (registration.getTarget() instanceof Supplier) { - for (String name : registration.getNames()) { - suppliers.put(name, (Supplier) registration.getTarget()); - } + else if (reg.getTarget() instanceof Function){ + functions.put(name, (Function) reg.getTarget()); } - if (registration.getTarget() instanceof Function) { - for (String name : registration.getNames()) { - functions.put(name, (Function) registration.getTarget()); - } + else if (reg.getTarget() instanceof Supplier){ + suppliers.put(name, (Supplier) reg.getTarget()); } - } + })); } @Override @@ -77,16 +68,10 @@ public class InMemoryFunctionCatalog implements FunctionCatalog { @Override @SuppressWarnings({ "unchecked", "rawtypes" }) public Function lookupFunction(String name) { - if (name.indexOf(',') == -1) { - return (Function) functions.get(name); - } - String[] tokens = StringUtils.tokenizeToStringArray(name, ","); - Function function = null; - for (String token : tokens) { - Function next = lookupFunction(token); - function = (function == null) ? next : function.andThen(next); - } - return function; + return (Function) Stream.of(StringUtils.tokenizeToStringArray(name, ",")) + .map(functions::get) + .filter(f -> f != null) + .reduce(null, (f1, f2) -> f1 == null ? f2 : f1.andThen((Function)f2)); } @Override @@ -109,5 +94,4 @@ public class InMemoryFunctionCatalog implements FunctionCatalog { public Set getConsumerNames() { return consumers.keySet(); } - } diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/ContextFunctionCatalogAutoConfigurationTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/ContextFunctionCatalogAutoConfigurationTests.java index 00c18cd0f..39d93dba2 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/ContextFunctionCatalogAutoConfigurationTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/ContextFunctionCatalogAutoConfigurationTests.java @@ -73,10 +73,19 @@ public class ContextFunctionCatalogAutoConfigurationTests { } @Test - public void simpleFunction() { + public void lookUps() { create(SimpleConfiguration.class); assertThat(context.getBean("function")).isInstanceOf(Function.class); assertThat(catalog.lookupFunction("function")).isInstanceOf(Function.class); + assertThat(context.getBean("function2")).isInstanceOf(Function.class); + assertThat(catalog.lookupFunction("function,function2")).isInstanceOf(Function.class); + Function,Flux> f = catalog.lookupFunction("function,function2,function3"); + assertThat(f).isInstanceOf(Function.class); + assertThat(f.apply(Flux.just("hello")).blockFirst()).isEqualTo("HELLOfunction2function3"); + assertThat(context.getBean("supplierFoo")).isInstanceOf(Supplier.class); + assertThat(catalog.lookupSupplier("supplierFoo")).isInstanceOf(Supplier.class); + assertThat(context.getBean("supplier_Foo")).isInstanceOf(Supplier.class); + assertThat(catalog.lookupSupplier("supplier_Foo")).isInstanceOf(Supplier.class); } @Test @@ -331,11 +340,26 @@ public class ContextFunctionCatalogAutoConfigurationTests { return value -> value.toUpperCase(); } + @Bean + public Function function2() { + return value -> value + "function2"; + } + + @Bean + public Function function3() { + return value -> value + "function3"; + } + @Bean public Supplier supplier() { return () -> "hello"; } + @Bean(name={"supplierFoo", "supplier_Foo"}) + public Supplier foo() { + return () -> "hello"; + } + @Bean public Consumer consumer() { return value -> list.add(value);