Contents


Integrating IBM Integration Bus with WebSphere Service Registry and Repository

Part 6: Service gateway and registry lookup scenarios

Comments

Content series:

This content is part # of # in the series: Integrating IBM Integration Bus with WebSphere Service Registry and Repository

Stay tuned for additional content in this series.

This content is part of the series:Integrating IBM Integration Bus with WebSphere Service Registry and Repository

Stay tuned for additional content in this series.

It is generally accepted that you should never allow direct access to a service provider in a SOA environment. Instead, you should deploy a new virtual service to the Enterprise Service Bus (ESB) which acts as a proxy to the real back end service. Introducing a controlled point of access to the back end service provides several benefits. In its most basic form it achieves loose coupling between the service consumer and the service provider, allowing you to relocate the back end service or modify its interface without necessarily impacting the service consumer. This pattern is commonly referred to as a simple service proxy. It also enables you to introduce service management functionality, for example error handling and alerting, logging, security configuration, traffic management, service charging and performance measurement. These are extensions to the simple service proxy pattern.

One problem with the simple service proxy pattern is that you need to implement and deploy a new virtual service for each back end service in your SOA. Obviously, as the number of the services in your SOA starts to grow, the effort that is required to achieve this could become prohibitive. The service gateway pattern addresses this problem by providing a single point of access for multiple back end services, routing requests for different service providers to the appropriate endpoint. This pattern also allows you to introduce common service management functionality for all of the services that are accessed through the gateway.

This article describes a sample message flow that implements the service gateway pattern. It dynamically retrieves metadata from WSRR at runtime and uses it to determine how to route service requests.

Service Gateway Business Scenario

A gateway is a part of an ESB which provides boundary functions which apply to all incoming messages and are not format dependent.

Boundary functions typically utilise data from standard headers (at transport, SOAP or even data level) to determine what action to take but do not need to understand the complete format of the message data (or body). A gateway pattern may then call a service directly or invoke a further pattern. These boundary functions include:

  • Request routing
  • Authentication
  • Authorisation
  • Audit and logging
  • Protocol conversion
  • Response correlation

Examples of gateway patterns include:

  • Security gateway

    This rather specific example of a gateway pattern offloads all non-standard security processing from the main infrastructure and will execute authentication, authorisation, and possibly audit before calling the true destination. In this mode there is almost always a trusted link between the gateway and other parts of the ESB so that the security model required for those other parts of the ESB can be simplified. Security gateways may reside in a different security zone to the rest of the ESB and would provide connectivity to external clients. This pattern would support a wide range of incoming security protocols while simplifying security in other ESB components.

  • Service connector

    The gateway pattern can provide the simplest possible way of connecting a number of existing services into an ESB when introduced as part of an enterprise architecture based on service oriented principles. The gateway introduces a point of control in the enterprise architecture and can bring a range of ad hoc services under the control of a service registry and associated governance but without the need to develop individual mediation flows for each service. Messages enter the gateway and are routed onwards to an end provider, to a provider facade or to a further mediation flow.

  • Boundary mediator

    The boundary mediator pattern extends the service connection pattern by enabling standard mediations to be applied to all incoming (and/or outgoing) service requests or messages. These standard (content independent) mediations are developed once in the gateway and can be applied to all incoming messages. They can include any or all of validation, logging, audit, authentication and authorization. They can be applied universally or selectively based on the gateway properties, on data looked up based on request data or on data within the incoming request (normally in headers).

Service Gateway Business Scenario

The sample flow that is described within this article is an implementation of the Service connector pattern described above. It focuses on the Service Gateway scenario described in Part 1: Scenarios and configuration, as follows:

  • Business Problem

    You have several services that you want to apply some common processing to at the ESB level. You do not want to build and deploy a separate flow to proxy each back-end service to achieve this.

  • Solution

    By using a SOAP Input node in gateway mode, no service specific validation is performed on the SOAP messages that are received by that node. This enables you to implement a single message flow that can handle service requests for many back end services. Such a message flow can then provide common functionality that is applied to all of the service requests that it processes, such as authorization, logging and so on. To route the service requests to the back-end services the message flow must retrieve the endpoints from WSRR.

  • Benefits

    This approach enables you to implement common processing logic in a single place, reducing the overall development and test effort by simplifying the process of routing, monitoring, logging, versioning and securing service requests for multiple services. It also simplifies the process of invoking the target services because the service consumers only need to know a single endpoint.

