From ad7bf9563f48e97c1b5e43e36561c69295dc4b92 Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Mon, 2 Mar 2020 09:58:36 +0100 Subject: [PATCH] GH-1919 Fix function+consumer composition Ensured that when composing Function and Consumer no output binding is created. The initila fix was part of #1911 which addressed the reactive function/consumer combination. This fix does the same for imperative function/consumer combination Resolves #1919 --- .../function/FunctionConfiguration.java | 9 ++++++--- .../ImplicitFunctionBindingTests.java | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FunctionConfiguration.java b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FunctionConfiguration.java index 8b1eaeab9..210132a41 100644 --- a/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FunctionConfiguration.java +++ b/spring-cloud-stream/src/main/java/org/springframework/cloud/stream/function/FunctionConfiguration.java @@ -657,9 +657,12 @@ public class FunctionConfiguration { int outputCount = FunctionTypeUtils.getOutputCount(functionType); if (!isSupplier && functionType instanceof ParameterizedType) { Type outputType = ((ParameterizedType) functionType).getActualTypeArguments()[1]; - if (FunctionTypeUtils.isMono(outputType) && outputType instanceof ParameterizedType - && ((ParameterizedType) outputType).getActualTypeArguments()[0].getTypeName().endsWith("Void")) { - this.outputCount = 0; + if (FunctionTypeUtils.isOfType(outputType, Mono.class) && outputType instanceof ParameterizedType + && FunctionTypeUtils.isOfType(((ParameterizedType) outputType).getActualTypeArguments()[0], Void.class)) { + outputCount = 0; + } + else if (FunctionTypeUtils.isOfType(outputType, Void.class)) { + outputCount = 0; } } return outputCount; diff --git a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/ImplicitFunctionBindingTests.java b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/ImplicitFunctionBindingTests.java index 6175a6fd4..f216bc46c 100644 --- a/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/ImplicitFunctionBindingTests.java +++ b/spring-cloud-stream/src/test/java/org/springframework/cloud/stream/function/ImplicitFunctionBindingTests.java @@ -280,6 +280,24 @@ public class ImplicitFunctionBindingTests { } } + @Test + public void fooFunctionComposedWithConsumerNoOutputChannel() { + System.clearProperty("spring.cloud.function.definition"); + try (ConfigurableApplicationContext context = new SpringApplicationBuilder( + TestChannelBinderConfiguration.getCompleteConfiguration(ReactiveFunctionConfiguration.class, SingleReactiveConsumerConfiguration.class)) + .web(WebApplicationType.NONE).run("--spring.jmx.enabled=false", "--spring.cloud.function.definition=echo|consumer")) { + + assertThat(context.containsBean("echoconsumer-out-0")).isFalse(); + + InputDestination inputDestination = context.getBean(InputDestination.class); + Message inputMessage = MessageBuilder.withPayload("Hello".getBytes()).build(); + inputDestination.send(inputMessage); + + assertThat(System.getProperty("consumer")).isEqualTo("Hello"); + System.clearProperty("consumer"); + } + } + @Test public void testReactiveConsumerWithoutDefinitionProperty() { System.clearProperty("spring.cloud.function.definition"); @@ -685,6 +703,7 @@ public class ImplicitFunctionBindingTests { TestChannelBinderConfiguration.getCompleteConfiguration(FunctionalConsumerConfiguration.class)) .web(WebApplicationType.NONE).run("--spring.jmx.enabled=false")) { + assertThat(context.containsBean("funcConsumer-out-0")).isFalse(); InputDestination inputDestination = context.getBean(InputDestination.class); Message inputMessage = MessageBuilder.withPayload("Hello".getBytes()).build(); inputDestination.send(inputMessage);