Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

developerWorks Community:

  • Close [x]

IBM WebSphere Developer Technical Journal: Building an Enterprise Service Bus with WebSphere Application Server V6 -- Part 4

Building a better bus with mediations

Rachel Reinitz (rreinitz@us.ibm.com), Senior Consulting IT Specialist, IBM
Rachel Reinitz is a Senior Consulting IT Specialist with IBM Software Services for WebSphere focusing on Web services. Rachel consults with customers and ISVs on how service oriented architecture and Web services can be used to achieve their business and technical objectives. She developed IBM's Advanced Web Services Training course and is a frequent conference presenter. Rachel is also an IBM Academy Member, and an experienced eXtreme Programming coach who has used XP practices for 4 years. She lives in the Bay Area in California, and enjoys hiking, socializing, and international travel.
Andre Tost (atost@us.ibm.com), Senior Technical Staff Member, IBM
Andre Tost works as a Senior Technical Staff Member in the Software Group's Enterprise Integration Solutions organization, where he helps IBM's customers establishing Service-Oriented Architectures. His special focus is on Web services technology. Before his current assignment, he spent ten years in various partner enablement, development and architecture roles in IBM software development, most recently for the WebSphere Business Development group. Originally from Germany, he now lives and works in Rochester, Minnesota. In his spare time, he likes to spend time with his family and play and watch soccer whenever possible.

Summary:  Develop and install a simple mediation that accesses messages as they flow through the bus in Part 4 of this series on using the new messaging engine in IBM® WebSphere® Application Server V6 to build an Enterprise Service Bus.

Date:  11 May 2005
Level:  Intermediate
Also available in:   Russian

Activity:  6250 views
Comments:  

Introduction

Now that we have explored how to setup a bus, and how to use JMS as a message protocol going across the bus, we are finally ready to introduce another key component into our solution: Mediations!

In Part 4 of this series on using the new messaging engine in IBM WebSphere Application Server to build an Enterprise Service Bus (ESB), we will show you how to add a simple mediation to our solution in progress that accesses messages as they flow through the bus.

So far, our solution has evolved from these articles:


Mediations revisited

As we explained in Part 1, messages that are sent to the bus are actually going to a destination. Destinations can be linked to each other by means of configuration, effectively creating a routing path that messages follow.

Mediations provide access to messages as they flow from destination to destination. A mediation is associated with one or more destinations, and will be invoked as soon as a message arrives at that destination. When invoked, a mediation has access to the message and its context flowing through the destination, and can change the content of the message, the routing of the message (that is, the next destination where it is sent), or it can write the message to a log and monitor the data flowing through the bus, which is one of the core characteristics of what an ESB provides.

One additional concept of a mediation, which we will take advantage of later in our example, is that it can read configuration information using what are called context properties, which are key-value pairs configured through the application server administrative console. This feature can be used to provide switches that change the behavior of a mediation without having to change its code.

For a good primer on mediations, see A practical introduction to message mediation.


Mediation programming model

Mediations can be written to be protocol neutral and it is a good design practice to separate any protocol (that is, SOAP or JMS or MQ) processing into separate mediation handlers. In other words, a mediation can be independent from the protocol that was used to send the message to the associated destination. This requires a way for a mediation to access message data in a neutral fashion. This is where Service Data Objects (SDO) come in. We will not provide any detailed explanation of SDO here (see Resources for more material), but note that whenever you are developing mediations for advanced purposes, you will do so leveraging the SDO API.

At the core of mediation programming, each mediation implements a generic interface, named MediationHandler, that enables the bus to invoke it when a message is delivered to a destination. The only method in this interface is called handle(), and it takes an argument of type MessageContext. This context, among other things, contains a reference to the actual message. And that is pretty much it! The handle() method gets called when a message arrives, and that message is passed to the mediation in the MessageContext parameter.

By the way, if you are familiar with the concept of JAX-RPC handlers, mediations follow a very similar (but not the same!) programming model. In fact, the MessageContext class that the mediations use comes from the JAX-RPC specification.

But how do you actually develop and install a mediation? Don't worry; we will take you through a simple step-by-step example right here.


Develop a simple logging mediation

For our example, we will develop a mediation that logs every occurrence of a message that is sent to a destination. The message will simply be printed to System.out. An actual solution would most likely take advantage of the standard java.util.logging mechanism. For now, we will not be changing the actual message content; we will leave that for another article.

The WebSphere Application Server Toolkit (AST) or IBM Rational® Application Developer for WebSphere Software V6 (hereafter referred to as Application Developer) can be used to develop code and create an installable package that contains mediations for WebSphere Application Server. One important detail is that mediations -- even though they are developed as simple Java™ classes -- are deployed in the form of stateless session EJB components. The AST or Application Developer will generate this EJB when the mediation is deployed. More on that later.

