Overriding the WebSphere DataPower WSDL optimization conversion

WebSphere® DataPower performs a WSDL conversion when it exposes the WSDL to their clients. However, some Java™ clients cannot retrieve additional schemas, which DataPower creates for optimization purposes. In this article, you will learn how to override this optimization by using XSL transformations and XSL dynamic routing.

Share:

Jaime Martin Talavera (jaime_martin@es.ibm.com), IT Consultant, IBM

Photo of Jaime Martin TalaveraJaime Martin Talavera is an IT Consultant on the IBM Software Services for WebSphere team in Madrid, Spain. He primarily focuses on WebSphere DataPower. Jaime has been involved in numerous projects providing customers his technical expertise. He was selected for IBM Spain as part of a Graduate program in 2008.



26 September 2012

Introduction

IBM WebSphere DataPower SOA Appliance (hereafter called DataPower) helps you virtualize your web services to act as a gateway. This pattern gives you many advantages, such as:

  • Web services virtualization
  • Attack protection
  • Policy enforcement

For this reason, it is common to see this pattern in the network infrastructure of the customers.

Prerequisites and system requirements

This article is written for WebSphere DataPower SOA Appliances administrators and developers who have had interoperability issues with web services consumers that require the schema to be embedded in the WSDL, instead of a reference to the XSD schema file.

To build and execute the example in this article, you will need:

  • A WebSphere DataPower SOA Appliance. While this article is developed using an XI50 device, other models are also compatible, such as XS40, XG45, XI52, XB60, and XB62.
  • An XML editor. You can also use your favorite editor.

Sample files

You can import the export package, provided with this article, from the Import configuration option of your DataPower Control Panel. You will also need to modify the mappings.xml file to make the sample work properly with your services. No further downloads are required to complete the instructions in this article.


Understanding the architecture

One of the typical scenarios where DataPower fits is shown in Figure 1.

Figure 1. Basic scheme of the example
Basic scheme of the example

The web service itself is located in WebSphere Application Server (hereafter called Application Server) and DataPower sits between Application Server and clients (typically the Demilitarized Zone - DMZ). When a client wants to consume a web service, it invokes to DataPower, which checks for security threats and URL rewrites, checks the scheme of the incoming message, and performs all the operations specified on its processing policy before it invokes the service in the local Intranet.

The most flexible way to expose web services when you work with DataPower is using a Web Service Proxy. When you expose a web service using the Web Service Proxy object, DataPower requires the Web Services Description Language (WSDL) file. Once the service is deployed in the Web Service Proxy, DataPower internally optimizes the WSDL file for its consumption. If a client invokes the address of the service deployed in DataPower (plus the WSDL), it serves an optimized version of the WSDL, as shown in the xsd:import below:

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" ...>
        ...
  <wsdl:types xmlns:xsd="http://www.w3.org/2001/XMLSchema">
     <xsd:schema>
      <xsd:import schemaLocation="TemperatureConverter.xsd1.xsd" 
       namespace="http://converter.com"/>
      </xsd:schema>
     </wsdl:types>
        ...
</wsdl:definitions>

Sometimes, a legacy web service client may request the WSDL to the device. As mentioned before, DataPower serves the WSDL with internal references to XML schemas (also known as XSD), and the client cannot retrieve the XSD file. It needs a single WSDL file with every artifact embedded in it.

Therefore, if the client cannot retrieve the schemas, you can configure a Multi-Protocol Gateway in DataPower to retrieve the internal references, compose a single WSDL file, and serve it to the client. This pattern is reflected in Figure 2.

Figure 2. Internal objects involved in the example
Internal objects involved in the example

Creating the Multi-Protocol Gateway in DataPower

  1. Once you are logged into your domain in DataPower, you see the Control Panel page. Click on the Multi-Protocol Gateway icon, and create a new one by clicking on the Add button as shown in Figure 3.
    Figure 3. Adding a new Multi-Protocol Gateway
    Adding a new Multi-Protocol Gateway
  2. Write a name for the Multi-Protocol Gateway, such as Rewrite_XSD_Imports. Configure it as a dynamic-backend gateway and set both the request and response type as XML.
  3. Add a Front Side Protocol Handler (typically HTTP), and remember to check the GET method under the "Allowed Methods and versions" section, as shown in Figure 4.
    Figure 4. Creating an HTTP Front Side Handler
    Creating an HTTP Front Side Handler
  4. Under the Advanced tab, make sure that the Process messages whose body is empty is set to on. This parameter lets DataPower process the GET requests from the clients requesting the WSDL.

