xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.springframework.integration.samples</groupId>
    <artifactId>jdbc</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>jdbc-sample</name>
    <url>http://www.springsource.org/spring-integration</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring.integration.version>2.1.0.M3</spring.integration.version>
        <slf4j.version>1.6.1</slf4j.version>
        <junit.version>4.7</junit.version>
        <spring.test.version>3.0.6.RELEASE</spring.test.version>
		<derbyclient.driver.version>10.8.2.2</derbyclient.driver.version>
    </properties>

    <repositories>
        <repository>
            <id>repository.springframework.maven.release</id>
            <name>Spring Framework Maven Release Repository</name>
            <url>http://maven.springframework.org/release</url>
        </repository>
		<repository>
		    <id>repository.springframework.maven.milestone</id>
		    <name>Spring Framework Maven Milestone Repository</name>
		    <url>http://maven.springframework.org/milestone</url>
		</repository>
    </repositories>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.8</version>
                <configuration>
                    <additionalProjectnatures>
                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                    </additionalProjectnatures>
                    <additionalBuildcommands>
                        <buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
                    </additionalBuildcommands>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>true</downloadJavadocs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArgument>-Xlint:all</compilerArgument>
                    <showWarnings>true</showWarnings>
                    <showDeprecation>true</showDeprecation>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2</version>
                <configuration>
                    <mainClass>org.springframework.integration.samples.jdbc.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>

        <!-- Testing -->

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>

        <!-- Spring Integration -->

        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-core</artifactId>
            <version>${spring.integration.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.integration</groupId>
            <artifactId>spring-integration-jdbc</artifactId>
            <version>${spring.integration.version}</version>
        </dependency>

        <!-- Logging -->

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>0.9.28</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j-over-slf4j</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${slf4j.version}</version>
        </dependency>

        <!-- Embedded Database -->

        <dependency>
	        <groupId>com.h2database</groupId>
	        <artifactId>h2</artifactId>
	        <version>1.3.160</version>
	    </dependency>

	    <!-- Derby dependency -->
	    <dependency>
    		<groupId>org.apache.derby</groupId>
    		<artifactId>derbyclient</artifactId>
    		<version>${derbyclient.driver.version}</version>
		</dependency>

		<!-- Spring test -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.test.version}</version>
		</dependency>
    </dependencies>
</project>
This commit is contained in:
Amol Nayak
2011-12-14 23:48:21 +05:30
86 changed files with 3906 additions and 108 deletions

1
.gitignore vendored
View File

@@ -9,3 +9,4 @@ log.roo
*.iml
*.ipr
*.iws
derby.log

View File

