INT-1340 Add TCP Connection Interceptor Chain

This commit is contained in:
Gary Russell
2010-08-08 22:13:19 +00:00
parent c4c728b52b
commit c25367cfd3
31 changed files with 1250 additions and 68 deletions

View File

@@ -297,6 +297,7 @@
task-executor="externalTE"
pool-size="321"
using-direct-buffers="true"
interceptor-factory-chain="interceptors"
/>
<ip:tcp-connection-factory
@@ -318,8 +319,11 @@
task-executor="externalTE"
pool-size="123"
using-direct-buffers="true"
interceptor-factory-chain="interceptors"
/>
<bean id="interceptors" class="org.springframework.integration.ip.tcp.connection.TcpConnectionInterceptorFactoryChain" />
<bean id="serial" class="org.springframework.commons.serializer.java.JavaStreamingConverter" />
<ip:tcp-outbound-channel-adapter id="tcpNewOut1"
@@ -337,6 +341,8 @@
<ip:tcp-inbound-channel-adapter id="tcpNewIn2"
channel="tcpChannel"
connection-factory="server1" />
</beans>

View File

@@ -16,6 +16,7 @@
package org.springframework.integration.ip.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
@@ -436,6 +437,7 @@ public class ParserUnitTests {
assertSame(taskExecutor, dfa.getPropertyValue("taskExecutor"));
assertEquals(321, dfa.getPropertyValue("poolSize"));
assertEquals(true, dfa.getPropertyValue("usingDirectBuffers"));
assertNotNull(dfa.getPropertyValue("interceptorFactoryChain"));
}
@Test
@@ -454,7 +456,8 @@ public class ParserUnitTests {
assertEquals(true, dfa.getPropertyValue("singleUse"));
assertSame(taskExecutor, dfa.getPropertyValue("taskExecutor"));
assertEquals(123, dfa.getPropertyValue("poolSize"));
assertEquals(true, dfa.getPropertyValue("usingDirectBuffers"));
assertEquals(true, dfa.getPropertyValue("usingDirectBuffers"));
assertNotNull(dfa.getPropertyValue("interceptorFactoryChain"));
}
@Test

View File

@@ -0,0 +1,72 @@
<?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/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.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="tcpIpUtils" class="org.springframework.integration.ip.util.SocketUtils" />
<bean id="serializer" class="org.springframework.commons.serializer.java.JavaStreamingConverter" />
<bean id="helloWorldInterceptors" class="org.springframework.integration.ip.tcp.connection.TcpConnectionInterceptorFactoryChain">
<property name="interceptors">
<array>
<bean class="org.springframework.integration.ip.tcp.connection.HelloWorldInterceptorFactory"/>
<bean class="org.springframework.integration.ip.tcp.connection.HelloWorldInterceptorFactory">
<constructor-arg value="Hi"/>
<constructor-arg value="planet!"/>
</bean>
</array>
</property>
</bean>
<int-ip:tcp-connection-factory id="server"
type="server"
port="#{tcpIpUtils.findAvailableServerSocket(10000)}"
input-converter="serializer"
output-converter="serializer"
using-nio="true"
single-use="true"
interceptor-factory-chain="helloWorldInterceptors"
/>
<int-ip:tcp-connection-factory id="client"
type="client"
host="localhost"
port="#{server.port}"
single-use="true"
so-timeout="100000"
input-converter="serializer"
output-converter="serializer"
interceptor-factory-chain="helloWorldInterceptors"
/>
<int:channel id="input" />
<int:channel id="replies">
<int:queue/>
</int:channel>
<int-ip:tcp-outbound-channel-adapter id="outboundClient"
channel="input"
connection-factory="client"/>
<int-ip:tcp-inbound-channel-adapter id="inboundClient"
channel="replies"
connection-factory="client"/>
<int-ip:tcp-inbound-channel-adapter id="inboundServer"
channel="loop"
connection-factory="server"/>
<int-ip:tcp-outbound-channel-adapter id="outboundServer"
channel="loop"
connection-factory="server"/>
<int:channel id="loop" />
</beans>

View File

