diff --git a/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/TelnetServer.java b/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/TelnetServer.java
index 4d471ad0..3b7490a1 100644
--- a/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/TelnetServer.java
+++ b/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/TelnetServer.java
@@ -15,7 +15,12 @@
*/
package org.springframework.integration.samples.tcpclientserver;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
+import org.springframework.core.env.MapPropertySource;
/**
* The configured inbound gateway uses CRLF delimited messages which means
@@ -23,15 +28,31 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
* telnet localhost 11111 - each time you hit enter you should see your input
* echoed back, preceded by 'echo:'.
*
+ * Alternatively, you can also customize the port by providing an additional system
+ * property at startup e.g. -DavailableServerSocket=7777
+ *
* @author Gary Russell
+ * @author Gunnar Hillert
*
*/
public class TelnetServer {
public static void main(String[] args) throws Exception {
- new ClassPathXmlApplicationContext("/META-INF/spring/integration/tcpClientServerDemo-context.xml");
+
+ ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"/META-INF/spring/integration/tcpClientServerDemo-context.xml"}, false);
+
+ final Map sockets = new HashMap();
+ sockets.put("availableServerSocket", 11111);
+
+ final MapPropertySource propertySource = new MapPropertySource("sockets", sockets);
+
+ context.getEnvironment().getPropertySources().addLast(propertySource);
+ context.refresh();
+
+ System.out.println("Use telnet and connect to port: " + context.getEnvironment().getProperty("availableServerSocket"));
System.out.println("Press Enter/Return in the console to exit");
System.in.read();
+ System.out.println("exiting application...bye.\n\n");
System.exit(0);
}
diff --git a/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/support/SocketUtils.java b/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/support/SocketUtils.java
new file mode 100644
index 00000000..cf0bec8b
--- /dev/null
+++ b/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/support/SocketUtils.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2002-2012 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.samples.tcpclientserver.support;
+
+import java.net.ServerSocket;
+
+import javax.net.ServerSocketFactory;
+
+/**
+ *
+ * @author Gunnar Hillert
+ *
+ */
+public final class SocketUtils {
+
+ public static int findAvailableServerSocket(int seed) {
+ for (int i = seed; i < seed+200; i++) {
+ try {
+ ServerSocket sock = ServerSocketFactory.getDefault().createServerSocket(i);
+ sock.close();
+ return i;
+ } catch (Exception e) { }
+ }
+ throw new RuntimeException("Cannot find a free server socket");
+ }
+
+ public static int findAvailableServerSocket() {
+ return findAvailableServerSocket(5678);
+ }
+
+}
diff --git a/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpClientServerDemo-context.xml b/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpClientServerDemo-context.xml
index e4d865c9..c9c6e66d 100644
--- a/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpClientServerDemo-context.xml
+++ b/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpClientServerDemo-context.xml
@@ -1,68 +1,69 @@
-
-
-
-
+
-
+
+
+
+
-
-
-
-
+
+
+
+
+ reply-timeout="10000"/>
-
-
+
-
-
-
-
+
+
-
-
-
+
-
-
-
+
+
+
+
-
-
-
-
+
+
diff --git a/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpClientServerDemo-conversion-context.xml b/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpClientServerDemo-conversion-context.xml
index fd5d0cda..b836cdff 100644
--- a/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpClientServerDemo-conversion-context.xml
+++ b/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpClientServerDemo-conversion-context.xml
@@ -1,39 +1,48 @@
-
-
+
This version demonstrates the use of a conversion service and channel 'dataType'
instead of explicit transformers to convert from byte array to String.
-
+
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
+
-
-
+
-
+ port="${availableServerSocket}"/>
-
-
+
-
-
-
-
+
+
diff --git a/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpServerConnectionDeserialize-context.xml b/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpServerConnectionDeserialize-context.xml
index 174bf73e..12188ecc 100644
--- a/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpServerConnectionDeserialize-context.xml
+++ b/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpServerConnectionDeserialize-context.xml
@@ -1,27 +1,32 @@
+ 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"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.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.xsd">
-
+
+
+
+ service-interface="org.springframework.integration.samples.tcpclientserver.SimpleGateway"
+ default-request-channel="input"/>
-
+
+ deserializer="connectionSerializeDeserialize"/>
@@ -30,27 +35,26 @@
reply-channel="clientBytes2StringChannel"
connection-factory="client"
request-timeout="10000"
- reply-timeout="10000"
- />
+ reply-timeout="10000"/>
-
+
-
-
-
+
+
+ port="${availableServerSocket}"
+ serializer="connectionSerializeDeserialize"
+ deserializer="connectionSerializeDeserialize"/>
-
+
-
+
\ No newline at end of file
diff --git a/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpServerCustomSerialize-context.xml b/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpServerCustomSerialize-context.xml
index 32887a62..a01d88b9 100644
--- a/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpServerCustomSerialize-context.xml
+++ b/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpServerCustomSerialize-context.xml
@@ -1,34 +1,39 @@
+ 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"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.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.xsd">
+
-
-
+
+
+ port="${availableServerSocket}"
+ single-use="true"
+ so-linger="10000"
+ serializer="connectionSerializeDeserialize"
+ deserializer="connectionSerializeDeserialize"/>
-
+
-
+
-
\ No newline at end of file
+
diff --git a/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpClientServerDemoTest.java b/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpClientServerDemoTest.java
index bdff84ea..48f6e488 100644
--- a/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpClientServerDemoTest.java
+++ b/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpClientServerDemoTest.java
@@ -20,6 +20,7 @@ import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.integration.samples.tcpclientserver.support.CustomTestContextLoader;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -32,17 +33,14 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* echo service and the echoed response comes back over tcp and is returned to
* the test case for verification.
*
- * The alternate configuration shows how the conversion service can be used
- * instead of explicit transformers to convert the byte array payloads to
+ * The test uses explicit transformers to convert the byte array payloads to
* Strings.
*
* @author Gary Russell
*
*/
// This one uses transformers
-@ContextConfiguration("/META-INF/spring/integration/tcpClientServerDemo-context.xml")
-// This one uses the conversion service
-//@ContextConfiguration("/META-INF/spring/integration/tcpClientServerDemo-conversion-context.xml")
+@ContextConfiguration(loader=CustomTestContextLoader.class, locations={"/META-INF/spring/integration/tcpClientServerDemo-context.xml"})
@RunWith(SpringJUnit4ClassRunner.class)
@DirtiesContext
public class TcpClientServerDemoTest {
diff --git a/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpClientServerDemoWithConversionServiceTest.java b/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpClientServerDemoWithConversionServiceTest.java
new file mode 100644
index 00000000..440efd0f
--- /dev/null
+++ b/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpClientServerDemoWithConversionServiceTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2002-2012 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.samples.tcpclientserver;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.integration.samples.tcpclientserver.support.CustomTestContextLoader;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+
+/**
+ * Demonstrates the use of a gateway as an entry point into the integration flow.
+ * The message generated by the gateway is sent over tcp by the outbound gateway
+ * to the inbound gateway. In turn the inbound gateway sends the message to an
+ * echo service and the echoed response comes back over tcp and is returned to
+ * the test case for verification.
+ *
+ * This version shows how the conversion service can be used
+ * instead of explicit transformers to convert the byte array payloads to
+ * Strings.
+ *
+ * @author Gary Russell
+ *
+ */
+@ContextConfiguration(loader=CustomTestContextLoader.class, locations={"/META-INF/spring/integration/tcpClientServerDemo-conversion-context.xml"})
+@RunWith(SpringJUnit4ClassRunner.class)
+@DirtiesContext
+public class TcpClientServerDemoWithConversionServiceTest {
+
+ @Autowired
+ SimpleGateway gw;
+
+ @Test
+ public void testHappyDay() {
+ String result = gw.send("Hello world!");
+ System.out.println(result);
+ assertEquals("echo:Hello world!", result);
+ }
+
+ @Test
+ public void testZeroLength() {
+ String result = gw.send("");
+ System.out.println(result);
+ assertEquals("echo:", result);
+ }
+
+ @Test
+ public void testFail() {
+ String result = gw.send("FAIL");
+ System.out.println(result);
+ assertEquals("FAIL:Failure Demonstration", result);
+ }
+
+}
diff --git a/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpServerConnectionDeserializeTest.java b/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpServerConnectionDeserializeTest.java
index 335197c9..ebd6dbe0 100644
--- a/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpServerConnectionDeserializeTest.java
+++ b/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpServerConnectionDeserializeTest.java
@@ -24,6 +24,7 @@ import org.springframework.integration.MessageChannel;
import org.springframework.integration.core.SubscribableChannel;
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
import org.springframework.integration.ip.tcp.serializer.ByteArrayStxEtxSerializer;
+import org.springframework.integration.samples.tcpclientserver.support.CustomTestContextLoader;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -43,7 +44,8 @@ import static org.junit.Assert.assertEquals;
* @author: ceposta
*/
@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(locations = {"/META-INF/spring/integration/tcpServerConnectionDeserialize-context.xml"})
+@ContextConfiguration(loader=CustomTestContextLoader.class,
+ locations = {"/META-INF/spring/integration/tcpServerConnectionDeserialize-context.xml"})
@DirtiesContext
public class TcpServerConnectionDeserializeTest {
diff --git a/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpServerCustomSerializerTest.java b/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpServerCustomSerializerTest.java
index 14a2396f..84f76e38 100644
--- a/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpServerCustomSerializerTest.java
+++ b/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpServerCustomSerializerTest.java
@@ -30,10 +30,12 @@ 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.beans.factory.annotation.Value;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.core.SubscribableChannel;
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
+import org.springframework.integration.samples.tcpclientserver.support.CustomTestContextLoader;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -47,7 +49,8 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* @author: ceposta
*/
@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(locations = {"/META-INF/spring/integration/tcpServerCustomSerialize-context.xml"})
+@ContextConfiguration(loader=CustomTestContextLoader.class,
+ locations = {"/META-INF/spring/integration/tcpServerCustomSerialize-context.xml"})
@DirtiesContext
public class TcpServerCustomSerializerTest {
@@ -55,6 +58,9 @@ public class TcpServerCustomSerializerTest {
@Qualifier("incomingServerChannel")
MessageChannel incomingServerChannel;
+ @Value("${availableServerSocket}")
+ int availableServerSocket;
+
@Test
public void testHappyPath() {
@@ -86,7 +92,7 @@ public class TcpServerCustomSerializerTest {
Writer out = null;
BufferedReader in = null;
try {
- socket = new Socket("localhost", 11111);
+ socket = new Socket("localhost", availableServerSocket);
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
out.write(sourceMessage);
out.flush();
diff --git a/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/support/CustomTestContextLoader.java b/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/support/CustomTestContextLoader.java
new file mode 100644
index 00000000..372d257f
--- /dev/null
+++ b/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/support/CustomTestContextLoader.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2002-2012 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.samples.tcpclientserver.support;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.springframework.context.support.GenericApplicationContext;
+import org.springframework.core.env.MapPropertySource;
+import org.springframework.test.context.MergedContextConfiguration;
+import org.springframework.test.context.support.GenericXmlContextLoader;
+
+/**
+ *
+ * @author Gunnar Hillert
+ *
+ */
+public class CustomTestContextLoader extends GenericXmlContextLoader {
+
+ private static final Logger LOGGER = Logger.getLogger(CustomTestContextLoader.class);
+
+ @Override
+ protected void loadBeanDefinitions(GenericApplicationContext context,
+ MergedContextConfiguration mergedConfig) {
+
+ int availableServerSocket = SocketUtils.findAvailableServerSocket(5678);
+
+ final Map sockets = new HashMap();
+ sockets.put("availableServerSocket", availableServerSocket);
+
+ if (LOGGER.isInfoEnabled()) {
+ LOGGER.info("Available Server Socket 1: " + availableServerSocket);
+ }
+
+ final MapPropertySource propertySource = new MapPropertySource("sockets", sockets);
+
+ context.getEnvironment().getPropertySources().addLast(propertySource);
+ super.loadBeanDefinitions(context, mergedConfig);
+ }
+
+}