GH-1063 Fix header propagation in composed function

Resolves #1063
This commit is contained in:
Oleg Zhurakousky
2023-09-25 13:11:59 +02:00
parent 57355aad66
commit de9c4123a5
2 changed files with 32 additions and 0 deletions

View File

@@ -636,6 +636,7 @@ public class SimpleFunctionRegistry implements FunctionRegistry {
@Override
public <V> Function<Object, V> andThen(Function<? super Object, ? extends V> after) {
Assert.isTrue(after instanceof FunctionInvocationWrapper, "Composed function must be an instanceof FunctionInvocationWrapper.");
if (FunctionTypeUtils.isMultipleArgumentType(this.inputType)
|| FunctionTypeUtils.isMultipleArgumentType(this.outputType)
|| FunctionTypeUtils.isMultipleArgumentType(((FunctionInvocationWrapper) after).inputType)
@@ -643,6 +644,8 @@ public class SimpleFunctionRegistry implements FunctionRegistry {
throw new UnsupportedOperationException("Composition of functions with multiple arguments is not supported at the moment");
}
this.setSkipOutputConversion(true);
((FunctionInvocationWrapper) after).setSkipOutputConversion(true);
Function rawComposedFunction = v -> ((FunctionInvocationWrapper) after).doApply(doApply(v));
FunctionInvocationWrapper afterWrapper = (FunctionInvocationWrapper) after;

View File

@@ -59,6 +59,7 @@ import org.springframework.cloud.function.json.JacksonMapper;
import org.springframework.cloud.function.json.JsonMapper;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.ResolvableType;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
@@ -550,6 +551,14 @@ public class SimpleFunctionRegistryTests {
assertThat(FunctionTypeUtils.isMono(function.getOutputType()));
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testHeaderPropagationInComposedFunction() {
FunctionCatalog catalog = this.configureCatalog(GH_1063_Configuration.class);
Consumer function = catalog.lookup("uppercase|reverse|print");
function.accept("hello");
}
@Test
public void testFunctionCompositionWithReactiveSupplierAndConsumer() {
SimpleFunctionRegistry catalog = new SimpleFunctionRegistry(this.conversionService, this.messageConverter,
@@ -820,4 +829,24 @@ public class SimpleFunctionRegistryTests {
}
}
@EnableAutoConfiguration
@Configuration
public static class GH_1063_Configuration {
@Bean
Function<String, Message<String>> uppercase() {
return input -> MessageBuilder.withPayload(input).setHeader("FOO", "BAR").build();
}
@Bean
Function<String, String> reverse() {
return payload -> new StringBuilder(payload).reverse().toString();
}
@Bean
Consumer<Message<String>> print() {
return msg -> assertThat(msg.getHeaders().get("FOO")).isEqualTo("BAR");
}
}
}