Remove references to original content type
This commit is contained in:
@@ -174,3 +174,4 @@ TBD
|
||||
- Reactive module in favor of native support via spring-cloud-function. [Details to follow]
|
||||
- Test support module with MessageCollector [Details to follow]
|
||||
- @StreamMessageConverter [Details to follow]
|
||||
- Original content type - removed
|
||||
|
||||
@@ -208,8 +208,6 @@ public abstract class AbstractBinderTests<B extends AbstractTestBinder<? extends
|
||||
Assert.isTrue(latch.await(5, TimeUnit.SECONDS), "Failed to receive message");
|
||||
|
||||
assertThat(inboundMessageRef.get().getPayload()).isEqualTo("foo".getBytes());
|
||||
assertThat(inboundMessageRef.get().getHeaders()
|
||||
.get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE)).isNull();
|
||||
assertThat(inboundMessageRef.get().getHeaders().get(MessageHeaders.CONTENT_TYPE)
|
||||
.toString()).isEqualTo("text/plain");
|
||||
producerBinding.unbind();
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015-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.config;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.binder.BinderHeaders;
|
||||
import org.springframework.cloud.stream.messaging.Sink;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Soby Chacko
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringBootTest(classes = { LegacyContentTypeTests.LegacyTestSink.class })
|
||||
public class LegacyContentTypeTests {
|
||||
|
||||
@Autowired
|
||||
private Sink testSink;
|
||||
|
||||
@Test
|
||||
public void testOriginalContentTypeIsRetrievedForLegacyContentHeaderType()
|
||||
throws Exception {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
MessageHandler messageHandler = new MessageHandler() {
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
assertThat(message.getPayload()).isInstanceOf(byte[].class);
|
||||
assertThat(((byte[]) message.getPayload())).isEqualTo(
|
||||
"{\"message\":\"Hi\"}".getBytes(StandardCharsets.UTF_8));
|
||||
assertThat(
|
||||
message.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString())
|
||||
.isEqualTo("application/json");
|
||||
latch.countDown();
|
||||
}
|
||||
};
|
||||
this.testSink.input().subscribe(messageHandler);
|
||||
this.testSink.input().send(MessageBuilder
|
||||
.withPayload("{\"message\":\"Hi\"}".getBytes())
|
||||
.setHeader(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE, "application/json")
|
||||
.build());
|
||||
assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue();
|
||||
this.testSink.input().unsubscribe(messageHandler);
|
||||
}
|
||||
|
||||
@EnableBinding(Sink.class)
|
||||
@EnableAutoConfiguration
|
||||
public static class LegacyTestSink {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,7 +25,6 @@ import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
|
||||
import org.springframework.cloud.stream.binder.Binder;
|
||||
import org.springframework.cloud.stream.binder.BinderHeaders;
|
||||
import org.springframework.cloud.stream.binder.Binding;
|
||||
import org.springframework.cloud.stream.binder.ConsumerProperties;
|
||||
import org.springframework.cloud.stream.binder.ProducerProperties;
|
||||
@@ -193,12 +192,7 @@ public class TestSupportBinder
|
||||
public Message<?> preSend(Message<?> message, MessageChannel channel) {
|
||||
Class<?> targetClass = null;
|
||||
MessageConverter converter = null;
|
||||
MimeType contentType = message.getHeaders()
|
||||
.containsKey(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE)
|
||||
? MimeType.valueOf(message.getHeaders()
|
||||
.get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE)
|
||||
.toString())
|
||||
: MimeType.valueOf(this.contentTypeResolver
|
||||
MimeType contentType = MimeType.valueOf(this.contentTypeResolver
|
||||
.resolve(message.getHeaders()).toString());
|
||||
|
||||
if (contentType != null) {
|
||||
@@ -225,8 +219,7 @@ public class TestSupportBinder
|
||||
catch (Exception e) {
|
||||
throw new IllegalStateException(
|
||||
"Failed to determine class name for contentType: "
|
||||
+ message.getHeaders().get(
|
||||
BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE),
|
||||
+ message.getHeaders(),
|
||||
e);
|
||||
}
|
||||
}
|
||||
@@ -256,7 +249,7 @@ public class TestSupportBinder
|
||||
message = MessageBuilder.withPayload(payload)
|
||||
.copyHeaders(message.getHeaders())
|
||||
.setHeader(MessageHeaders.CONTENT_TYPE, contentType)
|
||||
.removeHeader(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE).build();
|
||||
.build();
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
@@ -1099,12 +1099,6 @@ public abstract class AbstractMessageChannelBinder<C extends ConsumerProperties,
|
||||
if (contentType != null) {
|
||||
transformed.put(MessageHeaders.CONTENT_TYPE, contentType.toString());
|
||||
}
|
||||
Object originalContentType = transformed
|
||||
.get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE);
|
||||
if (originalContentType != null) {
|
||||
transformed.put(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE,
|
||||
originalContentType.toString());
|
||||
}
|
||||
payload = EmbeddedHeaderUtils.embedHeaders(transformed,
|
||||
this.embeddedHeaders);
|
||||
}
|
||||
|
||||
@@ -28,12 +28,6 @@ import org.springframework.messaging.MessageHeaders;
|
||||
*/
|
||||
public final class BinderHeaders {
|
||||
|
||||
/**
|
||||
* Indicates the original content type of a message that has been transformed in a
|
||||
* native transport format.
|
||||
*/
|
||||
public static final String BINDER_ORIGINAL_CONTENT_TYPE = "originalContentType";
|
||||
|
||||
/**
|
||||
* The headers that will be propagated, by default, by binder implementations that
|
||||
* have no inherent header support (by embedding the headers in the payload).
|
||||
@@ -41,8 +35,7 @@ public final class BinderHeaders {
|
||||
public static final String[] STANDARD_HEADERS = new String[] {
|
||||
IntegrationMessageHeaderAccessor.CORRELATION_ID,
|
||||
IntegrationMessageHeaderAccessor.SEQUENCE_SIZE,
|
||||
IntegrationMessageHeaderAccessor.SEQUENCE_NUMBER, MessageHeaders.CONTENT_TYPE,
|
||||
BINDER_ORIGINAL_CONTENT_TYPE };
|
||||
IntegrationMessageHeaderAccessor.SEQUENCE_NUMBER, MessageHeaders.CONTENT_TYPE};
|
||||
|
||||
private static final String PREFIX = "scst_";
|
||||
|
||||
|
||||
@@ -261,21 +261,21 @@ public class MessageConverterConfigurer
|
||||
.getField(MessageConverterConfigurer.this.headersField,
|
||||
message.getHeaders());
|
||||
MimeType contentType = this.mimeType;
|
||||
/*
|
||||
* NOTE: The below code for BINDER_ORIGINAL_CONTENT_TYPE is to support legacy
|
||||
* message format established in 1.x version of the framework and should/will
|
||||
* no longer be supported in 3.x
|
||||
*/
|
||||
if (message.getHeaders()
|
||||
.containsKey(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE)) {
|
||||
Object ct = message.getHeaders()
|
||||
.get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE);
|
||||
contentType = ct instanceof String ? MimeType.valueOf((String) ct)
|
||||
: (ct == null ? this.mimeType : (MimeType) ct);
|
||||
headersMap.put(MessageHeaders.CONTENT_TYPE, contentType);
|
||||
headersMap.remove(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE);
|
||||
}
|
||||
// == end legacy note
|
||||
// /*
|
||||
// * NOTE: The below code for BINDER_ORIGINAL_CONTENT_TYPE is to support legacy
|
||||
// * message format established in 1.x version of the framework and should/will
|
||||
// * no longer be supported in 3.x
|
||||
// */
|
||||
// if (message.getHeaders()
|
||||
// .containsKey(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE)) {
|
||||
// Object ct = message.getHeaders()
|
||||
// .get(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE);
|
||||
// contentType = ct instanceof String ? MimeType.valueOf((String) ct)
|
||||
// : (ct == null ? this.mimeType : (MimeType) ct);
|
||||
// headersMap.put(MessageHeaders.CONTENT_TYPE, contentType);
|
||||
// headersMap.remove(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE);
|
||||
// }
|
||||
// // == end legacy note
|
||||
|
||||
if (!message.getHeaders().containsKey(MessageHeaders.CONTENT_TYPE)) {
|
||||
headersMap.put(MessageHeaders.CONTENT_TYPE, contentType);
|
||||
@@ -311,17 +311,11 @@ public class MessageConverterConfigurer
|
||||
|
||||
@Override
|
||||
public Message<?> doPreSend(Message<?> message, MessageChannel channel) {
|
||||
// If handler is a function, FunctionInvoker will already perform message
|
||||
// conversion.
|
||||
// In fact in the future we should consider propagating knowledge of the
|
||||
// default content type
|
||||
// to MessageConverters instead of interceptors
|
||||
if (message.getPayload() instanceof byte[]
|
||||
&& message.getHeaders().containsKey(MessageHeaders.CONTENT_TYPE)) {
|
||||
return message;
|
||||
}
|
||||
|
||||
// ===== 1.3 backward compatibility code part-1 ===
|
||||
String oct = message.getHeaders().containsKey(MessageHeaders.CONTENT_TYPE)
|
||||
? message.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString()
|
||||
: null;
|
||||
@@ -329,7 +323,6 @@ public class MessageConverterConfigurer
|
||||
? JavaClassMimeTypeUtils.mimeTypeFromObject(message.getPayload(),
|
||||
ObjectUtils.nullSafeToString(oct)).toString()
|
||||
: oct;
|
||||
// ===== END 1.3 backward compatibility code part-1 ===
|
||||
|
||||
if (!message.getHeaders().containsKey(MessageHeaders.CONTENT_TYPE)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -348,17 +341,13 @@ public class MessageConverterConfigurer
|
||||
+ "' to outbound message.");
|
||||
}
|
||||
|
||||
/// ===== 1.3 backward compatibility code part-2 ===
|
||||
if (ct != null && !ct.equals(oct) && oct != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> headersMap = (Map<String, Object>) ReflectionUtils
|
||||
.getField(MessageConverterConfigurer.this.headersField,
|
||||
outboundMessage.getHeaders());
|
||||
headersMap.put(MessageHeaders.CONTENT_TYPE, MimeType.valueOf(ct));
|
||||
headersMap.put(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE,
|
||||
MimeType.valueOf(oct));
|
||||
}
|
||||
// ===== END 1.3 backward compatibility code part-2 ===
|
||||
return outboundMessage;
|
||||
}
|
||||
|
||||
|
||||
@@ -94,26 +94,6 @@ public class ContentTypeTckTests {
|
||||
assertThat(new String(outputMessage.getPayload())).isEqualTo("oleg");
|
||||
}
|
||||
|
||||
@Test
|
||||
// emulates 1.3 behavior
|
||||
public void stringToMapMessageStreamListenerOriginalContentType() {
|
||||
ApplicationContext context = new SpringApplicationBuilder(
|
||||
StringToMapMessageStreamListener.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\"}";
|
||||
|
||||
Message<byte[]> message = MessageBuilder.withPayload(jsonPayload.getBytes())
|
||||
.setHeader(MessageHeaders.CONTENT_TYPE, "text/plain")
|
||||
.setHeader("originalContentType", "application/json;charset=UTF-8")
|
||||
.build();
|
||||
|
||||
source.send(message);
|
||||
Message<byte[]> outputMessage = target.receive();
|
||||
assertThat(new String(outputMessage.getPayload())).isEqualTo("oleg");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void withInternalPipeline() {
|
||||
ApplicationContext context = new SpringApplicationBuilder(InternalPipeLine.class)
|
||||
|
||||
@@ -21,7 +21,6 @@ import java.util.Collections;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.cloud.stream.binder.BinderHeaders;
|
||||
import org.springframework.cloud.stream.config.BindingProperties;
|
||||
import org.springframework.cloud.stream.config.BindingServiceProperties;
|
||||
import org.springframework.cloud.stream.converter.CompositeMessageConverterFactory;
|
||||
@@ -32,7 +31,6 @@ import org.springframework.messaging.converter.AbstractMessageConverter;
|
||||
import org.springframework.messaging.converter.MessageConversionException;
|
||||
import org.springframework.messaging.converter.MessageConverter;
|
||||
import org.springframework.messaging.support.GenericMessage;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
import org.springframework.util.MimeType;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -105,29 +103,6 @@ public class MessageConverterConfigurerTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConfigureInputChannelWithLegacyContentType() {
|
||||
BindingServiceProperties props = new BindingServiceProperties();
|
||||
BindingProperties bindingProps = new BindingProperties();
|
||||
bindingProps.setContentType("foo/bar");
|
||||
props.setBindings(Collections.singletonMap("foo", bindingProps));
|
||||
CompositeMessageConverterFactory converterFactory = new CompositeMessageConverterFactory(
|
||||
Collections.<MessageConverter>emptyList(), null);
|
||||
MessageConverterConfigurer configurer = new MessageConverterConfigurer(props,
|
||||
converterFactory.getMessageConverterForAllRegistered());
|
||||
QueueChannel in = new QueueChannel();
|
||||
configurer.configureInputChannel(in, "foo");
|
||||
Foo foo = new Foo();
|
||||
in.send(MessageBuilder.withPayload(foo)
|
||||
.setHeader(BinderHeaders.BINDER_ORIGINAL_CONTENT_TYPE, "application/json")
|
||||
.setHeader(BinderHeaders.SCST_VERSION, "1.x").build());
|
||||
Message<?> received = in.receive(0);
|
||||
assertThat(received).isNotNull();
|
||||
assertThat(received.getPayload()).isEqualTo(foo);
|
||||
assertThat(received.getHeaders().get(MessageHeaders.CONTENT_TYPE).toString())
|
||||
.isEqualTo("application/json");
|
||||
}
|
||||
|
||||
public static class Foo {
|
||||
|
||||
private String bar = "bar";
|
||||
|
||||
Reference in New Issue
Block a user