INT-1707 Don't set SO_LINGER unless specified; close socket on send when appropriate, unless SO_LINGER=0; ensure any self-called close() is properly routed through any interceptors; suppress error on read when socket closed normally

This commit is contained in:
Gary Russell
2010-12-22 17:21:40 -05:00
parent abec48dce3
commit cfd61c4218
15 changed files with 444 additions and 72 deletions

View File

@@ -1,13 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<beansProjectDescription>
<version>1</version>
<pluginVersion><![CDATA[2.3.3.201005102200-CI-R3771-B739]]></pluginVersion>
<configSuffixes>
<configSuffix><![CDATA[xml]]></configSuffix>
</configSuffixes>
<enableImports><![CDATA[false]]></enableImports>
<configs>
</configs>
<configSets>
</configSets>
</beansProjectDescription>
<?xml version="1.0" encoding="UTF-8"?>
<beansProjectDescription>
<version>1</version>
<pluginVersion><![CDATA[2.5.1.201011101000-RELEASE]]></pluginVersion>
<configSuffixes>
<configSuffix><![CDATA[xml]]></configSuffix>
</configSuffixes>
<enableImports><![CDATA[false]]></enableImports>
<configs>
<config>src/test/java/org/springframework/integration/ip/tcp/connection/SOLingerTests-context.xml</config>
</configs>
<configSets>
</configSets>
</beansProjectDescription>

View File

