Re-enable ContentTypeTCK tests

Other fixes related to spring-cloud-function 4.x branch
This commit is contained in:
Oleg Zhurakousky
2022-01-14 11:41:36 +01:00
parent c40417964a
commit 938fbbb4b9
3 changed files with 836 additions and 1163 deletions

View File

@@ -30,6 +30,7 @@ import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.cloud.function.context.FunctionCatalog;
import org.springframework.cloud.function.context.FunctionRegistration;
import org.springframework.cloud.function.context.FunctionRegistry;
import org.springframework.cloud.function.context.catalog.FunctionTypeUtils;
import org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry.FunctionInvocationWrapper;
import org.springframework.cloud.function.context.message.MessageUtils;
import org.springframework.cloud.stream.binder.Binder;

View File

@@ -0,0 +1,835 @@
/*
* Copyright 2017-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.stream.binder.tck;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.function.json.JsonMapper;
import org.springframework.cloud.stream.binder.test.InputDestination;
import org.springframework.cloud.stream.binder.test.OutputDestination;
import org.springframework.cloud.stream.binder.test.TestChannelBinder;
import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.lang.Nullable;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.MessagingException;
import org.springframework.messaging.converter.AbstractMessageConverter;
import org.springframework.messaging.converter.MessageConversionException;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.util.MimeType;
import org.springframework.util.MimeTypeUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Sort of a TCK test suite to validate payload conversion is done properly by interacting
* with binder's input/output destinations instead of its bridged channels. This means
* that all payloads (sent/received) must be expressed in the wire format (byte[])
*
* @author Oleg Zhurakousky
* @author Gary Russell
*
*/
public class ContentTypeTckTests {
@Test
public void stringToMapMessageStreamListener() {
ApplicationContext context = new SpringApplicationBuilder(
StringToMapMessageConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(new String(outputMessage.getPayload())).isEqualTo("oleg");
}
@Test
public void pojoToPojo() {
ApplicationContext context = new SpringApplicationBuilder(
PojoToPojoConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
}
@Test
public void pojoToString() {
ApplicationContext context = new SpringApplicationBuilder(
PojoToStringConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo("oleg");
}
@Test
public void pojoToStringOutboundContentTypeBinding() {
ApplicationContext context = new SpringApplicationBuilder(
PojoToStringConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.bindings.echo-out-0.contentType=text/plain",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.TEXT_PLAIN_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo("oleg");
}
@Test
public void pojoToByteArray() {
ApplicationContext context = new SpringApplicationBuilder(
PojoToByteArrayConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo("oleg");
}
@Test
public void pojoToByteArrayOutboundContentTypeBinding() {
ApplicationContext context = new SpringApplicationBuilder(
PojoToByteArrayConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo("oleg");
}
@Test
public void stringToPojoInboundContentTypeBinding() {
ApplicationContext context = new SpringApplicationBuilder(
StringToPojoConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.bindings.echo-on-0.contentType=text/plain",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
}
@Test
public void typelessToPojoInboundContentTypeBinding() {
ApplicationContext context = new SpringApplicationBuilder(
TypelessToPojoConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.bindings.echo-in-0.contentType=text/plain",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
}
@Test
public void typelessToPojoInboundContentTypeBindingJson() {
ApplicationContext context = new SpringApplicationBuilder(
TypelessToPojoConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.bindings.echo-in-0.contentType=application/json",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
}
@Test
public void typelessMessageToPojoInboundContentTypeBinding() {
ApplicationContext context = new SpringApplicationBuilder(
TypelessMessageToPojoConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.cloud.stream.bindings.echo-in-0.contentType=text/plain",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
}
@Test
public void typelessMessageToPojoInboundContentTypeBindingJson() {
ApplicationContext context = new SpringApplicationBuilder(
TypelessMessageToPojoConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.cloud.stream.bindings.echo-in-0.contentType=application/json",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
}
@Test
public void typelessToPojoWithTextHeaderContentTypeBinding() {
ApplicationContext context = new SpringApplicationBuilder(
TypelessToPojoConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(MessageBuilder.withPayload(jsonPayload.getBytes())
.setHeader(MessageHeaders.CONTENT_TYPE, MimeType.valueOf("text/plain"))
.build());
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
}
@Test
public void typelessToPojoOutboundContentTypeBinding() {
ApplicationContext context = new SpringApplicationBuilder(
TypelessToMessageConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.bindings.echo-out-0.contentType=text/plain",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(MessageBuilder.withPayload(jsonPayload.getBytes())
.setHeader("contentType", new MimeType("text", "plain")).build());
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.TEXT_PLAIN_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
}
@Test
public void outboundMessageWithTextContentTypeOnly() {
ApplicationContext context = new SpringApplicationBuilder(
TypelessToMessageTextOnlyContentTypeConfiguration.class)
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(MessageBuilder.withPayload(jsonPayload.getBytes())
.setHeader("contentType", new MimeType("text")).build());
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString())
.startsWith("text/");
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
}
@Test
public void stringToPojoInboundContentTypeHeader() {
ApplicationContext context = new SpringApplicationBuilder(
StringToPojoConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes(),
new MessageHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE,
MimeTypeUtils.TEXT_PLAIN))));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
}
@Test
public void byteArrayToPojoInboundContentTypeBinding() {
ApplicationContext context = new SpringApplicationBuilder(
ByteArrayToPojoConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.bindings.echo-in-0.contentType=text/plain",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
}
@Test
public void byteArrayToPojoInboundContentTypeHeader() {
ApplicationContext context = new SpringApplicationBuilder(
StringToPojoConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes(),
new MessageHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE,
MimeTypeUtils.TEXT_PLAIN))));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.APPLICATION_JSON_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
}
@Test
public void byteArrayToByteArray() {
ApplicationContext context = new SpringApplicationBuilder(
ByteArrayToByteArrayConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
}
@Test
public void byteArrayToByteArrayInboundOutboundContentTypeBinding() {
ApplicationContext context = new SpringApplicationBuilder(
ByteArrayToByteArrayConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.cloud.stream.bindings.input.contentType=text/plain",
"--spring.cloud.stream.bindings.output.contentType=text/plain",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
}
@Test
public void pojoMessageToStringMessage() {
ApplicationContext context = new SpringApplicationBuilder(
PojoMessageToStringMessageConfiguration.class)
.web(WebApplicationType.NONE).run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo(MimeTypeUtils.TEXT_PLAIN_VALUE);
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo("oleg");
}
@Test
public void customMessageConverter_defaultContentTypeBinding() {
ApplicationContext context = new SpringApplicationBuilder(
StringToStringConfiguration.class, CustomConverters.class)
.web(WebApplicationType.NONE)
.run("--spring.cloud.stream.default.contentType=foo/bar",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage).isNotNull();
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo("FooBarMessageConverter");
assertThat(outputMessage.getHeaders().get(MessageHeaders.CONTENT_TYPE))
.isEqualTo("foo/bar");
}
// Failure tests
@Test
public void _jsonToPojoWrongDefaultContentTypeProperty() {
ApplicationContext context = new SpringApplicationBuilder(
PojoToPojoConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.default.contentType=text/plain",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
TestChannelBinder binder = context.getBean(TestChannelBinder.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
assertThat(binder.getLastError().getPayload() instanceof MessagingException)
.isTrue();
}
@Test
@Ignore
public void _toStringDefaultContentTypePropertyUnknownContentType() {
ApplicationContext context = new SpringApplicationBuilder(
StringToStringConfiguration.class).web(WebApplicationType.NONE).run(
"--spring.cloud.stream.default.contentType=foo/bar",
"--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
TestChannelBinder binder = context.getBean(TestChannelBinder.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
assertThat(
binder.getLastError().getPayload() instanceof MessageConversionException)
.isTrue();
}
@Test
public void toCollectionWithParameterizedType() {
ApplicationContext context = new SpringApplicationBuilder(
CollectionWithParameterizedTypes.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "[{\"person\":{\"name\":\"jon\"},\"id\":123},{\"person\":{\"name\":\"jane\"},\"id\":456}]";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(outputMessage.getPayload()).isEqualTo(jsonPayload.getBytes());
}
// ======
@Test
public void testWithMapInputParameter() {
ApplicationContext context = new SpringApplicationBuilder(
MapInputConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
}
@Test
public void testWithMapPayloadParameter() {
ApplicationContext context = new SpringApplicationBuilder(
MapInputConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
}
@Test
public void testWithListInputParameter() {
ApplicationContext context = new SpringApplicationBuilder(
ListInputConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false", "--debug");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "[\"foo\",\"bar\"]";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isEqualTo(jsonPayload);
}
@Test
@Ignore // TODO fix it. We can recognize MessageHeaders and parse it out of the message properly
public void testWithMessageHeadersInputParameter() {
ApplicationContext context = new SpringApplicationBuilder(
MessageHeadersInputConfiguration.class).web(WebApplicationType.NONE)
.run("--spring.jmx.enabled=false");
InputDestination source = context.getBean(InputDestination.class);
OutputDestination target = context.getBean(OutputDestination.class);
String jsonPayload = "{\"name\":\"oleg\"}";
source.send(new GenericMessage<>(jsonPayload.getBytes()));
Message<byte[]> outputMessage = target.receive();
assertThat(new String(outputMessage.getPayload(), StandardCharsets.UTF_8))
.isNotEqualTo(jsonPayload);
assertThat(outputMessage.getHeaders().containsKey(MessageHeaders.ID)).isTrue();
assertThat(outputMessage.getHeaders().containsKey(MessageHeaders.CONTENT_TYPE))
.isTrue();
}
@Import(TestChannelBinderConfiguration.class)
@EnableAutoConfiguration
public static class CollectionWithParameterizedTypes {
@Bean
public Function<List<Employee<Person>>, List<Employee<Person>>> echo() {
return value -> {
assertThat(value.get(0) != null).isTrue();
return value;
};
}
}
@Import(TestChannelBinderConfiguration.class)
@EnableAutoConfiguration
public static class PojoToPojoConfiguration {
@Bean
public Function<Person, Person> ecgo() {
return value -> value;
}
}
@Import(TestChannelBinderConfiguration.class)
@EnableAutoConfiguration
public static class PojoToStringConfiguration {
@Bean
public Function<Person, String> echo() {
return value -> value.toString();
}
}
@Import(TestChannelBinderConfiguration.class)
@EnableAutoConfiguration
public static class PojoToByteArrayConfiguration {
@Bean
public Function<Person, byte[]> echo() {
return value -> value.toString().getBytes(StandardCharsets.UTF_8);
}
}
@Import(TestChannelBinderConfiguration.class)
@EnableAutoConfiguration
public static class ByteArrayToPojoConfiguration {
@Bean
public Function<byte[], Person> echo(JsonMapper mapper) {
return value -> mapper.fromJson(value, Person.class);
}
}
@Import(TestChannelBinderConfiguration.class)
@EnableAutoConfiguration
public static class StringToPojoConfiguration {
@Bean
public Function<String, Person> echo(JsonMapper mapper) {
return value -> mapper.fromJson(value, Person.class);
}
}
@Import(TestChannelBinderConfiguration.class)
@EnableAutoConfiguration
public static class TypelessToPojoConfiguration {
@Bean
public Function<Object, Person> echo(JsonMapper mapper) {
return value -> value instanceof byte[]
? mapper.fromJson((byte[]) value, Person.class)
: mapper.fromJson((String) value, Person.class);
}
}
@Import(TestChannelBinderConfiguration.class)
@EnableAutoConfiguration
public static class TypelessMessageToPojoConfiguration {
@Bean
public Function<Message<?>, Person> echo(JsonMapper mapper) {
return message -> message.getPayload() instanceof byte[]
? mapper.fromJson((byte[]) message.getPayload(), Person.class)
: mapper.fromJson((String) message.getPayload(), Person.class);
}
}
@Import(TestChannelBinderConfiguration.class)
@EnableAutoConfiguration
public static class TypelessToMessageConfiguration {
@Bean
public Function<Object, Message<?>> echo() {
return value -> MessageBuilder.withPayload(value.toString())
.setHeader("contentType", new MimeType("text", "plain")).build();
}
}
@Import(TestChannelBinderConfiguration.class)
@EnableAutoConfiguration
public static class TypelessToMessageTextOnlyContentTypeConfiguration {
@Bean
public Function<?, Message<?>> echo() {
return value -> {
return MessageBuilder.withPayload(value.toString())
.setHeader("expected-content-type", "text/*").build();
};
}
}
@Import(TestChannelBinderConfiguration.class)
@EnableAutoConfiguration
public static class ByteArrayToByteArrayConfiguration {
@Bean
public Function<byte[], byte[]> echo() {
return value -> value;
}
}
@Import(TestChannelBinderConfiguration.class)
@EnableAutoConfiguration
public static class StringToStringConfiguration {
@Bean
public Function<String, String> echo() {
return v -> v;
}
}
@Import(TestChannelBinderConfiguration.class)
@EnableAutoConfiguration
public static class StringToMapMessageConfiguration {
@Bean
public Function<Message<Map<?, ?>>, String> echo() {
return value -> {
assertThat(value.getPayload() instanceof Map).isTrue();
return (String) value.getPayload().get("name");
};
}
}
@Import(TestChannelBinderConfiguration.class)
@EnableAutoConfiguration
public static class PojoMessageToStringMessageConfiguration {
@Bean
public Function<Message<Person>, Message<String>> echo() {
return value -> MessageBuilder.withPayload(value.getPayload().toString())
.setHeader("expected-content-type", MimeTypeUtils.TEXT_PLAIN_VALUE)
.build();
}
}
public static class Employee<P> {
private P person;
private int id;
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public P getPerson() {
return this.person;
}
public void setPerson(P person) {
this.person = person;
}
}
public static class Person {
private String name;
public Person() {
this(null);
}
public Person(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return this.name;
}
}
@Configuration
public static class CustomConverters {
@Bean
public FooBarMessageConverter fooBarMessageConverter() {
return new FooBarMessageConverter(MimeType.valueOf("foo/bar"));
}
@Bean
public AlwaysStringKryoMessageConverter kryoOverrideMessageConverter() {
return new AlwaysStringKryoMessageConverter(
MimeType.valueOf("application/x-java-object"));
}
/**
* Even though this MessageConverter has nothing to do with Kryo it still shows
* how Kryo conversion can be customized/overriden since it simply overriding a
* converter for contentType 'application/x-java-object'.
*
*/
public static class AlwaysStringKryoMessageConverter
extends AbstractMessageConverter {
public AlwaysStringKryoMessageConverter(MimeType supportedMimeType) {
super(supportedMimeType);
}
@Override
protected boolean supports(Class<?> clazz) {
return clazz == null || String.class.isAssignableFrom(clazz);
}
@Override
protected Object convertFromInternal(Message<?> message, Class<?> targetClass,
@Nullable Object conversionHint) {
return this.getClass().getSimpleName();
}
@Override
protected Object convertToInternal(Object payload,
@Nullable MessageHeaders headers, @Nullable Object conversionHint) {
return ((String) payload).getBytes(StandardCharsets.UTF_8);
}
}
public static class FooBarMessageConverter extends AbstractMessageConverter {
protected FooBarMessageConverter(MimeType supportedMimeType) {
super(supportedMimeType);
}
@Override
protected boolean supports(Class<?> clazz) {
return clazz != null && String.class.isAssignableFrom(clazz);
}
@Override
protected Object convertFromInternal(Message<?> message, Class<?> targetClass,
@Nullable Object conversionHint) {
return this.getClass().getSimpleName();
}
@Override
protected Object convertToInternal(Object payload,
@Nullable MessageHeaders headers, @Nullable Object conversionHint) {
return ((String) payload).getBytes(StandardCharsets.UTF_8);
}
}
}
@Import(TestChannelBinderConfiguration.class)
@EnableAutoConfiguration
public static class MapInputConfiguration {
@Bean
public Function<Map<?, ?>, Map<?, ?>> echo() {
return value -> value;
}
}
@Import(TestChannelBinderConfiguration.class)
@EnableAutoConfiguration
public static class ListInputConfiguration {
@Bean
public Function<List<?>, List<?>> echo() {
return v -> v;
}
}
@Import(TestChannelBinderConfiguration.class)
@EnableAutoConfiguration
public static class MessageHeadersInputConfiguration {
@Bean
public Function<MessageHeaders, Map<?, ?>> echo() {
return v -> v;
}
}
}