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
This commit is contained in:
Oleg Zhurakousky
2017-07-12 08:44:14 -05:00
committed by Dave Syer
parent ae14c236e1
commit 182317dbe9
2 changed files with 41 additions and 33 deletions

View File

@@ -22,13 +22,16 @@ import java.util.Set;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Stream;
import org.springframework.cloud.function.registry.FunctionCatalog; import org.springframework.cloud.function.registry.FunctionCatalog;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
* @author Dave Syer * @author Dave Syer
* @author Mark Fisher * @author Mark Fisher
* @author Oleg Zhurakousky
*/ */
public class InMemoryFunctionCatalog implements FunctionCatalog { public class InMemoryFunctionCatalog implements FunctionCatalog {
@@ -38,34 +41,22 @@ public class InMemoryFunctionCatalog implements FunctionCatalog {
private final Map<String, Supplier<?>> suppliers; private final Map<String, Supplier<?>> suppliers;
public InMemoryFunctionCatalog(Map<String, Supplier<?>> suppliers,
Map<String, Function<?, ?>> functions, Map<String, Consumer<?>> consumers) {
this.suppliers = suppliers;
this.functions = functions;
this.consumers = consumers;
}
public InMemoryFunctionCatalog(Set<FunctionRegistration<?>> registrations) { public InMemoryFunctionCatalog(Set<FunctionRegistration<?>> registrations) {
Assert.notNull(registrations, "'registrations' must not be null");
this.suppliers = new HashMap<>(); this.suppliers = new HashMap<>();
this.functions = new HashMap<>(); this.functions = new HashMap<>();
this.consumers = new HashMap<>(); this.consumers = new HashMap<>();
for (FunctionRegistration<?> registration : registrations) { registrations.stream().forEach(reg -> reg.getNames().stream().forEach(name -> {
if (registration.getTarget() instanceof Consumer) { if (reg.getTarget() instanceof Consumer){
for (String name : registration.getNames()) { consumers.put(name, (Consumer<?>) reg.getTarget());
consumers.put(name, (Consumer<?>) registration.getTarget());
}
} }
if (registration.getTarget() instanceof Supplier) { else if (reg.getTarget() instanceof Function){
for (String name : registration.getNames()) { functions.put(name, (Function<?, ?>) reg.getTarget());
suppliers.put(name, (Supplier<?>) registration.getTarget());
}
} }
if (registration.getTarget() instanceof Function) { else if (reg.getTarget() instanceof Supplier){
for (String name : registration.getNames()) { suppliers.put(name, (Supplier<?>) reg.getTarget());
functions.put(name, (Function<?, ?>) registration.getTarget());
}
} }
} }));
} }
@Override @Override
@@ -77,16 +68,10 @@ public class InMemoryFunctionCatalog implements FunctionCatalog {
@Override @Override
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
public <T, R> Function<T, R> lookupFunction(String name) { public <T, R> Function<T, R> lookupFunction(String name) {
if (name.indexOf(',') == -1) { return (Function<T, R>) Stream.of(StringUtils.tokenizeToStringArray(name, ","))
return (Function<T, R>) functions.get(name); .map(functions::get)
} .filter(f -> f != null)
String[] tokens = StringUtils.tokenizeToStringArray(name, ","); .reduce(null, (f1, f2) -> f1 == null ? f2 : f1.andThen((Function)f2));
Function function = null;
for (String token : tokens) {
Function next = lookupFunction(token);
function = (function == null) ? next : function.andThen(next);
}
return function;
} }
@Override @Override
@@ -109,5 +94,4 @@ public class InMemoryFunctionCatalog implements FunctionCatalog {
public Set<String> getConsumerNames() { public Set<String> getConsumerNames() {
return consumers.keySet(); return consumers.keySet();
} }
} }

View File

@@ -73,10 +73,19 @@ public class ContextFunctionCatalogAutoConfigurationTests {
} }
@Test @Test
public void simpleFunction() { public void lookUps() {
create(SimpleConfiguration.class); create(SimpleConfiguration.class);
assertThat(context.getBean("function")).isInstanceOf(Function.class); assertThat(context.getBean("function")).isInstanceOf(Function.class);
assertThat(catalog.lookupFunction("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<String>,Flux<String>> 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 @Test
@@ -331,11 +340,26 @@ public class ContextFunctionCatalogAutoConfigurationTests {
return value -> value.toUpperCase(); return value -> value.toUpperCase();
} }
@Bean
public Function<String, String> function2() {
return value -> value + "function2";
}
@Bean
public Function<String, String> function3() {
return value -> value + "function3";
}
@Bean @Bean
public Supplier<String> supplier() { public Supplier<String> supplier() {
return () -> "hello"; return () -> "hello";
} }
@Bean(name={"supplierFoo", "supplier_Foo"})
public Supplier<String> foo() {
return () -> "hello";
}
@Bean @Bean
public Consumer<String> consumer() { public Consumer<String> consumer() {
return value -> list.add(value); return value -> list.add(value);