Chapter 10. Enterprise services—email and messaging

 

This chapter covers

  • Roo support for enterprise services
  • Asynchronous messaging using a JMS topic
  • Email service
  • Asynchronous messaging using a JMS queue
  • Monitoring messaging activity

 

In the previous two chapters, you secured your Roo application by adding the Spring Security API to the application architecture mix, and you learned how to enrich the web tier of the Roo application so it’s functional from a business standpoint. In addition to robust security features and a rich user interface, a real-world application also requires services such as customer email notification and offline data processing that occurs outside of your main business operations, where your customers receive notifications about results at a later time.

In this chapter, we discuss the integration that the Roo framework provides for email and asynchronous messaging using the Java Message Service (JMS) API. We review three different use cases to demonstrate how to integrate email notifications and asynchronous messaging into real-world software applications. We look at Roo commands to set up the infrastructure for email and JMS components. And we define Spring bean components to abstract the connection configuration parameters to communicate with these enterprise services. Finally, you’ll generate the template code to send emails and post messages to a JMS topic and a queue.

By the end of this chapter, you’ll understand how to implement enterprise application services like email and JMS messaging. You’ll also be well versed on two design patterns: publish-subscribe (pub/sub) and point-to-point (PTP). With Roo’s built-in support for email and JMS services, you’ll also see why it’s easier to implement these requirements within your application if you use Roo.

We start with a brief overview of email and JMS support that comes out of the box with the Spring Roo framework. We also cover how messaging works, the types of messaging, and the details of how Roo implements email and messaging components in enterprise Java applications.

10.1. Roo integration with enterprise services

Roo includes excellent support for several enterprise services as well as Java Enterprise Edition (Java EE) resources such as email and messaging. Roo also makes it easy to install the various components (configuration files as well as application code) that you need to enable email and messaging functionality in a Java application.

10.1.1. Email support

Roo provides the mail commands to set up the three components you’ll need to implement the email notification capability. Let’s look at these three components:

  • Mail sender —This is the Spring Bean configuration for the JavaMailSenderImpl class and the SMTP mail server configuration parameters.
  • Email template —This is the Spring Bean configuration for the SimpleMail-Message class.
  • Template field —In a Java class (typically a controller or service class), the template field uses the template to send email messages.

Later in this chapter, you’ll learn how to create these components using code examples. But first you’ll need to become familiar with the asynchronous messaging paradigm and how it helps with offline processing requirements of Java applications.

10.1.2. Asynchronous messaging

Messaging is a communication method between software components where an application can send or receive messages to and from another application. Each application connects to a messaging agent (JMS broker) that provides facilities for creating, sending, receiving, and reading messages. Asynchronous messaging is based on a loosely coupled architecture in which the message sender and receiver don’t know anything about each other, and they don’t have to be available at the same time in order to communicate. This architecture is a core part of service-oriented architecture (SOA) and cloud computing (CC) architectures, both of which have been gaining more attention in recent years.

Figure 10.1 shows the architecture for asynchronous messaging, which includes two processes: Process A for posting a message to a message queue, and Process B for consuming the message from the queue and continuing to the next step in the process flow.

Figure 10.1. Asynchronous messaging architecture

JMS is a Java API that allows applications to create, send, receive, and read messages. The JMS API defines a common set of interfaces and associated semantics that allow Java applications to communicate with other messaging implementations.

In business use cases there are several advantages to using the asynchronous messaging architecture rather than a tightly coupled solution such as the Remote Procedure Call (RPC). These advantages include loose coupling, reliability, scalability, and message durability.

One of the use cases discussed later in this chapter (the course registration wait-list notification) is a good example of a use case that benefits from these advantages, and helps you implement JMS messaging using Roo commands.

