IBM WebSphere Developer Technical Journal: Dynamic routing improvements in WebSphere Enterprise Service Bus V6.0.2

Learn how the dramatic improvements in dynamic routing at runtime in IBM® WebSphere® Enterprise Service Bus V6.0.2 can enhance your service-oriented solutions.

Share:

Greg Flurry, Senior Technical Staff Member, IBM India Software Lab Services and Solutions

Greg Flurry photoGreg Flurry is a Senior Technical Staff Member in IBM's SOA Advanced Technology group. His responsibilities include working with customers on service-oriented solutions and advancing IBM's service-oriented products. If you have comments for the Greg about this article, send them to wsdd@us.ibm.com.



24 January 2007

From the IBM WebSphere Developer Technical Journal.

Introduction

In 2006, I wrote an article Dynamic routing at runtime in WebSphere Enterprise Service Bus (developerWorks, 2006) describing the limitations on dynamic routing in WebSphere Enterprise Service Bus V6.0.1, and demonstrated some techniques you could use to circumvent those limitations. The good news is that WebSphere Enterprise Service Bus Version 6.0.2 (hereafter WebSphere ESB) has eliminated these limitations and added features that greatly facilitate dynamic routing in conjunction with a services registry.

In this article, I'll tell you about at the dynamic endpoint mechanism available in WebSphere ESB V6.0.2 (WebSphere ESB) and how you can use it. I'll also show you how to use mediation primitives, new in Version 6, to support two different forms of endpoint resolution that you can use in conjunction with the dynamic endpoint mechanism to support dynamic routing.


Static routing for SOAP/HTTP

In my previous article, I showed you how to build a WebSphere ESB mediation module that supports only static routing using WebSphere Integration Developer V6.0.1 (Integration Developer). You can build a mediation module for WebSphere ESB V6.0.2 that performs static routing the same way using Integration Developer V6.0.2, so I won't repeat the process in this article.

The process in the previous article included defining a Business Integration Library project called Resources, containing the WSDL for a BigEcho Web service, shown in Listing 1. For the examples in this article, you need to create the library using Integration Developer V6.0.2.

Listing 1. BigEcho service definition
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://big.com"
xmlns:impl="http://big.com"
xmlns:intf="http://big.com"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsi="http://ws-i.org/profiles/basic/1.1/xsd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <wsdl:types>
  <schema targetNamespace="http://big.com"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:impl="http://big.com"
xmlns:intf="http://big.com"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <complexType name="BEData">
    <sequence>
     <element name="one" nillable="true" type="xsd:string"/>
     <element name="two" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
   <element name="echoResponse">
    <complexType>
     <sequence>
      <element name="echoReturn" nillable="true" type="impl:BEData"/>
     </sequence>
    </complexType>
   </element>
   <element name="echo">
    <complexType>
     <sequence>
      <element name="d" nillable="true" type="impl:BEData"/>
     </sequence>
    </complexType>
   </element>
  </schema>
 </wsdl:types>

 <wsdl:message name="echoRequest">
    <wsdl:part element="impl:echo" name="parameters"/>
 </wsdl:message>
 <wsdl:message name="echoResponse">
    <wsdl:part element="impl:echoResponse" name="parameters"/>
 </wsdl:message>

 <wsdl:portType name="BigEcho">
    <wsdl:operation name="echo">
       <wsdl:input message="impl:echoRequest" name="echoRequest"/>
       <wsdl:output message="impl:echoResponse" name="echoResponse"/>
    </wsdl:operation>
 </wsdl:portType>

 <wsdl:binding name="BigEchoSoapBinding" type="impl:BigEcho">
    <wsdlsoap:binding style="document" 
transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="echo">
       <wsdlsoap:operation soapAction=""/>
       <wsdl:input name="echoRequest">
          <wsdlsoap:body use="literal"/>
       </wsdl:input>
       <wsdl:output name="echoResponse">
          <wsdlsoap:body use="literal"/>
       </wsdl:output>
    </wsdl:operation>
 </wsdl:binding>

 <wsdl:service name="BigEchoService">
    <wsdl:port binding="impl:BigEchoSoapBinding" name="BigEcho">
       <wsdlsoap:address
location="http://localhost:9080/BigEcho/services/BigEcho"/>
    </wsdl:port>
 </wsdl:service>
</wsdl:definitions>

Figure 1 shows the Integration Developer assembly diagram that results from creating the mediation module. You can see the export on the left, the import on the right, and the mediation component in the middle.

Figure 1. StaticRoute mediation module assembly
Figure 1. StaticRoute mediation module assembly

Figure 2 shows the operation mapping for the mediation component in the Mediation Flow editor. The mediation component interface, BigEcho, is represented on the left and the mediation component reference, BigEchoPartner, is on the right.

Figure 2. Operation mapping for StaticRoute
Figure 2. Operation mapping for StaticRoute

Figure 3 shows the simple request flow in which the Input node (representing the request from Export1) is associated with the mediation component interface. The mediation component interface is wired directly to the mediation component reference. The Callout node (representing the request to Import1) is associated with the mediation component reference. This arrangement passes an incoming request directly from the export to the import with no processing. Note the differences in the visual appearance of the artifacts in the Mediation Flow editor between Versions 6.0.1 and 6.0.2; in 6.0.2 the representation distinguishes between the export and the interface and between the reference and the import. I'll talk about the significance of that below.

Figure 3. StaticRoute Request flow
Figure 3. StaticRoute Request flow

Figure 4 shows the simple response flow in which the CalloutResponse node (representing the response from Import1) is associated with the mediation component reference, which is wired directly to the mediation component interface, which is associated with the InputResponse node (representing the response to Export1). This arrangement passes an incoming response directly from the import to the export.

Figure 4. StaticRoute Response flow
Figure 4. StaticRoute Response flow

As in my previous article, once you've saved the mediation module and deployed it to the test server (either WebSphere ESB or WebSphere Process Server Version 6.0.2), you can test the mediation module. The simplest way to do that is to use the Web Services Explorer. The BigEcho service implementation we used ran in the same test environment as the StaticRoute mediation module, so it prints the message +++ Got to BigEcho to the test environment console, which shows that the mediation module invokes the BigEcho service on behalf of the service requester, in this case the Web Services Explorer.

Of course, the StaticRoute is rather boring, as it really does nothing. Even worse, if the static address identified in the Import needs to change, you have to modify the mediation module and redeploy it. This example does, however, show the decoupling of the service requester and provider, shown the continuity between Versions 6.0.1 and 6.02, and set the stage for our further discussion.


Dynamic endpoints

After you've completed the StaticRoute mediation, navigate to the request flow in the Mediation Flow editor, and select the Callout node associated with the mediation component reference. Then click the Properties tab and select Details, as shown in Figure 5.

Figure 5. StaticRoute request flow Callout Properties
Figure 5. StaticRoute request flow Callout Properties

Note the checkbox labeled Use dynamic endpoint if set in the message header. This means that, if the request message in the request mediation flow contains an address in the message header, the request message is sent to the provider at that address.

The full story is a little more complex. If this property is turned off, then the static address from the import associated with the reference is used; if there is no import that supplies an address, an exception results. When the property is turned on (the default), if there is no address in the header and there is an import, then the static address from the import is used; again if there is no import that supplies an addres, an exception results.

It's important to understand that when this property is turned on, you don't have to have an import. Since you don't have to have an import, you don't have a binding. This is extremely powerful as it enables you to use different addresses not only to access providers with the same binding but different addresses, but also to access providers with different bindings.

