From c7e5a7815b509034f24b8655deccd85aae7395bc Mon Sep 17 00:00:00 2001 From: Gunnar Hillert Date: Wed, 8 Feb 2012 16:34:57 -0500 Subject: [PATCH 1/7] INTSAMPLES-57 Update README.md For reference: https://jira.springsource.org/browse/INTSAMPLES-57 * reflect the correct Main class to be used * add exec-maven-plugin and add usage to README.md --- basic/xml/README.md | 6 +++++- basic/xml/pom.xml | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/basic/xml/README.md b/basic/xml/README.md index 59b16a94..63b8a726 100644 --- a/basic/xml/README.md +++ b/basic/xml/README.md @@ -8,7 +8,11 @@ This example demonstrates the following aspects of the XML support available wit 3. XPath Expression - which tests to see if the order item is in stock 3. XSLT Transformer - to transform the payload of the order message into a resupply message where the order item is found to be out of stock. -To run sample simply execute **BookOrderProcessingTest**. You should see the following output: +To run the sample execute class **org.springframework.integration.samples.xml.BookOrderProcessingTestApp**. With Maven you can run the sample by executing: + + $ mvn clean package exec:java + +You should see the following output: INFO : org.springframework.integration.samples.xml.WarehouseDispatch - Warehouse dispatching orderItem: diff --git a/basic/xml/pom.xml b/basic/xml/pom.xml index 3e50dd72..663ca24c 100644 --- a/basic/xml/pom.xml +++ b/basic/xml/pom.xml @@ -45,6 +45,14 @@ false + + org.codehaus.mojo + exec-maven-plugin + 1.2 + + org.springframework.integration.samples.xml.BookOrderProcessingTestApp + + From 834f0a96300d833895bde18db27a4ee849a555b6 Mon Sep 17 00:00:00 2001 From: Gunnar Hillert Date: Thu, 9 Feb 2012 00:59:33 -0500 Subject: [PATCH 2/7] INTSAMPLES-56 Update README.md for ws-outbound-gateway sample For reference: https://jira.springsource.org/browse/INTSAMPLES-56 --- basic/ws-outbound-gateway/README.md | 5 ++++- basic/ws-outbound-gateway/pom.xml | 8 ++++++++ .../integration/samples/ws/WebServiceDemoTestApp.java | 10 +++++----- 3 files changed, 17 insertions(+), 6 deletions(-) rename basic/ws-outbound-gateway/src/main/java/{rg => org}/springframework/integration/samples/ws/WebServiceDemoTestApp.java (92%) diff --git a/basic/ws-outbound-gateway/README.md b/basic/ws-outbound-gateway/README.md index 43e06058..0caac28a 100644 --- a/basic/ws-outbound-gateway/README.md +++ b/basic/ws-outbound-gateway/README.md @@ -14,4 +14,7 @@ A very simple example that show you how easy it is to invoke a SOAP based servic * The *WS Outbound Gateway* converts the Message to a SOAP request and sends it to a remote service, which converts a temperature from Fahrenheit to Celsius and the result is printed to the console. -To run sample simply execute **WebServicesDemoTest** +To run the sample simply execute **WebServiceDemoTestApp** in package *org.springframework.integration.samples.ws*. You can also execute that class using the [Exec Maven Plugin](http://mojo.codehaus.org/exec-maven-plugin/): + + $ mvn clean package exec:java + diff --git a/basic/ws-outbound-gateway/pom.xml b/basic/ws-outbound-gateway/pom.xml index 605b09b3..9195718b 100644 --- a/basic/ws-outbound-gateway/pom.xml +++ b/basic/ws-outbound-gateway/pom.xml @@ -62,6 +62,14 @@ false + + org.codehaus.mojo + exec-maven-plugin + 1.2 + + org.springframework.integration.samples.ws.WebServiceDemoTestApp + + diff --git a/basic/ws-outbound-gateway/src/main/java/rg/springframework/integration/samples/ws/WebServiceDemoTestApp.java b/basic/ws-outbound-gateway/src/main/java/org/springframework/integration/samples/ws/WebServiceDemoTestApp.java similarity index 92% rename from basic/ws-outbound-gateway/src/main/java/rg/springframework/integration/samples/ws/WebServiceDemoTestApp.java rename to basic/ws-outbound-gateway/src/main/java/org/springframework/integration/samples/ws/WebServiceDemoTestApp.java index b4167bcd..13637b6b 100644 --- a/basic/ws-outbound-gateway/src/main/java/rg/springframework/integration/samples/ws/WebServiceDemoTestApp.java +++ b/basic/ws-outbound-gateway/src/main/java/org/springframework/integration/samples/ws/WebServiceDemoTestApp.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * 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. @@ -14,7 +14,7 @@ * limitations under the License. */ -package rg.springframework.integration.samples.ws; +package org.springframework.integration.samples.ws; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.integration.Message; @@ -27,13 +27,13 @@ import org.springframework.integration.support.channel.ChannelResolver; * Demonstrates a web service invocation through a Web Service outbound Gateway. * A header-enricher provides the Soap Action prior to invocation. See the * 'temperatureConversion.xml' configuration file for more detail. - * + * * @author Marius Bogoevici */ public class WebServiceDemoTestApp { public static void main(String[] args) { - ClassPathXmlApplicationContext context = + ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/META-INF/spring/integration/temperatureConversion.xml"); ChannelResolver channelResolver = new BeanFactoryChannelResolver(context); @@ -50,5 +50,5 @@ public class WebServiceDemoTestApp { MessageChannel channel = channelResolver.resolveChannelName("fahrenheitChannel"); channel.send(message); } - + } From c223667e32285f0f5b4d97c25da702f32857896c Mon Sep 17 00:00:00 2001 From: Gunnar Hillert Date: Wed, 8 Feb 2012 17:42:55 -0500 Subject: [PATCH 3/7] INTSAMPLES-53 Update README.md For reference see: https://jira.springsource.org/browse/INTSAMPLES-53 --- basic/http/README.md | 41 +++++++++++++++---- basic/http/pom.xml | 13 ++++++ .../samples/http/HttpClientDemo.java | 0 basic/http/src/main/resources/log4j.xml | 6 +-- 4 files changed, 49 insertions(+), 11 deletions(-) rename basic/http/src/{test => main}/java/org/springframework/integration/samples/http/HttpClientDemo.java (100%) diff --git a/basic/http/README.md b/basic/http/README.md index f61b0981..2dd28770 100644 --- a/basic/http/README.md +++ b/basic/http/README.md @@ -3,13 +3,38 @@ Http Sample This example demonstrates simple request/reply communication when using a pair of **HTTP Inbound/Outbound Gateways**. -It consists of two parts - Client and Server. To run this sample: +The sample consists of two parts: -1. Deploy project - * If you are using STS and project is imported as Eclipse project in your workspace you can just execute **Run on Server** - * You can also run **mvn clean install** and generate the WAR file that you can deploy the conventional way -2. Run the simple test client program: **org.springframework.integration.samples.http.DemoHttpClient** +* Client - Basic command-line application +* Server - Web application (War-file) + +## Running the sample + +### Command Line Using Maven + +The easiest way to run the **server** is to use the [Maven Jetty Plugin](http://docs.codehaus.org/display/JETTY/Maven+Jetty+Plugin). Simply execute: + + $ mvn jetty:run + +This command starts a Jetty servlet container running on port 8080 serving the application. Alternatively you can also package the war-file and deploy it manually to a servlet container of your choosing. For that to happen execute: + + $ mvn clean package + +The resulting war-file will be located in the **target** folder. In order to run the **client**, execute: + + $ mvn clean package exec:java + +This will package the application and run it using the [Exec Maven Plugin](http://mojo.codehaus.org/exec-maven-plugin/) + +### Using an IDE such as SpringSource Tool Suite™ (STS) + +If you are using STS and the project is imported as an Eclipse project into your workspace, you can just execute **Run on Server**. This will start the **server** application. + +Next, run the simple test **client** program: **org.springframework.integration.samples.http.HttpClientDemo** + +### Output + +The gateway (**client**) initiates a simple request posting "Hello" to the **server** and the **server** responds by appending **from the other side** to the message payload and returns. You should see the following output from the server: -The gateway initiates a simple request posting "Hello" to the server and server responds by appending **from the other side** to the message payload and returns. You should see the following output from the server: - - INFO : org.springframework.integration.samples.http.HttpClientDemo - Replied with: Hello from the other side \ No newline at end of file + INFO : org.springframework.integration.samples.http.HttpClientDemo - Replied with: Hello from the other side + diff --git a/basic/http/pom.xml b/basic/http/pom.xml index 5f4b1940..b6272076 100644 --- a/basic/http/pom.xml +++ b/basic/http/pom.xml @@ -65,6 +65,19 @@ false + + org.codehaus.mojo + exec-maven-plugin + 1.2 + + org.springframework.integration.samples.http.HttpClientDemo + + + + org.mortbay.jetty + maven-jetty-plugin + 6.1.10 + diff --git a/basic/http/src/test/java/org/springframework/integration/samples/http/HttpClientDemo.java b/basic/http/src/main/java/org/springframework/integration/samples/http/HttpClientDemo.java similarity index 100% rename from basic/http/src/test/java/org/springframework/integration/samples/http/HttpClientDemo.java rename to basic/http/src/main/java/org/springframework/integration/samples/http/HttpClientDemo.java diff --git a/basic/http/src/main/resources/log4j.xml b/basic/http/src/main/resources/log4j.xml index 6b716c53..df1bb3f4 100644 --- a/basic/http/src/main/resources/log4j.xml +++ b/basic/http/src/main/resources/log4j.xml @@ -10,11 +10,11 @@ - + - + - + From d3f789bd3d96d047dd87c6c187fd38e19394fde0 Mon Sep 17 00:00:00 2001 From: Gunnar Hillert Date: Fri, 10 Feb 2012 10:48:20 -0500 Subject: [PATCH 4/7] INTSAMPLES-53 Restructured client and server section in README.md --- basic/http/README.md | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/basic/http/README.md b/basic/http/README.md index 2dd28770..15a48290 100644 --- a/basic/http/README.md +++ b/basic/http/README.md @@ -10,7 +10,9 @@ The sample consists of two parts: ## Running the sample -### Command Line Using Maven +### Server + +#### Command Line Using Maven The easiest way to run the **server** is to use the [Maven Jetty Plugin](http://docs.codehaus.org/display/JETTY/Maven+Jetty+Plugin). Simply execute: @@ -20,17 +22,25 @@ This command starts a Jetty servlet container running on port 8080 serving the a $ mvn clean package -The resulting war-file will be located in the **target** folder. In order to run the **client**, execute: +The resulting war-file will be located in the **target** folder. + +#### Using an IDE such as SpringSource Tool Suite™ (STS) + +If you are using [STS](http://www.springsource.com/developer/sts) and the project is imported as an Eclipse project into your workspace, you can just execute **Run on Server**. This will start the **server** application. + +### Client + +#### Command Line Using Maven + +In order to run the **client** using Maven, execute: $ mvn clean package exec:java This will package the application and run it using the [Exec Maven Plugin](http://mojo.codehaus.org/exec-maven-plugin/) -### Using an IDE such as SpringSource Tool Suite™ (STS) +#### Using an IDE such as SpringSource Tool Suite™ (STS) -If you are using STS and the project is imported as an Eclipse project into your workspace, you can just execute **Run on Server**. This will start the **server** application. - -Next, run the simple test **client** program: **org.springframework.integration.samples.http.HttpClientDemo** +In STS (Eclipse), go to package **org.springframework.integration.samples.http**, right-click **HttpClientDemo** and select **Run as** --> **Java Application**. This will run the **client** application. ### Output From a60a5b29012c2d51f3afe8a22243dc0c2338bc33 Mon Sep 17 00:00:00 2001 From: Gunnar Hillert Date: Fri, 10 Feb 2012 15:39:39 -0500 Subject: [PATCH 5/7] INTSAMPLES-55 - Update README.md for OddEven Sample For reference: https://jira.springsource.org/browse/INTSAMPLES-55 * Update README.md to reflect correct classes * Improve documentation * Add Maven Exec Maven Plugin for easy execution from the command line --- basic/oddeven/README.md | 56 +++++++-- basic/oddeven/pom.xml | 119 +++++++++++------- .../integration/samples/oddeven/Counter.java | 4 +- .../samples/oddeven/CronOddEvenDemo.java | 4 +- .../samples/oddeven/EvenLogger.java | 6 +- .../oddeven/IntervalOddEvenDemoTestApp.java | 15 +-- .../samples/oddeven/OddLogger.java | 6 +- .../integration/intervalOddEvenDemo.xml | 2 +- 8 files changed, 133 insertions(+), 79 deletions(-) diff --git a/basic/oddeven/README.md b/basic/oddeven/README.md index 7875e567..566029d2 100644 --- a/basic/oddeven/README.md +++ b/basic/oddeven/README.md @@ -1,21 +1,53 @@ Odd Even Sample =============== -This example demonstrates the following aspects of the CORE EIP support available with Spring Integration: +This project contains the following 2 sample applications: -1. Inbound Channel Adapter -2. Filter -3. Router (SpEL based) -4. Poller with Cron and Interval Trigers +* CronOddEvenDemo +* IntervalOddEvenDemoTestApp -Messages are simply being emitted by the Poller (interval based or cron) triggering '**next()**' method of Counter class and sent to a '**numbers**' channel - Inbound Channel Adapter. From the '**numbers**' channel Messages are sent to an expression-based router (Spring Expression Language). All that the router does is simply routing messages to *OddLogger* and *EvenLogger* service +## CronOddEvenDemo -To execute the Interval-based sample simply run **IntervalOddEvenDemoTest** class and for Cron-based sample simply -run CronOddEvenDemo class, You should see the output similar to this: +This example demonstrates the following aspects of the core Enterprise Integration Patterns (EIP) support available with Spring Integration: -INFO : org.springframework.integration.samples.oddeven.OddLogger - odd: 1 at 2010-09-16 05:55:46 -INFO : org.springframework.integration.samples.oddeven.EvenLogger - even: 2 at 2010-09-16 05:55:49 -INFO : org.springframework.integration.samples.oddeven.OddLogger - odd: 3 at 2010-09-16 05:55:52 -INFO : org.springframework.integration.samples.oddeven.EvenLogger - even: 4 at 2010-09-16 05:55:55 +* Inbound Channel Adapter +* Poller with Cron Trigger +* Filter +* Router (SpEL based) +* Service Activator +Messages are simply being emitted by the **Poller** (**Cron-based**) through triggering the **next()** method of the *org.springframework.integration.samples.oddeven.Counter* class. The messages are sent via the **numbers** channel to a *Spring Expression Language* (SpEL) based **Message Filter**. The filter discards any messages that contain a payload whose value is less than the number one (1). + +Via the **positives** channel messages are sent to the a SpEL expression-based router. All that the router does is to simply route messages to one of the following two **Service Activators**: + +* OddLogger +* EvenLogger + +## IntervalOddEvenDemoTestApp + +Demonstrates a method-invoking **Inbound Channel Adapter** acting as a **Polling Consumer** with an **Interval-based trigger**. That adapter is followed, downstream, by a Content Based **Router**. The router sends to one of two channels based on whether the payload number is odd or even. Each of those two channels has an **Event Driven Consumer** ready to log the number and the current time. + +The following Spring Integration components are being used: + +* Inbound Channel Adapter +* Poller with Fixed Delay Trigger +* Router (SpEL based) +* Service Activator + +## Running the Samples + +To run the two samples, simply execute either **CronOddEvenDemo** or **IntervalOddEvenDemoTestApp** in package **org.springframework.integration.samples.oddeven**. You can also execute those two samples using the [Exec Maven Plugin](http://mojo.codehaus.org/exec-maven-plugin/): + + $ mvn clean package exec:java -P cron + +which will execute **CronOddEvenDemo**. In order to run **IntervalOddEvenDemoTestApp**, execute: + + $ mvn clean package exec:java -P interval + +For both samples you should see the output similar to this: + + INFO : org.springframework.integration.samples.oddeven.OddLogger - odd: 1 at 2012-02-10 03:29:32 + INFO : org.springframework.integration.samples.oddeven.EvenLogger - even: 2 at 2012-02-10 03:29:35 + INFO : org.springframework.integration.samples.oddeven.OddLogger - odd: 3 at 2012-02-10 03:29:38 + INFO : org.springframework.integration.samples.oddeven.EvenLogger - even: 4 at 2012-02-10 03:29:41 diff --git a/basic/oddeven/pom.xml b/basic/oddeven/pom.xml index 382c4d7c..5fc359e7 100644 --- a/basic/oddeven/pom.xml +++ b/basic/oddeven/pom.xml @@ -1,52 +1,77 @@ - 4.0.0 - org.springframework.integration.samples - oddeven - Samples (Basic) - Odd-Even Sample - 2.1.0.BUILD-SNAPSHOT - jar - - UTF-8 - 2.1.0.RELEASE - 1.2.16 - 4.10 - - - - org.springframework.integration - spring-integration-core - ${spring.integration.version} - - - log4j - log4j - ${log4j.version} - - - - junit - junit - ${junit.version} - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 2.3.2 - - 1.5 - 1.5 - -Xlint:all - true - false - - - - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + 4.0.0 + org.springframework.integration.samples + oddeven + Samples (Basic) - Odd-Even Sample + 2.1.0.BUILD-SNAPSHOT + jar + + UTF-8 + 2.1.0.RELEASE + 1.2.16 + 4.10 + + + + + cron + + org.springframework.integration.samples.oddeven.CronOddEvenDemo + + + + interval + + org.springframework.integration.samples.oddeven.IntervalOddEvenDemoTestApp + + + + + + + org.springframework.integration + spring-integration-core + ${spring.integration.version} + + + log4j + log4j + ${log4j.version} + + + + junit + junit + ${junit.version} + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.5 + 1.5 + -Xlint:all + true + false + + + + org.codehaus.mojo + exec-maven-plugin + 1.2 + + ${java.main.class} + + + + repo.springsource.org.milestone diff --git a/basic/oddeven/src/main/java/org/springframework/integration/samples/oddeven/Counter.java b/basic/oddeven/src/main/java/org/springframework/integration/samples/oddeven/Counter.java index 736989d8..841b6def 100644 --- a/basic/oddeven/src/main/java/org/springframework/integration/samples/oddeven/Counter.java +++ b/basic/oddeven/src/main/java/org/springframework/integration/samples/oddeven/Counter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * 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. @@ -24,7 +24,7 @@ import java.util.concurrent.atomic.AtomicInteger; * Adapter acting as a Polling Consumer. *

