Fix to-Message conversion logic

Fixed  logic to ensure that for cases where user may return a Message with no contentType set, the property-set content type is propagated
This commit is contained in:
Oleg Zhurakousky
2020-02-22 08:24:27 +01:00
parent 9eb98bd545
commit f4530e0d89
2 changed files with 22 additions and 15 deletions

View File

@@ -16,13 +16,13 @@
package org.springframework.cloud.function.context.catalog; package org.springframework.cloud.function.context.catalog;
import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
@@ -79,6 +79,7 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.MimeType; import org.springframework.util.MimeType;
import org.springframework.util.MimeTypeUtils; import org.springframework.util.MimeTypeUtils;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@@ -466,12 +467,16 @@ public class BeanFactoryAwareFunctionRegistry
private final String functionDefinition; private final String functionDefinition;
private final Field headersField;
FunctionInvocationWrapper(Object target, Type functionType, String functionDefinition, String... acceptedOutputMimeTypes) { FunctionInvocationWrapper(Object target, Type functionType, String functionDefinition, String... acceptedOutputMimeTypes) {
this.target = target; this.target = target;
this.composed = functionDefinition.contains("|") || target instanceof RoutingFunction; this.composed = functionDefinition.contains("|") || target instanceof RoutingFunction;
this.functionType = functionType; this.functionType = functionType;
this.acceptedOutputMimeTypes = acceptedOutputMimeTypes; this.acceptedOutputMimeTypes = acceptedOutputMimeTypes;
this.functionDefinition = functionDefinition; this.functionDefinition = functionDefinition;
this.headersField = ReflectionUtils.findField(MessageHeaders.class, "headers");
this.headersField.setAccessible(true);
} }
@Override @Override
@@ -680,25 +685,24 @@ public class BeanFactoryAwareFunctionRegistry
return convertedValue; return convertedValue;
} }
@SuppressWarnings("rawtypes") @SuppressWarnings({ "rawtypes", "unchecked" })
private Message convertValueToMessage(Object value, Function<Message, Message> enricher, MimeType acceptedContentType) { private Message convertValueToMessage(Object value, Function<Message, Message> enricher, MimeType acceptedContentType) {
Message outputMessage = null; Message outputMessage = null;
if (enricher != null) { if (value instanceof Message) {
if (!(value instanceof Message)) { MessageHeaders headers = ((Message) value).getHeaders();
value = MessageBuilder.withPayload(value).setHeader(MessageHeaders.CONTENT_TYPE, acceptedContentType).build(); if (!headers.containsKey(MessageHeaders.CONTENT_TYPE)) {
Map<String, Object> headersMap = (Map<String, Object>) ReflectionUtils
.getField(this.headersField, headers);
headersMap.put(MessageHeaders.CONTENT_TYPE, acceptedContentType);
} }
value = enricher.apply((Message) value);
outputMessage = messageConverter.toMessage(((Message) value).getPayload(), ((Message) value).getHeaders());
} }
else { else {
if (value instanceof Message) { value = MessageBuilder.withPayload(value).setHeader(MessageHeaders.CONTENT_TYPE, acceptedContentType).build();
outputMessage = messageConverter.toMessage(((Message) value).getPayload(), ((Message) value).getHeaders());
}
else {
outputMessage = messageConverter.toMessage(value,
new MessageHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE, acceptedContentType)));
}
} }
if (enricher != null) {
value = enricher.apply((Message) value);
}
outputMessage = messageConverter.toMessage(((Message) value).getPayload(), ((Message) value).getHeaders());
return outputMessage; return outputMessage;
} }

View File

@@ -83,7 +83,10 @@ public class BeanFactoryAwareFunctionRegistryTests {
assertThat(((boolean) field.get(function))).isFalse(); assertThat(((boolean) field.get(function))).isFalse();
//== //==
System.setProperty("spring.cloud.function.definition", "uppercase|uppercaseFlux"); System.setProperty("spring.cloud.function.definition", "uppercase|uppercaseFlux");
function = catalog.lookup(""); function = catalog.lookup("", "application/json");
Function<Flux<String>, Flux<Message<String>>> typedFunction = (Function<Flux<String>, Flux<Message<String>>>) function;
Object blockFirst = typedFunction.apply(Flux.just("hello")).blockFirst();
System.out.println(blockFirst);
assertThat(function).isNotNull(); assertThat(function).isNotNull();
field = ReflectionUtils.findField(FunctionInvocationWrapper.class, "composed"); field = ReflectionUtils.findField(FunctionInvocationWrapper.class, "composed");
field.setAccessible(true); field.setAccessible(true);