diff --git a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/SimpleFunctionRegistry.java b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/SimpleFunctionRegistry.java index 18737a1da..3b6e08e5d 100644 --- a/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/SimpleFunctionRegistry.java +++ b/spring-cloud-function-context/src/main/java/org/springframework/cloud/function/context/catalog/SimpleFunctionRegistry.java @@ -822,7 +822,7 @@ public class SimpleFunctionRegistry implements FunctionRegistry, FunctionInspect convertedValue = value; } if (value instanceof Message) { // see AWS adapter with Optional payload - if (messageNeedsConversion(rawType, (Message) value)) { + if (messageNeedsConversion(rawType, type, (Message) value)) { boolean convertWithHint = false; Type hint = type; @@ -956,13 +956,24 @@ public class SimpleFunctionRegistry implements FunctionRegistry, FunctionInspect return false; } - private boolean messageNeedsConversion(Type rawType, Message message) { + private boolean messageNeedsConversion(Type rawType, Type type, Message message) { Boolean skipConversion = message.getHeaders().containsKey(FunctionProperties.SKIP_CONVERSION_HEADER) ? message.getHeaders().get(FunctionProperties.SKIP_CONVERSION_HEADER, Boolean.class) : false; if (skipConversion) { return false; } + + if (FunctionTypeUtils.isTypeCollection(message.getPayload().getClass()) + && !CollectionUtils.isEmpty((Collection) message.getPayload())) { + + Class elementType = CollectionUtils.findCommonElementType((Collection) message.getPayload()); + Class itemType = TypeResolver.resolveRawClass(FunctionTypeUtils.getImmediateGenericType(type, 0), null); + if (elementType == itemType) { + return false; + } + } + return rawType instanceof Class && !(message.getPayload() instanceof Optional) && !this.payloadIsSpecialType(message.getPayload()) diff --git a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/userissues/UserIssuesTests.java b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/userissues/UserIssuesTests.java index 75ba98c11..544a91558 100644 --- a/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/userissues/UserIssuesTests.java +++ b/spring-cloud-function-context/src/test/java/org/springframework/cloud/function/userissues/UserIssuesTests.java @@ -17,14 +17,17 @@ package org.springframework.cloud.function.userissues; import java.lang.reflect.Type; +import java.util.ArrayList; import java.util.List; import java.util.function.Function; import org.junit.Before; import org.junit.Test; + import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.cloud.function.context.FunctionCatalog; +import org.springframework.cloud.function.context.catalog.FunctionTypeUtils; import org.springframework.cloud.function.json.JsonMapper; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; @@ -61,6 +64,37 @@ public class UserIssuesTests { int result = function.apply( new GenericMessage("[{\"name\":\"julien\"},{\"name\":\"ricky\"},{\"name\":\"bubbles\"}]")); assertThat(result).isEqualTo(3); + } + + @Test + public void testIssue602asPOJO() throws Exception { + FunctionCatalog catalog = this.configureCatalog(Issue602Configuration.class); + Function>, Integer> function = catalog.lookup("consumer"); + ArrayList products = new ArrayList<>(); + Product p = new Product(); + p.setName("julien"); + products.add(p); + p = new Product(); + p.setName("ricky"); + products.add(p); + p = new Product(); + p.setName("bubbles"); + products.add(p); + int result = function.apply(new GenericMessage>(products)); + assertThat(result).isEqualTo(3); + + } + + @Test + public void testIssue602asCollectionOfUnconvertedItems() throws Exception { + FunctionCatalog catalog = this.configureCatalog(Issue602Configuration.class); + Function>, Integer> function = catalog.lookup("consumer"); + ArrayList products = new ArrayList<>(); + products.add("{\"name\":\"julien\"}"); + products.add("{\"name\":\"ricky\"}"); + products.add("{\"name\":\"bubbles\"}"); + int result = function.apply(new GenericMessage>(products)); + assertThat(result).isEqualTo(3); } @@ -105,6 +139,9 @@ public class UserIssuesTests { @Override protected boolean canConvertFrom(Message message, Class targetClass) { + if (!FunctionTypeUtils.isTypeCollection(message.getPayload().getClass())) { + return false; + } return true; }