The following sections briefly discuss the two messaging domains called publish-subscribe and point-to-point. The book Java Message Service by Mark Richards offers extensive coverage of the JMS topic. Another good resource is ActiveMQ in Action (http://www.manning.com/snyder/), which details messaging-oriented middleware application development using Apache’s ActiveMQ container.

Publish-Subscribe Messaging

In a publish-subscribe, or pub/sub, messaging scenario, a service component posts messages to a topic. Publishers and subscribers dynamically publish or subscribe to the topic. The messaging container takes care of distributing the messages arriving from a topic’s multiple publishers to its multiple subscribers. Topics retain messages only as long as it takes to distribute them to current subscribers. In this messaging domain, each message may have one or more message consumers. The JMS destination you use for processing the pub/sub communication is topic (which is represented by the Java class Topic in the javax.jms package). The architecture for publish-subscribe messaging is shown in figure 10.2.

Figure 10.2. Publish-subscribe messaging architecture

In the scenario represented in figure 10.2, a single process (publisher) can post a message to a queue that can be consumed and used by multiple other processes (subscribers 1 through 3).

Point-to-Point Messaging

The point-to-point pattern is built around the concept of message queues, senders, and receivers. Each message is addressed to a specific queue, and the receiving clients extract the messages from the queue or queues established to hold their messages. Queues retain all messages sent to them until the messages are consumed, or until the messages expire. In this domain, each message has only one consumer. The corresponding Java class for a JMS queue is the javax.jms.Queue class.

The JMS commands provided by Roo include the setup of JMS infrastructure components for the JMS container (with the ActiveMQ embedded broker, which makes it easier to unit test the asynchronous messaging logic in the application), JMS connection factory, and JMS destinations (topics or queues). Also included is a command for configuring the application-level JMS components and helper classes such as the JMS Template and the JMS Listener class.

If you have experience implementing asynchronous messaging using the JMS API in a Java application, you’ll understand how many different objects you need to create in order to send a simple message. The steps include the following JMS constructs: connection factories, destinations, connections, sessions, message producers, and message consumers or listeners (for receiving messages). Roo makes it easier to create all these messaging components by running just a few commands without having to write a lot of Java code or XML configuration..

These commands are discussed in more detail, using code examples, later in this chapter. The example use cases include messaging patterns from the Enterprise Integration Patterns[1] website.

1 If you’re working on any messaging-related applications in your organization, an excellent resource for messaging design patterns is the Enterprise Integration Patterns book by Gregor Hohpe and Bobby Woolf. Srini met Gregor at a Java symposium in 2004 and attended one of his sessions on EIP patterns.

Let’s get started by introducing the sample application. This application will include different use cases that use the asynchronous messaging paradigm.

10.2. Defining the sample Course Manager use cases

The business use cases for email and messaging services discussed in this chapter include course catalog distribution and course registration confirmation notification. The course catalog distribution use case involves publishing course catalog updates to a JMS topic, which trading partners subscribe to to get course updates. These trading partners can include institutions such as schools, community organizations, or other vendors. The course registration confirmation notification use case uses email and a JMS queue to notify customers who have successfully registered for a specific course.

The best way to see how these use cases work is to try them out in a sample application. Let’s do that with a look at three use cases in the Course Manager application (the two we discussed previously and a third called the course registration wait-list notification use case) that use email functionality and asynchronous messaging to implement the business requirements. Asynchronous messaging uses JMS technology and covers both the pub/sub and PTP messaging scenarios.

10.2.1. Use case 1: course catalog distribution

The Course Manager application will broadcast the course catalog updates by posting a course catalog message to a JMS topic. Then the trading partners who subscribe to this topic will receive the message to process it and update their information systems. Roo uses the ActiveMQ messaging container as the default JMS provider.

ActiveMQ is an open source, lightweight asynchronous messaging and integration patterns provider from the Apache team. It supports the JMS 1.1 and Java EE 1.4 specifications with support for transient, persistent, transactional, and XA messaging. ActiveMQ also supports advanced messaging features such as message groups, virtual destinations, wildcards, and composite destinations.

Integration with the Spring framework is available out of the box, so you can embed ActiveMQ into Spring applications easily and configure it using Spring’s XML configuration, which is what Roo does when you run the JMS commands. This feature benefits developers who follow test-driven development (TDD) techniques to test their application logic outside the container, without having to build and deploy the application every time they make a code change.

10.2.2. Use case 2: course registration confirmation notification

The second use case is the course registration confirmation notification. When students successfully register for a specific course, the requirement is that the Course Manager application immediately notifies them (via synchronous notification) that their registration has been successful, and provides a confirmation number.

10.2.3. Use case 3: course registration wait-list notification

The final use case you’ll implement is the course registration wait-list notification. When a student tries to register for a course that’s already full, the Course Manager program will capture the registration details and notify the student that their registration request has been placed on a waiting list. It will also notify the student again when someone else cancels their registration and there’s an open spot available for the course.

Let’s look more closely at each of these three use cases and implement them using Roo commands so you can see how the Roo framework supports enterprise services like email notification and asynchronous messaging.

10.3. Setting up JMS in the Course Manager

Your first step is to implement the course catalog distribution use case. In this section, you’ll create all of the messaging components needed for the use case. You do this using Roo JMS commands.

10.3.1. Course catalog updates

The process flow diagram for the course catalog distribution use case is shown in figure 10.3.

Figure 10.3. Course catalog distribution process flow

You’ll use Roo commands to create the JMS topic and the other messaging components needed to implement this use case. All the JMS commands are contained in the org.springframework.roo.addon.jms.JmsCommands class.

JMS Provider

The first step to enabling JMS capability is to install a JMS provider in your Roo project. Similar to the persistence setup command, the jms setup command requires you to specify the provider details such as the JMS provider type (a required argument), the destinationType (an optional argument; specify QUEUE or TOPIC), and the destinationName (also an optional argument). The following command is for the provider setup, where you’ll create a new JMS topic called CourseCatalogUpdate-Alerts to post the course catalog details:

jms setup --provider ACTIVEMQ_IN_MEMORY --destinationType TOPIC
    --destinationName jms.topic.CourseCatalogUpdateAlerts

The following example shows the console output for this command:

Created SRC_MAIN_RESOURCESMETA-INFspringapplicationContext-jms.xml
Managed SRC_MAIN_RESOURCESMETA-INFspringapplicationContext-jms.xml
Managed ROOTpom.xml [Added dependency org.springframework:spring-beans:${spring.version}]
Managed ROOTpom.xml [Added dependency org.springframework:spring-jms:${spring.version}]
Managed ROOTpom.xml [Added dependency org.apache.geronimo.specs:geronimo-jms_1.1_spec:1.1]
Managed ROOTpom.xml [Added dependency org.apache.activemq:activemq-core:5.3.2]
Managed ROOTpom.xml [Added dependency org.apache.xbean:xbean-spring:3.6]
roo>

In the previous example Roo added dependencies to the Maven build file (pom.xml). These dependencies are required to implement the JMS-related code in your application. These dependencies are shown in the following listing.

Listing 10.1. Maven dependencies for JMS-related code

The main JMS libraries you’ll need are the JMS API and the ActiveMQ API , respectively. The XBean library included in the Maven application build file in the previous listing allows you to run the ActiveMQ messaging broker by referencing an XML configuration file located in the classpath. The XBean URI points to an XML document, which can be parsed via the XBean API. You’ll need the Spring JMS JAR file to use Spring JMS classes, such as org.springframework.jms.core.JmsTemplate and org.springframework.jms.connection.CachingConnectionFactory, which simplify the JMS code in the application.

Roo also creates a new Spring configuration file called applicationContext jms.xml, which contains the Spring bean configuration details for all of the messaging components used in the application. The following listing shows this configuration.

Listing 10.2. The Spring context configuration file with JMS components

Note that the previous configuration file uses the ActiveMQ namespace (amq) , which simplifies the configuration syntax for defining the JMS components. Similarly, the Spring JMS namespace simplifies the configuration for Spring JMS classes (like jms:listener-container, shown in the previous configuration). The ActiveMQ messaging broker and the JMS connection factory beans are used to configure the infrastructure details of the JMS container.

The JMS connection factory used for the Spring JMS template is an instance of the CachingConnectionFactory class (located in the org.springframework.jms .connection package) . The advantage of using the CachingConnectionFactory class is to avoid creating a connection for each request to post a message to the JMS destination. In the next section you’ll see how Spring’s JMS template works. The JMS topic you’ll use for this use case is defined by the amq:topic element with a JNDI name of jms.topic.CourseCatalogUpdateAlerts.

JMS Template

The next step is to add a JmsTemplate attribute into an existing class (usually a controller or a service class). The JMS template creation command requires two parameters: fieldName for the name of the field to add (default is jmsTemplate), and class, which is the name of the class to receive this field. Let’s type in the command field jms template, which creates the template attribute and shows the following output:

Managed SRC_MAIN_JAVAcom
ooinactioncoursemanagerwebCourseCatalogController.java
~.web.CourseCatalogController roo>

The JMS template field and a new method called sendMessage have been added to the controller class, as shown in the following code.

Listing 10.3. Controller class with JMS logic

In the previous code example, the new variable jmsTemplate is used for injecting the instance of JmsTemplate into the controller class. The sendMessage method is where you add your custom business logic for posting the message into the JMS destination (topic).

JMS Listener

The third step in the JMS setup is to create a JMS consumer class. You’ll use the command jms listener class for this step. The command takes three parameters: class (mandatory parameter to specify the name of the class to create the JMS listener), destinationName to specify the name of the destination (default value for this parameter is myDestination), and destinationType, which is used to define the type of the destination (default is QUEUE).

Type in the following command specifying the custom names you want for your JMS components:

jms listener class --class ~.messaging.  JmsCourseCatalogUpdateTopicListener --destinationType TOPIC   --destinationName jms.topic.CourseCatalogUpdateAlerts

Here’s the output of this command:

Created SRC_MAIN_JAVAcom
ooinactioncoursemanagermessaging
Created SRC_MAIN_JAVAcom
ooinactioncoursemanagermessagingJmsCourseCatalogUpdateTopicListener.java
Managed SRC_MAIN_RESOURCESMETA-INFspringapplicationContext-jms.xml
~.web.CourseCatalogController roo>

Roo adds the JMS configuration in the applicationContext-jms.xml file, as shown in the following listing.

Listing 10.4. Configuration for JMS listener components

The JmsCourseCatalogUpdateTopicListener class is where you’ll write the logic on how to process the message received from the CourseCatalogUpdateAlerts JMS topic. The Spring JMS module makes it easier to expose a POJO as a message-driven component with the help of the JMS listener container component.

There’s also a new Java class, JmsCourseCatalogUpdateTopicListener, added in the package you specified (org.rooinaction.coursemanager.messaging). This new class has a placeholder method called onMessage that you can use to add your business logic to do the processing when a message is posted in the CourseCatalogUpdateAlerts JMS topic, as shown in the following example:

package org.rooinaction.coursemanager.messaging;

public class JmsCourseCatalogUpdateTopicListener {

    public void onMessage(Object message) {
        System.out.println("JMS message received: " + message);
    }
}

 

Note

Because this JMS destination is the same Topic where you post the message from the controller class, make sure the destinationName parameter in step 3 has the same value as the destinationName parameter specified in the JMS provider setup (step 1).

 

10.3.2. Testing the course catalog distribution use case

With the required JMS setup complete, you’re ready to test and validate the JMS broadcast functionality in the Course Manager application. But if you want to do this testing using the web application inside an application server container, you’ll have to compile, build, and deploy the web application to the container before you can do any testing. You’ll also need to launch the application, navigate to the home page, update the course catalog, and publish it. All of these steps take time, which could impact your development time and progress. So, in the spirit of agile software development and unit testing, you’ll create few test client classes to make your job easier and your testing faster.

You’ll post the message to the JMS topic using Spring’s JMS template class in the test client. This gives you an easy way to publish and intercept the events that you can use to unit test the JMS functionality from within the IDE, without having to build and deploy the web application to the container.

The following listing shows the code for the JUnit test class, CourseCatalogUpdateEventPublisherTest, that you’ll create to test JMS functionality.

Listing 10.5. JUnit test class for testing course catalog distribution event
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
        "classpath:/META-INF/spring/applicationContext.xml",
        "classpath:/META-INF/spring/applicationContext-jms.xml"
    })
