GH-1106 Addressed backward/forward contentType compatibility issues

Fixes #1106

- This PR builds on the previous PR with commit hash 6c259be6... (pr/1112)
- Added support in AbstractBinderTests to create bindable channel based on determining channel input type based on it's name (i.e., *input*)
- Added LegacyContentTypeHeaderInterceptor to TestSupportBinder to restor the previous behavior of MessageCollector for cases
  where Message's payload content type is a variant of 'text'.
- Restored tests that use MessageCollector to depend on proper payload type
- Added 'deserialize' routine back to MessageSerializationUtils
- Polished MessageConverterConfigurer.LegacyContentTypeHeaderInterceptor to remove conditional original-content-type header logic
- Removed default contentType from BindingProperties
- Restored tests that use MessageCollector to depend on proper payload type
- polishing
- fixed Kryo/Java serialization
- Fixed ser/de for "application/json" and contentType equals
- Fixed of ser/de of JSON strings to ensure that Strings are not re-quoted
- Fixed how we comparing contentTypes
- more polishing
- Fixed NPE in MessageSerializationUtils
- Make bindings and consumer groups in new tests added to AbstractBinderTests mutually exclusive
This commit is contained in:
Oleg Zhurakousky
2017-10-28 18:02:42 -04:00
committed by Soby Chacko
parent 6c259be62b
commit a7fdf6dbb2
48 changed files with 875 additions and 382 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2016 the original author or authors.
* Copyright 2015-2017 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.
@@ -27,7 +27,9 @@ import org.springframework.cloud.stream.binder.Binder;
import org.springframework.cloud.stream.binder.Binding;
import org.springframework.cloud.stream.binder.ConsumerProperties;
import org.springframework.cloud.stream.binder.ProducerProperties;
import org.springframework.cloud.stream.binding.MessageConverterConfigurer;
import org.springframework.cloud.stream.test.matcher.MessageQueueMatcher;
import org.springframework.integration.channel.AbstractMessageChannel;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
@@ -47,6 +49,7 @@ import org.springframework.util.Assert;
* @author Eric Bottard
* @author Gary Russell
* @author Mark Fisher
* @author Oleg Zhurakousky
* @see MessageQueueMatcher
*/
public class TestSupportBinder implements Binder<MessageChannel, ConsumerProperties, ProducerProperties> {
@@ -97,6 +100,8 @@ public class TestSupportBinder implements Binder<MessageChannel, ConsumerPropert
private final Map<MessageChannel, BlockingQueue<Message<?>>> results = new HashMap<>();
private BlockingQueue<Message<?>> register(MessageChannel channel) {
// we need to add this intercepter to ensure MessageCollector's compatibility with previous versions of SCSt
((AbstractMessageChannel)channel).addInterceptor(new MessageConverterConfigurer.InboundMessageConvertingInterceptor());
LinkedBlockingDeque<Message<?>> result = new LinkedBlockingDeque<>();
Assert.isTrue(!results.containsKey(channel), "Channel [" + channel + "] was already bound");
results.put(channel, result);

View File

@@ -52,13 +52,14 @@ public class AggregateWithBeanTest {
public AggregateApplication aggregateApplication;
@Test
@SuppressWarnings("unchecked")
public void testAggregateApplication() throws InterruptedException {
Processor uppercaseProcessor = aggregateApplication.getBinding(Processor.class, "upper");
Processor suffixProcessor = aggregateApplication.getBinding(Processor.class, "suffix");
uppercaseProcessor.input().send(MessageBuilder.withPayload("Hello").build());
Message<byte[]> receivedMessage = (Message<byte[]>) messageCollector.forChannel(suffixProcessor.output()).poll(1, TimeUnit.SECONDS);
Message<String> receivedMessage = (Message<String>) messageCollector.forChannel(suffixProcessor.output()).poll(1, TimeUnit.SECONDS);
assertThat(receivedMessage).isNotNull();
assertThat(receivedMessage.getPayload()).isEqualTo("HELLO WORLD!".getBytes());
assertThat(receivedMessage.getPayload()).isEqualTo("HELLO WORLD!");
}
@SpringBootApplication

View File

@@ -42,6 +42,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
public class AggregateWithMainTest {
@SuppressWarnings("unchecked")
@Test
public void testAggregateApplication() throws InterruptedException {
// emulate a main method
@@ -55,9 +56,9 @@ public class AggregateWithMainTest {
Processor uppercaseProcessor = aggregateAccessor.getBinding(Processor.class, "upper");
Processor suffixProcessor = aggregateAccessor.getBinding(Processor.class, "suffix");
uppercaseProcessor.input().send(MessageBuilder.withPayload("Hello").build());
Message<byte[]> receivedMessage = (Message<byte[]>) messageCollector.forChannel(suffixProcessor.output()).poll(1, TimeUnit.SECONDS);
Message<String> receivedMessage = (Message<String>) messageCollector.forChannel(suffixProcessor.output()).poll(1, TimeUnit.SECONDS);
assertThat(receivedMessage).isNotNull();
assertThat(receivedMessage.getPayload()).isEqualTo("HELLO WORLD!".getBytes());
assertThat(receivedMessage.getPayload()).isEqualTo("HELLO WORLD!");
context.close();
}

View File

@@ -55,13 +55,14 @@ public class AutoconfigurationDisabledTest {
@Autowired
public Processor processor;
@SuppressWarnings("unchecked")
@Test
public void testAutoconfigurationDisabled() throws Exception {
processor.input().send(MessageBuilder.withPayload("Hello").build());
// Since the interaction is synchronous, the result should be immediate
Message<byte[]> response = (Message<byte[]>) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
Message<String> response = (Message<String>) messageCollector.forChannel(processor.output()).poll(1000, TimeUnit.MILLISECONDS);
assertThat(response).isNotNull();
assertThat(response.getPayload()).isEqualTo("Hello world".getBytes());
assertThat(response.getPayload()).isEqualTo("Hello world");
}
@SpringBootApplication(exclude = TestSupportBinderAutoConfiguration.class)

View File

@@ -22,9 +22,7 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
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.binder.BinderFactory;
import org.springframework.cloud.stream.messaging.Processor;
import org.springframework.cloud.stream.test.binder.MessageCollector;
import org.springframework.integration.annotation.Transformer;
@@ -45,14 +43,10 @@ import static org.assertj.core.api.Assertions.assertThat;
@DirtiesContext
public class ExampleTest {
@Autowired
private BinderFactory binderFactory;
@Autowired
private MessageCollector messageCollector;
@Autowired
@Bindings(MyProcessor.class)
private Processor processor;
@Test
@@ -60,8 +54,8 @@ public class ExampleTest {
public void testWiring() {
Message<String> message = new GenericMessage<>("hello");
this.processor.input().send(message);
Message<byte[]> received = (Message<byte[]>) this.messageCollector.forChannel(this.processor.output()).poll();
assertThat(received.getPayload()).isEqualTo("hello world".getBytes());
Message<String> received = (Message<String>) this.messageCollector.forChannel(this.processor.output()).poll();
assertThat(received.getPayload()).isEqualTo("hello world");
}
@SpringBootApplication