Content type redesign
Fixes #992, #1050, #1051, #1052 Adding custom jackson converter with some tests Adds kryo message converter to replace codec Checkstyle changes Removing codec support - Removed codec dependency from AbstractBinder - MessageSerializationUtils is almost an empty shell for now, just to keep code compiling until we get EmbeddedHeaders interceptors - Updated Kryo tests Removing codec module from build Added a new Annotation for custom converters '@StreamConverter' Fixed some tests with new expected behavior Moved broken tests to a temporary package to keep track of progress Fixed KryoConverter to fail based on headers Fixed a couple of more tests Making converters strict to only convert their corresponding contentType Bypassing conversion for ErrorMessages * Configuring SI ConfigurableCompositeMessageConverter - Moved ContentType related beans into separate configuration - Configured SI ConfigurableCompositeMessageConverter to use same converters as Stream does (for ServiceActivator) - TupleConverter should return byte[] as all other converters - Fixed tests * Fixes tests - Revert to Boot 2.0.0.M3. Snapshots breaking actuator - Checkstyle fixes - Disable JsonUnmarshalling as a catch all converter Fixing Schema tests Fixing Metrics tests Fixing reactive tests applying checkstyle fixes * Adding new content type tests - Fixed ContentTypeInterceptor misusage of default mimeType Changing contentType doc section Improving doc section Last minute polish Fixing BinderTests to use bytes to compare messages Applied changes to Base Binders test to use the new contentType handling mechanism PR review fixes Renaming StreamConverter -> StreamMessageConverter
This commit is contained in:
committed by
Soby Chacko
parent
24cf992301
commit
171f034a8c
@@ -38,6 +38,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Vinicius Carvalho
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = { ContentTypeOutboundSourceTests.TestSource.class })
|
||||
@@ -53,12 +54,15 @@ public class ContentTypeOutboundSourceTests {
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testMessageHeaderWhenNoExplicitContentTypeOnMessage() throws Exception {
|
||||
testSource.output().send(MessageBuilder.withPayload("{\"message\":\"Hi\"}").build());
|
||||
Message<String> received = (Message<String>) ((TestSupportBinder) binderFactory.getBinder(null,
|
||||
testSource.output().send(MessageBuilder.withPayload("{\"message\":\"Hi\"}").setHeader(MessageHeaders.CONTENT_TYPE,"text/plain").build());
|
||||
Message<?> received = ((TestSupportBinder) binderFactory.getBinder(null,
|
||||
MessageChannel.class))
|
||||
.messageCollector().forChannel(testSource.output()).poll();
|
||||
assertThat(received.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString()).isEqualTo("application/json");
|
||||
assertThat(received).hasFieldOrPropertyWithValue("payload", "{\"message\":\"Hi\"}");
|
||||
assertThat(received.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString()).contains("text/plain");
|
||||
Object payload = received.getPayload();
|
||||
assertThat(payload.getClass().isAssignableFrom(byte[].class)).isTrue();
|
||||
byte[] contents = (byte[])payload;
|
||||
assertThat("{\"message\":\"Hi\"}").isEqualTo(new String(contents));
|
||||
}
|
||||
|
||||
@EnableBinding(Source.class)
|
||||
|
||||
@@ -53,6 +53,11 @@ public class CustomHeaderPropagationTests {
|
||||
private BinderFactory binderFactory;
|
||||
|
||||
@Test
|
||||
/**
|
||||
* @since 2.0 The behavior of content type handling has changed.
|
||||
* All input/output channels have a default content type of application/json
|
||||
* When a processor or a source returns a String, and if the content type is json it will be quoted
|
||||
*/
|
||||
public void testCustomHeaderPropagation() throws Exception {
|
||||
testProcessor.input().send(MessageBuilder.withPayload("{'name':'foo'}")
|
||||
.setHeader(MessageHeaders.CONTENT_TYPE, "application/json")
|
||||
@@ -65,8 +70,8 @@ public class CustomHeaderPropagationTests {
|
||||
assertThat(received).isNotNull();
|
||||
assertThat(received.getHeaders()).containsEntry("foo", "fooValue");
|
||||
assertThat(received.getHeaders()).doesNotContainKey("bar");
|
||||
assertThat(received.getHeaders()).doesNotContainKey(MessageHeaders.CONTENT_TYPE);
|
||||
assertThat(received.getPayload()).isEqualTo("{'name':'foo'}");
|
||||
assertThat(received.getHeaders()).containsKeys(MessageHeaders.CONTENT_TYPE);
|
||||
assertThat(new String((byte[])received.getPayload())).isEqualTo("{'name':'foo'}");
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
@@ -74,8 +79,9 @@ public class CustomHeaderPropagationTests {
|
||||
public static class HeaderPropagationProcessor {
|
||||
|
||||
@ServiceActivator(inputChannel = "input", outputChannel = "output")
|
||||
public String consume(String data) {
|
||||
return data;
|
||||
public Message<String> consume(String data) {
|
||||
//if we don't force content to be String, it will be quoted on the outbound channel
|
||||
return MessageBuilder.withPayload(data).setHeader(MessageHeaders.CONTENT_TYPE,"text/plain").build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.stream.annotation.Bindings;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.StreamMessageConverter;
|
||||
import org.springframework.cloud.stream.binder.BinderFactory;
|
||||
import org.springframework.cloud.stream.messaging.Source;
|
||||
import org.springframework.cloud.stream.test.binder.TestSupportBinder;
|
||||
@@ -35,8 +36,6 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.integration.support.converter.ConfigurableCompositeMessageConverter;
|
||||
import org.springframework.integration.support.converter.DefaultDatatypeChannelMessageConverter;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
@@ -64,14 +63,14 @@ public class CustomMessageConverterTests {
|
||||
private BinderFactory binderFactory;
|
||||
|
||||
@Autowired
|
||||
@StreamMessageConverter
|
||||
private List<MessageConverter> customMessageConverters;
|
||||
|
||||
@Test
|
||||
public void testCustomMessageConverter() throws Exception {
|
||||
assertThat(customMessageConverters).hasSize(4);
|
||||
assertThat(customMessageConverters).hasSize(2);
|
||||
assertThat(customMessageConverters).extracting("class").contains(FooConverter.class,
|
||||
BarConverter.class, DefaultDatatypeChannelMessageConverter.class,
|
||||
ConfigurableCompositeMessageConverter.class);
|
||||
BarConverter.class);
|
||||
testSource.output().send(MessageBuilder.withPayload(new Foo("hi")).build());
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<String> received = (Message<String>) ((TestSupportBinder) binderFactory.getBinder(null,
|
||||
@@ -88,11 +87,13 @@ public class CustomMessageConverterTests {
|
||||
public static class TestSource {
|
||||
|
||||
@Bean
|
||||
@StreamMessageConverter
|
||||
public MessageConverter fooConverter() {
|
||||
return new FooConverter();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@StreamMessageConverter
|
||||
public MessageConverter barConverter() {
|
||||
return new BarConverter();
|
||||
}
|
||||
|
||||
@@ -64,8 +64,8 @@ public class DefaultHeaderPropagationTests {
|
||||
assertThat(received).isNotNull();
|
||||
assertThat(received.getHeaders()).containsEntry("foo", "fooValue");
|
||||
assertThat(received.getHeaders()).containsEntry("bar", "barValue");
|
||||
assertThat(received.getHeaders()).doesNotContainKey(MessageHeaders.CONTENT_TYPE);
|
||||
assertThat(received.getPayload()).isEqualTo("{'name':'foo'}");
|
||||
assertThat(received.getHeaders()).containsKeys(MessageHeaders.CONTENT_TYPE);
|
||||
assertThat(received.getPayload()).isEqualTo("{'name':'foo'}".getBytes());
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
@@ -73,8 +73,8 @@ public class DefaultHeaderPropagationTests {
|
||||
public static class HeaderPropagationProcessor {
|
||||
|
||||
@ServiceActivator(inputChannel = "input", outputChannel = "output")
|
||||
public String consume(String data) {
|
||||
return data;
|
||||
public Message<String> consume(String data) {
|
||||
return MessageBuilder.withPayload(data).setHeader(MessageHeaders.CONTENT_TYPE,"text/plain").build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,9 +33,9 @@ import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.converter.MessageConversionException;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
@@ -51,8 +51,8 @@ public class DefaultHeaderPropagationWithApplicationProvidedHeaderTests {
|
||||
@Autowired
|
||||
private BinderFactory binderFactory;
|
||||
|
||||
@Test
|
||||
public void testHeaderPropagationIfSetByApplication() throws Exception {
|
||||
@Test(expected = MessageConversionException.class)
|
||||
public void testFailedonCustomContentTypeWithoutConverter() throws Exception {
|
||||
testProcessor.input().send(MessageBuilder.withPayload("{'name':'foo'}")
|
||||
.setHeader(MessageHeaders.CONTENT_TYPE, "application/json")
|
||||
.setHeader("foo", "fooValue")
|
||||
@@ -61,11 +61,7 @@ public class DefaultHeaderPropagationWithApplicationProvidedHeaderTests {
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<?> received = ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
|
||||
.messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(received.getHeaders()).containsEntry("foo", "fooValue");
|
||||
assertThat(received.getHeaders()).containsEntry("bar", "barValue");
|
||||
assertThat(received.getHeaders()).containsEntry(MessageHeaders.CONTENT_TYPE, "custom/header");
|
||||
assertThat(received).isNotNull();
|
||||
assertThat(received.getPayload()).isEqualTo("{'name':'foo'}");
|
||||
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
|
||||
@@ -64,8 +64,8 @@ public class DeserializeJSONToJavaTypeTests {
|
||||
Message<?> received = ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
|
||||
.messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(received).isNotNull();
|
||||
assertThat(received.getPayload()).isInstanceOf(Foo.class);
|
||||
assertThat((Foo) received.getPayload()).hasFieldOrPropertyWithValue("name", "Bar");
|
||||
assertThat(received.getPayload()).isInstanceOf(byte[].class);
|
||||
assertThat((byte[]) received.getPayload()).isEqualTo("{\"name\":\"Bar\"}".getBytes());
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
|
||||
@@ -33,7 +33,6 @@ import org.springframework.integration.annotation.ServiceActivator;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.tuple.TupleBuilder;
|
||||
@@ -56,12 +55,13 @@ public class InboundJsonToTupleConversionTest {
|
||||
@Test
|
||||
public void testInboundJsonTupleConversion() throws Exception {
|
||||
testProcessor.input().send(MessageBuilder.withPayload("{'name':'foo'}")
|
||||
.setHeader(MessageHeaders.CONTENT_TYPE, "application/json").build());
|
||||
.build());
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<?> received = ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
|
||||
.messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(received).isNotNull();
|
||||
assertThat(received.getPayload()).isEqualTo(TupleBuilder.tuple().of("name", "foo"));
|
||||
|
||||
assertThat(TupleBuilder.fromString(new String((byte[])received.getPayload()))).isEqualTo(TupleBuilder.tuple().of("name", "foo"));
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
|
||||
@@ -42,7 +42,6 @@ import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.messaging.converter.CompositeMessageConverter;
|
||||
import org.springframework.messaging.converter.MessageConverter;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -78,14 +77,13 @@ public class MessageChannelConfigurerTests {
|
||||
MessageHandler messageHandler = new MessageHandler() {
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
assertThat(message.getPayload()).isInstanceOf(Tuple.class);
|
||||
assertThat(((Tuple) message.getPayload()).getFieldNames().get(0)).isEqualTo("message");
|
||||
assertThat(((Tuple) message.getPayload()).getValue(0)).isEqualTo("Hi");
|
||||
assertThat(message.getPayload()).isInstanceOf(byte[].class);
|
||||
assertThat(message.getPayload()).isEqualTo("{\"message\":\"Hi\"}".getBytes());
|
||||
latch.countDown();
|
||||
}
|
||||
};
|
||||
testSink.input().subscribe(messageHandler);
|
||||
testSink.input().send(MessageBuilder.withPayload("{\"message\":\"Hi\"}").build());
|
||||
testSink.input().send(MessageBuilder.withPayload("{\"message\":\"Hi\"}".getBytes()).build());
|
||||
assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue();
|
||||
testSink.input().unsubscribe(messageHandler);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
@@ -48,6 +49,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Vinicius Carvalho
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class StreamListenerHandlerBeanTests {
|
||||
@@ -76,13 +78,13 @@ public class StreamListenerHandlerBeanTests {
|
||||
MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}")
|
||||
.setHeader("contentType", "application/json").build());
|
||||
HandlerBean handlerBean = context.getBean(HandlerBean.class);
|
||||
assertThat(handlerBean.receivedPojos).hasSize(1);
|
||||
assertThat(handlerBean.receivedPojos.get(0)).hasFieldOrPropertyWithValue("foo",
|
||||
Assertions.assertThat(handlerBean.receivedPojos).hasSize(1);
|
||||
Assertions.assertThat(handlerBean.receivedPojos.get(0)).hasFieldOrPropertyWithValue("foo",
|
||||
"barbar" + id);
|
||||
Message<String> message = (Message<String>) collector.forChannel(
|
||||
Message<byte[]> message = (Message<byte[]>) collector.forChannel(
|
||||
processor.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(message).isNotNull();
|
||||
assertThat(message.getPayload()).isEqualTo("{\"bar\":\"barbar" + id + "\"}");
|
||||
assertThat(new String(message.getPayload())).isEqualTo("{\"bar\":\"barbar" + id + "\"}");
|
||||
assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
.includes(MimeTypeUtils.APPLICATION_JSON));
|
||||
context.close();
|
||||
|
||||
@@ -64,13 +64,15 @@ import static org.springframework.cloud.stream.binding.StreamListenerErrorMessag
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Gary Russell
|
||||
* @author Vinicius Carvalho
|
||||
*/
|
||||
public class StreamListenerHandlerMethodTests {
|
||||
|
||||
@Test
|
||||
public void testInvalidInputOnMethod() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestInvalidInputOnMethod.class, "--server.port=0");
|
||||
SpringApplication.run(TestInvalidInputOnMethod.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
fail("Exception expected: " + INPUT_AT_STREAM_LISTENER);
|
||||
}
|
||||
catch (BeanCreationException e) {
|
||||
@@ -81,30 +83,41 @@ public class StreamListenerHandlerMethodTests {
|
||||
@Test
|
||||
public void testMethodWithObjectAsMethodArgument() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(TestMethodWithObjectAsMethodArgument.class,
|
||||
"--server.port=0");
|
||||
"--server.port=0",
|
||||
"--spring.jmx.enabled=false",
|
||||
"--spring.cloud.stream.bindings.input.contentType=text/plain",
|
||||
"--spring.cloud.stream.bindings.output.contentType=text/plain");
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
final String testMessage = "testing";
|
||||
processor.input().send(MessageBuilder.withPayload(testMessage).build());
|
||||
MessageCollector messageCollector = context.getBean(MessageCollector.class);
|
||||
Message<?> result = messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
|
||||
Message<byte[]> result = (Message<byte[]>) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getPayload()).isEqualTo(testMessage.toUpperCase());
|
||||
assertThat(new String(result.getPayload())).isEqualTo(testMessage.toUpperCase());
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
/**
|
||||
* @since 2.0 : This test is an example of the new behavior of 2.0 when it comes to contentType handling.
|
||||
* The default contentType being JSON in order to be able to check a message without quotes the user needs to set the input/output contentType accordingly
|
||||
* Also, received messages are always of Message<byte[]> now.
|
||||
*/
|
||||
public void testMethodHeadersPropagatged() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(TestMethodHeadersPropagated.class,
|
||||
"--server.port=0");
|
||||
"--server.port=0",
|
||||
"--spring.jmx.enabled=false",
|
||||
"--spring.cloud.stream.bindings.input.contentType=text/plain",
|
||||
"--spring.cloud.stream.bindings.output.contentType=text/plain");
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
final String testMessage = "testing";
|
||||
processor.input().send(MessageBuilder.withPayload(testMessage)
|
||||
.setHeader("foo", "bar")
|
||||
.build());
|
||||
MessageCollector messageCollector = context.getBean(MessageCollector.class);
|
||||
Message<?> result = messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
|
||||
Message<byte[]> result = (Message<byte[]>) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getPayload()).isEqualTo(testMessage.toUpperCase());
|
||||
assertThat(new String(result.getPayload())).isEqualTo(testMessage.toUpperCase());
|
||||
assertThat(result.getHeaders().get("foo")).isEqualTo("bar");
|
||||
context.close();
|
||||
}
|
||||
@@ -112,41 +125,49 @@ public class StreamListenerHandlerMethodTests {
|
||||
@Test
|
||||
public void testMethodHeadersNotPropagatged() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(TestMethodHeadersNotPropagated.class,
|
||||
"--server.port=0");
|
||||
"--server.port=0",
|
||||
"--spring.jmx.enabled=false",
|
||||
"--spring.cloud.stream.bindings.input.contentType=text/plain",
|
||||
"--spring.cloud.stream.bindings.output.contentType=text/plain");
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
final String testMessage = "testing";
|
||||
processor.input().send(MessageBuilder.withPayload(testMessage)
|
||||
.setHeader("foo", "bar")
|
||||
.build());
|
||||
MessageCollector messageCollector = context.getBean(MessageCollector.class);
|
||||
Message<?> result = messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
|
||||
Message<byte[]> result = (Message<byte[]>) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getPayload()).isEqualTo(testMessage.toUpperCase());
|
||||
assertThat(new String(result.getPayload())).isEqualTo(testMessage.toUpperCase());
|
||||
assertThat(result.getHeaders().get("foo")).isNull();
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
//TODO: Handle dynamic destinations and contentType
|
||||
public void testStreamListenerMethodWithTargetBeanFromOutside() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication
|
||||
.run(TestStreamListenerMethodWithTargetBeanFromOutside.class, "--server.port=0");
|
||||
.run(TestStreamListenerMethodWithTargetBeanFromOutside.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false",
|
||||
"--spring.cloud.stream.bindings.input.contentType=text/plain",
|
||||
"--spring.cloud.stream.bindings.output.contentType=text/plain");
|
||||
Sink sink = context.getBean(Sink.class);
|
||||
final String testMessageToSend = "testing";
|
||||
sink.input().send(MessageBuilder.withPayload(testMessageToSend).build());
|
||||
DirectChannel directChannel = (DirectChannel) context.getBean(testMessageToSend.toUpperCase(),
|
||||
MessageChannel.class);
|
||||
MessageCollector messageCollector = context.getBean(MessageCollector.class);
|
||||
Message<?> result = messageCollector.forChannel(directChannel).poll(1000, TimeUnit.MILLISECONDS);
|
||||
Message<byte[]> result = (Message<byte[]>) messageCollector.forChannel(directChannel).poll(1000, TimeUnit.MILLISECONDS);
|
||||
sink.input().send(MessageBuilder.withPayload(testMessageToSend).build());
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getPayload()).isEqualTo(testMessageToSend.toUpperCase());
|
||||
assertThat(new String(result.getPayload())).isEqualTo(testMessageToSend.toUpperCase());
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidReturnTypeWithSendToAndOutput() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestReturnTypeWithMultipleOutput.class, "--server.port=0");
|
||||
SpringApplication.run(TestReturnTypeWithMultipleOutput.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
fail("Exception expected: " + RETURN_TYPE_MULTIPLE_OUTBOUND_SPECIFIED);
|
||||
}
|
||||
catch (BeanCreationException e) {
|
||||
@@ -157,7 +178,8 @@ public class StreamListenerHandlerMethodTests {
|
||||
@Test
|
||||
public void testInvalidReturnTypeWithNoOutput() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestInvalidReturnTypeWithNoOutput.class, "--server.port=0");
|
||||
SpringApplication.run(TestInvalidReturnTypeWithNoOutput.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
fail("Exception expected: " + RETURN_TYPE_NO_OUTBOUND_SPECIFIED);
|
||||
}
|
||||
catch (BeanCreationException e) {
|
||||
@@ -168,7 +190,8 @@ public class StreamListenerHandlerMethodTests {
|
||||
@Test
|
||||
public void testInvalidInputAnnotationWithNoValue() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestInvalidInputAnnotationWithNoValue.class, "--server.port=0");
|
||||
SpringApplication.run(TestInvalidInputAnnotationWithNoValue.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
fail("Exception expected: " + INVALID_INBOUND_NAME);
|
||||
}
|
||||
catch (BeanCreationException e) {
|
||||
@@ -179,7 +202,8 @@ public class StreamListenerHandlerMethodTests {
|
||||
@Test
|
||||
public void testInvalidOutputAnnotationWithNoValue() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestInvalidOutputAnnotationWithNoValue.class, "--server.port=0");
|
||||
SpringApplication.run(TestInvalidOutputAnnotationWithNoValue.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
fail("Exception expected: " + INVALID_OUTBOUND_NAME);
|
||||
}
|
||||
catch (BeanCreationException e) {
|
||||
@@ -190,7 +214,8 @@ public class StreamListenerHandlerMethodTests {
|
||||
@Test
|
||||
public void testMethodInvalidInboundName() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestMethodInvalidInboundName.class, "--server.port=0");
|
||||
SpringApplication.run(TestMethodInvalidInboundName.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
fail("Exception expected on using invalid inbound name");
|
||||
}
|
||||
catch (BeanCreationException e) {
|
||||
@@ -203,7 +228,8 @@ public class StreamListenerHandlerMethodTests {
|
||||
@Test
|
||||
public void testMethodInvalidOutboundName() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestMethodInvalidOutboundName.class, "--server.port=0");
|
||||
SpringApplication.run(TestMethodInvalidOutboundName.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
fail("Exception expected on using invalid outbound name");
|
||||
}
|
||||
catch (BeanCreationException e) {
|
||||
@@ -215,7 +241,8 @@ public class StreamListenerHandlerMethodTests {
|
||||
@Test
|
||||
public void testAmbiguousMethodArguments1() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestAmbiguousMethodArguments1.class, "--server.port=0");
|
||||
SpringApplication.run(TestAmbiguousMethodArguments1.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
fail("Exception expected: " + AMBIGUOUS_MESSAGE_HANDLER_METHOD_ARGUMENTS);
|
||||
}
|
||||
catch (BeanCreationException e) {
|
||||
@@ -226,7 +253,8 @@ public class StreamListenerHandlerMethodTests {
|
||||
@Test
|
||||
public void testAmbiguousMethodArguments2() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestAmbiguousMethodArguments2.class, "--server.port=0");
|
||||
SpringApplication.run(TestAmbiguousMethodArguments2.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
fail("Exception expected:" + AMBIGUOUS_MESSAGE_HANDLER_METHOD_ARGUMENTS);
|
||||
}
|
||||
catch (BeanCreationException e) {
|
||||
@@ -237,7 +265,8 @@ public class StreamListenerHandlerMethodTests {
|
||||
@Test
|
||||
public void testMethodWithInputAsMethodAndParameter() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestMethodWithInputAsMethodAndParameter.class, "--server.port=0");
|
||||
SpringApplication.run(TestMethodWithInputAsMethodAndParameter.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
fail("Exception expected: " + INVALID_DECLARATIVE_METHOD_PARAMETERS);
|
||||
}
|
||||
catch (BeanCreationException e) {
|
||||
@@ -248,7 +277,8 @@ public class StreamListenerHandlerMethodTests {
|
||||
@Test
|
||||
public void testMethodWithOutputAsMethodAndParameter() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestMethodWithOutputAsMethodAndParameter.class, "--server.port=0");
|
||||
SpringApplication.run(TestMethodWithOutputAsMethodAndParameter.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
fail("Exception expected:" + INVALID_OUTPUT_VALUES);
|
||||
}
|
||||
catch (BeanCreationException e) {
|
||||
@@ -259,7 +289,8 @@ public class StreamListenerHandlerMethodTests {
|
||||
@Test
|
||||
public void testMethodWithoutInput() throws Exception {
|
||||
try {
|
||||
SpringApplication.run(TestMethodWithoutInput.class, "--server.port=0");
|
||||
SpringApplication.run(TestMethodWithoutInput.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
fail("Exception expected when inbound target is not set");
|
||||
}
|
||||
catch (BeanCreationException e) {
|
||||
@@ -270,7 +301,8 @@ public class StreamListenerHandlerMethodTests {
|
||||
@Test
|
||||
public void testMethodWithMultipleInputParameters() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(TestMethodWithMultipleInputParameters.class,
|
||||
"--server.port=0");
|
||||
"--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
StreamListenerTestUtils.FooInboundChannel1 inboundChannel2 = context
|
||||
.getBean(StreamListenerTestUtils.FooInboundChannel1.class);
|
||||
@@ -294,7 +326,8 @@ public class StreamListenerHandlerMethodTests {
|
||||
@Test
|
||||
public void testMethodWithMultipleOutputParameters() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(TestMethodWithMultipleOutputParameters.class,
|
||||
"--server.port=0");
|
||||
"--server.port=0",
|
||||
"--spring.jmx.enabled=false");
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
String id = UUID.randomUUID().toString();
|
||||
StreamListenerTestUtils.FooOutboundChannel1 source2 = context
|
||||
|
||||
@@ -44,6 +44,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Vinicius Carvalho
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class StreamListenerMessageArgumentTests {
|
||||
@@ -63,7 +64,7 @@ public class StreamListenerMessageArgumentTests {
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testMessageArgument() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication
|
||||
.run(this.configClass, "--server.port=0");
|
||||
.run(this.configClass, "--server.port=0", "--spring.cloud.stream.bindings.output.contentType=text/plain","--spring.jmx.enabled=false");
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
String id = UUID.randomUUID().toString();
|
||||
@@ -73,10 +74,10 @@ public class StreamListenerMessageArgumentTests {
|
||||
.getBean(TestPojoWithMessageArgument.class);
|
||||
assertThat(testPojoWithMessageArgument.receivedMessages).hasSize(1);
|
||||
assertThat(testPojoWithMessageArgument.receivedMessages.get(0).getPayload()).isEqualTo("barbar" + id);
|
||||
Message<StreamListenerTestUtils.BarPojo> message = (Message<StreamListenerTestUtils.BarPojo>) collector
|
||||
Message<byte[]> message = (Message<byte[]>) collector
|
||||
.forChannel(processor.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(message).isNotNull();
|
||||
assertThat(message.getPayload().getBar()).isEqualTo("barbar" + id);
|
||||
assertThat(new String(message.getPayload())).contains("barbar" + id);
|
||||
context.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
@@ -50,6 +52,8 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Vinicius Carvalho
|
||||
*
|
||||
*/
|
||||
@RunWith(StreamListenerMethodReturnWithConversionTests.class)
|
||||
@Suite.SuiteClasses({ StreamListenerMethodReturnWithConversionTests.TestReturnConversion.class,
|
||||
@@ -79,19 +83,19 @@ public class StreamListenerMethodReturnWithConversionTests extends Suite {
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testReturnConversion() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(this.configClass,
|
||||
"--spring.cloud.stream.bindings.output.contentType=application/json", "--server.port=0");
|
||||
"--spring.cloud.stream.bindings.output.contentType=application/json", "--server.port=0","--spring.jmx.enabled=false");
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
String id = UUID.randomUUID().toString();
|
||||
processor.input().send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}")
|
||||
.setHeader("contentType", "application/json").build());
|
||||
TestPojoWithMimeType testPojoWithMimeType = context.getBean(TestPojoWithMimeType.class);
|
||||
assertThat(testPojoWithMimeType.receivedPojos).hasSize(1);
|
||||
assertThat(testPojoWithMimeType.receivedPojos.get(0)).hasFieldOrPropertyWithValue("foo", "barbar" + id);
|
||||
Message<String> message = (Message<String>) collector.forChannel(processor.output()).poll(1,
|
||||
Assertions.assertThat(testPojoWithMimeType.receivedPojos).hasSize(1);
|
||||
Assertions.assertThat(testPojoWithMimeType.receivedPojos.get(0)).hasFieldOrPropertyWithValue("foo", "barbar" + id);
|
||||
Message<byte[]> message = (Message<byte[]>) collector.forChannel(processor.output()).poll(1,
|
||||
TimeUnit.SECONDS);
|
||||
assertThat(message).isNotNull();
|
||||
assertThat(message.getPayload()).isEqualTo("{\"bar\":\"barbar" + id + "\"}");
|
||||
assertThat(new String(message.getPayload())).isEqualTo("{\"bar\":\"barbar" + id + "\"}");
|
||||
assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
.includes(MimeTypeUtils.APPLICATION_JSON));
|
||||
context.close();
|
||||
@@ -103,6 +107,8 @@ public class StreamListenerMethodReturnWithConversionTests extends Suite {
|
||||
|
||||
private Class<?> configClass;
|
||||
|
||||
private ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
public TestReturnNoConversion(Class<?> configClass) {
|
||||
this.configClass = configClass;
|
||||
}
|
||||
@@ -115,21 +121,22 @@ public class StreamListenerMethodReturnWithConversionTests extends Suite {
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testReturnNoConversion() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0");
|
||||
ConfigurableApplicationContext context = SpringApplication.run(this.configClass, "--server.port=0","--spring.jmx.enabled=false");
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
String id = UUID.randomUUID().toString();
|
||||
processor.input().send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}")
|
||||
.setHeader("contentType", "application/json").build());
|
||||
TestPojoWithMimeType testPojoWithMimeType = context.getBean(TestPojoWithMimeType.class);
|
||||
assertThat(testPojoWithMimeType.receivedPojos).hasSize(1);
|
||||
assertThat(testPojoWithMimeType.receivedPojos.get(0)).hasFieldOrPropertyWithValue("foo", "barbar" + id);
|
||||
Message<StreamListenerTestUtils.BarPojo> message = (Message<StreamListenerTestUtils.BarPojo>) collector
|
||||
Assertions.assertThat(testPojoWithMimeType.receivedPojos).hasSize(1);
|
||||
Assertions.assertThat(testPojoWithMimeType.receivedPojos.get(0)).hasFieldOrPropertyWithValue("foo", "barbar" + id);
|
||||
Message<byte[]> message = (Message<byte[]>) collector
|
||||
.forChannel(processor.output()).poll(1,
|
||||
TimeUnit.SECONDS);
|
||||
assertThat(message).isNotNull();
|
||||
assertThat(message.getPayload().getBar()).isEqualTo("barbar" + id);
|
||||
assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class) == null);
|
||||
StreamListenerTestUtils.BarPojo barPojo = mapper.readValue(message.getPayload(),StreamListenerTestUtils.BarPojo.class);
|
||||
assertThat(barPojo.getBar()).isEqualTo("barbar" + id);
|
||||
assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class) != null);
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
@@ -44,6 +45,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Vinicius Carvalho
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class StreamListenerMethodWithReturnMessageTests {
|
||||
@@ -63,7 +65,7 @@ public class StreamListenerMethodWithReturnMessageTests {
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testReturnMessage() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication
|
||||
.run(this.configClass, "--server.port=0");
|
||||
.run(this.configClass, "--server.port=0","--spring.jmx.enabled=false");
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
String id = UUID.randomUUID().toString();
|
||||
@@ -72,12 +74,12 @@ public class StreamListenerMethodWithReturnMessageTests {
|
||||
.setHeader("contentType", "application/json").build());
|
||||
TestPojoWithMessageReturn testPojoWithMessageReturn = context
|
||||
.getBean(TestPojoWithMessageReturn.class);
|
||||
assertThat(testPojoWithMessageReturn.receivedPojos).hasSize(1);
|
||||
assertThat(testPojoWithMessageReturn.receivedPojos.get(0)).hasFieldOrPropertyWithValue("foo", "barbar" + id);
|
||||
Message<StreamListenerTestUtils.BarPojo> message = (Message<StreamListenerTestUtils.BarPojo>) collector
|
||||
Assertions.assertThat(testPojoWithMessageReturn.receivedPojos).hasSize(1);
|
||||
Assertions.assertThat(testPojoWithMessageReturn.receivedPojos.get(0)).hasFieldOrPropertyWithValue("foo", "barbar" + id);
|
||||
Message<byte[]> message = (Message<byte[]>) collector
|
||||
.forChannel(processor.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(message).isNotNull();
|
||||
assertThat(message.getPayload().getBar()).isEqualTo("barbar" + id);
|
||||
assertThat(new String(message.getPayload())).contains("barbar" + id);
|
||||
context.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
@@ -63,21 +64,21 @@ public class StreamListenerMethodWithReturnValueTests {
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testReturn() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication
|
||||
.run(this.configClass, "--server.port=0");
|
||||
.run(this.configClass, "--server.port=0","--spring.jmx.enabled=false");
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
String id = UUID.randomUUID().toString();
|
||||
processor.input()
|
||||
.send(MessageBuilder.withPayload("{\"foo\":\"barbar" + id + "\"}")
|
||||
.setHeader("contentType", "application/json").build());
|
||||
Message<String> message = (Message<String>) collector
|
||||
Message<byte[]> message = (Message<byte[]>) collector
|
||||
.forChannel(processor.output()).poll(1, TimeUnit.SECONDS);
|
||||
TestStringProcessor testStringProcessor = context
|
||||
.getBean(TestStringProcessor.class);
|
||||
assertThat(testStringProcessor.receivedPojos).hasSize(1);
|
||||
assertThat(testStringProcessor.receivedPojos.get(0)).hasFieldOrPropertyWithValue("foo", "barbar" + id);
|
||||
Assertions.assertThat(testStringProcessor.receivedPojos).hasSize(1);
|
||||
Assertions.assertThat(testStringProcessor.receivedPojos.get(0)).hasFieldOrPropertyWithValue("foo", "barbar" + id);
|
||||
assertThat(message).isNotNull();
|
||||
assertThat(message.getPayload()).isEqualTo("barbar" + id);
|
||||
assertThat(new String(message.getPayload())).contains("barbar" + id);
|
||||
context.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,14 @@ public class StreamListenerTestUtils {
|
||||
public void setFoo(String foo) {
|
||||
this.foo = foo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer sb = new StringBuffer("FooPojo{");
|
||||
sb.append("foo='").append(foo).append('\'');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class BarPojo {
|
||||
@@ -68,5 +76,13 @@ public class StreamListenerTestUtils {
|
||||
public void setBar(String bar) {
|
||||
this.bar = bar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer sb = new StringBuffer("BarPojo{");
|
||||
sb.append("bar='").append(bar).append('\'');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,12 +45,13 @@ import static org.springframework.cloud.stream.binding.StreamListenerErrorMessag
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Ilayaperumal Gopinathan
|
||||
* @author Vinicius Carvalho
|
||||
*/
|
||||
public class StreamListenerWithAnnotatedInputOutputArgsTests {
|
||||
|
||||
@Test
|
||||
public void testInputOutputArgs() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication.run(TestInputOutputArgs.class, "--server.port=0");
|
||||
ConfigurableApplicationContext context = SpringApplication.run(TestInputOutputArgs.class, "--server.port=0", "--spring.cloud.stream.bindings.output.contentType=text/plain", "--spring.jmx.enabled=false");
|
||||
sendMessageAndValidate(context);
|
||||
}
|
||||
|
||||
@@ -68,7 +69,7 @@ public class StreamListenerWithAnnotatedInputOutputArgsTests {
|
||||
@Test
|
||||
public void testInputOutputArgsWithInvalidBindableTarget() {
|
||||
try {
|
||||
SpringApplication.run(TestInputOutputArgsWithInvalidBindableTarget.class, "--server.port=0");
|
||||
SpringApplication.run(TestInputOutputArgsWithInvalidBindableTarget.class, "--server.port=0","--spring.jmx.enabled=false");
|
||||
fail("Exception expected on using invalid bindable target as method parameter");
|
||||
}
|
||||
catch (BeanCreationException e) {
|
||||
@@ -81,7 +82,7 @@ public class StreamListenerWithAnnotatedInputOutputArgsTests {
|
||||
@Test
|
||||
public void testInputOutputArgsWithParameterOrderChanged() throws Exception {
|
||||
ConfigurableApplicationContext context = SpringApplication
|
||||
.run(TestInputOutputArgsWithParameterOrderChanged.class, "--server.port=0");
|
||||
.run(TestInputOutputArgsWithParameterOrderChanged.class, "--server.port=0", "--spring.cloud.stream.bindings.output.contentType=text/plain","--spring.jmx.enabled=false");
|
||||
sendMessageAndValidate(context);
|
||||
}
|
||||
|
||||
@@ -90,9 +91,9 @@ public class StreamListenerWithAnnotatedInputOutputArgsTests {
|
||||
Processor processor = context.getBean(Processor.class);
|
||||
processor.input().send(MessageBuilder.withPayload("hello").setHeader("contentType", "text/plain").build());
|
||||
MessageCollector messageCollector = context.getBean(MessageCollector.class);
|
||||
Message<?> result = messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
|
||||
Message<byte[]> result = (Message<byte[]>) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getPayload()).isEqualTo("HELLO");
|
||||
assertThat(new String(result.getPayload())).isEqualTo("HELLO");
|
||||
context.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -56,30 +56,30 @@ public class TextPlainConversionTest {
|
||||
public void testTextPlainConversionOnOutput() throws Exception {
|
||||
testProcessor.input().send(MessageBuilder.withPayload("Bar").build());
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<?> received = ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
|
||||
Message<byte[]> received = (Message<byte[]>) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
|
||||
.messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(received).isNotNull();
|
||||
assertThat(received.getPayload()).isEqualTo("Foo{name='Bar'}");
|
||||
assertThat(new String(received.getPayload())).isEqualTo("Foo{name='Bar'}");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testByteArrayConversionOnOutput() throws Exception {
|
||||
testProcessor.output().send(MessageBuilder.withPayload("Bar".getBytes()).build());
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<?> received = ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
|
||||
Message<byte[]> received = (Message<byte[]>) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
|
||||
.messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(received).isNotNull();
|
||||
assertThat(received.getPayload()).isEqualTo("Bar");
|
||||
assertThat(new String(received.getPayload())).isEqualTo("Bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTextPlainConversionOnInputAndOutput() throws Exception {
|
||||
testProcessor.input().send(MessageBuilder.withPayload(new Foo("Bar")).build());
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<?> received = ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
|
||||
Message<byte[]> received = (Message<byte[]>) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
|
||||
.messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(received).isNotNull();
|
||||
assertThat(received.getPayload()).isEqualTo("Foo{name='Foo{name='Bar'}'}");
|
||||
assertThat(new String(received.getPayload())).isEqualTo("Foo{name='Foo{name='Bar'}'}");
|
||||
}
|
||||
|
||||
@EnableBinding(Processor.class)
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.cloud.stream.config;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@@ -33,6 +34,7 @@ import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.converter.MessageConversionException;
|
||||
import org.springframework.messaging.handler.annotation.SendTo;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@@ -40,6 +42,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Vinicius Carvalho
|
||||
* @since 1.2
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@@ -52,16 +55,23 @@ public class TextPlainToJsonConversionTest {
|
||||
@Autowired
|
||||
private BinderFactory binderFactory;
|
||||
|
||||
private ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
@Test
|
||||
public void testNoContentTypeToJsonConversionOnInput() throws Exception {
|
||||
testProcessor.input().send(MessageBuilder.withPayload("{\"name\":\"Bar\"}").build());
|
||||
Message<?> received = ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
|
||||
Message<byte[]> received = (Message<byte[]>) ((TestSupportBinder) binderFactory.getBinder(null, MessageChannel.class))
|
||||
.messageCollector().forChannel(testProcessor.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(received).isNotNull();
|
||||
assertThat(((Foo) received.getPayload()).getName()).isEqualTo("transformed-Bar");
|
||||
Foo foo = mapper.readValue(received.getPayload(),Foo.class);
|
||||
assertThat(foo.getName()).isEqualTo("transformed-Bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
/**
|
||||
* @since 2.0: Conversion from text/plain -> json is no longer supported. Strict contentType only.
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test(expected = MessageConversionException.class)
|
||||
public void testTextPlainToJsonConversionOnInput() throws Exception {
|
||||
testProcessor.input().send(MessageBuilder.withPayload("{\"name\":\"Bar\"}")
|
||||
.setHeader(MessageHeaders.CONTENT_TYPE, "text/plain").build());
|
||||
|
||||
@@ -49,9 +49,10 @@ public class AggregateApplicationTests {
|
||||
TestSupportBinder testSupportBinder = (TestSupportBinder) context.getBean(BinderFactory.class).getBinder(null,
|
||||
MessageChannel.class);
|
||||
MessageChannel processorOutput = testSupportBinder.getChannelForName("output");
|
||||
Message<String> received = (Message<String>) (testSupportBinder.messageCollector().forChannel(processorOutput)
|
||||
Message<byte[]> received = (Message<byte[]>) (testSupportBinder.messageCollector().forChannel(processorOutput)
|
||||
.poll(5, TimeUnit.SECONDS));
|
||||
Assert.assertThat(received, notNullValue());
|
||||
Assert.assertTrue(received.getPayload().endsWith("processed"));
|
||||
String payload = new String(received.getPayload());
|
||||
Assert.assertTrue(payload.endsWith("processed"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,10 @@ import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.messaging.Processor;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.handler.annotation.SendTo;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
|
||||
/**
|
||||
* @author Ilayaperumal Gopinathan
|
||||
@@ -33,7 +36,7 @@ public class TestProcessor {
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
@SendTo(Processor.OUTPUT)
|
||||
public String process(String message) {
|
||||
return message + " processed";
|
||||
public Message<String> process(String message) {
|
||||
return MessageBuilder.withPayload(message + " processed").setHeader(MessageHeaders.CONTENT_TYPE,"text/plain").build();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,8 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.integration.annotation.InboundChannelAdapter;
|
||||
import org.springframework.integration.core.MessageSource;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
|
||||
/**
|
||||
* @author Ilayaperumal Gopinathan
|
||||
@@ -43,7 +44,7 @@ public class TestSource {
|
||||
return new MessageSource<String>() {
|
||||
@Override
|
||||
public Message<String> receive() {
|
||||
return new GenericMessage<>(new SimpleDateFormat("DDMMMYYYY").format(new Date()));
|
||||
return MessageBuilder.withPayload(new SimpleDateFormat("DDMMMYYYY").format(new Date())).setHeader(MessageHeaders.CONTENT_TYPE,"text/plain").build();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,445 @@
|
||||
/*
|
||||
* Copyright 2016 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
|
||||
*
|
||||
* http://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.config.contentType;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.esotericsoftware.kryo.Kryo;
|
||||
import com.esotericsoftware.kryo.io.Output;
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.Input;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.converter.KryoMessageConverter;
|
||||
import org.springframework.cloud.stream.converter.MessageConverterUtils;
|
||||
import org.springframework.cloud.stream.messaging.Source;
|
||||
import org.springframework.cloud.stream.test.binder.MessageCollector;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.SubscribableChannel;
|
||||
import org.springframework.messaging.handler.annotation.Headers;
|
||||
import org.springframework.tuple.Tuple;
|
||||
import org.springframework.tuple.TupleBuilder;
|
||||
import org.springframework.util.MimeType;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Vinicius Carvalho
|
||||
*/
|
||||
public class ContentTypeTests {
|
||||
|
||||
private ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
@Test
|
||||
public void testSendWithDefaultContentType() throws Exception {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SourceApplication.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false")) {
|
||||
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Source source = context.getBean(Source.class);
|
||||
User user = new User("Alice");
|
||||
source.output().send(MessageBuilder.withPayload(user).build());
|
||||
Message<byte[]> message = (Message<byte[]>) collector
|
||||
.forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
User received = mapper.readValue(message.getPayload(), User.class);
|
||||
assertThat(
|
||||
message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
.includes(MimeTypeUtils.APPLICATION_JSON));
|
||||
assertThat(user.getName()).isEqualTo(received.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendJsonAsString() throws Exception {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SourceApplication.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false")) {
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Source source = context.getBean(Source.class);
|
||||
User user = new User("Alice");
|
||||
String json = mapper.writeValueAsString(user);
|
||||
source.output().send(MessageBuilder.withPayload(user).build());
|
||||
Message<byte[]> message = (Message<byte[]>) collector
|
||||
.forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(
|
||||
message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
.includes(MimeTypeUtils.APPLICATION_JSON));
|
||||
assertThat(json.getBytes()).isEqualTo(message.getPayload());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendJsonString() throws Exception{
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SourceApplication.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false")) {
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Source source = context.getBean(Source.class);
|
||||
source.output().send(MessageBuilder.withPayload("foo").build());
|
||||
Message<byte[]> message = (Message<byte[]>) collector
|
||||
.forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(
|
||||
message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
.includes(MimeTypeUtils.APPLICATION_JSON));
|
||||
assertThat("\"foo\"".getBytes()).isEqualTo(message.getPayload());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendBynaryDataWithoutContentType() throws Exception {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SourceApplication.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false")) {
|
||||
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Source source = context.getBean(Source.class);
|
||||
byte[] data = new byte[] { 0, 1, 2, 3 };
|
||||
source.output().send(MessageBuilder.withPayload(data).build());
|
||||
Message<byte[]> message = (Message<byte[]>) collector
|
||||
.forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(
|
||||
message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
.includes(MimeTypeUtils.APPLICATION_OCTET_STREAM));
|
||||
assertThat(message.getPayload()).isEqualTo(data);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendBinaryDataWithContentType() throws Exception {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SourceApplication.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false",
|
||||
"--spring.cloud.stream.bindings.output.contentType=image/jpeg")) {
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Source source = context.getBean(Source.class);
|
||||
byte[] data = new byte[] { 0, 1, 2, 3 };
|
||||
source.output().send(MessageBuilder.withPayload(data)
|
||||
.build());
|
||||
Message<byte[]> message = (Message<byte[]>) collector
|
||||
.forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
.includes(MimeTypeUtils.IMAGE_JPEG));
|
||||
assertThat(message.getPayload()).isEqualTo(data);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendBinaryDataWithContentTypeUsingHeaders() throws Exception {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SourceApplication.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false")) {
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Source source = context.getBean(Source.class);
|
||||
byte[] data = new byte[] { 0, 1, 2, 3 };
|
||||
source.output().send(MessageBuilder.withPayload(data)
|
||||
.setHeader(MessageHeaders.CONTENT_TYPE,MimeTypeUtils.IMAGE_JPEG)
|
||||
.build());
|
||||
Message<byte[]> message = (Message<byte[]>) collector
|
||||
.forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
.includes(MimeTypeUtils.IMAGE_JPEG));
|
||||
assertThat(message.getPayload()).isEqualTo(data);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendJavaSerializable() throws Exception {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SourceApplication.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false",
|
||||
"--spring.cloud.stream.bindings.output.contentType=application/x-java-serialized-object")) {
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Source source = context.getBean(Source.class);
|
||||
User user = new User("Alice");
|
||||
source.output().send(MessageBuilder.withPayload(user).build());
|
||||
Message<byte[]> message = (Message<byte[]>) collector
|
||||
.forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
.includes(MessageConverterUtils.X_JAVA_SERIALIZED_OBJECT));
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream((byte[]) (message.getPayload()));
|
||||
User received = (User) new ObjectInputStream(bis).readObject();
|
||||
assertThat(user.getName()).isEqualTo(received.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendKryoSerialized() throws Exception {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SourceApplication.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false",
|
||||
"--spring.cloud.stream.bindings.output.contentType=application/x-java-object")) {
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Kryo kryo = new Kryo();
|
||||
Source source = context.getBean(Source.class);
|
||||
User user = new User("Alice");
|
||||
source.output().send(MessageBuilder.withPayload(user).build());
|
||||
Message<byte[]> message = (Message<byte[]>) collector
|
||||
.forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
com.esotericsoftware.kryo.io.Input input = new com.esotericsoftware.kryo.io.Input(new ByteArrayInputStream(message.getPayload()));
|
||||
User received = kryo.readObject(input,User.class);
|
||||
input.close();
|
||||
assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
.includes(MimeType.valueOf(KryoMessageConverter.KRYO_MIME_TYPE)));
|
||||
assertThat(user.getName()).isEqualTo(received.getName());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendStringType() throws Exception{
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SourceApplication.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false",
|
||||
"--spring.cloud.stream.bindings.output.contentType=text/plain")) {
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Source source = context.getBean(Source.class);
|
||||
User user = new User("Alice");
|
||||
source.output().send(MessageBuilder.withPayload(user).build());
|
||||
Message<byte[]> message = (Message<byte[]>) collector
|
||||
.forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
.includes(MimeTypeUtils.TEXT_PLAIN));
|
||||
assertThat(message.getPayload()).isEqualTo(user.toString().getBytes());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendTuple() throws Exception {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SourceApplication.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false",
|
||||
"--spring.cloud.stream.bindings.output.contentType=application/x-spring-tuple")) {
|
||||
MessageCollector collector = context.getBean(MessageCollector.class);
|
||||
Source source = context.getBean(Source.class);
|
||||
Tuple tuple = TupleBuilder.tuple().of("foo","bar");
|
||||
source.output().send(MessageBuilder.withPayload(tuple).build());
|
||||
Message<byte[]> message = (Message<byte[]>) collector
|
||||
.forChannel(source.output()).poll(1, TimeUnit.SECONDS);
|
||||
assertThat(message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class)
|
||||
.includes(MessageConverterUtils.X_SPRING_TUPLE));
|
||||
assertThat(TupleBuilder.fromString(new String(message.getPayload()))).isEqualTo(tuple);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceiveWithDefaults() throws Exception {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SinkApplication.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false")) {
|
||||
TestSink testSink = context.getBean(TestSink.class);
|
||||
SinkApplication sourceApp = context.getBean(SinkApplication.class);
|
||||
User user = new User("Alice");
|
||||
testSink.pojo().send(MessageBuilder.withPayload(mapper.writeValueAsBytes(user)).build());
|
||||
Map<String,Object> headers = (Map<String, Object>) sourceApp.arguments.pop();
|
||||
User received = (User)sourceApp.arguments.pop();
|
||||
assertThat(((MimeType)headers.get(MessageHeaders.CONTENT_TYPE))
|
||||
.includes(MimeTypeUtils.APPLICATION_JSON));
|
||||
assertThat(user.getName()).isEqualTo(received.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceiveRawWithDifferentContentTypes() throws Exception {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SinkApplication.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false")) {
|
||||
TestSink testSink = context.getBean(TestSink.class);
|
||||
SinkApplication sourceApp = context.getBean(SinkApplication.class);
|
||||
testSink.raw().send(MessageBuilder.withPayload(new byte[4])
|
||||
.setHeader(MessageHeaders.CONTENT_TYPE,MimeTypeUtils.IMAGE_JPEG)
|
||||
.build());
|
||||
testSink.raw().send(MessageBuilder.withPayload(new byte[4])
|
||||
.setHeader(MessageHeaders.CONTENT_TYPE,MimeTypeUtils.IMAGE_GIF)
|
||||
.build());
|
||||
Map<String,Object> headers = (Map<String, Object>) sourceApp.arguments.pop();
|
||||
sourceApp.arguments.pop();
|
||||
assertThat(((MimeType)headers.get(MessageHeaders.CONTENT_TYPE))
|
||||
.includes(MimeTypeUtils.IMAGE_GIF));
|
||||
headers = (Map<String, Object>) sourceApp.arguments.pop();
|
||||
sourceApp.arguments.pop();
|
||||
assertThat(((MimeType)headers.get(MessageHeaders.CONTENT_TYPE))
|
||||
.includes(MimeTypeUtils.IMAGE_JPEG));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceiveKryoPayload() throws Exception {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SinkApplication.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false",
|
||||
"--spring.cloud.stream.bindings.pojo_input.contentType=application/x-java-object"
|
||||
)) {
|
||||
TestSink testSink = context.getBean(TestSink.class);
|
||||
SinkApplication sourceApp = context.getBean(SinkApplication.class);
|
||||
Kryo kryo = new Kryo();
|
||||
User user = new User("Alice");
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
Output output = new Output(baos);
|
||||
kryo.writeObject(output,user);
|
||||
output.close();
|
||||
testSink.pojo().send(MessageBuilder.withPayload(baos.toByteArray()).build());
|
||||
Map<String,Object> headers = (Map<String, Object>) sourceApp.arguments.pop();
|
||||
User received = (User)sourceApp.arguments.pop();
|
||||
assertThat(((MimeType)headers.get(MessageHeaders.CONTENT_TYPE))
|
||||
.includes(MimeType.valueOf(KryoMessageConverter.KRYO_MIME_TYPE)));
|
||||
assertThat(user.getName()).isEqualTo(received.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceiveKryoWithHeadersOverridingDefault() throws Exception{
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SinkApplication.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false"
|
||||
)) {
|
||||
TestSink testSink = context.getBean(TestSink.class);
|
||||
SinkApplication sourceApp = context.getBean(SinkApplication.class);
|
||||
Kryo kryo = new Kryo();
|
||||
User user = new User("Alice");
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
Output output = new Output(baos);
|
||||
kryo.writeObject(output,user);
|
||||
output.close();
|
||||
testSink.pojo().send(MessageBuilder.withPayload(baos.toByteArray())
|
||||
.setHeader(MessageHeaders.CONTENT_TYPE, MimeType.valueOf(KryoMessageConverter.KRYO_MIME_TYPE))
|
||||
.build());
|
||||
Map<String,Object> headers = (Map<String, Object>) sourceApp.arguments.pop();
|
||||
User received = (User)sourceApp.arguments.pop();
|
||||
assertThat(((MimeType)headers.get(MessageHeaders.CONTENT_TYPE))
|
||||
.includes(MimeType.valueOf(KryoMessageConverter.KRYO_MIME_TYPE)));
|
||||
assertThat(user.getName()).isEqualTo(received.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReceiveJavaSerializable() throws Exception {
|
||||
try (ConfigurableApplicationContext context = SpringApplication.run(
|
||||
SinkApplication.class, "--server.port=0",
|
||||
"--spring.jmx.enabled=false",
|
||||
"--spring.cloud.stream.bindings.pojo_input.contentType=application/x-java-serialized-object"
|
||||
)) {
|
||||
TestSink testSink = context.getBean(TestSink.class);
|
||||
SinkApplication sourceApp = context.getBean(SinkApplication.class);
|
||||
User user = new User("Alice");
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
new ObjectOutputStream(baos).writeObject(user);
|
||||
testSink.pojo().send(MessageBuilder.withPayload(baos.toByteArray()).build());
|
||||
Map<String,Object> headers = (Map<String, Object>) sourceApp.arguments.pop();
|
||||
User received = (User)sourceApp.arguments.pop();
|
||||
assertThat(((MimeType)headers.get(MessageHeaders.CONTENT_TYPE))
|
||||
.includes(MessageConverterUtils.X_JAVA_SERIALIZED_OBJECT));
|
||||
assertThat(user.getName()).isEqualTo(received.getName());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@EnableBinding(Source.class)
|
||||
@SpringBootApplication
|
||||
public static class SourceApplication {
|
||||
}
|
||||
|
||||
@EnableBinding(TestSink.class)
|
||||
@SpringBootApplication
|
||||
public static class SinkApplication {
|
||||
|
||||
public LinkedList arguments = new LinkedList();
|
||||
|
||||
@StreamListener("POJO_INPUT")
|
||||
public void receive(User user, @Headers Map<String, Object> headers){
|
||||
arguments.push(user);
|
||||
arguments.push(headers);
|
||||
}
|
||||
|
||||
@StreamListener("TUPLE_INPUT")
|
||||
public void receive(Tuple tuple){
|
||||
}
|
||||
|
||||
@StreamListener("STRING_INPUT")
|
||||
public void receive(String string){
|
||||
}
|
||||
|
||||
@StreamListener("RAW_INPUT")
|
||||
public void receive(byte[] data, @Headers Map<String, Object> headers){
|
||||
arguments.push(data);
|
||||
arguments.push(headers);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface TestSink {
|
||||
|
||||
@Input("POJO_INPUT")
|
||||
SubscribableChannel pojo();
|
||||
|
||||
@Input("STRING_INPUT")
|
||||
SubscribableChannel string();
|
||||
|
||||
@Input("TUPLE_INPUT")
|
||||
SubscribableChannel tuple();
|
||||
|
||||
@Input("RAW_INPUT")
|
||||
SubscribableChannel raw();
|
||||
|
||||
}
|
||||
|
||||
public static class User implements Serializable {
|
||||
|
||||
private String name;
|
||||
|
||||
public User(){}
|
||||
|
||||
@JsonCreator
|
||||
public User(@JsonProperty("name") String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer sb = new StringBuffer("User{");
|
||||
sb.append("name='").append(name).append('\'');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
spring.cloud.stream.bindings.output.destination=partOut
|
||||
spring.cloud.stream.bindings.output.producer.partitionKeyExpression=payload
|
||||
spring.cloud.stream.bindings.output.producer.partitionCount=3
|
||||
|
||||
|
||||
Reference in New Issue
Block a user