public class CourseCatalogUpdateEventPublisherTest {

    private static final Log log = LogFactory.getLog(CourseCatalogUpdateEventPublisherTest.class);

    @Autowired
    private transient JmsTemplate jmsTopicTemplate;

    @Test
    public void verifyCourseCatalogUpdateEventIsSuccessful() {

        String courseCatalogEvent = "Test CourseCatalogEvent Message.";
        log.debug("CourseCatalogEvent: " + courseCatalogEvent);

        // Post the message to JMS Destination
        sendMessage(courseCatalogEvent);
    }

    private void sendMessage(Object messageObject) {
        jmsTopicTemplate.convertAndSend(messageObject);
    }
}

When you run the unit test class, you’ll see that when the CourseCatalogUpdateEvent occurs, the message listener (JmsCourseCatalogUpdateTopicListener) will get the program control and process the JMS message.

That’s all of the steps required to enable the publish-subscribe messaging feature for the course catalog distribution use case. We’ll come back to the point-to-point messaging domain later in the chapter, but next we’ll look at how to integrate the email notification feature in a Roo application. This is covered in the following section as part of the course registration confirmation notification use case.

10.4. Adding email support for course registration

The course registration confirmation notification use case involves a synchronous process, so you want to ensure that all steps in the process are successfully completed before a confirmation email is sent to a student. The process flow details for this use case are shown in figure 10.4.