A couple of additional details are important. In the request message (actually the Service Message Object or SMO), the dynamic endpoint address that identifies the desired provider must be at the location identified by the XPath expression /headers/SMOHeader/Target/address. Further, the address must be a valid URI for one of the supported bindings. The bindings currently supported are SOAP/HTTP, SOAP/JMS and SCA (the default binding for SCA modules). See Resources for more information about the dynamic endpoint mechanism.

The dynamic endpoint mechanism makes dynamic routing very simple and powerful; you only have to put a valid address in /headers/SMOHeader/Target/address to send requests to the desired provider with any of the supported bindings. So how do you get an address in the header? Fortunately, WebSphere ESB offers a number of options for inserting the address in the header:

  • You can use a custom mediation primitive, similar to what was demonstrated in my previous article.
  • You can use the DatabaseLookup mediation primitive to extract a key value from the request message and use that to find the appropriate address by inserting the address into the header.
  • You can use the MessageElementSetter mediation primitive (new to V6.0.2).
  • You can use the EndpointLookup mediation primitive (new to V6.0.2).

In this article, I'll describe the last two options.


Dynamic routing with MessageElementSetter

Let's look at an approach to dynamic routing that leverages the dynamic endpoint mechanism and the new MessageElementSetter mediation primitive.

  1. First, you create a mediation module named MESRouter that references the Resources Library in its dependencies using the techniques demonstrated in Getting started with WebSphere Enterprise Service Bus and WebSphere Integration Developer. Figure 6 shows the Integration Developer assembly diagram that is the result of:
    • Creating the mediation module that contains a mediation component automatically named Mediation1
    • Adding to the mediation module an export automatically named Export1
    • Assigning the BigEcho interface to Export1
    • Generating a Web services binding (HTTP) for Export1
    • Wiring Export1 to Mediation1
    • Adding a reference to Mediation1 that has an interface definition of BigEcho
    Figure 6. Assembly diagram for MESRouter
    Figure 6. Assembly diagram for MESRouter

    MESRouter has a single export and a mediation component. Note that it has no import, since you're going to leverage the dynamic endpoint mechanism.

  2. Open the Mediation Flow editor and map the operation as shown in Figure 2.
  3. Open the request flow and drop a MessageElementSetter mediation primitive into the request flow. Wire the mediation component interface to the primitive input terminal and wire the primitive output terminal to the mediation component reference as shown in Figure 7.
    Figure 7. MESRouter request flow
    Figure 7. MESRouter request flow
  4. Click MessageElementSetter1, click the Properties tab, and select Details. You'll see a table of {Target, Type, Value} triples that determine what elements in the message get set and to what value. Click Add to display the Add/Edit dialog shown in Figure 8.
  5. Click Custom XPath to define the location in the SMO where the address will be placed.
    Figure 8. Add/Edit dialog
    Figure 8. Add/Edit dialog
  6. In the Build the XPath Expression dialog, expand headers => SMOHeader => Target, and select address, as shown in Figure 9, then click OK to return to the Add/Edit dialog.
    Figure 9. XPath expression dialog
    Figure 9. XPath expression dialog
  7. Enter the address of the provider to route the message to. For this first test, use the value of the SOAP/HTTP Web service shown in the WSDL in Listing 1, then click Finish in the Add/Edit dialog. The properties for the primitive should appear as shown in Figure 10.
    Figure 10. Property details for MessageElementSetter1
    Figure 10. Property details for MessageElementSetter1
  8. Wire the response flow just as shown for the StaticRoute in Figure 4.
  9. Save the mediation flow and the mediation module and deploy MESRoute to the test environment.
  10. Test the module using Web Services Explorer. The BigEcho service implementation ran in the same test environment as the MESRoute mediation module, so it prints the message +++ Got to BigEcho to the test environment console, showing that the mediation module invokes the BigEcho service.

To demonstrate the flexibility of the dynamic endpoint mechanism, let's create another service provider. Instead of having a SOAP/HTTP binding, as does the BigEcho service shown in Listing 1, this version has a SOAP/JMS binding.

