From 59fe298b67fcb9249db727a7b3a33612fc7a9f75 Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Mon, 29 Apr 2024 16:56:45 +0200 Subject: [PATCH] GH-1139 Fix function composition with non-existing functions Resolves #1139 --- .../BeanFactoryAwareFunctionRegistry.java | 7 +++--- ...BeanFactoryAwareFunctionRegistryTests.java | 25 +++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistry.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistry.java index e62b8a8b6..468e277c2 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistry.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistry.java @@ -144,11 +144,12 @@ public class BeanFactoryAwareFunctionRegistry extends SimpleFunctionRegistry imp Set functionRegistratioinNames = super.getNames(null); String[] functionNames = StringUtils.delimitedListToStringArray(functionDefinition.replaceAll(",", "|").trim(), "|"); for (String functionName : functionNames) { - if (functionRegistratioinNames.contains(functionName) && logger.isDebugEnabled()) { - logger.debug("Skipping function '" + functionName + "' since it is already present"); + if (functionRegistratioinNames.contains(functionName)) { + if (logger.isDebugEnabled()) { + logger.debug("Skipping function '" + functionName + "' since it is already present"); + } } else { - Object functionCandidate = this.discoverFunctionInBeanFactory(functionName); if (functionCandidate != null) { Type functionType = null; diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistryTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistryTests.java index e39d71f29..49ab2baa7 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistryTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/catalog/BeanFactoryAwareFunctionRegistryTests.java @@ -29,6 +29,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @@ -115,6 +116,30 @@ public class BeanFactoryAwareFunctionRegistryTests { assertThat(result).isEqualTo("{}"); } + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Test + public void testCompositionWithNonExistingFunction() throws Exception { + FunctionCatalog catalog = this.configureCatalog(CompositionWithNullReturnInBetween.class); + for (int i = 0; i < 10; i++) { + catalog.lookup("echo1|any"); + } + Field functionRegistrationsField = ReflectionUtils.findField(catalog.getClass(), "functionRegistrations"); + functionRegistrationsField.setAccessible(true); + Set functionRegistrations = (Set) functionRegistrationsField.get(catalog); + assertThat(functionRegistrations.size()).isEqualTo(1); + FunctionRegistration registration = functionRegistrations.iterator().next(); + assertThat(registration.getNames().size()).isEqualTo(1); + assertThat(registration.getNames().iterator().next()).isEqualTo("echo1"); + + for (int i = 0; i < 10; i++) { + catalog.lookup("echo1|any|foo|bar|bye"); + } + assertThat(functionRegistrations.size()).isEqualTo(1); + registration = functionRegistrations.iterator().next(); + assertThat(registration.getNames().size()).isEqualTo(1); + assertThat(registration.getNames().iterator().next()).isEqualTo("echo1"); + } + @SuppressWarnings({ "rawtypes", "unchecked" }) @Test public void testCompositionWithNullReturnInBetween() {