Figure 10.4. Course registration confirmation notification use case

There are three main steps to implement the course registration confirmation notification use case, which we’ll cover in detail in the following section. These steps include defining the SMTP server configuration, the email message template, and the email template attribute.

10.4.1. Registration confirmation via email

Similar to the JMS configuration, the main steps to enable the SMTP configuration using Roo mail commands include setting up the SMTP server and email message template, and adding the mail template attribute in a Java class (usually controller or service). For your sample application, you’ll also create a custom Java class to encapsulate the email processing application logic so any class in the application can use this helper class for the notification requirements, without having to duplicate the same logic in multiple classes. The next few sections show the different mail commands you’ll use to enable the email feature in your sample application. Roo’s mail commands are contained in the org.springframework.roo.addon.email.MailCommands class.

Java Class for Email Processing

Before you set up the email configuration, you need to create an interface and an implementation class for encapsulating the email processing logic to decouple it from the application logic.

The Roo shell supports creating new Java interfaces or classes from the command line using interface or class commands, respectively. You first create an interface called NotificationService. Type in the following command on the Roo shell:

interface --class ~.email.NotificationService

Roo creates the Java interface in the specified package and displays the following output:

Created SRC_MAIN_JAVAorg
ooinactioncoursemanageremail
Created SRC_MAIN_JAVAorg
ooinactioncoursemanageremailNotificationService.java
~.email.NotificationService roo>

Now, run the class command to create the skeleton for the implementation class called NotificationServiceImpl:

class --class ~.email.NotificationServiceImpl

Here’s the output of the class command:

Created SRC_MAIN_JAVAorg
ooinactioncoursemanageremailNotificationServiceImpl.java
~.email.NotificationServiceImpl roo>

Now that you have the helper class (and its interface that the client classes can use to delegate the email processing logic), you’re ready to build the infrastructure components of the email configuration. First among these components is the email sender (SMTP server).