Creating the Multi-Protocol Gateway Policy

In this section, you create a policy with three rules in it:

  1. The first rule is in charge of getting all the WSDL requests from the clients, getting the WSDL from the backend, transforming it adding the XSDs, and giving it back to the client.
  2. The second rule bypasses the SOAP request to the backend.
  3. The third rule gets back the response from the backend server and serves it to the client.

The policy looks similar to Figure 5.

Figure 5. Policy overview of the Multi-Protocol Gateway
Policy overview of the Multi-Protocol Gateway

Rule 1: Both directions

This rule is triggered when the consumer requests the WSDL (see Figure 6). It will be detected by the presence of the "?WSDL" pattern ending the URL.

Figure 6. Rule overview for the WSDL transformation
Rule overview for the WSDL transformation
  1. Create a match action, which will trigger this rule for every incoming request whose URL ends in "?WSDL". The easiest way to do this is to configure the Match Regular Expression as (.*)[w|W][s|S][d|D][l|L]. Check the Match with PCRE toggle to on under the Main tab of the Matching Rule.
  2. Add a Transform Action after the Match Action you created before, and select the wsdl-fetch.xsl stylesheet of this example.

    This stylesheet gets the WSDL file from the backend. Since the Multi-Protocol Gateway you are creating in this sample can be used to modify the WSDLs of several Web Service Proxy services, the stylesheet loads a routing file, whose format is: URL of the service (deployed in the Multi-Protocol Gateway) and host of the service (where the service is located, typically the Web Service Proxy. An entry for this file would be:

    <mapping source="http://9.172.176.70:5321/services/TemperatureConverter"
     target="http://127.0.0.1:567"/>

    After getting the host where the service is deployed and building a valid URL for the WSDL, the stylesheet performs a dp:url-open() call to obtain the WSDL. The code for the stylesheet is shown in Listing 1.

    Listing 1. wsdl-fetch.xsl file
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:dp="http://www.datapower.com/extensions"
        xmlns:regexp="http://exslt.org/regular-expressions"
        xmlns:dpconfig="http://www.datapower.com/param/config"
        extension-element-prefixes="dp dpconfig regexp"
        version="1.0">
        
      <xsl:param name="dpconfig:mapping-file" select="'off'"/>
      <dp:param name="dpconfig:mapping-file" type="'dmFileToggle'" xmlns="">
        <tab-override>basic</tab-override>
        <display>Mapping file</display>
        <description>Select the mapping file to convert the URL's
        The default is local:///mappings.xml.</description>
        <default>local:///mappings.xml</default>
      </dp:param>
    
      <xsl:template match="/">
         <xsl:variable name="mappings" select="document($dpconfig:mapping-file)"/>
         <xsl:variable name="host_to_find"
            select="regexp:replace(
                       dp:variable('var://service/URL-in'),
                       '(.*)\?wsdl','i','$1')"/>
         <xsl:variable name="host"
            select="$mappings/mappings/mapping[@source=$host_to_find]/@target"/>
         <dp:set-variable name="'var://context/wsdl-fetch/host_to_find'"
            value="$host_to_find"/>
         <dp:set-variable name="'var://context/wsdl-fetch/host'" value="$host"/>
         <dp:set-variable name="'var://context/wsdl-fetch/wsdl-location'"
            value="concat($host,dp:variable('var://service/URI'))"/>
         <dp:url-open target="{
            dp:variable('var://context/wsdl-fetch/wsdl-location')}"/>
      </xsl:template>
        
    </xsl:stylesheet>

    The WSDL is the output of the stylesheet.

  3. Add another Transform Action by selecting the schema-fetch.xsl sytelesheet from the sample code.

    The schema-fetch.xsl stylesheet finds all the imports in the previously downloaded WSDL and replaces all of them with the document, which it is pointing to. To replace the import tags, the stylesheet builds, again, the URL of each schema and uses the dp:url-open() extension again to fetch them and place it into the WSDL file. The code for the schema-fetch.xsl stylesheet is shown in Listing 2.

    Listing 2. schema-fetch.xsl file
    	<?xml version="1.0" encoding="UTF-8"?>
    	<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    	    xmlns:dp="http://www.datapower.com/extensions"
    	    xmlns:regexp="http://exslt.org/regular-expressions"
    	    extension-element-prefixes="dp regexp"
    	    version="1.0">
    	    
    	    <xsl:template match="/">
    	        <xsl:apply-templates/>
    	    </xsl:template>
    	    
    	    <xsl:template match="/*[local-name()='definitions']
    	            /*[local-name()='types']/*[local-name()='schema']">
    	        <xsl:for-each select="*[local-name()='import']">
    	              <xsl:variable name="myURI"
    	                  select="regexp:replace(
    	                      dp:variable('var://service/URI'),
    	                      '(.*)/(.*)?wsdl','i','$1/')"/>
    	              <xsl:variable name="location"
    	                  select="concat(
    	                      dp:variable('var://context/wsdl-fetch/host'),
    	                      $myURI,@schemaLocation)"/>
    	              <dp:url-open target="{$location}"/>
    	        </xsl:for-each>
    	    </xsl:template>
    	    
    	    <!-- Copy everything else -->
    	    <xsl:template match="@*">
    	        <xsl:copy/>
    	    </xsl:template>
    	    
    	    <xsl:template match="*">
    	        <xsl:copy>
    	            <xsl:copy-of select="@*"/>
    	            <xsl:apply-templates select="node()"/>
    	        </xsl:copy>
    	    </xsl:template>
    	    
    	</xsl:stylesheet>
  4. After the second transformation, add a set-variable action and set the var://service/mpgw/skip-backside variable to "1". This avoids the backside processing phase.

Rule 2: Client-to-server direction

This rule handles the client SOAP requests and forwards it to the backend (see Figure 7).

Figure 7. Rule overview for the SOAP requests
Rule overview for the SOAP requests
  1. Create a match-all action that gets all the SOAP requests and sends them to the backend.
  2. Add a transform action after the match-all and select the wsdl-post.xsl stylesheet provided in the sample file. This stylesheet gets the routing information (as you previously did in the first rule) and forwards the SOAP request to the backend. The content for the wsdl-post.xsl stylesheet is shown in Listing 3.
    Listing 3. wsdl-post.xsl file
    	<?xml version="1.0" encoding="UTF-8"?>
    	<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    	    xmlns:dp="http://www.datapower.com/extensions"
    	    extension-element-prefixes="dp"
    	    version="1.0">
    	    
    	    <xsl:template match="/">
    	        <xsl:variable name="mappings" select="document('local:///mappings.xml')"/>
    	        <xsl:variable name="host" select="$mappings/mappings/mapping[@source=
                 dp:variable('var://service/URL-in')]/@target"/>
    	        <dp:set-variable name="'var://service/routing-url'" value="concat(
                 $host,dp:variable('var://service/URI'))"/>
    	
    	    </xsl:template>
    	    
    	</xsl:stylesheet>

Rule 3: Server-to-client direction

This rule handles the SOAP response and serves it back to the consumer (see Figure 8).

Figure 8. Rule overview for the SOAP responses
Rule overview for the SOAP responses

Create a server-to-client rule just to get the SOAP responses back to the client.


Sample files

The zip file provided with this article contains the sample files you previously selected in the configuration of the Multi-Protocol Gateway. Unzip them using your favorite ZIP extraction tool. An export of the Multi-Protocol Gateway is also provided (Rewrite_XSD_Imports.zip), so you can import it using the Import Configuration option in the DataPower Control Panel. The zip file includes the following files:

  • mappings.xml
  • schema-fetch.xsl
  • wsdl-fetch.xsl
  • wsdl-post.xsl
  • Rewrite_XSD_Imports.zip

Conclusion

In this article, you learned how to change services in WebSphere DataPower to modify the content of the WSDL files served by the Web Service Proxy object, or any other server that splits the WSDL file in several files. Splitting the files is good practice, but some clients are not able to get those files. You also learned how to route requests using a routing file and the var://service/routing-url variable.


Download

DescriptionNameSize
Sample filessample-files.zip481KB

Resources

Learn

  • WebSphere DataPower V4.0.1 Training: In this IBM Training course, you learn about the components of the WebSphere DataPower. The course also explores patterns, common security threats, and shows you how to build services to interoperate with various systems.
  • WebSphere DataPower V4.0.2 Information Center: A single web portal to all WebSphere DataPower documentation, with conceptual, task, and reference information on installing, configuring, and using your WebSphere DataPower SOA Appliance.
  • WebSphere DataPower Education Assistant: A web portal to WebSphere DataPower documentation, with narrated presentations given by people from education and people from the labs.
  • developerWorks WebSphere DataPower zone: A technical resources page that provides how-to articles and information about DataPower.

Discuss

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 WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=837208
ArticleTitle=Overriding the WebSphere DataPower WSDL optimization conversion
publish-date=09262012