Merge pull request #14 from spring-tom/master
Added Spring Integration AMQP config to Cafe Sample
This commit is contained in:
@@ -7,14 +7,25 @@
|
||||
<version>2.0.0</version>
|
||||
<name>Spring Integration Cafe Sample</name>
|
||||
<properties>
|
||||
<spring.integration.version>2.0.5.RELEASE</spring.integration.version>
|
||||
<spring.integration.version>2.1.0.M3</spring.integration.version>
|
||||
<spring.core.version>3.1.0.RC1</spring.core.version>
|
||||
<log4j.version>1.2.16</log4j.version>
|
||||
<junit.version>4.7</junit.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
<version>${spring.core.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring.core.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.integration</groupId>
|
||||
<artifactId>spring-integration-core</artifactId>
|
||||
<artifactId>spring-integration-amqp</artifactId>
|
||||
<version>${spring.integration.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -22,6 +33,17 @@
|
||||
<artifactId>spring-integration-stream</artifactId>
|
||||
<version>${spring.integration.version}</version>
|
||||
</dependency>
|
||||
<!-- Jackson JSON Mapper -->
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-core-asl</artifactId>
|
||||
<version>1.8.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.jackson</groupId>
|
||||
<artifactId>jackson-mapper-asl</artifactId>
|
||||
<version>1.8.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
|
||||
@@ -8,7 +8,7 @@ The domain is that of a Cafe, and the basic flow is depicted in the following di
|
||||
|==========| -->| |
|
||||
orders drinks / | prepareHotDrink() |
|
||||
Place Order ->Cafe->|======|->OrderSplitter->|======|->DrinkRouter | |
|
||||
\ coldDeinks | prepareColdDrink() |
|
||||
\ coldDrinks | prepareColdDrink() |
|
||||
|==========| -->| |
|
||||
|____________________|
|
||||
|
||||
@@ -26,11 +26,24 @@ Instructions for running the CafeDemo sample
|
||||
-------------------------------------------------------------------------------
|
||||
1. The example comes with two identical configurations. One is ANNOTATION-based anther is XML-based
|
||||
|
||||
2. To run this sample simply execute the CafeDemo* test classes
|
||||
2. To run this sample simply execute the CafeDemoApp test classes
|
||||
in the org.springframework.integration.samples.cafe.xml or
|
||||
org.springframework.integration.samples.cafe.annotation package.
|
||||
|
||||
3. The example also provides an alternative configuration that uses AMQP channels to distribute the components
|
||||
in the CafeDemo sample. To run this alternative configuration of the sample, be sure to have a RabbitMQ broker
|
||||
started on localhost:5672 configured with the default guest | guest client credentials on the / vHost,
|
||||
then execute the following test classes in order:
|
||||
|
||||
You shoudl see the output similar to this:
|
||||
1. cafeDemoAppBaristaColdAmqp - starts the Cold Drink Barista
|
||||
2. cafeDemoAppBaristaHotAmqp- starts the Hot Drink Barista
|
||||
3. cafeDemoAppAmqp - starts the Cafe Storefront (Places 100 orders on the orders queue)
|
||||
4. cafeDemoAppOperationsAmqp - starts the Cafe Operations (OrderSplitter, DrinkRouter, PreparedDrinkAggregator)
|
||||
|
||||
* Note: All AMQP exchanges, queues, and bindings needed for this sample are defined within the different xml
|
||||
config files that support the above test classes.
|
||||
|
||||
Upon running any of the alternatives, you should see the output similar to this:
|
||||
|
||||
INFO : org.springframework.integration.samples.cafe.annotation.Barista - task-scheduler-1 prepared cold drink #1 for order #1: iced 3 shot MOCHA
|
||||
INFO : org.springframework.integration.samples.cafe.annotation.Barista - task-scheduler-1 prepared cold drink #2 for order #2: iced 3 shot MOCHA
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,16 +20,18 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Tom McCuch
|
||||
*/
|
||||
public class Delivery {
|
||||
|
||||
private static final String SEPARATOR = "-----------------------";
|
||||
|
||||
|
||||
private List<Drink> deliveredDrinks;
|
||||
|
||||
private int orderNumber;
|
||||
|
||||
// Default constructor required by Jackson Java JSON-processor
|
||||
public Delivery() {}
|
||||
|
||||
public Delivery(List<Drink> deliveredDrinks) {
|
||||
assert(deliveredDrinks.size() > 0);
|
||||
@@ -42,10 +44,18 @@ public class Delivery {
|
||||
return orderNumber;
|
||||
}
|
||||
|
||||
public void setOrderNumber(int orderNumber) {
|
||||
this.orderNumber = orderNumber;
|
||||
}
|
||||
|
||||
public List<Drink> getDeliveredDrinks() {
|
||||
return deliveredDrinks;
|
||||
}
|
||||
|
||||
public void setDeliveredDrinks(List<Drink> deliveredDrinks) {
|
||||
this.deliveredDrinks = deliveredDrinks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer(SEPARATOR + "\n");
|
||||
|
||||
@@ -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.";
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,27 +22,39 @@ import java.util.List;
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Marius Bogoevici
|
||||
* @author Tom McCuch
|
||||
*/
|
||||
public class Order {
|
||||
|
||||
private List<OrderItem> orderItems = new ArrayList<OrderItem>();
|
||||
|
||||
/** the order number used for tracking */
|
||||
private int number;
|
||||
|
||||
// Default constructor required by Jackson Java JSON-processor
|
||||
public Order() {}
|
||||
|
||||
public Order(int number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
public void addItem(DrinkType drinkType, int shots, boolean iced) {
|
||||
this.orderItems.add(new OrderItem(this, drinkType, shots, iced));
|
||||
this.orderItems.add(new OrderItem(this.number, drinkType, shots, iced));
|
||||
}
|
||||
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public void setNumber(int number) {
|
||||
this.number = number;
|
||||
}
|
||||
|
||||
public List<OrderItem> getItems() {
|
||||
return this.orderItems;
|
||||
}
|
||||
|
||||
public void setItems(List<OrderItem> orderItems) {
|
||||
this.orderItems = orderItems;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ package org.springframework.integration.samples.cafe;
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Marius Bogoevici
|
||||
* @author Tom McCuch
|
||||
*/
|
||||
public class OrderItem {
|
||||
|
||||
@@ -28,34 +29,52 @@ public class OrderItem {
|
||||
|
||||
private boolean iced = false;
|
||||
|
||||
private final Order order;
|
||||
/** the order this item is tied to */
|
||||
private int orderNumber;
|
||||
|
||||
// Default constructor required by Jackson Java JSON-processor
|
||||
public OrderItem() {}
|
||||
|
||||
public OrderItem(Order order, DrinkType type, int shots, boolean iced) {
|
||||
this.order = order;
|
||||
public OrderItem(int orderNumber, DrinkType type, int shots, boolean iced) {
|
||||
this.orderNumber = orderNumber;
|
||||
this.type = type;
|
||||
this.shots = shots;
|
||||
this.iced = iced;
|
||||
}
|
||||
|
||||
|
||||
public Order getOrder() {
|
||||
return this.order;
|
||||
public int getOrderNumber() {
|
||||
return this.orderNumber;
|
||||
}
|
||||
|
||||
public void setOrderNumber(int orderNumber) {
|
||||
this.orderNumber = orderNumber;
|
||||
}
|
||||
|
||||
public boolean isIced() {
|
||||
return this.iced;
|
||||
}
|
||||
|
||||
public int getShots() {
|
||||
public void setIced(boolean iced) {
|
||||
this.iced = iced;
|
||||
}
|
||||
|
||||
public int getShots() {
|
||||
return shots;
|
||||
}
|
||||
|
||||
public DrinkType getDrinkType() {
|
||||
public void setShots(int shots) {
|
||||
this.shots = shots;
|
||||
}
|
||||
|
||||
public DrinkType getDrinkType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
public void setDrinkType(DrinkType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return ((this.iced) ? "iced " : "hot ") + this.shots + " shot " + this.type;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,7 +27,9 @@ import org.springframework.stereotype.Component;
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Marius Bogoevici
|
||||
* @author Tom McCuch
|
||||
*/
|
||||
|
||||
@Component
|
||||
public class Barista {
|
||||
private static Logger logger = Logger.getLogger(Barista.class);
|
||||
@@ -54,8 +56,8 @@ public class Barista {
|
||||
Thread.sleep(this.hotDrinkDelay);
|
||||
logger.info(Thread.currentThread().getName()
|
||||
+ " prepared hot drink #" + hotDrinkCounter.incrementAndGet() + " for order #"
|
||||
+ orderItem.getOrder().getNumber() + ": " + orderItem);
|
||||
return new Drink(orderItem.getOrder().getNumber(), orderItem.getDrinkType(), orderItem.isIced(),
|
||||
+ orderItem.getOrderNumber() + ": " + orderItem);
|
||||
return new Drink(orderItem.getOrderNumber(), orderItem.getDrinkType(), orderItem.isIced(),
|
||||
orderItem.getShots());
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
@@ -69,8 +71,8 @@ public class Barista {
|
||||
Thread.sleep(this.coldDrinkDelay);
|
||||
logger.info(Thread.currentThread().getName()
|
||||
+ " prepared cold drink #" + coldDrinkCounter.incrementAndGet() + " for order #"
|
||||
+ orderItem.getOrder().getNumber() + ": " + orderItem);
|
||||
return new Drink(orderItem.getOrder().getNumber(), orderItem.getDrinkType(), orderItem.isIced(),
|
||||
+ orderItem.getOrderNumber() + ": " + orderItem);
|
||||
return new Drink(orderItem.getOrderNumber(), orderItem.getDrinkType(), orderItem.isIced(),
|
||||
orderItem.getShots());
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.samples.cafe.xml;
|
||||
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.samples.cafe.Cafe;
|
||||
import org.springframework.integration.samples.cafe.DrinkType;
|
||||
import org.springframework.integration.samples.cafe.Order;
|
||||
|
||||
/**
|
||||
* Provides the 'main' method for running the Cafe Demo store front
|
||||
* application using AMQP. Before running, be sure to have a
|
||||
* RabbitMQ broker started on localhost:5672 configured with the default
|
||||
* guest | guest client credentials on the / vHost. When an order is
|
||||
* placed, the Cafe store front will publish that order on the cafe-orders
|
||||
* exchange to be processed.
|
||||
* <p/>
|
||||
* The relevant components are defined within the configuration files:
|
||||
* ("cafeDemo-amqp-xml.xml", "cafeDemo-amqp-config-xml.xml").
|
||||
* <p/>
|
||||
* If deploying in SpringSource dmServer, the relevant ApplicationContext
|
||||
* configuration is in the META-INF/spring directory instead.
|
||||
*
|
||||
* @author Tom McCuch
|
||||
*/
|
||||
public class CafeDemoAppAmqp {
|
||||
|
||||
/**
|
||||
* place some orders
|
||||
* @param context spring context
|
||||
* @param count the number of standard orders
|
||||
*/
|
||||
public static void order(AbstractApplicationContext context, int count){
|
||||
Cafe cafe = (Cafe) context.getBean("cafe");
|
||||
for (int i = 1; i <= 100; i++) {
|
||||
Order order = new Order(i);
|
||||
order.addItem(DrinkType.LATTE, 2, false);
|
||||
order.addItem(DrinkType.MOCHA, 3, true);
|
||||
cafe.placeOrder(order);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
AbstractApplicationContext context =
|
||||
CafeDemoAppUtilities.loadProfileContext(
|
||||
"/META-INF/spring/integration/amqp/cafeDemo-amqp-xml.xml",
|
||||
CafeDemoAppAmqp.class,CafeDemoAppUtilities.DEV);
|
||||
order(context, 100);
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.samples.cafe.xml;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.samples.cafe.Cafe;
|
||||
import org.springframework.integration.samples.cafe.DrinkType;
|
||||
import org.springframework.integration.samples.cafe.Order;
|
||||
|
||||
/**
|
||||
* Provides the 'main' method for running the Cafe Demo Cold Drink
|
||||
* Barista application using AMQP. Before running, be sure to have a
|
||||
* RabbitMQ broker started on localhost:5672 configured with the default
|
||||
* guest | guest client credentials on the / vHost. When a drink order
|
||||
* is placed on the cold-drinks queue, the Barista will prepare the drink
|
||||
* and reply to the reply-to queue set by the sender.
|
||||
* <p/>
|
||||
* The relevant components are defined within the configuration files:
|
||||
* ("cafeDemo-amqp-baristaCold-xml.xml", "cafeDemo-amqp-config-xml.xml").
|
||||
* <p/>
|
||||
* If deploying in SpringSource dmServer, the relevant ApplicationContext
|
||||
* configuration is in the META-INF/spring directory instead.
|
||||
*
|
||||
* @author Tom McCuch
|
||||
*/
|
||||
public class CafeDemoAppBaristaColdAmqp {
|
||||
|
||||
public static void main(String[] args) {
|
||||
AbstractApplicationContext context =
|
||||
CafeDemoAppUtilities.loadProfileContext(
|
||||
"/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaCold-xml.xml",
|
||||
CafeDemoAppBaristaColdAmqp.class,CafeDemoAppUtilities.DEV);
|
||||
|
||||
System.out.println("Press Enter/Return in the console to exit the Barista Cold App");
|
||||
try {
|
||||
System.in.read();
|
||||
} catch (IOException e) {
|
||||
context.close();
|
||||
}
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.samples.cafe.xml;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.samples.cafe.Cafe;
|
||||
import org.springframework.integration.samples.cafe.DrinkType;
|
||||
import org.springframework.integration.samples.cafe.Order;
|
||||
|
||||
/**
|
||||
* Provides the 'main' method for running the Cafe Demo Hot Drink
|
||||
* Barista application using AMQP. Before running, be sure to have a
|
||||
* RabbitMQ broker started on localhost:5672 configured with the default
|
||||
* guest | guest client credentials on the / vHost. When a drink order
|
||||
* is placed on the hot-drinks queue, the Barista will prepare the drink
|
||||
* and reply to the reply-to queue set by the sender.
|
||||
* <p/>
|
||||
* The relevant components are defined within the configuration files:
|
||||
* ("cafeDemo-amqp-baristaHot-xml.xml", "cafeDemo-amqp-config-xml.xml").
|
||||
* <p/>
|
||||
* If deploying in SpringSource dmServer, the relevant ApplicationContext
|
||||
* configuration is in the META-INF/spring directory instead.
|
||||
*
|
||||
* @author Tom McCuch
|
||||
*/
|
||||
public class CafeDemoAppBaristaHotAmqp {
|
||||
|
||||
public static void main(String[] args) {
|
||||
AbstractApplicationContext context =
|
||||
CafeDemoAppUtilities.loadProfileContext(
|
||||
"/META-INF/spring/integration/amqp/cafeDemo-amqp-baristaHot-xml.xml",
|
||||
CafeDemoAppBaristaHotAmqp.class,CafeDemoAppUtilities.DEV);
|
||||
|
||||
System.out.println("Press Enter/Return in the console to exit the Barista Hot App");
|
||||
try {
|
||||
System.in.read();
|
||||
} catch (IOException e) {
|
||||
context.close();
|
||||
}
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.samples.cafe.xml;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.samples.cafe.Cafe;
|
||||
import org.springframework.integration.samples.cafe.DrinkType;
|
||||
import org.springframework.integration.samples.cafe.Order;
|
||||
|
||||
/**
|
||||
* Provides the 'main' method for running the Cafe Demo Operations
|
||||
* application using AMQP. Before running, be sure to have a RabbitMQ
|
||||
* broker started on localhost:5672 configured with the default
|
||||
* guest | guest client credentials on the / vHost. When an order is
|
||||
* placed on the new-orders queue, the Cafe Operations app will split
|
||||
* the order into order line items, route them to either the coldDrink
|
||||
* or hotDrink Barista, aggregate the prepared drinks returned from the
|
||||
* Barista using a Waiter, and publish the delivered order on the
|
||||
* cafe-deliveries exchange.
|
||||
* <p/>
|
||||
* The relevant components are defined within the configuration files:
|
||||
* ("cafeDemo-amqp-operations-xml.xml", "cafeDemo-amqp-config-xml.xml").
|
||||
* <p/>
|
||||
* Before starting this app, be sure to start the CafeDemoAppBaristaCold
|
||||
* and CafeDemoAppBaristaHot apps first.
|
||||
*
|
||||
* If deploying in SpringSource dmServer, the relevant ApplicationContext
|
||||
* configuration is in the META-INF/spring directory instead.
|
||||
*
|
||||
* @author Tom McCuch
|
||||
*/
|
||||
public class CafeDemoAppOperationsAmqp {
|
||||
|
||||
public static void main(String[] args) {
|
||||
AbstractApplicationContext context =
|
||||
CafeDemoAppUtilities.loadProfileContext(
|
||||
"/META-INF/spring/integration/amqp/cafeDemo-amqp-operations-xml.xml",
|
||||
CafeDemoAppOperationsAmqp.class,CafeDemoAppUtilities.DEV);
|
||||
|
||||
System.out.println("Press Enter/Return in the console to exit the Cafe Operations App");
|
||||
try {
|
||||
System.in.read();
|
||||
} catch (IOException e) {
|
||||
context.close();
|
||||
}
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-amqp="http://www.springframework.org/schema/integration/amqp"
|
||||
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
|
||||
xmlns:stream="http://www.springframework.org/schema/integration/stream"
|
||||
xmlns:cloud="http://schema.cloudfoundry.org/spring"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||
http://schema.cloudfoundry.org/spring
|
||||
http://schema.cloudfoundry.org/spring/cloudfoundry-spring-0.8.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
|
||||
http://www.springframework.org/schema/integration/amqp
|
||||
http://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd
|
||||
http://www.springframework.org/schema/rabbit
|
||||
http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd
|
||||
http://www.springframework.org/schema/integration/stream
|
||||
http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd">
|
||||
|
||||
|
||||
<!-- rabbit connection factory, rabbit template, and rabbit admin -->
|
||||
<import resource="classpath:META-INF/spring/integration/amqp/cafeDemo-amqp-config-xml.xml" />
|
||||
|
||||
<!-- To receive an AMQP Message from a Queue, and respond to its reply-to address, configure an inbound-gateway. -->
|
||||
<int-amqp:inbound-gateway
|
||||
id="coldDrinksBarista"
|
||||
request-channel="coldJsonDrinks"
|
||||
queue-names="cold-drinks"
|
||||
connection-factory="rabbitConnectionFactory" />
|
||||
|
||||
<int:chain input-channel="coldJsonDrinks">
|
||||
<int:json-to-object-transformer type="org.springframework.integration.samples.cafe.OrderItem"/>
|
||||
<int:service-activator method="prepareColdDrink">
|
||||
<bean class="org.springframework.integration.samples.cafe.xml.Barista"/>
|
||||
</int:service-activator>
|
||||
<int:object-to-json-transformer />
|
||||
</int:chain>
|
||||
|
||||
<!-- rabbit exchanges, queues, and bindings used by this app -->
|
||||
<rabbit:topic-exchange name="cafe-drinks" auto-delete="true" durable="true">
|
||||
<rabbit:bindings>
|
||||
<rabbit:binding queue="cold-drinks" pattern="drink.cold"/>
|
||||
<rabbit:binding queue="all-cold-drinks" pattern="drink.cold"/>
|
||||
</rabbit:bindings>
|
||||
</rabbit:topic-exchange>
|
||||
|
||||
<rabbit:queue name="cold-drinks" auto-delete="true" durable="true"/>
|
||||
<rabbit:queue name="all-cold-drinks" auto-delete="true" durable="true"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-amqp="http://www.springframework.org/schema/integration/amqp"
|
||||
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
|
||||
xmlns:stream="http://www.springframework.org/schema/integration/stream"
|
||||
xmlns:cloud="http://schema.cloudfoundry.org/spring"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||
http://schema.cloudfoundry.org/spring
|
||||
http://schema.cloudfoundry.org/spring/cloudfoundry-spring-0.8.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
|
||||
http://www.springframework.org/schema/integration/amqp
|
||||
http://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd
|
||||
http://www.springframework.org/schema/rabbit
|
||||
http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd
|
||||
http://www.springframework.org/schema/integration/stream
|
||||
http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd">
|
||||
|
||||
|
||||
<!-- rabbit connection factory, rabbit template, and rabbit admin -->
|
||||
<import resource="classpath:META-INF/spring/integration/amqp/cafeDemo-amqp-config-xml.xml" />
|
||||
|
||||
<!-- To receive an AMQP Message from a Queue, and respond to its reply-to address, configure an inbound-gateway. -->
|
||||
<int-amqp:inbound-gateway
|
||||
id="hotDrinksBarista"
|
||||
request-channel="hotJsonDrinks"
|
||||
queue-names="hot-drinks"
|
||||
connection-factory="rabbitConnectionFactory" />
|
||||
|
||||
<int:chain input-channel="hotJsonDrinks">
|
||||
<int:json-to-object-transformer type="org.springframework.integration.samples.cafe.OrderItem"/>
|
||||
<int:service-activator method="prepareHotDrink">
|
||||
<bean class="org.springframework.integration.samples.cafe.xml.Barista"/>
|
||||
</int:service-activator>
|
||||
<int:object-to-json-transformer />
|
||||
</int:chain>
|
||||
|
||||
<!-- rabbit exchanges, queues, and bindings used by this app -->
|
||||
<rabbit:topic-exchange name="cafe-drinks" auto-delete="true" durable="true">
|
||||
<rabbit:bindings>
|
||||
<rabbit:binding queue="hot-drinks" pattern="drink.hot"/>
|
||||
<rabbit:binding queue="all-hot-drinks" pattern="drink.hot"/>
|
||||
</rabbit:bindings>
|
||||
</rabbit:topic-exchange>
|
||||
|
||||
<rabbit:queue name="hot-drinks" auto-delete="true" durable="true"/>
|
||||
<rabbit:queue name="all-hot-drinks" auto-delete="true" durable="true"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
|
||||
xmlns:cloud="http://schema.cloudfoundry.org/spring"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||
http://schema.cloudfoundry.org/spring
|
||||
http://schema.cloudfoundry.org/spring/cloudfoundry-spring-0.8.xsd
|
||||
http://www.springframework.org/schema/rabbit
|
||||
http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd">
|
||||
|
||||
<!-- Set up the AmqpTemplate/RabbitTemplate: -->
|
||||
<rabbit:template id="amqpTemplate"
|
||||
connection-factory="rabbitConnectionFactory" reply-timeout="10000" />
|
||||
|
||||
<!-- Request that queues, exchanges and bindings be automatically declared
|
||||
on the broker: -->
|
||||
<rabbit:admin connection-factory="rabbitConnectionFactory" />
|
||||
|
||||
<!-- profiles must be the last element sin the file -->
|
||||
|
||||
<!-- Obtain a connection to the RabbitMQ via cloudfoundry-runtime: -->
|
||||
<beans profile="cloud">
|
||||
<cloud:rabbit-connection-factory
|
||||
id="rabbitConnectionFactory" />
|
||||
</beans>
|
||||
|
||||
<!-- connect to the local broker using the default user name and password -->
|
||||
<beans profile="dev">
|
||||
<bean id="rabbitConnectionFactory"
|
||||
class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
|
||||
<constructor-arg value="localhost" />
|
||||
<property name="username" value="guest" />
|
||||
<property name="password" value="guest" />
|
||||
</bean>
|
||||
</beans>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,118 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-amqp="http://www.springframework.org/schema/integration/amqp"
|
||||
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
|
||||
xmlns:stream="http://www.springframework.org/schema/integration/stream"
|
||||
xmlns:cloud="http://schema.cloudfoundry.org/spring"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||
http://schema.cloudfoundry.org/spring
|
||||
http://schema.cloudfoundry.org/spring/cloudfoundry-spring-0.8.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
|
||||
http://www.springframework.org/schema/integration/amqp
|
||||
http://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd
|
||||
http://www.springframework.org/schema/rabbit
|
||||
http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd
|
||||
http://www.springframework.org/schema/integration/stream
|
||||
http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd">
|
||||
|
||||
<!-- rabbit connection factory, rabbit template, and rabbit admin -->
|
||||
<import resource="classpath:META-INF/spring/integration/amqp/cafeDemo-amqp-config-xml.xml" />
|
||||
|
||||
<!-- intercept messages on these channels while still allowing them to continue -->
|
||||
<int:wire-tap channel="logger" pattern="orders,coldDrinks,hotDrinks,preparedDrinks,deliveries"/>
|
||||
<int:logging-channel-adapter id="logger" log-full-message="true" level="INFO"/>
|
||||
|
||||
<!-- To receive AMQP Messages from a Queue, configure an inbound-channel-adapter -->
|
||||
<int-amqp:inbound-channel-adapter queue-names="new-orders" channel="jsonOrders" connection-factory="rabbitConnectionFactory" acknowledge-mode="AUTO" />
|
||||
|
||||
<int:json-to-object-transformer id="json-to-order" input-channel="jsonOrders" output-channel="preOrders" type="org.springframework.integration.samples.cafe.Order" />
|
||||
|
||||
<int:splitter input-channel="preOrders" expression="payload.items" output-channel="preDrinks" apply-sequence="true"/>
|
||||
|
||||
<int:header-enricher input-channel="preDrinks" output-channel="drinks">
|
||||
<int:header name="ICED" expression="payload.isIced()"/>
|
||||
</int:header-enricher>
|
||||
|
||||
<int:object-to-json-transformer id="drink-to-json" input-channel="drinks" output-channel="jsonDrinks" />
|
||||
|
||||
<int:router input-channel="jsonDrinks" expression="headers.ICED ? 'coldDrinks' : 'hotDrinks'"/>
|
||||
|
||||
<int:channel id="coldDrinks">
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
<!-- Default poller -->
|
||||
<int:poller default="true" fixed-rate="100"/>
|
||||
|
||||
<int:channel id="hotDrinks">
|
||||
<int:queue/>
|
||||
</int:channel>
|
||||
|
||||
<!-- To send AMQP Messages to an Exchange and receive back a response from a remote client, configure an outbound-gateway -->
|
||||
<int-amqp:outbound-gateway
|
||||
id="coldDrinksBarista"
|
||||
request-channel="coldDrinks"
|
||||
reply-channel="preparedJsonDrinks"
|
||||
exchange-name="cafe-drinks"
|
||||
routing-key="drink.cold"
|
||||
amqp-template="amqpTemplate" />
|
||||
|
||||
<!-- To send AMQP Messages to an Exchange and receive back a response from a remote client, configure an outbound-gateway -->
|
||||
<int-amqp:outbound-gateway
|
||||
id="hotDrinksBarista"
|
||||
request-channel="hotDrinks"
|
||||
reply-channel="preparedJsonDrinks"
|
||||
exchange-name="cafe-drinks"
|
||||
routing-key="drink.hot"
|
||||
amqp-template="amqpTemplate" />
|
||||
|
||||
<int:channel id="preparedJsonDrinks"/>
|
||||
|
||||
<int:json-to-object-transformer id="json-to-drink" input-channel="preparedJsonDrinks" output-channel="preparedDrinks" type="org.springframework.integration.samples.cafe.Drink"/>
|
||||
|
||||
<int:aggregator input-channel="preparedDrinks" method="prepareDelivery" output-channel="preDeliveries">
|
||||
<bean class="org.springframework.integration.samples.cafe.xml.Waiter"/>
|
||||
</int:aggregator>
|
||||
|
||||
<int:channel id="preDeliveries" />
|
||||
|
||||
<int:header-enricher input-channel="preDeliveries" output-channel="deliveries">
|
||||
<int:header name="NUMBER" expression="payload.getOrderNumber()" />
|
||||
</int:header-enricher>
|
||||
|
||||
<int:object-to-json-transformer id="delivery-to-json" input-channel="deliveries" output-channel="jsonDeliveries"/>
|
||||
|
||||
<int:channel id="jsonDeliveries" />
|
||||
|
||||
<!-- To send AMQP Messages to an Exchange, configure an outbound-channel-adapter. -->
|
||||
<int-amqp:outbound-channel-adapter
|
||||
id="deliveredOrders"
|
||||
channel="jsonDeliveries"
|
||||
amqp-template="amqpTemplate"
|
||||
exchange-name="cafe-deliveries"
|
||||
routing-key-expression="'delivery.'+headers.NUMBER" />
|
||||
|
||||
<bean id="waiter" class="org.springframework.integration.samples.cafe.xml.Waiter"/>
|
||||
|
||||
<!-- rabbit exchanges, queues, and bindings used by this app -->
|
||||
<rabbit:topic-exchange name="cafe-drinks" auto-delete="true" durable="true">
|
||||
<rabbit:bindings>
|
||||
<rabbit:binding queue="all-drinks" pattern="drink.*"/>
|
||||
</rabbit:bindings>
|
||||
</rabbit:topic-exchange>
|
||||
|
||||
<rabbit:queue name="all-drinks" auto-delete="true" durable="true"/>
|
||||
|
||||
<rabbit:fanout-exchange name="cafe-deliveries" auto-delete="false" durable="true">
|
||||
<rabbit:bindings>
|
||||
<rabbit:binding queue="all-deliveries" />
|
||||
</rabbit:bindings>
|
||||
</rabbit:fanout-exchange>
|
||||
|
||||
<rabbit:queue name="all-deliveries" auto-delete="false" durable="true"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:int-amqp="http://www.springframework.org/schema/integration/amqp"
|
||||
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
|
||||
xmlns:stream="http://www.springframework.org/schema/integration/stream"
|
||||
xmlns:cloud="http://schema.cloudfoundry.org/spring"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||
http://schema.cloudfoundry.org/spring
|
||||
http://schema.cloudfoundry.org/spring/cloudfoundry-spring-0.8.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
|
||||
http://www.springframework.org/schema/integration/amqp
|
||||
http://www.springframework.org/schema/integration/amqp/spring-integration-amqp.xsd
|
||||
http://www.springframework.org/schema/rabbit
|
||||
http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd
|
||||
http://www.springframework.org/schema/integration/stream
|
||||
http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd">
|
||||
|
||||
<!-- rabbit connection factory, rabbit template, and rabbit admin -->
|
||||
<import resource="classpath:META-INF/spring/integration/amqp/cafeDemo-amqp-config-xml.xml" />
|
||||
|
||||
<!-- spring integration flow -->
|
||||
<int:gateway id="cafe" service-interface="org.springframework.integration.samples.cafe.Cafe" />
|
||||
|
||||
<int:channel id="orders"/>
|
||||
|
||||
<int:header-enricher input-channel="orders" output-channel="newOrders">
|
||||
<int:header name="NUMBER" expression="payload.getNumber()"/>
|
||||
</int:header-enricher>
|
||||
|
||||
<int:object-to-json-transformer input-channel="newOrders" output-channel="jsonNewOrders" />
|
||||
|
||||
<int:channel id="jsonNewOrders" />
|
||||
|
||||
<!-- To send AMQP Messages to an Exchange, configure an outbound-channel-adapter. -->
|
||||
<int-amqp:outbound-channel-adapter
|
||||
channel="jsonNewOrders"
|
||||
exchange-name="cafe-orders"
|
||||
routing-key-expression="'order.'+headers.NUMBER"
|
||||
amqp-template="amqpTemplate" />
|
||||
|
||||
<!-- rabbit exchanges, queues, and bindings used by this app -->
|
||||
<rabbit:topic-exchange name="cafe-orders" auto-delete="false" durable="true">
|
||||
<rabbit:bindings>
|
||||
<rabbit:binding queue="new-orders" pattern="order.*"/>
|
||||
<rabbit:binding queue="all-orders" pattern="order.*"/>
|
||||
</rabbit:bindings>
|
||||
</rabbit:topic-exchange>
|
||||
|
||||
<rabbit:queue name="new-orders" auto-delete="false" durable="true"/>
|
||||
<rabbit:queue name="all-orders" auto-delete="false" durable="true"/>
|
||||
|
||||
</beans>
|
||||
@@ -12,22 +12,27 @@
|
||||
|
||||
<gateway id="cafe" service-interface="org.springframework.integration.samples.cafe.Cafe"/>
|
||||
|
||||
<!-- each order has a collection of order items that is split apart to be processed -->
|
||||
<channel id="orders"/>
|
||||
<splitter input-channel="orders" expression="payload.items" output-channel="drinks"/>
|
||||
|
||||
<!-- The router sends different drink orders on different paths -->
|
||||
<channel id="drinks"/>
|
||||
<router input-channel="drinks" expression="payload.iced ? 'coldDrinks' : 'hotDrinks'"/>
|
||||
|
||||
<!-- individual order items are processed by the barista -->
|
||||
<channel id="coldDrinks">
|
||||
<queue capacity="10"/>
|
||||
</channel>
|
||||
<service-activator input-channel="coldDrinks" ref="barista" method="prepareColdDrink" output-channel="preparedDrinks"/>
|
||||
|
||||
<!-- individual order items are processed by the barista -->
|
||||
<channel id="hotDrinks">
|
||||
<queue capacity="10"/>
|
||||
</channel>
|
||||
<service-activator input-channel="hotDrinks" ref="barista" method="prepareHotDrink" output-channel="preparedDrinks"/>
|
||||
|
||||
<!-- drink order items are aggregated in a call to the waiter -->
|
||||
<channel id="preparedDrinks"/>
|
||||
<aggregator input-channel="preparedDrinks" method="prepareDelivery" output-channel="deliveries">
|
||||
<beans:bean class="org.springframework.integration.samples.cafe.xml.Waiter"/>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<appender name="console" class="org.apache.log4j.ConsoleAppender">
|
||||
<param name="Target" value="System.out" />
|
||||
<layout class="org.apache.log4j.PatternLayout">
|
||||
<param name="ConversionPattern" value="%-5p: %c - %m%n" />
|
||||
<param name="ConversionPattern" value="%t %-5p: %c - %m%n" />
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
@@ -15,6 +15,14 @@
|
||||
<level value="warn" />
|
||||
</logger>
|
||||
|
||||
<logger name="org.springframework.amqp">
|
||||
<level value="info" />
|
||||
</logger>
|
||||
|
||||
<logger name="org.springframework.integration">
|
||||
<level value="info" />
|
||||
</logger>
|
||||
|
||||
<logger name="org.springframework.integration.samples">
|
||||
<level value="debug" />
|
||||
</logger>
|
||||
|
||||
Reference in New Issue
Block a user