From a32ed6647b530db2970a15f442d343d4a1a9b377 Mon Sep 17 00:00:00 2001 From: Tom McCuch Date: Sun, 30 Oct 2011 18:52:42 -0400 Subject: [PATCH 01/15] interim commit changed copyright on Order.java --- applications/cafe/pom.xml | 4 +- .../integration/samples/cafe/Order.java | 2 +- .../samples/cafe/annotation/Barista.java | 2 +- .../amqp/cafeDemo-amqp-baristaCold-xml.xml | 61 ++++++++ .../amqp/cafeDemo-amqp-baristaHot-xml.xml | 62 ++++++++ .../integration/amqp/cafeDemo-amqp-xml.xml | 133 ++++++++++++++++++ 6 files changed, 260 insertions(+), 4 deletions(-) create mode 100644 applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml create mode 100644 applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaHot-xml.xml create mode 100644 applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml diff --git a/applications/cafe/pom.xml b/applications/cafe/pom.xml index aa0dbf58..5a80da72 100644 --- a/applications/cafe/pom.xml +++ b/applications/cafe/pom.xml @@ -7,14 +7,14 @@ 2.0.0 Spring Integration Cafe Sample - 2.0.5.RELEASE + 2.1.0.M3 1.2.16 4.7 org.springframework.integration - spring-integration-core + spring-integration-amqp ${spring.integration.version} diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Order.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Order.java index 883d9708..6b6f68d6 100644 --- a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Order.java +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Order.java @@ -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. diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/annotation/Barista.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/annotation/Barista.java index a3ccc9e3..3ceac0e3 100644 --- a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/annotation/Barista.java +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/annotation/Barista.java @@ -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. diff --git a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml new file mode 100644 index 00000000..ed990516 --- /dev/null +++ b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaHot-xml.xml b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaHot-xml.xml new file mode 100644 index 00000000..6ff636a6 --- /dev/null +++ b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaHot-xml.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml new file mode 100644 index 00000000..d840e9b7 --- /dev/null +++ b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 15dc7cd0593cdaf6194f7e1d5cebee20d0ae4824 Mon Sep 17 00:00:00 2001 From: Tom McCuch Date: Mon, 31 Oct 2011 13:04:28 -0400 Subject: [PATCH 02/15] domain updates + new runnable class --- .../integration/samples/cafe/Delivery.java | 14 ++++- .../integration/samples/cafe/Drink.java | 38 +++++++++++- .../integration/samples/cafe/DrinkType.java | 2 +- .../integration/samples/cafe/Order.java | 13 +++- .../integration/samples/cafe/OrderItem.java | 38 ++++++++---- .../samples/cafe/annotation/Barista.java | 10 ++-- .../integration/samples/cafe/xml/Barista.java | 12 ++-- .../samples/cafe/xml/CafeDemoAppAmqp.java | 60 +++++++++++++++++++ .../integration/amqp/cafeDemo-amqp-xml.xml | 5 +- .../cafe/src/test/resources/log4j.xml | 10 +++- 10 files changed, 172 insertions(+), 30 deletions(-) create mode 100644 applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppAmqp.java diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Delivery.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Delivery.java index a59fbd43..2f0b5b49 100644 --- a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Delivery.java +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Delivery.java @@ -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 deliveredDrinks; private int orderNumber; + // Default constructor required by Jackson Java JSON-processor + public Delivery() {} public Delivery(List deliveredDrinks) { assert(deliveredDrinks.size() > 0); @@ -42,10 +44,18 @@ public class Delivery { return orderNumber; } + public void setOrderNumber(int orderNumber) { + this.orderNumber = orderNumber; + } + public List getDeliveredDrinks() { return deliveredDrinks; } + public void setDeliveredDrinks(List deliveredDrinks) { + this.deliveredDrinks = deliveredDrinks; + } + @Override public String toString() { StringBuffer buffer = new StringBuffer(SEPARATOR + "\n"); diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Drink.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Drink.java index 504a8658..aa336199 100644 --- a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Drink.java +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Drink.java @@ -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."; diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java index 7e438db4..4944ca4c 100644 --- a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java @@ -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. diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Order.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Order.java index 6b6f68d6..448d7186 100644 --- a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Order.java +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Order.java @@ -22,6 +22,7 @@ import java.util.List; /** * @author Mark Fisher * @author Marius Bogoevici + * @author Tom McCuch */ public class Order { @@ -29,20 +30,30 @@ public class Order { 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 getItems() { return this.orderItems; } + public void setItems(List orderItems) { + this.orderItems = orderItems; + } } diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java index 0215ff4c..d256bd81 100644 --- a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java @@ -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,51 @@ public class OrderItem { private boolean iced = false; - private final Order order; + 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; } diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/annotation/Barista.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/annotation/Barista.java index 3ceac0e3..ece88941 100644 --- a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/annotation/Barista.java +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/annotation/Barista.java @@ -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(); diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/Barista.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/Barista.java index 4db79f81..c4d117f0 100644 --- a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/Barista.java +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/Barista.java @@ -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(); diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppAmqp.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppAmqp.java new file mode 100644 index 00000000..23c110c6 --- /dev/null +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppAmqp.java @@ -0,0 +1,60 @@ +/* + * 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 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 will send that order to the "orders" channel. + *

+ * The relevant components are defined within the configuration files: + * ("cafeDemo-amqp-xml.xml", "cafeDemo-amqp-baristaCold-xml.xml, and + * "cafeDemo-amqp-baristaHot-xml.xml). + *

