Ensure a function is inspectable as itself and its wrapper

Since a function is wrapper in a FluxWrapper (and possibly also
an Isolated), the link is lost between the bean and the type
metadata without this change.
This commit is contained in:
Dave Syer
2018-03-01 09:10:14 +00:00
parent 955e99bfe3
commit dc008cc24d
4 changed files with 100 additions and 12 deletions

View File

@@ -107,4 +107,5 @@ public class FunctionRegistration<T> {
public FunctionRegistration<T> names(String... names) {
return this.names(Arrays.asList(names));
}
}

View File

@@ -39,10 +39,34 @@ public class FunctionType {
public static FunctionType UNCLASSIFIED = new FunctionType(ResolvableType
.forClassWithGenerics(Function.class, Object.class, Object.class).getType());
private Type type;
final private Type type;
final private Class<?> inputType;
final private Class<?> outputType;
final private Class<?> inputWrapper;
final private Class<?> outputWrapper;
final private boolean message;
public FunctionType(Type type) {
this.type = type;
this.inputWrapper = findType(ParamType.INPUT_WRAPPER);
this.outputWrapper = findType(ParamType.OUTPUT_WRAPPER);
this.inputType = findType(ParamType.INPUT);
this.outputType = findType(ParamType.OUTPUT);
this.message = messageType();
}
private boolean messageType() {
Class<?> inputType = findType(ParamType.INPUT_INNER_WRAPPER);
Class<?> outputType = findType(ParamType.OUTPUT_INNER_WRAPPER);
return inputType.getName().startsWith(Message.class.getName())
|| Message.class.isAssignableFrom(inputType)
|| outputType.getName().startsWith(Message.class.getName())
|| Message.class.isAssignableFrom(outputType);
}
public Type getType() {
@@ -50,28 +74,23 @@ public class FunctionType {
}
public Class<?> getInputWrapper() {
return findType(ParamType.INPUT_WRAPPER);
return inputWrapper;
}
public Class<?> getOutputWrapper() {
return findType(ParamType.OUTPUT_WRAPPER);
return outputWrapper;
}
public Class<?> getInputType() {
return findType(ParamType.INPUT);
return inputType;
}
public Class<?> getOutputType() {
return findType(ParamType.OUTPUT);
return outputType;
}
public boolean isMessage() {
Class<?> inputType = findType(ParamType.INPUT_INNER_WRAPPER);
Class<?> outputType = findType(ParamType.OUTPUT_INNER_WRAPPER);
return inputType.getName().startsWith(Message.class.getName())
|| Message.class.isAssignableFrom(inputType)
|| outputType.getName().startsWith(Message.class.getName())
|| Message.class.isAssignableFrom(outputType);
return message;
}
public boolean isWrapper() {
@@ -279,6 +298,60 @@ public class FunctionType {
return param;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((inputType == null) ? 0 : inputType.toString().hashCode());
result = prime * result
+ ((inputWrapper == null) ? 0 : inputWrapper.toString().hashCode());
result = prime * result + (message ? 1231 : 1237);
result = prime * result
+ ((outputType == null) ? 0 : outputType.toString().hashCode());
result = prime * result
+ ((outputWrapper == null) ? 0 : outputWrapper.toString().hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
FunctionType other = (FunctionType) obj;
if (inputType == null) {
if (other.inputType != null)
return false;
}
else if (!inputType.toString().equals(other.inputType.toString()))
return false;
if (inputWrapper == null) {
if (other.inputWrapper != null)
return false;
}
else if (!inputWrapper.toString().equals(other.inputWrapper.toString()))
return false;
if (message != other.message)
return false;
if (outputType == null) {
if (other.outputType != null)
return false;
}
else if (!outputType.toString().equals(other.outputType.toString()))
return false;
if (outputWrapper == null) {
if (other.outputWrapper != null)
return false;
}
else if (!outputWrapper.toString().equals(other.outputWrapper.toString()))
return false;
return true;
}
enum ParamType {
INPUT, OUTPUT, INPUT_WRAPPER, OUTPUT_WRAPPER, INPUT_INNER_WRAPPER, OUTPUT_INNER_WRAPPER;

View File

@@ -425,7 +425,7 @@ public class ContextFunctionCatalogAutoConfiguration {
else {
return;
}
this.names.remove(target);
// this.names.remove(target);
this.names.put(registration.getTarget(), key);
if (publisher != null) {
publisher.publishEvent(new FunctionRegistrationEvent(

View File

@@ -331,6 +331,20 @@ public class ContextFunctionCatalogAutoConfigurationTests {
}
}
@Test
public void simpleFunction() {
create(SimpleConfiguration.class);
Object bean = context.getBean("function");
assertThat(bean).isInstanceOf(Function.class);
Function<Flux<String>, Flux<String>> function = catalog.lookup(Function.class,
"function");
assertThat(function.apply(Flux.just("foo")).blockFirst()).isEqualTo("FOO");
assertThat(bean).isNotSameAs(function);
assertThat(inspector.getRegistration(bean)).isNotNull();
assertThat(inspector.getRegistration(bean).getType())
.isEqualTo(inspector.getRegistration(function).getType());
}
@Test
public void simpleSupplier() {
create(SimpleConfiguration.class);