@@ -81,7 +81,7 @@ public class TcpSendingMessageHandler extends AbstractMessageHandler implements
public void handleMessageInternal(final Message<?> message) throws MessageRejectedException,
MessageHandlingException, MessageDeliveryException {
if (this.serverConnectionFactory != null) {
// We don't own the connection
// We don't own the connection, we are asynchronously replying
Object connectionId = message.getHeaders().get(IpHeaders.CONNECTION_ID);
TcpConnection connection = connections.get(connectionId);
if (connection != null) {
@@ -97,7 +97,7 @@ public class TcpSendingMessageHandler extends AbstractMessageHandler implements
return;
}
// we own the connection
try {
doWrite(message);
} catch (MessageMappingException e) {

View File

@@ -60,11 +60,11 @@ public abstract class AbstractConnectionFactory
private boolean soTcpNoDelay;
private int soLinger;
private int soLinger = -1; // don't set by default
private boolean soKeepAlive;
private int soTrafficClass;
private int soTrafficClass = -1; // don't set by default
protected Executor taskExecutor;

View File

@@ -16,13 +16,15 @@
package org.springframework.integration.ip.tcp.connection;
import java.net.Socket;
import java.net.SocketException;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.serializer.Deserializer;
import org.springframework.core.serializer.Serializer;
import org.springframework.integration.Message;
import org.springframework.integration.ip.tcp.serializer.AbstractByteArraySerializer;
import org.springframework.util.Assert;
@@ -48,6 +50,8 @@ public abstract class AbstractTcpConnection implements TcpConnection {
protected TcpMessageMapper mapper;
protected TcpListener listener;
private TcpListener actualListener;
protected TcpSender sender;
@@ -59,8 +63,27 @@ public abstract class AbstractTcpConnection implements TcpConnection {
private AtomicLong sequence = new AtomicLong();
public AbstractTcpConnection(boolean server) {
private int soLinger = -1;
public AbstractTcpConnection(Socket socket, boolean server) {
this.server = server;
try {
this.soLinger = socket.getSoLinger();
} catch (SocketException e) { }
}
public void afterSend(Message<?> message) throws Exception {
if (logger.isDebugEnabled())
logger.debug("Message sent " + message);
if (this.singleUse) {
// if (we're a server socket, or a send-only socket), and soLinger <> 0, close
if ((this.isServer() || this.actualListener == null) && this.soLinger != 0) {
if (logger.isDebugEnabled()) {
logger.debug("Closing single-use connection" + this.getConnectionId());
}
this.closeConnection();
}
}
}
/**
@@ -71,7 +94,23 @@ public abstract class AbstractTcpConnection implements TcpConnection {
this.sender.removeDeadConnection(this);
}
}
/**
* If we have been intercepted, propagate the close from the outermost interceptor;
* otherwise, just call close().
*/
protected void closeConnection() {
if (!(this.listener instanceof TcpConnectionInterceptor)) {
close();
return;
}
TcpConnectionInterceptor outerInterceptor = (TcpConnectionInterceptor) this.listener;
while (outerInterceptor.getListener() instanceof TcpConnectionInterceptor) {
outerInterceptor = (TcpConnectionInterceptor) outerInterceptor.getListener();
}
outerInterceptor.close();
}
/**
* @return the mapper
*/
@@ -129,6 +168,16 @@ public abstract class AbstractTcpConnection implements TcpConnection {
*/
public void registerListener(TcpListener listener) {
this.listener = listener;
// Determine the actual listener for this connection
if (!(this.listener instanceof TcpConnectionInterceptor)) {
this.actualListener = this.listener;
} else {
TcpConnectionInterceptor outerInterceptor = (TcpConnectionInterceptor) this.listener;
while (outerInterceptor.getListener() instanceof TcpConnectionInterceptor) {
outerInterceptor = (TcpConnectionInterceptor) outerInterceptor.getListener();
}
this.actualListener = outerInterceptor.getListener();
}
}
/**

View File

@@ -34,7 +34,8 @@ public abstract class AbstractTcpConnectionInterceptor implements TcpConnectionI
private TcpListener tcpListener;
private TcpSender tcpSender;
private Boolean realSender;
public void close() {
this.theConnection.close();
@@ -61,8 +62,8 @@ public abstract class AbstractTcpConnectionInterceptor implements TcpConnectionI
}
public void registerListener(TcpListener listener) {
this.theConnection.registerListener(this);
this.tcpListener = listener;
this.theConnection.registerListener(this);
}
public void registerSender(TcpSender sender) {
@@ -159,6 +160,21 @@ public abstract class AbstractTcpConnectionInterceptor implements TcpConnectionI
public long getConnectionSeq() {
return this.theConnection.getConnectionSeq();
}
TcpSender getSender() {
return this.tcpSender;
}
protected boolean hasRealSender() {
if (this.realSender != null) {
return this.realSender;
}
TcpSender sender = this.getSender();
while (sender != null && sender instanceof AbstractTcpConnectionInterceptor) {
sender = ((AbstractTcpConnectionInterceptor) sender).getSender();
}
this.realSender = sender != null;
return this.realSender;
}
}

View File

@@ -26,8 +26,8 @@ package org.springframework.integration.ip.tcp.connection;
public interface TcpConnectionInterceptorFactory {
/**
* Called for each new connection - if an interceptor is
* stateful, a new interceptor must be returned on each call.
* Called for each new connection;
* a new interceptor must be returned on each call.
*
* @return the TcpInterceptor
*/

View File

@@ -35,6 +35,8 @@ public class TcpNetConnection extends AbstractTcpConnection {
private final Socket socket;
private boolean noReadErrorOnClose;
/**
* Constructs a TcpNetConnection for the socket.
* @param socket the socket
@@ -42,7 +44,7 @@ public class TcpNetConnection extends AbstractTcpConnection {
* a result of an incoming request.
*/
public TcpNetConnection(Socket socket, boolean server) {
super(server);
super(socket, server);
this.socket = socket;
getConnectionId();
}
@@ -51,6 +53,7 @@ public class TcpNetConnection extends AbstractTcpConnection {
* Closes this connection.
*/
public void close() {
this.noReadErrorOnClose = true;
try {
this.socket.close();
} catch (Exception e) {}
@@ -65,8 +68,7 @@ public class TcpNetConnection extends AbstractTcpConnection {
public synchronized void send(Message<?> message) throws Exception {
Object object = mapper.fromMessage(message);
this.serializer.serialize(object, this.socket.getOutputStream());
if (logger.isDebugEnabled())
logger.debug("Message sent " + message);
this.afterSend(message);
}
public String getHostAddress() {
@@ -108,12 +110,19 @@ public class TcpNetConnection extends AbstractTcpConnection {
try {
message = this.mapper.toMessage(this);
} catch (Exception e) {
this.close();
this.closeConnection();
if (!(e instanceof SoftEndOfStreamException)) {
if (e instanceof SocketTimeoutException && this.singleUse) {
logger.debug("Closing single use socket after timeout");
} else {
if (logger.isTraceEnabled()) {
if (this.noReadErrorOnClose) {
if (logger.isDebugEnabled()) {
logger.debug("Read exception " +
this.getConnectionId() + " " +
e.getClass().getSimpleName() +
":" + e.getCause() + ":" + e.getMessage());
}
} else if (logger.isTraceEnabled()) {
logger.error("Read exception " +
this.getConnectionId(), e);
} else {
@@ -138,7 +147,7 @@ public class TcpNetConnection extends AbstractTcpConnection {
if (e instanceof NoListenerException) {
if (this.singleUse) {
logger.debug("Closing single use socket after inbound message " + this.connectionId);
this.close();
this.closeConnection();
okToRun = false;
} else {
logger.warn("Unexpected message - no inbound adapter registered with connection " + message);
@@ -154,7 +163,7 @@ public class TcpNetConnection extends AbstractTcpConnection {
*/
if (this.singleUse && ((!this.server && !intercepted) || (this.server && this.sender == null))) {
logger.debug("Closing single use socket after inbound message " + this.connectionId);
this.close();
this.closeConnection();
okToRun = false;
}
}

View File

@@ -71,7 +71,7 @@ public class TcpNioConnection extends AbstractTcpConnection {
* a result of an incoming request.
*/
public TcpNioConnection(SocketChannel socketChannel, boolean server) throws Exception {
super(server);
super(socketChannel.socket(), server);
this.socketChannel = socketChannel;
this.pipedInputStream = new PipedInputStream();
this.pipedOutputStream = new PipedOutputStream(this.pipedInputStream);
@@ -107,6 +107,7 @@ public class TcpNioConnection extends AbstractTcpConnection {
synchronized(mapper) {
Object object = mapper.fromMessage(message);
this.serializer.serialize(object, this.channelOutputStream);
this.afterSend(message);
}
}
@@ -209,7 +210,7 @@ public class TcpNioConnection extends AbstractTcpConnection {
try {
message = this.mapper.toMessage(this);
} catch (Exception e) {
this.close();
this.closeConnection();
if (e instanceof SocketTimeoutException && this.singleUse) {
if (logger.isDebugEnabled()) {
logger.debug("Closing single use socket after timeout " + this.connectionId);
@@ -244,7 +245,7 @@ public class TcpNioConnection extends AbstractTcpConnection {
if (logger.isDebugEnabled()) {
logger.debug("Closing single use channel after inbound message " + this.connectionId);
}
this.close();
this.closeConnection();
}
} else {
logger.error("Exception sending meeeage: " + message, e);
@@ -257,7 +258,7 @@ public class TcpNioConnection extends AbstractTcpConnection {
*/
if (this.singleUse && ((!this.server && !intercepted) || (this.server && this.sender == null))) {
logger.debug("Closing single use cbannel after inbound message " + this.connectionId);
this.close();
this.closeConnection();
}
}
@@ -275,7 +276,7 @@ public class TcpNioConnection extends AbstractTcpConnection {
rawBuffer.clear();
int len = socketChannel.read(rawBuffer);
if (len < 0) {
this.close();
this.closeConnection();
throw new IOException("Channel closed");
}
rawBuffer.flip();
@@ -310,7 +311,7 @@ public class TcpNioConnection extends AbstractTcpConnection {
logger.error("Exception on Read " +
this.getConnectionId() + " " +
e.getMessage());
this.close();
this.closeConnection();
}
}
@@ -318,7 +319,7 @@ public class TcpNioConnection extends AbstractTcpConnection {
* Close the socket due to timeout.
*/
void timeout() {
this.close();
this.closeConnection();
}
/**

View File

@@ -69,15 +69,16 @@ public class TcpInboundGatewayTests {
return channel;
}
});
Socket socket = SocketFactory.getDefault().createSocket("localhost", port);
socket.getOutputStream().write("Test1\r\n".getBytes());
socket.getOutputStream().write("Test2\r\n".getBytes());
handler.handleMessage(channel.receive());
handler.handleMessage(channel.receive());
Socket socket1 = SocketFactory.getDefault().createSocket("localhost", port);
socket1.getOutputStream().write("Test1\r\n".getBytes());
Socket socket2 = SocketFactory.getDefault().createSocket("localhost", port);
socket2.getOutputStream().write("Test2\r\n".getBytes());
handler.handleMessage(channel.receive(1000));
handler.handleMessage(channel.receive(1000));
byte[] bytes = new byte[12];
readFully(socket.getInputStream(), bytes);
readFully(socket1.getInputStream(), bytes);
assertEquals("Echo:Test1\r\n", new String(bytes));
readFully(socket.getInputStream(), bytes);
readFully(socket2.getInputStream(), bytes);
assertEquals("Echo:Test2\r\n", new String(bytes));
}
@@ -134,19 +135,17 @@ public class TcpInboundGatewayTests {
return channel;
}
});
Socket socket = SocketFactory.getDefault().createSocket("localhost", port);
socket.getOutputStream().write("Test1\r\n".getBytes());
socket.getOutputStream().write("Test2\r\n".getBytes());
Socket socket1 = SocketFactory.getDefault().createSocket("localhost", port);
socket1.getOutputStream().write("Test1\r\n".getBytes());
Socket socket2 = SocketFactory.getDefault().createSocket("localhost", port);
socket2.getOutputStream().write("Test2\r\n".getBytes());
handler.handleMessage(channel.receive());
handler.handleMessage(channel.receive());
Set<String> results = new HashSet<String>();
byte[] bytes = new byte[12];
readFully(socket.getInputStream(), bytes);
results.add(new String(bytes));
readFully(socket.getInputStream(), bytes);
results.add(new String(bytes));
assertTrue(results.remove("Echo:Test1\r\n"));
assertTrue(results.remove("Echo:Test2\r\n"));
readFully(socket1.getInputStream(), bytes);
assertEquals("Echo:Test1\r\n", new String(bytes));
readFully(socket2.getInputStream(), bytes);
assertEquals("Echo:Test2\r\n", new String(bytes));
}
@Test
@@ -210,13 +209,14 @@ public class TcpInboundGatewayTests {
gateway.setRequestChannel(channel);
ServiceActivatingHandler handler = new ServiceActivatingHandler(new FailingService());
channel.subscribe(handler);
Socket socket = SocketFactory.getDefault().createSocket("localhost", port);
socket.getOutputStream().write("Test1\r\n".getBytes());
socket.getOutputStream().write("Test2\r\n".getBytes());
Socket socket1 = SocketFactory.getDefault().createSocket("localhost", port);
socket1.getOutputStream().write("Test1\r\n".getBytes());
Socket socket2 = SocketFactory.getDefault().createSocket("localhost", port);
socket2.getOutputStream().write("Test2\r\n".getBytes());
byte[] bytes = new byte[errorMessage.length() + 2];
readFully(socket.getInputStream(), bytes);
readFully(socket1.getInputStream(), bytes);
assertEquals(errorMessage + "\r\n", new String(bytes));
readFully(socket.getInputStream(), bytes);
readFully(socket2.getInputStream(), bytes);
assertEquals(errorMessage + "\r\n", new String(bytes));
}

View File

@@ -518,6 +518,7 @@ public class TcpReceivingChannelAdapterTests {
new ObjectOutputStream(socket.getOutputStream()).writeObject("Hello");
assertEquals("world!", new ObjectInputStream(socket.getInputStream()).readObject());
new ObjectOutputStream(socket.getOutputStream()).writeObject("Test1");
socket = SocketFactory.getDefault().createSocket("localhost", port);
new ObjectOutputStream(socket.getOutputStream()).writeObject("Hello");
assertEquals("world!", new ObjectInputStream(socket.getInputStream()).readObject());

View File

@@ -42,6 +42,8 @@ public class HelloWorldInterceptor extends AbstractTcpConnectionInterceptor {
private String hello = "Hello";
private String world = "world!";
private boolean closeReceived;
public HelloWorldInterceptor() {
}
@@ -86,24 +88,58 @@ public class HelloWorldInterceptor extends AbstractTcpConnectionInterceptor {
return true;
}
}
return super.onMessage(message);
try {
return super.onMessage(message);
} finally {
// on the server side, we don't want to close if we are expecting a response
if (!(this.isServer() && this.hasRealSender())) {
this.checkDeferredClose();
}
}
}
@Override
public void send(Message<?> message) throws Exception {
if (!this.negotiated) {
if (!this.isServer()) {
logger.debug("Sending " + hello);
super.send(MessageBuilder.withPayload(hello).build());
this.negotiationSemaphore.tryAcquire(this.timeout, TimeUnit.MILLISECONDS);
if (!this.negotiated) {
throw new MessagingException("Negotiation error");
try {
if (!this.negotiated) {
if (!this.isServer()) {
logger.debug("Sending " + hello);
super.send(MessageBuilder.withPayload(hello).build());
this.negotiationSemaphore.tryAcquire(this.timeout, TimeUnit.MILLISECONDS);
if (!this.negotiated) {
throw new MessagingException("Negotiation error");
}
}
}
super.send(message);
} finally {
this.checkDeferredClose();
}
super.send(message);
}
/**
* Defer the close until we've actually sent the data after negotiation
*/
@Override
public void close() {
if (this.negotiated) {
super.close();
return;
}
closeReceived = true;
logger.debug("Deferring close");
}
/**
* Execute the close, if deferred
*/
private void checkDeferredClose() {
if (this.closeReceived) {
logger.debug("Executing deferred close");
this.close();
}
}
}

View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:int-ip="http://www.springframework.org/schema/integration/ip"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/ip http://www.springframework.org/schema/integration/ip/spring-integration-ip-2.0.xsd">
<bean id="tcpIpUtils" class="org.springframework.integration.ip.util.SocketTestUtils" />
<int-ip:tcp-connection-factory id="inCFNet"
type="server"
port="#{tcpIpUtils.findAvailableServerSocket(9000)}"
so-timeout="1000"
single-use="true"
/>
<int-ip:tcp-inbound-gateway request-channel="echo"
connection-factory="inCFNet" />
<int-ip:tcp-connection-factory id="inCFNio"
type="server"
port="#{tcpIpUtils.findAvailableServerSocket(9100)}"
so-timeout="1000"
single-use="true"
using-nio="true"
/>
<int-ip:tcp-inbound-gateway request-channel="echo"
connection-factory="inCFNio" />
<int-ip:tcp-connection-factory id="inCFNetRst"
type="server"
port="#{tcpIpUtils.findAvailableServerSocket(9200)}"
so-timeout="1000"
single-use="true"
so-linger="0"
/>
<int-ip:tcp-inbound-gateway request-channel="echo"
connection-factory="inCFNetRst" />
<int-ip:tcp-connection-factory id="inCFNioRst"
type="server"
port="#{tcpIpUtils.findAvailableServerSocket(9300)}"
so-timeout="1000"
single-use="true"
using-nio="true"
so-linger="0"
/>
<int-ip:tcp-inbound-gateway request-channel="echo"
connection-factory="inCFNioRst" />
<int-ip:tcp-connection-factory id="inCFNetLinger"
type="server"
port="#{tcpIpUtils.findAvailableServerSocket(9400)}"
so-timeout="1000"
single-use="true"
so-linger="1000"
/>
<int-ip:tcp-inbound-gateway request-channel="echo"
connection-factory="inCFNetLinger" />
<int-ip:tcp-connection-factory id="inCFNioLinger"
type="server"
port="#{tcpIpUtils.findAvailableServerSocket(9500)}"
so-timeout="1000"
single-use="true"
using-nio="true"
so-linger="1000"
/>
<int-ip:tcp-inbound-gateway request-channel="echo"
connection-factory="inCFNioLinger" />
<int:service-activator input-channel="echo" ref="testService"/>
<bean id="testService" class="org.springframework.integration.ip.tcp.TestService"/>
</beans>

View File

@@ -0,0 +1,166 @@
/*
* 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.connection;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.SocketTimeoutException;
import javax.net.SocketFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Gary Russell
* @since 2.0.2
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class SOLingerTests {
@Autowired
private AbstractServerConnectionFactory inCFNet;
@Autowired
private AbstractServerConnectionFactory inCFNio;
@Autowired
private AbstractServerConnectionFactory inCFNetRst;
@Autowired
private AbstractServerConnectionFactory inCFNioRst;
@Autowired
private AbstractServerConnectionFactory inCFNetLinger;
@Autowired
private AbstractServerConnectionFactory inCFNioLinger;
@Test
public void configOk() {}
@Test
public void finReceivedNet() {
finReceived(inCFNet);
}
@Test
public void finReceivedNio() {
finReceived(inCFNio);
}
@Test
public void rstReceivedNet() {
rstReceived(inCFNetRst);
}
@Test
public void rstReceivedNio() {
rstReceived(inCFNioRst);
}
@Test
public void finReceivedNetLinger() {
finReceived(inCFNetLinger);
}
@Test
public void finReceivedNioLinger() {
finReceived(inCFNioLinger);
}
private void finReceived(AbstractServerConnectionFactory inCF) {
int port = inCF.getPort();
int n = 0;
while (!inCF.isListening()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
fail("Interrupted");
}
if (n++ > 100) {
fail("Failed to start");
}
}
try {
Socket socket = SocketFactory.getDefault().createSocket("localhost", port);
String test = "Test\r\n";
socket.getOutputStream().write(test.getBytes());
byte[] buff = new byte[test.length() + 5];
readFully(socket.getInputStream(), buff);
assertEquals("echo:" + test, new String(buff));
n = socket.getInputStream().read();
// we expect an orderly close
assertEquals(-1, n);
} catch (Exception e) {
e.printStackTrace();
fail("Unexpected Exception " + e.getMessage());
}
}
private void rstReceived(AbstractServerConnectionFactory inCF) {
int port = inCF.getPort();
int n = 0;
while (!inCF.isListening()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
fail("Interrupted");
}
if (n++ > 100) {
fail("Failed to start");
}
}
try {
Socket socket = SocketFactory.getDefault().createSocket("localhost", port);
socket.setSoTimeout(200);
String test = "Test\r\n";
socket.getOutputStream().write(test.getBytes());
byte[] buff = new byte[test.length() + 5];
readFully(socket.getInputStream(), buff);
assertEquals("echo:" + test, new String(buff));
try {
n = socket.getInputStream().read();
fail("Expected IOException");
} catch (IOException ioe) {
assertTrue(ioe instanceof SocketTimeoutException);
}
} catch (Exception e) {
e.printStackTrace();
fail("Unexpected Exception " + e.getMessage());
}
}
private void readFully(InputStream is, byte[] buff) throws IOException {
for (int i = 0; i < buff.length; i++) {
buff[i] = (byte) is.read();
}
}
}

View File

@@ -19,6 +19,10 @@ import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.net.Socket;
import javax.net.SocketFactory;
import org.junit.Test;
import org.springframework.integration.Message;
import org.springframework.integration.ip.IpHeaders;
@@ -68,7 +72,8 @@ public class TcpMessageMapperTests {
public void testToMessageSequence() throws Exception {
TcpMessageMapper mapper = new TcpMessageMapper();
TcpConnection connection = new AbstractTcpConnection(false) {
Socket socket = SocketFactory.getDefault().createSocket();
TcpConnection connection = new AbstractTcpConnection(socket, false) {
public void run() {
}
public void send(Message<?> message) throws Exception {

View File

@@ -235,6 +235,7 @@ public class TcpNioConnectionReadTests {
SocketTestUtils.testSendLengthOverflow(port);
whileOpen(semaphore, added);
assertEquals(1, added.size());
assertTrue(semaphore.tryAcquire(10000, TimeUnit.MILLISECONDS));
assertTrue(removed.size() > 0);
scf.close();
}
@@ -273,6 +274,7 @@ public class TcpNioConnectionReadTests {
SocketTestUtils.testSendStxEtxOverflow(port);
whileOpen(semaphore, added);
assertEquals(1, added.size());
assertTrue(semaphore.tryAcquire(10000, TimeUnit.MILLISECONDS));
assertTrue(removed.size() > 0);
scf.close();
}
@@ -311,6 +313,7 @@ public class TcpNioConnectionReadTests {
SocketTestUtils.testSendCrLfOverflow(port);
whileOpen(semaphore, added);
assertEquals(1, added.size());
assertTrue(semaphore.tryAcquire(10000, TimeUnit.MILLISECONDS));
assertTrue(removed.size() > 0);
scf.close();
}
@@ -349,6 +352,7 @@ public class TcpNioConnectionReadTests {
socket.close();
whileOpen(semaphore, added);
assertEquals(1, added.size());
assertTrue(semaphore.tryAcquire(10000, TimeUnit.MILLISECONDS));
assertTrue(removed.size() > 0);
scf.close();
}
@@ -416,6 +420,7 @@ public class TcpNioConnectionReadTests {
socket.close();
whileOpen(semaphore, added);
assertEquals(1, added.size());
assertTrue(semaphore.tryAcquire(10000, TimeUnit.MILLISECONDS));
assertTrue(removed.size() > 0);
scf.close();
}