View Javadoc
1   package ejava.examples.asyncmarket.ejb;
2   
3   import java.util.List;
4   
5   import javax.annotation.PostConstruct;
6   import javax.annotation.Resource;
7   import javax.annotation.security.PermitAll;
8   import javax.ejb.ActivationConfigProperty;
9   import javax.ejb.EJB;
10  import javax.ejb.MessageDriven;
11  import javax.ejb.MessageDrivenContext;
12  import javax.inject.Inject;
13  import javax.jms.MapMessage;
14  import javax.jms.Message;
15  import javax.jms.MessageListener;
16  
17  import org.slf4j.Logger;
18  import org.slf4j.LoggerFactory;
19  
20  import ejava.examples.asyncmarket.bo.AuctionItem;
21  import ejava.examples.asyncmarket.bo.Bid;
22  import ejava.examples.asyncmarket.bo.Order;
23  import ejava.examples.asyncmarket.dao.OrderDAO;
24  
25  
26  /**
27   * This class will listen for market events and cause further bidding to 
28   * occur. Note that this is mostly a technology demonstration and not
29   * a great architectural demonstration. It would be best to restrict
30   * this class to only the async/JMS interface and move all detailed
31   * processing and business logic to lower level classes. Architecturally,
32   * MDBs should be restricted to just interface adaption. If you place 
33   * too much business logic here it becomes harder to test and reuse.
34   *  
35   */
36  @MessageDriven(activationConfig={
37  		/* I placed the first few in the ejb-jar.xml DD
38  		 * since they are configuration options that,
39  		 * when they change, do not impact the code.
40          @ActivationConfigProperty(
41                  propertyName="destinationType",
42                  propertyValue="javax.jms.Topic"),            
43          @ActivationConfigProperty(
44                  propertyName="destination",
45                  propertyValue="java:/jms/topic/ejava/examples/asyncMarket/topic1"),            
46          @ActivationConfigProperty(
47                  propertyName="messageSelector",
48                  propertyValue="JMSType in ('forSale', 'saleUpdate')"),
49          */
50  		//This one, however, would impact the code if it were changed
51          @ActivationConfigProperty(
52                  propertyName="acknowledgeMode",
53                  propertyValue="Auto-acknowledge")            
54  })
55  public class BuyerMDB implements MessageListener {
56      private static final Logger logger = LoggerFactory.getLogger(BuyerMDB.class);
57      
58      @EJB
59      private BuyerLocal buyer;
60      @EJB
61      private AuctionMgmtLocal auctionMgmt;     
62      
63      @Inject
64      private OrderDAO orderDAO;
65      
66      @Resource
67      private MessageDrivenContext ctx;
68      
69      @PostConstruct
70      public void init() {
71          logger.info("*** BuyerMDB init() ***");
72          logger.debug("ctx=" + ctx);
73          logger.debug("buyer=" + buyer);
74          logger.debug("auctionMgmt=" + auctionMgmt);
75      }
76  
77      @PermitAll
78      public void onMessage(Message message) {
79          try {
80              logger.debug("onMessage:" + message.getJMSMessageID());
81              MapMessage auctionMsg = (MapMessage)message;
82              long itemId = auctionMsg.getLong("id");
83              processAuctionItem(itemId);
84          }
85          catch (Exception ex) {
86              logger.error("error processing message", ex);
87          }
88      }
89      
90      protected void processAuctionItem(long itemId) {
91          int index=0;
92          List<Order> orders = null;
93          do {
94              orders = orderDAO.getOrdersforItem(itemId, index, 10);
95              for (Order order: orders) {
96                  processOrder(order);
97              }
98              index += orders.size();            
99          } while (orders.size() > 0);        
100     }
101 
102     protected void processOrder(Order order) {
103         logger.debug("processing order:" + order);
104         try {
105             AuctionItem item = order.getItem();
106             Bid highestBid = item.getHighestBid();
107             if (highestBid == null) {
108                 if (item.getMinBid() < order.getMaxBid()) {
109                     buyer.bidProduct(item.getId(), 
110                                      order.getBuyer().getUserId(), 
111                                      item.getMinBid());
112                     logger.debug("placed initial bid for order: {}", order);
113                 }
114             }
115             else if (highestBid.getAmount() < order.getMaxBid()
116             		// add don't bid against ourself
117             		&& item.getHighestBid().getBidder().getId() !=
118             		   order.getBuyer().getId()){
119                 buyer.bidProduct(item.getId(), 
120                                  order.getBuyer().getUserId(), 
121                                  item.getHighestBid().getAmount() + 1.00);
122                 logger.debug("placed new bid for order: {}", order);
123             }
124         } catch (ResourceNotFoundException ex) {
125           logger.error("error processing order:" + order, ex);
126         } catch (InvalidRequestException ex) {
127             logger.error("error processing order:" + order, ex);
128         } finally {}
129     }
130 }