+ * If deploying in SpringSource dmServer, the relevant ApplicationContext + * configuration is in the META-INF/spring directory instead. + * + * @author Tom McCuch + */ +public class CafeDemoAppAmqp { + + public static void main(String[] args) { + AbstractApplicationContext context = + new ClassPathXmlApplicationContext( + new String[] {"/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml", + "/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml", + "/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaHot-xml.xml"}, + CafeDemoAppAmqp.class); + + 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); + } + context.close(); + } +} diff --git a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml index d840e9b7..b5472278 100644 --- a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml +++ b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml @@ -22,9 +22,8 @@ - - - + diff --git a/applications/cafe/src/test/resources/log4j.xml b/applications/cafe/src/test/resources/log4j.xml index 678b69b3..bbcbcf15 100644 --- a/applications/cafe/src/test/resources/log4j.xml +++ b/applications/cafe/src/test/resources/log4j.xml @@ -6,7 +6,7 @@ - + @@ -15,6 +15,14 @@ + + + + + + + + From f366d5386995927ff308a771562f25bcdeba066c Mon Sep 17 00:00:00 2001 From: Gunnar Hillert Date: Thu, 3 Nov 2011 01:02:57 -0400 Subject: [PATCH 03/15] INTSAMPLES-33 Add initial Jdbc sample --- basic/jdbc/README.md | 28 ++++ basic/jdbc/pom.xml | 129 ++++++++++++++++++ .../integration/samples/jdbc/Main.java | 97 +++++++++++++ .../integration/samples/jdbc/User.java | 38 ++++++ .../integration/samples/jdbc/UserMapper.java | 24 ++++ .../samples/jdbc/service/UserService.java | 33 +++++ .../spring-integration-context.xml | 38 ++++++ basic/jdbc/src/main/resources/logback.xml | 24 ++++ .../jdbc/src/main/resources/setup-tables.sql | 5 + .../sts/StringConversionServiceTest.java | 59 ++++++++ basic/pom.xml | 1 + 11 files changed, 476 insertions(+) create mode 100644 basic/jdbc/README.md create mode 100644 basic/jdbc/pom.xml create mode 100644 basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/Main.java create mode 100644 basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/User.java create mode 100644 basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/UserMapper.java create mode 100644 basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/service/UserService.java create mode 100644 basic/jdbc/src/main/resources/META-INF/spring/integration/spring-integration-context.xml create mode 100644 basic/jdbc/src/main/resources/logback.xml create mode 100644 basic/jdbc/src/main/resources/setup-tables.sql create mode 100644 basic/jdbc/src/test/java/org/springframework/integration/sts/StringConversionServiceTest.java diff --git a/basic/jdbc/README.md b/basic/jdbc/README.md new file mode 100644 index 00000000..e6c5bec1 --- /dev/null +++ b/basic/jdbc/README.md @@ -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 + diff --git a/basic/jdbc/pom.xml b/basic/jdbc/pom.xml new file mode 100644 index 00000000..33e8ae93 --- /dev/null +++ b/basic/jdbc/pom.xml @@ -0,0 +1,129 @@ + + 4.0.0 + + org.springframework.integration.samples + jdbc + 1.0-SNAPSHOT + jar + + jdbc-sample + http://www.springsource.org/spring-integration + + + UTF-8 + 2.1.0.M3 + 1.6.1 + 4.7 + + + + + repository.springframework.maven.release + Spring Framework Maven Release Repository + http://maven.springframework.org/release + + + repository.springframework.maven.milestone + Spring Framework Maven Milestone Repository + http://maven.springframework.org/milestone + + + + + + + maven-eclipse-plugin + 2.8 + + + org.springframework.ide.eclipse.core.springnature + + + org.springframework.ide.eclipse.core.springbuilder + + true + true + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + -Xlint:all + true + true + + + + org.codehaus.mojo + exec-maven-plugin + 1.2 + + org.springframework.integration.samples.jdbc.Main + + + + + + + + + + + junit + junit + ${junit.version} + test + + + + + + org.springframework.integration + spring-integration-core + ${spring.integration.version} + + + + org.springframework.integration + spring-integration-jdbc + ${spring.integration.version} + + + + + + ch.qos.logback + logback-classic + 0.9.28 + + + org.slf4j + slf4j-api + ${slf4j.version} + + + org.slf4j + log4j-over-slf4j + ${slf4j.version} + + + org.slf4j + jcl-over-slf4j + ${slf4j.version} + + + + + + com.h2database + h2 + 1.3.160 + + + + diff --git a/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/Main.java b/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/Main.java new file mode 100644 index 00000000..0edab38b --- /dev/null +++ b/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/Main.java @@ -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 : "); + 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 :"); + + } + + LOGGER.info("Exiting application...bye."); + + System.exit(0); + + } +} diff --git a/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/User.java b/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/User.java new file mode 100644 index 00000000..2fcbd1f5 --- /dev/null +++ b/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/User.java @@ -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; + } +} diff --git a/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/UserMapper.java b/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/UserMapper.java new file mode 100644 index 00000000..ce87ceb3 --- /dev/null +++ b/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/UserMapper.java @@ -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 { + public User mapRow(ResultSet rs, int rowNum) throws SQLException { + return new User(rs.getString("username"), rs.getString("password"), rs.getString("email")); + } +} diff --git a/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/service/UserService.java b/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/service/UserService.java new file mode 100644 index 00000000..38d03fa6 --- /dev/null +++ b/basic/jdbc/src/main/java/org/springframework/integration/samples/jdbc/service/UserService.java @@ -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); + +} diff --git a/basic/jdbc/src/main/resources/META-INF/spring/integration/spring-integration-context.xml b/basic/jdbc/src/main/resources/META-INF/spring/integration/spring-integration-context.xml new file mode 100644 index 00000000..bd04abaa --- /dev/null +++ b/basic/jdbc/src/main/resources/META-INF/spring/integration/spring-integration-context.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/basic/jdbc/src/main/resources/logback.xml b/basic/jdbc/src/main/resources/logback.xml new file mode 100644 index 00000000..eee6b966 --- /dev/null +++ b/basic/jdbc/src/main/resources/logback.xml @@ -0,0 +1,24 @@ + + + + + + + %d %5p | %t | %-55logger{55} | %m %n + + + + + + + + + + + + + + + + + diff --git a/basic/jdbc/src/main/resources/setup-tables.sql b/basic/jdbc/src/main/resources/setup-tables.sql new file mode 100644 index 00000000..a57cd2a0 --- /dev/null +++ b/basic/jdbc/src/main/resources/setup-tables.sql @@ -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'); \ No newline at end of file diff --git a/basic/jdbc/src/test/java/org/springframework/integration/sts/StringConversionServiceTest.java b/basic/jdbc/src/test/java/org/springframework/integration/sts/StringConversionServiceTest.java new file mode 100644 index 00000000..d20bc4f4 --- /dev/null +++ b/basic/jdbc/src/test/java/org/springframework/integration/sts/StringConversionServiceTest.java @@ -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()); + + } + +} diff --git a/basic/pom.xml b/basic/pom.xml index 22943de9..6a0492e0 100644 --- a/basic/pom.xml +++ b/basic/pom.xml @@ -15,6 +15,7 @@ file ftp helloworld + jdbc jms jmx mail From ac5693d31082561e9787b0f394dbd0b56a45c61f Mon Sep 17 00:00:00 2001 From: Gunnar Hillert Date: Fri, 4 Nov 2011 15:51:37 -0400 Subject: [PATCH 04/15] INTSAMPLES-34 Initial commit of the Enricher Sample --- basic/enricher/README.md | 36 +++++ basic/enricher/pom.xml | 123 +++++++++++++++++ .../integration/samples/enricher/Main.java | 128 ++++++++++++++++++ .../integration/samples/enricher/User.java | 63 +++++++++ .../samples/enricher/service/UserService.java | 37 +++++ .../enricher/service/impl/SystemService.java | 55 ++++++++ .../spring-integration-context.xml | 54 ++++++++ basic/enricher/src/main/resources/logback.xml | 24 ++++ .../enricher/service/UserServiceTest.java | 77 +++++++++++ basic/pom.xml | 1 + 10 files changed, 598 insertions(+) create mode 100644 basic/enricher/README.md create mode 100644 basic/enricher/pom.xml create mode 100644 basic/enricher/src/main/java/org/springframework/integration/samples/enricher/Main.java create mode 100644 basic/enricher/src/main/java/org/springframework/integration/samples/enricher/User.java create mode 100644 basic/enricher/src/main/java/org/springframework/integration/samples/enricher/service/UserService.java create mode 100644 basic/enricher/src/main/java/org/springframework/integration/samples/enricher/service/impl/SystemService.java create mode 100644 basic/enricher/src/main/resources/META-INF/spring/integration/spring-integration-context.xml create mode 100644 basic/enricher/src/main/resources/logback.xml create mode 100644 basic/enricher/src/test/java/org/springframework/integration/samples/enricher/service/UserServiceTest.java diff --git a/basic/enricher/README.md b/basic/enricher/README.md new file mode 100644 index 00000000..e862836c --- /dev/null +++ b/basic/enricher/README.md @@ -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 by covering 2 use-cases. +Once the application is started, you can execute each individual use case by: + +* entering 1 + Enter +* entering 2 + Enter + +Each use case will trigger slightly different Spring Integration message flows. For +both flows a **User** object containing only the **username** is passed in through a *Gateway*. + +However the Enrichment is executed differently for each flow: + +* 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. + +# Resources + +For help please take a look at the Spring Integration documentation: + +http://www.springsource.org/spring-integration + diff --git a/basic/enricher/pom.xml b/basic/enricher/pom.xml new file mode 100644 index 00000000..9c109744 --- /dev/null +++ b/basic/enricher/pom.xml @@ -0,0 +1,123 @@ + + 4.0.0 + + org.springframework.integration.samples + enricher + 1.0-SNAPSHOT + jar + + enricher-sample + http://www.springsource.org/spring-integration + + + UTF-8 + 2.1.0.BUILD-SNAPSHOT + 1.6.1 + 4.7 + + + + + repository.springframework.maven.release + Spring Framework Maven Release Repository + http://maven.springframework.org/release + + + repository.springframework.maven.milestone + Spring Framework Maven Milestone Repository + http://maven.springframework.org/milestone + + + + + + + maven-eclipse-plugin + 2.8 + + + org.springframework.ide.eclipse.core.springnature + + + org.springframework.ide.eclipse.core.springbuilder + + true + true + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + -Xlint:all + true + true + + + + org.codehaus.mojo + exec-maven-plugin + 1.2 + + org.springframework.integration.samples.enricher.Main + + + + + + + + + + + junit + junit + ${junit.version} + test + + + + + + org.springframework.integration + spring-integration-core + ${spring.integration.version} + + + + + + ch.qos.logback + logback-classic + 0.9.28 + + + org.slf4j + slf4j-api + ${slf4j.version} + + + org.slf4j + log4j-over-slf4j + ${slf4j.version} + + + org.slf4j + jcl-over-slf4j + ${slf4j.version} + + + + + + com.h2database + h2 + 1.3.160 + + + + diff --git a/basic/enricher/src/main/java/org/springframework/integration/samples/enricher/Main.java b/basic/enricher/src/main/java/org/springframework/integration/samples/enricher/Main.java new file mode 100644 index 00000000..7bc7ea50 --- /dev/null +++ b/basic/enricher/src/main/java/org/springframework/integration/samples/enricher/Main.java @@ -0,0 +1,128 @@ +/* + * 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.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 + Enter or 2 + Enter " + + EMPTY_LINE + + "\n 2 different message flows are triggered. For both flows a " + + "\n user object containing only the username is passed in. " + + EMPTY_LINE + + "\n However the Enrichment is executed differently: " + + 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. " + + 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 { + LOGGER.info("\n\n Please enter '1' or '2' :\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"); + } + + } + +} diff --git a/basic/enricher/src/main/java/org/springframework/integration/samples/enricher/User.java b/basic/enricher/src/main/java/org/springframework/integration/samples/enricher/User.java new file mode 100644 index 00000000..eb6defa9 --- /dev/null +++ b/basic/enricher/src/main/java/org/springframework/integration/samples/enricher/User.java @@ -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(); + } + +} diff --git a/basic/enricher/src/main/java/org/springframework/integration/samples/enricher/service/UserService.java b/basic/enricher/src/main/java/org/springframework/integration/samples/enricher/service/UserService.java new file mode 100644 index 00000000..d26a0c45 --- /dev/null +++ b/basic/enricher/src/main/java/org/springframework/integration/samples/enricher/service/UserService.java @@ -0,0 +1,37 @@ +/* + * 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 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); + +} diff --git a/basic/enricher/src/main/java/org/springframework/integration/samples/enricher/service/impl/SystemService.java b/basic/enricher/src/main/java/org/springframework/integration/samples/enricher/service/impl/SystemService.java new file mode 100644 index 00000000..a6a41625 --- /dev/null +++ b/basic/enricher/src/main/java/org/springframework/integration/samples/enricher/service/impl/SystemService.java @@ -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"); + + } + +} diff --git a/basic/enricher/src/main/resources/META-INF/spring/integration/spring-integration-context.xml b/basic/enricher/src/main/resources/META-INF/spring/integration/spring-integration-context.xml new file mode 100644 index 00000000..8c55e18f --- /dev/null +++ b/basic/enricher/src/main/resources/META-INF/spring/integration/spring-integration-context.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/basic/enricher/src/main/resources/logback.xml b/basic/enricher/src/main/resources/logback.xml new file mode 100644 index 00000000..eee6b966 --- /dev/null +++ b/basic/enricher/src/main/resources/logback.xml @@ -0,0 +1,24 @@ + + + + + + + %d %5p | %t | %-55logger{55} | %m %n + + + + + + + + + + + + + + + + + diff --git a/basic/enricher/src/test/java/org/springframework/integration/samples/enricher/service/UserServiceTest.java b/basic/enricher/src/test/java/org/springframework/integration/samples/enricher/service/UserServiceTest.java new file mode 100644 index 00000000..ac16ba85 --- /dev/null +++ b/basic/enricher/src/test/java/org/springframework/integration/samples/enricher/service/UserServiceTest.java @@ -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()); + + } + +} diff --git a/basic/pom.xml b/basic/pom.xml index 22943de9..47fcf255 100644 --- a/basic/pom.xml +++ b/basic/pom.xml @@ -11,6 +11,7 @@ amqp + enricher feed file ftp From 9c9c1da7f30f10cd6caea0e617d5797453b81079 Mon Sep 17 00:00:00 2001 From: Tom McCuch Date: Sun, 6 Nov 2011 18:21:48 -0500 Subject: [PATCH 05/15] Final Packaging --- applications/cafe/pom.xml | 11 ++ applications/cafe/readme.txt | 19 ++- .../integration/samples/cafe/Cafe.java | 2 +- .../samples/cafe/xml/CafeDemoAppAmqp.java | 19 ++- .../cafe/xml/CafeDemoAppBaristaColdAmqp.java | 59 +++++++++ .../cafe/xml/CafeDemoAppBaristaHotAmqp.java | 59 +++++++++ .../cafe/xml/CafeDemoAppOperationsAmqp.java | 65 ++++++++++ .../amqp/cafeDemo-amqp-baristaCold-xml.xml | 18 +-- .../amqp/cafeDemo-amqp-baristaHot-xml.xml | 19 +-- .../amqp/cafeDemo-amqp-config-xml.xml | 23 ++++ .../amqp/cafeDemo-amqp-operations-xml.xml | 113 ++++++++++++++++ .../integration/amqp/cafeDemo-amqp-xml.xml | 121 ++++-------------- 12 files changed, 385 insertions(+), 143 deletions(-) create mode 100644 applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaColdAmqp.java create mode 100644 applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaHotAmqp.java create mode 100644 applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppOperationsAmqp.java create mode 100644 applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-config-xml.xml create mode 100644 applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-operations-xml.xml diff --git a/applications/cafe/pom.xml b/applications/cafe/pom.xml index 5a80da72..b0483d22 100644 --- a/applications/cafe/pom.xml +++ b/applications/cafe/pom.xml @@ -22,6 +22,17 @@ spring-integration-stream ${spring.integration.version} + + + org.codehaus.jackson + jackson-core-asl + 1.8.3 + + + org.codehaus.jackson + jackson-mapper-asl + 1.8.3 + log4j log4j diff --git a/applications/cafe/readme.txt b/applications/cafe/readme.txt index 69ae4e18..a0c3f488 100644 --- a/applications/cafe/readme.txt +++ b/applications/cafe/readme.txt @@ -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. cafeDemoAppOperationsAmqp - starts the Cafe Operations (OrderSplitter, DrinkRouter, PreparedDrinkAggregator) + 4. cafeDemoAppAmqp - starts the Cafe Storefront (Places 100 orders on the orders queue) + + * 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 diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Cafe.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Cafe.java index 66363ca8..fecbce4d 100644 --- a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Cafe.java +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Cafe.java @@ -30,7 +30,7 @@ import org.springframework.integration.annotation.Gateway; */ public interface Cafe { - @Gateway(requestChannel="orders") + @Gateway(requestChannel="preOrders") void placeOrder(Order order); } diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppAmqp.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppAmqp.java index 23c110c6..db802315 100644 --- a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppAmqp.java +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppAmqp.java @@ -23,15 +23,15 @@ import org.springframework.integration.samples.cafe.DrinkType; import org.springframework.integration.samples.cafe.Order; /** - * Provides the 'main' method for running the Cafe Demo application - * using AMQP. Before running, be sure to have a RabbitMQ broker - * started on localhost:5672 configured with the default + * 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 will send that order to the "orders" channel. + * placed, the Cafe store front will publish that order on the cafe-orders + * exchange to be processed. *

