GH-762 Fix condition for parsing JSON collection strings into individual messages
Resolves #762
This commit is contained in:
@@ -23,6 +23,7 @@ import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
@@ -37,6 +38,8 @@ import org.reactivestreams.Publisher;
|
||||
import reactor.core.publisher.Flux;
|
||||
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils;
|
||||
import org.springframework.cloud.function.context.FunctionRegistration;
|
||||
import org.springframework.cloud.function.context.FunctionType;
|
||||
import org.springframework.cloud.function.context.config.FunctionContextUtils;
|
||||
@@ -45,7 +48,9 @@ import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Set of utility operations to interrogate function definitions.
|
||||
@@ -80,6 +85,10 @@ public final class FunctionTypeUtils {
|
||||
return Collection.class.isAssignableFrom(rawType);
|
||||
}
|
||||
|
||||
public static boolean isTypeArray(Type type) {
|
||||
return getRawType(type).isArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method identical to {@link #getImmediateGenericType(Type, int)}
|
||||
* for cases when provided 'type' is {@link Publisher} or {@link Message}.
|
||||
@@ -271,9 +280,23 @@ public final class FunctionTypeUtils {
|
||||
type = FunctionType.of(FunctionContextUtils.findType(applicationContext.getBeanFactory(), functionBeanDefinitionName)).getType();
|
||||
}
|
||||
}
|
||||
else if (!(type instanceof ParameterizedType)) {
|
||||
String beanDefinitionName = discoverBeanDefinitionNameByQualifier(applicationContext.getBeanFactory(), functionName);
|
||||
if (StringUtils.hasText(beanDefinitionName)) {
|
||||
type = FunctionType.of(FunctionContextUtils.findType(applicationContext.getBeanFactory(), beanDefinitionName)).getType();
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public static String discoverBeanDefinitionNameByQualifier(ListableBeanFactory beanFactory, String qualifier) {
|
||||
Map<String, Object> beanMap = BeanFactoryAnnotationUtils.qualifiedBeansOfType(beanFactory, Object.class, qualifier);
|
||||
if (!CollectionUtils.isEmpty(beanMap) && beanMap.size() == 1) {
|
||||
return beanMap.keySet().iterator().next();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static Type getOutputType(Type functionType) {
|
||||
assertSupportedTypes(functionType);
|
||||
|
||||
@@ -764,12 +764,22 @@ public class SimpleFunctionRegistry implements FunctionRegistry, FunctionInspect
|
||||
if (input instanceof Message) {
|
||||
payload = ((Message) input).getPayload();
|
||||
}
|
||||
if (JsonMapper.isJsonStringRepresentsCollection(payload) && !FunctionTypeUtils.isTypeCollection(this.inputType)) {
|
||||
payload = jsonMapper.fromJson(payload, List.class);
|
||||
if (JsonMapper.isJsonStringRepresentsCollection(payload)
|
||||
&& !FunctionTypeUtils.isTypeCollection(this.inputType) && !FunctionTypeUtils.isTypeArray(this.inputType)) {
|
||||
MessageHeaders headers = ((Message) input).getHeaders();
|
||||
input = ((List) payload).stream()
|
||||
.map(p -> MessageBuilder.withPayload(p).copyHeaders(headers).build())
|
||||
.collect(Collectors.toList());
|
||||
Collection collectionPayload = jsonMapper.fromJson(payload, Collection.class);
|
||||
Class inputClass = FunctionTypeUtils.getRawType(this.inputType);
|
||||
if (this.isInputTypeMessage()) {
|
||||
inputClass = FunctionTypeUtils.getRawType(FunctionTypeUtils.getImmediateGenericType(this.inputType, 0));
|
||||
}
|
||||
|
||||
if (!inputClass.isAssignableFrom(Object.class) && !inputClass.isAssignableFrom(byte[].class)) {
|
||||
logger.debug("Converting JSON string representing collection to a list of Messages. Function '"
|
||||
+ this + "' will be invoked iteratively");
|
||||
input = collectionPayload.stream()
|
||||
.map(p -> MessageBuilder.withPayload(p).copyHeaders(headers).build())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user