From 3c77e89de72c35ef92a8b06803c20fd1077c4a69 Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Fri, 19 Mar 2021 16:07:51 +0100 Subject: [PATCH] GH-2035 Add autodetect property to give user control over function autodetection Resolves #2035 --- .../main/asciidoc/spring-cloud-stream.adoc | 3 +++ .../function/FunctionConfiguration.java | 7 ++++++- .../ImplicitFunctionBindingTests.java | 21 ++++++++++++++++++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/docs/src/main/asciidoc/spring-cloud-stream.adoc b/docs/src/main/asciidoc/spring-cloud-stream.adoc index a520d2ca5..ef517f2a2 100644 --- a/docs/src/main/asciidoc/spring-cloud-stream.adoc +++ b/docs/src/main/asciidoc/spring-cloud-stream.adoc @@ -358,6 +358,9 @@ you must provide `spring.cloud.function.definition` property. NOTE: In the event you only have single bean of type `java.util.function.[Supplier/Function/Consumer]`, you can skip the `spring.cloud.function.definition` property, since such functional bean will be auto-discovered. However, it is considered best practice to use such property to avoid any confusion. +Some time this auto-discovery can get in the way, since single bean of type `java.util.function.[Supplier/Function/Consumer]` +could be there for purposes other then handling messages, yet being single it is auto-discovered and auto-bound. +For these rare scenarios you can disable auto-discovery by providing `spring.cloud.stream.function.autodetect` property with value set to `false`. Here is the example of the application exposing message handler as `java.util.function.Function` effectively supporting _pass-thru_ semantics by acting as consumer and producer of data. 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 c3e31c5cf..a045b2d72 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 @@ -760,7 +760,12 @@ public class FunctionConfiguration { return outputCount; } + private void determineFunctionName(FunctionCatalog catalog, Environment environment) { +//======= +// private boolean determineFunctionName(FunctionCatalog catalog, Environment environment) { + boolean autodetect = environment.getProperty("spring.cloud.stream.function.autodetect", boolean.class, true); +//>>>>>>> 9db08ec6... GH-2035 Add autodetect property to give user control over function autodetection String definition = streamFunctionProperties.getDefinition(); if (!StringUtils.hasText(definition)) { definition = environment.getProperty("spring.cloud.function.definition"); @@ -773,7 +778,7 @@ public class FunctionConfiguration { || environment.containsProperty("spring.cloud.function.routing-expression")) { streamFunctionProperties.setDefinition(RoutingFunction.FUNCTION_NAME); } - else { + else if (autodetect) { streamFunctionProperties.setDefinition(((FunctionInspector) functionCatalog).getName(functionCatalog.lookup(""))); } } 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 093b7a73f..db3802855 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 @@ -79,6 +79,23 @@ public class ImplicitFunctionBindingTests { System.clearProperty("spring.cloud.function.definition"); } + @SuppressWarnings({"rawtypes" }) + @Test + public void testDisableAutodetect() { + try (ConfigurableApplicationContext context = new SpringApplicationBuilder( + TestChannelBinderConfiguration.getCompleteConfiguration(SendToDestinationConfiguration.class)) + .web(WebApplicationType.NONE) + .run("--spring.jmx.enabled=false", "--spring.cloud.stream.function.autodetect=false")) { + + BindingsLifecycleController ctrl = context.getBean(BindingsLifecycleController.class); + Binding input = ctrl.queryState("echo-in-0"); + Binding output = ctrl.queryState("echo-out-0"); + assertThat(input).isNull(); + assertThat(output).isNull(); + } + } + + @SuppressWarnings({"rawtypes" }) @Test public void testBindingControl() { @@ -214,7 +231,9 @@ public class ImplicitFunctionBindingTests { try (ConfigurableApplicationContext context = new SpringApplicationBuilder( TestChannelBinderConfiguration.getCompleteConfiguration(NoEnableBindingConfiguration.class)) .web(WebApplicationType.NONE) - .run("--spring.jmx.enabled=false", "--spring.cloud.function.definition=func|addHeaders")) { + .run("--spring.jmx.enabled=false", + "--spring.cloud.stream.function.autodetect=false", + "--spring.cloud.function.definition=func|addHeaders")) { InputDestination inputDestination = context.getBean(InputDestination.class); OutputDestination outputDestination = context.getBean(OutputDestination.class);