* The relevant components are defined within the configuration files: - * ("cafeDemo-amqp-xml.xml", "cafeDemo-amqp-baristaCold-xml.xml, and - * "cafeDemo-amqp-baristaHot-xml.xml). + * ("cafeDemo-amqp-xml.xml", "cafeDemo-amqp-config-xml.xml"). *

* If deploying in SpringSource dmServer, the relevant ApplicationContext * configuration is in the META-INF/spring directory instead. @@ -42,11 +42,7 @@ public class CafeDemoAppAmqp { public static void main(String[] args) { AbstractApplicationContext context = - new ClassPathXmlApplicationContext( - new String[] {"/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml", - "/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml", - "/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaHot-xml.xml"}, - CafeDemoAppAmqp.class); + new ClassPathXmlApplicationContext("/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml", CafeDemoAppAmqp.class); Cafe cafe = (Cafe) context.getBean("cafe"); for (int i = 1; i <= 100; i++) { @@ -55,6 +51,7 @@ public class CafeDemoAppAmqp { order.addItem(DrinkType.MOCHA, 3, true); cafe.placeOrder(order); } + context.close(); } } diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaColdAmqp.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaColdAmqp.java new file mode 100644 index 00000000..bde92220 --- /dev/null +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaColdAmqp.java @@ -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. + *

+ * The relevant components are defined within the configuration files: + * ("cafeDemo-amqp-baristaCold-xml.xml", "cafeDemo-amqp-config-xml.xml"). + *

+ * 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 = + new ClassPathXmlApplicationContext( + "/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml", + CafeDemoAppBaristaColdAmqp.class); + + 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(); + } +} diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaHotAmqp.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaHotAmqp.java new file mode 100644 index 00000000..0f0d8d9c --- /dev/null +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaHotAmqp.java @@ -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. + *

+ * The relevant components are defined within the configuration files: + * ("cafeDemo-amqp-baristaHot-xml.xml", "cafeDemo-amqp-config-xml.xml"). + *

+ * 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 = + new ClassPathXmlApplicationContext( + "/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaHot-xml.xml", + CafeDemoAppBaristaHotAmqp.class); + + 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(); + } +} diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppOperationsAmqp.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppOperationsAmqp.java new file mode 100644 index 00000000..ec894dc8 --- /dev/null +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppOperationsAmqp.java @@ -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. + *

+ * The relevant components are defined within the configuration files: + * ("cafeDemo-amqp-operations-xml.xml", "cafeDemo-amqp-config-xml.xml"). + *

