View Javadoc
1   package ejava.examples.asyncmarket.ejb;
2   
3   import javax.annotation.PostConstruct;
4   import javax.annotation.Resource;
5   import javax.ejb.EJBException;
6   import javax.ejb.SessionContext;
7   import javax.ejb.Stateless;
8   import javax.ejb.Timeout;
9   import javax.ejb.Timer;
10  import javax.ejb.TimerConfig;
11  import javax.ejb.TimerService;
12  import javax.ejb.TransactionAttribute;
13  import javax.ejb.TransactionAttributeType;
14  import javax.inject.Inject;
15  import javax.jms.Destination;
16  import javax.jms.JMSConnectionFactory;
17  import javax.jms.JMSContext;
18  import javax.jms.JMSException;
19  import javax.jms.JMSProducer;
20  import javax.jms.MapMessage;
21  import javax.jms.Topic;
22  
23  import org.slf4j.Logger;
24  import org.slf4j.LoggerFactory;
25  
26  import ejava.examples.asyncmarket.bo.AuctionItem;
27  import ejava.examples.asyncmarket.bo.Bid;
28  import ejava.examples.asyncmarket.bo.Person;
29  import ejava.examples.asyncmarket.dao.AuctionItemDAO;
30  import ejava.examples.asyncmarket.dao.PersonDAO;
31  
32  @Stateless
33  @TransactionAttribute(TransactionAttributeType.REQUIRED)
34  public class SellerEJB
35      implements SellerLocal, SellerRemote {
36      private static final Logger logger = LoggerFactory.getLogger(SellerEJB.class);
37      
38      @Inject @JMSConnectionFactory("java:/JmsXA")
39      private JMSContext jmsContext;
40      @Resource(lookup="java:/jms/topic/ejava/examples/asyncMarket/topic1", type=Topic.class)
41      private Destination sellTopic;
42      
43      @Resource
44      private TimerService timerService;
45      @Resource
46      private SessionContext ctx;
47  
48      @Inject
49      private PersonDAO sellerDAO;
50      @Inject
51      private AuctionItemDAO auctionItemDAO;
52      @Inject
53      private DtoMapper dtoMapper;
54      
55      @PostConstruct
56      public void init() {
57          logger.info("******************* SellerEJB Created ******************");
58          logger.debug("ctx={}", ctx);
59          logger.debug("connFactory={}", jmsContext);
60          logger.debug("sellTopic={}", sellTopic);
61          logger.debug("timerService={}", timerService);
62      }
63      
64      @TransactionAttribute(TransactionAttributeType.REQUIRED)
65      public long sellProduct(String sellerId, AuctionItem item) throws ResourceNotFoundException {
66          logger.debug("sellProduct(sellerId={},item={})", sellerId, item);
67          
68          Person seller = sellerDAO.getPersonByUserId(sellerId);
69          if (seller==null) {
70              throw new ResourceNotFoundException("seller[%s] not found", sellerId);
71          }
72          
73          try {
74              seller.getItems().add(item);
75              item.setOwner(seller);
76              auctionItemDAO.createItem(item);
77              
78              publishForSale(item);
79              timerService.createSingleActionTimer(item.getEndDate(), 
80                                                   new TimerConfig(new Long(item.getId()), false));
81              return item.getId();
82          }
83          catch (JMSException ex) {
84              logger.error("error publishing sale", ex);
85              ctx.setRollbackOnly();
86              throw new EJBException("error publishing sell");
87          }
88          catch (Exception ex) {
89              logger.error("error selling product", ex);
90              ctx.setRollbackOnly();
91              throw new InternalErrorException("error selling product: %s", ex);
92          }
93      }    
94      
95      protected void publishForSale(AuctionItem item) throws JMSException {
96          JMSProducer producer = jmsContext.createProducer();
97          MapMessage message = jmsContext.createMapMessage();
98          message.setJMSType("forSale");
99          message.setLong("id", item.getId());
100         message.setString("name", item.getName());
101         message.setString("seller", item.getOwner().getUserId());
102         message.setLong("startDate", item.getStartDate().getTime());
103         message.setLong("endDate", item.getEndDate().getTime());
104         message.setDouble("minBid", item.getMinBid());
105         message.setDouble("bids", item.getBids().size());
106         message.setDouble("highestBid", 
107                 (item.getHighestBid() == null ? 0.00 :
108                     item.getHighestBid().getAmount()));            
109         producer.send(sellTopic, message);
110         logger.debug("sent=" + message);
111     }
112 
113 
114     public AuctionItem getItem(long itemId) throws ResourceNotFoundException {
115         AuctionItem item = auctionItemDAO.getItem(itemId);
116         if (item==null) {
117             throw new ResourceNotFoundException("itemId[%d] not found", itemId);            
118         }
119         
120         try {
121             AuctionItem dto = dtoMapper.toDTO(item);
122             logger.debug("dao item=" + item);
123             logger.debug("dto item=" + dto);
124             return dto;
125         }
126         catch (Exception ex) {
127             logger.error("error getting auction item", ex);
128             throw new InternalErrorException("error getting auction item:%s", ex);
129         }
130     }
131     
132     protected Bid getWinningDTO(Bid winningBid, AuctionItem item) {
133         Bid dto = null;
134         if (winningBid != null) {
135             for(Bid bid : item.getBids()) {
136                 if (bid.getId() == winningBid.getId()) {
137                     dto = bid;
138                     break;
139                 }
140             }
141         }
142         return dto;
143     }
144     
145     @Timeout
146     public void timeout(Timer timer) {
147         try {
148             long itemId = ((Long)timer.getInfo()).longValue();
149             endAuction(itemId);
150         }
151         catch (ResourceNotFoundException ex) {
152             //ignored -- application may be shutting down
153         }
154         catch (Exception ex) {
155             logger.error("error ending auction for:" + timer.getInfo(), ex);
156         }
157     }
158     
159     public void endAuction(long itemId) throws ResourceNotFoundException  {
160         AuctionItem item = auctionItemDAO.getItem(itemId);
161         if (item==null) {
162             throw new ResourceNotFoundException("itemId[%d] not found", itemId);
163         }
164         
165         try {
166             item.closeBids();          
167             logger.info("ending auction for:" + item);    
168             publishSold(item);
169         } catch (JMSException ex) {
170             logger.error("error publishing jms message", ex);
171             throw new InternalErrorException("error publishing jms message", ex);
172         } catch (Exception ex) {
173             logger.error("error ending auction:" + itemId, ex);
174             throw new InternalErrorException("error ending auction[%d]: %s", itemId, ex);
175         }
176     }
177     
178     protected void publishSold(AuctionItem item) throws JMSException {
179         JMSProducer producer = jmsContext.createProducer();
180         MapMessage message = jmsContext.createMapMessage();
181         message.setJMSType("sold");
182         message.setLong("id", item.getId());
183         message.setString("name", item.getName());
184         message.setString("seller", item.getOwner().getUserId());
185         message.setLong("startDate", item.getStartDate().getTime());
186         message.setLong("endDate", item.getEndDate().getTime());
187         message.setDouble("minBid", item.getMinBid());
188         message.setDouble("bids", item.getBids().size());
189         message.setString("buyerId", 
190                           (item.getWinningBid() == null ?
191                            "" : 
192                            item.getWinningBid().getBidder().getUserId()));
193         message.setDouble("winningBid", 
194                 (item.getHighestBid() == null ? 0.00 :
195                     item.getHighestBid().getAmount()));            
196         producer.send(sellTopic, message);
197         logger.debug("sent=" + message);
198     }
199 }