GH-2145 Add support for honoring SpEL on output payload in functions

Typically output type conversion would happen in s-c-function which is a bit too early for cases when user uses SpEL on the output payload (e.g., Rabbit routing-key)
This defers this type conversion

Resolves #2145
This commit is contained in:
Oleg Zhurakousky
2021-04-07 15:36:57 +02:00
parent 315028f461
commit b200d73b2d

View File

@@ -23,6 +23,8 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.cloud.function.context.FunctionCatalog;
import org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry.FunctionInvocationWrapper;
import org.springframework.cloud.stream.binder.BinderHeaders;
import org.springframework.cloud.stream.binder.ConsumerProperties;
import org.springframework.cloud.stream.binder.DefaultPollableMessageSource;
@@ -34,6 +36,7 @@ import org.springframework.cloud.stream.config.BindingProperties;
import org.springframework.cloud.stream.config.BindingServiceProperties;
import org.springframework.cloud.stream.converter.MessageConverterUtils;
import org.springframework.cloud.stream.function.StreamFunctionProperties;
import org.springframework.core.env.Environment;
import org.springframework.integration.channel.AbstractMessageChannel;
import org.springframework.integration.expression.ExpressionUtils;
import org.springframework.integration.support.MessageBuilderFactory;
@@ -152,13 +155,22 @@ public class MessageConverterConfigurer
}
}
Environment environment = this.beanFactory == null ? null : this.beanFactory.getBean(Environment.class);
ConsumerProperties consumerProperties = bindingProperties.getConsumer();
if (this.isNativeEncodingNotSet(producerProperties, consumerProperties, inbound)) {
if (inbound) {
messageChannel.addInterceptor(new InboundContentTypeEnhancingInterceptor(contentType));
}
else if (!functional) {
messageChannel.addInterceptor(new OutboundContentTypeConvertingInterceptor(contentType, this.compositeMessageConverter));
else {
if (environment != null && environment.containsProperty("spring.cloud.stream.rabbit.bindings." + channelName + ".producer.routing-key-expression")) {
FunctionCatalog catalog = this.beanFactory.getBean(FunctionCatalog.class);
FunctionInvocationWrapper function = catalog.lookup(this.streamFunctionProperties.getDefinition());
function.setSkipOutputConversion(true);
functional = false;
}
if (!functional) {
messageChannel.addInterceptor(new OutboundContentTypeConvertingInterceptor(contentType, this.compositeMessageConverter));
}
}
}
}