INT-4285: TCP: Add Elastic Raw Deserializer
JIRA: https://jira.spring.io/browse/INT-4285 Buffer grows as needed.
This commit is contained in:
committed by
Artem Bilan
parent
a7ad22adcf
commit
c3031a2c7c
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
* 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.ip.tcp.serializer;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.springframework.core.serializer.Deserializer;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
/**
|
||||
* A deserializer that uses a {@link ByteArrayOutputStream} instead of a fixed buffer,
|
||||
* allowing the buffer to grow as needed. Completion is indicated by the sender closing
|
||||
* the socket.
|
||||
*
|
||||
* @author Gary Russell
|
||||
* @since 5.0
|
||||
*
|
||||
*/
|
||||
public class ByteArrayElasticRawDeserializer implements Deserializer<byte[]> {
|
||||
|
||||
private final int initialBufferSize;
|
||||
|
||||
/**
|
||||
* Construct an instance that uses {@link ByteArrayOutputStream}s with an initial
|
||||
* buffer size of 32;
|
||||
*/
|
||||
public ByteArrayElasticRawDeserializer() {
|
||||
this(32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance that uses {@link ByteArrayOutputStream}s with the provided
|
||||
* initial buffer size.
|
||||
* @param initialBufferSize the initial buffer size.
|
||||
*/
|
||||
public ByteArrayElasticRawDeserializer(int initialBufferSize) {
|
||||
this.initialBufferSize = initialBufferSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] deserialize(InputStream inputStream) throws IOException {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(this.initialBufferSize);
|
||||
StreamUtils.copy(inputStream, out);
|
||||
out.close();
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -141,6 +141,21 @@ public class DeserializationTests {
|
||||
server.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadRawElastic() throws Exception {
|
||||
ServerSocket server = ServerSocketFactory.getDefault().createServerSocket(0);
|
||||
int port = server.getLocalPort();
|
||||
server.setSoTimeout(10000);
|
||||
SocketTestUtils.testSendRaw(port);
|
||||
Socket socket = server.accept();
|
||||
socket.setSoTimeout(5000);
|
||||
ByteArrayElasticRawDeserializer serializer = new ByteArrayElasticRawDeserializer();
|
||||
byte[] out = serializer.deserialize(socket.getInputStream());
|
||||
assertEquals("Data", SocketTestUtils.TEST_STRING + SocketTestUtils.TEST_STRING,
|
||||
new String(out));
|
||||
server.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadSerialized() throws Exception {
|
||||
ServerSocket server = ServerSocketFactory.getDefault().createServerSocket(0);
|
||||
|
||||
@@ -264,6 +264,7 @@ The `ByteArrayRawSerializer`^*^, converts a byte array to a stream of bytes and
|
||||
When using this serializer, message reception will hang until the client closes the socket, or a timeout occurs; a timeout will NOT result in a message.
|
||||
When this serializer is being used, and the client is a Spring Integration application, the client must use a connection factory that is configured with single-use=true - this causes the adapter to close the socket after sending the message; the serializer will not, itself, close the connection.
|
||||
This serializer should only be used with connection factories used by channel adapters (not gateways), and the connection factories should be used by either an inbound or outbound adapter, and not both.
|
||||
Also see `ByteArrayElasticRawDeserializer` below.
|
||||
|
||||
NOTE: Before version 4.2.2, when using NIO, this serializer treated a timeout (during read) as an end of file and the
|
||||
data read so far was emitted as a message.
|
||||
@@ -294,6 +295,11 @@ instead of its super class `AbstractByteArraySerializer`, and implement `doDeser
|
||||
The buffer will be returned to the pool automatically.
|
||||
`AbstractPooledBufferByteArraySerializer` also provides a convenient utility method `copyToSizedArray()`.
|
||||
|
||||
__Version 5.0__ added the `ByteArrayElasticRawDeserializer`.
|
||||
This is similar to the deserializer side of `ByteArrayRawSerializer` above, except it is not necessary to set a `maxMessageSize`.
|
||||
Internally, it uses a `ByteArrayOutputStream` which allows the buffer to grow as needed.
|
||||
The client must close the socket in an orderly manner to signal end of message.
|
||||
|
||||
The `MapJsonSerializer` uses a Jackson `ObjectMapper` to convert between a `Map` and JSON.
|
||||
This can be used in conjunction with a `MessageConvertingTcpMessageMapper` and a `MapMessageConverter` to transfer selected headers and the payload in a JSON format.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user