Information Available from the Service Request

To route a service request to the correct target service, the message flow needs to extract enough information from the request to allow it to find the correct endpoint in WSRR. The two key pieces of information that we need to extract are the namespace for the service request and the name of the operation being invoked. The sections that follow describe how this information is extracted.

Service Namespace

The most popular binding style of web service implementations is document/literal wrapped. The basic characteristics of this pattern are as follows:

  • The input message has a single part
  • The part is an element
  • The element has the same name as the operation
  • The element's complex type has no attributes

As a result, the message flow is able to determine the namespace for the service by inspecting the body of the request. It does this by programmatically obtaining a reference to the child element of the SOAP body and then querying the namespace of the element.

The Math Service is an example of a web service that uses the document/literal wrapped pattern. shows an example of a service request for the Math Service. You can see from this request that the namespace for the service is http://math.pot.ibm.com.

Example Math Service Request
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
                     xmlns:math="http://math.pot.ibm.com">
  <soapenv:Header>
    <math:MathHeader>
      <consumerID>CalculatorApplication</consumerID>
      <contextID>CTX_1</contextID>
    </math:MathHeader>
   </soapenv:Header>
   <soapenv:Body>
      <math:add>
         <augend>1</augend>
         <addend>1</addend>
      </math:add>
   </soapenv:Body>
</soapenv:Envelope>

Operation Name

The SOAP Input node, provided by IBM Integration Bus, parses each service request and extracts additional information. One of the pieces of information it attempts to extract is the name of the operation being invoked. This is stored in the message tree generated by the node. shows the location of the operation name in the message tree using the debugger that is provided in the IBM Integration Toolkit. The operation name shown, add, has been extracted from the service request shown in the previous listing.

Operation Name Shown in the Debugger
Operation Name Shown in the Debugger
Operation Name Shown in the Debugger

Service Operations

When a WSDL or XSD document is loaded into WSRR, it parses the content of the document and creates a number of objects to represent that content. If the WSDL document contains a portType element that defines the operations for the service, WSRR will create a Service Operation object for each operation defined. The service operation contains a number of properties that can be used by the message flow to determine the correct endpoint to which service requests should be routed.

Service Operation Properties

In the context of this discussion, the most important properties on a service operation are as follows:

  • Namespace
  • Operation name
  • Interface name
  • Interface namespace
  • Interface version

The service namespace and operation name that were extracted from the service request can be used by the message flow to retrieve the corresponding service operation from WSRR. The message flow can then use the values of the Interface name, Interface namespace and Interface version properties on the retrieved service operation to retrieve the endpoint for the target service using the Endpoint Lookup node. describes these properties, along with the other properties that are defined on the service operation type.

Service Operation Properties
Display nameProperty nameDescriptionType
NamenameA descriptive name for the service operation.String
DescriptiondescriptionA textual description of the service operation.String
NamespacenamespaceThe XML schema namespace for the service operation.String
VersionversionThe version of the service operation.String
Interface versionsm63_interfaceVersionThe version of the service interface (port type version).String
Interface namespacesm63_interfaceNamespaceThe namespace of the service interface (port type namespace).String
Interface namesm63_interfaceNameThe name of the service interface (port type name).String
Operation namesm63_operationNameThe name of the WSDL operation that is represented by this service operation.String

Using the sample data provided with the articles in this series, shows how the relevant objects in WSRR are related to each other. It shows the four Service Operation objects and the two SOAP Service Endpoints for the Math Service. Note that, for clarity, some objects are not shown on this graph.

Graph of objects pertaining to the MathService.
Graph of objects pertaining to the MathService.
Graph of objects pertaining to the MathService.

Message Flow Description

The gateway flow extracts information from the service request and uses it to retrieve the corresponding service operation from WSRR. The additional information that is available on the service operation is then used to perform another query against WSRR, this time to retrieve the actual endpoint for the target service. After the endpoint is determined, the gateway flow routes the service request to the target service and returns the response to the client. If either of the queries against WSRR return no results, a SOAP fault is returned to the client.

The implementation of the gateway flow comprises 8 nodes; 7 for normal operation and 1 for error handling. shows the flow itself in the Message Flow Editor of the IBM Integration Toolkit. The following describes each of the nodes in this message flow in detail.

