Fix naming indirection so that input types are correctly located

Also applies to output types, wrapper types and identifying if
messages can be processed directly.

See gh-81 (the ambiguity is still there, but the indirection bug
is fixed).
This commit is contained in:
Dave Syer
2017-07-11 17:37:45 +01:00
parent 18743fdf17
commit 4b30721d02
2 changed files with 70 additions and 1 deletions

View File

@@ -153,6 +153,7 @@ public class ContextFunctionCatalogAutoConfiguration {
private Set<String> suppliers = new HashSet<>(); private Set<String> suppliers = new HashSet<>();
private Set<String> functions = new HashSet<>(); private Set<String> functions = new HashSet<>();
private Set<String> consumers = new HashSet<>(); private Set<String> consumers = new HashSet<>();
private Map<String, String> beans = new HashMap<>();
private BeanDefinitionRegistry registry; private BeanDefinitionRegistry registry;
private ConversionService conversionService; private ConversionService conversionService;
@@ -178,7 +179,8 @@ public class ContextFunctionCatalogAutoConfiguration {
} }
Class<?> type = findInputType(name); Class<?> type = findInputType(name);
return conversionService.canConvert(String.class, type) return conversionService.canConvert(String.class, type)
? conversionService.convert(value, type) : value; ? conversionService.convert(value, type)
: value;
} }
public Set<FunctionRegistration<?>> merge( public Set<FunctionRegistration<?>> merge(
@@ -248,6 +250,9 @@ public class ContextFunctionCatalogAutoConfiguration {
private void wrap(FunctionRegistration<Object> registration, String key) { private void wrap(FunctionRegistration<Object> registration, String key) {
Object target = registration.getTarget(); Object target = registration.getTarget();
for (String name : registration.getNames()) {
beans.put(name, key);
}
if (target instanceof Supplier) { if (target instanceof Supplier) {
registration.target(target((Supplier<?>) target, key)); registration.target(target((Supplier<?>) target, key));
} }
@@ -529,6 +534,9 @@ public class ContextFunctionCatalogAutoConfiguration {
} }
private boolean isMessage(String name) { private boolean isMessage(String name) {
if (name != null) {
name = beans.get(name);
}
if (name == null || !registry.containsBeanDefinition(name)) { if (name == null || !registry.containsBeanDefinition(name)) {
return false; return false;
} }
@@ -542,6 +550,9 @@ public class ContextFunctionCatalogAutoConfiguration {
} }
private Class<?> findInputWrapper(String name) { private Class<?> findInputWrapper(String name) {
if (name != null) {
name = beans.get(name);
}
if (name == null || !registry.containsBeanDefinition(name)) { if (name == null || !registry.containsBeanDefinition(name)) {
return Object.class; return Object.class;
} }
@@ -551,6 +562,9 @@ public class ContextFunctionCatalogAutoConfiguration {
} }
private Class<?> findOutputWrapper(String name) { private Class<?> findOutputWrapper(String name) {
if (name != null) {
name = beans.get(name);
}
if (name == null || !registry.containsBeanDefinition(name)) { if (name == null || !registry.containsBeanDefinition(name)) {
return Object.class; return Object.class;
} }
@@ -560,6 +574,9 @@ public class ContextFunctionCatalogAutoConfiguration {
} }
private Class<?> findInputType(String name) { private Class<?> findInputType(String name) {
if (name != null) {
name = beans.get(name);
}
if (name == null || !registry.containsBeanDefinition(name)) { if (name == null || !registry.containsBeanDefinition(name)) {
return Object.class; return Object.class;
} }
@@ -569,6 +586,9 @@ public class ContextFunctionCatalogAutoConfiguration {
} }
private Class<?> findOutputType(String name) { private Class<?> findOutputType(String name) {
if (name != null) {
name = beans.get(name);
}
if (name == null || !registry.containsBeanDefinition(name)) { if (name == null || !registry.containsBeanDefinition(name)) {
return Object.class; return Object.class;
} }

View File

@@ -27,6 +27,7 @@ import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.junit.After; import org.junit.After;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
@@ -79,6 +80,18 @@ public class ContextFunctionCatalogAutoConfigurationTests {
assertThat(catalog.lookupFunction("function")).isInstanceOf(Function.class); assertThat(catalog.lookupFunction("function")).isInstanceOf(Function.class);
} }
@Test
@Ignore("see https://github.com/spring-cloud/spring-cloud-function/issues/81")
public void ambiguousFunction() {
create(AmbiguousConfiguration.class);
assertThat(context.getBean("foos")).isInstanceOf(Function.class);
assertThat(catalog.lookupFunction("foos")).isInstanceOf(Function.class);
assertThat(catalog.lookupConsumer("foos")).isInstanceOf(Consumer.class);
// Could be String or Foo
assertThat(inspector.getInputType("foos")).isEqualTo(Foo.class);
}
@Test @Test
public void genericFunction() { public void genericFunction() {
create(GenericConfiguration.class); create(GenericConfiguration.class);
@@ -194,6 +207,7 @@ public class ContextFunctionCatalogAutoConfigurationTests {
assertThat(context.getBean("function")).isInstanceOf(Function.class); assertThat(context.getBean("function")).isInstanceOf(Function.class);
assertThat(catalog.lookupFunction("function")).isNull(); assertThat(catalog.lookupFunction("function")).isNull();
assertThat(catalog.lookupFunction("other")).isInstanceOf(Function.class); assertThat(catalog.lookupFunction("other")).isInstanceOf(Function.class);
assertThat(inspector.getInputType("other")).isEqualTo(String.class);
} }
@Test @Test
@@ -308,6 +322,23 @@ public class ContextFunctionCatalogAutoConfigurationTests {
} }
} }
@EnableAutoConfiguration
@Configuration
protected static class AmbiguousConfiguration {
private List<Foo> list = new ArrayList<>();
@Bean
public Function<String, Foo> foos() {
return value -> new Foo(value.toUpperCase());
}
@Bean
@Qualifier("foos")
public Consumer<Foo> consumer() {
return value -> list.add(value);
}
}
@EnableAutoConfiguration @EnableAutoConfiguration
@Configuration @Configuration
protected static class GenericConfiguration { protected static class GenericConfiguration {
@@ -405,4 +436,22 @@ public class ContextFunctionCatalogAutoConfigurationTests {
} }
} }
public static class Foo {
private String value;
public Foo(String value) {
this.value = value;
}
Foo() {
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
} }