Using MDB in a publish-and-subscribe application

The publish-and-subscribe architecture can be useful in keeping track of the availability of individuals. In this recipe, we will develop an application that uses a topic to monitor and record when a person is available. That is, when a person is at his/her desk, logged on to a computer or otherwise able to respond to requests.

Getting ready

A topic is similar to a queue. Messages are sent to a topic just as they are sent to a queue. However, once there they may be accessed by more than one consumer. The essential structure of a servlet used to generate a message was introduced in the introduction. Here we will address the unique elements of creating and using a topic to support a publish-and-subscribe application which include:

  1. Creating a message and sending it to the topic
  2. Registering a subscriber for the topic
  3. Receiving and processing the message

How to do it...

Create a Topic named jms/AvailabilityTopic and a TopicConnectionFactory named jms/AvailabilityFactoryPool as described in the introduction. Next, create a new Java EE application called PublishAndSubscribeApplication. In the EJB module add a package called packt and three classes:

  • Availability a simple Java class representing the availability of an individual
  • LoggingBean an MDB that logs a person's availability
  • SubscriberBean an MDB that may be interested in whether someone is available or not

In the WAR module add a package called servlet with a servlet called AvailabilityServlet.

The Availability class associates a name with that person's availability. It consists of a string variable for a name and a Boolean variable to indicate whether they are available or not. The class must implement the Serializable interface otherwise the object cannot be sent as part of a message.

import java.io.Serializable;
public class Availability implements Serializable {
private String name;
private boolean available;
public Availability(String name, boolean available) {
this.name = name;
this.available = available;
}
public boolean isAvailable() {
return available;
}
public String getName() {
return name;
}
}

Next, create the AvailabilityServlet as listed below. The doGet and doPost methods are not shown.

public class AvailabilityServlet extends HttpServlet {
private Availability availability;
@Resource(mappedName="jms/AvailabilityFactoryPool")
private TopicConnectionFactory topicConnectionFactory;
@Resource(mappedName="jms/AvailabilityTopic")
private Topic topic;
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
Connection connection;
availability = new Availability("Tom",true);
try {
connection = topicConnectionFactory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer messageProducer = (MessageProducer) session.createProducer(topic);
ObjectMessage availabilityMessage = session.createObjectMessage(availability);
availabilityMessage.setStringProperty("test", "tested");
messageProducer.send(availabilityMessage);
System.out.println("---> availability status sent");
} catch (JMSException ex) {
Logger.getLogger(AvailabilityServlet.class.getName()). log(Level.SEVERE, null, ex);
}
out.println("<html>");
Message-Driven Bean (MDB)using, in publish-and-subscribe applicationout.println("<head>");
out.println("<title>Servlet AvailabilityServlet</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Servlet AvailabilityServlet at " + request.getContextPath () + "</h1>");
out.println("</body>");
out.println("</html>");
} finally {
out.close();
}
}

We will use two MDBs. The LoggingBean EJB logs an individual's availability for later analysis. The SubscriberBean EJB listens to the messages and indicates it has received the message.

Add the LoggingBean as follows:

@MessageDriven(mappedName = "jms/AvailabilityTopic", activationConfig = {
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
@ActivationConfigProperty(propertyName = "subscriptionDurability", propertyValue = "Durable"),
@ActivationConfigProperty(propertyName = "clientId", propertyValue = "LoggingBean"),
@ActivationConfigProperty(propertyName = "subscriptionName", propertyValue = "LoggingBean")
})
public class LoggingBean implements MessageListener {
public LoggingBean() {
}
public void onMessage(Message message) {
Message-Driven Bean (MDB)using, in publish-and-subscribe applicationObjectMessage objectMessage = (ObjectMessage) message;
try {
Availability availability = (Availability) objectMessage.getObject();
if(availability.isAvailable()) {
Logger.getLogger(LoggingBean.class.getName()). log(Level.SEVERE, availability.getName() + " is available");
} else {
Logger.getLogger(LoggingBean.class.getName()). log(Level.SEVERE,
availability.getName() + " is not available");
}
System.out.println("---> logging ");
} catch (JMSException ex) {
Logger.getLogger(LoggingBean.class.getName()). log(Level.SEVERE, null, ex);
}
}
}

Create the SubscriberBean next.

@MessageDriven(mappedName = "jms/AvailabilityTopic", activationConfig = {
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
@ActivationConfigProperty(propertyName = "subscriptionDurability", propertyValue = "Durable"),
@ActivationConfigProperty(propertyName = "clientId", propertyValue = "SubscriberBean"),
@ActivationConfigProperty(propertyName = "subscriptionName", propertyValue = "SubscriberBean")
})
public class SubscriberBean implements MessageListener {
public SubscriberBean() {
}
public void onMessage(Message message) {
System.out.println("---> subscriber ");
}
}

Execute the AvailabilityServlet. You will observe the following output in the console window:

INFO: ---> availability status sent

INFO: ---> subscriber

SEVERE: Jonathan is available

INFO: ---> logging

How it works...

The AvailabilityServlet created a message that was sent to a topic. The @Resource annotation injected a TopicConnectionFactory and a Topic. This chapter's introduction discusses the process for establishing a connection to a queue. The approach is essentially the same for a topic except a topic is used instead of a queue.

Notice how the Availability object was created and sent. An ObjectMessge was used for the message and is discussed in the Handling an object-based message recipe earlier in this chapter.

The LoggingBean is responsible for maintaining a log of the availability of individuals. The @MessageDriven annotation used the mappedName attribute to specify the topic used. Two @ActivationConfigProperty elements were used to specify the acknowledgement mode and that the destination was a topic. In addition, three other @ActivationConfigProperty elements were set for the topic:

  • subscriptionDurability Durable
  • clientId LoggingBean
  • subscriptionName LoggingBean

A durable message is held in the topic temporarily if the subscriber happens to become temporarily unavailable. It is sent to the subscriber once the subscriber is able to receive the message. However, it is necessary for the subscriber to register with the topic using a unique clientId and subscriptionName as affected by the @ActivationConfigProperty annotation.

The onMessage method retrieved the Availability object and used the isAvailable method to determine whether the individual was available or not. It then logged a message to that effect.

The SubscriberBean represents an individual or entity that is interested in knowing whether someone is available or not. Its @MessageDriven annotation is similar to the LoggingBean. The onMessage implementation simply displayed a message indicating the subscriber has handled the message.

See also

The Using an MDB in a point-to-point application recipe illustrates another common strategy for using MDBs. Also, the Handling an object-based message recipe details the use of the ObjectMessage.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.235.188