GH-727 Fix Azure's Supplier<Publisher> logic to avoid NPE

Resolves #727
This commit is contained in:
Oleg Zhurakousky
2021-11-18 13:29:07 +01:00
parent 4f17065cad
commit 49ccc9ff7f
2 changed files with 41 additions and 9 deletions

View File

@@ -111,7 +111,11 @@ public class FunctionInvoker<I, O> {
public O handleRequest(I input, ExecutionContext executionContext) { public O handleRequest(I input, ExecutionContext executionContext) {
String functionDefinition = executionContext.getFunctionName(); String functionDefinition = executionContext.getFunctionName();
FunctionInvocationWrapper function = FUNCTION_CATALOG.lookup(functionDefinition); FunctionInvocationWrapper function = FUNCTION_CATALOG.lookup(functionDefinition);
if (function == null && StringUtils.hasText(functionDefinition) && APPLICATION_CONTEXT.containsBean(functionDefinition)) { if (function != null && StringUtils.hasText(functionDefinition) && !function.getFunctionDefinition().equals(functionDefinition)) {
this.registerFunction(functionDefinition);
function = FUNCTION_CATALOG.lookup(functionDefinition);
}
else if (function == null && StringUtils.hasText(functionDefinition) && APPLICATION_CONTEXT.containsBean(functionDefinition)) {
this.registerFunction(functionDefinition); this.registerFunction(functionDefinition);
function = FUNCTION_CATALOG.lookup(functionDefinition); function = FUNCTION_CATALOG.lookup(functionDefinition);
} }
@@ -129,7 +133,7 @@ public class FunctionInvoker<I, O> {
resultList.addAll((Collection) resultItem); resultList.addAll((Collection) resultItem);
} }
else { else {
if (Collection.class.isAssignableFrom(FunctionTypeUtils.getRawType(function.getInputType())) if (!function.isSupplier() && Collection.class.isAssignableFrom(FunctionTypeUtils.getRawType(function.getInputType()))
&& !Collection.class.isAssignableFrom(FunctionTypeUtils.getRawType(function.getOutputType()))) { && !Collection.class.isAssignableFrom(FunctionTypeUtils.getRawType(function.getOutputType()))) {
return (O) this.convertOutputIfNecessary(input, resultItem); return (O) this.convertOutputIfNecessary(input, resultItem);
} }
@@ -146,15 +150,17 @@ public class FunctionInvoker<I, O> {
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
private void registerFunction(String functionDefinition) { private void registerFunction(String functionDefinition) {
FunctionRegistration functionRegistration = if (APPLICATION_CONTEXT.containsBean(functionDefinition)) {
new FunctionRegistration(APPLICATION_CONTEXT.getBean(functionDefinition), functionDefinition); FunctionRegistration functionRegistration =
new FunctionRegistration(APPLICATION_CONTEXT.getBean(functionDefinition), functionDefinition);
Type type = FunctionContextUtils. Type type = FunctionContextUtils.
findType(functionDefinition, APPLICATION_CONTEXT.getBeanFactory()); findType(functionDefinition, APPLICATION_CONTEXT.getBeanFactory());
functionRegistration = functionRegistration.type(new FunctionType(type)); functionRegistration = functionRegistration.type(new FunctionType(type));
((FunctionRegistry) FUNCTION_CATALOG).register(functionRegistration); ((FunctionRegistry) FUNCTION_CATALOG).register(functionRegistration);
}
} }
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
@@ -187,7 +193,7 @@ public class FunctionInvoker<I, O> {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private Object convertOutputIfNecessary(Object input, Object output) { private Object convertOutputIfNecessary(Object input, Object output) {
if (input != null && input instanceof HttpRequestMessage) { if (input instanceof HttpRequestMessage) {
HttpRequestMessage<I> requestMessage = (HttpRequestMessage<I>) input; HttpRequestMessage<I> requestMessage = (HttpRequestMessage<I>) input;
Map<String, Object> headers = null; Map<String, Object> headers = null;
if (output instanceof Message) { if (output instanceof Message) {

View File

@@ -134,6 +134,16 @@ public class FunctionInvokerTests {
assertThat(result.toString()).isEqualTo("[foo1, foo2]"); assertThat(result.toString()).isEqualTo("[foo1, foo2]");
} }
@Test
public void supplierPublisherBean() {
FunctionInvoker<Void, ?> handler = handler(ReactiveSupplierConfig.class);
Foo resultSingle = (Foo) handler.handleRequest(new TestExecutionContext("suppliermono"));
assertThat(resultSingle.getValue()).isEqualTo("hello");
List<Foo> resultList = (List<Foo>) handler.handleRequest(new TestExecutionContext("supplierflux"));
assertThat(resultList.size()).isEqualTo(2);
}
private static String consumerResult; private static String consumerResult;
@Test @Test
@@ -209,6 +219,22 @@ public class FunctionInvokerTests {
} }
@Configuration
// @EnableAutoConfiguration
protected static class ReactiveSupplierConfig {
@Bean
public Supplier<Mono<Foo>> suppliermono() {
return () -> Mono.just(new Foo("hello"));
}
@Bean
public Supplier<Flux<Foo>> supplierflux() {
return () -> Flux.just(new Foo("hello"), new Foo("bye"));
}
}
@Configuration @Configuration
protected static class BareConfig { protected static class BareConfig {