The Service Gateway Flow
Diagram of the service registry gateway flow
Diagram of the service registry gateway flow

SOAP Input node

The input node for the gateway flow is a SOAP Input node. It is configured to use the HTTP transport with a URL suffix of /gateway. The important point to note about this node is that it is configured to Operate in gateway mode. This is specified on the Basic tab of the Properties editor for the node. The SOAP Input node is connected to the next node in the gateway flow using the out terminal.

Gateway Mode
Gateway Mode
Gateway Mode

Process Gateway Request node

The Process Gateway Request node is an instance of a Java Compute node. It processes the service requests that are passed to it from the SOAP Input node, extracting the namespace, for the service request, and the operation name, as described in .

Process Gateway Request node
Process Gateway Request node

The code shown in the following listing gets a reference to the first child element of the SOAP body and then retrieves the namespace for this element. This is the namespace for the operation being invoked. It also retrieves the name of the operation being invoked by inspecting the relevant location in the message tree. The operation name was written to this location by the SOAP Input node when it parsed the incoming service request.

Java code reading the namespace and operation name
MbElement bodyChildElement = 
    rootElement.getFirstElementByPath("SOAP/Body").getFirstChild();
    
String namespace = bodyChildElement.getNamespace();

String operation = 
    (String)rootElement.evaluateXPath("string(SOAP/Context/attribute::operation)");

Having checked that a valid service namespace and operation name have been extracted from the service request, the Process Gateway Request node then inserts the relevant fields into the local environment tree to programmatically override the properties on the Registry Lookup node. The code shown in the following listing configures the Registry Lookup node to retrieve objects that have a Namespace property that matches the namespace of the service request, and a sm63_operationName property that matches the operation name of the service request. In the Governance Enablement Profile (GEP), the default configuration profile for WSRR, the sm63_operationName property is unique to the Service Operation type, so the Registry Lookup node should only return objects of this type. However, for clarity, the Process Gateway Request node also specifies that the primaryType must match the URI of the Service Operation type. The Process Gateway Request node then passes the message to the out terminal, which is wired to the Registry Lookup node.

Java code overriding Registry Lookup node variables
private static final String OWL_URI_SERVICE_OPERATION = 
    "http://www.ibm.com/xmlns/prod/serviceregistry/v6r3/ServiceModel#ServiceOperation";

MbMessage environment = new MbMessage(inAssembly.getLocalEnvironment());
MbElement environmentRoot = environment.getRootElement();
environmentRoot.evaluateXPath(
    "?ServiceRegistry LookupProperties/?UserProperties/?Namespace[
    set-value('" + namespace + "')]");
    
environmentRoot.evaluateXPath(
    "?ServiceRegistry LookupProperties/?UserProperties/?sm63_operationName[
    set-value('" + operation + "')]");
    
environmentRoot.evaluateXPath(
    "?ServiceRegistry LookupProperties/?UserProperties/?primaryType[
    set-value('" + OWL_URI_SERVICE_OPERATION + "')]");

If either the namespace or the operation name for the service request cannot be determined, a SOAP fault is generated and the node passes the message to the failure terminal. This terminal is wired directly to the SOAP Reply node, which passes the SOAP fault back to the client.

Registry Lookup node

The behaviour of the Registry Lookup node is determined by the entries that were programmatically created in the local environment tree by the previous node. As discussed above, one or more Service Operation objects will be returned whose operation name and namespace matches the values extracted from the service request. The node inserts representations of all the matching objects into the ServiceRegistry entry in the local environment tree and then passes the message to the out terminal. The Match Policy for the node is set to All and the Depth Policy is set to Return matched only (Depth = 0). A dummy value must be specified for the Name property to allow the message flow to be saved and deployed to IBM Integration Bus. This value is programmatically cleared by the previous node in the flow.

Registry Lookup node
Registry Lookup node

If the query performed by the Registry Lookup node returns no results, the node passes the message to the NoMatch terminal, which is wired to the No Match Faultnode.

Process Service Operations node

The Process Service Operations node is another instance of a Java Compute node. It processes the results of the query performed by the previous Registry Lookup node and uses them to insert the relevant fields into the local environment tree to programmatically override the properties on the Endpoint Lookup node.

Process Service Operations node
Process Service Operations node