Email Sender

The email sender setup command installs Spring’s JavaMailSender in this project. This command takes several parameters with the information required to configure the Spring bean configuration for the JavaMailSenderImpl class. Here’s a list of these parameters and what information they provide to the command.

  • hostServer—SMTP host server (required parameter)
  • protocol—Used by the mail server (for example, SMTP)
  • port—Number used by mail server
  • encoding—Used for sending mail messages
  • username—For the SMTP account
  • password—For the SMTP account

To set up the SMTP server configuration, use the following command:

roo> email sender setup --hostServer smtp.gmail.com --protocol SMTP   --port 587 --username rooinaction --password yourpassword

And here’s the output on the Roo console:

Managed SRC_MAIN_RESOURCESMETA-INFspringapplicationContext.xml
Managed ROOTpom.xml [Added dependency org.springframework:  spring-context-support:${spring.version}]
Managed ROOTpom.xml [Added dependency javax.mail:mail:1.4.1]
Managed ROOTpom.xml [Added dependency javax.activation:  activation:1.1.1]
Created SRC_MAIN_RESOURCESMETA-INFspringemail.properties

This command creates a new properties file called email.properties to store the SMTP server connection parameters. It also adds the mailSender Spring bean configuration to the applicationContext.xml file. The following listing shows the SMTP configuration details.

Listing 10.6. SMTP provider configuration
<bean class="org.springframework.mail.javamail.JavaMailSenderImpl"         id="mailSender">
     <property name="host" value="${email.host}"/>
     <property name="protocol" value="${email.protocol}"/>
     <property name="port" value="${email.port}"/>
     <property name="username" value="${email.username}"/>
     <property name="password" value="${email.password}"/>
     <property name="javaMailProperties">
         <props>
             <prop key="mail.smtp.auth">true</prop>
             <prop key="mail.smtp.starttls.enable">true</prop>
         </props>
     </property>
</bean>

In a real-world application, you should define the SMTP server as a JNDI resource. For example, to configure an SMTP session as a JNDI object in a Tomcat container, you’d add a new Resource element in the configuration to Tomcat’s context.xml file. This configuration is shown in the following listing.

Listing 10.7. In-container JNDI resource configuration for SMTP provider
<?xml version="1.0" encoding="UTF-8"?>

<Context path="/myapp" docBase="myapp" debug="5" crossContext="false">

    <Resource name="mail/Session"
              auth="Container"
              type="javax.mail.Session"
              username="smtp_user_name"
              password="smtp_password"
              mail.debug="true"
              mail.user="username"
              mail.password="password"
              mail.transport.protocol="smtp"
              mail.smtp.host="SMTP_HOST_NAME"
              mail.smtp.auth="true"
              mail.smtp.port="25"
              mail.smtp.starttls.enable="true"/>
</Context>

The previous configuration will create a new SMTP resource in the Tomcat container and will be available for all web applications running on the servlet container. This configuration is straightforward, but let’s look at how to view and modify the SMTP properties in the file generated by Roo.

View and Modify SMTP Properties

You can use the Roo shell command called properties to view and modify the contents of properties files like the email.properties file created in the previous step. Let’s check the contents and modify one of the properties in this file. First, to view the email.properties file contents, type in the following command:

properties list --name email.properties --path SPRING_CONFIG_ROOT

The output of this command is shown in the following example:

email.host = smtp.gmail.com
email.password = yourpassword
email.port = 587
email.protocol = smtp
email.username = rooinaction
roo>

Let’s modify the password property in this file. You can do this by using the properties command with the set argument. Here’s the example:

properties set --name email.properties --path SPRING_CONFIG_ROOT --key email.password --value newpassword

It shows the following message, which says that the properties file has been updated:

Managed SRC_MAIN_RESOURCESMETA-INFspringemail.properties
roo>

You can call the properties list command again to view an update. A different command will display all of the properties of the Roo shell. This command is system properties, which displays the following output (abbreviated to show only the first few entries).

Listing 10.8. Command output for system properties
awt.toolkit = sun.awt.windows.WToolkit
developmentMode = false
felix.auto.deploy.dir = C:devframeworksRoospring-roo-1.2.0.  RELEASEundle
felix.config.properties = file:C:devframeworksRoospring-roo-1.2.0.  RELEASEconfconfig.properties
file.encoding = Cp1252
file.encoding.pkg = sun.io
file.separator = 
flash.message.disabled = false
java.awt.graphicsenv = sun.awt.Win32GraphicsEnvironment
java.awt.printerjob = sun.awt.windows.WPrinterJob
....

After you’ve modified the SMTP properties to fit your application requirements, you’re ready to create the SMTP message template.

Email Message Template

You need to create the email template that the Spring framework will use to send the email messages. The command email template setup configures a template for the SimpleMailMessage class using two parameters: from and subject. Type in the following command:

email template setup --from [email protected] --subject "Course Registration Confirmation"