+ * 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 = + new ClassPathXmlApplicationContext( + "/META-INF/spring/integration/amqp/cafeDemo-amqp-operations-xml.xml", + CafeDemoAppOperationsAmqp.class); + + 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(); + } +} diff --git a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml index ed990516..517fd70f 100644 --- a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml +++ b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml @@ -20,6 +20,9 @@ http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd"> + + + - - - - - - - - - - - - - - + diff --git a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaHot-xml.xml b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaHot-xml.xml index 6ff636a6..ea48b719 100644 --- a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaHot-xml.xml +++ b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaHot-xml.xml @@ -20,6 +20,9 @@ http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd"> + + + - - - - - - - - - - - - - - - + diff --git a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-config-xml.xml b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-config-xml.xml new file mode 100644 index 00000000..2613cf8f --- /dev/null +++ b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-config-xml.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + diff --git a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-operations-xml.xml b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-operations-xml.xml new file mode 100644 index 00000000..d8bbcbc8 --- /dev/null +++ b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-operations-xml.xml @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml index b5472278..b4c8feef 100644 --- a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml +++ b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml @@ -19,114 +19,37 @@ http://www.springframework.org/schema/integration/stream http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd"> - - - - + + - + + - - - + + + + + + + - - - + - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - + + - - - - - - - - - - - - - - - - - + \ No newline at end of file From e08a4a775d29892f8e85139cc0c080dab9e72af7 Mon Sep 17 00:00:00 2001 From: Gunnar Hillert Date: Mon, 7 Nov 2011 17:22:02 -0500 Subject: [PATCH 06/15] INTSAMPLES-34 Added sample for enriching a Map --- basic/enricher/README.md | 22 +++++++++---------- .../integration/samples/enricher/Main.java | 22 +++++++++++++++---- .../samples/enricher/service/UserService.java | 9 ++++++++ .../spring-integration-context.xml | 15 ++++++++----- 4 files changed, 48 insertions(+), 20 deletions(-) diff --git a/basic/enricher/README.md b/basic/enricher/README.md index e862836c..e03919b3 100644 --- a/basic/enricher/README.md +++ b/basic/enricher/README.md @@ -14,19 +14,19 @@ You can run the sample application by either - mvn package - mvn exec:java -This example illustrates the usage of the Content Enricher by covering 2 use-cases. -Once the application is started, you can execute each individual use case by: - +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 - -Each use case will trigger slightly different Spring Integration message flows. For -both flows a **User** object containing only the **username** is passed in through a *Gateway*. - -However the Enrichment is executed differently for each flow: - -* 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. +* 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 diff --git a/basic/enricher/src/main/java/org/springframework/integration/samples/enricher/Main.java b/basic/enricher/src/main/java/org/springframework/integration/samples/enricher/Main.java index 7bc7ea50..92f67e0c 100644 --- a/basic/enricher/src/main/java/org/springframework/integration/samples/enricher/Main.java +++ b/basic/enricher/src/main/java/org/springframework/integration/samples/enricher/Main.java @@ -15,6 +15,8 @@ */ package org.springframework.integration.samples.enricher; +import java.util.HashMap; +import java.util.Map; import java.util.Scanner; import org.slf4j.Logger; @@ -73,15 +75,16 @@ public final class Main { + EMPTY_LINE + "\n This example illustrates the usage of the Content Enricher. " + EMPTY_LINE - + "\n Usage: Please enter 1 + Enter or 2 + Enter " + + "\n Usage: Please enter 1 or 2 or 3 + Enter " + EMPTY_LINE - + "\n 2 different message flows are triggered. For both flows a " + + "\n 3 different message flows are triggered. For sample 1+2 a " + "\n user object containing only the username is passed in. " - + EMPTY_LINE - + "\n However the Enrichment is executed differently: " + + "\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); @@ -101,6 +104,17 @@ public final class Main { final User fullUser = service.findUserByUsername(user); printUserInformation(fullUser); + } else if ("3".equals(input)) { + + final Map userData = new HashMap(); + userData.put("username", "foo_map"); + + final Map enrichedUserData = service.findUserWithUsernameInMap(userData); + + final User fullUser = (User) enrichedUserData.get("user"); + + printUserInformation(fullUser); + } else { LOGGER.info("\n\n Please enter '1' or '2' :\n\n"); } diff --git a/basic/enricher/src/main/java/org/springframework/integration/samples/enricher/service/UserService.java b/basic/enricher/src/main/java/org/springframework/integration/samples/enricher/service/UserService.java index d26a0c45..3b2cdcac 100644 --- a/basic/enricher/src/main/java/org/springframework/integration/samples/enricher/service/UserService.java +++ b/basic/enricher/src/main/java/org/springframework/integration/samples/enricher/service/UserService.java @@ -15,6 +15,8 @@ */ package org.springframework.integration.samples.enricher.service; +import java.util.Map; + import org.springframework.integration.samples.enricher.User; /** @@ -34,4 +36,11 @@ public interface UserService { */ 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 findUserWithUsernameInMap(Map userdata); + } diff --git a/basic/enricher/src/main/resources/META-INF/spring/integration/spring-integration-context.xml b/basic/enricher/src/main/resources/META-INF/spring/integration/spring-integration-context.xml index 8c55e18f..b9b57f57 100644 --- a/basic/enricher/src/main/resources/META-INF/spring/integration/spring-integration-context.xml +++ b/basic/enricher/src/main/resources/META-INF/spring/integration/spring-integration-context.xml @@ -7,9 +7,7 @@ - - - + @@ -20,8 +18,9 @@ - - + + + + + + Date: Tue, 8 Nov 2011 09:04:35 -0500 Subject: [PATCH 07/15] fixed breakage --- .../org/springframework/integration/samples/cafe/Cafe.java | 2 +- .../spring/integration/amqp/cafeDemo-amqp-operations-xml.xml | 4 ++-- .../META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Cafe.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Cafe.java index fecbce4d..66363ca8 100644 --- a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Cafe.java +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Cafe.java @@ -30,7 +30,7 @@ import org.springframework.integration.annotation.Gateway; */ public interface Cafe { - @Gateway(requestChannel="preOrders") + @Gateway(requestChannel="orders") void placeOrder(Order order); } diff --git a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-operations-xml.xml b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-operations-xml.xml index d8bbcbc8..535bb351 100644 --- a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-operations-xml.xml +++ b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-operations-xml.xml @@ -27,9 +27,9 @@ - + - + diff --git a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml index b4c8feef..fd000aa7 100644 --- a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml +++ b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml @@ -25,9 +25,9 @@ - + - + From 5e13691d2d59e908abc51ae1b59aa370def7c2a7 Mon Sep 17 00:00:00 2001 From: Tom McCuch Date: Tue, 8 Nov 2011 09:27:17 -0500 Subject: [PATCH 08/15] updated readme --- applications/cafe/readme.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/applications/cafe/readme.txt b/applications/cafe/readme.txt index a0c3f488..baee0e61 100644 --- a/applications/cafe/readme.txt +++ b/applications/cafe/readme.txt @@ -37,8 +37,8 @@ Instructions for running the CafeDemo sample 1. cafeDemoAppBaristaColdAmqp - starts the Cold Drink Barista 2. cafeDemoAppBaristaHotAmqp- starts the Hot Drink Barista - 3. cafeDemoAppOperationsAmqp - starts the Cafe Operations (OrderSplitter, DrinkRouter, PreparedDrinkAggregator) - 4. cafeDemoAppAmqp - starts the Cafe Storefront (Places 100 orders on the orders queue) + 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. From 6afbf69cf0b40b346ba52a1ae79ca7cc477f196c Mon Sep 17 00:00:00 2001 From: Gunnar Hillert Date: Mon, 14 Nov 2011 13:35:37 -0500 Subject: [PATCH 09/15] INTSAMPLES-35 - Stored Procedure Sample for Derby For reference see: https://jira.springsource.org/browse/INTSAMPLES-35 --- .gitignore | 1 + README.md | 2 + intermediate/pom.xml | 1 + .../stored-procedures-derby/README.md | 30 ++++ intermediate/stored-procedures-derby/pom.xml | 122 ++++++++++++++++ .../org/springframework/integration/Main.java | 107 ++++++++++++++ .../derby/DerbyStoredProcedures.java | 71 ++++++++++ .../integration/model/CoffeeBeverage.java | 131 ++++++++++++++++++ .../integration/service/CoffeeService.java | 48 +++++++ .../support/CoffeBeverageMapper.java | 33 +++++ .../spring-integration-context.xml | 41 ++++++ .../resources/derby-stored-procedures.sql | 14 ++ .../src/main/resources/logback.xml | 24 ++++ .../integration/CoffeeServiceFindAllTest.java | 48 +++++++ .../CoffeeServiceFindCoffeeTest.java | 45 ++++++ .../integration/CoffeeServiceStartupTest.java | 36 +++++ 16 files changed, 754 insertions(+) create mode 100644 intermediate/stored-procedures-derby/README.md create mode 100644 intermediate/stored-procedures-derby/pom.xml create mode 100644 intermediate/stored-procedures-derby/src/main/java/org/springframework/integration/Main.java create mode 100644 intermediate/stored-procedures-derby/src/main/java/org/springframework/integration/jdbc/storedproc/derby/DerbyStoredProcedures.java create mode 100644 intermediate/stored-procedures-derby/src/main/java/org/springframework/integration/model/CoffeeBeverage.java create mode 100644 intermediate/stored-procedures-derby/src/main/java/org/springframework/integration/service/CoffeeService.java create mode 100644 intermediate/stored-procedures-derby/src/main/java/org/springframework/integration/support/CoffeBeverageMapper.java create mode 100644 intermediate/stored-procedures-derby/src/main/resources/META-INF/spring/integration/spring-integration-context.xml create mode 100644 intermediate/stored-procedures-derby/src/main/resources/derby-stored-procedures.sql create mode 100644 intermediate/stored-procedures-derby/src/main/resources/logback.xml create mode 100644 intermediate/stored-procedures-derby/src/test/java/org/springframework/integration/CoffeeServiceFindAllTest.java create mode 100644 intermediate/stored-procedures-derby/src/test/java/org/springframework/integration/CoffeeServiceFindCoffeeTest.java create mode 100644 intermediate/stored-procedures-derby/src/test/java/org/springframework/integration/CoffeeServiceStartupTest.java diff --git a/.gitignore b/.gitignore index fe5e0208..8a0da337 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ log.roo *.iml *.ipr *.iws +derby.log diff --git a/README.md b/README.md index 81c293db..2283550e 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/intermediate/pom.xml b/intermediate/pom.xml index 216a102e..400acb90 100644 --- a/intermediate/pom.xml +++ b/intermediate/pom.xml @@ -15,6 +15,7 @@ file-processing multipart-http travel + stored-procedures-derby diff --git a/intermediate/stored-procedures-derby/README.md b/intermediate/stored-procedures-derby/README.md new file mode 100644 index 00000000..b7e17953 --- /dev/null +++ b/intermediate/stored-procedures-derby/README.md @@ -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 + diff --git a/intermediate/stored-procedures-derby/pom.xml b/intermediate/stored-procedures-derby/pom.xml new file mode 100644 index 00000000..73565810 --- /dev/null +++ b/intermediate/stored-procedures-derby/pom.xml @@ -0,0 +1,122 @@ + + 4.0.0 + + org.springframework.integration.samples + derby-stored-procedures + 1.0-SNAPSHOT + jar + + stored-procedures-derby + http://www.springsource.org/spring-integration + + + UTF-8 + 2.1.0.BUILD-SNAPSHOT + 1.6.1 + 4.7 + + + + + repository.springframework.maven.release + Spring Framework Maven Release Repository + http://maven.springframework.org/release + + + + + + + maven-eclipse-plugin + 2.8 + + + org.springframework.ide.eclipse.core.springnature + + + org.springframework.ide.eclipse.core.springbuilder + + true + true + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + -Xlint:all + true + true + + + + org.codehaus.mojo + exec-maven-plugin + 1.2 + + org.springframework.integration.Main + + + + + + + + + + + junit + junit + ${junit.version} + test + + + + + + org.springframework.integration + spring-integration-core + ${spring.integration.version} + + + + org.springframework.integration + spring-integration-jdbc + ${spring.integration.version} + + + + + + ch.qos.logback + logback-classic + 0.9.28 + + + org.slf4j + slf4j-api + ${slf4j.version} + + + org.slf4j + log4j-over-slf4j + ${slf4j.version} + + + org.slf4j + jcl-over-slf4j + ${slf4j.version} + + + + org.apache.derby + derby + 10.8.2.2 + + + + diff --git a/intermediate/stored-procedures-derby/src/main/java/org/springframework/integration/Main.java b/intermediate/stored-procedures-derby/src/main/java/org/springframework/integration/Main.java new file mode 100644 index 00000000..e206d857 --- /dev/null +++ b/intermediate/stored-procedures-derby/src/main/java/org/springframework/integration/Main.java @@ -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 to get a list of coffees."); + System.out.print("Enter a coffee id, e.g. '1' and press to get a description.\n\n"); + + while (!scanner.hasNext("q")) { + + String input = scanner.nextLine(); + + if ("list".equalsIgnoreCase(input)) { + List 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 :\n\n"); + } + + } + + LOGGER.info("Exiting application...bye."); + + System.exit(0); + + } +} diff --git a/intermediate/stored-procedures-derby/src/main/java/org/springframework/integration/jdbc/storedproc/derby/DerbyStoredProcedures.java b/intermediate/stored-procedures-derby/src/main/java/org/springframework/integration/jdbc/storedproc/derby/DerbyStoredProcedures.java new file mode 100644 index 00000000..f44180d3 --- /dev/null +++ b/intermediate/stored-procedures-derby/src/main/java/org/springframework/integration/jdbc/storedproc/derby/DerbyStoredProcedures.java @@ -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(); + + } +} diff --git a/intermediate/stored-procedures-derby/src/main/java/org/springframework/integration/model/CoffeeBeverage.java b/intermediate/stored-procedures-derby/src/main/java/org/springframework/integration/model/CoffeeBeverage.java new file mode 100644 index 00000000..74440472 --- /dev/null +++ b/intermediate/stored-procedures-derby/src/main/java/org/springframework/integration/model/CoffeeBeverage.java @@ -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(); + } + +} diff --git a/intermediate/stored-procedures-derby/src/main/java/org/springframework/integration/service/CoffeeService.java b/intermediate/stored-procedures-derby/src/main/java/org/springframework/integration/service/CoffeeService.java new file mode 100644 index 00000000..efbb978b --- /dev/null +++ b/intermediate/stored-procedures-derby/src/main/java/org/springframework/integration/service/CoffeeService.java @@ -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 findAllCoffeeBeverages(); + +} diff --git a/intermediate/stored-procedures-derby/src/main/java/org/springframework/integration/support/CoffeBeverageMapper.java b/intermediate/stored-procedures-derby/src/main/java/org/springframework/integration/support/CoffeBeverageMapper.java new file mode 100644 index 00000000..582d5559 --- /dev/null +++ b/intermediate/stored-procedures-derby/src/main/java/org/springframework/integration/support/CoffeBeverageMapper.java @@ -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 { + + public CoffeeBeverage mapRow(ResultSet rs, int rowNum) throws SQLException { + return new CoffeeBeverage(rs.getInt("ID"), rs.getString("COFFEE_NAME"), rs.getString("COFFEE_DESCRIPTION")); + } + +} diff --git a/intermediate/stored-procedures-derby/src/main/resources/META-INF/spring/integration/spring-integration-context.xml b/intermediate/stored-procedures-derby/src/main/resources/META-INF/spring/integration/spring-integration-context.xml new file mode 100644 index 00000000..cc7ffcf6 --- /dev/null +++ b/intermediate/stored-procedures-derby/src/main/resources/META-INF/spring/integration/spring-integration-context.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/intermediate/stored-procedures-derby/src/main/resources/derby-stored-procedures.sql b/intermediate/stored-procedures-derby/src/main/resources/derby-stored-procedures.sql new file mode 100644 index 00000000..f9232408 --- /dev/null +++ b/intermediate/stored-procedures-derby/src/main/resources/derby-stored-procedures.sql @@ -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'; + diff --git a/intermediate/stored-procedures-derby/src/main/resources/logback.xml b/intermediate/stored-procedures-derby/src/main/resources/logback.xml new file mode 100644 index 00000000..eee6b966 --- /dev/null +++ b/intermediate/stored-procedures-derby/src/main/resources/logback.xml @@ -0,0 +1,24 @@ + + + + + + + %d %5p | %t | %-55logger{55} | %m %n + + + + + + + + + + + + + + + + + diff --git a/intermediate/stored-procedures-derby/src/test/java/org/springframework/integration/CoffeeServiceFindAllTest.java b/intermediate/stored-procedures-derby/src/test/java/org/springframework/integration/CoffeeServiceFindAllTest.java new file mode 100644 index 00000000..4ed29597 --- /dev/null +++ b/intermediate/stored-procedures-derby/src/test/java/org/springframework/integration/CoffeeServiceFindAllTest.java @@ -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 coffeeBeverages = service.findAllCoffeeBeverages(); + + assertTrue(coffeeBeverages.size() == 4); + + } + +} diff --git a/intermediate/stored-procedures-derby/src/test/java/org/springframework/integration/CoffeeServiceFindCoffeeTest.java b/intermediate/stored-procedures-derby/src/test/java/org/springframework/integration/CoffeeServiceFindCoffeeTest.java new file mode 100644 index 00000000..b3a116cc --- /dev/null +++ b/intermediate/stored-procedures-derby/src/test/java/org/springframework/integration/CoffeeServiceFindCoffeeTest.java @@ -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); + + } + +} diff --git a/intermediate/stored-procedures-derby/src/test/java/org/springframework/integration/CoffeeServiceStartupTest.java b/intermediate/stored-procedures-derby/src/test/java/org/springframework/integration/CoffeeServiceStartupTest.java new file mode 100644 index 00000000..1db43575 --- /dev/null +++ b/intermediate/stored-procedures-derby/src/test/java/org/springframework/integration/CoffeeServiceStartupTest.java @@ -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); + } + +} From 3db74937466d565b1f2e6be0341a041c3a955cd1 Mon Sep 17 00:00:00 2001 From: Joe Freeman Date: Wed, 16 Nov 2011 06:26:02 -0500 Subject: [PATCH 10/15] added comments --- .../integration/samples/cafe/Order.java | 1 + .../integration/samples/cafe/OrderItem.java | 1 + .../amqp/cafeDemo-amqp-baristaCold-xml.xml | 1 + .../integration/amqp/cafeDemo-amqp-baristaHot-xml.xml | 1 + .../integration/amqp/cafeDemo-amqp-config-xml.xml | 11 ++++++++++- .../integration/amqp/cafeDemo-amqp-operations-xml.xml | 7 ++++++- .../spring/integration/amqp/cafeDemo-amqp-xml.xml | 1 + .../META-INF/spring/integration/cafeDemo-xml.xml | 5 +++++ 8 files changed, 26 insertions(+), 2 deletions(-) diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Order.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Order.java index 448d7186..6f836a82 100644 --- a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Order.java +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/Order.java @@ -28,6 +28,7 @@ public class Order { private List orderItems = new ArrayList(); + /** the order number used for tracking */ private int number; // Default constructor required by Jackson Java JSON-processor diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java index d256bd81..c3e0a2b0 100644 --- a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java @@ -29,6 +29,7 @@ public class OrderItem { private boolean iced = false; + /** the order this item is tied to */ private int orderNumber; // Default constructor required by Jackson Java JSON-processor diff --git a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml index 517fd70f..1f9fc98f 100644 --- a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml +++ b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml @@ -23,6 +23,7 @@ + + + + + + - + + + diff --git a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-operations-xml.xml b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-operations-xml.xml index 535bb351..6235a8e6 100644 --- a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-operations-xml.xml +++ b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-operations-xml.xml @@ -22,9 +22,11 @@ + + @@ -49,7 +51,8 @@ - + + + + + + + + + + From 32e38d09d2848f0692efa7d3fac8da84cf56deaf Mon Sep 17 00:00:00 2001 From: Joe Freeman Date: Wed, 16 Nov 2011 13:07:22 -0500 Subject: [PATCH 11/15] converted to spring 3.1 to support profiles --- applications/cafe/pom.xml | 11 +++++ .../samples/cafe/xml/CafeDemoAppAmqp.java | 23 ++++++--- .../cafe/xml/CafeDemoAppBaristaColdAmqp.java | 4 +- .../cafe/xml/CafeDemoAppBaristaHotAmqp.java | 4 +- .../cafe/xml/CafeDemoAppOperationsAmqp.java | 4 +- .../cafe/xml/CafeDemoAppUtilities.java | 36 ++++++++++++++ .../amqp/cafeDemo-amqp-config-xml.xml | 47 +++++++++++-------- 7 files changed, 96 insertions(+), 33 deletions(-) create mode 100644 applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppUtilities.java diff --git a/applications/cafe/pom.xml b/applications/cafe/pom.xml index b0483d22..a823958b 100644 --- a/applications/cafe/pom.xml +++ b/applications/cafe/pom.xml @@ -8,10 +8,21 @@ Spring Integration Cafe Sample 2.1.0.M3 + 3.1.0.RC1 1.2.16 4.7 + + org.springframework + spring-tx + ${spring.core.version} + + + org.springframework + spring-context + ${spring.core.version} + org.springframework.integration spring-integration-amqp diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppAmqp.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppAmqp.java index db802315..4d259852 100644 --- a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppAmqp.java +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppAmqp.java @@ -38,12 +38,14 @@ import org.springframework.integration.samples.cafe.Order; * * @author Tom McCuch */ -public class CafeDemoAppAmqp { - - public static void main(String[] args) { - AbstractApplicationContext context = - new ClassPathXmlApplicationContext("/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml", CafeDemoAppAmqp.class); - +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); @@ -51,7 +53,14 @@ public class CafeDemoAppAmqp { 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(); } } diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaColdAmqp.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaColdAmqp.java index bde92220..2fa94d32 100644 --- a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaColdAmqp.java +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaColdAmqp.java @@ -44,9 +44,9 @@ public class CafeDemoAppBaristaColdAmqp { public static void main(String[] args) { AbstractApplicationContext context = - new ClassPathXmlApplicationContext( + CafeDemoAppUtilities.loadProfileContext( "/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml", - CafeDemoAppBaristaColdAmqp.class); + CafeDemoAppBaristaColdAmqp.class,CafeDemoAppUtilities.DEV); System.out.println("Press Enter/Return in the console to exit the Barista Cold App"); try { diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaHotAmqp.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaHotAmqp.java index 0f0d8d9c..0d37cad6 100644 --- a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaHotAmqp.java +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppBaristaHotAmqp.java @@ -44,9 +44,9 @@ public class CafeDemoAppBaristaHotAmqp { public static void main(String[] args) { AbstractApplicationContext context = - new ClassPathXmlApplicationContext( + CafeDemoAppUtilities.loadProfileContext( "/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaHot-xml.xml", - CafeDemoAppBaristaHotAmqp.class); + CafeDemoAppBaristaHotAmqp.class,CafeDemoAppUtilities.DEV); System.out.println("Press Enter/Return in the console to exit the Barista Hot App"); try { diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppOperationsAmqp.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppOperationsAmqp.java index ec894dc8..f2246647 100644 --- a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppOperationsAmqp.java +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppOperationsAmqp.java @@ -50,9 +50,9 @@ public class CafeDemoAppOperationsAmqp { public static void main(String[] args) { AbstractApplicationContext context = - new ClassPathXmlApplicationContext( + CafeDemoAppUtilities.loadProfileContext( "/META-INF/spring/integration/amqp/cafeDemo-amqp-operations-xml.xml", - CafeDemoAppOperationsAmqp.class); + CafeDemoAppOperationsAmqp.class,CafeDemoAppUtilities.DEV); System.out.println("Press Enter/Return in the console to exit the Cafe Operations App"); try { diff --git a/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppUtilities.java b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppUtilities.java new file mode 100644 index 00000000..6eac278f --- /dev/null +++ b/applications/cafe/src/main/java/org/springframework/integration/samples/cafe/xml/CafeDemoAppUtilities.java @@ -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; + } + + + + +} diff --git a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-config-xml.xml b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-config-xml.xml index cd82b341..3ac623d0 100644 --- a/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-config-xml.xml +++ b/applications/cafe/src/main/resources/META-INF/spring/integration/amqp/cafeDemo-amqp-config-xml.xml @@ -1,32 +1,39 @@ - - - - - - - - - - - + - - + + + + + + + + + + + + + + + + + + From 5134d44073a8fb98071a79e44a01c15b815ef7b8 Mon Sep 17 00:00:00 2001 From: David Turanski Date: Tue, 29 Nov 2011 16:51:19 -0500 Subject: [PATCH 12/15] updated readme.txt --- applications/cafe-scripted/.gitignore | 5 + applications/cafe-scripted/error.out | 0 applications/cafe-scripted/pom.xml | 212 ++++++++++++++++++ applications/cafe-scripted/readme.txt | 50 +++++ .../scripts/groovy/barista.groovy | 19 ++ .../scripts/javascript/barista.js | 13 ++ .../cafe-scripted/scripts/python/barista.py | 11 + .../cafe-scripted/scripts/ruby/barista.rb | 15 ++ .../integration/samples/cafe/Customer.java | 27 +++ .../integration/samples/cafe/Delivery.java | 61 +++++ .../integration/samples/cafe/Drink.java | 50 +++++ .../integration/samples/cafe/DrinkType.java | 29 +++ .../integration/samples/cafe/Order.java | 52 +++++ .../integration/samples/cafe/OrderItem.java | 62 +++++ .../integration/samples/cafe/Waiter.java | 46 ++++ .../samples/cafe/WaiterMonitor.java | 22 ++ .../samples/cafe/demo/CafeDemoApp.java | 77 +++++++ .../samples/cafe/demo/ControlBusMain.java | 64 ++++++ .../integration/cafeDemo-control-bus.xml | 30 +++ .../spring/integration/cafeDemo-groovy.xml | 33 +++ .../integration/cafeDemo-javascript.xml | 32 +++ .../spring/integration/cafeDemo-python.xml | 36 +++ .../spring/integration/cafeDemo-ruby.xml | 37 +++ .../META-INF/spring/integration/cafeDemo.xml | 83 +++++++ .../src/main/resources/log4j.xml | 36 +++ .../integration/samples/cafe/ScriptTests.java | 63 ++++++ 26 files changed, 1165 insertions(+) create mode 100644 applications/cafe-scripted/.gitignore create mode 100644 applications/cafe-scripted/error.out create mode 100644 applications/cafe-scripted/pom.xml create mode 100644 applications/cafe-scripted/readme.txt create mode 100644 applications/cafe-scripted/scripts/groovy/barista.groovy create mode 100644 applications/cafe-scripted/scripts/javascript/barista.js create mode 100644 applications/cafe-scripted/scripts/python/barista.py create mode 100644 applications/cafe-scripted/scripts/ruby/barista.rb create mode 100644 applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Customer.java create mode 100644 applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Delivery.java create mode 100644 applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Drink.java create mode 100644 applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java create mode 100644 applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Order.java create mode 100644 applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java create mode 100644 applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Waiter.java create mode 100644 applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/WaiterMonitor.java create mode 100644 applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/CafeDemoApp.java create mode 100644 applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/ControlBusMain.java create mode 100644 applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-control-bus.xml create mode 100644 applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-groovy.xml create mode 100644 applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-javascript.xml create mode 100644 applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-python.xml create mode 100644 applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-ruby.xml create mode 100644 applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo.xml create mode 100644 applications/cafe-scripted/src/main/resources/log4j.xml create mode 100644 applications/cafe-scripted/src/test/java/org/springframework/integration/samples/cafe/ScriptTests.java diff --git a/applications/cafe-scripted/.gitignore b/applications/cafe-scripted/.gitignore new file mode 100644 index 00000000..c2f82a3b --- /dev/null +++ b/applications/cafe-scripted/.gitignore @@ -0,0 +1,5 @@ +/target +.classpath +.project +.springBeans +.settings diff --git a/applications/cafe-scripted/error.out b/applications/cafe-scripted/error.out new file mode 100644 index 00000000..e69de29b diff --git a/applications/cafe-scripted/pom.xml b/applications/cafe-scripted/pom.xml new file mode 100644 index 00000000..011dcee9 --- /dev/null +++ b/applications/cafe-scripted/pom.xml @@ -0,0 +1,212 @@ + + + 4.0.0 + org.springframework.integration.samples + cafe-scripted + 2.1.0 + Spring Integration Cafe Sample + + 2.1.0.RC1 + 3.1.0.RC1 + 1.2.16 + 4.7 + + + + + org.springframework + spring-core + ${spring.version} + + + + org.springframework + spring-test + ${spring.version} + test + + + + org.springframework + spring-context + ${spring.version} + + + + org.springframework + spring-context-support + ${spring.version} + + + + org.springframework.integration + spring-integration-core + ${spring.integration.version} + + + + org.springframework.integration + spring-integration-stream + ${spring.integration.version} + + + + org.springframework.integration + spring-integration-groovy + ${spring.integration.version} + + + org.springframework.integration + spring-integration-rmi + ${spring.integration.version} + + + org.springframework.integration + spring-integration-jmx + ${spring.integration.version} + + + + org.springframework.integration + spring-integration-scripting + ${spring.integration.version} + + + + log4j + log4j + ${log4j.version} + + + + junit + junit + ${junit.version} + + + + + + org.jruby + jruby + 1.5.6 + + + + org.python + jython-standalone + 2.5.2 + + + + org.codehaus.groovy + groovy-all + 1.7.5 + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.2 + + 1.5 + 1.6 + -Xlint:all + true + false + + + + + + + + + true + + demo + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + + exec + + + + + java + + -classpath + + org.springframework.integration.samples.cafe.demo.CafeDemoApp + ${lang} + + + 0 + + + + + + + + control-bus + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + + + exec + + + + + java + + -classpath + + org.springframework.integration.samples.cafe.demo.ControlBusMain + + + + 0 + + + + + + + + + + repository.springframework.maven.release + Spring Framework Maven Release Repository + http://maven.springframework.org/release + + + repository.springframework.maven.milestone + Spring Framework Maven Milestone Repository + http://maven.springframework.org/milestone + + + repository.springframework.maven.snapshot + Spring Framework Maven Snapshot Repository + http://maven.springframework.org/snapshot + + + diff --git a/applications/cafe-scripted/readme.txt b/applications/cafe-scripted/readme.txt new file mode 100644 index 00000000..2bd00e6a --- /dev/null +++ b/applications/cafe-scripted/readme.txt @@ -0,0 +1,50 @@ +This is the scripted implementation of the standard 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] + +This sample also demonstrates the use of Spring Integration's groovy control bus which enables +control bus messages to be Groovy scripts which may invoke operations on application components. + +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. + +The Cafe sample emulates a simple operation of the Coffee shop shop when modeled using EIP +It is inspired by one of the samples featured in Gregor Hohpe's Ramblings. +The domain is that of a Cafe, and the basic flow is depicted in the following diagram: + + + Barista (scripted) + hotDrinks _______________________ + |==========| -->| | + orders drinks / | prepareDrink() | +Place Order ->Customer->|======|->OrderSplitter->|======|->DrinkRouter | timeToPrepare=5 sec | + (scripted) (scripted) \ coldDrinks | prepareDrink() | + |==========| -->| timeToPrepare=1 sec | + |_______________________| + + Legend: |====| - channels + + +The Order object may contain multiple OrderItems. Once the order is placed, a Splitter will break the +composite order message into a single message per drink. Each of these is then processed by a Router that +determines whether the drink is hot or cold (checking the OrderItem object's 'isIced' property). The Barista +prepares each drink. Hot and cold drink preparation are handled by two distinct script invocations of +'prepareDrink', each with different variable assignments. + +The prepared drinks are then sent to the Waiter where they are aggregated into a Delivery object. + + +Happy integration :-) \ No newline at end of file diff --git a/applications/cafe-scripted/scripts/groovy/barista.groovy b/applications/cafe-scripted/scripts/groovy/barista.groovy new file mode 100644 index 00000000..cf5da34f --- /dev/null +++ b/applications/cafe-scripted/scripts/groovy/barista.groovy @@ -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) + + + + \ No newline at end of file diff --git a/applications/cafe-scripted/scripts/javascript/barista.js b/applications/cafe-scripted/scripts/javascript/barista.js new file mode 100644 index 00000000..3f1effe7 --- /dev/null +++ b/applications/cafe-scripted/scripts/javascript/barista.js @@ -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); + diff --git a/applications/cafe-scripted/scripts/python/barista.py b/applications/cafe-scripted/scripts/python/barista.py new file mode 100644 index 00000000..fef0b2f3 --- /dev/null +++ b/applications/cafe-scripted/scripts/python/barista.py @@ -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) + \ No newline at end of file diff --git a/applications/cafe-scripted/scripts/ruby/barista.rb b/applications/cafe-scripted/scripts/ruby/barista.rb new file mode 100644 index 00000000..6e235b9f --- /dev/null +++ b/applications/cafe-scripted/scripts/ruby/barista.rb @@ -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()) + + + \ No newline at end of file diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Customer.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Customer.java new file mode 100644 index 00000000..fa48aa75 --- /dev/null +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Customer.java @@ -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; + } +} diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Delivery.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Delivery.java new file mode 100644 index 00000000..a59fbd43 --- /dev/null +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Delivery.java @@ -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 deliveredDrinks; + + private int orderNumber; + + + public Delivery(List deliveredDrinks) { + assert(deliveredDrinks.size() > 0); + this.deliveredDrinks = deliveredDrinks; + this.orderNumber = deliveredDrinks.get(0).getOrderNumber(); + } + + + public int getOrderNumber() { + return orderNumber; + } + + public List 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(); + } + +} diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Drink.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Drink.java new file mode 100644 index 00000000..504a8658 --- /dev/null +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Drink.java @@ -0,0 +1,50 @@ +/* + * 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; + +/** + * @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."; + } + +} diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java new file mode 100644 index 00000000..7e438db4 --- /dev/null +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java @@ -0,0 +1,29 @@ +/* + * 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; + +/** + * @author Mark Fisher + */ +public enum DrinkType { + + ESPRESSO, + LATTE, + CAPPUCCINO, + MOCHA + +} diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Order.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Order.java new file mode 100644 index 00000000..3174ee99 --- /dev/null +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Order.java @@ -0,0 +1,52 @@ +/* + * 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.ArrayList; +import java.util.List; + +/** + * @author Mark Fisher + * @author Marius Bogoevici + */ +public class Order { + + private List orderItems = new ArrayList(); + + 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 getItems() { + return this.orderItems; + } + + public String toString() { + return "Order number " + number; + } + +} diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java new file mode 100644 index 00000000..928cfed6 --- /dev/null +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java @@ -0,0 +1,62 @@ +/* + * 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; + +/** + * @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; + } + +} diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Waiter.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Waiter.java new file mode 100644 index 00000000..fac1e6ae --- /dev/null +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Waiter.java @@ -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 drinks) { + totalDeliveries.getAndIncrement(); + return new Delivery(drinks); + } + + @ManagedOperation + public int getTotalDeliveries() { + return this.totalDeliveries.get(); + } + +} diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/WaiterMonitor.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/WaiterMonitor.java new file mode 100644 index 00000000..c71dfaad --- /dev/null +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/WaiterMonitor.java @@ -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); +} diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/CafeDemoApp.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/CafeDemoApp.java new file mode 100644 index 00000000..2c3d357f --- /dev/null +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/CafeDemoApp.java @@ -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.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 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); + } +} diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/ControlBusMain.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/ControlBusMain.java new file mode 100644 index 00000000..95c7cec0 --- /dev/null +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/ControlBusMain.java @@ -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); + } + +} diff --git a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-control-bus.xml b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-control-bus.xml new file mode 100644 index 00000000..67764eb7 --- /dev/null +++ b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-control-bus.xml @@ -0,0 +1,30 @@ + + + + + This is the application context for ControlBusMain. It configures a Gateway tied to an RMI outbound gateway to communicate + remotely with the CafeDemoApp. + + + + + + + + + + diff --git a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-groovy.xml b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-groovy.xml new file mode 100644 index 00000000..84f26e1c --- /dev/null +++ b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-groovy.xml @@ -0,0 +1,33 @@ + + + + + payload.items + + + + payload.iced ? "coldDrinks" : "hotDrinks" + + + + + + + + + + + + + + + + diff --git a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-javascript.xml b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-javascript.xml new file mode 100644 index 00000000..3c8245f4 --- /dev/null +++ b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-javascript.xml @@ -0,0 +1,32 @@ + + + + + payload.items; + + + + payload.iced ? "coldDrinks" : "hotDrinks"; + + + + + + + + + + + + + + + diff --git a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-python.xml b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-python.xml new file mode 100644 index 00000000..dfaa92e4 --- /dev/null +++ b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-python.xml @@ -0,0 +1,36 @@ + + + + + + items=payload.items + + + + 'coldDrinks' if payload.iced else 'hotDrinks' + + + + + + + + + + + + + + + + diff --git a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-ruby.xml b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-ruby.xml new file mode 100644 index 00000000..4c1922a7 --- /dev/null +++ b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo-ruby.xml @@ -0,0 +1,37 @@ + + + + + + payload.items + + + + + payload.iced ? "coldDrinks": "hotDrinks" + + + + + + + + + + + + + + + + diff --git a/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo.xml b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo.xml new file mode 100644 index 00000000..78ba9e2c --- /dev/null +++ b/applications/cafe-scripted/src/main/resources/META-INF/spring/integration/cafeDemo.xml @@ -0,0 +1,83 @@ + + + + + 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. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/cafe-scripted/src/main/resources/log4j.xml b/applications/cafe-scripted/src/main/resources/log4j.xml new file mode 100644 index 00000000..fd99f56c --- /dev/null +++ b/applications/cafe-scripted/src/main/resources/log4j.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/applications/cafe-scripted/src/test/java/org/springframework/integration/samples/cafe/ScriptTests.java b/applications/cafe-scripted/src/test/java/org/springframework/integration/samples/cafe/ScriptTests.java new file mode 100644 index 00000000..e616d3b9 --- /dev/null +++ b/applications/cafe-scripted/src/test/java/org/springframework/integration/samples/cafe/ScriptTests.java @@ -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 variables = new HashMap(); + 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 variables = new HashMap(); + 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); + + } +} From b686a8f0d97ca94463111de4e42f43ea09b75aa5 Mon Sep 17 00:00:00 2001 From: David Turanski Date: Sat, 3 Dec 2011 08:05:32 -0500 Subject: [PATCH 13/15] updated README --- applications/cafe-scripted/README.md | 27 +++++++++++++++ applications/cafe-scripted/error.out | 0 applications/cafe-scripted/readme.txt | 50 --------------------------- 3 files changed, 27 insertions(+), 50 deletions(-) create mode 100644 applications/cafe-scripted/README.md delete mode 100644 applications/cafe-scripted/error.out delete mode 100644 applications/cafe-scripted/readme.txt diff --git a/applications/cafe-scripted/README.md b/applications/cafe-scripted/README.md new file mode 100644 index 00000000..53119680 --- /dev/null +++ b/applications/cafe-scripted/README.md @@ -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. diff --git a/applications/cafe-scripted/error.out b/applications/cafe-scripted/error.out deleted file mode 100644 index e69de29b..00000000 diff --git a/applications/cafe-scripted/readme.txt b/applications/cafe-scripted/readme.txt deleted file mode 100644 index 2bd00e6a..00000000 --- a/applications/cafe-scripted/readme.txt +++ /dev/null @@ -1,50 +0,0 @@ -This is the scripted implementation of the standard 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] - -This sample also demonstrates the use of Spring Integration's groovy control bus which enables -control bus messages to be Groovy scripts which may invoke operations on application components. - -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. - -The Cafe sample emulates a simple operation of the Coffee shop shop when modeled using EIP -It is inspired by one of the samples featured in Gregor Hohpe's Ramblings. -The domain is that of a Cafe, and the basic flow is depicted in the following diagram: - - - Barista (scripted) - hotDrinks _______________________ - |==========| -->| | - orders drinks / | prepareDrink() | -Place Order ->Customer->|======|->OrderSplitter->|======|->DrinkRouter | timeToPrepare=5 sec | - (scripted) (scripted) \ coldDrinks | prepareDrink() | - |==========| -->| timeToPrepare=1 sec | - |_______________________| - - Legend: |====| - channels - - -The Order object may contain multiple OrderItems. Once the order is placed, a Splitter will break the -composite order message into a single message per drink. Each of these is then processed by a Router that -determines whether the drink is hot or cold (checking the OrderItem object's 'isIced' property). The Barista -prepares each drink. Hot and cold drink preparation are handled by two distinct script invocations of -'prepareDrink', each with different variable assignments. - -The prepared drinks are then sent to the Waiter where they are aggregated into a Delivery object. - - -Happy integration :-) \ No newline at end of file From 4a9d7ab1359e6c072211d10ac7c25124d07a85d9 Mon Sep 17 00:00:00 2001 From: David Turanski Date: Sat, 3 Dec 2011 08:16:02 -0500 Subject: [PATCH 14/15] updated copyright notices --- .../org/springframework/integration/samples/cafe/Drink.java | 2 +- .../org/springframework/integration/samples/cafe/DrinkType.java | 2 +- .../org/springframework/integration/samples/cafe/Order.java | 2 +- .../org/springframework/integration/samples/cafe/OrderItem.java | 2 +- .../integration/samples/cafe/demo/CafeDemoApp.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Drink.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Drink.java index 504a8658..a8e445ee 100644 --- a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Drink.java +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Drink.java @@ -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. diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java index 7e438db4..4944ca4c 100644 --- a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/DrinkType.java @@ -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. diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Order.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Order.java index 3174ee99..eb2d7e75 100644 --- a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Order.java +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/Order.java @@ -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. diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java index 928cfed6..07c5e9a4 100644 --- a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/OrderItem.java @@ -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. diff --git a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/CafeDemoApp.java b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/CafeDemoApp.java index 2c3d357f..adcab88b 100644 --- a/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/CafeDemoApp.java +++ b/applications/cafe-scripted/src/main/java/org/springframework/integration/samples/cafe/demo/CafeDemoApp.java @@ -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. From 67606fa2dbb303d5ac001f8bd523815b0efe0397 Mon Sep 17 00:00:00 2001 From: Gary Russell Date: Sat, 10 Dec 2011 11:45:57 -0500 Subject: [PATCH 15/15] INTSAMPLES-37 Add ConversionService to TCP Sample Show alternative configuration for converting from tcp byte arrays to Strings. --- basic/tcp-client-server/readme.txt | 4 + .../ByteArrayToStringConverter.java | 57 +++++++++++++++ ...tcpClientServerDemo-conversion-context.xml | 73 +++++++++++++++++++ .../TcpClientServerDemoTest.java | 13 +++- 4 files changed, 144 insertions(+), 3 deletions(-) create mode 100644 basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/ByteArrayToStringConverter.java create mode 100644 basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpClientServerDemo-conversion-context.xml diff --git a/basic/tcp-client-server/readme.txt b/basic/tcp-client-server/readme.txt index 3567dd93..653b1f2c 100644 --- a/basic/tcp-client-server/readme.txt +++ b/basic/tcp-client-server/readme.txt @@ -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'). diff --git a/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/ByteArrayToStringConverter.java b/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/ByteArrayToStringConverter.java new file mode 100644 index 00000000..096b1d7c --- /dev/null +++ b/basic/tcp-client-server/src/main/java/org/springframework/integration/samples/tcpclientserver/ByteArrayToStringConverter.java @@ -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 { + + 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; + } + +} diff --git a/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpClientServerDemo-conversion-context.xml b/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpClientServerDemo-conversion-context.xml new file mode 100644 index 00000000..fd5d0cda --- /dev/null +++ b/basic/tcp-client-server/src/main/resources/META-INF/spring/integration/tcpClientServerDemo-conversion-context.xml @@ -0,0 +1,73 @@ + + + + + This version demonstrates the use of a conversion service and channel 'dataType' + instead of explicit transformers to convert from byte array to String. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpClientServerDemoTest.java b/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpClientServerDemoTest.java index 705a0c97..50c830b4 100644 --- a/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpClientServerDemoTest.java +++ b/basic/tcp-client-server/src/test/java/org/springframework/integration/samples/tcpclientserver/TcpClientServerDemoTest.java @@ -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("");