/*
* Copyright 2013 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.xd.dirt.integration.bus;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import java.io.IOException;
import java.util.Collections;
import java.util.Properties;
import org.junit.Before;
import org.junit.Test;
import org.springframework.integration.codec.kryo.PojoCodec;
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.ContentTypeResolver;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.util.MimeType;
import org.springframework.util.MimeTypeUtils;
import org.springframework.xd.dirt.integration.bus.MessageBusSupport.JavaClassMimeTypeConversion;
import org.springframework.xd.tuple.DefaultTuple;
import org.springframework.xd.tuple.Tuple;
import org.springframework.xd.tuple.TupleBuilder;
import org.springframework.xd.tuple.serializer.kryo.TupleKryoRegistrar;
/**
* @author Gary Russell
* @author David Turanski
*/
public class MessageBusSupportTests {
private ContentTypeResolver contentTypeResolver = new StringConvertingContentTypeResolver();
private final TestMessageBus messageBus = new TestMessageBus();
@SuppressWarnings({"unchecked", "rawtypes"})
@Before
public void setUp() {
messageBus.setCodec(new PojoCodec(new TupleKryoRegistrar()));
}
@Test
public void testBytesPassThru() {
byte[] payload = "foo".getBytes();
Message<byte[]> message = MessageBuilder.withPayload(payload).build();
MessageValues converted = messageBus.serializePayloadIfNecessary(message
);
assertSame(payload, converted.getPayload());
Message<?> convertedMessage = converted.toMessage();
assertSame(payload, convertedMessage.getPayload());
assertEquals(MimeTypeUtils.APPLICATION_OCTET_STREAM,
contentTypeResolver.resolve(convertedMessage.getHeaders()));
MessageValues reconstructed = messageBus.deserializePayloadIfNecessary(convertedMessage);
payload = (byte[]) reconstructed.getPayload();
assertSame(converted.getPayload(), payload);
assertNull(reconstructed.get(XdHeaders.XD_ORIGINAL_CONTENT_TYPE));
}
@Test
public void testBytesPassThruContentType() {
byte[] payload = "foo".getBytes();
Message<byte[]> message = MessageBuilder.withPayload(payload)
.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_OCTET_STREAM_VALUE)
.build();
MessageValues messageValues = messageBus.serializePayloadIfNecessary(message
);
Message<?> converted = messageValues.toMessage();
assertSame(payload, converted.getPayload());
assertEquals(MimeTypeUtils.APPLICATION_OCTET_STREAM,
contentTypeResolver.resolve(converted.getHeaders()));
MessageValues reconstructed = messageBus.deserializePayloadIfNecessary(converted);
payload = (byte[]) reconstructed.getPayload();
assertSame(converted.getPayload(), payload);
assertEquals(MimeTypeUtils.APPLICATION_OCTET_STREAM_VALUE,
reconstructed.get(MessageHeaders.CONTENT_TYPE));
assertNull(reconstructed.get(XdHeaders.XD_ORIGINAL_CONTENT_TYPE));
}
@Test
public void testString() throws IOException {
MessageValues convertedValues = messageBus.serializePayloadIfNecessary(
new GenericMessage<String>("foo"));
Message<?> converted = convertedValues.toMessage();
assertEquals(MimeTypeUtils.TEXT_PLAIN,
contentTypeResolver.resolve(converted.getHeaders()));
MessageValues reconstructed = messageBus.deserializePayloadIfNecessary(converted);
assertEquals("foo", reconstructed.getPayload());
assertNull(reconstructed.get(MessageHeaders.CONTENT_TYPE));
}
@Test
public void testContentTypePreserved() throws IOException {
Message<String> inbound = MessageBuilder.withPayload("{\"foo\":\"foo\"}")
.copyHeaders(Collections.singletonMap(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON))
.build();
MessageValues convertedValues = messageBus.serializePayloadIfNecessary(
inbound);
Message<?> converted = convertedValues.toMessage();
assertEquals(MimeTypeUtils.TEXT_PLAIN,
contentTypeResolver.resolve(converted.getHeaders()));
assertEquals(MimeTypeUtils.APPLICATION_JSON,
converted.getHeaders().get(XdHeaders.XD_ORIGINAL_CONTENT_TYPE));
MessageValues reconstructed = messageBus.deserializePayloadIfNecessary(converted);
assertEquals("{\"foo\":\"foo\"}", reconstructed.getPayload());
assertEquals(MimeTypeUtils.APPLICATION_JSON, reconstructed.get(MessageHeaders.CONTENT_TYPE));
}
@Test
public void testPojoSerialization() {
MessageValues convertedValues = messageBus.serializePayloadIfNecessary(
new GenericMessage<Foo>(new Foo("bar"))
);
Message<?> converted = convertedValues.toMessage();
MimeType mimeType = contentTypeResolver.resolve(converted.getHeaders());
assertEquals("application", mimeType.getType());
assertEquals("x-java-object", mimeType.getSubtype());
assertEquals(Foo.class.getName(), mimeType.getParameter("type"));
MessageValues reconstructed = messageBus.deserializePayloadIfNecessary(converted);
assertEquals("bar", ((Foo) reconstructed.getPayload()).getBar());
assertNull(reconstructed.get(MessageHeaders.CONTENT_TYPE));
}
@Test
public void testPojoWithXJavaObjectMimeTypeNoType() {
MessageValues convertedValues = messageBus.serializePayloadIfNecessary(
new GenericMessage<Foo>(new Foo("bar"))
);
Message<?> converted = convertedValues.toMessage();
MimeType mimeType = contentTypeResolver.resolve(converted.getHeaders());
assertEquals("application", mimeType.getType());
assertEquals("x-java-object", mimeType.getSubtype());
assertEquals(Foo.class.getName(), mimeType.getParameter("type"));
MessageValues reconstructed = messageBus.deserializePayloadIfNecessary(converted);
assertEquals("bar", ((Foo) reconstructed.getPayload()).getBar());
assertNull(reconstructed.get(MessageHeaders.CONTENT_TYPE));
}
@Test
public void testPojoWithXJavaObjectMimeTypeExplicitType() {
MessageValues convertedValues = messageBus.serializePayloadIfNecessary(
new GenericMessage<Foo>(new Foo("bar"))
);
Message<?> converted = convertedValues.toMessage();
MimeType mimeType = contentTypeResolver.resolve(converted.getHeaders());
assertEquals("application", mimeType.getType());
assertEquals("x-java-object", mimeType.getSubtype());
assertEquals(Foo.class.getName(), mimeType.getParameter("type"));
MessageValues reconstructed = messageBus.deserializePayloadIfNecessary(converted);
assertEquals("bar", ((Foo) reconstructed.getPayload()).getBar());
assertNull(reconstructed.get(MessageHeaders.CONTENT_TYPE));
}
@Test
public void testTupleSerialization() {
Tuple payload = TupleBuilder.tuple().of("foo", "bar");
MessageValues convertedValues = messageBus.serializePayloadIfNecessary(new GenericMessage<Tuple>(payload)
);
Message<?> converted = convertedValues.toMessage();
MimeType mimeType = contentTypeResolver.resolve(converted.getHeaders());
assertEquals("application", mimeType.getType());
assertEquals("x-java-object", mimeType.getSubtype());
assertEquals(DefaultTuple.class.getName(), mimeType.getParameter("type"));
MessageValues reconstructed = messageBus.deserializePayloadIfNecessary(converted);
assertEquals("bar", ((Tuple) reconstructed.getPayload()).getString("foo"));
assertNull(reconstructed.get(MessageHeaders.CONTENT_TYPE));
}
@Test
public void mimeTypeIsSimpleObject() throws ClassNotFoundException {
MimeType mt = JavaClassMimeTypeConversion.mimeTypeFromObject(new Object());
String className = JavaClassMimeTypeConversion.classNameFromMimeType(mt);
assertEquals(Object.class, Class.forName(className));
}
@Test
public void mimeTypeIsObjectArray() throws ClassNotFoundException {
MimeType mt = JavaClassMimeTypeConversion.mimeTypeFromObject(new String[0]);
String className = JavaClassMimeTypeConversion.classNameFromMimeType(mt);
assertEquals(String[].class, Class.forName(className));
}
@Test
public void mimeTypeIsMultiDimensionalObjectArray() throws ClassNotFoundException {
MimeType mt = JavaClassMimeTypeConversion.mimeTypeFromObject(new String[0][0][0]);
String className = JavaClassMimeTypeConversion.classNameFromMimeType(mt);
assertEquals(String[][][].class, Class.forName(className));
}
@Test
public void mimeTypeIsPrimitiveArray() throws ClassNotFoundException {
MimeType mt = JavaClassMimeTypeConversion.mimeTypeFromObject(new int[0]);
String className = JavaClassMimeTypeConversion.classNameFromMimeType(mt);
assertEquals(int[].class, Class.forName(className));
}
@Test
public void mimeTypeIsMultiDimensionalPrimitiveArray() throws ClassNotFoundException {
MimeType mt = JavaClassMimeTypeConversion.mimeTypeFromObject(new int[0][0][0]);
String className = JavaClassMimeTypeConversion.classNameFromMimeType(mt);
assertEquals(int[][][].class, Class.forName(className));
}
public static class Foo {
private String bar;
public Foo() {
}
public Foo(String bar) {
this.bar = bar;
}
public String getBar() {
return bar;
}
public void setBar(String bar) {
this.bar = bar;
}
}
public static class Bar {
private String foo;
public Bar() {
}
public Bar(String foo) {
this.foo = foo;
}
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
}
public class TestMessageBus extends MessageBusSupport {
@Override
public void bindConsumer(String name, MessageChannel channel, Properties properties) {
}
@Override
public void bindPubSubConsumer(String name, MessageChannel moduleInputChannel,
Properties properties) {
}
@Override
public void bindPubSubProducer(String name, MessageChannel moduleOutputChannel,
Properties properties) {
}
@Override
public void bindProducer(String name, MessageChannel channel, Properties properties) {
}
@Override
public void bindRequestor(String name, MessageChannel requests, MessageChannel replies,
Properties properties) {
}
@Override
public void bindReplier(String name, MessageChannel requests, MessageChannel replies,
Properties properties) {
}
}
}