The output of the previous command looks like this:

Managed SRC_MAIN_RESOURCESMETA-INFspringapplicationContext.xml
Managed SRC_MAIN_RESOURCESMETA-INFspringemail.properties
roo>

This command adds the following two additional properties to the email.properties file:

[email protected]
email.subject=Course

This command also adds a new Spring bean definition in the applicationContext.xml file for the MailMessage template class with the from and subject attributes set to the specified values in the command line:

<bean class="org.springframework.mail.SimpleMailMessage" id="templateMessage">
        <property name="from" value="${email.from}"/>
        <property name="subject" value="${email.subject}"/>
    </bean>
Email Template Attribute in Service Class

In this last step, you set up the email template attribute in the newly created custom NotificationService class. Type in the following command:

field email template --fieldName mailTemplate --class ~.email.NotificationServiceImpl

Here’s the command output:

Managed SRC_MAIN_JAVAorg
ooinactioncoursemanageremailNotificationServiceImpl.java

The NotificationServiceImpl class will now look like that shown in the following listing.

Listing 10.9. Notification service implementation class

This class has the attributes for the SMTP mail server and Spring’s MailMessage implementation class to abstract the email send logic. The sendMessage method has the email notification code.

You can now run the Eclipse command, perform eclipse, to refresh the project contents so the Roo project is refreshed with all of the code and configuration changes you’ve made so far.

10.4.2. Testing the course registration confirmation notification use case

You’ll create a test client class similar to the way you tested the JMS functionality to verify the registration notification functionality. The following listing shows the code example of the test class RegistrationNotificationEventPublisherTest.

Listing 10.10. JUnit test class for course registration confirmation notification
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
        "classpath:/META-INF/spring/applicationContext.xml"
    })
public class RegistrationNotificationEventPublisherTest {

    @Autowired
    private NotificationService notificationService;

    @Test
    public void verifyThatRegistrationNotificationIsSuccessful() {
        // Send e-mail notification
        String mailTo = "[email protected]";
        String message = "Registration Successful.";
        notificationService.sendMessage(mailTo, message);
    }
}

Now that we’ve covered the first two use cases in the Course Manager sample application, you know how to enable the JMS (pub/sub) and email features in Roo applications. Let’s look at the step-by-step details for implementing point-to-point asynchronous messaging, which involves a queue (as opposed to a topic).

10.5. Asynchronous messaging for registration confirmation

The course registration wait-list notification use case involves asynchronous messaging, where the main business process stops when a customer’s registration request is placed on the waiting list. After this step, the offline (asynchronous) processing takes over. The offline processing includes a JMS queue-based messaging solution, which uses a CourseRegistrationCancellationEvent to unregister a customer who wants to cancel a registration. The program then notifies the first customer on the waiting list that there’s an open spot in the course and their registration has now been confirmed.

Let’s look at how you would implement this use case in a Roo application.

10.5.1. JMS configuration

Similar to the first use case covered in this chapter, the JMS configuration for the course registration wait-list notification use case includes steps for setting up the JMS queue, called CourseRegistrationWaitListQueue. You’ll use the same JMS provider (ActiveMQ messaging server) you created in that use case and create a message queue on that JMS container. This use case requires three steps, which include creating a new message queue, a JMS template, and a message listener class.

Message Queue

The first step in the JMS configuration for this use case is to create a message queue that will be used to post the course registration wait-list notification details. Here’s the JMS command to add the configuration for a JMS Queue with the name jms.queue.CourseRegistrationWaitListQueue:

jms setup --provider ACTIVEMQ_IN_MEMORY --destinationType QUEUE --destinationName jms.queue.CourseRegistrationWaitListQueue

The message queue configuration step adds a new amq:queue Spring bean in the JMS Spring configuration file. As shown in the following snippet, a JMS queue (amq:queue) and a JMS listener container (jms:listener-container) for mapping the queue to the JMS provider are added to the applicationContext-jms.xml file:

<amq:queue id="jms.queue.CourseRegistrationWaitListQueue" physicalName="jms.queue.CourseRegistrationWaitListQueue"/>
<jms:listener-container connection-factory="jmsFactory" destination-type="queue"/>
JMS Template Field

After you configure the message queue component, the next step is to add a JMS template to the helper Java class, which in this case is the CourseRegistrationNotificationHelper class. Here’s the command for this configuration:

field jms template --fieldName jmsTemplate --class ~.web.CourseRegistrationNotificationHelper

As the following command-line output shows, Roo added the JMS template attribute (jmsTemplate) to the CourseRegistrationNotificationHelper Java class:

Updated SRC_MAIN_JAVAorg
ooinactioncoursemanagerwebCourseRegistrationNotificationHelper.java
~.web.CourseRegistrationNotificationHelper
roo>
JMS Listener

Now for the final step: you need to add a listener class that acts as an asynchronous message consumer. The following is the Roo command for the message listener configuration:

jms listener class --class ~.messaging.JmsCourseRegistrationWaitListQueueListener --destinationType QUEUE --destinationNamejms.queue.CourseRegistrationWaitListQueue

Roo creates a new Java class called JmsCourseRegistrationWaitListQueueListener with a stub for the onMessage() method. It also updates the applicationContext jms.xml file, as shown in the following output:

Created SRC_MAIN_JAVAorg
ooinactioncoursemanagermessagingJmsCourseRegistrationWaitListQueueListener.java
Managed SRC_MAIN_RESOURCESMETA-INFspringapplicationContext-jms.xml

The following Spring bean element for the JmsCourseRegistrationWaitListQueue-Listener class is added to the XML configuration file:

<bean class="org
ooinactioncoursemanager.messaging.JmsCourseRegistrationWaitListQueueListener" id="jmsCourseRegistrationWaitListQueueListener"/>

With the configuration steps complete, you’re now ready to test the new Java classes and configuration changes for the course registration wait-list notification use case.

10.5.2. Testing JMS setup for wait-list notification

To test the course registration wait-list notification functionality, you need to post a message to the JMS queue and process the message using the listener class. Let’s write a new unit test class (called RegistrationNotificationWaitListEventPublisherTest) to test the wait-list scenario. The following listing shows the code for this unit test.

Listing 10.11. JUnit test class for course registration wait-list notification
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
        "classpath:/META-INF/spring/applicationContext.xml",
        "classpath:/META-INF/spring/applicationContext-jms.xml"
    })
public class RegistrationNotificationWaitListEventPublisherTest {

    private static final Log log = LogFactory.getLog(          RegistrationNotificationWaitListEventPublisherTest.class);
    @Autowired
    private transient JmsTemplate jmsQueueTemplate;

    @Test
    public void verifyRegistrationWaitListNotificationIsSuccessful() {

        String regNotifyWaitListEvent = "Test regNotifyWaitList Message.";

        log.debug("regNotifyWaitListEvent: " + regNotifyWaitListEvent);

        // Post the message to JMS Destination
        sendMessage(regNotifyWaitListEvent);
    }

    private void sendMessage(Object messageObject) {
        jmsQueueTemplate.convertAndSend(messageObject);
    }
}

10.5.3. Course completion certificate use case

Another good case for using JMS messaging is the certificate completion use case. Let’s say the Course Manager application organization outsources the process of printing the course completion certificates and mailing them to the students. You can use the Trading Partner user role (ROLE_TRADING_PARTNER), for example, to notify of the course completion event and provide the student details. This allows the course completion certificate with the student’s information to be generated and sent to the student.

As previously discussed in this chapter, there are several different components that are working together in a typical enterprise messaging application to send, receive, and process the various business message objects. This is why it’s important to monitor these JMS components to see what’s going on behind the scenes of the application to be able to respond to any production problems and troubleshoot the messaging-related issues. This is what we’ll look at in the next section on how to monitor the Course Manager application using tools like VisualVM.

10.6. Monitoring messaging activity

Now that you’ve implemented all of the use cases, let’s look at how to monitor your application to ensure that the various JMS resources you’ve installed and configured (JMS container, JMS topic, and JMS queue) are up and running, as well as how many messages they’re processing.

The Java standard for application and system or server monitoring is the Java Management Extensions (JMX). For JMS message activity monitoring purposes, Roo provides a JMS add-on that enables monitoring (JMX) support by default. So you can check the JMS message activity using tools such as JConsole, VisualVM, or any other JMX client.

To turn on the monitoring capability in the ActiveMQ messaging broker, you’ll use the useJmx parameter (with a value of true) in the amq:broker element. After you make this change and restart the messaging server, you can use the following URL to connect to the ActiveMQ Broker JMX MBean server: service:jmx:rmi:///jndi/rmi:// localhost:1099/jmxrmi.

After you’ve enabled the JMX feature in the ActiveMQ broker, you can use a JMX client to monitor the messaging activity in the application in a server runtime environment.

10.6.1. Application monitoring using VisualVM JConsole

The VisualVM tool comes bundled with the JDK installation, with the jvisualvm and jconsole executable files located in the%JAVA_HOME%/bin directory. Note that JAVA_HOME is the folder where you installed JDK on your machine. The JConsole module in VisualVM can be used for monitoring the MBean components.

Open a new command prompt and run the following commands to launch the VisualVM tool:

set JAVA_HOME="C:Program FilesJavajdk1.6.0_22"

set PATH=%PATH%;%JAVA_HOME%in;

cd %JAVA_HOME%in

jconsole service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi

Figure 10.5 shows the MBean screen in the JConsole JMX client tool.

Figure 10.5. Messaging activity details using the JConsole JMX client

