INTSAMPLES-76 - Fix Failing Tests in TCP Client Server Sample

* The port is no longer hard-coded
* fixed also the conversion service test and refactored it into its own class
This commit is contained in:
Gunnar Hillert
2012-05-16 17:20:01 -04:00
parent bddb52b469
commit 6aa46ab901
11 changed files with 342 additions and 124 deletions

View File

@@ -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. <i>-DavailableServerSocket=7777</i>
*
* @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<String, Object> sockets = new HashMap<String, Object>();
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);
}

View File

@@ -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);
}
}

View File

@@ -1,68 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/integration"
xmlns:ip="http://www.springframework.org/schema/integration/ip"
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">
<!-- Client side -->
<gateway id="gw"
service-interface="org.springframework.integration.samples.tcpclientserver.SimpleGateway"
default-request-channel="input"/>
<context:property-placeholder />
<ip:tcp-connection-factory id="client"
<!-- Client side -->
<int:gateway id="gw"
service-interface="org.springframework.integration.samples.tcpclientserver.SimpleGateway"
default-request-channel="input"/>
<int-ip:tcp-connection-factory id="client"
type="client"
host="localhost"
port="11111"
port="${availableServerSocket}"
single-use="true"
so-timeout="10000"
/>
<channel id="input" />
<ip:tcp-outbound-gateway id="outGateway"
so-timeout="10000"/>
<int:channel id="input" />
<int-ip:tcp-outbound-gateway id="outGateway"
request-channel="input"
reply-channel="clientBytes2StringChannel"
connection-factory="client"
request-timeout="10000"
reply-timeout="10000"
/>
reply-timeout="10000"/>
<transformer id="clientBytes2String"
<int:transformer id="clientBytes2String"
input-channel="clientBytes2StringChannel"
expression="new String(payload)"/>
<!-- Server side -->
<ip:tcp-connection-factory id="crLfServer"
<int-ip:tcp-connection-factory id="crLfServer"
type="server"
port="11111"/>
<ip:tcp-inbound-gateway id="gatewayCrLf"
port="${availableServerSocket}"/>
<int-ip:tcp-inbound-gateway id="gatewayCrLf"
connection-factory="crLfServer"
request-channel="serverBytes2StringChannel"
request-channel="serverBytes2StringChannel"
error-channel="errorChannel"/>
<channel id="toSA" />
<service-activator input-channel="toSA"
ref="echoService"
method="test"
/>
<int:channel id="toSA" />
<beans:bean id="echoService"
class="org.springframework.integration.samples.tcpclientserver.EchoService" />
<transformer id="serverBytes2String"
<int:service-activator input-channel="toSA"
ref="echoService"
method="test"/>
<bean id="echoService"
class="org.springframework.integration.samples.tcpclientserver.EchoService" />
<int:transformer id="serverBytes2String"
input-channel="serverBytes2StringChannel"
output-channel="toSA"
output-channel="toSA"
expression="new String(payload)"/>
<transformer id="errorHandler"
<int:transformer id="errorHandler"
input-channel="errorChannel"
expression="payload.failedMessage.payload + ':' + payload.cause.message"/>
</beans:beans>
</beans>

View File

@@ -1,39 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/integration"
xmlns:ip="http://www.springframework.org/schema/integration/ip"
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">
<beans:description>
<description>
This version demonstrates the use of a conversion service and channel 'dataType'
instead of explicit transformers to convert from byte array to String.
</beans:description>
</description>
<converter>
<beans:bean class="org.springframework.integration.samples.tcpclientserver.ByteArrayToStringConverter" />
</converter>
<bean id="integrationConversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="org.springframework.integration.samples.tcpclientserver.ByteArrayToStringConverter" />
</list>
</property>
</bean>
<context:property-placeholder />
<!-- Client side -->
<gateway id="gw"
service-interface="org.springframework.integration.samples.tcpclientserver.SimpleGateway"
default-request-channel="input"
default-reply-channel="reply"/>
<int:gateway id="gw"
service-interface="org.springframework.integration.samples.tcpclientserver.SimpleGateway"
default-request-channel="input"
default-reply-channel="reply"/>
<ip:tcp-connection-factory id="client"
<int-ip:tcp-connection-factory id="client"
type="client"
host="localhost"
port="11111"
port="${availableServerSocket}"
single-use="true"
so-timeout="10000"
/>
<channel id="input" />
<int:channel id="input" />
<ip:tcp-outbound-gateway id="outGateway"
<int-ip:tcp-outbound-gateway id="outGateway"
request-channel="input"
reply-channel="reply"
connection-factory="client"
@@ -42,32 +51,33 @@
/>
<!-- dataType attribute invokes the conversion service -->
<channel id="reply" datatype="java.lang.String" />
<int:channel id="reply" datatype="java.lang.String" />
<!-- Server side -->
<ip:tcp-connection-factory id="crLfServer"
<int-ip:tcp-connection-factory id="crLfServer"
type="server"
port="11111"/>
port="${availableServerSocket}"/>
<ip:tcp-inbound-gateway id="gatewayCrLf"
<int-ip:tcp-inbound-gateway id="gatewayCrLf"
connection-factory="crLfServer"
request-channel="toSA"
error-channel="errorChannel"/>
<!-- dataType attribute invokes the conversion service -->
<channel id="toSA" datatype="java.lang.String" />
<int:channel id="toSA" datatype="java.lang.String" />
<service-activator input-channel="toSA"
ref="echoService"
method="test"
<int:service-activator input-channel="toSA"
ref="echoService"
method="test"
/>
<beans:bean id="echoService"
<bean id="echoService"
class="org.springframework.integration.samples.tcpclientserver.EchoService" />
<transformer id="errorHandler"
<int:transformer id="errorHandler"
input-channel="errorChannel"
expression="payload.failedMessage.payload + ':' + payload.cause.message"/>
</beans:beans>
</beans>

