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 }