The easiest way to do this is to use Integration Developer to build a business module to run in WebSphere Process Server. The details on how to do this are outside the scope for this paper, but the module would have an export with a Web services (SOAP/JMS) binding and a Java™ component that outputs +++++ Got to BigEchoJMS to the console when invoked. Listing 2 shows the WSDL generated by Integration Developer to describe the service provider named BigEchoJMS.

Listing 2. BigEchoJMS service definition
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="Export1_BigEchoJms_Service" 
targetNamespace="http://big.com/Binding"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:Port_0="http://big.com"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:this="http://big.com/Binding"
xmlns="http://schemas.xmlsoap.org/wsdl/">
  <wsdl:import namespace="http://big.com" location="BigEcho.wsdl"/>
  <wsdl:binding name="Export1_BigEchoJmsBinding" type="Port_0:BigEcho">
    <soap:binding style="document" 
transport="http://schemas.xmlsoap.org/soap/jms"/>
    <wsdl:operation name="echo">
      <soap:operation/>
      <wsdl:input name="echoRequest">
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="echoResponse">
        <soap:body use="literal"/>
      </wsdl:output>
      <wsdl:fault name="BadBoyException">
        <soap:fault name="BadBoyException" use="literal"/>
      </wsdl:fault>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="Export1_BigEchoJmsService">
  <wsdl:port name="Export1_BigEchoJmsPort"
binding="this:Export1_BigEchoJmsBinding">
      <soap:address
location="jms:/queue?destination=jms/Export1&
	connectionFactory=jms/Export1QCF&
	targetService=Export1_BigEchoJmsPort"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>
  1. Open the Mediation Flow editor for MESRouter, and click the Property tab, then Details for the MessageElementSetter1. You should see something like Figure 10.
  2. Edit the value field for /headers/SMOHeader/Target/address to contain the JMS address of the BigEchoJMS module (it will be similar to that shown in the location attribute of the address element in Listing 2).
  3. Save the mediation module and restart it.
  4. If you test MESRouter again, you should see the message +++++ Got to BigEchoJMS in the test environment console, showing that the mediation module invokes the BigEchoJMS provider. Not only have you changed the provider address, but the provider binding as well!

Another advantage to using the MessageElementSetter mediation primitive is that WebSphere ESB V6.0.2 allows properties, such as the value of the provider address placed in the SMO head, to be promoted. This makes such properties available in the WebSphere ESB administrative console, so you can change them after deployment without redevelopment.

Figure 11 shows how the provider address would be promoted for MessageElementSetter1 in the MESRouter mediation module. You can then find and modify the address in the administrative console under the name MessageElementSetter1.targetAddress. This allows you to change the address from the BigEcho provider to the BigEchoJMS provider after deployment of the MESRouter mediation module. This feature means that you can easily perform administrative duties, such as changing target addresses when moving service providers from one environment to another. See Dynamic endpoint example URIs in the WebSphere Integration Developer Information Center for more information on promoted properties.

Figure 11. Promoted properties
Figure 11. Promoted properties

There's one more feature of the MessageElementSetter you should know about. When you constructed the message element target using the Add/Edit dialog in Figure 8, you left the Type field as String so that the Value field could be the desired string constant. However, the Type field has additional options, one of which is copy, which allows you to copy a value from anywhere in the message (also identified by an XPath expression) into the desired location, in this case the address used by the dynamic endpoint mechanism. You can use this feature perform some forms of content-based routing.


Dynamic routing with EndpointLookup

Now let's look at the new EndpointLookup mediation primitive, built specifically to leverage the dynamic endpoint mechanism. One of the key characteristics of dynamic routing performed by an ESB is the ability to be metadata-driven. This enables a more holistic service-oriented solution that is tightly integrated with the overall governance model for an enterprise. A service registry is at the core of this principle. IBM's WebSphere Service Registry and Repository (hereafter called Service Registry and Repository) fills the role of a service registry in service-oriented solutions. For information about Service Registry and Repository, see Resources. While Service Registry and Repository spans a broad range of activities in a service-oriented solution, I'm going to focus on dynamic routing enabled by metadata managed by Service Registry and Repository.

