@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.cloud.function.context.config;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
@@ -34,12 +35,13 @@ import org.springframework.context.expression.MapAccessor;
|
||||
import org.springframework.expression.BeanResolver;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.DataBindingPropertyAccessor;
|
||||
import org.springframework.expression.spel.support.SimpleEvaluationContext;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
||||
/**
|
||||
* An implementation of Function which acts as a gateway/router by actually
|
||||
* delegating incoming invocation to a function specified .. .
|
||||
@@ -60,6 +62,9 @@ public class RoutingFunction implements Function<Object, Object> {
|
||||
|
||||
private final StandardEvaluationContext evalContext = new StandardEvaluationContext();
|
||||
|
||||
private final SimpleEvaluationContext headerEvalContext = SimpleEvaluationContext
|
||||
.forPropertyAccessors(DataBindingPropertyAccessor.forReadOnlyAccess()).build();
|
||||
|
||||
private final SpelExpressionParser spelParser = new SpelExpressionParser();
|
||||
|
||||
private final FunctionCatalog functionCatalog;
|
||||
@@ -72,6 +77,18 @@ public class RoutingFunction implements Function<Object, Object> {
|
||||
this(functionCatalog, functionProperties, null, null);
|
||||
}
|
||||
|
||||
public RoutingFunction(FunctionCatalog functionCatalog, Map<String, String> propertiesMap,
|
||||
BeanResolver beanResolver, MessageRoutingCallback routingCallback) {
|
||||
this(functionCatalog, extractIntoFunctionProperties(propertiesMap), beanResolver, routingCallback);
|
||||
}
|
||||
|
||||
private static FunctionProperties extractIntoFunctionProperties(Map<String, String> propertiesMap) {
|
||||
FunctionProperties functionProperties = new FunctionProperties();
|
||||
functionProperties.setDefinition(propertiesMap.get(FunctionProperties.FUNCTION_DEFINITION));
|
||||
functionProperties.setRoutingExpression(propertiesMap.get(FunctionProperties.PREFIX + ".routing-expression"));
|
||||
return functionProperties;
|
||||
}
|
||||
|
||||
public RoutingFunction(FunctionCatalog functionCatalog, FunctionProperties functionProperties,
|
||||
BeanResolver beanResolver, MessageRoutingCallback routingCallback) {
|
||||
this.functionCatalog = functionCatalog;
|
||||
@@ -124,7 +141,7 @@ public class RoutingFunction implements Function<Object, Object> {
|
||||
}
|
||||
}
|
||||
else if (StringUtils.hasText((String) message.getHeaders().get("spring.cloud.function.routing-expression"))) {
|
||||
function = this.functionFromExpression((String) message.getHeaders().get("spring.cloud.function.routing-expression"), message);
|
||||
function = this.functionFromExpression((String) message.getHeaders().get("spring.cloud.function.routing-expression"), message, true);
|
||||
if (function.isInputTypePublisher()) {
|
||||
this.assertOriginalInputIsNotPublisher(originalInputIsPublisher);
|
||||
}
|
||||
@@ -193,12 +210,16 @@ public class RoutingFunction implements Function<Object, Object> {
|
||||
}
|
||||
|
||||
private FunctionInvocationWrapper functionFromExpression(String routingExpression, Object input) {
|
||||
return functionFromExpression(routingExpression, input, false);
|
||||
}
|
||||
|
||||
private FunctionInvocationWrapper functionFromExpression(String routingExpression, Object input, boolean isViaHeader) {
|
||||
Expression expression = spelParser.parseExpression(routingExpression);
|
||||
if (input instanceof Message) {
|
||||
input = MessageUtils.toCaseInsensitiveHeadersStructure((Message<?>) input);
|
||||
}
|
||||
|
||||
String functionName = expression.getValue(this.evalContext, input, String.class);
|
||||
String functionName = isViaHeader ? expression.getValue(this.headerEvalContext, input, String.class) : expression.getValue(this.evalContext, input, String.class);
|
||||
Assert.hasText(functionName, "Failed to resolve function name based on routing expression '" + functionProperties.getRoutingExpression() + "'");
|
||||
FunctionInvocationWrapper function = functionCatalog.lookup(functionName);
|
||||
Assert.notNull(function, "Failed to lookup function to route to based on the expression '"
|
||||
|
||||
Reference in New Issue
Block a user