View File

@@ -1,27 +1,32 @@
<?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.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">
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">
<!-- Client side -->
<context:property-placeholder />
<!-- Client side -->
<int:gateway id="gw"
service-interface="org.springframework.integration.samples.tcpclientserver.SimpleGateway"
default-request-channel="input"/>
service-interface="org.springframework.integration.samples.tcpclientserver.SimpleGateway"
default-request-channel="input"/>
<!-- Create a connection for the client gateway that uses the same Stx-Etx deserializer to turn the stream
into the appropriate content (it looks for the Stx byte, extracts anything between it and the Etx byte). We
don't specify the serializer (although we could) because the unit test explicitly shows how the content
to be sent is wrapped by the Stx and Etx bytes. -->
<!-- Create a connection for the client gateway that uses the same Stx-Etx deserializer to turn the stream
into the appropriate content (it looks for the Stx byte, extracts anything between it and the Etx byte). We
don't specify the serializer (although we could) because the unit test explicitly shows how the content
to be sent is wrapped by the Stx and Etx bytes. -->
<int-ip:tcp-connection-factory id="client"
type="client"
host="localhost"
port="22222"
port="${availableServerSocket}"
single-use="true"
so-timeout="10000"
deserializer="connectionSerializeDeserialize"
/>
deserializer="connectionSerializeDeserialize"/>
<int:channel id="input" />
@@ -30,27 +35,26 @@
reply-channel="clientBytes2StringChannel"
connection-factory="client"
request-timeout="10000"
reply-timeout="10000"
/>
reply-timeout="10000"/>
<int:channel id="clientBytes2StringChannel"/>
<int:channel id="clientBytes2StringChannel"/>
<int:transformer id="clientBytes2String"
<int:transformer id="clientBytes2String"
input-channel="clientBytes2StringChannel"
expression="new String(payload)"/>
<!-- Server side -->
<!-- When creating the socket factory on the server side, we specify both the serializer and deserializer
which deals with both accepting a stream formatted with the Stx-Etx bytes as well as sending a stream
formatted with the Stx-Etx bytes. -->
<!-- Server side -->
<!-- When creating the socket factory on the server side, we specify both the serializer and deserializer
which deals with both accepting a stream formatted with the Stx-Etx bytes as well as sending a stream
formatted with the Stx-Etx bytes. -->
<int-ip:tcp-connection-factory id="serverConnectionFactory"
type="server"
port="22222"
serializer="connectionSerializeDeserialize"
deserializer="connectionSerializeDeserialize"/>
port="${availableServerSocket}"
serializer="connectionSerializeDeserialize"
deserializer="connectionSerializeDeserialize"/>
<bean id="connectionSerializeDeserialize" class="org.springframework.integration.ip.tcp.serializer.ByteArrayStxEtxSerializer"/>
<bean id="connectionSerializeDeserialize" class="org.springframework.integration.ip.tcp.serializer.ByteArrayStxEtxSerializer"/>
<int-ip:tcp-inbound-gateway id="gatewayCrLf"
@@ -58,9 +62,9 @@
request-channel="incomingServerChannel"
error-channel="errorChannel"/>
<!-- We leave a message listener off of this channel on purpose because we hook
one up before the test actually runs (see the unit test associated with this
context file) -->
<!-- We leave a message listener off of this channel on purpose because we hook
one up before the test actually runs (see the unit test associated with this
context file) -->
<int:channel id="incomingServerChannel" />
</beans>

View File

@@ -1,34 +1,39 @@
<?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.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">
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">
<context:property-placeholder />
<!-- Server side -->
<!-- When creating the socket factory on the server side, we specify both the serializer and deserializer
which deals with both accepting a stream formatted with the Stx-Etx bytes as well as sending a stream
formatted with the Stx-Etx bytes. -->
<!-- Server side -->
<!-- When creating the socket factory on the server side, we specify both the serializer and deserializer
which deals with both accepting a stream formatted with the Stx-Etx bytes as well as sending a stream
formatted with the Stx-Etx bytes. -->
<int-ip:tcp-connection-factory id="serverConnectionFactory"
type="server"
port="11111"
single-use="true"
so-linger="10000"
serializer="connectionSerializeDeserialize"
deserializer="connectionSerializeDeserialize"/>
port="${availableServerSocket}"
single-use="true"
so-linger="10000"
serializer="connectionSerializeDeserialize"
deserializer="connectionSerializeDeserialize"/>
<bean id="connectionSerializeDeserialize" class="org.springframework.integration.samples.tcpclientserver.CustomSerializerDeserializer"/>
<bean id="connectionSerializeDeserialize" class="org.springframework.integration.samples.tcpclientserver.CustomSerializerDeserializer"/>
<int-ip:tcp-inbound-gateway id="gatewayCrLf"
connection-factory="serverConnectionFactory"
request-channel="incomingServerChannel"
error-channel="errorChannel"/>
<!-- We leave a message listener off of this channel on purpose because we hook
one up before the test actually runs (see the unit test associated with this
context file) -->
<!-- We leave a message listener off of this channel on purpose because we hook
one up before the test actually runs (see the unit test associated with this
context file) -->
<int:channel id="incomingServerChannel" />
</beans>
</beans>