The EndpointLookup mediation primitive enables a mediation flow component to leverage Service Registry and Repository without requiring custom programming to facilitate metadata-driven dynamic routing. The EndpointLookup mediation primitive allows a mediation component to retrieve service endpoint information from Service Registry and Repository. See EndpointLookup mediation primitive in the WebSphere ESB Information center for more information. The service endpoint information can relate to Web services or to SCA module exports with Web services or SCA bindings.

The primitive queries Service Registry and Repository for endpoint information that matches the criteria configured in the properties of the primitive. The only mandatory criteria relate to the WSDL port type of the providers, but the criteria can also include user-defined properties and classifications. The primitive also has a match policy property that tells the primitive to return one or all matches. For one match, the primitive automatically inserts the endpoint address in the SMO header to drive the dynamic endpoint mechanism. For all matches, you need to insert some other mediation primitive in the flow to process the matches and choose one to drive the dynamic endpoint mechanism.

Now let's look at probably the simplest, but nevertheless interesting, use of the EndpointLookup mediation primitive. To implement the example, you need to install Service Registry and Repository, including the latest fix pack (see Resources). You also need to define the Service Registry and Repository to the WebSphere ESB or WebSphere Process Server on which you plan to run the mediation module that uses the EndpointLookup; this is necessary even for a test environment in Integration Developer.

  1. To configure a Service Registry and Repository instance in the server environment, open the administrative console, select Service Integration => WSRR definitions and click New . Figure 12 shows the definition of the Service Registry and Repository instance, TestWSRR, used in the demonstration of the EndpointLookup. Notice that the authentication alias is set for an insecure connection to Service Registry and Repository.
    Figure 12. Service Registry and Reposity definition in test environment
    Figure 12. Service Registry and Reposity definition in test environment
  2. Load, or publish, the WSDL document for the BigEcho provider, as shown in Figure 13.
    Figure 13. Published WSDL for BigEcho provider
    Figure 13. Published WSDL for BigEcho provider

    Service Registry and Repository understands WSDL documents and will create the logical elements defined in a WSDL document. Figure 14 shows the WSDL port type created, Figure 15 shows the binding, Figure 16 shows the service, and Figure 17 shows the port.

    Figure 14. Port type for BigEcho provider
    Figure 14. Port type for BigEcho provider
    Figure 15. Binding for BigEcho provider
    Figure 15. Binding for BigEcho provider
    Figure 16. Service for BigEcho provider
    Figure 16. Service for BigEcho provider
    Figure 17. Port for BigEcho provider
    Figure 17. Port for BigEcho provider
  3. Next create a new mediation module, WSRRRouter, that uses the EndpointLookup mediation primitive. In the assembly editor, follow the instructions above for the MESRouter to create a mediation module that looks like Figure 6.
  4. Open the Mediation Flow editor and map the operation and create the response flow as you did for the MESRouter. For the request flow, drop an EndpointLookup mediation primitive into the flow. Wire the mediation component interface to the primitive input terminal and wire the primitive output terminal to the mediation component reference, as shown in Figure 18.
    Figure 18. WSRRRouter request flow
    WSRRRouter request flow
  5. Open the properties for EndpointLookup1, as shown in Figure 19. Set the port type's Name and Namespace to those used for the BigEcho port type. You can click Browse to simplify the process. Leave the Version field blank. You need to identify the Service Registry and Repository used; the primitive will extract the access information about that Service Registry and Repository from the server environment. For this example, enter TestWSRR as the Registry Name. Finally, in the Match Policy field, select Return one matching endpoint. Save the mediation flow and the mediation module and deploy the module to the test environment in Integration Developer.
    Figure 19. EndpointLookup1 properties
    Figure 19. EndpointLookup1 properties
  6. Test WSRRRouter using the Web Services Explorer. When the mediation primitive gets the request, it queries for all ports matching the port type identified in the properties. Because BigEcho is the only match in this test, the endpoint information is returned in the query and the primitive places the endpoint address in the header to drive the dynamic endpoint mechanism. You should see the message +++ Got to BigEcho in the test environment console, showing that the mediation module invokes the BigEcho provider.

