From 49ccc9ff7fbbf804bfb7f720576b2e0ec1859967 Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Thu, 18 Nov 2021 13:29:07 +0100 Subject: [PATCH] GH-727 Fix Azure's Supplier logic to avoid NPE Resolves #727 --- .../adapter/azure/FunctionInvoker.java | 24 ++++++++++------- .../adapter/azure/FunctionInvokerTests.java | 26 +++++++++++++++++++ 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/main/java/org/springframework/cloud/function/adapter/azure/FunctionInvoker.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/main/java/org/springframework/cloud/function/adapter/azure/FunctionInvoker.java index a60494169..e714d0cc1 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/main/java/org/springframework/cloud/function/adapter/azure/FunctionInvoker.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/main/java/org/springframework/cloud/function/adapter/azure/FunctionInvoker.java @@ -111,7 +111,11 @@ public class FunctionInvoker { public O handleRequest(I input, ExecutionContext executionContext) { String functionDefinition = executionContext.getFunctionName(); 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); function = FUNCTION_CATALOG.lookup(functionDefinition); } @@ -129,7 +133,7 @@ public class FunctionInvoker { resultList.addAll((Collection) resultItem); } 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()))) { return (O) this.convertOutputIfNecessary(input, resultItem); } @@ -146,15 +150,17 @@ public class FunctionInvoker { @SuppressWarnings({ "unchecked", "rawtypes" }) private void registerFunction(String functionDefinition) { - FunctionRegistration functionRegistration = - new FunctionRegistration(APPLICATION_CONTEXT.getBean(functionDefinition), functionDefinition); + if (APPLICATION_CONTEXT.containsBean(functionDefinition)) { + FunctionRegistration functionRegistration = + new FunctionRegistration(APPLICATION_CONTEXT.getBean(functionDefinition), functionDefinition); - Type type = FunctionContextUtils. - findType(functionDefinition, APPLICATION_CONTEXT.getBeanFactory()); + Type type = FunctionContextUtils. + 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" }) @@ -187,7 +193,7 @@ public class FunctionInvoker { @SuppressWarnings("unchecked") private Object convertOutputIfNecessary(Object input, Object output) { - if (input != null && input instanceof HttpRequestMessage) { + if (input instanceof HttpRequestMessage) { HttpRequestMessage requestMessage = (HttpRequestMessage) input; Map headers = null; if (output instanceof Message) { diff --git a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/FunctionInvokerTests.java b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/FunctionInvokerTests.java index 1f31d49ce..cc024d7ea 100644 --- a/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/FunctionInvokerTests.java +++ b/spring-cloud-function-adapters/spring-cloud-function-adapter-azure/src/test/java/org/springframework/cloud/function/adapter/azure/FunctionInvokerTests.java @@ -134,6 +134,16 @@ public class FunctionInvokerTests { assertThat(result.toString()).isEqualTo("[foo1, foo2]"); } + @Test + public void supplierPublisherBean() { + FunctionInvoker handler = handler(ReactiveSupplierConfig.class); + Foo resultSingle = (Foo) handler.handleRequest(new TestExecutionContext("suppliermono")); + assertThat(resultSingle.getValue()).isEqualTo("hello"); + + List resultList = (List) handler.handleRequest(new TestExecutionContext("supplierflux")); + assertThat(resultList.size()).isEqualTo(2); + } + private static String consumerResult; @Test @@ -209,6 +219,22 @@ public class FunctionInvokerTests { } + @Configuration +// @EnableAutoConfiguration + protected static class ReactiveSupplierConfig { + + @Bean + public Supplier> suppliermono() { + return () -> Mono.just(new Foo("hello")); + } + + @Bean + public Supplier> supplierflux() { + return () -> Flux.just(new Foo("hello"), new Foo("bye")); + } + + } + @Configuration protected static class BareConfig {