1 package ejava.examples.asyncmarket.ejb; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import javax.annotation.PostConstruct; 7 import javax.annotation.Resource; 8 import javax.ejb.EJBException; 9 import javax.ejb.SessionContext; 10 import javax.ejb.Stateless; 11 import javax.ejb.Timeout; 12 import javax.ejb.Timer; 13 import javax.ejb.TimerService; 14 import javax.ejb.TransactionAttribute; 15 import javax.ejb.TransactionAttributeType; 16 import javax.jms.Connection; 17 import javax.jms.ConnectionFactory; 18 import javax.jms.Destination; 19 import javax.jms.JMSException; 20 import javax.jms.MapMessage; 21 import javax.jms.MessageProducer; 22 import javax.jms.Session; 23 import javax.jms.Topic; 24 import javax.persistence.EntityManager; 25 import javax.persistence.NoResultException; 26 import javax.persistence.PersistenceContext; 27 28 import org.apache.commons.logging.Log; 29 import org.apache.commons.logging.LogFactory; 30 31 import ejava.examples.asyncmarket.MarketException; 32 import ejava.examples.asyncmarket.bo.AuctionItem; 33 import ejava.examples.asyncmarket.bo.Bid; 34 import ejava.examples.asyncmarket.bo.Person; 35 import ejava.examples.asyncmarket.dao.AuctionItemDAO; 36 import ejava.examples.asyncmarket.dao.PersonDAO; 37 import ejava.examples.asyncmarket.jpa.JPAAuctionItemDAO; 38 import ejava.examples.asyncmarket.jpa.JPAPersonDAO; 39 40 @Stateless 41 @TransactionAttribute(TransactionAttributeType.REQUIRED) 42 public class SellerEJB 43 implements SellerLocal, SellerRemote { 44 Log log = LogFactory.getLog(SellerEJB.class); 45 46 @Resource(lookup="java:/JmsXA") 47 private ConnectionFactory connFactory; 48 @Resource(lookup="java:/topic/ejava/examples/asyncMarket/topic1", type=Topic.class) 49 private Destination sellTopic; 50 51 @Resource 52 private TimerService timerService; 53 @Resource 54 private SessionContext ctx; 55 @PersistenceContext(unitName="asyncMarket") 56 private EntityManager em; 57 58 private PersonDAO sellerDAO; 59 private AuctionItemDAO auctionItemDAO; 60 61 @PostConstruct 62 public void init() { 63 log.info("******************* SellerEJB Created ******************"); 64 log.debug("ctx=" + ctx); 65 log.debug("connFactory=" + connFactory); 66 log.debug("sellTopic=" + sellTopic); 67 log.debug("em=" + em); 68 log.debug("timerService=" + timerService); 69 70 sellerDAO = new JPAPersonDAO(); 71 ((JPAPersonDAO)sellerDAO).setEntityManager(em); 72 73 auctionItemDAO = new JPAAuctionItemDAO(); 74 ((JPAAuctionItemDAO)auctionItemDAO).setEntityManager(em); 75 } 76 77 @TransactionAttribute(TransactionAttributeType.REQUIRED) 78 public long sellProduct(String sellerId, AuctionItem item) 79 throws MarketException { 80 log.debug("sellProduct(sellerId=" + sellerId + ",item=" + item + ")"); 81 82 Connection connection = null; 83 Session session = null; 84 Person seller = null; 85 try { 86 connection = connFactory.createConnection(); 87 session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 88 89 seller = sellerDAO.getPersonByUserId(sellerId); 90 seller.getItems().add(item); 91 item.setOwner(seller); 92 auctionItemDAO.createItem(item); 93 94 publishForSale(session, item); 95 timerService.createTimer(item.getEndDate(), new Long(item.getId())); 96 return item.getId(); 97 } 98 catch (JMSException ex) { 99 log.error("error publishing sell", ex); 100 ctx.setRollbackOnly(); 101 throw new EJBException("error publishing sell"); 102 } 103 catch (NoResultException ex) { 104 log.error("error locating information for sale, seller=" + seller, 105 ex); 106 ctx.setRollbackOnly(); 107 throw new MarketException("error locating information for sale, " + 108 "seller=" + seller + ":" + ex); 109 } 110 catch (Exception ex) { 111 log.error("error selling product", ex); 112 ctx.setRollbackOnly(); 113 throw new MarketException("error selling product:" + ex); 114 } 115 finally { 116 try { 117 if (session != null) { session.close(); } 118 if (connection != null) { connection.close(); } 119 } catch (JMSException ex) { 120 log.error("unable to close resources", ex); 121 } 122 } 123 } 124 125 protected void publishForSale(Session session, AuctionItem item) 126 throws JMSException { 127 MessageProducer producer = null; 128 try { 129 producer = session.createProducer(sellTopic); 130 MapMessage message = session.createMapMessage(); 131 message.setJMSType("forSale"); 132 message.setLong("id", item.getId()); 133 message.setString("name", item.getName()); 134 message.setString("seller", item.getOwner().getUserId()); 135 message.setLong("startDate", item.getStartDate().getTime()); 136 message.setLong("endDate", item.getEndDate().getTime()); 137 message.setDouble("minBid", item.getMinBid()); 138 message.setDouble("bids", item.getBids().size()); 139 message.setDouble("highestBid", 140 (item.getHighestBid() == null ? 0.00 : 141 item.getHighestBid().getAmount())); 142 producer.send(message); 143 log.debug("sent=" + message); 144 } 145 finally { 146 if (producer != null) { producer.close(); } 147 } 148 } 149 150 151 public AuctionItem getItem(long id) throws MarketException { 152 try { 153 AuctionItem item = auctionItemDAO.getItem(id); 154 AuctionItem dto = null; 155 if (item != null) { 156 dto = makeDTO(item); 157 log.debug("dao item=" + item); 158 log.debug("dto item=" + dto); 159 } 160 return dto; 161 } 162 catch (Exception ex) { 163 log.error("error getting auction item", ex); 164 throw new MarketException("error getting auction item" + ex); 165 } 166 } 167 168 protected AuctionItem makeDTO(AuctionItem item) { 169 AuctionItem dto = new AuctionItem(item.getId()); 170 dto.setStartDate(item.getStartDate()); 171 dto.setEndDate(item.getEndDate()); 172 dto.setMinBid(item.getMinBid()); 173 dto.setName(item.getName()); 174 dto.setProductId(item.getProductId()); 175 dto.setVersion(item.getVersion()); 176 dto.setBids(makeDTO(item.getBids(), dto)); 177 dto.setClosed(item.isClosed()); 178 dto.setWinningBid(getWinningDTO(item.getWinningBid(), dto)); 179 return dto; 180 } 181 182 protected List<Bid> makeDTO(List<Bid> bids, AuctionItem item) { 183 List<Bid> dtos = new ArrayList<Bid>(); 184 for(Bid bid : bids) { 185 Bid dto = new Bid(bid.getId()); 186 dto.setAmount(bid.getAmount()); 187 dto.setBidder(makeDTO(bid.getBidder(), dto)); 188 item.getBids().add(dto); 189 dto.setItem(item); 190 dtos.add(dto); 191 } 192 return dtos; 193 } 194 195 protected Bid getWinningDTO(Bid winningBid, AuctionItem item) { 196 Bid dto = null; 197 if (winningBid != null) { 198 for(Bid bid : item.getBids()) { 199 if (bid.getId() == winningBid.getId()) { 200 dto = bid; 201 break; 202 } 203 } 204 } 205 return dto; 206 } 207 208 protected Person makeDTO(Person person, Bid bid) { 209 Person dto = new Person(person.getId()); 210 dto.setName(person.getName()); 211 dto.setUserId(person.getUserId()); 212 dto.getBids().add(bid); 213 bid.setBidder(dto); 214 return dto; 215 } 216 217 @Timeout 218 public void timeout(Timer timer) { 219 try { 220 long itemId = ((Long)timer.getInfo()).longValue(); 221 endAuction(itemId); 222 } 223 catch (Exception ex) { 224 log.error("error ending auction for:" + timer.getInfo(), ex); 225 } 226 } 227 228 public void endAuction(long itemId) throws MarketException { 229 Connection connection = null; 230 Session session = null; 231 try { 232 AuctionItem item = auctionItemDAO.getItem(itemId); 233 if (item != null) { 234 item.closeBids(); 235 log.info("ending auction for:" + item); 236 237 connection = connFactory.createConnection(); 238 session = connection.createSession( 239 false, Session.AUTO_ACKNOWLEDGE); 240 publishSold(session, item); 241 } 242 } 243 catch (JMSException jex) { 244 log.error("error publishing jms message:", jex); 245 } 246 finally { 247 try { 248 if (session != null) { session.close(); } 249 if (connection != null) { connection.close(); } 250 } 251 catch (Exception ignored) {} 252 } 253 } 254 255 protected void publishSold(Session session, AuctionItem item) 256 throws JMSException { 257 MessageProducer producer = null; 258 try { 259 producer = session.createProducer(sellTopic); 260 MapMessage message = session.createMapMessage(); 261 message.setJMSType("sold"); 262 message.setLong("id", item.getId()); 263 message.setString("name", item.getName()); 264 message.setString("seller", item.getOwner().getUserId()); 265 message.setLong("startDate", item.getStartDate().getTime()); 266 message.setLong("endDate", item.getEndDate().getTime()); 267 message.setDouble("minBid", item.getMinBid()); 268 message.setDouble("bids", item.getBids().size()); 269 message.setString("buyerId", 270 (item.getWinningBid() == null ? 271 "" : 272 item.getWinningBid().getBidder().getUserId())); 273 message.setDouble("winningBid", 274 (item.getHighestBid() == null ? 0.00 : 275 item.getHighestBid().getAmount())); 276 producer.send(message); 277 log.debug("sent=" + message); 278 } 279 finally { 280 if (producer != null) { producer.close(); } 281 } 282 } 283 284 }