INT-1486 polish; rename byte array 'serializers' and all test usage
This commit is contained in:
@@ -45,7 +45,7 @@ public abstract class AbstractClientConnectionFactory extends AbstractConnection
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers attributes such as converters, singleUse etc to a new connection.
|
||||
* Transfers attributes such as (de)serializers, singleUse etc to a new connection.
|
||||
* When the connection factory has a reference to a TCPListener (to read
|
||||
* responses), or for single use connections, the connection is executed.
|
||||
* Single use connections need to read from the connection in order to
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.commons.serializer.Deserializer;
|
||||
import org.springframework.commons.serializer.Serializer;
|
||||
import org.springframework.context.SmartLifecycle;
|
||||
import org.springframework.integration.ip.tcp.converter.ByteArrayCrLfConverter;
|
||||
import org.springframework.integration.ip.tcp.serializer.ByteArrayCrLfSerializer;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -68,9 +68,9 @@ public abstract class AbstractConnectionFactory
|
||||
|
||||
protected Executor taskExecutor;
|
||||
|
||||
protected Deserializer<?> deserializer = new ByteArrayCrLfConverter();
|
||||
protected Deserializer<?> deserializer = new ByteArrayCrLfSerializer();
|
||||
|
||||
protected Serializer<?> serializer = new ByteArrayCrLfConverter();
|
||||
protected Serializer<?> serializer = new ByteArrayCrLfSerializer();
|
||||
|
||||
protected TcpMessageMapper mapper = new TcpMessageMapper();
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ public abstract class AbstractServerConnectionFactory extends AbstractConnection
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers attributes such as converters, singleUse etc to a new connection.
|
||||
* Transfers attributes such as (de)serializer, singleUse etc to a new connection.
|
||||
* For single use sockets, enforces a socket timeout (default 10 seconds).
|
||||
* @param connection The new connection.
|
||||
* @param socket The new socket.
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.commons.serializer.Deserializer;
|
||||
import org.springframework.commons.serializer.Serializer;
|
||||
import org.springframework.integration.ip.tcp.converter.AbstractByteArrayStreamingConverter;
|
||||
import org.springframework.integration.ip.tcp.serializer.AbstractByteArraySerializer;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -86,7 +86,7 @@ public abstract class AbstractTcpConnection implements TcpConnection {
|
||||
Assert.notNull(mapper, this.getClass().getName() + " Mapper may not be null");
|
||||
this.mapper = mapper;
|
||||
if (this.serializer != null &&
|
||||
!(this.serializer instanceof AbstractByteArrayStreamingConverter)) {
|
||||
!(this.serializer instanceof AbstractByteArraySerializer)) {
|
||||
mapper.setStringToBytes(false);
|
||||
}
|
||||
}
|
||||
@@ -119,7 +119,7 @@ public abstract class AbstractTcpConnection implements TcpConnection {
|
||||
*/
|
||||
public void setSerializer(Serializer<?> serializer) {
|
||||
this.serializer = serializer;
|
||||
if (!(serializer instanceof AbstractByteArrayStreamingConverter)) {
|
||||
if (!(serializer instanceof AbstractByteArraySerializer)) {
|
||||
this.mapper.setStringToBytes(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.springframework.integration.Message;
|
||||
|
||||
/**
|
||||
* An abstraction over {@link Socket} and {@link SocketChannel} that
|
||||
* sends {@link Message} objects by converting the payload
|
||||
* sends {@link Message} objects by serializing the payload
|
||||
* and streaming it to the destination. Requires a {@link TcpListener}
|
||||
* to receive incoming messages.
|
||||
*
|
||||
@@ -53,7 +53,7 @@ public interface TcpConnection extends Runnable {
|
||||
public void send(Message<?> message) throws Exception;
|
||||
|
||||
/**
|
||||
* Uses the input converter to obtain the message payload
|
||||
* Uses the deserializer to obtain the message payload
|
||||
* from the connection's input stream.
|
||||
* @return The payload
|
||||
* @throws Exception
|
||||
|
||||
@@ -88,7 +88,7 @@ public class TcpMessageMapper implements
|
||||
}
|
||||
else {
|
||||
throw new MessageHandlingException(message,
|
||||
"When using a byte array streaming converter, the socket mapper expects " +
|
||||
"When using a byte array serializer, the socket mapper expects " +
|
||||
"either a byte array or String payload, but received: " + payload.getClass());
|
||||
}
|
||||
return bytes;
|
||||
|
||||
@@ -19,9 +19,10 @@ package org.springframework.integration.ip.tcp.connection;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
|
||||
import org.springframework.commons.serializer.Deserializer;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.ip.tcp.SocketIoUtils;
|
||||
import org.springframework.integration.ip.tcp.converter.SoftEndOfStreamException;
|
||||
import org.springframework.integration.ip.tcp.serializer.SoftEndOfStreamException;
|
||||
|
||||
/**
|
||||
* A TcpConnection that uses and underlying {@link Socket}.
|
||||
@@ -88,7 +89,7 @@ public class TcpNetConnection extends AbstractTcpConnection {
|
||||
* If there is no listener, and this connection is not for single use,
|
||||
* this method exits. When there is a listener, the method runs in a
|
||||
* loop reading input from the connections's stream, data is converted
|
||||
* to an object using the {@link InputStreamingConverter} and the listener's
|
||||
* to an object using the {@link Deserializer} and the listener's
|
||||
* {@link TcpListener#onMessage(Message)} method is called. For single use
|
||||
* connections with no listener, the socket is closed after its timeout
|
||||
* expires. If data is received on a single use socket with no listener,
|
||||
|
||||
@@ -31,7 +31,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.ip.tcp.SocketIoUtils;
|
||||
import org.springframework.integration.ip.tcp.converter.SoftEndOfStreamException;
|
||||
import org.springframework.integration.ip.tcp.serializer.SoftEndOfStreamException;
|
||||
|
||||
/**
|
||||
* A TcpConnection that uses and underlying {@link SocketChannel}.
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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.converter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.commons.serializer.Deserializer;
|
||||
import org.springframework.commons.serializer.Serializer;
|
||||
|
||||
/**
|
||||
* Base class for streaming converters that convert to/from a byte array.
|
||||
*
|
||||
* @author Gary Russell
|
||||
* @since 2.0
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractByteArrayStreamingConverter implements
|
||||
Serializer<byte[]>,
|
||||
Deserializer<byte[]> {
|
||||
|
||||
protected int maxMessageSize = 2048;
|
||||
|
||||
protected Log logger = LogFactory.getLog(this.getClass());
|
||||
|
||||
/**
|
||||
* The maximum supported message size for this converter.
|
||||
* Default 2048.
|
||||
* @return The max message size.
|
||||
*/
|
||||
public int getMaxMessageSize() {
|
||||
return maxMessageSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum supported message size for this converter.
|
||||
* Default 2048.
|
||||
* @param maxMessageSize The max message size.
|
||||
*/
|
||||
public void setMaxMessageSize(int maxMessageSize) {
|
||||
this.maxMessageSize = maxMessageSize;
|
||||
}
|
||||
|
||||
protected void checkClosure(int bite) throws IOException {
|
||||
if (bite < 0) {
|
||||
logger.debug("Socket closed");
|
||||
throw new IOException("Socket closed");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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.converter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Converts data in an InputStream to a byte[]; data is terminated by \r\n
|
||||
* (not included in resulting byte[]).
|
||||
* Writes a byte[] to an OutputStream and adds \r\n.
|
||||
*
|
||||
* @author Gary Russell
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ByteArrayCrLfConverter extends AbstractByteArrayStreamingConverter {
|
||||
|
||||
/**
|
||||
* Converts the data in the inputstream to a byte[]. Data must be terminated
|
||||
* by CRLF (\r\n). Throws a {@link SoftEndOfStreamException} if the stream
|
||||
* is closed immediately after the \r\n (i.e. no data is in the process of
|
||||
* being read).
|
||||
*/
|
||||
public byte[] deserialize(InputStream inputStream) throws IOException {
|
||||
byte[] buffer = new byte[this.maxMessageSize];
|
||||
int n = 0;
|
||||
int bite;
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Available to read:" + inputStream.available());
|
||||
while (true) {
|
||||
bite = inputStream.read();
|
||||
// logger.debug("Read:" + (char) bite);
|
||||
if (bite < 0 && n == 0) {
|
||||
throw new SoftEndOfStreamException("Stream closed between payloads");
|
||||
}
|
||||
checkClosure(bite);
|
||||
if (n > 0 && bite == '\n' && buffer[n-1] == '\r')
|
||||
break;
|
||||
buffer[n++] = (byte) bite;
|
||||
if (n >= this.maxMessageSize) {
|
||||
throw new IOException("CRLF not found before max message length: "
|
||||
+ this.maxMessageSize);
|
||||
}
|
||||
};
|
||||
byte[] assembledData = new byte[n-1];
|
||||
System.arraycopy(buffer, 0, assembledData, 0, n-1);
|
||||
return assembledData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the byte[] to the stream and appends \r\n.
|
||||
*/
|
||||
public void serialize(byte[] bytes, OutputStream outputStream) throws IOException {
|
||||
outputStream.write(bytes);
|
||||
outputStream.write('\r');
|
||||
outputStream.write('\n');
|
||||
outputStream.flush();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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.converter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Converts data in an InputStream to a byte[]; data is preceded by
|
||||
* a 4 byte binary length (network byte order,
|
||||
* not included in resulting byte[]).
|
||||
* Writes a byte[] to an OutputStream after a 4 byte binary length.\
|
||||
* The length field contains the length of data following the length
|
||||
* field.
|
||||
* (network byte order).
|
||||
*
|
||||
* @author Gary Russell
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ByteArrayLengthHeaderConverter extends AbstractByteArrayStreamingConverter {
|
||||
|
||||
private Log logger = LogFactory.getLog(this.getClass());
|
||||
|
||||
/**
|
||||
* Reads a 4 byte length from the stream and then reads that length
|
||||
* from the stream and returns the data in a byte[]. Throws an
|
||||
* IOException if the length field exceeds the maxMessageSize.
|
||||
* Throws a {@link SoftEndOfStreamException} if the stream
|
||||
* is closed between messages.
|
||||
*/
|
||||
public byte[] deserialize(InputStream inputStream) throws IOException {
|
||||
byte[] lengthPart = new byte[4];
|
||||
int status = read(inputStream, lengthPart, true);
|
||||
if (status < 0) {
|
||||
throw new SoftEndOfStreamException("Stream closed between payloads");
|
||||
}
|
||||
int messageLength = ByteBuffer.wrap(lengthPart).getInt();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Message length is " + messageLength);
|
||||
}
|
||||
if (messageLength > this.maxMessageSize) {
|
||||
throw new IOException("Message length " + messageLength +
|
||||
" exceeds max message length: " + this.maxMessageSize);
|
||||
}
|
||||
byte[] messagePart = new byte[messageLength];
|
||||
read(inputStream, messagePart, false);
|
||||
return messagePart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the byte[] to the output stream, preceded by a 4 byte
|
||||
* length in network byte order (big endian).
|
||||
*/
|
||||
public void serialize(byte[] bytes, OutputStream outputStream) throws IOException {
|
||||
ByteBuffer lengthPart = ByteBuffer.allocate(4);
|
||||
lengthPart.putInt(bytes.length);
|
||||
outputStream.write(lengthPart.array());
|
||||
outputStream.write(bytes);
|
||||
outputStream.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads data from the socket and puts the data in buffer. Blocks until
|
||||
* buffer is full or a socket timeout occurs.
|
||||
* @param buffer
|
||||
* @param header true if we are reading the header
|
||||
* @return < 0 if socket closed and not in the middle of a message
|
||||
* @throws IOException
|
||||
*/
|
||||
protected int read(InputStream inputStream, byte[] buffer, boolean header)
|
||||
throws IOException {
|
||||
int lengthRead = 0;
|
||||
int needed = buffer.length;
|
||||
while (lengthRead < needed) {
|
||||
int len;
|
||||
len = inputStream.read(buffer, lengthRead,
|
||||
needed - lengthRead);
|
||||
if (len < 0 && header && lengthRead == 0) {
|
||||
return len;
|
||||
}
|
||||
if (len < 0) {
|
||||
throw new IOException("Stream closed after " + lengthRead + " of " + needed);
|
||||
}
|
||||
lengthRead += len;
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Read " + len + " bytes, buffer is now at " +
|
||||
lengthRead + " of " +
|
||||
needed);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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.converter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.springframework.integration.mapping.MessageMappingException;
|
||||
|
||||
/**
|
||||
* Converts data in an InputStream to a byte[]; data is prefixed by <stx> and
|
||||
* terminated by <etx> (not included in resulting byte[]).
|
||||
* Writes a byte[] to an OutputStream and prefixed by <stx> terminated by <etx>
|
||||
*
|
||||
* @author Gary Russell
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ByteArrayStxEtxConverter extends AbstractByteArrayStreamingConverter {
|
||||
|
||||
public static final int STX = 0x02;
|
||||
|
||||
public static final int ETX = 0x03;
|
||||
|
||||
/**
|
||||
* Converts the data in the inputstream to a byte[]. Data must be prefixed
|
||||
* with an ASCII STX character, and terminated with an ASCII ETX character.
|
||||
* Throws a {@link SoftEndOfStreamException} if the stream
|
||||
* is closed immediately before the STX (i.e. no data is in the process of
|
||||
* being read).
|
||||
*
|
||||
*/
|
||||
public byte[] deserialize(InputStream inputStream) throws IOException {
|
||||
int bite = inputStream.read();
|
||||
if (bite < 0) {
|
||||
throw new SoftEndOfStreamException("Stream closed between payloads");
|
||||
}
|
||||
if (bite != STX)
|
||||
throw new MessageMappingException("Expected STX to begin message");
|
||||
byte[] buffer = new byte[this.maxMessageSize];
|
||||
int n = 0;
|
||||
while ((bite = inputStream.read()) != ETX) {
|
||||
checkClosure(bite);
|
||||
buffer[n++] = (byte) bite;
|
||||
if (n >= this.maxMessageSize) {
|
||||
throw new IOException("ETX not found before max message length: "
|
||||
+ this.maxMessageSize);
|
||||
}
|
||||
}
|
||||
byte[] assembledData = new byte[n];
|
||||
System.arraycopy(buffer, 0, assembledData, 0, n);
|
||||
return assembledData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the byte[] to the stream, prefixed by an ASCII STX character and
|
||||
* terminated with an ASCII ETX character.
|
||||
*/
|
||||
public void serialize(byte[] bytes, OutputStream outputStream) throws IOException {
|
||||
outputStream.write(STX);
|
||||
outputStream.write(bytes);
|
||||
outputStream.write(ETX);
|
||||
outputStream.flush();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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.converter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Used to communicate that a stream has closed, but between logical
|
||||
* messages.
|
||||
*
|
||||
* @author Gary Russell
|
||||
* @since 2.0
|
||||
*
|
||||
*/
|
||||
public class SoftEndOfStreamException extends IOException {
|
||||
|
||||
private static final long serialVersionUID = 7309907445617226978L;
|
||||
|
||||
public SoftEndOfStreamException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public SoftEndOfStreamException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
/**
|
||||
* Byte array converters for putting some protocol on the
|
||||
* wire so we can delimit incoming messages.
|
||||
*/
|
||||
package org.springframework.integration.ip.tcp.converter;
|
||||
|
||||
@@ -299,7 +299,7 @@ the factory, the connection will be closed after a response is received.
|
||||
</xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
A Serializer that converts message payloads to/from output streams/input streams
|
||||
associated with the connection. Default is ByteArrayCrLfConverter. Serializer and Deserializer
|
||||
associated with the connection. Default is ByteArrayCrLfSerializer. Serializer and Deserializer
|
||||
would normally be the same but this is not required.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
@@ -313,7 +313,7 @@ would normally be the same but this is not required.
|
||||
</xsd:appinfo>
|
||||
<xsd:documentation>
|
||||
A Deserializer that converts message payloads to/from output streams/input streams
|
||||
associated with the connection. Default is ByteArrayCrLfConverter. Serializer and Deserializer
|
||||
associated with the connection. Default is ByteArrayCrLfSerializer. Serializer and Deserializer
|
||||
would normally be the same but this is not required.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
|
||||
Reference in New Issue
Block a user