@@ -0,0 +1,80 @@
/*
* 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;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.integration.Message;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.core.MessageBuilder;
import org.springframework.integration.core.MessageChannel;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Gary Russell
* @since 2.0
*
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class InterceptedSharedConnectionTests {
@Autowired
AbstractApplicationContext ctx;
@Autowired
@Qualifier(value="inboundServer")
TcpReceivingChannelAdapter listener;
/**
* Tests a loopback. The client-side outbound adapter sends a message over
* a connection from the client connection factory; the server side
* receives the message, puts in on a channel which is the input channel
* for the outbound adapter that's sharing the connections. The response
* comes back to an inbound adapter that is sharing the client's
* connection and we verify we get the echo back as expected.
*
* @throws Exception
*/
@Test
public void test1() throws Exception {
int n = 0;
Object o = ctx.getBean("inboundServer");
while (!listener.isListening()) {
Thread.sleep(100);
if (n++ > 100) {
fail("Failed to listen");
}
}
MessageChannel input = ctx.getBean("input", MessageChannel.class);
input.send(MessageBuilder.withPayload("Test").build());
QueueChannel replies = ctx.getBean("replies", QueueChannel.class);
Message<?> message = replies.receive(10000);
assertNotNull(message);
assertEquals("Test", message.getPayload());
}
}

View File

