INT-3779: CodecMessageConverter and Docs

JIRA: https://jira.spring.io/browse/INT-3779

Fix timeouts for the `EnableIntegrationTests`: https://build.spring.io/browse/INT-B41-385
This commit is contained in:
Gary Russell
2015-08-03 10:31:35 -04:00
committed by Artem Bilan
parent 455a146a1f
commit adb0f43aa8
15 changed files with 517 additions and 9 deletions

View File

@@ -25,18 +25,17 @@ import com.esotericsoftware.kryo.Registration;
* A {@link KryoRegistrar} used to validateRegistration a File serializer.
*
* @author David Turanski
* @author Gary Russell
* @since 4.2
*/
public class FileKryoRegistrar extends AbstractKryoRegistrar {
private final static int DEFAULT_REGISTRATION_ID = 40;
private final int registrationId;
private final FileSerializer fileSerializer = new FileSerializer();
public FileKryoRegistrar() {
this.registrationId = DEFAULT_REGISTRATION_ID;
this.registrationId = RegistrationIds.DEFAULT_FILE_REGISTRATION_ID;
}
/**

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2015 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.integration.codec.kryo;
/**
* {@link PojoCodec} configured to encode/decode {@code Message<?>}s.
* @author Gary Russell
* @since 4.2
*
*/
public class MessageCodec extends PojoCodec {
/**
* Construct an instance using the default registration ids for messsage
* headers.
*/
public MessageCodec() {
super(new MessageKryoRegistrar());
}
/**
* Construct an instance using a custom registrar - usually used if different
* registration ids are required for message headers.
* @param registrar the registrar.
*/
public MessageCodec(MessageKryoRegistrar registrar) {
super(registrar);
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2015 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.integration.codec.kryo;
import java.util.HashMap;
import java.util.Map;
import org.springframework.messaging.MessageHeaders;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.Serializer;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
/**
* Kryo Serializer for {@link MessageHeaders}.
* @author David Turanski
* @since 4.2
*/
class MessageHeadersSerializer extends Serializer<MessageHeaders> {
@Override
public void write(Kryo kryo, Output output, MessageHeaders headers) {
HashMap<String, Object> map = new HashMap<String, Object>();
for (Map.Entry<String, Object> entry : headers.entrySet()) {
if (entry.getValue() != null) {
map.put(entry.getKey(), entry.getValue());
}
}
kryo.writeObject(output, map);
}
@Override
public MessageHeaders read(Kryo kryo, Input input, Class<MessageHeaders> type) {
@SuppressWarnings("unchecked")
Map<String, Object> headers = kryo.readObject(input, HashMap.class);
return new MessageHeaders(headers);
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2015 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.integration.codec.kryo;
import java.util.Arrays;
import java.util.List;
import org.springframework.integration.support.MutableMessageHeaders;
import org.springframework.messaging.MessageHeaders;
import com.esotericsoftware.kryo.Registration;
/**
* Registers common MessageHeader types and Serializers.
* @author David Turanski
* @author Gary Russell
* @since 4.2
*/
public class MessageKryoRegistrar extends AbstractKryoRegistrar {
private volatile int messageHeadersRegistrationId = RegistrationIds.DEFAULT_MESSAGEHEADERS_ID;
private volatile int mutableMessageHeadersRegistrationId = RegistrationIds.DEFAULT_MUTABLE_MESSAGEHEADERS_ID;
/**
* Set the registration id for {@code MessageHeaders}.
* @param messageHeadersRegistrationId the id, default 41.
*/
public void setMessageHeadersRegistrationId(int messageHeadersRegistrationId) {
this.messageHeadersRegistrationId = messageHeadersRegistrationId;
}
/**
* Set the registration id for {@code MutableMessageHeaders}.
* @param mutableMessageHeadersRegistrationId the id, default 42.
*/
public void setMutableMessageHeadersRegistrationId(int mutableMessageHeadersRegistrationId) {
this.mutableMessageHeadersRegistrationId = mutableMessageHeadersRegistrationId;
}
@Override
public List<Registration> getRegistrations() {
return Arrays.asList(
new Registration(MessageHeaders.class, new MessageHeadersSerializer(),
this.messageHeadersRegistrationId),
new Registration(MutableMessageHeaders.class, new MutableMessageHeadersSerializer(),
this.mutableMessageHeadersRegistrationId));
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2015 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.integration.codec.kryo;
import java.util.HashMap;
import java.util.Map;
import org.springframework.integration.support.MutableMessageHeaders;
import org.springframework.messaging.MessageHeaders;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
/**
* Kryo Serializer for {@link MutableMessageHeaders}.
* @author David Turanski
* @since 4.2
*/
class MutableMessageHeadersSerializer extends MessageHeadersSerializer {
@Override
public MessageHeaders read(Kryo kryo, Input input, Class<MessageHeaders> type) {
@SuppressWarnings("unchecked")
Map<String, Object> headers = kryo.readObject(input, HashMap.class);
return new MutableMessageHeaders(headers);
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2015 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.integration.codec.kryo;
/**
* Default registration ids for serializers provided by the framework.
*
* @author Gary Russell
* @since 4.2
*
*/
public final class RegistrationIds {
public final static int DEFAULT_FILE_REGISTRATION_ID = 40;
public static final int DEFAULT_MESSAGEHEADERS_ID = 41;
public static final int DEFAULT_MUTABLE_MESSAGEHEADERS_ID = 42;
private RegistrationIds() {}
}

View File

@@ -37,10 +37,11 @@ import org.springframework.util.ObjectUtils;
* @author Gary Russell
* @author Artem Bilan
* @author Stuart Williams
* @author David Turanski
* @since 4.0
*
*/
class MutableMessage<T> implements Message<T>, Serializable {
public class MutableMessage<T> implements Message<T>, Serializable {
private static final long serialVersionUID = -636635024258737500L;
@@ -48,11 +49,11 @@ class MutableMessage<T> implements Message<T>, Serializable {
private final MutableMessageHeaders headers;
MutableMessage(T payload) {
public MutableMessage(T payload) {
this(payload, null);
}
MutableMessage(T payload, Map<String, Object> headers) {
public MutableMessage(T payload, Map<String, Object> headers) {
Assert.notNull(payload, "payload must not be null");
this.payload = payload;

View File

@@ -26,13 +26,14 @@ import org.springframework.messaging.MessageHeaders;
* header map.
*
* @author Stuart Williams
* @author David Turanski
* @since 4.2
*/
class MutableMessageHeaders extends MessageHeaders {
public class MutableMessageHeaders extends MessageHeaders {
private static final long serialVersionUID = 3084692953798643018L;
MutableMessageHeaders(Map<String, Object> headers) {
public MutableMessageHeaders(Map<String, Object> headers) {
super(headers);
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright 2015 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.integration.support.converter;
import java.io.IOException;
import org.springframework.integration.codec.Codec;
import org.springframework.integration.context.IntegrationObjectSupport;
import org.springframework.integration.support.AbstractIntegrationMessageBuilder;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.MessagingException;
import org.springframework.messaging.converter.MessageConverter;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.util.Assert;
/**
* A {@link MessageConverter} that delegates to a {@link Codec} to convert
*
* @author Gary Russell
* @since 4.2
*
*/
public class CodecMessageConverter extends IntegrationObjectSupport implements MessageConverter {
private final Codec codec;
private final Class<?> messageClass;
public CodecMessageConverter(Codec codec) {
this.codec = codec;
this.messageClass = GenericMessage.class;
}
@Override
public Object fromMessage(Message<?> message, Class<?> targetClass) {
try {
return this.codec.encode(message);
}
catch (IOException e) {
throw new MessagingException(message, e);
}
}
@Override
public Message<?> toMessage(Object payload, MessageHeaders headers) {
Assert.isInstanceOf(byte[].class, payload);
try {
Message<?> decoded = (Message<?>) this.codec.decode((byte[]) payload, messageClass);
if (headers != null) {
AbstractIntegrationMessageBuilder<?> builder = getMessageBuilderFactory().fromMessage(decoded);
builder.copyHeaders(headers);
return builder.build();
}
else {
return decoded;
}
}
catch (IOException e) {
throw new MessagingException("Failed to decode", e);
}
}
}

View File

@@ -1262,7 +1262,7 @@ public class EnableIntegrationTests {
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@MessagingGateway(defaultRequestChannel = "gatewayChannel", reactorEnvironment = "reactorEnv",
defaultRequestTimeout="${default.request.timeout:23}", defaultReplyTimeout="#{34}",
defaultRequestTimeout="${default.request.timeout:12300}", defaultReplyTimeout="#{13400}",
defaultHeaders = @GatewayHeader(name = "foo", value = "FOO"))
public @interface TestMessagingGateway {