Let's take a look at another scenario.

  1. "Load the WSDL document for the BigEchoJMS provider into the Service Registry and Repository. If you examine the registry content, you'll see the WSDL documents for the BigEchoJMS provider and the BigEcho provider, as shown in Figure 20.
    Figure 20. WSDL for BigEchoJMS and BigEcho
    Figure 20. WSDL for BigEchoJMS and BigEcho

    Since both providers implement the same port type, only the BigEcho port type is defined in the registry. There will of course be a new binding, a new service and a new port, as shown in Figure 21, Figure 22, and Figure 23 respectively.

    Figure 21. HTTP and JMS bindings
    Figure 21. HTTP and JMS bindings
    Figure 22. BigEcho and BigEchoJMS services
    Figure 22. BigEcho and BigEchoJMS services
    Figure 23. BigEchoJMS and BigEcho ports
    Figure 23. BigEchoJMS and BigEcho ports
  2. Without making any changes to WSRRRouter, run the test again. Although not guaranteed, you'll probably see the following message +++++ Got to BigEchoJMS in the test environment console, showing that the mediation module invokes the BigEchoJMS provider instead of the BigEcho provider.

You made this change simply by using metadata. This is because even though there are now two matches for the port type, you have the match policy set to return only the first. Since the JMS version was loaded last, it happens to be the first found during the query; however, that might not always be the case, depending on other activity in the registry.

If you want to guarantee which provider is chosen by the primitive, you can leverage the additional criteria that can be used in the query by modifying the EndpointLookup1 properties as shown in Figure 24.

  1. Select Details, then click the Advanced tab.
  2. Click Add in the User Properties section, and add a property with the name Preferred, a type of string, and a value of yes.
  3. Save the mediation flow and mediation module.
    Figure 24. Additional criteria for WSRR query
    Figure 24. Additional criteria for WSRR query
  4. Add a custom property to the desired provider. In the Service Registry and Repository console, select Ports => BigEcho => Custom Properties. Click New and add a property named Preferred with a value of yes and save the information. See Figure 25 for the results.
    Figure 25. Custom property for BigEcho port
    Figure 25. Custom property for BigEcho port
  5. Test WSRRRouter again. You'll see the message +++ Got to BigEcho in the test environment console, showing that the mediation module invokes the BigEcho provider instead of the BigEchoJMS provider.

Once again, you accomplished this change using the power of metadata! You can, of course, ensure that BigEchoJMS provider is chosen instead by setting a Preferred property to yes on its port, in conjunction with setting the Preferred property on the BigEcho port to any value but yes or by ensuring that there is no such property.


Summary

This article showed you some of the new features in of WebSphere ESB V6.0.2. These features greatly enhance your ability to use WebSphere ESB to perform metadata-driven routing. However, this article demonstrated only the basics. Consider combining the MessageElementSetter and the EndpointLookup mediation primitives to enable metadata-driven routing along with an administratively configured default. Or, consider adding the MessageFilter mediation primitive to that combination to support multiple port types. Using WebSphere ESB V6.0.2, you can perform powerful and flexible dynamic routing that greatly enhances your service-oriented solutions.

Resources

Learn

Get products and technologies

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


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. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

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.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

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

 


All information submitted is secure.

Dig deeper into Business process management on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Business process management, WebSphere, SOA and web services
ArticleID=191440
ArticleTitle=IBM WebSphere Developer Technical Journal: Dynamic routing improvements in WebSphere Enterprise Service Bus V6.0.2
publish-date=01242007