@@ -29,7 +29,6 @@ import org.springframework.integration.Message;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.core.MessageBuilder;
import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.ip.tcp.connection.TcpListener;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -48,7 +47,7 @@ public class SharedConnectionTests {
@Autowired
@Qualifier(value="inboundServer")
TcpListener listener;
TcpReceivingChannelAdapter listener;
/**
* Tests a loopback. The client-side outbound adapter sends a message over

View File

@@ -22,7 +22,11 @@ import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
@@ -34,10 +38,14 @@ import java.util.concurrent.Executors;
import javax.net.SocketFactory;
import org.junit.Test;
import org.springframework.commons.serializer.java.JavaStreamingConverter;
import org.springframework.integration.Message;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.ip.AbstractInternetProtocolReceivingChannelAdapter;
import org.springframework.integration.ip.tcp.connection.AbstractServerConnectionFactory;
import org.springframework.integration.ip.tcp.connection.HelloWorldInterceptorFactory;
import org.springframework.integration.ip.tcp.connection.TcpConnectionInterceptorFactory;
import org.springframework.integration.ip.tcp.connection.TcpConnectionInterceptorFactoryChain;
import org.springframework.integration.ip.tcp.connection.TcpNetServerConnectionFactory;
import org.springframework.integration.ip.tcp.connection.TcpNioServerConnectionFactory;
import org.springframework.integration.ip.tcp.converter.ByteArrayCrLfConverter;
@@ -577,6 +585,190 @@ public class TcpReceivingChannelAdapterTests {
}
}
@Test
public void newTestNetInterceptors() throws Exception {
final int port = SocketUtils.findAvailableServerSocket();
AbstractServerConnectionFactory scf = new TcpNetServerConnectionFactory(port);
interceptorsGuts(port, scf);
}
@Test
public void newTestNetSingleNoOutboundInterceptors() throws Exception {
final int port = SocketUtils.findAvailableServerSocket();
AbstractServerConnectionFactory scf = new TcpNetServerConnectionFactory(port);
singleNoOutboundInterceptorsGuts(port, scf);
}
@Test
public void newTestNetSingleSharedInterceptors() throws Exception {
final int port = SocketUtils.findAvailableServerSocket();
AbstractServerConnectionFactory scf = new TcpNetServerConnectionFactory(port);
singleSharedInterceptorsGuts(port, scf);
}
@Test
public void newTestNioInterceptors() throws Exception {
final int port = SocketUtils.findAvailableServerSocket();
AbstractServerConnectionFactory scf = new TcpNioServerConnectionFactory(port);
interceptorsGuts(port, scf);
}
@Test
public void newTestNioSingleNoOutboundInterceptors() throws Exception {
final int port = SocketUtils.findAvailableServerSocket();
AbstractServerConnectionFactory scf = new TcpNioServerConnectionFactory(port);
singleNoOutboundInterceptorsGuts(port, scf);
}
@Test
public void newTestNioSingleSharedInterceptors() throws Exception {
final int port = SocketUtils.findAvailableServerSocket();
AbstractServerConnectionFactory scf = new TcpNioServerConnectionFactory(port);
singleSharedInterceptorsGuts(port, scf);
}
private void interceptorsGuts(final int port,
AbstractServerConnectionFactory scf) throws Exception {
JavaStreamingConverter converter = new JavaStreamingConverter();
scf.setInputConverter(converter);
scf.setOutputConverter(converter);
scf.setSingleUse(false);
TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter();
adapter.setConnectionFactory(scf);
TcpConnectionInterceptorFactoryChain fc = new TcpConnectionInterceptorFactoryChain();
fc.setInterceptors(new TcpConnectionInterceptorFactory[]
{new HelloWorldInterceptorFactory(),
new HelloWorldInterceptorFactory()});
scf.setInterceptorFactoryChain(fc);
scf.setSoTimeout(10000);
scf.start();
int n = 0;
while (!scf.isListening()) {
Thread.sleep(100);
if (n++ > 100) {
fail("Failed to start listening");
}
}
QueueChannel channel = new QueueChannel();
adapter.setOutputChannel(channel);
Socket socket = SocketFactory.getDefault().createSocket("localhost", port);
socket.setSoTimeout(10000);
new ObjectOutputStream(socket.getOutputStream()).writeObject("Hello");
assertEquals("world!", new ObjectInputStream(socket.getInputStream()).readObject());
new ObjectOutputStream(socket.getOutputStream()).writeObject("Hello");
assertEquals("world!", new ObjectInputStream(socket.getInputStream()).readObject());
new ObjectOutputStream(socket.getOutputStream()).writeObject("Test1");
new ObjectOutputStream(socket.getOutputStream()).writeObject("Test2");
Message<?> message = channel.receive(10000);
assertNotNull(message);
assertEquals("Test1", message.getPayload());
message = channel.receive(10000);
assertNotNull(message);
assertEquals("Test2", message.getPayload());
}
private void singleNoOutboundInterceptorsGuts(final int port,
AbstractServerConnectionFactory scf) throws Exception {
JavaStreamingConverter converter = new JavaStreamingConverter();
scf.setInputConverter(converter);
scf.setOutputConverter(converter);
scf.setSingleUse(true);
scf.setSoTimeout(10000);
TcpConnectionInterceptorFactoryChain fc = new TcpConnectionInterceptorFactoryChain();
fc.setInterceptors(new TcpConnectionInterceptorFactory[]
{new HelloWorldInterceptorFactory(),
new HelloWorldInterceptorFactory()});
scf.setInterceptorFactoryChain(fc);
TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter();
adapter.setConnectionFactory(scf);
scf.start();
int n = 0;
while (!scf.isListening()) {
Thread.sleep(100);
if (n++ > 100) {
fail("Failed to start listening");
}
}
QueueChannel channel = new QueueChannel();
adapter.setOutputChannel(channel);
Socket socket = SocketFactory.getDefault().createSocket("localhost", port);
socket.setSoTimeout(10000);
new ObjectOutputStream(socket.getOutputStream()).writeObject("Hello");
assertEquals("world!", new ObjectInputStream(socket.getInputStream()).readObject());
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());
new ObjectOutputStream(socket.getOutputStream()).writeObject("Hello");
assertEquals("world!", new ObjectInputStream(socket.getInputStream()).readObject());
new ObjectOutputStream(socket.getOutputStream()).writeObject("Test2");
Message<?> message = channel.receive(10000);
assertNotNull(message);
// with single use, results may come back in a different order
Set<Object> results = new HashSet<Object>();
results.add(message.getPayload());
message = channel.receive(10000);
assertNotNull(message);
results.add(message.getPayload());
assertTrue(results.contains("Test1"));
assertTrue(results.contains("Test2"));
}
private void singleSharedInterceptorsGuts(final int port,
AbstractServerConnectionFactory scf) throws Exception {
JavaStreamingConverter converter = new JavaStreamingConverter();
scf.setInputConverter(converter);
scf.setOutputConverter(converter);
scf.setSingleUse(true);
scf.setSoTimeout(60000);
TcpConnectionInterceptorFactoryChain fc = new TcpConnectionInterceptorFactoryChain();
fc.setInterceptors(new TcpConnectionInterceptorFactory[]
{new HelloWorldInterceptorFactory(),
new HelloWorldInterceptorFactory()});
scf.setInterceptorFactoryChain(fc);
TcpSendingMessageHandler handler = new TcpSendingMessageHandler();
handler.setConnectionFactory(scf);
TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter();
adapter.setConnectionFactory(scf);
scf.start();
QueueChannel channel = new QueueChannel();
adapter.setOutputChannel(channel);
int n = 0;
while (!scf.isListening()) {
Thread.sleep(100);
if (n++ > 100) {
fail("Failed to listen");
}
}
Socket socket1 = SocketFactory.getDefault().createSocket("localhost", port);
socket1.setSoTimeout(60000);
new ObjectOutputStream(socket1.getOutputStream()).writeObject("Hello");
assertEquals("world!", new ObjectInputStream(socket1.getInputStream()).readObject());
new ObjectOutputStream(socket1.getOutputStream()).writeObject("Hello");
assertEquals("world!", new ObjectInputStream(socket1.getInputStream()).readObject());
new ObjectOutputStream(socket1.getOutputStream()).writeObject("Test1");
Socket socket2 = SocketFactory.getDefault().createSocket("localhost", port);
socket2.setSoTimeout(60000);
new ObjectOutputStream(socket2.getOutputStream()).writeObject("Hello");
assertEquals("world!", new ObjectInputStream(socket2.getInputStream()).readObject());
new ObjectOutputStream(socket2.getOutputStream()).writeObject("Hello");
assertEquals("world!", new ObjectInputStream(socket2.getInputStream()).readObject());
new ObjectOutputStream(socket2.getOutputStream()).writeObject("Test2");
Message<?> message = channel.receive(10000);
assertNotNull(message);
handler.handleMessage(message);
message = channel.receive(10000);
assertNotNull(message);
handler.handleMessage(message);
assertEquals("Test1", new ObjectInputStream(socket1.getInputStream()).readObject());
assertEquals("Test2", new ObjectInputStream(socket2.getInputStream()).readObject());
}
}

View File

@@ -18,6 +18,7 @@ package org.springframework.integration.ip.tcp;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.InputStream;
@@ -41,6 +42,9 @@ import org.springframework.integration.Message;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.core.MessageBuilder;
import org.springframework.integration.ip.tcp.connection.AbstractConnectionFactory;
import org.springframework.integration.ip.tcp.connection.HelloWorldInterceptorFactory;
import org.springframework.integration.ip.tcp.connection.TcpConnectionInterceptorFactory;
import org.springframework.integration.ip.tcp.connection.TcpConnectionInterceptorFactoryChain;
import org.springframework.integration.ip.tcp.connection.TcpNetClientConnectionFactory;
import org.springframework.integration.ip.tcp.connection.TcpNioClientConnectionFactory;
import org.springframework.integration.ip.tcp.converter.ByteArrayCrLfConverter;
@@ -272,7 +276,7 @@ public class TcpSendingMessageHandlerTests {
}
@Test
public void newTestNio() throws Exception {
public void newTestNioCrLf() throws Exception {
final int port = SocketUtils.findAvailableServerSocket();
final CountDownLatch latch = new CountDownLatch(1);
final AtomicBoolean done = new AtomicBoolean();
@@ -827,7 +831,7 @@ public class TcpSendingMessageHandlerTests {
while (true) {
Socket socket = server.accept();
semaphore.release();
byte[] b = new byte[8];
byte[] b = new byte[9];
readFully(socket.getInputStream(), b);
b = ("Reply" + (i++) + "\r\n").getBytes();
socket.getOutputStream().write(b);
@@ -853,19 +857,267 @@ public class TcpSendingMessageHandlerTests {
QueueChannel channel = new QueueChannel();
adapter.setOutputChannel(channel);
assertTrue(latch.await(10, TimeUnit.SECONDS));
for (int i = 100; i < 200; i++) {
handler.handleMessage(MessageBuilder.withPayload("Test" + i).build());
int i = 0;
try {
for (i = 100; i < 200; i++) {
handler.handleMessage(MessageBuilder.withPayload("Test" + i).build());
}
} catch (Exception e) {
e.printStackTrace();
fail("Exception at " + i);
}
assertTrue(semaphore.tryAcquire(100, 20000, TimeUnit.MILLISECONDS));
Set<String> replies = new HashSet<String>();
for (int i = 100; i < 200; i++) {
for (i = 100; i < 200; i++) {
Message<?> mOut = channel.receive(20000);
assertNotNull(mOut);
replies.add(new String((byte[])mOut.getPayload()));
}
for (int i = 0; i < 100; i++) {
for (i = 0; i < 100; i++) {
assertTrue("Reply" + i + " missing", replies.remove("Reply" + i));
}
done.set(true);
}
@Test
public void newTestNetNegotiate() throws Exception {
final int port = SocketUtils.findAvailableServerSocket();
final CountDownLatch latch = new CountDownLatch(1);
final AtomicBoolean done = new AtomicBoolean();
Executors.newSingleThreadExecutor().execute(new Runnable() {
public void run() {
try {
ServerSocket server = ServerSocketFactory.getDefault().createServerSocket(port);
latch.countDown();
Socket socket = server.accept();
int i = 0;
while (true) {
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Object in;
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
if (i == 0) {
in = ois.readObject();
// System.out.println(in);
oos.writeObject("world!");
ois = new ObjectInputStream(socket.getInputStream());
oos = new ObjectOutputStream(socket.getOutputStream());
in = ois.readObject();
// System.out.println(in);
oos.writeObject("world!");
ois = new ObjectInputStream(socket.getInputStream());
oos = new ObjectOutputStream(socket.getOutputStream());
}
in = ois.readObject();
oos.writeObject("Reply" + (++i));
}
} catch (Exception e) {
if (!done.get()) {
e.printStackTrace();
}
}
}
});
AbstractConnectionFactory ccf = new TcpNetClientConnectionFactory("localhost", port);
JavaStreamingConverter converter = new JavaStreamingConverter();
ccf.setInputConverter(converter);
ccf.setOutputConverter(converter);
ccf.setSoTimeout(10000);
TcpConnectionInterceptorFactoryChain fc = new TcpConnectionInterceptorFactoryChain();
fc.setInterceptors(new TcpConnectionInterceptorFactory[]
{new HelloWorldInterceptorFactory(),
new HelloWorldInterceptorFactory()});
ccf.setInterceptorFactoryChain(fc);
ccf.start();
TcpSendingMessageHandler handler = new TcpSendingMessageHandler();
handler.setConnectionFactory(ccf);
TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter();
adapter.setConnectionFactory(ccf);
QueueChannel channel = new QueueChannel();
adapter.setOutputChannel(channel);
assertTrue(latch.await(10, TimeUnit.SECONDS));
handler.handleMessage(MessageBuilder.withPayload("Test").build());
handler.handleMessage(MessageBuilder.withPayload("Test").build());
Message<?> mOut = channel.receive(10000);
assertNotNull(mOut);
assertEquals("Reply1", mOut.getPayload());
mOut = channel.receive(10000);
assertNotNull(mOut);
assertEquals("Reply2", mOut.getPayload());
done.set(true);
}
@Test
public void newTestNioNegotiate() throws Exception {
final int port = SocketUtils.findAvailableServerSocket();
final CountDownLatch latch = new CountDownLatch(1);
final AtomicBoolean done = new AtomicBoolean();
Executors.newSingleThreadExecutor().execute(new Runnable() {
public void run() {
try {
ServerSocket server = ServerSocketFactory.getDefault().createServerSocket(port);
latch.countDown();
Socket socket = server.accept();
int i = 0;
while (true) {
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Object in;
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
if (i == 0) {
in = ois.readObject();
// System.out.println(in);
oos.writeObject("world!");
ois = new ObjectInputStream(socket.getInputStream());
oos = new ObjectOutputStream(socket.getOutputStream());
}
in = ois.readObject();
oos.writeObject("Reply" + (++i));
}
} catch (Exception e) {
if (!done.get()) {
e.printStackTrace();
}
}
}
});
AbstractConnectionFactory ccf = new TcpNioClientConnectionFactory("localhost", port);
JavaStreamingConverter converter = new JavaStreamingConverter();
ccf.setInputConverter(converter);
ccf.setOutputConverter(converter);
ccf.setSoTimeout(10000);
TcpConnectionInterceptorFactoryChain fc = new TcpConnectionInterceptorFactoryChain();
fc.setInterceptors(new TcpConnectionInterceptorFactory[] {new HelloWorldInterceptorFactory()});
ccf.setInterceptorFactoryChain(fc);
ccf.start();
TcpSendingMessageHandler handler = new TcpSendingMessageHandler();
handler.setConnectionFactory(ccf);
TcpReceivingChannelAdapter adapter = new TcpReceivingChannelAdapter();
adapter.setConnectionFactory(ccf);
QueueChannel channel = new QueueChannel();
adapter.setOutputChannel(channel);
assertTrue(latch.await(10, TimeUnit.SECONDS));
handler.handleMessage(MessageBuilder.withPayload("Test").build());
handler.handleMessage(MessageBuilder.withPayload("Test").build());
Message<?> mOut = channel.receive(10000);
assertNotNull(mOut);
assertEquals("Reply1", mOut.getPayload());
mOut = channel.receive(10000);
assertNotNull(mOut);
assertEquals("Reply2", mOut.getPayload());
done.set(true);
}
@Test
public void newTestNetNegotiateSingleNoListen() throws Exception {
final int port = SocketUtils.findAvailableServerSocket();
final CountDownLatch latch = new CountDownLatch(1);
final AtomicBoolean done = new AtomicBoolean();
Executors.newSingleThreadExecutor().execute(new Runnable() {
public void run() {
try {
ServerSocket server = ServerSocketFactory.getDefault().createServerSocket(port);
latch.countDown();
Socket socket = server.accept();
int i = 0;
while (true) {
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Object in;
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
if (i == 0) {
in = ois.readObject();
// System.out.println(in);
oos.writeObject("world!");
ois = new ObjectInputStream(socket.getInputStream());
oos = new ObjectOutputStream(socket.getOutputStream());
in = ois.readObject();
// System.out.println(in);
oos.writeObject("world!");
ois = new ObjectInputStream(socket.getInputStream());
oos = new ObjectOutputStream(socket.getOutputStream());
}
in = ois.readObject();
oos.writeObject("Reply" + (++i));
}
} catch (Exception e) {
if (!done.get()) {
e.printStackTrace();
}
}
}
});
AbstractConnectionFactory ccf = new TcpNetClientConnectionFactory("localhost", port);
JavaStreamingConverter converter = new JavaStreamingConverter();
ccf.setInputConverter(converter);
ccf.setOutputConverter(converter);
ccf.setSoTimeout(10000);
TcpConnectionInterceptorFactoryChain fc = new TcpConnectionInterceptorFactoryChain();
fc.setInterceptors(new TcpConnectionInterceptorFactory[]
{new HelloWorldInterceptorFactory(),
new HelloWorldInterceptorFactory()});
ccf.setInterceptorFactoryChain(fc);
ccf.setSingleUse(true);
ccf.start();
TcpSendingMessageHandler handler = new TcpSendingMessageHandler();
handler.setConnectionFactory(ccf);
assertTrue(latch.await(10, TimeUnit.SECONDS));
handler.handleMessage(MessageBuilder.withPayload("Test").build());
done.set(true);
}
@Test
public void newTestNioNegotiateSingleNoListen() throws Exception {
final int port = SocketUtils.findAvailableServerSocket();
final CountDownLatch latch = new CountDownLatch(1);
final AtomicBoolean done = new AtomicBoolean();
Executors.newSingleThreadExecutor().execute(new Runnable() {
public void run() {
try {
ServerSocket server = ServerSocketFactory.getDefault().createServerSocket(port);
latch.countDown();
Socket socket = server.accept();
int i = 0;
while (true) {
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Object in;
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
if (i == 0) {
in = ois.readObject();
// System.out.println(in);
oos.writeObject("world!");
ois = new ObjectInputStream(socket.getInputStream());
oos = new ObjectOutputStream(socket.getOutputStream());
in = ois.readObject();
// System.out.println(in);
oos.writeObject("world!");
ois = new ObjectInputStream(socket.getInputStream());
oos = new ObjectOutputStream(socket.getOutputStream());
}
in = ois.readObject();
oos.writeObject("Reply" + (++i));
}
} catch (Exception e) {
if (!done.get()) {
e.printStackTrace();
}
}
}
});
AbstractConnectionFactory ccf = new TcpNioClientConnectionFactory("localhost", port);
JavaStreamingConverter converter = new JavaStreamingConverter();
ccf.setInputConverter(converter);
ccf.setOutputConverter(converter);
ccf.setSoTimeout(10000);
TcpConnectionInterceptorFactoryChain fc = new TcpConnectionInterceptorFactoryChain();
fc.setInterceptors(new TcpConnectionInterceptorFactory[]
{new HelloWorldInterceptorFactory(),
new HelloWorldInterceptorFactory()});
ccf.setInterceptorFactoryChain(fc);
ccf.setSingleUse(true);
ccf.start();
TcpSendingMessageHandler handler = new TcpSendingMessageHandler();
handler.setConnectionFactory(ccf);
assertTrue(latch.await(10, TimeUnit.SECONDS));
handler.handleMessage(MessageBuilder.withPayload("Test").build());
done.set(true);
}
}

View File

@@ -0,0 +1,110 @@
/*
* 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 java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.integration.Message;
import org.springframework.integration.MessagingException;
import org.springframework.integration.core.MessageBuilder;
import org.springframework.integration.ip.tcp.connection.AbstractTcpConnectionInterceptor;
/**
* @author Gary Russell
* @since 2.0
*
*/
public class HelloWorldInterceptor extends AbstractTcpConnectionInterceptor {
Log logger = LogFactory.getLog(this.getClass());
private boolean negotiated;
private Semaphore negotiationSemaphore = new Semaphore(0);
private long timeout = 10000;
private String hello = "Hello";
private String world = "world!";
public HelloWorldInterceptor() {
}
/**
* @param hello
* @param world
*/
public HelloWorldInterceptor(String hello, String world) {
super();
this.hello = hello;
this.world = world;
}
@Override
public void onMessage(Message<?> message) {
if (!this.negotiated) {
Object payload = message.getPayload();
if (this.isServer()) {
if (payload.equals(hello)) {
try {
logger.debug("sending " + this.world);
super.send(MessageBuilder.withPayload(world).build());
this.negotiated = true;
return;
} catch (Exception e) {
throw new MessagingException("Negotiation error", e);
}
} else {
throw new MessagingException("Negotiation error, expected '" + hello +
"' received '" + payload + "'");
}
} else {
logger.debug("received " + payload);
if (payload.equals(world)) {
this.negotiated = true;
this.negotiationSemaphore.release();
} else {
throw new MessagingException("Negotiation error - expected '" + world +
"' received " + payload);
}
return;
}
}
super.onMessage(message);
}
@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");
}
}
}
super.send(message);
}
}

