diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/RoutingFunction.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/RoutingFunction.java index dd6b965b3..564836968 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/RoutingFunction.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/config/RoutingFunction.java @@ -16,6 +16,8 @@ package org.springframework.cloud.function.context.config; +import java.util.Map; +import java.util.TreeMap; import java.util.function.Function; import org.apache.commons.logging.Log; @@ -193,6 +195,10 @@ public class RoutingFunction implements Function { private FunctionInvocationWrapper functionFromExpression(String routingExpression, Object input) { Expression expression = spelParser.parseExpression(routingExpression); + if (input instanceof Message) { + input = new MessageStructureWithCaseInsensitiveHeaderKeys((Message) input); + } + String functionName = 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); @@ -203,4 +209,24 @@ public class RoutingFunction implements Function { } return function; } + + @SuppressWarnings({"rawtypes", "unused"}) + private static class MessageStructureWithCaseInsensitiveHeaderKeys { + private final Object payload; + private final Map headers; + + @SuppressWarnings("unchecked") + MessageStructureWithCaseInsensitiveHeaderKeys(Message message) { + this.payload = message.getPayload(); + this.headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + this.headers.putAll(message.getHeaders()); + } + public Object getPayload() { + return payload; + } + + public Map getHeaders() { + return headers; + } + } } diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/RoutingFunctionTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/RoutingFunctionTests.java index cb9267b91..d3ef8210c 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/RoutingFunctionTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/context/config/RoutingFunctionTests.java @@ -134,6 +134,20 @@ public class RoutingFunctionTests { assertThat(function.apply(message)).isEqualTo("olleh"); } + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Test + public void testInvocationWithMessageAndRoutingExpressionCaseInsensitive() { + System.setProperty(FunctionProperties.PREFIX + ".routing-expression", "headers.function_Name"); + FunctionCatalog functionCatalog = this.configureCatalog(); + Function function = functionCatalog.lookup(RoutingFunction.FUNCTION_NAME); + assertThat(function).isNotNull(); + Message message = MessageBuilder.withPayload("hello").setHeader("function_name", "reverse").build(); + assertThat(function.apply(message)).isEqualTo("olleh"); + + System.setProperty(FunctionProperties.PREFIX + ".routing-expression", "headers.FunCtion_namE"); + assertThat(function.apply(message)).isEqualTo("olleh"); + } + @SuppressWarnings({ "rawtypes", "unchecked" }) @Test public void testInvocationWithRoutingBeanExpression() {