Module 6 Message-Driven Beans. History Introduced in EJB 2.0 –Supports processing of asynchronous...
-
Upload
shonda-ryan -
Category
Documents
-
view
219 -
download
0
Transcript of Module 6 Message-Driven Beans. History Introduced in EJB 2.0 –Supports processing of asynchronous...
History
• Introduced in EJB 2.0– Supports processing of asynchronous
messages from a JMS provider• Definition expanded in EJB 2.1
– Supports any messaging system• Annotations introduced in EJB 3.0
JMS and Message-Driven Beans
• All EJB 3.0 vendors must support a JMS provider
• JMS– Vendor neutral API used to access
enterprise messaging systems– Similar in concept to JDBC
JMS Terminology
• JMS Client– Applications that use JMS
• JMS Provider– System that handles routing and
delivery of messages• JMS Application
– Business system composed of many JMS clients and typically one JMS provider
• Producer– JMS client that sends a message
• Consumer– JMS client that receives a message
JMS in Action
• EJBs of all type can use JMS to send messages
• Messages consumed by other application or message-driven beans
Example using JMS
• TravelAgentBean
@Resource(mappedName=“ConnectionFactoryNameGoesHere”)private ConnectionFactory connectionFactory;
@Resource(mappedName=“TicketTopic”)private Topic topic;
@Removepublic TicketDO bookFlight (CreditCardDO card, double price)
throws IncompleteConversationalState {
if(customer == null || flight == null || seat == null)throw new IncompleteConversationalState();
Example using JMS
• TravelAgentBean
try {Reservation reservation = new Reservation(
customer, flight, seat, price, new Date());entityManager.persist(reservation);
process.byCredit(customer,card,price);TicketDO ticket = new TicketDO(customer, flight, seat, price);
Connection connect = connectionFactory.createConnection();Session session = connect.createSession(true,0);MessageProducer producer = session.createProducer(topic);TextMessage textMsg = session.createTextMessage();textMsg.setText(ticket.description);producer.send(textMsg);connect.close();
return ticket;} catch(Exception e) {
throw new EJBException(e);}
}
Message Types
• JMS Message is a Java Object– Header
•Delivery Information and Metadata– Message Body
•Text•Serializable Objects•Byte Streams•Other application data
Example using MapMessage
• TravelAgentBean
try {……TicketDO ticket = new TicketDO(customer, flight, seat,
price);……MessageProducer producer = session.createProducer(topic);MapMessage mapMsg = session.createMapMessage();mapMsg.setInt(“CustomerID”, ticket.customerID.intValue());mapMsg.setInt(“FlightID”, ticket.flightID.intValue());mapMsg.setInt(“SeatID”, ticket.seatID.intValue());mapMsg.setDouble(“Price”, ticket.price);producer.send(mapMsg);……
}
JMS is Asynchronous
• JMS client can send a message without having to wait for a reply
• Synchronous communication requires tight coupling between client and EJB
• Asynchronous communication decouples senders from receivers
JMS Messaging Models
• Publish-and-Subscribe (pub/sub)– One-to-Many broadcast– Topic– Push-based model
• Point-to-Point (p2p)– One-to-One delivery– Queue– Pull- or Polling-based model
Session Beans Should not Receive Messages
• Session beans (or entities) cannot be programmed to respond to JMS messages
• Can set up a business method that attempts to consume a JMS message but:– Method must be invoked
synchronously from EJB client– Method prone to blocking if no
message available• Bottom Line: Use Message-Driven
Beans instead!
Message-Driven Beans
• EJB– But no remote or local interface
• Stateless• Server-Side• Transaction-Aware• Processes Asynchronous Messages• Concurrent behavior because container
creates numerous instances
Message-Driven Bean
• ReservationProcessorBean
package edu.weber.reservationprocessor;import javax.jms.*;import edu.weber.domain.*;import edu.weber.processpayment.*;import edu.weber.travelagent.*;import java.util.Date;import javax.ejb.*;import javax.annotation.*;import javax.persistence.*;
@MessageDriven(activationConfig={@ActivationConfigProperty(
propertyName=“destinationType”,propertyValue=“javax.jms.Queue”),
@ActivationConfigProperty(propertyName=“messageSelector”,propertyValue=“MessageFormat=‘Version 3.4’”),
@ActivationConfigProperty(propertyName=“acknowledgeMode”,propertyValue=“Auto-acknowledge”)})
Message-Driven Bean
•ReservationProcessorBean
public class ReservationProcessBean implements javax.jms.MessageListener {
@PersistenceContext(unitName=“titanDB)private EntityManager em;
@EJBprivate ProcessPaymentLocal process;
@Resource(mappedName=“ConnectionFactory”)private ConnectionFactory connectionFactory;
Message-Driven Bean
• ReservationProcessorBean
public void onMessage(Message message) {try{
MapMessage reservationMsg = (MapMessage)message;
int customerPk = reservationMsg.getInt(“CustomerID”);int flightPk = reservationMsg.getInt(“FlightID”);int seatPk = reservationMsg.getInt(“SeatID”);double price = reservationMsg.getDouble(“Price”);
// get the credit card
Date expirationDate = new Date(reservationMsg.getLong(“CreditCardExpDate”);
String cardNumber = reservationMsg.getString(“CreditCardNum”);String cardType = reservationMsg.getString(“CreditCardType”);
CreditCardDO card = new CreditCardDO(cardNumber, expirationDate, cardType);
Message-Driven Bean
• ReservationProcessorBeanCustomer customer = em.find(Customer.class, customerPk);Flight flight = em.find(Flight.class, flightPk);Seat seat = em.find(Seat.class, seatPk);
Reservation reservation = new Reservation(customer, flight, seat, price, new Date());
em.persist(reservation);
process.byCredit(customer, card, price);
TicketDO ticket = new TicketDO(customer, cruise, cabin, price);
deliverTicket(reservationMsg, ticket);} catch (Exception e) {
throw new EJBException(e);}
}
Message-Driven Bean
• ReservationProcessorBeanpublic void deliverTicket(MapMessage reservationMsg, TicketDO ticket)
throws JMSException {
Queue queue = (Queue)reservationMsg.getJMSReplyTo();Connection connect =
connectionFactory.createConnection();Session session = connect.createSession(true, 0);MessageProducer sender =
session.createProducer(queue);ObjectMessage message =
session.createObjectMessage();message.setObject(ticket);sender.send(message);
connect.close();}
Message-Driven Bean Lifecycle
Does Not Exist
Method-ReadyPool
Class.newInstance()injections
@PostConstruct