To develop our mediation:

  1. Create a new EJB project within the development tool you chose to use, and name it LoggingMediation.
  2. By default, the tool also offers to create a new EAR project, called LoggingMediationEAR. We will use this default.
  3. Create a package called logging in the predefined ejbModule folder of the EJB project (assuming you are in the tool's J2EE perspective).
  4. Finally, create a new Java class in this package called LoggingMediation, which implements the com.ibm.websphere.sib.mediation.handler.MediationHandler interface. Figure 1 shows what this structure will look like.
    Figure 1. EJB Project structure
    Figure 1. EJB Project structure
    The tool will also create an empty implementation class for you that contains the following code in an empty method with the signature:

    public boolean handle(MessageContext arg0) throws MessageContextException {


  5. Add the following code to the handle() method that will log the reception of a message

    public boolean handle(MessageContext arg0) throws MessageContextException {
    		
       // Convert the MessageContext into an SIMessageContext
    	SIMessageContext sim = (SIMessageContext)arg0;
    	    
        // Retrieve the message from the context 
        SIMessage message = sim.getSIMessage();     
    	    
        try {
        	if (message.getFormat().equals("JMS:text")) {
        // get an SDO DataGraph from the message
    	DataGraph dataGraph = message.getDataGraph();
    
        //SIBus SDO representation of a JMS message, has a property named 'data' 
    	DataObject jmsMessage = root.getDataObject("data");
    	    		
        //the DataObject for the JMS message has a property which contains the
        //value of the message. We access that value as a string. SDO will do 
        //its best to convert  the message in the format requested.
    	String payLoad = jmsMessage.getString("value");
    
     	    System.out.println("Message logged. The payload of the message is "+payLoad);
        	} else {
        	    System.out.println("The received message is not a JMS text message!");
        	}
        } catch (SIException ex) {
        	System.out.println(ex.getLocalizedMessage());
        }
    		
    	return true;
    }
    


  6. Add these import statements to the class:

    import com.ibm.websphere.sib.mediation.handler.MediationHandler;
    import com.ibm.websphere.sib.mediation.handler.MessageContextException;
    import com.ibm.websphere.sib.mediation.messagecontext.SIMessageContext;
    import commonj.sdo.DataGraph;
    


Notice how the payload of the message is retrieved. The system integration bus (SIBus) uses the dynamic interface for Service Data Objects (SDO). The message is represented as an SDO DataGraph, hence we call a method named getDataGraph(). A DataGraph always contains at least one DataObject instance -- that's the actual data. Once we have obtained the root DataObject from the graph, we can look at its properties using the getRootObject() method.

The SIBus representation of a JMS message defines a property on the root DataObject called data which returns another DataObject. The data DataObject has a property called value, which is the actual message content.

The method getString("value") is part of the SDO dynamic interface and needs a bit of an explanation. We can retrieve a property in whatever type fits our needs; the SDO call to the DataObject will do its best to convert the property type -- if it is not stored in that type in the DataObject. In our example, then, we use the getString() method, which says that we want the content of the retrieved property as a String. There are also other methods on the DataObject (...) which try to return the content of a property in the respective type.

Navigating SDO DataObjects
Properties in a DataObject are named. Moreover, DataObjects can contain other DataObjects. The SDO API provides a shortcut you can use to navigate a hierarchy of DataObjects, using an XPath-style query. In our example, instead of the code:

DataObject jmsMessage = root.getDataObject("data");
String payLoad = jmsMessage.getString("value");


we could use the code:

String payLoad = root.getString("data/value");

where the string "data/value" is an XPath type of query, meaning we are retrieving a property named "value" that exists in a property on the root object named "data".

The explanation of the SDO handling we offer here is certainly not sufficient for advanced mediation programming. See Resources for more thorough discussions of SDO and how it applies to WebSphere Messaging Resources.

How did we know that such properties as data and value existed and that they indeed were what we were looking for? This is documented in the WebSphere Application Server V6 Information Center; drill down under SDO Datagraph information => JMS Formats and look at any of the formats.

To make sure that this mediation is only used for JMS text messages, we added a call to message.getFormat(), which will return the string JMS:text for that message type. In a real life solution, we would either create a mediation to handle all message formats, or develop one logging mediation per message format.


Deploy the new mediation

We are now ready to deploy our mediation. This means we add an entry to the EJB deployment descriptor of the EJB project, named LoggingMediation. The tool will automatically generate a stateless session bean that wraps the mediation we just created. This new entry in the deployment descriptor is not part of the standard EJB 2.1 deployment descriptor, so it is stored in an extension file, ws-handler.xmi. However, the tool lets us edit the standard fields and all extensions in one editor window.

To deploy the new mediation:

  1. Double-click the Deployment Descriptor: LoggingMediation entry in the Project Explorer view. This will open the (still empty) deployment descriptor in the editor window.
  2. Select the Mediation Handlers tab at the bottom to define the mediation (Figure 2).
    Figure 2. Mediation handler parameters
    Figure 2. Mediation handler parameters
  3. To add a new mediation, select the Add... button.
  4. In the Define Mediation Handler window, select the Browse button to navigate to our mediation class (Figure 3.)
    Figure 3. Define a new mediation
    Figure 3. Define a new mediation
  5. Select OK.
  6. Enter LoggingMediation for the Name, then Finish.
  7. After this step, you should see that a new Session EJB exists in the module, which represents the mediation (Figure 4).
    Figure 4. Mediation defined in the project
    Figure 4. Mediation defined in the project

We can now install the EAR project that contains the mediation into the application server.


Install the mediation

To install the new mediation:

  1. Export the LoggingMediationEAR project to an EAR file, using the Export menu option in the development tool (see Download for a complete loggingmediation.ear file).
  2. Start up your application server and open the admin console in your browser.
  3. Install a new enterprise application from the loggingmediation.ear file. For the install, remember to check both the Generate default bindings and the Deploy enterprise beans checkboxes, if they are not already selected. Keep the default values for all other fields.
  4. Upon install completion, go to the Enterprise Applications view of the admin console and start the new LoggingMediationEAR application.


Configure the bus for the mediation

Next, we will define the mediation to the bus:

  1. Open the admin view for the bus, which we called TheBus, and select Mediations (Figure 5).
    Figure 5. Bus configuration properties
    Figure 5. Bus configuration properties
  2. Select New.
  3. For both the Mediation name and Handler list name, enter the value LoggingMediation, as shown in Figure 6.
    Figure 6. Configure the bus mediation
    Figure 6. Configure the bus mediation
  4. Select OK and save your changes. You now have a mediation available that can be associated with any destination.

So that we can test our new mediation, we will associate it with the PackageReceivedDestination destination that we used previously in our JMS example:

  1. Open the destination list in the admin console and check PackageReceivedDestination.
  2. Select the Mediate button, shown in Figure 7.
    Figure 7. Associate destination with mediation
    Figure 7. Associate destination with mediation
  3. In the dialog shown in Figure 8, make sure the LoggingMediation mediation is selected (it should be the only mediation that is defined), then Next.
  4. Select Next again, then Finish.
  5. Save your changes. The list of destinations now shows that LoggingMediation is assigned to PackageReceivedDestination (Figure 8) .
    Figure 8. Associate destination with mediation
    Figure 8. Associate destination with mediation


Test the mediation

You can simply run the JMS client application to test the mediation, as described in Part 3 of this article series, assuming you have the PackageReceived enterprise application installed and started (see Resources for the article containing this EAR file). Launch the client application using the launchclient utility. The System.out file in the logs\server1 directory now contains additional output from the mediation (Figure 9).


Figure 9. Log file with mediation output
Figure 9. Log file with mediation output

In Figure 9, it looks as though the output is logged twice. The reason for this is because the message content is logged first by the mediation, and then by the receiving MDB.


Conclusion

In Part 4 of this series on building an Enterprise Service Bus with WebSphere Application Server V6, we have demonstrated how to develop, deploy, and install a mediation, and how to configure an ESB to use mediations, a key concept of the new WebSphere Messaging Resources. Developed as simple JavaBeans, a mediation is wrapped into a stateless session EJB, installed in the application server as an enterprise application, and, after associating it with a destination, is invoked whenever a message arrives at the destination. Flexible by nature, mediations can transform and route messages, or simply be used for logging purposes, as shown in this article.



Download

NameSizeDownload method
LoggingMediationEAR.ZIP5 KBFTP|HTTP

Information about download methods


Resources

About the authors

Rachel Reinitz

Rachel Reinitz is a Senior Consulting IT Specialist with IBM Software Services for WebSphere focusing on Web services. Rachel consults with customers and ISVs on how service oriented architecture and Web services can be used to achieve their business and technical objectives. She developed IBM's Advanced Web Services Training course and is a frequent conference presenter. Rachel is also an IBM Academy Member, and an experienced eXtreme Programming coach who has used XP practices for 4 years. She lives in the Bay Area in California, and enjoys hiking, socializing, and international travel.

Andre Tost

Andre Tost works as a Senior Technical Staff Member in the Software Group's Enterprise Integration Solutions organization, where he helps IBM's customers establishing Service-Oriented Architectures. His special focus is on Web services technology. Before his current assignment, he spent ten years in various partner enablement, development and architecture roles in IBM software development, most recently for the WebSphere Business Development group. Originally from Germany, he now lives and works in Rochester, Minnesota. In his spare time, he likes to spend time with his family and play and watch soccer whenever possible.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere, Open source
ArticleID=83058
ArticleTitle=IBM WebSphere Developer Technical Journal: Building an Enterprise Service Bus with WebSphere Application Server V6 -- Part 4
publish-date=05112005
author1-email=rreinitz@us.ibm.com
author1-email-cc=
author2-email=atost@us.ibm.com
author2-email-cc=