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
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 }