* Every 5th number will be returned as a negative value. - * + * * @author Mark Fisher */ public class Counter { diff --git a/basic/oddeven/src/main/java/org/springframework/integration/samples/oddeven/CronOddEvenDemo.java b/basic/oddeven/src/main/java/org/springframework/integration/samples/oddeven/CronOddEvenDemo.java index e540e956..4fbbc3f0 100644 --- a/basic/oddeven/src/main/java/org/springframework/integration/samples/oddeven/CronOddEvenDemo.java +++ b/basic/oddeven/src/main/java/org/springframework/integration/samples/oddeven/CronOddEvenDemo.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * 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. @@ -29,7 +29,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; *

* See the 'cronOddEvenDemo.xml' configuration file for more detail. The cron * expression is based on the Fibonacci sequence. Feel free to modify it. - * + * * @author Mark Fisher */ public class CronOddEvenDemo { diff --git a/basic/oddeven/src/main/java/org/springframework/integration/samples/oddeven/EvenLogger.java b/basic/oddeven/src/main/java/org/springframework/integration/samples/oddeven/EvenLogger.java index ac4937b0..bae0f372 100644 --- a/basic/oddeven/src/main/java/org/springframework/integration/samples/oddeven/EvenLogger.java +++ b/basic/oddeven/src/main/java/org/springframework/integration/samples/oddeven/EvenLogger.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * 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. @@ -25,14 +25,14 @@ import org.springframework.integration.annotation.ServiceActivator; /** * A POJO Service Activator that logs even numbers and the current time. - * + * * @author Mark Fisher * @author Marius Bogoevici */ @MessageEndpoint public class EvenLogger { private static Logger logger = Logger.getLogger(EvenLogger.class); - + @ServiceActivator public void log(int i) { logger.info("even: " + i + " at " + new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date())); diff --git a/basic/oddeven/src/main/java/org/springframework/integration/samples/oddeven/IntervalOddEvenDemoTestApp.java b/basic/oddeven/src/main/java/org/springframework/integration/samples/oddeven/IntervalOddEvenDemoTestApp.java index f1bd7c40..d5d49fee 100644 --- a/basic/oddeven/src/main/java/org/springframework/integration/samples/oddeven/IntervalOddEvenDemoTestApp.java +++ b/basic/oddeven/src/main/java/org/springframework/integration/samples/oddeven/IntervalOddEvenDemoTestApp.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * 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. @@ -13,22 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.integration.samples.oddeven; import org.springframework.context.support.ClassPathXmlApplicationContext; /** - * Demonstrates a method-invoking inbound Channel Adapter acting as a Polling + * Demonstrates a method-invoking Inbound Channel Adapter acting as a Polling * Consumer with an interval-based trigger. That adapter is followed, - * downstream, by a simple method-invoking Message Filter that discards - * negative numbers to the "nullChannel". Next is a Content Based Router. The - * router sends to one of two channels based on whether the payload number is - * odd or even. Each of those two channels has an Event Driven Consumer ready - * to log the number and the current time. + * downstream, by a Content Based Router. The router sends to one of two channels, + * based on whether the payload number is odd or even. Each of those two channels + * has an Event Driven Consumer ready to log the number and the current time. *

* See the 'intervalOddEvenDemo.xml' configuration file for more detail. - * + * * @author Mark Fisher */ public class IntervalOddEvenDemoTestApp { diff --git a/basic/oddeven/src/main/java/org/springframework/integration/samples/oddeven/OddLogger.java b/basic/oddeven/src/main/java/org/springframework/integration/samples/oddeven/OddLogger.java index cd237a8d..ac422254 100644 --- a/basic/oddeven/src/main/java/org/springframework/integration/samples/oddeven/OddLogger.java +++ b/basic/oddeven/src/main/java/org/springframework/integration/samples/oddeven/OddLogger.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * 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. @@ -25,7 +25,7 @@ import org.springframework.integration.annotation.ServiceActivator; /** * A POJO Service Activator that logs odd numbers and the current time. - * + * * @author Mark Fisher * @author Marius Bogoevici */ @@ -35,7 +35,7 @@ public class OddLogger { @ServiceActivator public void log(int i) { - logger.info("odd: " + i + " at " + new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date())); + logger.info("odd: " + i + " at " + new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date())); } } \ No newline at end of file diff --git a/basic/oddeven/src/main/resources/META-INF/spring/integration/intervalOddEvenDemo.xml b/basic/oddeven/src/main/resources/META-INF/spring/integration/intervalOddEvenDemo.xml index 200e4a8c..1aac0833 100644 --- a/basic/oddeven/src/main/resources/META-INF/spring/integration/intervalOddEvenDemo.xml +++ b/basic/oddeven/src/main/resources/META-INF/spring/integration/intervalOddEvenDemo.xml @@ -5,7 +5,7 @@ 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/spring-integration-2.1.xsd"> From 9eaea901702711314bd4d0780619bdfdcf08d134 Mon Sep 17 00:00:00 2001 From: Gunnar Hillert Date: Mon, 13 Feb 2012 09:53:27 -0500 Subject: [PATCH 6/7] INTSAMPLES-55 Code review: Mention that every 5th number returned by the Counter class is negative. --- basic/oddeven/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/basic/oddeven/README.md b/basic/oddeven/README.md index 566029d2..c6c85f28 100644 --- a/basic/oddeven/README.md +++ b/basic/oddeven/README.md @@ -16,7 +16,7 @@ This example demonstrates the following aspects of the core Enterprise Integrati * Router (SpEL based) * Service Activator -Messages are simply being emitted by the **Poller** (**Cron-based**) through triggering the **next()** method of the *org.springframework.integration.samples.oddeven.Counter* class. The messages are sent via the **numbers** channel to a *Spring Expression Language* (SpEL) based **Message Filter**. The filter discards any messages that contain a payload whose value is less than the number one (1). +Messages are simply being emitted by the **Poller** (**Cron-based**) through triggering the **next()** method of the *org.springframework.integration.samples.oddeven.Counter* class. Every 5th number generated by the **Counter** class will be negative. The messages are sent via the **numbers** channel to a *Spring Expression Language* (SpEL) based **Message Filter**. The filter discards any messages that contain a payload whose value is less than the number one (1). Via the **positives** channel messages are sent to the a SpEL expression-based router. All that the router does is to simply route messages to one of the following two **Service Activators**: From 375cc41b1a4ca172b3102eb4fcd89fb4504d7b87 Mon Sep 17 00:00:00 2001 From: Christian Posta Date: Fri, 3 Feb 2012 23:48:20 -0700 Subject: [PATCH 7/7] INTSAMPLES-22: Create sample for inbound tcp-connection-factory using deserializer and serializer * Added new tests * Added comments * Created the custom serializer/deserializer. Fixing some small issues with it * Changed the sending to use java socket api * Working, just trying to figure out junit differences * Found an error in the input message (contained \r\n) fixed now * added .idea and activemq-data folders to ignore * Cleaned up unused code, added documentation to the README.md * Added more comments * Added Copyright notices --- .gitignore | 2 + basic/tcp-client-server/README.md | 5 + basic/tcp-client-server/pom.xml | 8 +- .../ByteArrayToStringConverter.java | 2 +- .../samples/tcpclientserver/CustomOrder.java | 54 +++++++ .../CustomSerializerDeserializer.java | 149 ++++++++++++++++++ .../samples/tcpclientserver/EchoService.java | 4 +- .../tcpclientserver/SimpleGateway.java | 4 +- .../samples/tcpclientserver/TelnetServer.java | 4 +- ...tcpServerConnectionDeserialize-context.xml | 66 ++++++++ .../tcpServerCustomSerialize-context.xml | 34 ++++ .../src/main/resources/log4j.xml | 6 +- .../TcpClientServerDemoTest.java | 8 +- .../TcpServerConnectionDeserializeTest.java | 100 ++++++++++++ .../TcpServerCustomSerializerTest.java | 120 ++++++++++++++ 15 files changed, 554 insertions(+), 12 deletions(-) create mode 100644 basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/CustomOrder.java create mode 100644 basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/CustomSerializerDeserializer.java create mode 100644 basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpServerConnectionDeserialize-context.xml create mode 100644 basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpServerCustomSerialize-context.xml create mode 100644 basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpServerConnectionDeserializeTest.java create mode 100644 basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpServerCustomSerializerTest.java diff --git a/.gitignore b/.gitignore index 278e4bd1..e06881e9 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ log.roo *.ipr *.iws derby.log +.idea +activemq-data diff --git a/basic/tcp-client-server/README.md b/basic/tcp-client-server/README.md index c4f05803..4ec514a9 100644 --- a/basic/tcp-client-server/README.md +++ b/basic/tcp-client-server/README.md @@ -47,3 +47,8 @@ This can also be demonstrated with the telnet client thus... telnet> quit Connection closed. +A third option exists for converting a stream of bytes to a domain object or message payload. You can hook up different serializers/deserializers at the connection factory which will apply the conversions right when the stream comes in to the gateway and right when it goes out. + +See **TcpServerConnectionDeserializeTest** for using a simple (comes with spring) Stx/Etx serializer. + +See **TcpServerCustomSerializerTest** for creating and using your own serializers \ No newline at end of file diff --git a/basic/tcp-client-server/pom.xml b/basic/tcp-client-server/pom.xml index b43cb304..aa558496 100644 --- a/basic/tcp-client-server/pom.xml +++ b/basic/tcp-client-server/pom.xml @@ -47,7 +47,13 @@ ${spring.version} test - + + commons-lang + commons-lang + 2.6 + + + diff --git a/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/ByteArrayToStringConverter.java b/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/ByteArrayToStringConverter.java index 096b1d7c..80acafba 100644 --- a/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/ByteArrayToStringConverter.java +++ b/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/ByteArrayToStringConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * 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. diff --git a/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/CustomOrder.java b/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/CustomOrder.java new file mode 100644 index 00000000..9ab1513f --- /dev/null +++ b/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/CustomOrder.java @@ -0,0 +1,54 @@ +/* + * 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 org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; + +/** + * @author: ceposta + */ +public class CustomOrder { + private int number; + private String sender; + private String message; + + public CustomOrder(int number, String sender) { + this.number = number; + this.sender = sender; + } + + public int getNumber() { + return number; + } + + public String getSender() { + return sender; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); + } +} diff --git a/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/CustomSerializerDeserializer.java b/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/CustomSerializerDeserializer.java new file mode 100644 index 00000000..9beaa8b4 --- /dev/null +++ b/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/CustomSerializerDeserializer.java @@ -0,0 +1,149 @@ +/* + * 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 java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.core.serializer.Deserializer; +import org.springframework.core.serializer.Serializer; + +/** + * This class is used to demonstrate how you can create a custom serializer/deserializer + * to convert a TCP stream into custom objects which your domain-specific code can use. + * + * Since this is custom, it will have to have its own predefined assumptions for dealing + * with the stream. In other words, there will have to be some indication within the + * contents of the stream where the beginning/end is and how to extract the contents + * into something meaningful (like an object). An example would be a fixed-file formatted + * stream with the length encoded in some well known part of the stream (for example, the + * first 8 bytes of the stream?). + * + * This custom serializer/deserializer assumes the first 3 bytes of the stream will be + * considered an Order Number, the next 10 bytes will be the Sender's Name, the next 6 bytes + * represents an left-zero-padded integer that specifies how long the rest of the message + * content is. After that message content is parsed from the stream, the stream is assumed + * to not have anything after it. In your code you could have delimiters to mark the end + * of the stream, or could agree with the client that a valid stream is only n characters, + * etc. Eitherway, since its custom, the client and server must have some predefined + * assumptions in place for the communication to take place. + * + * + * @author: ceposta + */ +public class CustomSerializerDeserializer implements Serializer, Deserializer{ + + protected final Log logger = LogFactory.getLog(this.getClass()); + + private static final int ORDER_NUMBER_LENGTH = 3; + private static final int SENDER_NAME_LENGTH = 10; + private static final int MESSAGE_LENGTH_LENGTH = 6; + + + /** + * Convert a CustomOrder object into a byte-stream + * + * @param object + * @param outputStream + * @throws IOException + */ + public void serialize(CustomOrder object, OutputStream outputStream) throws IOException { + byte[] number = Integer.toString(object.getNumber()).getBytes(); + outputStream.write(number); + + byte[] senderName = object.getSender().getBytes(); + outputStream.write(senderName); + + String lenghtPadded = pad(6, object.getMessage().length()); + byte[] length = lenghtPadded.getBytes(); + outputStream.write(length); + + outputStream.write(object.getMessage().getBytes()); + outputStream.flush(); + } + + private String pad(int desiredLength, int length) { + return StringUtils.leftPad(Integer.toString(length), desiredLength, '0'); + } + + /** + * Convert a raw byte stream into a CustomOrder + * + * @param inputStream + * @return + * @throws IOException + */ + public CustomOrder deserialize(InputStream inputStream) throws IOException { + int orderNumber = parseOrderNumber(inputStream); + String senderName = parseSenderName(inputStream); + + CustomOrder order = new CustomOrder(orderNumber, senderName); + String message = parseMessage(inputStream); + order.setMessage(message); + return order; + } + + private String parseMessage(InputStream inputStream) throws IOException { + String lengthString = parseString(inputStream, MESSAGE_LENGTH_LENGTH); + int lengthOfMessage = Integer.valueOf(lengthString); + + String message = parseString(inputStream, lengthOfMessage); + return message; + } + + private String parseString(InputStream inputStream, int length) throws IOException { + StringBuilder builder = new StringBuilder(); + + int c; + for (int i = 0; i < length; ++i) { + c = inputStream.read(); + checkClosure(c); + builder.append((char)c); + } + + return builder.toString(); + } + + private String parseSenderName(InputStream inputStream) throws IOException { + return parseString(inputStream, SENDER_NAME_LENGTH); + } + + private int parseOrderNumber(InputStream inputStream) throws IOException { + String value = parseString(inputStream, ORDER_NUMBER_LENGTH); + return Integer.valueOf(value.toString()); + } + + + /** + * Check whether the byte passed in is the "closed socket" byte + * Note, I put this in here just as an example, but you could just extend the + * {@link org.springframework.integration.ip.tcp.serializer.AbstractByteArraySerializer} class + * which has this method + * + * @param bite + * @throws IOException + */ + protected void checkClosure(int bite) throws IOException { + if (bite < 0) { + logger.debug("Socket closed during message assembly"); + throw new IOException("Socket closed during message assembly"); + } + } +} diff --git a/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/EchoService.java b/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/EchoService.java index e0015dc9..d63e1810 100644 --- a/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/EchoService.java +++ b/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/EchoService.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * 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. @@ -18,7 +18,7 @@ package org.springframework.integration.samples.tcpclientserver; /** * Simple service that receives data in a byte array, * converts it to a String and appends it to 'echo:'. - * + * * @author Gary Russell * */ diff --git a/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/SimpleGateway.java b/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/SimpleGateway.java index df7d1b51..c6c7dcc4 100644 --- a/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/SimpleGateway.java +++ b/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/SimpleGateway.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * 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. @@ -22,5 +22,5 @@ package org.springframework.integration.samples.tcpclientserver; public interface SimpleGateway { public String send(String text); - + } \ No newline at end of file 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 99d97e5e..4d471ad0 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * 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. @@ -22,7 +22,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; * it works fine as a very simple Telnet server - connect using * telnet localhost 11111 - each time you hit enter you should see your input * echoed back, preceded by 'echo:'. - * + * * @author Gary Russell * */ 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 new file mode 100644 index 00000000..174bf73e --- /dev/null +++ b/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpServerConnectionDeserialize-context.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ 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 new file mode 100644 index 00000000..32887a62 --- /dev/null +++ b/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpServerCustomSerialize-context.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/basic/tcp-client-server/src/main/resources/log4j.xml b/basic/tcp-client-server/src/main/resources/log4j.xml index f391e2ed..4c5f6f83 100644 --- a/basic/tcp-client-server/src/main/resources/log4j.xml +++ b/basic/tcp-client-server/src/main/resources/log4j.xml @@ -15,6 +15,10 @@ + + + + @@ -24,5 +28,5 @@ - + \ 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 50c830b4..bdff84ea 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * 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. @@ -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.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -27,7 +28,7 @@ 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 + * 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. * @@ -43,9 +44,10 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; // This one uses the conversion service //@ContextConfiguration("/META-INF/spring/integration/tcpClientServerDemo-conversion-context.xml") @RunWith(SpringJUnit4ClassRunner.class) +@DirtiesContext public class TcpClientServerDemoTest { - @Autowired + @Autowired SimpleGateway gw; @Test 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 new file mode 100644 index 00000000..335197c9 --- /dev/null +++ b/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpServerConnectionDeserializeTest.java @@ -0,0 +1,100 @@ +/* + * 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 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.integration.Message; +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.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.io.StringWriter; + +import static org.junit.Assert.assertEquals; + +/** + * Shows an example of using the Stx/Etx stream framing serializers that are included with + * Spring Integration. We can be confident that the streams are properly handled because we + * explicitly send a stream with the Stx/Etx frame and the beginning and end of the actual + * content and the Server is configured to be able to handle the frame. In the asserts, we + * assert that the payload, once it reaches a component (in this case, the message listener + * we create and attach to the incomingServerChannel), does not have any of the Stx/Etx bytes. + * + * @author: ceposta + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = {"/META-INF/spring/integration/tcpServerConnectionDeserialize-context.xml"}) +@DirtiesContext +public class TcpServerConnectionDeserializeTest { + + @Autowired + SimpleGateway gw; + + @Autowired + @Qualifier("incomingServerChannel") + MessageChannel incomingServerChannel; + + @Test + public void testHappyPath() { + + // add a listener to this channel, otherwise there is not one defined + // the reason we use a listener here is so we can assert truths on the + // message and/or payload + SubscribableChannel channel = (SubscribableChannel) incomingServerChannel; + channel.subscribe(new AbstractReplyProducingMessageHandler(){ + + @Override + protected Object handleRequestMessage(Message requestMessage) { + byte[] payload = (byte[]) requestMessage.getPayload(); + + // we assert during the processing of the messaging that the + // payload is just the content we wanted to send without the + // framing bytes (STX/ETX) + assertEquals("Hello World!", new String(payload)); + return requestMessage; + } + }); + + String sourceMessage = wrapWithStxEtx("Hello World!"); + String result = gw.send(sourceMessage); + System.out.println(result); + assertEquals("Hello World!", result); + } + + /** + * Show, explicitly, how the stream would look if you had to manually create it. + * + * See more about TCP synchronous communication for more about framing the stream + * with STX/ETX: http://en.wikipedia.org/wiki/Binary_Synchronous_Communications + * + * @param content + * @return a string that is wrapped with the STX/ETX framing bytes + */ + private String wrapWithStxEtx(String content) { + StringWriter writer = new StringWriter(); + writer.write(ByteArrayStxEtxSerializer.STX); + writer.write(content); + writer.write(ByteArrayStxEtxSerializer.ETX); + return writer.toString(); + } +} 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 new file mode 100644 index 00000000..14a2396f --- /dev/null +++ b/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpServerCustomSerializerTest.java @@ -0,0 +1,120 @@ +/* + * 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 static org.junit.Assert.fail; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.net.Socket; + +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.integration.Message; +import org.springframework.integration.MessageChannel; +import org.springframework.integration.core.SubscribableChannel; +import org.springframework.integration.handler.AbstractReplyProducingMessageHandler; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * Some use cases may dictate you needing to create your own stream handling serializers + * and deserializers. This sample shows a custom serializer/deserializer being used with + * the Java socket API on the front end (client) and the Spring Integration TCP inbound + * gateway with the custom serializer/deserializers. + * + * @author: ceposta + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = {"/META-INF/spring/integration/tcpServerCustomSerialize-context.xml"}) +@DirtiesContext +public class TcpServerCustomSerializerTest { + + @Autowired + @Qualifier("incomingServerChannel") + MessageChannel incomingServerChannel; + + @Test + public void testHappyPath() { + + // add a listener to this channel, otherwise there is not one defined + // the reason we use a listener here is so we can assert truths on the + // message and/or payload + SubscribableChannel channel = (SubscribableChannel) incomingServerChannel; + channel.subscribe(new AbstractReplyProducingMessageHandler(){ + + @Override + protected Object handleRequestMessage(Message requestMessage) { + CustomOrder payload = (CustomOrder) requestMessage.getPayload(); + + // we assert during the processing of the messaging that the + // payload is just the content we wanted to send without the + // framing bytes (STX/ETX) + assertEquals(123, payload.getNumber()); + assertEquals("PINGPONG02", payload.getSender()); + assertEquals("You got it to work!", payload.getMessage()); + return requestMessage; + } + }); + + String sourceMessage = "123PINGPONG02000019You got it to work!"; + + + // use the java socket API to make the connection to the server + Socket socket = null; + Writer out = null; + BufferedReader in = null; + try { + socket = new Socket("localhost", 11111); + out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); + out.write(sourceMessage); + out.flush(); + + in = new BufferedReader(new InputStreamReader(socket.getInputStream())); + StringBuffer str = new StringBuffer(); + + int c; + while ((c = in.read()) != -1) { + str.append((char) c); + } + + String response = str.toString(); + assertEquals(sourceMessage, response); + + } catch (IOException e) { + fail("Test ended with an exception " + e.getMessage()); + } + finally { + try { + socket.close(); + out.close(); + in.close(); + + } catch (Exception e) { + // swallow exception + } + + } + } +}