@@ -52,6 +52,8 @@ This category targets developers who are already more familiar with the Spring I
* **file-processing** - Sample demonstrates how to wire a message flow to process files either sequentially (maintain the order) or concurrently (no order).
* **multipart-http** - Demonstrates the sending of HTTP multipart requests using Spring's **RestTemplate** and a Spring Integration **Http Outbound Gateway**
* **travel** - More sophisticated example showing the retrieval of weather (SOAP Web Service) and traffic (HTTP Service) reports using real services
* **stored-procedures-derby** Provides an example of the stored procedure Outbound Gateway using *[Apache Derby](http://db.apache.org/derby/)*
* **stored-procedures-oracle** Provides an example of the stored procedure Outbound Gateway using *ORACLE XE*
## Advanced

5
applications/cafe-scripted/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
/target
.classpath
.project
.springBeans
.settings

View File

@@ -0,0 +1,27 @@
Cafe Demo - Scripted Implementation
===================================
This is the scripted implementation of the classic **cafe** sample application. You can choose among **javascript**,
**groovy**, **ruby**, and **python** scripting languages. The functionality is basically identical in all cases to the
original cafe demo.
# Instructions for running the CafeDemo sample
The script language is passed as a command line argument. This may be run directly from maven:
>mvn clean compile
>mvn exec:exec -Dlang=[language]
## Groovy Control Bus
This sample also demonstrates the use of Spring Integration's **groovy control bus** which accepts
Groovy scripts as control messages. These scripts may invoke lifecycle operations on adapters or
operations on managed beans.
To demonstrate the control bus, while the CafeDemoApp is running, execute in a separate window:
>mvn exec:exec -Pcontrol-bus
This will use groovy scripts to
* Query the waiter for the total number of orders delivered
* If the total orders > 3, stop the inbound adaptor on the cafe (the order flow). The Cafe application
will continue to run, but eventually the output will stop when all pending orders have completed.

View File

@@ -0,0 +1,212 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.integration.samples</groupId>
<artifactId>cafe-scripted</artifactId>
<version>2.1.0</version>
<name>Spring Integration Cafe Sample</name>
<properties>
<spring.integration.version>2.1.0.RC1</spring.integration.version>
<spring.version>3.1.0.RC1</spring.version>
<log4j.version>1.2.16</log4j.version>
<junit.version>4.7</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-stream</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-groovy</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-rmi</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-jmx</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-scripting</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<!-- This is an older release. 1.6 and above cause stdout to mysteriously
dissappear -->
<dependency>
<groupId>org.jruby</groupId>
<artifactId>jruby</artifactId>
<version>1.5.6</version>
</dependency>
<dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>1.7.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.2</version>
<configuration>
<source>1.5</source>
<target>1.6</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>false</showDeprecation>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<id>demo</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>java</executable>
<arguments>
<argument>-classpath</argument>
<classpath />
<argument>org.springframework.integration.samples.cafe.demo.CafeDemoApp</argument>
<argument>${lang}</argument>
</arguments>
<successCodes>
<successCode>0</successCode>
</successCodes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>control-bus</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>java</executable>
<arguments>
<argument>-classpath</argument>
<classpath />
<argument>org.springframework.integration.samples.cafe.demo.ControlBusMain</argument>
</arguments>
<successCodes>
<successCode>0</successCode>
</successCodes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<repositories>
<repository>
<id>repository.springframework.maven.release</id>
<name>Spring Framework Maven Release Repository</name>
<url>http://maven.springframework.org/release</url>
</repository>
<repository>
<id>repository.springframework.maven.milestone</id>
<name>Spring Framework Maven Milestone Repository</name>
<url>http://maven.springframework.org/milestone</url>
</repository>
<repository>
<id>repository.springframework.maven.snapshot</id>
<name>Spring Framework Maven Snapshot Repository</name>
<url>http://maven.springframework.org/snapshot</url>
</repository>
</repositories>
</project>

View File

@@ -0,0 +1,19 @@
package groovy
import org.springframework.integration.samples.cafe.Drink
def prepareDrink(orderItem){
println "groovy: preparing $orderItem for order ${orderItem.order.number}"
try {
Thread.sleep(timeToPrepare as long)
} catch (e) {
println "sleep interrupted"
}
new Drink(orderItem.getOrder().getNumber(), orderItem.getDrinkType(), orderItem.isIced(),
orderItem.getShots())
}
prepareDrink(payload)

View File

@@ -0,0 +1,13 @@
importClass(org.springframework.integration.samples.cafe.Drink);
importClass(java.lang.Thread);
importClass(java.lang.System);
function prepareDrink(orderItem){
Thread.sleep(timeToPrepare);
System.out.println("javascript: preparing "+ orderItem + " for order "+ orderItem.getOrder().getNumber())
return new Drink(orderItem.getOrder().getNumber(), orderItem.getDrinkType(), orderItem.isIced(),
orderItem.getShots())
}
prepareDrink(payload);

View File

@@ -0,0 +1,11 @@
from org.springframework.integration.samples.cafe import Drink
import time
def prepareDrink(orderItem):
print("python: preparing %s for order %s" % (orderItem,orderItem.order.number))
time.sleep(eval(timeToPrepare))
return Drink(orderItem.getOrder().getNumber(), orderItem.getDrinkType(), orderItem.isIced(),
orderItem.getShots())
drink = prepareDrink(payload)

View File

@@ -0,0 +1,15 @@
require 'java'
import org.springframework.integration.samples.cafe.Drink
orderItem = payload
puts "ruby: preparing #{orderItem} for order #{orderItem.order.number}"
sleep(timeToPrepare.to_f)
Drink.new(orderItem.getOrder().getNumber(), orderItem.getDrinkType(), orderItem.isIced(),
orderItem.getShots())

View File

@@ -0,0 +1,27 @@
/*
* Copyright 2002-2011 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.cafe;
/**
* @author David Turanski
*
*/
public class Customer {
int orderNumber = 1;
public Order getOrder(){
Order order = new Order(orderNumber++);
order.addItem(DrinkType.LATTE, 2, false);
order.addItem(DrinkType.MOCHA, 3, true);
return order;
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.samples.cafe;
import java.util.List;
/**
* @author Marius Bogoevici
*/
public class Delivery {
private static final String SEPARATOR = "-----------------------";
private List<Drink> deliveredDrinks;
private int orderNumber;
public Delivery(List<Drink> deliveredDrinks) {
assert(deliveredDrinks.size() > 0);
this.deliveredDrinks = deliveredDrinks;
this.orderNumber = deliveredDrinks.get(0).getOrderNumber();
}
public int getOrderNumber() {
return orderNumber;
}
public List<Drink> getDeliveredDrinks() {
return deliveredDrinks;
}
@Override
public String toString() {
StringBuffer buffer = new StringBuffer(SEPARATOR + "\n");
buffer.append("Order #" + getOrderNumber() + "\n");
for (Drink drink : getDeliveredDrinks()) {
buffer.append(drink);
buffer.append("\n");
}
buffer.append(SEPARATOR + "\n");
return buffer.toString();
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2002-2011 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.cafe;
/**
* @author Marius Bogoevici
*/
public class Drink {
private boolean iced;
private int shots;
private DrinkType drinkType;
private int orderNumber;
public Drink(int orderNumber, DrinkType drinkType, boolean hot, int shots) {
this.orderNumber = orderNumber;
this.drinkType = drinkType;
this.iced = hot;
this.shots = shots;
}
public int getOrderNumber() {
return orderNumber;
}
@Override
public String toString() {
return (iced?"Iced":"Hot") + " " + drinkType.toString() + ", " + shots + " shots.";
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright 2002-2011 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.cafe;
/**
* @author Mark Fisher
*/
public enum DrinkType {
ESPRESSO,
LATTE,
CAPPUCCINO,
MOCHA
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2002-2011 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.cafe;
import java.util.ArrayList;
import java.util.List;
/**
* @author Mark Fisher
* @author Marius Bogoevici
*/
public class Order {
private List<OrderItem> orderItems = new ArrayList<OrderItem>();
private int number;
public Order(int number) {
this.number = number;
}
public void addItem(DrinkType drinkType, int shots, boolean iced) {
this.orderItems.add(new OrderItem(this, drinkType, shots, iced));
}
public int getNumber() {
return number;
}
public List<OrderItem> getItems() {
return this.orderItems;
}
public String toString() {
return "Order number " + number;
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright 2002-2011 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.cafe;
/**
* @author Mark Fisher
* @author Marius Bogoevici
*/
public class OrderItem {
private DrinkType type;
private int shots = 1;
private boolean iced = false;
private final Order order;
public OrderItem(Order order, DrinkType type, int shots, boolean iced) {
this.order = order;
this.type = type;
this.shots = shots;
this.iced = iced;
}
public Order getOrder() {
return this.order;
}
public boolean isIced() {
return this.iced;
}
public int getShots() {
return shots;
}
public DrinkType getDrinkType() {
return this.type;
}
public String toString() {
return ((this.iced) ? "iced " : "hot ") + " order:" + this.order.getNumber() + " " +this.shots + " shot " + this.type;
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.samples.cafe;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedResource;
/**
* A managed resource implementation to expose the total deliveries via the Control Bus
*
* @author Marius Bogoevici
* @author David Turanski
*/
@ManagedResource
public class Waiter {
private AtomicInteger totalDeliveries = new AtomicInteger();
public Delivery prepareDelivery(List<Drink> drinks) {
totalDeliveries.getAndIncrement();
return new Delivery(drinks);
}
@ManagedOperation
public int getTotalDeliveries() {
return this.totalDeliveries.get();
}
}

View File

@@ -0,0 +1,22 @@
/*
* Copyright 2002-2011 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.cafe;
/**
* Send a groovy script to the control bus and return the result
* @author David Turanski
*
*/
public interface WaiterMonitor {
Object sendControlScript(String script);
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright 2002-2011 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.cafe.demo;
import java.util.Arrays;
import java.util.List;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.StringUtils;
/**
* An implementation of the Cafe Demo application to demonstrate Spring Integration's
* scripting capability. This process expects a command line argument corresponding to the scripting language
* to use.
*
* Provides the 'main' method for running the Cafe Demo application. When an
* order is placed, the Cafe will send that order to the "orders" channel.
* The relevant components are defined within the configuration file
* ("cafeDemo.xml").
*
* @author Mark Fisher
* @author Marius Bogoevici
* @author Oleg Zhurakousky
* @author David Turanski
*/
public class CafeDemoApp {
public static void main(String[] args) {
List<String> languages = Arrays.asList(new String[]{"groovy","ruby","javascript","python"});
if (args.length != 1) {
usage();
}
String lang = args[0];
if (!StringUtils.hasText(lang)){
usage();
}
lang = lang.toLowerCase();
if (!languages.contains(lang)){
usage();
}
/*
* Create an application context and set the active profile to configure the
* corresponding scripting implementation
*/
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext();
((ConfigurableEnvironment)ctx.getEnvironment()).setActiveProfiles(lang);
ctx.setConfigLocation("/META-INF/spring/integration/cafeDemo.xml");
ctx.refresh();
}
private static void usage() {
System.out.println("missing or invalid commannd line argument [groovy,ruby,javascript,python]");
System.exit(1);
}
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2002-2011 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.cafe.demo;
import org.apache.log4j.Logger;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.samples.cafe.WaiterMonitor;
/**
* Sets up a remote connection to the CafeDemoApp to manage it using the Groovy Control Bus.
* The WaiterMonitor queries the total delivered orders every second.
* If totalDeliveries >= 3, stop the cafe inbound adapter.
*
* @author David Turanski
*
*/
public class ControlBusMain {
private static Logger logger = Logger.getLogger(ControlBusMain.class);
public static void main(String[] args) {
AbstractApplicationContext context =
new ClassPathXmlApplicationContext("/META-INF/spring/integration/cafeDemo-control-bus.xml");
WaiterMonitor waiterMonitor = (WaiterMonitor) context.getBean("waiterMonitor");
int totalDeliveries = 0;
while (totalDeliveries <= 3) {
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
totalDeliveries = (Integer)waiterMonitor.sendControlScript("waiter.totalDeliveries");
logger.info("Total cafe deliveries: " + totalDeliveries);
if (totalDeliveries > 3) {
logger.info("stopping orders...");
waiterMonitor.sendControlScript("cafe.stop()");
logger.info("orders stopped");
}
}
context.close();
System.exit(0);
}
}

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/integration"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:groovy="http://www.springframework.org/schema/integration/groovy"
xmlns:rmi="http://www.springframework.org/schema/integration/rmi"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/rmi http://www.springframework.org/schema/integration/rmi/spring-integration-rmi.xsd
http://www.springframework.org/schema/integration/groovy http://www.springframework.org/schema/integration/groovy/spring-integration-groovy.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<beans:description>
This is the application context for ControlBusMain. It configures a Gateway tied to an RMI outbound gateway to communicate
remotely with the CafeDemoApp.
</beans:description>
<gateway id="waiterMonitor"
service-interface="org.springframework.integration.samples.cafe.WaiterMonitor">
<method name="sendControlScript" request-channel="controlBusInput" request-timeout="1000" reply-timeout="1000"/>
</gateway>
<rmi:outbound-gateway
request-channel="controlBusInput"
remote-channel="controlBusInput"
reply-timeout="1000"
request-timeout="1000"
host="localhost"/>
</beans:beans>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:stream="http://www.springframework.org/schema/integration/stream"
xmlns:script="http://www.springframework.org/schema/integration/scripting"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/script http://www.springframework.org/schema/integration/script.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration/scripting http://www.springframework.org/schema/integration/scripting/spring-integration-scripting.xsd">
<splitter input-channel="orders" output-channel="drinks">
<script:script lang="groovy">payload.items</script:script>
</splitter>
<router id="orderRouter" input-channel="drinks">
<script:script lang="groovy">payload.iced ? "coldDrinks" : "hotDrinks"</script:script>
</router>
<service-activator id="coldDrinkBarista" input-channel="coldDrinks" output-channel="preparedDrinks">
<script:script lang="groovy" location="file:scripts/groovy/barista.groovy">
<script:variable name="timeToPrepare" value="1000"/>
</script:script>
</service-activator>
<service-activator id="hotDrinkBarista" input-channel="hotDrinks" output-channel="preparedDrinks">
<script:script lang="groovy" location="file:scripts/groovy/barista.groovy">
<script:variable name="timeToPrepare" value="5000"/>
</script:script>
</service-activator>
</beans:beans>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:stream="http://www.springframework.org/schema/integration/stream"
xmlns:script="http://www.springframework.org/schema/integration/scripting"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/script http://www.springframework.org/schema/integration/script.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration/scripting http://www.springframework.org/schema/integration/scripting/spring-integration-scripting.xsd">
<splitter input-channel="orders" output-channel="drinks">
<script:script lang="js">payload.items;</script:script>
</splitter>
<router input-channel="drinks">
<script:script lang="js">payload.iced ? "coldDrinks" : "hotDrinks";</script:script>
</router>
<service-activator input-channel="coldDrinks" output-channel="preparedDrinks">
<script:script lang="js" location="file:scripts/javascript/barista.js">
<script:variable name="timeToPrepare" value="1000"/>
</script:script>
</service-activator>
<service-activator input-channel="hotDrinks" output-channel="preparedDrinks">
<script:script lang="js" location="file:scripts/javascript/barista.js">
<script:variable name="timeToPrepare" value="5000"/>
</script:script>
</service-activator>
</beans:beans>

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:stream="http://www.springframework.org/schema/integration/stream"
xmlns:script="http://www.springframework.org/schema/integration/scripting"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/script http://www.springframework.org/schema/integration/script.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration/scripting http://www.springframework.org/schema/integration/scripting/spring-integration-scripting.xsd">
<splitter input-channel="orders" output-channel="drinks">
<!-- Note an explicit variable assignment is required here. This is a limitation of the Jython script engine -->
<script:script lang="python">items=payload.items</script:script>
</splitter>
<router input-channel="drinks">
<script:script lang="python">'coldDrinks' if payload.iced else 'hotDrinks'
</script:script>
</router>
<service-activator input-channel="coldDrinks"
output-channel="preparedDrinks">
<script:script lang="python" location="file:scripts/python/barista.py">
<script:variable name="timeToPrepare" value="1" />
</script:script>
</service-activator>
<service-activator input-channel="hotDrinks"
output-channel="preparedDrinks">
<script:script lang="python" location="file:scripts/python/barista.py">
<script:variable name="timeToPrepare" value="5" />
</script:script>
</service-activator>
</beans:beans>

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:stream="http://www.springframework.org/schema/integration/stream"
xmlns:script="http://www.springframework.org/schema/integration/scripting"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/script http://www.springframework.org/schema/integration/script.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration/scripting http://www.springframework.org/schema/integration/scripting/spring-integration-scripting.xsd">
<splitter input-channel="orders" output-channel="drinks">
<script:script lang="ruby">payload.items</script:script>
</splitter>
<router input-channel="drinks">
<script:script lang="ruby">
payload.iced ? "coldDrinks": "hotDrinks"
</script:script>
</router>
<service-activator input-channel="coldDrinks"
output-channel="preparedDrinks">
<script:script lang="ruby" location="file:scripts/ruby/barista.rb">
<script:variable name="timeToPrepare" value="1" />
</script:script>
</service-activator>
<service-activator input-channel="hotDrinks"
output-channel="preparedDrinks">
<script:script lang="ruby" location="file:scripts/ruby/barista.rb">
<script:variable name="timeToPrepare" value="5" />
</script:script>
</service-activator>
</beans:beans>

View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:groovy="http://www.springframework.org/schema/integration/groovy"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:rmi="http://www.springframework.org/schema/integration/rmi"
xmlns:stream="http://www.springframework.org/schema/integration/stream"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/rmi http://www.springframework.org/schema/integration/rmi/spring-integration-rmi.xsd
http://www.springframework.org/schema/integration/stream http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd
http://www.springframework.org/schema/integration/groovy http://www.springframework.org/schema/integration/groovy/spring-integration-groovy.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<beans:description>
This is the application context for the scripted implementation of CafeDemoApp. The functionality is basically
identical to the original CafeDemoApp.
In order to demonstrate the Groovy control bus, the original cafe Gateway is replaced with an
inbound-channel-adapter (which supports the SmartLifeCycle interface).
The inbound-channel-adapter is backed by a Customer bean which provides the orders.
This configuration also uses Spring 3.1 environment profiles to inject a configuration specific to the
selected scripting language.
</beans:description>
<beans:beans>
<rmi:inbound-gateway request-channel="controlBusInput"
reply-channel="controlBusOutput" />
<groovy:control-bus input-channel="controlBusInput"
output-channel="controlBusOutput" />
<channel id="controlBusOutput" />
<inbound-channel-adapter id="cafe" channel="orders"
ref="customer" method="getOrder" />
<beans:bean id="customer"
class="org.springframework.integration.samples.cafe.Customer" />
<channel id="orders" />
<channel id="coldDrinks">
<queue capacity="10" />
</channel>
<channel id="hotDrinks">
<queue capacity="10" />
</channel>
<!-- Aggregator does not currently support scripting -->
<aggregator input-channel="preparedDrinks" method="prepareDelivery"
output-channel="deliveries" ref="waiter" />
<beans:bean id="waiter"
class="org.springframework.integration.samples.cafe.Waiter" />
<stream:stdout-channel-adapter id="deliveries" />
<poller id="poller" default="true" fixed-delay="1000" />
</beans:beans>
<beans:beans profile="groovy">
<beans:import
resource="classpath:META-INF/spring/integration/cafeDemo-groovy.xml" />
</beans:beans>
<beans:beans profile="ruby">
<beans:import
resource="classpath:META-INF/spring/integration/cafeDemo-ruby.xml" />
</beans:beans>
<beans:beans profile="javascript">
<beans:import
resource="classpath:META-INF/spring/integration/cafeDemo-javascript.xml" />
</beans:beans>
<beans:beans profile="python">
<beans:import
resource="classpath:META-INF/spring/integration/cafeDemo-python.xml" />
</beans:beans>
</beans:beans>

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- Appenders -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%r %t %-5p: %c - %m%n" />
</layout>
</appender>
<!-- Loggers -->
<logger name="org.springframework">
<level value="warn" />
</logger>
<logger name="org.springframework.integration">
<level value="warn" />
</logger>
<logger name="loggingInterceptor">
<level value="debug" />
</logger>
<logger name="org.springframework.integration.samples">
<level value="debug" />
</logger>
<!-- Root Logger -->
<root>
<priority value="info" />
<appender-ref ref="console" />
</root>
</log4j:configuration>

View File

@@ -0,0 +1,63 @@
/*
* Copyright 2002-2011 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.cafe;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import org.springframework.core.io.FileSystemResource;
import org.springframework.integration.scripting.ScriptExecutor;
import org.springframework.integration.scripting.jsr223.ScriptExecutorFactory;
import org.springframework.scripting.support.ResourceScriptSource;
/**
* @author David Turanski
*
*/
public class ScriptTests {
@Test
public void testRuby() {
ScriptExecutor executor = ScriptExecutorFactory.getScriptExecutor("ruby");
Order order = new Order(0);
order.addItem(DrinkType.LATTE, 2, false);
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("payload", order.getItems().get(0));
variables.put("timeToPrepare", 1L);
Object obj = executor.executeScript(
new ResourceScriptSource(new FileSystemResource("scripts/ruby/barista.rb")), variables);
assertNotNull(obj);
assertTrue(obj instanceof Drink);
}
@Test
public void testPython() {
ScriptExecutor executor = ScriptExecutorFactory.getScriptExecutor("python");
Order order = new Order(0);
order.addItem(DrinkType.LATTE, 2, false);
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("payload", order.getItems().get(0));
variables.put("timeToPrepare", "1");
Object obj = executor.executeScript(new ResourceScriptSource(
new FileSystemResource("scripts/python/barista.py")), variables);
assertNotNull(obj);
assertTrue(obj instanceof Drink);
}
}

View File

@@ -7,14 +7,25 @@
<version>2.0.0</version>
<name>Spring Integration Cafe Sample</name>
<properties>
<spring.integration.version>2.0.5.RELEASE</spring.integration.version>
<spring.integration.version>2.1.0.M3</spring.integration.version>
<spring.core.version>3.1.0.RC1</spring.core.version>
<log4j.version>1.2.16</log4j.version>
<junit.version>4.7</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.core.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.core.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<artifactId>spring-integration-amqp</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<dependency>
@@ -22,6 +33,17 @@
<artifactId>spring-integration-stream</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<!-- Jackson JSON Mapper -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.8.3</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.8.3</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>

View File

@@ -8,7 +8,7 @@ The domain is that of a Cafe, and the basic flow is depicted in the following di
|==========| -->| |
orders drinks / | prepareHotDrink() |
Place Order ->Cafe->|======|->OrderSplitter->|======|->DrinkRouter | |
\ coldDeinks | prepareColdDrink() |
\ coldDrinks | prepareColdDrink() |
|==========| -->| |
|____________________|
@@ -26,11 +26,24 @@ Instructions for running the CafeDemo sample
-------------------------------------------------------------------------------
1. The example comes with two identical configurations. One is ANNOTATION-based anther is XML-based
2. To run this sample simply execute the CafeDemo* test classes
2. To run this sample simply execute the CafeDemoApp test classes
in the org.springframework.integration.samples.cafe.xml or
org.springframework.integration.samples.cafe.annotation package.
3. The example also provides an alternative configuration that uses AMQP channels to distribute the components
in the CafeDemo sample. To run this alternative configuration of the sample, be sure to have a RabbitMQ broker
started on localhost:5672 configured with the default guest | guest client credentials on the / vHost,
then execute the following test classes in order:
You shoudl see the output similar to this:
1. cafeDemoAppBaristaColdAmqp - starts the Cold Drink Barista
2. cafeDemoAppBaristaHotAmqp- starts the Hot Drink Barista
3. cafeDemoAppAmqp - starts the Cafe Storefront (Places 100 orders on the orders queue)
4. cafeDemoAppOperationsAmqp - starts the Cafe Operations (OrderSplitter, DrinkRouter, PreparedDrinkAggregator)
* Note: All AMQP exchanges, queues, and bindings needed for this sample are defined within the different xml
config files that support the above test classes.
Upon running any of the alternatives, you should see the output similar to this:
INFO : org.springframework.integration.samples.cafe.annotation.Barista - task-scheduler-1 prepared cold drink #1 for order #1: iced 3 shot MOCHA
INFO : org.springframework.integration.samples.cafe.annotation.Barista - task-scheduler-1 prepared cold drink #2 for order #2: iced 3 shot MOCHA

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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,16 +20,18 @@ import java.util.List;
/**
* @author Marius Bogoevici
* @author Tom McCuch
*/
public class Delivery {
private static final String SEPARATOR = "-----------------------";
private List<Drink> deliveredDrinks;
private int orderNumber;
// Default constructor required by Jackson Java JSON-processor
public Delivery() {}
public Delivery(List<Drink> deliveredDrinks) {
assert(deliveredDrinks.size() > 0);
@@ -42,10 +44,18 @@ public class Delivery {
return orderNumber;
}
public void setOrderNumber(int orderNumber) {
this.orderNumber = orderNumber;
}
public List<Drink> getDeliveredDrinks() {
return deliveredDrinks;
}
public void setDeliveredDrinks(List<Drink> deliveredDrinks) {
this.deliveredDrinks = deliveredDrinks;
}
@Override
public String toString() {
StringBuffer buffer = new StringBuffer(SEPARATOR + "\n");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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,6 +18,7 @@ package org.springframework.integration.samples.cafe;
/**
* @author Marius Bogoevici
* @author Tom McCuch
*/
public class Drink {
@@ -30,10 +31,13 @@ public class Drink {
private int orderNumber;
public Drink(int orderNumber, DrinkType drinkType, boolean hot, int shots) {
// Default constructor required by Jackson Java JSON-processor
public Drink() {}
public Drink(int orderNumber, DrinkType drinkType, boolean iced, int shots) {
this.orderNumber = orderNumber;
this.drinkType = drinkType;
this.iced = hot;
this.iced = iced;
this.shots = shots;
}
@@ -42,6 +46,34 @@ public class Drink {
return orderNumber;
}
public void setOrderNumber(int orderNumber) {
this.orderNumber = orderNumber;
}
public boolean isIced() {
return this.iced;
}
public void setIced(boolean iced) {
this.iced = iced;
}
public DrinkType getDrinkType() {
return this.drinkType;
}
public void setDrinkType(DrinkType drinkType) {
this.drinkType = drinkType;
}
public int getShots() {
return this.shots;
}
public void setShots(int shots) {
this.shots = shots;
}
@Override
public String toString() {
return (iced?"Iced":"Hot") + " " + drinkType.toString() + ", " + shots + " shots.";

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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,27 +22,39 @@ import java.util.List;
/**
* @author Mark Fisher
* @author Marius Bogoevici
* @author Tom McCuch
*/
public class Order {
private List<OrderItem> orderItems = new ArrayList<OrderItem>();
/** the order number used for tracking */
private int number;
// Default constructor required by Jackson Java JSON-processor
public Order() {}
public Order(int number) {
this.number = number;
}
public void addItem(DrinkType drinkType, int shots, boolean iced) {
this.orderItems.add(new OrderItem(this, drinkType, shots, iced));
this.orderItems.add(new OrderItem(this.number, drinkType, shots, iced));
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public List<OrderItem> getItems() {
return this.orderItems;
}
public void setItems(List<OrderItem> orderItems) {
this.orderItems = orderItems;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -19,6 +19,7 @@ package org.springframework.integration.samples.cafe;
/**
* @author Mark Fisher
* @author Marius Bogoevici
* @author Tom McCuch
*/
public class OrderItem {
@@ -28,34 +29,52 @@ public class OrderItem {
private boolean iced = false;
private final Order order;
/** the order this item is tied to */
private int orderNumber;
// Default constructor required by Jackson Java JSON-processor
public OrderItem() {}
public OrderItem(Order order, DrinkType type, int shots, boolean iced) {
this.order = order;
public OrderItem(int orderNumber, DrinkType type, int shots, boolean iced) {
this.orderNumber = orderNumber;
this.type = type;
this.shots = shots;
this.iced = iced;
}
public Order getOrder() {
return this.order;
public int getOrderNumber() {
return this.orderNumber;
}
public void setOrderNumber(int orderNumber) {
this.orderNumber = orderNumber;
}
public boolean isIced() {
return this.iced;
}
public int getShots() {
public void setIced(boolean iced) {
this.iced = iced;
}
public int getShots() {
return shots;
}
public DrinkType getDrinkType() {
public void setShots(int shots) {
this.shots = shots;
}
public DrinkType getDrinkType() {
return this.type;
}
public String toString() {
public void setDrinkType(DrinkType type) {
this.type = type;
}
public String toString() {
return ((this.iced) ? "iced " : "hot ") + this.shots + " shot " + this.type;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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.
@@ -27,7 +27,9 @@ import org.springframework.stereotype.Component;
/**
* @author Mark Fisher
* @author Marius Bogoevici
* @author Tom McCuch
*/
@Component
public class Barista {
private static Logger logger = Logger.getLogger(Barista.class);
@@ -54,8 +56,8 @@ public class Barista {
Thread.sleep(this.hotDrinkDelay);
logger.info(Thread.currentThread().getName()
+ " prepared hot drink #" + hotDrinkCounter.incrementAndGet() + " for order #"
+ orderItem.getOrder().getNumber() + ": " + orderItem);
return new Drink(orderItem.getOrder().getNumber(), orderItem.getDrinkType(), orderItem.isIced(),
+ orderItem.getOrderNumber() + ": " + orderItem);
return new Drink(orderItem.getOrderNumber(), orderItem.getDrinkType(), orderItem.isIced(),
orderItem.getShots());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
@@ -69,8 +71,8 @@ public class Barista {
Thread.sleep(this.coldDrinkDelay);
logger.info(Thread.currentThread().getName()
+ " prepared cold drink #" + coldDrinkCounter.incrementAndGet() + " for order #"
+ orderItem.getOrder().getNumber() + ": " + orderItem);
return new Drink(orderItem.getOrder().getNumber(), orderItem.getDrinkType(), orderItem.isIced(),
+ orderItem.getOrderNumber() + ": " + orderItem);
return new Drink(orderItem.getOrderNumber(), orderItem.getDrinkType(), orderItem.isIced(),
orderItem.getShots());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2011 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,9 @@ import org.springframework.integration.samples.cafe.OrderItem;
/**
* @author Mark Fisher
* @author Marius Bogoevici
* @author Tom McCuch
*/
public class Barista {
private static Logger logger = Logger.getLogger(Barista.class);
private long hotDrinkDelay = 5000;
@@ -50,8 +52,8 @@ public class Barista {
Thread.sleep(this.hotDrinkDelay);
logger.info(Thread.currentThread().getName()
+ " prepared hot drink #" + hotDrinkCounter.incrementAndGet() + " for order #"
+ orderItem.getOrder().getNumber() + ": " + orderItem);
return new Drink(orderItem.getOrder().getNumber(), orderItem.getDrinkType(), orderItem.isIced(),
+ orderItem.getOrderNumber() + ": " + orderItem);
return new Drink(orderItem.getOrderNumber(), orderItem.getDrinkType(), orderItem.isIced(),
orderItem.getShots());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
@@ -64,8 +66,8 @@ public class Barista {
Thread.sleep(this.coldDrinkDelay);
logger.info(Thread.currentThread().getName()
+ " prepared cold drink #" + coldDrinkCounter.incrementAndGet() + " for order #"
+ orderItem.getOrder().getNumber() + ": " + orderItem);
return new Drink(orderItem.getOrder().getNumber(), orderItem.getDrinkType(), orderItem.isIced(),
+ orderItem.getOrderNumber() + ": " + orderItem);
return new Drink(orderItem.getOrderNumber(), orderItem.getDrinkType(), orderItem.isIced(),
orderItem.getShots());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2002-2011 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.cafe.xml;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.samples.cafe.Cafe;
import org.springframework.integration.samples.cafe.DrinkType;
import org.springframework.integration.samples.cafe.Order;
/**
* Provides the 'main' method for running the Cafe Demo store front
* application using AMQP. Before running, be sure to have a
* RabbitMQ broker started on localhost:5672 configured with the default
* guest | guest client credentials on the / vHost. When an order is
* placed, the Cafe store front will publish that order on the cafe-orders
* exchange to be processed.
* <p/>
* The relevant components are defined within the configuration files:
* ("cafeDemo-amqp-xml.xml", "cafeDemo-amqp-config-xml.xml").
* <p/>
* If deploying in SpringSource dmServer, the relevant ApplicationContext
* configuration is in the META-INF/spring directory instead.
*
* @author Tom McCuch
*/
public class CafeDemoAppAmqp {
/**
* place some orders
* @param context spring context
* @param count the number of standard orders
*/
public static void order(AbstractApplicationContext context, int count){
Cafe cafe = (Cafe) context.getBean("cafe");
for (int i = 1; i <= 100; i++) {
Order order = new Order(i);
order.addItem(DrinkType.LATTE, 2, false);
order.addItem(DrinkType.MOCHA, 3, true);
cafe.placeOrder(order);
}
}
public static void main(String[] args) {
AbstractApplicationContext context =
CafeDemoAppUtilities.loadProfileContext(
"/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml",
CafeDemoAppAmqp.class,CafeDemoAppUtilities.DEV);
order(context, 100);
context.close();
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright 2002-2011 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.cafe.xml;
import java.io.IOException;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.samples.cafe.Cafe;
import org.springframework.integration.samples.cafe.DrinkType;
import org.springframework.integration.samples.cafe.Order;
/**
* Provides the 'main' method for running the Cafe Demo Cold Drink
* Barista application using AMQP. Before running, be sure to have a
* RabbitMQ broker started on localhost:5672 configured with the default
* guest | guest client credentials on the / vHost. When a drink order
* is placed on the cold-drinks queue, the Barista will prepare the drink
* and reply to the reply-to queue set by the sender.
* <p/>
* The relevant components are defined within the configuration files:
* ("cafeDemo-amqp-baristaCold-xml.xml", "cafeDemo-amqp-config-xml.xml").
* <p/>
* If deploying in SpringSource dmServer, the relevant ApplicationContext
* configuration is in the META-INF/spring directory instead.
*
* @author Tom McCuch
*/
public class CafeDemoAppBaristaColdAmqp {
public static void main(String[] args) {
AbstractApplicationContext context =
CafeDemoAppUtilities.loadProfileContext(
"/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml",
CafeDemoAppBaristaColdAmqp.class,CafeDemoAppUtilities.DEV);
System.out.println("Press Enter/Return in the console to exit the Barista Cold App");
try {
System.in.read();
} catch (IOException e) {
context.close();
}
context.close();
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright 2002-2011 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.cafe.xml;
import java.io.IOException;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.samples.cafe.Cafe;
import org.springframework.integration.samples.cafe.DrinkType;
import org.springframework.integration.samples.cafe.Order;
/**
* Provides the 'main' method for running the Cafe Demo Hot Drink
* Barista application using AMQP. Before running, be sure to have a
* RabbitMQ broker started on localhost:5672 configured with the default
* guest | guest client credentials on the / vHost. When a drink order
* is placed on the hot-drinks queue, the Barista will prepare the drink
* and reply to the reply-to queue set by the sender.
* <p/>
* The relevant components are defined within the configuration files:
* ("cafeDemo-amqp-baristaHot-xml.xml", "cafeDemo-amqp-config-xml.xml").
* <p/>
* If deploying in SpringSource dmServer, the relevant ApplicationContext
* configuration is in the META-INF/spring directory instead.
*
* @author Tom McCuch
*/
public class CafeDemoAppBaristaHotAmqp {
public static void main(String[] args) {
AbstractApplicationContext context =
CafeDemoAppUtilities.loadProfileContext(
"/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaHot-xml.xml",
CafeDemoAppBaristaHotAmqp.class,CafeDemoAppUtilities.DEV);
System.out.println("Press Enter/Return in the console to exit the Barista Hot App");
try {
System.in.read();
} catch (IOException e) {
context.close();
}
context.close();
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2002-2011 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.cafe.xml;
import java.io.IOException;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.samples.cafe.Cafe;
import org.springframework.integration.samples.cafe.DrinkType;
import org.springframework.integration.samples.cafe.Order;
/**
* Provides the 'main' method for running the Cafe Demo Operations
* application using AMQP. Before running, be sure to have a RabbitMQ
* broker started on localhost:5672 configured with the default
* guest | guest client credentials on the / vHost. When an order is
* placed on the new-orders queue, the Cafe Operations app will split
* the order into order line items, route them to either the coldDrink
* or hotDrink Barista, aggregate the prepared drinks returned from the
* Barista using a Waiter, and publish the delivered order on the
* cafe-deliveries exchange.
* <p/>
* The relevant components are defined within the configuration files:
* ("cafeDemo-amqp-operations-xml.xml", "cafeDemo-amqp-config-xml.xml").
* <p/>
* Before starting this app, be sure to start the CafeDemoAppBaristaCold
* and CafeDemoAppBaristaHot apps first.
*
* If deploying in SpringSource dmServer, the relevant ApplicationContext
* configuration is in the META-INF/spring directory instead.
*
* @author Tom McCuch
*/
public class CafeDemoAppOperationsAmqp {
public static void main(String[] args) {
AbstractApplicationContext context =
CafeDemoAppUtilities.loadProfileContext(
"/META-INF/spring/integration/amqp/cafeDemo-amqp-operations-xml.xml",
CafeDemoAppOperationsAmqp.class,CafeDemoAppUtilities.DEV);
System.out.println("Press Enter/Return in the console to exit the Cafe Operations App");
try {
System.in.read();
} catch (IOException e) {
context.close();
}
context.close();
}
}

View File

@@ -0,0 +1,36 @@
package org.springframework.integration.samples.cafe.xml;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.integration.samples.cafe.Cafe;
import org.springframework.integration.samples.cafe.DrinkType;
import org.springframework.integration.samples.cafe.Order;
public class CafeDemoAppUtilities {
/** spring profile for running locally */
public static final String DEV = "dev";
/** spring profile for running in cloud foundry */
public static final String CLOUD = "cloud";
/**
*
* @param path path to the file
* @param targetClass the class who's classloader we will use to laod the context file
* @param profile a profile name
* @return the spring context
*/
public static AbstractApplicationContext loadProfileContext(String path, Class targetClass, String profile) {
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
ctx.getEnvironment().setActiveProfiles(profile);
ctx.setClassLoader(targetClass.getClassLoader());
ctx.load(path);
ctx.refresh();
return ctx;
}
}

View File

@@ -0,0 +1,52 @@
<?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-amqp="http://www.springframework.org/schema/integration/amqp"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xmlns:stream="http://www.springframework.org/schema/integration/stream"
xmlns:cloud="http://schema.cloudfoundry.org/spring"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://schema.cloudfoundry.org/spring
http://schema.cloudfoundry.org/spring/cloudfoundry-spring-0.8.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
http://www.springframework.org/schema/integration/amqp
http://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd
http://www.springframework.org/schema/rabbit
http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd
http://www.springframework.org/schema/integration/stream
http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd">
<!-- rabbit connection factory, rabbit template, and rabbit admin -->
<import resource="classpath:META-INF/spring/integration/amqp/cafeDemo-amqp-config-xml.xml" />
<!-- To receive an AMQP Message from a Queue, and respond to its reply-to address, configure an inbound-gateway. -->
<int-amqp:inbound-gateway
id="coldDrinksBarista"
request-channel="coldJsonDrinks"
queue-names="cold-drinks"
connection-factory="rabbitConnectionFactory" />
<int:chain input-channel="coldJsonDrinks">
<int:json-to-object-transformer type="org.springframework.integration.samples.cafe.OrderItem"/>
<int:service-activator method="prepareColdDrink">
<bean class="org.springframework.integration.samples.cafe.xml.Barista"/>
</int:service-activator>
<int:object-to-json-transformer />
</int:chain>
<!-- rabbit exchanges, queues, and bindings used by this app -->
<rabbit:topic-exchange name="cafe-drinks" auto-delete="true" durable="true">
<rabbit:bindings>
<rabbit:binding queue="cold-drinks" pattern="drink.cold"/>
<rabbit:binding queue="all-cold-drinks" pattern="drink.cold"/>
</rabbit:bindings>
</rabbit:topic-exchange>
<rabbit:queue name="cold-drinks" auto-delete="true" durable="true"/>
<rabbit:queue name="all-cold-drinks" auto-delete="true" durable="true"/>
</beans>

View File

@@ -0,0 +1,52 @@
<?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-amqp="http://www.springframework.org/schema/integration/amqp"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xmlns:stream="http://www.springframework.org/schema/integration/stream"
xmlns:cloud="http://schema.cloudfoundry.org/spring"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://schema.cloudfoundry.org/spring
http://schema.cloudfoundry.org/spring/cloudfoundry-spring-0.8.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
http://www.springframework.org/schema/integration/amqp
http://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd
http://www.springframework.org/schema/rabbit
http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd
http://www.springframework.org/schema/integration/stream
http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd">
<!-- rabbit connection factory, rabbit template, and rabbit admin -->
<import resource="classpath:META-INF/spring/integration/amqp/cafeDemo-amqp-config-xml.xml" />
<!-- To receive an AMQP Message from a Queue, and respond to its reply-to address, configure an inbound-gateway. -->
<int-amqp:inbound-gateway
id="hotDrinksBarista"
request-channel="hotJsonDrinks"
queue-names="hot-drinks"
connection-factory="rabbitConnectionFactory" />
<int:chain input-channel="hotJsonDrinks">
<int:json-to-object-transformer type="org.springframework.integration.samples.cafe.OrderItem"/>
<int:service-activator method="prepareHotDrink">
<bean class="org.springframework.integration.samples.cafe.xml.Barista"/>
</int:service-activator>
<int:object-to-json-transformer />
</int:chain>
<!-- rabbit exchanges, queues, and bindings used by this app -->
<rabbit:topic-exchange name="cafe-drinks" auto-delete="true" durable="true">
<rabbit:bindings>
<rabbit:binding queue="hot-drinks" pattern="drink.hot"/>
<rabbit:binding queue="all-hot-drinks" pattern="drink.hot"/>
</rabbit:bindings>
</rabbit:topic-exchange>
<rabbit:queue name="hot-drinks" auto-delete="true" durable="true"/>
<rabbit:queue name="all-hot-drinks" auto-delete="true" durable="true"/>
</beans>

View File

@@ -0,0 +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:rabbit="http://www.springframework.org/schema/rabbit"
xmlns:cloud="http://schema.cloudfoundry.org/spring"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://schema.cloudfoundry.org/spring
http://schema.cloudfoundry.org/spring/cloudfoundry-spring-0.8.xsd
http://www.springframework.org/schema/rabbit
http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd">
<!-- Set up the AmqpTemplate/RabbitTemplate: -->
<rabbit:template id="amqpTemplate"
connection-factory="rabbitConnectionFactory" reply-timeout="10000" />
<!-- Request that queues, exchanges and bindings be automatically declared
on the broker: -->
<rabbit:admin connection-factory="rabbitConnectionFactory" />
<!-- profiles must be the last element sin the file -->
<!-- Obtain a connection to the RabbitMQ via cloudfoundry-runtime: -->
<beans profile="cloud">
<cloud:rabbit-connection-factory
id="rabbitConnectionFactory" />
</beans>
<!-- connect to the local broker using the default user name and password -->
<beans profile="dev">
<bean id="rabbitConnectionFactory"
class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
<constructor-arg value="localhost" />
<property name="username" value="guest" />
<property name="password" value="guest" />
</bean>
</beans>
</beans>

View File

@@ -0,0 +1,118 @@
<?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-amqp="http://www.springframework.org/schema/integration/amqp"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xmlns:stream="http://www.springframework.org/schema/integration/stream"
xmlns:cloud="http://schema.cloudfoundry.org/spring"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://schema.cloudfoundry.org/spring
http://schema.cloudfoundry.org/spring/cloudfoundry-spring-0.8.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
http://www.springframework.org/schema/integration/amqp
http://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd
http://www.springframework.org/schema/rabbit
http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd
http://www.springframework.org/schema/integration/stream
http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd">
<!-- rabbit connection factory, rabbit template, and rabbit admin -->
<import resource="classpath:META-INF/spring/integration/amqp/cafeDemo-amqp-config-xml.xml" />
<!-- intercept messages on these channels while still allowing them to continue -->
<int:wire-tap channel="logger" pattern="orders,coldDrinks,hotDrinks,preparedDrinks,deliveries"/>
<int:logging-channel-adapter id="logger" log-full-message="true" level="INFO"/>
<!-- To receive AMQP Messages from a Queue, configure an inbound-channel-adapter -->
<int-amqp:inbound-channel-adapter queue-names="new-orders" channel="jsonOrders" connection-factory="rabbitConnectionFactory" acknowledge-mode="AUTO" />
<int:json-to-object-transformer id="json-to-order" input-channel="jsonOrders" output-channel="preOrders" type="org.springframework.integration.samples.cafe.Order" />
<int:splitter input-channel="preOrders" expression="payload.items" output-channel="preDrinks" apply-sequence="true"/>
<int:header-enricher input-channel="preDrinks" output-channel="drinks">
<int:header name="ICED" expression="payload.isIced()"/>
</int:header-enricher>
<int:object-to-json-transformer id="drink-to-json" input-channel="drinks" output-channel="jsonDrinks" />
<int:router input-channel="jsonDrinks" expression="headers.ICED ? 'coldDrinks' : 'hotDrinks'"/>
<int:channel id="coldDrinks">
<int:queue/>
</int:channel>
<!-- Default poller -->
<int:poller default="true" fixed-rate="100"/>
<int:channel id="hotDrinks">
<int:queue/>
</int:channel>
<!-- To send AMQP Messages to an Exchange and receive back a response from a remote client, configure an outbound-gateway -->
<int-amqp:outbound-gateway
id="coldDrinksBarista"
request-channel="coldDrinks"
reply-channel="preparedJsonDrinks"
exchange-name="cafe-drinks"
routing-key="drink.cold"
amqp-template="amqpTemplate" />
<!-- To send AMQP Messages to an Exchange and receive back a response from a remote client, configure an outbound-gateway -->
<int-amqp:outbound-gateway
id="hotDrinksBarista"
request-channel="hotDrinks"
reply-channel="preparedJsonDrinks"
exchange-name="cafe-drinks"
routing-key="drink.hot"
amqp-template="amqpTemplate" />
<int:channel id="preparedJsonDrinks"/>
<int:json-to-object-transformer id="json-to-drink" input-channel="preparedJsonDrinks" output-channel="preparedDrinks" type="org.springframework.integration.samples.cafe.Drink"/>
<int:aggregator input-channel="preparedDrinks" method="prepareDelivery" output-channel="preDeliveries">
<bean class="org.springframework.integration.samples.cafe.xml.Waiter"/>
</int:aggregator>
<int:channel id="preDeliveries" />
<int:header-enricher input-channel="preDeliveries" output-channel="deliveries">
<int:header name="NUMBER" expression="payload.getOrderNumber()" />
</int:header-enricher>
<int:object-to-json-transformer id="delivery-to-json" input-channel="deliveries" output-channel="jsonDeliveries"/>
<int:channel id="jsonDeliveries" />
<!-- To send AMQP Messages to an Exchange, configure an outbound-channel-adapter. -->
<int-amqp:outbound-channel-adapter
id="deliveredOrders"
channel="jsonDeliveries"
amqp-template="amqpTemplate"
exchange-name="cafe-deliveries"
routing-key-expression="'delivery.'+headers.NUMBER" />
<bean id="waiter" class="org.springframework.integration.samples.cafe.xml.Waiter"/>
<!-- rabbit exchanges, queues, and bindings used by this app -->
<rabbit:topic-exchange name="cafe-drinks" auto-delete="true" durable="true">
<rabbit:bindings>
<rabbit:binding queue="all-drinks" pattern="drink.*"/>
</rabbit:bindings>
</rabbit:topic-exchange>
<rabbit:queue name="all-drinks" auto-delete="true" durable="true"/>
<rabbit:fanout-exchange name="cafe-deliveries" auto-delete="false" durable="true">
<rabbit:bindings>
<rabbit:binding queue="all-deliveries" />
</rabbit:bindings>
</rabbit:fanout-exchange>
<rabbit:queue name="all-deliveries" auto-delete="false" durable="true"/>
</beans>

View File

@@ -0,0 +1,56 @@
<?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-amqp="http://www.springframework.org/schema/integration/amqp"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xmlns:stream="http://www.springframework.org/schema/integration/stream"
xmlns:cloud="http://schema.cloudfoundry.org/spring"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://schema.cloudfoundry.org/spring
http://schema.cloudfoundry.org/spring/cloudfoundry-spring-0.8.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
http://www.springframework.org/schema/integration/amqp
http://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd
http://www.springframework.org/schema/rabbit
http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd
http://www.springframework.org/schema/integration/stream
http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd">
<!-- rabbit connection factory, rabbit template, and rabbit admin -->
<import resource="classpath:META-INF/spring/integration/amqp/cafeDemo-amqp-config-xml.xml" />
<!-- spring integration flow -->
<int:gateway id="cafe" service-interface="org.springframework.integration.samples.cafe.Cafe" />
<int:channel id="orders"/>
<int:header-enricher input-channel="orders" output-channel="newOrders">
<int:header name="NUMBER" expression="payload.getNumber()"/>
</int:header-enricher>
<int:object-to-json-transformer input-channel="newOrders" output-channel="jsonNewOrders" />
<int:channel id="jsonNewOrders" />
<!-- To send AMQP Messages to an Exchange, configure an outbound-channel-adapter. -->
<int-amqp:outbound-channel-adapter
channel="jsonNewOrders"
exchange-name="cafe-orders"
routing-key-expression="'order.'+headers.NUMBER"
amqp-template="amqpTemplate" />
<!-- rabbit exchanges, queues, and bindings used by this app -->
<rabbit:topic-exchange name="cafe-orders" auto-delete="false" durable="true">
<rabbit:bindings>
<rabbit:binding queue="new-orders" pattern="order.*"/>
<rabbit:binding queue="all-orders" pattern="order.*"/>
</rabbit:bindings>
</rabbit:topic-exchange>
<rabbit:queue name="new-orders" auto-delete="false" durable="true"/>
<rabbit:queue name="all-orders" auto-delete="false" durable="true"/>
</beans>

View File

@@ -12,22 +12,27 @@
<gateway id="cafe" service-interface="org.springframework.integration.samples.cafe.Cafe"/>
<!-- each order has a collection of order items that is split apart to be processed -->
<channel id="orders"/>
<splitter input-channel="orders" expression="payload.items" output-channel="drinks"/>
<!-- The router sends different drink orders on different paths -->
<channel id="drinks"/>
<router input-channel="drinks" expression="payload.iced ? 'coldDrinks' : 'hotDrinks'"/>
<!-- individual order items are processed by the barista -->
<channel id="coldDrinks">
<queue capacity="10"/>
</channel>
<service-activator input-channel="coldDrinks" ref="barista" method="prepareColdDrink" output-channel="preparedDrinks"/>
<!-- individual order items are processed by the barista -->
<channel id="hotDrinks">
<queue capacity="10"/>
</channel>
<service-activator input-channel="hotDrinks" ref="barista" method="prepareHotDrink" output-channel="preparedDrinks"/>
<!-- drink order items are aggregated in a call to the waiter -->
<channel id="preparedDrinks"/>
<aggregator input-channel="preparedDrinks" method="prepareDelivery" output-channel="deliveries">
<beans:bean class="org.springframework.integration.samples.cafe.xml.Waiter"/>

View File

@@ -6,7 +6,7 @@
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p: %c - %m%n" />
<param name="ConversionPattern" value="%t %-5p: %c - %m%n" />
</layout>
</appender>
@@ -15,6 +15,14 @@
<level value="warn" />
</logger>
<logger name="org.springframework.amqp">
<level value="info" />
</logger>
<logger name="org.springframework.integration">
<level value="info" />
</logger>
<logger name="org.springframework.integration.samples">
<level value="debug" />
</logger>

36
basic/enricher/README.md Normal file
View File

@@ -0,0 +1,36 @@
Spring Integration - Enricher Sample
================================
# Overview
This sample demonstrates how the Enricher components can be used.
# Getting Started
You can run the sample application by either
* running the "Main" class from within STS (Right-click on Main class --> Run As --> Java Application)
* or from the command line execute:
- mvn package
- mvn exec:java
This example illustrates the usage of the Content Enricher.
Once the application has started, lease execute the various Content Enricher examples by
* entering 1 + Enter
* entering 2 + Enter
* entering 3 + Enter
3 different message flows are triggered. For use-cases 1+2 a **User** object containing only the **username** is passed in. For use-case 3 a Map with the **username** key is passed in and enriched with the **User** object using the **user** key:
* 1: In the *Enricher*, pass the full **User** object to the **request channel**.
* 2: In the *Enricher*, pass only the **username** to the **request channel** by using the **request-payload-expression** attribute.
* 3: In the *Enricher*, pass only the username to the **request channel**, executing the same Service Activator as in **2**.
# Resources
For help please take a look at the Spring Integration documentation:
http://www.springsource.org/spring-integration

123
basic/enricher/pom.xml Normal file
View File

@@ -0,0 +1,123 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.integration.samples</groupId>
<artifactId>enricher</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>enricher-sample</name>
<url>http://www.springsource.org/spring-integration</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.integration.version>2.1.0.BUILD-SNAPSHOT</spring.integration.version>
<slf4j.version>1.6.1</slf4j.version>
<junit.version>4.7</junit.version>
</properties>
<repositories>
<repository>
<id>repository.springframework.maven.release</id>
<name>Spring Framework Maven Release Repository</name>
<url>http://maven.springframework.org/release</url>
</repository>
<repository>
<id>repository.springframework.maven.milestone</id>
<name>Spring Framework Maven Milestone Repository</name>
<url>http://maven.springframework.org/milestone</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.8</version>
<configuration>
<additionalProjectnatures>
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
</additionalBuildcommands>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2</version>
<configuration>
<mainClass>org.springframework.integration.samples.enricher.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- Testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- Spring Integration -->
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>0.9.28</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- Embedded Database -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.3.160</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,142 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.samples.enricher;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.samples.enricher.service.UserService;
/**
* Starts the Spring Context and will initialize the Spring Integration routes.
*
* @author Gunnar Hillert
* @version 1.0
*
*/
public final class Main {
private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
private static final String LINE_SEPARATOR = "\n==========================================================================";
private static final String EMPTY_LINE = "\n ";
private Main() { }
/**
* Load the Spring Integration Application Context
*
* @param args - command line arguments
*/
public static void main(final String... args) {
LOGGER.info(LINE_SEPARATOR
+ EMPTY_LINE
+ "\n Welcome to Spring Integration! "
+ EMPTY_LINE
+ "\n For more information please visit: "
+ "\n http://www.springsource.org/spring-integration "
+ EMPTY_LINE
+ LINE_SEPARATOR );
final AbstractApplicationContext context =
new ClassPathXmlApplicationContext("classpath:META-INF/spring/integration/*-context.xml");
context.registerShutdownHook();
final Scanner scanner = new Scanner(System.in);
final UserService service = context.getBean(UserService.class);
LOGGER.info(LINE_SEPARATOR
+ EMPTY_LINE
+ "\n Please press 'q + Enter' to quit the application. "
+ EMPTY_LINE
+ LINE_SEPARATOR
+ EMPTY_LINE
+ "\n This example illustrates the usage of the Content Enricher. "
+ EMPTY_LINE
+ "\n Usage: Please enter 1 or 2 or 3 + Enter "
+ EMPTY_LINE
+ "\n 3 different message flows are triggered. For sample 1+2 a "
+ "\n user object containing only the username is passed in. "
+ "\n For sample 3 a Map with the 'username' key is passed in and enriched "
+ "\n with the user object using the 'user' key. "
+ EMPTY_LINE
+ "\n 1: In the Enricher, pass the full User object to the request channel. "
+ "\n 2: In the Enricher, pass only the username to the request channel. "
+ "\n 3: In the Enricher, pass only the username to the request channel. "
+ EMPTY_LINE
+ LINE_SEPARATOR);
while (!scanner.hasNext("q")) {
final String input = scanner.nextLine();
User user = new User("foo", null, null);
if ("1".equals(input)) {
final User fullUser = service.findUser(user);
printUserInformation(fullUser);
} else if ("2".equals(input)) {
final User fullUser = service.findUserByUsername(user);
printUserInformation(fullUser);
} else if ("3".equals(input)) {
final Map<String, Object> userData = new HashMap<String, Object>();
userData.put("username", "foo_map");
final Map<String, Object> enrichedUserData = service.findUserWithUsernameInMap(userData);
final User fullUser = (User) enrichedUserData.get("user");
printUserInformation(fullUser);
} else {
LOGGER.info("\n\n Please enter '1' or '2' <enter>:\n\n");
}
}
LOGGER.info("\n\nExiting application...bye.");
System.exit(0);
}
private static void printUserInformation(User user) {
if (user != null) {
LOGGER.info("\n\n User found - Username: '{}', Email: '{}', Password: '{}'.\n\n",
new Object[] {user.getUsername(), user.getEmail(), user.getPassword()});
} else {
LOGGER.info("\n\n No User found for username: 'foo'.\n\n");
}
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright 2002-2011 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.enricher;
public class User {
private String username;
private String password;
private String email;
public User(String username, String password, String email) {
super();
this.username = username;
this.password = password;
this.email = email;
}
public String getUsername() {
return this.username;
}
public String getPassword() {
return this.password;
}
public String getEmail() {
return this.email;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("User [username=")
.append(this.username)
.append(", password=")
.append(this.password)
.append(", email=")
.append(this.email).append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2002-2011 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.enricher.service;
import java.util.Map;
import org.springframework.integration.samples.enricher.User;
/**
* Provides user services.
*/
public interface UserService {
/**
* Retrieves a user based on the provided user. User object is routed to the
* "findUserEnricherChannel" channel.
*/
User findUser(User user);
/**
* Retrieves a user based on the provided user. User object is routed to the
* "findUserByUsernameEnricherChannel" channel.
*/
User findUserByUsername(User user);
/**
* Retrieves a user based on the provided username that is provided as a Map
* entry using the mapkey 'username'. Map object is routed to the
* "findUserWithMapChannel" channel.
*/
Map<String, Object> findUserWithUsernameInMap(Map<String, Object> userdata);
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright 2002-2011 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.enricher.service.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.integration.samples.enricher.User;
/**
* Simple Service class for retrieving user information.
*
* @author Gunnar Hillert
*
*/
public class SystemService {
private static final Logger LOGGER = LoggerFactory.getLogger(SystemService.class);
/** Default Constructor. */
public SystemService() {
super();
}
public User findUser(User user) {
LOGGER.info("Calling method 'findUser' with parameter {}", user);
final User fullUser = new User(user.getUsername(),
"secret",
user.getUsername() + "@springintegration.org");
return fullUser;
}
public User findUserByUsername(String username) {
LOGGER.info("Calling method 'findUserByUsername' with parameter: {}", username);
return new User(username, "secret", username + "@springintegration.org");
}
}

View File

@@ -0,0 +1,59 @@
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<int:channel id="findUserEnricherChannel"/>
<int:channel id="findUserByUsernameEnricherChannel"/>
<int:channel id="findUserWithMapEnricherChannel"/>
<int:channel id="findUserServiceChannel"/>
<int:channel id="findUserByUsernameServiceChannel"/>
<!-- See also:
http://static.springsource.org/spring-integration/reference/htmlsingle/#gateway-proxy
http://www.eaipatterns.com/MessagingGateway.html -->
<int:gateway id="userGateway" default-request-timeout="5000"
default-reply-timeout="5000"
service-interface="org.springframework.integration.samples.enricher.service.UserService">
<int:method name="findUser" request-channel="findUserEnricherChannel"/>
<int:method name="findUserByUsername" request-channel="findUserByUsernameEnricherChannel"/>
<int:method name="findUserWithUsernameInMap" request-channel="findUserWithMapEnricherChannel"/>
</int:gateway>
<int:enricher id="findUserEnricher"
input-channel="findUserEnricherChannel"
request-channel="findUserServiceChannel">
<int:property name="email" expression="payload.email"/>
<int:property name="password" expression="payload.password"/>
</int:enricher>
<int:enricher id="findUserByUsernameEnricher"
input-channel="findUserByUsernameEnricherChannel"
request-channel="findUserByUsernameServiceChannel"
request-payload-expression="payload.username">
<int:property name="email" expression="payload.email"/>
<int:property name="password" expression="payload.password"/>
</int:enricher>
<int:enricher id="findUserWithMapEnricher"
input-channel="findUserWithMapEnricherChannel"
request-channel="findUserByUsernameServiceChannel"
request-payload-expression="payload.username">
<int:property name="user" expression="payload"/>
</int:enricher>
<int:service-activator id="findUserServiceActivator"
ref="systemService" method="findUser"
input-channel="findUserServiceChannel"/>
<int:service-activator id="findUserByUsernameServiceActivator"
ref="systemService" method="findUserByUsername"
input-channel="findUserByUsernameServiceChannel"/>
<bean id="systemService"
class="org.springframework.integration.samples.enricher.service.impl.SystemService"/>
</beans>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %5p | %t | %-55logger{55} | %m %n</pattern>
</encoder>
</appender>
<logger name="org.springframework.integration">
<level value="INFO" />
</logger>
<logger name="org.springframework">
<level value="INFO" />
</logger>
<root>
<level value="INFO" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>

View File

@@ -0,0 +1,77 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.samples.enricher.service;
import static junit.framework.Assert.*;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.samples.enricher.User;
import org.springframework.integration.samples.enricher.service.UserService;
/**
* Verify that the Spring Integration Application Context starts successfully.
*/
public class UserServiceTest {
@Test
public void testStartupOfSpringInegrationContext() throws Exception{
final ApplicationContext context
= new ClassPathXmlApplicationContext("/META-INF/spring/integration/spring-integration-context.xml",
UserServiceTest.class);
Thread.sleep(2000);
}
@Test
public void testExecuteFindUser() {
final ApplicationContext context
= new ClassPathXmlApplicationContext("/META-INF/spring/integration/spring-integration-context.xml",
UserServiceTest.class);
final UserService service = context.getBean(UserService.class);
User user = new User("foo", null, null);
final User fullUser = service.findUser(user);
assertEquals("foo", fullUser.getUsername());
assertEquals("foo@springintegration.org", fullUser.getEmail());
assertEquals("secret", fullUser.getPassword());
}
@Test
public void testExecuteFindUserByUsername() {
final ApplicationContext context
= new ClassPathXmlApplicationContext("/META-INF/spring/integration/spring-integration-context.xml",
UserServiceTest.class);
final UserService service = context.getBean(UserService.class);
User user = new User("foo", null, null);
final User fullUser = service.findUserByUsername(user);
assertEquals("foo", fullUser.getUsername());
assertEquals("foo@springintegration.org", fullUser.getEmail());
assertEquals("secret", fullUser.getPassword());
}
}

28
basic/jdbc/README.md Normal file
View File

@@ -0,0 +1,28 @@
Spring Integration - JDBC Sample
================================
# Overview
This sample provides example of how the Jdbc Adapters can be used.
# Getting Started
You can run the application by either
* running the "Main" class from within STS (Right-click on Main class --> Run As --> Java Application)
* or from the command line:
- mvn package
- mvn exec:java
Currently one example exists. On the command prompt you can enter the following valid values and get a response back:
* 'a'
* 'b'
* 'foo'
# Resources
For help please take a look at the Spring Integration documentation:
http://www.springsource.org/spring-integration

View File

@@ -1,83 +1,144 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.integration.samples</groupId>
<artifactId>jdbc</artifactId>
<version>2.0.0</version>
<name>Spring Integration JDBC Adapter test packages</name>
<packaging>jar</packaging>
<properties>
<spring.integration.version>2.0.5.RELEASE</spring.integration.version>
<spring.test.version>3.0.6.RELEASE</spring.test.version>
<log4j.version>1.2.16</log4j.version>
<junit.version>4.7</junit.version>
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.integration.samples</groupId>
<artifactId>jdbc</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>jdbc-sample</name>
<url>http://www.springsource.org/spring-integration</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.integration.version>2.1.0.M3</spring.integration.version>
<slf4j.version>1.6.1</slf4j.version>
<junit.version>4.7</junit.version>
<spring.test.version>3.0.6.RELEASE</spring.test.version>
<derbyclient.driver.version>10.8.2.2</derbyclient.driver.version>
</properties>
<dependencies>
<dependency>
</properties>
<repositories>
<repository>
<id>repository.springframework.maven.release</id>
<name>Spring Framework Maven Release Repository</name>
<url>http://maven.springframework.org/release</url>
</repository>
<repository>
<id>repository.springframework.maven.milestone</id>
<name>Spring Framework Maven Milestone Repository</name>
<url>http://maven.springframework.org/milestone</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.8</version>
<configuration>
<additionalProjectnatures>
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
</additionalBuildcommands>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2</version>
<configuration>
<mainClass>org.springframework.integration.samples.jdbc.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- Testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- Spring Integration -->
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-jdbc</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>0.9.28</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- Embedded Database -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.3.160</version>
</dependency>
<!-- Derby dependency -->
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbyclient</artifactId>
<version>${derbyclient.driver.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-jdbc</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<!-- Spring test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.test.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- test-scoped dependencies -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>false</showDeprecation>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>repository.springframework.maven.release</id>
<name>Spring Framework Maven Release Repository</name>
<url>http://maven.springframework.org/release</url>
</repository>
<repository>
<id>repository.springframework.maven.milestone</id>
<name>Spring Framework Maven Milestone Repository</name>
<url>http://maven.springframework.org/milestone</url>
</repository>
<repository>
<id>repository.springframework.maven.snapshot</id>
<name>Spring Framework Maven Snapshot Repository</name>
<url>http://maven.springframework.org/snapshot</url>
</repository>
</repositories>
</dependencies>
</project>

View File

@@ -0,0 +1,97 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.samples.jdbc;
import java.util.Scanner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.samples.jdbc.service.UserService;
/**
* Starts the Spring Context and will initialize the Spring Integration routes.
*
* @author Gunnar Hillert
* @version 1.0
*
*/
public final class Main {
private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
private Main() { }
/**
* Load the Spring Integration Application Context
*
* @param args - command line arguments
*/
public static void main(final String... args) {
LOGGER.info("\n========================================================="
+ "\n "
+ "\n Welcome to Spring Integration! "
+ "\n "
+ "\n For more information please visit: "
+ "\n http://www.springsource.org/spring-integration "
+ "\n "
+ "\n=========================================================" );
final AbstractApplicationContext context =
new ClassPathXmlApplicationContext("classpath:META-INF/spring/integration/*-context.xml");
context.registerShutdownHook();
final Scanner scanner = new Scanner(System.in);
final UserService service = context.getBean(UserService.class);
LOGGER.info("\n========================================================="
+ "\n "
+ "\n Please press 'q + Enter' to quit the application. "
+ "\n "
+ "\n=========================================================" );
System.out.print("Please enter a string and press <enter>: ");
while (!scanner.hasNext("q")) {
final String input = scanner.nextLine();
final User user = service.findUser(input);
if (user != null) {
System.out.println(
String.format("User found - Username: '%s', Email: '%s', Password: '%s'",
user.getUsername(), user.getEmail(), user.getPassword()));
} else {
System.out.println(
String.format("No User found for username: '%s'.", input));
}
System.out.print("Please enter a string and press <enter>:");
}
LOGGER.info("Exiting application...bye.");
System.exit(0);
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2002-2011 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.jdbc;
public class User {
private String username;
private String password;
private String email;
public User(String username, String password, String email) {
super();
this.username = username;
this.password = password;
this.email = email;
}
public String getUsername() {
return this.username;
}
public String getPassword() {
return this.password;
}
public String getEmail() {
return this.email;
}
}

View File

@@ -0,0 +1,24 @@
/*
* Copyright 2002-2011 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.jdbc;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
public class UserMapper implements RowMapper<User> {
public User mapRow(ResultSet rs, int rowNum) throws SQLException {
return new User(rs.getString("username"), rs.getString("password"), rs.getString("email"));
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2002-2011 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.jdbc.service;
import org.springframework.integration.samples.jdbc.User;
/**
* Provides user services.
*/
public interface UserService {
/**
* Retrieves a user based on the provided username.
*
* @param username Find users by username
* @return The user if exists, null otherwise.
*/
User findUser(String username);
}

View File

@@ -0,0 +1,38 @@
<?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-jdbc="http://www.springframework.org/schema/integration/jdbc"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc-2.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<int:channel id="requestChannel"/>
<int:channel id="replyChannel"/>
<jdbc:embedded-database id="datasource" type="H2">
<jdbc:script location="classpath:setup-tables.sql"/>
</jdbc:embedded-database>
<!-- See also:
http://static.springsource.org/spring-integration/reference/htmlsingle/#gateway-proxy
http://www.eaipatterns.com/MessagingGateway.html -->
<int:gateway default-request-timeout="5000"
default-reply-timeout="5000"
default-request-channel="requestChannel"
default-reply-channel="replyChannel"
service-interface="org.springframework.integration.samples.jdbc.service.UserService">
<int:method name="convertToUpperCase"/>
</int:gateway>
<int-jdbc:outbound-gateway data-source="datasource"
update="UPDATE DUMMY SET DUMMY_VALUE='test'"
request-channel="requestChannel" query="select * from users where username=:payload"
reply-channel="replyChannel" row-mapper="rowMapper">
</int-jdbc:outbound-gateway>
<bean id="rowMapper" class="org.springframework.integration.samples.jdbc.UserMapper"/>
</beans>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %5p | %t | %-55logger{55} | %m %n</pattern>
</encoder>
</appender>
<logger name="org.springframework.integration">
<level value="INFO" />
</logger>
<logger name="org.springframework">
<level value="INFO" />
</logger>
<root>
<level value="INFO" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>

View File

@@ -0,0 +1,5 @@
create table IF NOT EXISTS USERS(USERNAME varchar(100),PASSWORD varchar(100), EMAIL varchar(100));
create table IF NOT EXISTS DUMMY(DUMMY_VALUE varchar(10));
INSERT INTO USERS(USERNAME, PASSWORD, EMAIL) VALUES ('a', 'secret', 'spring-integration@awesome.com');
INSERT INTO USERS(USERNAME, PASSWORD, EMAIL) VALUES ('b', 's3cr3t', 'spring@rocks.com');
INSERT INTO USERS(USERNAME, PASSWORD, EMAIL) VALUES ('foo', 'bar', 'foo@bar.de');

View File

@@ -0,0 +1,59 @@
/*
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.sts;
import static junit.framework.Assert.*;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.samples.jdbc.User;
import org.springframework.integration.samples.jdbc.service.UserService;
/**
* Verify that the Spring Integration Application Context starts successfully.
*/
public class StringConversionServiceTest {
@Test
public void testStartupOfSpringInegrationContext() throws Exception{
final ApplicationContext context
= new ClassPathXmlApplicationContext("/META-INF/spring/integration/spring-integration-context.xml",
StringConversionServiceTest.class);
Thread.sleep(2000);
}
@Test
public void testConvertStringToUpperCase() {
final ApplicationContext context
= new ClassPathXmlApplicationContext("/META-INF/spring/integration/spring-integration-context.xml",
StringConversionServiceTest.class);
final UserService service = context.getBean(UserService.class);
final String userNameToUse = "a";
final String expectedResult = "I LOVE SPRING INTEGRATION";
final User user = service.findUser(userNameToUse);
assertEquals("Expecting that the returned username is 'a'.",
userNameToUse, user.getUsername());
}
}

View File

@@ -11,10 +11,12 @@
<modules>
<module>amqp</module>
<module>enricher</module>
<module>feed</module>
<module>file</module>
<module>ftp</module>
<module>helloworld</module>
<module>jdbc</module>
<module>jms</module>
<module>jdbc</module>
<module>jmx</module>

View File

@@ -7,6 +7,10 @@ and the result is returned to the client that invoked the original SimpleGateway
To run sample simply execute a test case in org.springframework.integration.samples.tcpclientservice package.
Note that the test case includes an alternative configuration that uses the in-built conversion service
and the channel dataType attribute, instead of explicit transformers, to convert from byte arrays to Strings.
Simply change the @ContextConfiguration to switch between the two techniques.
In addition, a simple telnet server is provided; see TelnetServer in src/main/java. Run this class as a
java application and then use telnet to connect to the service ('telnet localhost 11111').

View File

@@ -0,0 +1,57 @@
/*
* Copyright 2002-2011 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.UnsupportedEncodingException;
import org.springframework.core.convert.converter.Converter;
/**
* Simple byte array to String converter; allowing the character set
* to be specified.
*
* @author Gary Russell
* @since 2.1
*
*/
public class ByteArrayToStringConverter implements Converter<byte[], String> {
private String charSet = "UTF-8";
public String convert(byte[] bytes) {
try {
return new String(bytes, this.charSet);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return new String(bytes);
}
}
/**
* @return the charSet
*/
public String getCharSet() {
return charSet;
}
/**
* @param charSet the charSet to set
*/
public void setCharSet(String charSet) {
this.charSet = charSet;
}
}

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="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"
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.xsd">
<beans: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>
<converter>
<beans:bean class="org.springframework.integration.samples.tcpclientserver.ByteArrayToStringConverter" />
</converter>
<!-- Client side -->
<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"
type="client"
host="localhost"
port="11111"
single-use="true"
so-timeout="10000"
/>
<channel id="input" />
<ip:tcp-outbound-gateway id="outGateway"
request-channel="input"
reply-channel="reply"
connection-factory="client"
request-timeout="10000"
reply-timeout="10000"
/>
<!-- dataType attribute invokes the conversion service -->
<channel id="reply" datatype="java.lang.String" />
<!-- Server side -->
<ip:tcp-connection-factory id="crLfServer"
type="server"
port="11111"/>
<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" />
<service-activator input-channel="toSA"
ref="echoService"
method="test"
/>
<beans:bean id="echoService"
class="org.springframework.integration.samples.tcpclientserver.EchoService" />
<transformer id="errorHandler"
input-channel="errorChannel"
expression="payload.failedMessage.payload + ':' + payload.cause.message"/>
</beans:beans>

View File

@@ -30,24 +30,31 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
* 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.
*
*
* The alternate configuration shows how the conversion service can be used
* instead of 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")
@RunWith(SpringJUnit4ClassRunner.class)
public class TcpClientServerDemoTest {
@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("");

View File

@@ -15,6 +15,7 @@
<module>file-processing</module>
<module>multipart-http</module>
<module>travel</module>
<module>stored-procedures-derby</module>
</modules>
</project>

View File

@@ -0,0 +1,30 @@
Spring Integration - Stored Procedure Example - Derby
================================================================================
# Overview
This example provides a simple example using the stored procedure Outbound Gateway
adapter. This example will call 2 Derby Stored Procedures.
One procedure uses an **Out** Parameter to return values and the second procedure
returns a **ResultSet**.
# Setup
Just make sure you have Maven set up and that the project builds successfully.
# Run the Sample
* running the "Main" class from within STS (Right-click on Main class --> Run As --> Java Application)
* or from the command line:
- mvn package
- mvn exec:java
* Follow the screen (command line) instructions.
--------------------------------------------------------------------------------
For help please take a look at the Spring Integration documentation:
http://www.springsource.org/spring-integration

View File

@@ -0,0 +1,122 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.integration.samples</groupId>
<artifactId>derby-stored-procedures</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>stored-procedures-derby</name>
<url>http://www.springsource.org/spring-integration</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.integration.version>2.1.0.BUILD-SNAPSHOT</spring.integration.version>
<slf4j.version>1.6.1</slf4j.version>
<junit.version>4.7</junit.version>
</properties>
<repositories>
<repository>
<id>repository.springframework.maven.release</id>
<name>Spring Framework Maven Release Repository</name>
<url>http://maven.springframework.org/release</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.8</version>
<configuration>
<additionalProjectnatures>
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
</additionalBuildcommands>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2</version>
<configuration>
<mainClass>org.springframework.integration.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- Testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- Spring Integration -->
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-jdbc</artifactId>
<version>${spring.integration.version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>0.9.28</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.8.2.2</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,107 @@
/*
* Copyright 2002-2011 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;
import java.util.List;
import java.util.Scanner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.model.CoffeeBeverage;
import org.springframework.integration.service.CoffeeService;
/**
* Starts the Spring Context and will initialize the Spring Integration routes.
*
* @author Gunnar Hillert
* @since 2.1
*
*/
public final class Main {
private static final Logger LOGGER = LoggerFactory.getLogger(Main.class);
private static final String LINE = "\n=========================================================";
private static final String NEWLINE = "\n ";
private Main() { }
/**
* Load the Spring Integration Application Context
*
* @param args - command line arguments
*/
public static void main(final String... args) {
LOGGER.info(LINE
+ LINE
+ "\n Welcome to Spring Integration Coffee Database! "
+ NEWLINE
+ "\n For more information please visit: "
+ "\n http://www.springsource.org/spring-integration "
+ NEWLINE
+ LINE );
final AbstractApplicationContext context =
new ClassPathXmlApplicationContext("classpath:META-INF/spring/integration/*-context.xml");
context.registerShutdownHook();
final Scanner scanner = new Scanner(System.in);
final CoffeeService service = context.getBean(CoffeeService.class);
LOGGER.info(LINE
+ NEWLINE
+ "\n Please press 'q + Enter' to quit the application. "
+ NEWLINE
+ LINE);
System.out.print("Please enter 'list' and press <enter> to get a list of coffees.");
System.out.print("Enter a coffee id, e.g. '1' and press <enter> to get a description.\n\n");
while (!scanner.hasNext("q")) {
String input = scanner.nextLine();
if ("list".equalsIgnoreCase(input)) {
List<CoffeeBeverage> coffeeBeverages = service.findAllCoffeeBeverages();
for (CoffeeBeverage coffeeBeverage : coffeeBeverages) {
System.out.println(String.format("%s - %s", coffeeBeverage.getId(),
coffeeBeverage.getName()));
}
} else {
System.out.println("Retrieving coffee information...");
String coffeeDescription = service.findCoffeeBeverage(Integer.valueOf(input));
System.out.println(String.format("Searched for '%s' - Found: '%s'.", input, coffeeDescription));
System.out.print("To try again, please enter another coffee beaverage and press <enter>:\n\n");
}
}
LOGGER.info("Exiting application...bye.");
System.exit(0);
}
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2002-2011 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.jdbc.storedproc.derby;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.support.JdbcUtils;
/**
*
* @author Gunnar Hillert
* @since 2.1
*
*/
public final class DerbyStoredProcedures {
private DerbyStoredProcedures() {
}
public static void findCoffee(int coffeeId, String[] coffeeDescription)
throws SQLException {
Connection connection = null;
PreparedStatement statement = null;
try {
connection = DriverManager.getConnection("jdbc:default:connection");
String sql = "SELECT * FROM COFFEE_BEVERAGES WHERE ID = ? ";
statement = connection.prepareStatement(sql);
statement.setLong(1, coffeeId);
ResultSet resultset = statement.executeQuery();
resultset.next();
coffeeDescription[0] = resultset.getString("COFFEE_DESCRIPTION");
} finally {
JdbcUtils.closeStatement(statement);
JdbcUtils.closeConnection(connection);
}
}
public static void findAllCoffeeBeverages(ResultSet[] coffeeBeverages)
throws SQLException {
Connection connection = null;
PreparedStatement statement = null;
connection = DriverManager.getConnection("jdbc:default:connection");
String sql = "SELECT * FROM COFFEE_BEVERAGES";
statement = connection.prepareStatement(sql);
coffeeBeverages[0] = statement.executeQuery();
}
}

View File

@@ -0,0 +1,131 @@
/*
* Copyright 2002-2011 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.model;
/**
*
* @author Gunnar Hillert
* @since 2.1
*
*/
public class CoffeeBeverage {
private Integer id;
private String name;
private String description;
/** Default Constructor */
public CoffeeBeverage() {
super();
}
/**
* @param id
* @param name
* @param description
*/
public CoffeeBeverage(Integer id, String name, String description) {
super();
this.id = id;
this.name = name;
this.description = description;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime
* result
+ ((this.description == null) ? 0 : this.description.hashCode());
result = prime * result
+ ((this.name == null) ? 0 : this.name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
CoffeeBeverage other = (CoffeeBeverage) obj;
if (this.description == null) {
if (other.description != null) {
return false;
}
} else if (!this.description.equals(other.description)) {
return false;
}
if (this.name == null) {
if (other.name != null) {
return false;
}
} else if (!this.name.equals(other.name)) {
return false;
}
return true;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("CoffeeBeverage [id=").append(this.id).append(", name=")
.append(this.name).append(", description=")
.append(this.description).append("]");
return builder.toString();
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2002-2011 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.service;
import java.util.List;
import org.springframework.integration.annotation.Payload;
import org.springframework.integration.model.CoffeeBeverage;
/**
* Provides access to the Coffee Database Services.
*
* @author Gunnar Hillert
* @since 2.1
*/
public interface CoffeeService {
/**
* Find the description for a provided coffee beverage.
*
* @param Id of the coffee beverage
* @return The the description of the coffee beverage
*/
String findCoffeeBeverage(Integer input);
/**
* Find the description for a provided coffee beverage.
*
* @return Collection of coffee beverages
*/
@Payload("new java.util.Date()")
List<CoffeeBeverage> findAllCoffeeBeverages();
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2002-2011 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.support;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.integration.model.CoffeeBeverage;
import org.springframework.jdbc.core.RowMapper;
/**
*
* @author Gunnar Hillert
* @since 2.1
*
*/
public class CoffeBeverageMapper implements RowMapper<CoffeeBeverage> {
public CoffeeBeverage mapRow(ResultSet rs, int rowNum) throws SQLException {
return new CoffeeBeverage(rs.getInt("ID"), rs.getString("COFFEE_NAME"), rs.getString("COFFEE_DESCRIPTION"));
}
}

View File

@@ -0,0 +1,41 @@
<?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-jdbc="http://www.springframework.org/schema/integration/jdbc"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<jdbc:embedded-database id="dataSource" type="DERBY"/>
<jdbc:initialize-database data-source="dataSource" ignore-failures="DROPS">
<jdbc:script location="classpath:derby-stored-procedures.sql"/>
</jdbc:initialize-database>
<int:channel id="findCoffeeProcedureRequestChannel"/>
<int:channel id="findAllProcedureRequestChannel"/>
<int:gateway id="gateway" default-request-timeout="5000"
default-reply-timeout="5000"
service-interface="org.springframework.integration.service.CoffeeService">
<int:method name="findCoffeeBeverage" request-channel="findCoffeeProcedureRequestChannel" />
<int:method name="findAllCoffeeBeverages" request-channel="findAllProcedureRequestChannel" />
</int:gateway>
<int-jdbc:stored-proc-outbound-gateway id="outbound-gateway-storedproc-find-coffee" data-source="dataSource"
request-channel="findCoffeeProcedureRequestChannel" skip-undeclared-results="true"
stored-procedure-name="FIND_COFFEE"
expect-single-result="true">
<int-jdbc:parameter name="COFFEE_NAME" expression="payload" />
</int-jdbc:stored-proc-outbound-gateway>
<int-jdbc:stored-proc-outbound-gateway id="outbound-gateway-storedproc-find-all" data-source="dataSource"
request-channel="findAllProcedureRequestChannel" expect-single-result="true"
stored-procedure-name="FIND_ALL_COFFEE_BEVERAGES">
<int-jdbc:returning-resultset name="coffeeBeverages" row-mapper="org.springframework.integration.support.CoffeBeverageMapper"/>
</int-jdbc:stored-proc-outbound-gateway>
</beans>

View File

@@ -0,0 +1,14 @@
drop table COFFEE_BEVERAGES;
drop PROCEDURE FIND_COFFEE;
drop PROCEDURE FIND_ALL_COFFEE_BEVERAGES;
create table COFFEE_BEVERAGES(ID INTEGER NOT NULL CONSTRAINT COFFEE_BEVERAGES_PK PRIMARY KEY, COFFEE_NAME varchar(100), COFFEE_DESCRIPTION varchar(200));
INSERT INTO COFFEE_BEVERAGES (ID, COFFEE_NAME, COFFEE_DESCRIPTION) VALUES (1, 'Espresso', 'Espressos keep developers going in the morning. There are never enough of them.');
INSERT INTO COFFEE_BEVERAGES (ID, COFFEE_NAME, COFFEE_DESCRIPTION) VALUES (2, 'Cappuccino', 'For the finer moments. Wrap your espresso in a tasty layer of foam.');
INSERT INTO COFFEE_BEVERAGES (ID, COFFEE_NAME, COFFEE_DESCRIPTION) VALUES (3, 'Mocha', 'Mmmmh, chocolate.');
INSERT INTO COFFEE_BEVERAGES (ID, COFFEE_NAME, COFFEE_DESCRIPTION) VALUES (4, 'Latte', 'If you are more into milk than into foam.');
CREATE PROCEDURE FIND_COFFEE( IN COFFEE_NAME INTEGER, OUT COFFEE_DESCRIPTION VARCHAR(100)) PARAMETER STYLE JAVA LANGUAGE JAVA EXTERNAL NAME 'org.springframework.integration.jdbc.storedproc.derby.DerbyStoredProcedures.findCoffee';
CREATE PROCEDURE FIND_ALL_COFFEE_BEVERAGES() PARAMETER STYLE JAVA LANGUAGE JAVA MODIFIES SQL DATA DYNAMIC RESULT SETS 1 EXTERNAL NAME 'org.springframework.integration.jdbc.storedproc.derby.DerbyStoredProcedures.findAllCoffeeBeverages';

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %5p | %t | %-55logger{55} | %m %n</pattern>
</encoder>
</appender>
<logger name="org.springframework.integration">
<level value="INFO" />
</logger>
<logger name="org.springframework">
<level value="INFO" />
</logger>
<root>
<level value="INFO" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2002-2011 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;
import java.util.List;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.model.CoffeeBeverage;
import org.springframework.integration.service.CoffeeService;
import static org.junit.Assert.assertTrue;
/**
* @author Gunnar Hillert
* @since 2.1
*/
public class CoffeeServiceFindAllTest {
@Test
public void testFindCoffee() {
final ApplicationContext context
= new ClassPathXmlApplicationContext("/META-INF/spring/integration/spring-integration-context.xml",
CoffeeServiceFindAllTest.class);
final CoffeeService service = context.getBean(CoffeeService.class);
List<CoffeeBeverage> coffeeBeverages = service.findAllCoffeeBeverages();
assertTrue(coffeeBeverages.size() == 4);
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2002-2011 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;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.service.CoffeeService;
import static org.junit.Assert.assertEquals;
/**
* @author Gunnar Hillert
* @since 2.1
*/
public class CoffeeServiceFindCoffeeTest {
@Test
public void testFindCoffee() {
final ApplicationContext context
= new ClassPathXmlApplicationContext("/META-INF/spring/integration/spring-integration-context.xml",
CoffeeServiceFindCoffeeTest.class);
final CoffeeService service = context.getBean(CoffeeService.class);
String description = service.findCoffeeBeverage(3);
assertEquals("Mmmmh, chocolate.", description);
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2002-2011 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;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Verify that the Spring Integration Application Context starts successfully.
*/
public class CoffeeServiceStartupTest {
@Test
public void testStartupOfSpringInegrationContext() throws Exception{
final ApplicationContext context
= new ClassPathXmlApplicationContext("/META-INF/spring/integration/spring-integration-context.xml",
CoffeeServiceStartupTest.class);
Thread.sleep(2000);
}
}