GH-2035 Add autodetect property to give user control over function autodetection

Resolves #2035
This commit is contained in:
Oleg Zhurakousky
2021-03-19 16:07:51 +01:00
parent 872da6cfec
commit 3c77e89de7
3 changed files with 29 additions and 2 deletions

View File

@@ -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.

View File

@@ -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("")));
}
}

View File

@@ -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);