Merge pull request #17 from dturanski/cafe-scripted

Added Cafe Scripted Demo
This commit is contained in:
Gunnar Hillert
2011-12-14 09:29:39 -08:00
25 changed files with 1142 additions and 0 deletions

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