View File

@@ -0,0 +1,51 @@
/*
* 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 org.springframework.integration.ip.tcp.connection.TcpConnectionInterceptorFactory;
/**
* @author Gary Russell
* @since 2.0
*
*/
public class HelloWorldInterceptorFactory extends
TcpConnectionInterceptorFactory {
private String hello = "Hello";
private String world = "world!";
public HelloWorldInterceptorFactory() {
}
/**
* @param hello
* @param world
*/
public HelloWorldInterceptorFactory(String hello, String world) {
this.hello = hello;
this.world = world;
}
@Override
public TcpConnectionInterceptor getInterceptor() {
return new HelloWorldInterceptor(hello, world);
}
}

View File

@@ -64,7 +64,7 @@ public class TcpNioConnectionTests {
});
assertTrue(latch.await(10000, TimeUnit.MILLISECONDS));
try {
TcpNioConnection connection = factory.getConnection();
TcpConnection connection = factory.getConnection();
connection.send(MessageBuilder.withPayload(new byte[1000000]).build());
} catch (Exception e) {
assertTrue("Expected SocketTimeoutException, got " + e.getClass().getSimpleName() +
@@ -97,7 +97,7 @@ public class TcpNioConnectionTests {
});
assertTrue(latch.await(10000, TimeUnit.MILLISECONDS));
try {
TcpNioConnection connection = factory.getConnection();
TcpConnection connection = factory.getConnection();
connection.send(MessageBuilder.withPayload("Test").build());
int n = 0;
while (connection.isOpen()) {
@@ -108,7 +108,7 @@ public class TcpNioConnectionTests {
}
assertTrue(!connection.isOpen());
} catch (Exception e) {
fail("Unexptected exception " + e);
fail("Unexpected exception " + e);
}
}