INT-1145 Retry Write After Socket Close and Clean up Reader in o/b Gateway
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.integration.ip.tcp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
|
||||
@@ -95,7 +96,16 @@ public abstract class AbstractTcpSendingMessageHandler extends
|
||||
*/
|
||||
public void handleMessage(final Message<?> message) throws MessageRejectedException,
|
||||
MessageHandlingException, MessageDeliveryException {
|
||||
doWrite(message);
|
||||
try {
|
||||
doWrite(message);
|
||||
} catch (MessageMappingException e) {
|
||||
// retry - socket may have closed
|
||||
if (e.getCause() instanceof IOException) {
|
||||
doWrite(message);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -67,7 +67,8 @@ public class SimpleTcpNetOutboundGateway extends
|
||||
@Override
|
||||
protected synchronized Object handleRequestMessage(Message<?> requestMessage) {
|
||||
this.handler.handleMessage(requestMessage);
|
||||
if (this.reader == null) {
|
||||
if (this.reader == null ||
|
||||
this.reader.getSocket() != handler.getSocket()) {
|
||||
Socket socket = this.handler.getSocket();
|
||||
this.reader = SocketIoUtils.createNetReader(this.messageFormat,
|
||||
this.customSocketReaderClass, socket, this.maxMessageSize,
|
||||
|
||||
@@ -15,6 +15,13 @@
|
||||
*/
|
||||
package org.springframework.integration.ip.tcp;
|
||||
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.net.ServerSocketFactory;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -22,6 +29,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.integration.channel.PollableChannel;
|
||||
import org.springframework.integration.channel.SubscribableChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.ip.util.SocketUtils;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
@@ -109,4 +117,37 @@ public class SimpleTcpNetOutboundGatewayTests {
|
||||
byte[] bytes = (byte[]) replyChannel.receive().getPayload();
|
||||
assertEquals("echo:test", new String(bytes).trim());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOutboundClose() throws Exception {
|
||||
final int port = SocketUtils.findAvailableServerSocket();
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
Thread t = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
ServerSocket ss = ServerSocketFactory.getDefault().createServerSocket(port);
|
||||
latch.countDown();
|
||||
while (true) {
|
||||
Socket s = ss.accept();
|
||||
byte[] b = new byte[1024];
|
||||
s.getInputStream().read(b);
|
||||
s.getOutputStream().write("OK\r\n".getBytes());
|
||||
s.close();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}});
|
||||
t.start();
|
||||
latch.await(2000, TimeUnit.MILLISECONDS);
|
||||
SimpleTcpNetOutboundGateway gateway = new SimpleTcpNetOutboundGateway
|
||||
("localhost", port);
|
||||
gateway.setMessageFormat(MessageFormats.FORMAT_CRLF);
|
||||
Message<String> message = MessageBuilder.withPayload("test").build();
|
||||
byte[] bytes = (byte[]) gateway.handleRequestMessage(message);
|
||||
assertEquals("OK", new String(bytes));
|
||||
bytes = (byte[]) gateway.handleRequestMessage(message);
|
||||
assertEquals("OK", new String(bytes));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user