2. Code Example

The gateway, or main entry point to the order flow, is the Order interface. It was defined in the Spring configuration and the @Gateway annotation indicates what channel any items passed to process(BookOrder order) will be sent to.

Example 1. Order

                
public interface Order {

    /**
     * Process a book order.
     */
    @Gateway(requestChannel="processOrder")
    public void process(BookOrder order);

}
                
            

The OrderRouter indicates it is a message endpoint by using the @MessageEndpoint on the class. The @Router annotation on processOrder(BookOrder order) configures the incoming channel by setting the inputChannel attribute. The method should return a String that matches one of the configured channels. In this case the incoming channel is set to 'processOrder' and depending on the order type either 'delivery' or 'pickup' will be returned.

Example 2. OrderRouter

                
@MessageEndpoint
public class OrderRouter {

    final Logger logger = LoggerFactory.getLogger(OrderRouter.class);
    
    /**
     * Process order.  Routes based on whether or 
     * not the order is a delivery or pickup.
     */
    @Router(inputChannel="processOrder")
    public String processOrder(BookOrder order) {
        String result = null;
        
        logger.debug("In OrderRouter.  title='{}'  quantity={}  orderType={}", 
                     new Object[] { order.getTitle(), 
                                    order.getQuantity(),
                                    order.getOrderType() });
        
        switch (order.getOrderType()) {
            case DELIVERY:
                result = "delivery";
                break;
            case PICKUP:
                result = "pickup";
                break;              
        }
        
        return result;
    }

}
                
            

The StoreEndpoint is the end of the store pickup flow. It just retrieves the message payload and logs it's output. In a real application the order could be electronically sent or printed at the appropriate store so the order could be prepared for pickup.

Example 3. StoreEndpoint

                
@MessageEndpoint
public class StoreEndpoint {

    final Logger logger = LoggerFactory.getLogger(StoreEndpoint.class);
    
    /**
     * Process an order for a pickup from the store.
     */
    public void processMessage(Message<BookOrder> message) {
        BookOrder order =  message.getPayload();
        
        logger.debug("In StoreEndpoint.  title='{}'  quantity={}  orderType={}", 
                new Object[] { order.getTitle(), 
                               order.getQuantity(),
                               order.getOrderType() });
    }

}
                
            

The DeliveryTransformer indicates processMessage(BookOrder order) is a transformer by using the @Transformer annotation. It converts a BookOrder from the 'delivery' channel to an OnlineBookOrder which will be sent to the 'post' channel. The address for the online order is hard coded, but in a real application the transformer could look up an address.

Example 4. DeliveryTransformer

                
@MessageEndpoint
public class DeliveryTransformer {

    final Logger logger = LoggerFactory.getLogger(DeliveryTransformer.class);
    
    /**
     * Transforms a <code>BookOrder</code> that is a delivery 
     * into a <code>OnlineBookOrder</code>.
     */
    @Transformer(inputChannel="delivery", outputChannel="post")
    public OnlineBookOrder processMessage(BookOrder order) {
        logger.debug("In DeliveryTransformer.  title='{}'  quantity={}  orderType={}", 
                new Object[] { order.getTitle(), 
                               order.getQuantity(),
                               order.getOrderType() });
        
        return new OnlineBookOrder(order.getTitle(), order.getQuantity(), 
                                   order.getOrderType(), 
                                   "1060 West Addison Chicago, IL 60613");
    }

}
                
            

The PostEndpoint is the end of the delivery flow. It just retrieves the message payload for the online order and logs it's output. In a real application the order could be electronically sent or printed at the appropriate warehouse so the order could be prepared for shipping to the address added by the DeliveryTransformer.

[Note]Note

The Message was passed in as an example, but since only the message payload is being used it could have been passed in directly (ex: processMessage(OnlineBookOrder order)). Also, @Header could have been used to annotate a method parameter to extract a value from the message header.

Example 5. PostEndpoint

                
@MessageEndpoint
public class PostEndpoint {

    final Logger logger = LoggerFactory.getLogger(PostEndpoint.class);
    
    /**
     * Process a delivery order for sending by mail.
     */
    public void processMessage(Message<OnlineBookOrder> message) {
        OnlineBookOrder order =  message.getPayload();
        
        logger.debug("In PostEndpoint.  title='{}'  quantity={}  orderType={}  address='{}'", 
                new Object[] { order.getTitle(), 
                               order.getQuantity(),
                               order.getOrderType(),
                               order.getAddress() });
    }

}