Removed duplication of fluxification logic

- Removed duplication of fluxification logic in FunctionRegistration and ContextFunctionCatalog.
- Polished FunctionRegistration.wrap logic
- Added initial javadoc
This commit is contained in:
Oleg Zhurakousky
2019-02-06 16:39:53 +01:00
parent 632b2bf6ab
commit 5b98c01d2a
2 changed files with 42 additions and 63 deletions

View File

@@ -34,6 +34,8 @@ import org.springframework.beans.factory.BeanNameAware;
import org.springframework.cloud.function.core.FluxConsumer; import org.springframework.cloud.function.core.FluxConsumer;
import org.springframework.cloud.function.core.FluxFunction; import org.springframework.cloud.function.core.FluxFunction;
import org.springframework.cloud.function.core.FluxSupplier; import org.springframework.cloud.function.core.FluxSupplier;
import org.springframework.cloud.function.core.FluxToMonoFunction;
import org.springframework.cloud.function.core.MonoToFluxFunction;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@@ -132,35 +134,48 @@ public class FunctionRegistration<T> implements BeanNameAware {
return this.names(Arrays.asList(names)); return this.names(Arrays.asList(names));
} }
/**
* Transforms (wraps) function identified by the 'target' to its {@code Flux}
* equivalent unless it already is. For example, {@code Function<String, String>}
* becomes {@code Function<Flux<String>, Flux<String>>}
* @param <S> the expected target type of the function (e.g., FluxFunction)
* @return {@code FunctionRegistration} with the appropriately wrapped target.
*
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public <S> FunctionRegistration<S> wrap() { public <S> FunctionRegistration<S> wrap() {
if (this.type == null || this.type.isWrapper()) { FunctionRegistration<S> result;
@SuppressWarnings("unchecked") if (this.type == null) {
FunctionRegistration<S> value = (FunctionRegistration<S>) this; result = (FunctionRegistration<S>) this;
return value;
} }
@SuppressWarnings("unchecked") else {
S target = (S) this.target; S target = (S) this.target;
FunctionRegistration<S> result = new FunctionRegistration<S>(target); result = new FunctionRegistration<S>(target);
result.type(this.type.getType()); result.type(this.type.getType());
if (target instanceof Function) { boolean flux = type.isWrapper();
@SuppressWarnings({ "unchecked", "rawtypes" }) if (!flux) {
S wrapped = (S) new FluxFunction((Function) target); if (target instanceof Function) {
target = wrapped; target = (S) new FluxFunction((Function<?, ?>) target);
result.type = result.type.wrap(Flux.class); }
else if (target instanceof Supplier) {
target = (S) new FluxSupplier((Supplier<?>) target);
}
else if (target instanceof Consumer) {
target = (S) new FluxConsumer((Consumer<?>) target);
}
}
if (Mono.class.isAssignableFrom(type.getOutputWrapper())) {
target = (S) new FluxToMonoFunction((Function) target);
}
else if (Mono.class.isAssignableFrom(type.getInputWrapper())) {
target = (S) new MonoToFluxFunction((Function) target);
}
result = result.target(target).names(this.names)
.type(result.type.wrap(Flux.class)).properties(this.properties);
} }
else if (target instanceof Supplier) {
@SuppressWarnings({ "unchecked", "rawtypes" }) return result;
S wrapped = (S) new FluxSupplier((Supplier) target);
target = wrapped;
result.type = result.type.wrap(Flux.class);
}
else if (target instanceof Consumer) {
@SuppressWarnings({ "unchecked", "rawtypes" })
S wrapped = (S) new FluxConsumer((Consumer) target);
target = wrapped;
result.type = result.type.wrap(Flux.class, Mono.class);
}
return result.target(target).names(this.names).properties(this.properties);
} }
@Override @Override

View File

@@ -62,7 +62,6 @@ import org.springframework.cloud.function.context.catalog.FunctionInspector;
import org.springframework.cloud.function.context.catalog.FunctionRegistrationEvent; import org.springframework.cloud.function.context.catalog.FunctionRegistrationEvent;
import org.springframework.cloud.function.context.catalog.FunctionUnregistrationEvent; import org.springframework.cloud.function.context.catalog.FunctionUnregistrationEvent;
import org.springframework.cloud.function.core.FluxConsumer; import org.springframework.cloud.function.core.FluxConsumer;
import org.springframework.cloud.function.core.FluxFunction;
import org.springframework.cloud.function.core.FluxSupplier; import org.springframework.cloud.function.core.FluxSupplier;
import org.springframework.cloud.function.core.FluxToMonoFunction; import org.springframework.cloud.function.core.FluxToMonoFunction;
import org.springframework.cloud.function.core.IsolatedConsumer; import org.springframework.cloud.function.core.IsolatedConsumer;
@@ -420,7 +419,7 @@ public class ContextFunctionCatalogAutoConfiguration {
registration.type(findType(target).getType()); registration.type(findType(target).getType());
} }
Class<?> type; Class<?> type;
registration = transform(registration); registration = isolated(registration).wrap();
target = registration.getTarget(); target = registration.getTarget();
if (target instanceof Supplier) { if (target instanceof Supplier) {
type = Supplier.class; type = Supplier.class;
@@ -450,41 +449,6 @@ public class ContextFunctionCatalogAutoConfiguration {
} }
} }
private FunctionRegistration<?> transform(FunctionRegistration<?> registration) {
return fluxify(isolated(registration));
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private FunctionRegistration<?> fluxify(FunctionRegistration<?> input) {
FunctionRegistration<Object> registration = (FunctionRegistration<Object>) input;
Object target = registration.getTarget();
FunctionType type = registration.getType();
boolean flux = hasFluxTypes(type);
if (!flux) {
if (target instanceof Supplier<?>) {
target = new FluxSupplier((Supplier<?>) target);
}
else if (target instanceof Function<?, ?>) {
target = new FluxFunction((Function<?, ?>) target);
}
else if (target instanceof Consumer<?>) {
target = new FluxConsumer((Consumer<?>) target);
}
registration.target(target);
}
if (Mono.class.isAssignableFrom(type.getOutputWrapper())) {
registration.target(new FluxToMonoFunction<>((Function) target));
}
else if (Mono.class.isAssignableFrom(type.getInputWrapper())) {
registration.target(new MonoToFluxFunction<>((Function) target));
}
return registration;
}
private boolean hasFluxTypes(FunctionType type) {
return type.isWrapper();
}
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
private FunctionRegistration<?> isolated(FunctionRegistration<?> input) { private FunctionRegistration<?> isolated(FunctionRegistration<?> input) {
FunctionRegistration<Object> registration = (FunctionRegistration<Object>) input; FunctionRegistration<Object> registration = (FunctionRegistration<Object>) input;