Another monitoring tool you can use in nonproduction environments is the new Spring Insight product from the SpringSource group (http://www.springsource.org/insight).

10.6.2. Application monitoring using Spring Insight

Spring Insight provides a graphical look at an application’s performance, response-time charts, and histograms, providing developers with a dashboard view into the application’s runtime environment to find where it’s spending most of its time in the program flow.

Spring Insight gives visibility into the application performance for each web request made in the web application. You can see all of the JDBC requests made, how much time it took to render the web pages, or the initialization times for any of the Spring beans. Also, the Application Health screen shows which Spring MVC controllers are taking considerable time and allows you to drill down into the details of the requests that took longer times. You can also navigate to specific remote web service calls that were made.

Spring Insight uses the AspectJ load-time weaving feature to add the tracing and monitoring statistics to web applications. This means your sample application doesn’t require any additional code or configuration changes to use Spring Insight. Also, Spring Insight collects the response data in memory and doesn’t require a backend database or a persistent data store.

VMware vFabric tc Server, Developer Edition (formerly known as SpringSource tc Server: http://mng.bz/LDGg) includes the Spring Insight monitoring module. The SpringSource Tool Suite (STS) IDE tool also bundles with Spring Insight. If you’re using the STS tool, you already have Spring Insight available for you to monitor your application’s performance and other server metrics.

At the time of this writing, Spring Insight doesn’t have a plug-in for JMS, but it’s on the feature list to be added in a future release. You can still see the components that were triggered by a JMS message. For example, if the JMS message listener calls any Spring bean component (such as a Java class that uses one of these annotations: @Service, @Repository, or @Controller), it will be displayed on the Spring Insight dashboard.

Note that Spring Insight shouldn’t be used in a production environment because it displays a detailed view of all of your application’s performance details, including sensitive information about the application and server settings. It’s meant for developers and QA testers to get runtime visibility into the applications in nonproduction environments. The Spring Insight reference manual (see the “Resources” section at the end of this chapter) is a good resource for learning more about this application monitoring framework.

Let’s use the Spring Insight tool to monitor the activity in your application, including JMS messaging activity. You’ll need this URL to view the dashboard: http://localhost:8080/insight/traces.

Open a web browser and navigate to the Spring Insight dashboard page using the previously mentioned URL. Click on the Browse Resources tab and expand the web application node in the Resources pane under the application’s root node.

When you run the Course Manager application and test the course registration functionality, you can see the details of the controller classes being called, and the messages being sent to JMS destinations (CourseCatalogUpdateAlerts topic and CourseRegistrationWaitListQueue queue) and consumed by the corresponding JMS listener objects. These details are shown in figure 10.6.

Figure 10.6. Spring Insight’s application monitoring dashboard

As you can see, it’s a straightforward process to enable the monitoring of messaging components in the Course Manager application using the JMX monitoring technology. You can view the attributes of various JMS components as well as invoke the operations (methods) of these components to dynamically change the JMS configuration parameters.

10.7. Summary

In this chapter, you learned how to send email notifications to your Course Manager application customers (students) from within the Spring Roo application, without having to write or configure the setup for the email provider, email processing logic, and so on. Roo’s email add-on makes it easier because it requires only a few commands to set up the SMTP provider and add Spring’s email template classes into your application.

You’ve also learned how to implement asynchronous messaging for business use cases that require offline processing capability, such as the course catalog distribution and the course registration wait-list notification use cases. You were able to do this by leveraging another Roo add-on, the JMS add-on, provided by the Roo framework. You also reviewed the publish-subscribe pattern (use case 1: course catalog distribution) as well as the point-to-point messaging pattern (use case 3: course registration wait-list notification) in this chapter.

At this point in the book, all of the chapter discussions on the Roo application have been based on it being deployed on a server hosted by an organization’s internal server environment. What if you want to deploy the same Roo application on a third-party server (or servers, in the case of a server cluster) hosted outside of an organization, at an external third-party site, on what’s called a cloud? With the cloud computing paradigm gaining attention over the last few years, cloud hosting has become a popular choice for software implementations.

We discuss cloud computing in chapter 13, where we’ll deploy the Course Manager application to the Cloud Foundry server environment. Roo once again provides excellent support for moving the Course Manager application to an externally hosted server environment. But before that, in the next two chapters, we’ll look at how to create custom add-on components using the Roo framework.

10.8. Resources

ActiveMQ Messaging/JMS Container (http://activemq.apache.org/)

Apache Velocity Framework (http://velocity.apache.org/)

Enterprise Integration Patterns (http://www.eaipatterns.com/)

Java Management Extensions (JMX) Technology (http://mng.bz/3k5z)

Java Message Service (JMS) (http://mng.bz/vEJP)

JMS (Java Message Service), for information about message-driven POJOs in Spring (http://mng.bz/ni05)

Spring Insight main page (http://www.springsource.org/insight)

Using JConsole (http://mng.bz/4LPo)

Using Spring Insight (reference manual) (http://mng.bz/hHFU)

VisualVM (http://visualvm.java.net/)

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

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