diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/ContextFunctionCatalogAutoConfiguration.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/ContextFunctionCatalogAutoConfiguration.java index 33656eac0..e748dbfef 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/ContextFunctionCatalogAutoConfiguration.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/ContextFunctionCatalogAutoConfiguration.java @@ -245,8 +245,12 @@ public class ContextFunctionCatalogAutoConfiguration { return lookup.get(name); } String[] stages = StringUtils.tokenizeToStringArray(name, ","); - Object function = lookup(stages[0], - !hasInput || stages.length == 1 ? lookup : this.functions); + Map source = !hasInput || stages.length <= 1 ? lookup + : this.functions; + if (stages.length == 0 && source.size() == 1) { + stages = new String[] { source.keySet().iterator().next() }; + } + Object function = lookup(stages[0], source); if (function == null) { return null; } @@ -494,12 +498,13 @@ public class ContextFunctionCatalogAutoConfiguration { int index = paramType.isOutput() ? 1 : 0; if (source instanceof StandardMethodMetadata) { // Standard @Bean metadata - Type beanType = ((StandardMethodMetadata) source) - .getIntrospectedMethod().getGenericReturnType(); + Type beanType = ((StandardMethodMetadata) source).getIntrospectedMethod() + .getGenericReturnType(); if (beanType instanceof ParameterizedType) { - ParameterizedType type = (ParameterizedType) beanType; - param = extractType(type, paramType, index); - } else { + ParameterizedType type = (ParameterizedType) beanType; + param = extractType(type, paramType, index); + } + else { param = findTypeFromBeanClass((Class) beanType, paramType); } } diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/BeanFactoryFunctionCatalogTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/BeanFactoryFunctionCatalogTests.java index e871d130f..6483836d7 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/BeanFactoryFunctionCatalogTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/BeanFactoryFunctionCatalogTests.java @@ -16,7 +16,11 @@ package org.springframework.cloud.function.context; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Supplier; import org.junit.Test; @@ -44,7 +48,14 @@ public class BeanFactoryFunctionCatalogTests { } @Test - public void compose() { + public void lookupFunctionWithEmptyName() { + processor.register(new FunctionRegistration<>(new Foos()).names("foos")); + Function, Flux> foos = processor.lookupFunction(""); + assertThat(foos.apply(Flux.just(2)).blockFirst()).isEqualTo("4"); + } + + @Test + public void composeFunction() { processor.register(new FunctionRegistration<>(new Foos()).names("foos")); processor.register(new FunctionRegistration<>(new Bars()).names("bars")); Function, Flux> foos = processor @@ -52,6 +63,60 @@ public class BeanFactoryFunctionCatalogTests { assertThat(foos.apply(Flux.just(2)).blockFirst()).isEqualTo("Hello 4"); } + @Test + public void composeSupplier() { + processor.register(new FunctionRegistration<>(new Source()).names("numbers")); + processor.register(new FunctionRegistration<>(new Foos()).names("foos")); + Supplier> foos = processor.lookupSupplier("numbers,foos"); + assertThat(foos.get().blockFirst()).isEqualTo("6"); + } + + @Test + public void composeUniqueSupplier() { + processor.register(new FunctionRegistration<>(new Source()).names("numbers")); + Supplier> foos = processor.lookupSupplier(""); + assertThat(foos.get().blockFirst()).isEqualTo(3); + } + + @Test + public void composeConsumer() { + processor.register(new FunctionRegistration<>(new Foos()).names("foos")); + Sink sink = new Sink(); + processor.register(new FunctionRegistration<>(sink).names("sink")); + Consumer> foos = processor.lookupConsumer("foos,sink"); + foos.accept(Flux.just(2)); + assertThat(sink.values).contains("4"); + } + + @Test + public void composeUniqueConsumer() { + Sink sink = new Sink(); + processor.register(new FunctionRegistration<>(sink).names("sink")); + Consumer> foos = processor.lookupConsumer(""); + foos.accept(Flux.just("2")); + assertThat(sink.values).contains("2"); + } + + protected static class Source implements Supplier { + + @Override + public Integer get() { + return 3; + } + + } + + protected static class Sink implements Consumer { + + private List values = new ArrayList<>(); + + @Override + public void accept(String value) { + values.add(value); + } + + } + protected static class Foos implements Function { @Override