IBM WebSphere Application Server V6 provides a new application messaging platform built on the Service Integration Bus (SIB), a highly available, highly scalable communications pipeline that abstracts applications from the network topology connecting them, enabling applications to transparently plug into the bus and participate in message exchanges. The new messaging platform is a JMS-compliant messaging provider that connects the applications using the SIBus and provides each application with local, in-process access to the messaging server. The SIBus also provides other features needed to connect the components in a service-oriented architecture (SOA): message mediation, invocation of Web services, protocol translation between HTTP Web services and JMS, and so on. For an introduction to SIBus, see the Building an Enterprise Service Bus series of articles.
The messaging platform supports both JMS messaging models:
The article Deploying message-driven beans and JMS applications into the Service Integration Bus explains how to configure the SIBus for point-to-point applications. In this article, we will describe how to configure the SIBus to support publish/subscribe applications, explain how the SIBus supports these applications, briefly introduce publish/subscribe terminology, and show how to deploy a sample application to test the configuration.
A brief overview of publish/subscribe
Unlike the point-to-point messaging model, in which the messaging system delivers each message on a queue to a single recipient, publish/subscribe messaging enables a publisher to broadcast a message to multiple subscribers. The publisher and subscribers are related by a topic, which represents the category of data in which the subscribers are interested. Each subscriber that subscribes to a topic will receive a copy of every message that is published to that topic, as shown in Figure 1. Once the messaging system delivers copies of the message to all of the subscribers, it discards the original message.
Figure 1. Publish/subscribe
There are two types of subscriptions, durable and non-durable, the difference being whether a subscribing application wants to receive messages that are published during the time the application is not running:
- Durable subscription
While a durable subscriber is disconnected from the messaging system, the messaging system stores messages published to the topic. When the subscriber reconnects, the messaging system delivers the messages that the subscriber otherwise would have missed. A durable subscriber has to explicitly unsubscribe from a topic to cancel its subscription. A JMS messaging system uniquely identifies a durable subscription with three keys:
- Connection's client ID
- Subscriber's subscription name.
- Non-durable subscription
While a non-durable subscriber is disconnected from the messaging system, the subscriber does not receive any messages published to the topic. The messaging system unsubscribes a non-durable subscriber when it disconnects, and resubscribes it when it reconnects.
The durability of a subscription is completely independent of whether the messages on the topic are persistent. A single topic can have both durable and non-durable subscribers.
Publish/subscribe with the SIBus
The article Deploying message-driven beans and JMS applications into the Service Integration Bus introduced you to point-to-point messaging using the SIBus, and described how the SIBus is implemented as a coordinated group of messaging engines, each running inside an application server, as shown in Figure 2.
Figure 2. Service Integration Bus
As that article described, a queue is both a JMS destination and a destination in the SIBus. The JMS destination for publish/subscribe is a topic, but that is not a destination in the SIBus. Rather, the SIBus destination for publish/subscribe is a topic space, which is a collection of topic hierarchies. The topics within a space simply organize the jumble of messages published to the space, much like a file system organizes its files using a directory hierarchy. A topic (the group of messages for a particular interest) is just one node in one tree in the topic space, as shown in Figure 3.
Figure 3. Topic space
Whereas a queue is associated with a particular bus member (an application server or cluster that is part of the bus), a topic space is part of the bus as a whole. Rather than the topic space being defined in a bus member or messaging engine, each messaging engine in the bus has a publication point for the topic space. A JMS topic is configured to point to a topic in the topic space; its implementation uses the publication point to send and receive messages on that topic. Figure 4 shows how the JMS resources relate to the SIBus resources.
Figure 4. Relationship of JMS and SIBus resources
For efficiency, a topic only exists within the topic space when it has at least one subscriber. When a topic has no subscribers, the JMS topic still exists as an application resource, but the publication point immediately discards any published message. After the first subscriber subscribes, when messages are published to the topic, the publication point adds the messages to the topic space until the last subscriber unsubscribes.
Publication points are used not only for applications to add and remove messages on topics, but also to propagate messages from one messaging engine to the others in the bus. When an application publishes a message to a topic within that topic space, the message flows to every publication point for that topic space, as shown in Figure 5.
Figure 5. Publication Points
This activity enables the bus to transparently implement a publish/subscribe system and deliver messages to subscribers that are located anywhere on the SIBus.
A subscriber (but not a publisher) can specify a topic name that contains wildcard characters, which creates a single subscription to multiple topics, such as a branch in a topic hierarchy. Figure 6 shows a few examples of how topic names with wildcards work.
Figure 6. Examples of topic names with wildcards
By including wildcards in the topic name of the JMS topic definition, a subscriber can receive messages from multiple topics with a single subscription. In Figure 6, for example, a subscriber to the topic name PSExampleCompany/* receives messages from the topics PSExampleDepartment and PSExampleDepartment2. Notice that the JMS definition for a topic also specifies the topic space. Keep in mind that an application cannot publish to a JMS topic whose topic name contains wildcards, because a publisher can only publish a message to a single topic.
Import and examine the sample publish/subscribe application
Now that we have reviewed what publish/subscribe is and how it is implemented in the SIBus, we will review the simple example application that we will use to test our server configuration.
Two EAR files are provided in the download file included with this article, one contains a stateless session EJB that publishes messages, the other EAR contains a pair of message-driven beans (MDBs) that will subscribe to the same topic (one a durable subscriber, the other a non-durable subscriber).
Import each EAR into a project following the instructions in the point-to-point article, using the EAR import wizard in IBM Rational® Application Developer. After importing the two EAR files, use the Project Explorer to examine their structure.
Examine the application
Expand the deployment descriptor section of each EAR (Figure 7). Observe that one EAR contains a single session bean that publishes a message, and that there are two message-driven beans. In this sample application, Subscriber1 is a durable subscriber and Subscriber2 is a non-durable subscriber.
Figure 7. EJBs in the example application
The code for the publisher is identical to that of the point-to-point application, because the JMS 1.1 API enables JMS code that can produce messages onto either a queue or a topic. Much like the point-to-point sample, the session bean uses a resource reference to access the JMS connection factory and a message destination reference to access the destination. You can view the references using the References tab of the deployment descriptor editor (Figure 8). For more information on message destination references, see Resources.
Figure 8. Environment references for the session bean
As in the point-to-point example, an MDB is associated with its topic using an activation specification because the JMS API for the SIBus's messaging platform is implemented using J2EE Connector Architecture (J2C) version 1.5, which supports inbound events. The only setting you are required to specify in the MDB's bindings is the JNDI name for the specification (Figure 9).
You can also specify additional activity configuration details in the bean's deployment descriptor that will override those in the activation specification. For example, you can specify the durability of the subscription in the bean's deployment descriptor, and that will override the durability specified in the activation specification. In our example, we leave each MDB's activity configuration blank, which means that the details specified in the activation specification will be used, enabling the server administrator to change these details in the server configuration without having to redeploy the application. However, there may be cases where you want to specify certain activity configuration in the deployment descriptor; for example, if you want to enforce the durability.
Figure 9. Bindings for the subscriber beans
(The MDB code is also identical to that of the point-to-point article; it prints the contents of each message it receives.)
Create and configure the SIBus
Now that we have reviewed how publish/subscribe works and seen the sample application, we will create our messaging infrastructure by configuring the SIBus. We will create an SIBus instance and add our application server to the bus, then create our destination, which in the SIBus for publish/subscribe is a topic space, as explained earlier. We will then configure our JMS provider so that applications can interact with the bus through the JMS API. As we do this, we will delve deeper into some of the configuration options of the provider.
Create the bus
Creating a service integration bus instance is simple (see Deploying message-driven beans and JMS applications into the Service Integration Bus for more detailed instructions):
- Start the server and open the administrative console.
- In the administrative console, in the Navigation panel, select Services integration => Buses (Figure 10). The Buses dialog will display.
Figure 10. Navigate to buses panel
- Press New to create a new bus.
- In the New bus dialog (Figure 11), name the bus
- Press Apply to create the bus.
Figure 11. Create new bus
We have now created the bus for our sample application.
Add the bus member
Now that we have a bus, we need to add our application server as a member of the bus:
- Navigate to Buses => PSExampleBus. In the Additional Properties section, select Bus members (Figure 12).
Figure 12. Navigate to bus members panel
- Press Add to add a new bus member.
- On the Add a new bus member dialog, select the default server and the default data store (Figure 13), then Next.
Figure 13. Add a new bus member
- Press Finish to create the bus member.
We have now created the bus member for our sample application.
Create the topic space
Creating a topic space is similar to creating a queue. However, as described earlier, one does not have to specify which bus member will host the destination; every messaging engine in the bus automatically has a publication point representing that topic space.
- Navigate to Buses => PSExampleBus, then select Destinations in the Additional Properties section (Figure 14).
Figure 14. Navigate to destinations panel
- Press New.
- Select Topic space as the destination type, then Next.
- In the Create new topic space dialog (Figure 15), name the topic space PSExampleTopicSpace, then Next.
Figure 15. Crate new topic space
- Press Finish to create the topic space.
- Save the server configuration.
We have now created the topic space for our sample application.
Configure the default messaging provider
At this point, we need to create the JMS resources for the application to use. Since they are JMS resources, we will create them in the JMS provider for the SIBus: the default messaging provider. We will create these resources in the provider and associate them with the bus.
In the point-to-point article, we described how the JMS resources act as a level of indirection between the bus and the application. Earlier in the article, we showed that the way an application connects to the bus is pretty much the same for publish/subscribe messaging as it was for point-to-point messaging (although topic subscriptions have more flexibility, as with topic name wildcards and durability).
Create the JMS connection factory
Here, we will create the connection factory that the session bean will use to connect to the message engine.
- In the Navigation panel of the administrative console, navigate to Resources => JMS Providers => Default messaging (Figure 16).
Figure 16. Navigate to default messaging provider panel
- In the Default messaging provider dialog, select JMS connection factory under the Connection Factories section (Figure 17). (With JMS 1.1, we can now create a unified JMS connection factory that works with both queues and topics.)
Figure 17. Navigate to JMS connection factories
- On the JMS connection factory dialog, press New.
- In the New dialog (Figure 18), name the connection factory
PSExampleConnectionFactorywith the JNDI name
- In the Connection section, select PSExampleBus as the bus name.
Figure 18. Create JMS connection factory
- Press OK to create the connection factory.
We have now created the connection factory for our sample application.
Create the JMS topic
In JMS, as mentioned earlier, the destination type for publish/subscribe is a topic. Applications look up a topic in JNDI and publish or consume messages. In a service integration bus, the publish/subscribe destination is a topic space. An administrator then defines a JMS topic in the provider and associates it with a topic space, which stores and transmits the messages for the topic. JMS topics are defined with a name, a JNDI name, and a topic name, where the topic name is for the structure defined in the topic space. As explained earlier, topics in a topic space can be arranged in topic hierarchies, so the topic name can be a path in a hierarchy tree.
With this in mind, we now need to create the topic the sample applications will use to publish and receive messages:
- In the Default messaging provider panel, select JMS topic under the Destinations section (Figure 19).
Figure 19. Navigate to JMS topics panel
- On the JMS topic dialog, press New.
- On the next panel (Figure 21), name the topic
PSExampleTopic, with the JNDI name
jms/PSExampleTopic, and the topic name
PSExampleCompany/PSExampleDepartment/PSExampleTopic. This defines a topic hierarchy whose root is PSExampleCompany, which has a child node PSExampleDepartment, and which has a child node PSExampleTopic that is a leaf, as shown in Figure 20.
Figure 20. Example topic hierarchy
- For the bus name, select PSExampleBus, then select PSExampleTopicSpace as the topic space for this topic.
Figure 21. Create JMS topic
- Press OK to create the topic.
We have now created the topic for our sample application.
Create the JMS activation specifications
An activation specification is used to bind an MDB to a JMS destination. In Version 5 of WebSphere Application Server, administrators use a listener port, which is still used in Version 6 with the WebSphere MQ provider (see Resources) or with the default Version 5 provider. The JMS provider for the SIBus in Version 6 is implemented as a J2C inbound adapter whose listeners are configured with activation specifications. We are going to define two activation specifications, one for the durable subscriber and one for the non-durable subscriber.
The activation specification is bound into JNDI; an MDB's configuration specifies its activation specification using the JNDI name. With this approach, multiple MDB classes can bind to a single activation specification. If the MDBs are subscribers, they will all share the subscription properties configured in the activation specification. Each MDB class can override this configuration by overriding the activation specification's properties. However, properties in an activation specification are easier to change because changes do not require redeploying the application, whereas a change to an MDB's configuration does require redeployment.
To create an activation specification:
- You will configure the activation specification by entering the name of your messaging engine. Navigate to Buses => PSExampleBus => Messaging engines, where the messaging engines are listed by name, and copy the name of your messaging engine.
- In the Default messaging provider panel, select JMS activation specification under the Activation Specifications section (Figure 22).
Figure 22. Navigate to JMS activation specifications panel
- On the JMS activation specification panel, press New.
- On the New panel, enter or select the following settings (Figure 23):
The unique administrative name.
- JNDI name:
The activation specification is bound into JNDI with this name, which is in turn what the MDBs use to access the activation specification.
- Destination type: Topic
The JMS destination type, queue or topic. Since we are using publish/subscribe, we select Topic.
- Destination JNDI name:
This specifies which destination the MDBs will listen to. The destination must be of the type specified in the previous step. The destination can be overridden by specifying the Destination under the binding file deployment descriptor.
- Bus name: PSExampleBus
Name of the service invocation bus that contains the destination.
- Subscription durability: Durable
Make the subscribers durable subscribers. Because this is now a durable subscription, we now must specify the properties which follow for durability.
- Subscription name:
The subscription name key that a JMS messaging provider uses to identify durable subscriptions, as described earlier.
- Client identifier:
The client ID key that a JMS messaging provider uses to identify durable subscriptions.
- Durable subscription home: the name of your message engine
The name of the messaging engine in your SIBus. (Use the name you copied from the Buses => PSExampleBus => Messaging engines panel in step 1.) The service integration bus will use the messaging engine you specify here to store messages that are published while a durable subscriber is disconnected.
- Leave the defaults for the remainder of the settings.
- Press OK to create the first activation specification.
Figure 23. Create first activation specification
- Create another Activation Specification for the nondurable subscriber. In this case, we do not need to specify durability information. Enter the following information (Figure 24):
- JNDI name:
- Destination type: Topic
- Destination JNDI name:
- Bus name: PSExampleBus
- Subscription durability: Nondurable
Figure 24. Create second activation specification
- Save your configuration.
We have now created both activation specifications for our sample application.
Before continuing, stop and start the server from the Server view to activate the new configurations.
Test the application
To deploy and test our application, we will use Rational Application Developer. We will use the Universal Test Client (UTC) to also call our session bean to publish the message. If you do not have Rational Application Developer, you can also deploy the EAR files directly and write your own client to test the EJB session bean. (You can also deploy the UTC EAR file that ships with WebSphere Application Server or use the WebSphere Application Server Toolkit (ASTK), as described in Make WebSphere MQ the JMS provider for applications deployed in WebSphere Application Server.)
To test publish/subscribe:
- In Rational Application Developer, go to the Servers view in the J2EE perspective. Right-click the server and select Add and Remove projects... (Figure 25).
Figure 25. Add projects to server
- Press the Add All >> button. The Configured projects pane will list all the SubscribersExample and PublishSubscribeExample projects.
- Press Finish (Figure 26) to deploy and start both EARs.
Figure 26. Add and remove projects dialog
- From the Project Explorer view, expand the PublishSubscriberExampleEJB project, select the PublisherSSB session bean, and select Run => Run on Server... on the pop-up menu (Figure 27).
- In the Server Selection dialog, choose to run the bean on the existing server we have already configured. This launches the Universal Test Client with the session bean's local home listed in the EJB Beans list.
Figure 27. Run stateless session bean
- Invoke the create() method on the EJB Home by clicking on PublisherSSBLocal create() and then Invoke. Press Work with Object in the Results frame to add the bean to the EJB Beans list.
- Next, select the publishMessage(String) link and enter
Test Message 1as the parameter value. Invoke the Method (Figure 28).
Figure 28. Publish first message
- Switch to the Console view. You will see that both subscribers received a copy of the message (Figure 29).
Figure 29. Receive first message
This shows that our publish/subscribe application is working.
Now that we have successfully tested our publish/subscribe configuration, let's test that our durable and non-durable subscriptions work.
- Return to the Servers view, select the SubscriberExample application and press Remove (Figure 30) to move the project to the Available projects list, then press Finish. Removing the application disconnects the subscribers. If the subscriber MDBs were bound to the messaging system using listener ports (as is the case when the messaging system is WebSphere MQ or a generic JMS provider), the server unsubscribes them when the server is restarted if no subscribers are bound to the listener ports -- even if they're durable. But these subscribers are bound using activity specifications; therefore, once the durable subscriptions are created, they will exist until the administrator deletes them -- even after the application is removed (as this example is about to illustrate).
Figure 30. Remove subscribers project
- Back in the UTC, type
Test Message 2into the input field and press Invoke (Figure 31). Both our subscribers are offline; however, the SIBus will save the message for the durable subscriber.
Figure 31. Publish second message
- Return to the Servers view, and re-add the SubscriberExample (Figure 32).
Figure 32. Add subscribers project
- Return to the Console. You should see that only Subscriber 1, which is our durable subscriber, received a copy of the Message (Figure 33).
Figure 33. Receive second message
- Publish a third test message (Figure 34).
Figure 34. Publish third message
- The Console should indicate that both subscribers received a copy of the message.
Figure 35. Receive third message
This result illustrates that subscribers with both durable and non-durable subscriptions are operating properly.
The Service Integration Bus enables us to integrate applications in a variety of ways, including the ability to build publish/subscribe messaging applications. This article explained how to configure a SIBus to support publish/subscribe, and demonstrated various configuration options available on the bus and on the JMS provider.
The authors would like to thank David Currie for his help in reviewing this article.
|Publish/subscribe sample app||PublishSubscribeDownload.zip ( HTTP | FTP )||16 KB|
- Java specifications
Books & documentation
- WebSphere Application Server V6 Information Center
- WebSphere Application Server V6 System Management and Configuration Handbook (IBM Redbook SG24-6451-00; February 2005)
- Enterprise Integration Patterns by Gregor Hohpe and Bobby Woolf (Addison-Wesley; 2003; ISBN 0321200683)
- IBM WebSphere: Deployment and Advanced Configuration by Roland Barcia, Bill Hines, Tom Alcott, and Keys Botzum (Prentice Hall; 2004; ISBN 0131468626)
- Enterprise Java Programming with IBM WebSphere (2nd Edition) by Kyle Brown, Gary Craig, Greg Hester, Russell Stinehour, W. David Pitt, Mark Weitzel, JimAmsden, Peter M. Jakab, and Daniel Berg (Addison-Weslet)
- Deploying message-driven beans and JMS applications into the Service Integration Bus by Roland Barcia and Saravana R Chandran (developerWorks; April 13, 2005)
- Make WebSphere MQ the JMS provider for applications deployed in WebSphere Application Server by Bobby Woolf (developerWorks; May 11, 2005)
- Building an Enterprise Service Bus with WebSphere Application Server v6 by Rachel Reinitz and Andre Tost (developerWorks)
- Working with the Enterprise Service Bus and Mediations, Part 1 by Doina Klinger and Dave Spriet (developerWorks; February 22, 2005)
- Creating and Testing Message Driven Beans using WebSphere Studio by Roland Barcia (developerWorks; November 20, 2002)
- JMS 1.1 simplifies messaging with unified domains by Bobby Woolf (developerWorks; August 1, 2002)
- Easiest, breeziest EJB components: Using Rational Application Developer for WebSphere Software (tutorial) by Jeff K Wilson (developerWorks; January 2005)
- J2EE in Practice by Bobby Woolf (developerWorks blog)
Get products and technologies
- WebSphere Application Server
- Rational Application Developer for WebSphere Software