The code shown in the following example gets a reference to all of the Entity entries that are contained in the ServiceRegistry entry in the local environment tree. If there are multiple compatible versions of the target service registered in WSRR, the query may return multiple results. If this is the case, you could choose to implement some logic to select a specific Service Operation. For example, you might want to ensure that the request is routed to the endpoint for the latest version of the service. This code assumes that all of the versions sharing the same namespace are compatible, which is in line with recommended practice for service versioning. For now, the Process Service Operations node simply selects the first service operation from the list. It then retrieves the values of the sm63_interfaceName, sm63_interfaceNamespace and sm63_interfaceVersion properties from this object. These properties correspond to the name, namespace and version properties on the portType for the target service.

Java code retrieving interface name, namespace and version properties from the Service Operation
MbElement rootElement = inAssembly.getLocalEnvironment().getRootElement();
MbElement serviceRegistry = rootElement.getFirstElementByPath("/ServiceRegistry");

List<MbElement> serviceOperations = 
  (List <MbElement>)serviceRegistry.evaluateXPath("Entity");
  
if (serviceOperations != null && !serviceOperations.isEmpty()) {
  MbElement serviceOperation = serviceOperations.get(0);
  String portTypeName = 
    (String)serviceOperation.evaluateXPath(
      "string(userDefinedProperties[@name='sm63_interfaceName']/attribute::value)");
      
  String portTypeNamespace = 
    (String)serviceOperation.evaluateXPath(
      "string(userDefinedProperties[@name='sm63_interfaceNamespace']/attribute::value)");
      
  String portTypeVersion = 
    (String)serviceOperation.evaluateXPath(
      "string(userDefinedProperties[@name='sm63_interfaceVersion']/attribute::value)");

The Process Service Operations node checks that valid interface name, namespace version properties have been retrieved from the selected service operation. It then inserts the relevant fields into the local environment tree to programmatically override the properties on the Endpoint Lookup node. It sets the value of the Name, Namespace and Version properties to those retrieved from the service operation. Before doing this it must remove the entries in the local environment tree that were used by the Registry Lookup node earlier in the message flow. Specifically, it needs to delete the UserProperties defined by the Process Gateway Request node. The code in shows these tasks being performed. The Process Service Operations node then passes the message to the out terminal, which is wired to the Endpoint Lookup node.

Java code setting parameters used by the Endpoint Lookup Node
private static final String OWL_URL_ONLINE = 
    "http://www.ibm.com/xmlns/prod/serviceregistry/lifecycle/v6r3/LifecycleDefinition"
    + "#Online";

if (  portTypeName != null && !portTypeName.isEmpty()
    && portTypeNamespace != null && !portTypeNamespace.isEmpty()
    && portTypeVersion != null && !portTypeVersion.isEmpty()
    )   {

    MbMessage environment = new MbMessage(inAssembly.getLocalEnvironment());
    MbElement environmentRoot = environment.getRootElement();
    
    ((List <MbElement>)environmentRoot.evaluateXPath(
        "ServiceRegistry LookupProperties/UserProperties")).get(0).delete();
        
    environmentRoot.evaluateXPath(
        "?ServiceRegistry LookupProperties/?Name[set-value('" + portTypeName + "')]");
        
    environmentRoot.evaluateXPath(
        "?ServiceRegistry LookupProperties/?Namespace[set-value('" 
            + portTypeNamespace + "')]");
            
    environmentRoot.evaluateXPath(
        "?ServiceRegistry LookupProperties/?Version[set-value('" 
            + portTypeVersion + "')]");
            
    environmentRoot.evaluateXPath(
        "?ServiceRegistry LookupProperties/?Classification[set-value('" 
            + OWL_URL_ONLINE + "')]");

If the Process Service Operations node was unable to retrieve one of the interface name, namespace or version properties from the service operation, a SOAP fault is generated and the node passes the message to the failure terminal. This terminal is wired directly to the SOAP Reply node, which passes the SOAP fault back to the client.

Endpoint Lookup node

The behaviour of the Endpoint Lookup node is determined by the entries that were programmatically created in the local environment tree by the previous node. The Match Policy for the node is set to One. This ensures that the node will select the first matching endpoint from the query results and set the relevant entries in the local environment tree that allow the node to be wired directly to a SOAP Request node. Optionally, you could specify a Match Policy of All and use another Java Compute node to select the most appropriate matching endpoint. In this case, your Java Compute node would also need to programatically set relevant entries in the local environment tree that are required by the SOAP Request node. Again, a dummy value has been specified for the Name property to allow the message flow to be saved and deployed to IBM Integration Bus. This value is programmatically overwritten by the previous node in the flow with name of the required portType.

Endpoint Lookup node
Endpoint Lookup node

If the query performed by the Endpoint Lookup node returns no results, the node passes the message to the NoMatch terminal. This terminal is wired to the No Match Fault node. Otherwise, the flow passes the results to the out terminal which is wired to the SOAP Request node.

SOAP Request and SOAP Reply nodes

The SOAP Request node is responsible for calling the target service. You must specify a value for the Web Service URL property when defining the flow, even though this will be programmatically overwritten at run time by the Endpoint Lookup node. As a result, a dummy value of http://tempuri.org/MathServer/services/MathServer has been specified for this property. Another important point to note is that the Operation mode for the node must be set to Invoke a generic web service. This is specified on the Basic tab of the Properties editor for the node. The SOAP Request node is wired directly to the SOAP Reply node using both the out and fault terminals.

SOAP Request and SOAP Reply nodes
SOAP Request and SOAP Reply nodes

The SOAP Reply node, as its name suggests, simply passes a SOAP response back to the service consumer. In a successful pass through the flow, the response returned will be the response from the actual target service. If an error occurs, the response will be a SOAP fault that was generated by one of the Java Compute nodes in the flow, or by the target service itself.

No Match Fault node

When an error occurs in either of the Java Compute nodes, the nodes programmatically generate an appropriate SOAP fault and pass this to their failure terminals. These are wired directly to the SOAP Reply node. However, when the queries performed by either the Registry Lookup or Endpoint Lookup nodes do not return any results, they do not automatically generate a SOAP fault. To do this, their NoMatch terminals are wired to the No Match Fault Java Compute node which programmatically generates a SOAP fault which is returned to the service consumer using the SOAP Reply node.

Testing the Message Flow

The steps that follow describe how to use the Calculator application to verify that the gateway flow is working correctly.

  1. Make sure that your IBM Integration Bus execution group is running, with the RegistryLookup_Gateway flow deployed and started.
  2. Start the calculator application, as described in Running the Calculator Application in Part 1.
  3. Specify suitable hostname and port number values for the server that is running IBM Integration Bus. For example, if you are running IBM Integration Bus on the same machine as the Calculator application and are using the default port these values would be localhost and 7800.
  4. Modify the path for the service, setting its value to /gateway. This is the endpoint for the Registry Lookup_Gateway flow deployed as part of article one. The Calculator application should look similar to this:
    The Calculator Application
    The Calculator Application
    The Calculator Application
  5. Specify some values and a suitable operator (+, -, /, *) in the drop-down and click = (the equals button). The Calculator application will send a service request to the gateway message flow, which will route the request to actual Math Service. The result is ultimately returned to the Calculator application and is then displayed.

You could also use a generic client that allows you to perform an HTTP POST to the gateway flow. This will allow you send service requests to the gateway for other services that are registered in WSRR and verify that the routing truly is dynamic. An example of using the Poster extension for Firefox to invoke Version 2 of the Math Service is shown below:

Using Poster
Using Poster
Using Poster

The namespace is http://math.pot.ibm.com/V2 and the added <dummyElement/> XML tag which make this a valid Version 2 request.

Conclusion

You should now understand why you want to use a gateway within your SOA environment. This article described an example message flow that provides an implementation of the service gateway pattern. This message flow extracted information from the service request and then dynamically retrieved metadata from WSRR at runtime that it used it to route the request to the target service. You should also be able to successfully exercise the functionality provided by the sample gateway flow with the calculator application or a generic client such as Poster.

Acknowledgements

The author thanks the following people for all of their help with the development of the sample messages flows in this series:

  • John Hosie
  • Ben Thompson
  • Matt Golby-Kirk
  • Trevor Dolby
  • Andreas Martens
  • Graham Haxby
  • Andrew Coleman
  • John Reeve

The author also thanks the following people for their help with reviewing this article:

  • David Seager
  • Anna Maciejkowicz

Downloadable resources


Related topics


Comments

Sign in or register to add and subscribe to comments.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Middleware
ArticleID=970374
ArticleTitle=Integrating IBM Integration Bus with WebSphere Service Registry and Repository: Part 6: Service gateway and registry lookup scenarios
publish-date=04302014