Cisco ACE XML Gateway User Guide (Software Version 6.0)
Transforming Messages with XSLT

Table Of Contents

Transforming Messages with XSLT

Transformations in the ACE XML Gateway

XSLT Version Support

XSLT Processing Points

Applying Remote XSL Transformations

XSLT Variables

Variables Summary

Example of Using XSLT Variables

LDAP Results Transformation Example

Processing by Remote XSLT

Using Remote XSLT Retrieval

Using Dynamically Selected Remote XSLT Retrieval


Transforming Messages with XSLT


This chapter describes how to use XML Transformations with the ACE XML Gateway. It covers these topics:

Transformations in the ACE XML Gateway

XSLT Variables

LDAP Results Transformation Example

Processing by Remote XSLT

Transformations in the ACE XML Gateway

In the normal course of processing a message, the ACE XML Gateway usually transforms the message in a variety of ways. For example, it may transform it from one protocol to another (for example, from JMS to HTTP), it may encrypt or decrypt the message, or add or consume message headers.

These transformations are a by-product of the ACE XML Gateway policy configuration. However, you can apply direct transformations to messages as well. Using XSL Transformations (XSLT), you can control the content and structure of messages passed through the ACE XML Gateway.

XSLT Version Support

The ACE XML Gateway supports XSLT as specified by XSL Transformations W3C Recommendation Version 1.0. For more, see:

http://www.w3.org/TR/xslt

All language feature described by the specification can be used in the XSLT files applied to the ACE XML Gateway.

Additionally, the ACE XML Gateway defines system variables that give you access to information regarding the message context, including source IP address, time of request, request arguments, and more.

XSLT Processing Points

As shown in Figure 13-1, XSLT processing can be applied to messages at various points in the processing flow:

Pre-processing of the request message (A)

Message body processing on the request route (B)

Post-processing of the request (C)

Pre-processing of the response (D)

Message body processing on the response route (E)

Post-processing of the response (F)

Message body before logging (G)

Figure 13-1 Message processing

While transforms generally act directly upon the message, the message log transformation (G) acts only upon a copy of the message as saved to the log. It is often used to hide sensitive information that would otherwise be logged.

Using XSLT variables, this type of transformation can also provide a mechanism for enhancing the information that is logged, adding information about requests to facilitate troubleshooting or development, for example.

Applying Remote XSL Transformations

Like other types of resources, to be used in the ACE XML Gateway policy, an XSL Transformation is usually first uploaded to the policy in the ACE XML Manager and then applied to a service definition as needed. However, for XSLT files, you have the additional option of having the ACE XML Gateway retrieve the XSLT from a remote resource dynamically at the time of message processing.

Remote XSLT retrieval makes it possible to modify and improve an XSLT without having to edit and redeploy the ACE XML Gateway policy. However, it also forms the basis of a configuration option that affords even greater flexibility—dynamic selection of XSLT files. In dynamic selection of XSLT files, the XSLT used to transform a particular message is chosen from multiple XSLTs based upon a factor evaluated at the time of message processing. It allows considerable flexibility for adapting content for a particular recipient.

XSLT Variables

XSLT variables give you access to runtime information. There are two types of variables:

User-defined variables

Built-in variables

A user-defined variable is one that is created and bound to a value in an SDK extension (such as an authorization or transformation extension). In such extensions, you can save information to what is called SDK data, which is intended for sharing information among extensions. Not only can other extensions access the information, but XSLTs can as well.

To access the value of this type of variable, reference the variable name with the prefix "$SDK_DATA". For example:

<xsl:copy-of select="$SDK_DATA-key"/>

In this example, "key" is the name given to the variable by an extension that has processed the message in the ACE XML Gateway processing path prior to the application of the XSLT. For more information on using variables from extensions, see the Cisco ACE XML Gateway Developer Guide.

Built-in variables are defined and set by the system. They provide runtime information related to the message being processed. You can access their content using a copy-of XSLT element, with the variable as the select target, as in the following form:

<xsl:copy-of select="$<prefix>-<var>"/>

Where prefix is the type of variable, and var is the name of the XSLT variable. As listed below, there are several types of built-in variables:

Metadata (META). General information on the message. These mainly pertain to the ACE XML Gateway's internal handling of the message.

Transport (TRANSSRC). Information on transport-related characteristics of the message, such as the source IP.

Message Header (MSGSRC). Information on message header values.

Security (SECSRC). Information on encryption and other security-related properties of the message.

LDAP (LDAPRESULT). Results of LDAP queries issued by the ACE XML Gateway for the message.

Arguments (ARGSRC). The arguments passed in the request, often as name-value pairs in the URL. Note that different variables need to be used to get the same request arguments depending on where the XSLT is applied in the message processing chain, whether in request processing or response processing.

Variables Summary

The following table lists the XSLT variables.

Table 13-1 XSLT variables

Variable
Description

META-GUID

A sixteen-character (hexadecimal) globally unique identifier for the message. This identifier is mainly for internal use.

However, it may be useful in some troubleshooting scenarios.

META-Receive-Time

The time the message was received, in the form: 2005-12-12T22:54:53Z

TRANSSRC-http-client-ip

The IP address of the client, in dotted-decimal notation (that is, n.n.n.n)

TRANSSRC-http-server-port

The number of the port on which the request was received at the ACE XML Gateway (for example, 80)

MSGSRC-http-method

The HTTP method of the client request, such as GET, POST, or DELETE.

MSGSRC-http-full-path

The full URL path requested by the client, including arguments (for example, /service?a=b)

MSGSRC-http-path

The path of the service requested by the client, without arguments

MSGSRC-http-host

The Host header sent by the client

MSGSRC-SOAPAction

The SOAPAction header sent by the client

MSGSRC-Content-Type

The Content-Type header sent by the client

MSGSRC-<Header_Name>

Any HTTP header sent by the client identified using the form MSGSRC-<Header_Name>, where Header_Name is the actual name of the header as it appears in the message

SECSRC-encrypted

Whether the request from the client was encrypted with SSL, returning:

1 if the request was received by the ACE XML Gateway encrypted

0 if it was not encrypted

SECSRC-cert-digest

The digest of the client's certificate as 20 two-character hexadecimal codes separated by colons

SECSRC-cert-verified

Whether the ACE XML Gateway certified the client certificate:

1 if the client's certificate was verified by the ACE XML Gateway

0 if it was not

SECSRC-cert-dn

The Distinguished Name of the client certificate

SECSRC-cert-issuer-dn

The Issuer Name of the client certificate

SECSRC-cert-revoked

Whether the client certificate has been revoked, returning either:

1 if the client's certificate was revoked

0 if the client's certificate was not revoked

LDAPRESULT-<n>

The results of the LDAP query in LDIF text format, where n indicates the number of the query.

ARGSRC-<Argument_Name>

The value of arguments submitted in the request when accessed in an XSLT applied to request processing. Replace Argument_Name with the actual name of the argument whose value you want to access.

For example, if the request argument is supplied in a GET request argument as prodid, the value would be accessed in request processing using the variable ARGSRC-prodid.

For response processing, access the arguments supplied in the original request using the REQARGSRC prefix.

REQARGSRC-<Argument_ Name>

The value of arguments submitted in the request. Use this variable prefix when accessing the variable from an XSLT applied to response processing.

For example, if the request argument is supplied in a GET request argument as prodid, the value would be accessed in response processing using the variable REQARGSRC-prodid.


Example of Using XSLT Variables

One way to become acquainted with using XSLT variables is by trying them in message log transformations. Message log transformations do not affect the messages as sent to either the requestor or backend service. Instead, they are applied to messages before the messages are logged on the appliance. Therefore, you can add try them out without affecting external test components.

The following sample shows a simple XSLT that simply replaces a message value with the output of several variables.

Example 13-1 XSLT with variables

<xsl:stylesheet  
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
  version="1.0" 
  xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" > 
  <xsl:output method="xml"/> 
  <xsl:template match="/"> 
    <xsl:element name="soap:Envelope"> 
      <xsl:element name="soap:Body"> 
        <xsl:element name="variableTestResults"> 
          <TRANSSRC-http-client-ip> 
            <xsl:copy-of select="$TRANSSRC-http-client-ip" /> 
          </TRANSSRC-http-client-ip> 
          <SECSRC-encrypted> 
            <xsl:copy-of select="$SECSRC-encrypted" /> 
          </SECSRC-encrypted> 
          <MSGSRC-http-path> 
            <xsl:copy-of select="$MSGSRC-http-path" /> 
          </MSGSRC-http-path> 
        </xsl:element>   
      </xsl:element> 
    </xsl:element> 
  </xsl:template> 
</xsl:stylesheet>

This listing includes three variables:

TRANSSRC-http-client-ip, the IP address of the requester

SECSRC-encrypted, the request was encrypted with SSL

MSGSRC-http-path, the resource path in the client request

To apply the XSLT to messages as written to the ACE XML Manager log, first copy the text in Example 13-1 to a text file named with a .xslt extension. Then follow these steps:


Step 1 In the web console, click the Virtual Services link from the navigation menu.

Step 2 Click on the name of the virtual service object to which you want to apply the test transformation.

Step 3 Click the Edit link next to the General settings header on the handler page.

Step 4 Make sure that the Default Message Logging selection is log bodies of inbound and outbound messages.

Step 5 Expand the settings under the heading labeled: Click the configure XSL transformation of message bodies before logging and click the Upload XSLT button.

Step 6 In the Upload XSL Transformation Resource dialog window, provide a descriptive name for the resource.

Step 7 Click the Browse button and navigate to and select the XSLT file you created from the listing.

Step 8 After selecting the file, click Upload. The ACE XML Manager validates the XSLT to be uploaded. If it finds errors, the ACE XML Manager reports them in the Upload window and cancels the operation.

Step 9 In the From the Request XSLT menu, choose the XSLT you just loaded, by resource name, from the menu.

Step 10 Click Save Changes and deploy the policy.


You can now test the transformation by directing traffic to the service you configured with the transformation resource. After sending traffic to the service, in the Message Traffic Log, click the req/resp pair link in the View column for the request.

Finally, click the body encoding link (such as [text/xml; charset=utf-8]) in the Logged Message Content window to see the logged message, which should appear as follows:

Figure 13-2 Message log output rewritten by an XSLT

Notice that the elements added by the transformation are populated with the corresponding runtime values.

LDAP Results Transformation Example

While the example in "Example of Using XSLT Variables" may be a helpful first look at a Gateway transformation, it does not have much real-world applicability. The following example provides a more practical look at how to use XSLTs with variables. Here, results of an LDAP authentication query are added to the outgoing request message. This may be useful in scenarios where the backend service need to know the results of client authorization queries made by the ACE XML Gateway to an LDAP directory.

A client request can result in several requests being issued to the LDAP server by the ACE XML Gateway. Each time an LDAP query is performed, the result is added as a variable of the form: LDAPRESULT-x where x is an integer, starting at 1.

Therefore, if the policy specifies that a user be authenticated with a setup query, the setup query result will be in LDAPRESULT-1, and the authentication query will be stored in LDAPRESULT-2.

Example 13-2 shows a transformation that adds the information in LDAP variables to the outgoing message.

Example 13-2 XSLT Using LDAP Query Results

<?xml version="1.0"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"  
 xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
 xmlns:l="http://www.example.com/LDAPStuff"> 
 
<!-- If the envelope already has a header, copy over and add it --> 
<xsl:template match="soap:Envelope[count(*[local-name()='Header'])=1]"> 
  <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}"> 
     <xsl:for-each select="@*"> 
       <xsl:attribute name="{name(.)}" namespace="{namespace-uri(.)}"> 
         <xsl:value-of select="."/> 
       </xsl:attribute> 
     </xsl:for-each> 
     <soap:Header> 
       <xsl:apply-templates select="soap:Header/*"/> 
       <xsl:call-template name="CreateHeader" /> 
     </soap:Header> 
     <xsl:apply-templates select="soap:Body" /> 
   </xsl:element> 
 </xsl:template> 
 
<!-- If the envelope does not have a header, create one --> 
<xsl:template match="soap:Envelope[count(*[local-name()='Header'])=0]"> 
  <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}"> 
     <xsl:for-each select="@*"> 
       <xsl:attribute name="{name(.)}" namespace="{namespace-uri(.)}"> 
         <xsl:value-of select="."/> 
       </xsl:attribute> 
     </xsl:for-each> 
     <soap:Header> 
        <xsl:call-template name="CreateHeader" /> 
     </soap:Header> 
     <xsl:apply-templates/> 
   </xsl:element> 
 </xsl:template> 
  
<!-- Create our header --> 
<xsl:template name="CreateHeader"> 
  <l:UserLDAP> 
      <Result1><xsl:copy-of select="$LDAPRESULT-1" /></Result1> 
      <Result2><xsl:copy-of select="$LDAPRESULT-2" /></Result2> 
  </l:UserLDAP> 
</xsl:template> 
  
<!-- identity transform --> 
<xsl:template match="*"> 
   <xsl:element name="{name(.)}" namespace="{namespace-uri(.)}"> 
     <xsl:for-each select="@*"> 
       <xsl:attribute name="{name(.)}" 
             namespace="{namespace-uri(.)}"> 
         <xsl:value-of select="."/> 
       </xsl:attribute> 
     </xsl:for-each> 
     <xsl:apply-templates/> 
   </xsl:element> 
 </xsl:template>
  
</xsl:stylesheet> 

The transformation in Example 13-2 creates a header in SOAP messages with the LDAP query results. If the message already has a header, the results are added to the existing header. Otherwise, the header is created.

This transformation is designed to capture two LDAP query results. Notice that a particular type of LDAP requirement you can configure in the ACE XML Gateway results in two separate queries being issued to an LDAP server, the first is called a set-up query and the second is a query that incorporates information from the set-up query. This transformation shows both results, in the LDAPRESULT-1 and LDAPRESULT-2 variables.

The result of the set-up query is to be contained in an element created with the following statement:

<Result1>  
  <xsl:copy-of select="$LDAPRESULT-1" /> 
</Result1>  

At runtime, the ACE XML Gateway uses the value returned by the LDAP directory to populate the Result1 element. When applied to a outgoing request, the backend service can receive and consume the results as appropriate.

Notice the final template in the XSLT. It illustrates a commonly used pattern in transformation scripts, and one which you may want to use as a basis for your transformation development work. The template simply passes through content from the input string to the output string (often called an identity transformation). This is useful when you want to change only a small part of a message, but leave the rest unmodified.

Processing by Remote XSLT

Like other types of resources, to be used in the ACE XML Gateway policy, an XSL Transformation is usually first uploaded to the Manager, and then applied in a service definition. However, for XSLTs, you have the additional option of having the ACE XML Gateway retrieve the XSLT from a remote resource dynamically at the time of message processing.

Remote XSLT retrieval allows for highly dynamic XSLTs—an XSLT can be added or changed without having to change or deploy the policy. Since the external resource serves the XSLT, it also allows dynamic selection of XSLTs.

With dynamic XSLT selection, the ACE XML Gateway passes a key value to the server that hosts the XSLTs. The remote server uses the key to decide which XSLT to serve to the ACE XML Gateway for use in transforming the message.

Figure 13-3 Remote retrieval of transformation resource

Remote XSLT utilization allows you to give partners and service extenders significant control over how information returned by service requests is rendered. For example, it can be used to enable a partner to develop XSLTs that specialize the presentation of content for individual end users. It enables data to be presented in the form most suited for the recipient, allowing for highly adapted, user-centric response content.

Since connections to remote resources may not always be dependable, you can configure alternative actions in case a remote server is non-responsive. Options include returning an error to the consumer, continue processing the message without transformation, and using a default XSLT.

Keep in mind that XSLTs use in this way are not cached at the ACE XML Gateway. The Gateway gets the XSLT resource from the remote server every time it is needed. Depending on your use case or network characteristics, this can have a significant impact on traffic processing performance.

The following sections describe how to set up XSLT retrieval, and how to set up dynamic XSLT selection from a remote resource.

Using Remote XSLT Retrieval

The following steps describe how to set up the ACE XML Gateway to retrieve XSLT used for message processing at runtime. To use this feature, the server that hosts the XSLT must be accessible by network to the ACE XML Gateway at runtime, and it must present the XSLT at a URL location.

To set up a remote XSLT:


Step 1 From the navigation menu, click XSL Transformations link.

Step 2 In the XSL Transformations page, click the Add a New Remote XSLT Resource.

Step 3 Provide a name for the resource that is unique for XSLT resources.

Step 4 Make sure that Fixed URL is selected in the Remote Source menu.

Step 5 In the URL field, type the complete URL path to the resource. The ACE XML Gateway will address a GET request to this URL. For example:

http://swan.example.com/docs/remoteIdXform.xsl

Step 6 Specify what action the ACE XML Gateway should take if the remote server is non-responsive. Options are:

return an error message. The client gets an error message indicating that a transformation error occurred while processing the message.

continue processing. The message continues processing without the transformation.

apply local XSLT. An XSLT that has been uploaded to the ACE XML Manager is used if the preferred remote one is not available.

Step 7 Click Save Changes.


The resource is now ready to be applied anywhere in the message processing that supports local XSLTs.

Once the remote resource is applied to a service definition and the policy is deployed, send test messages to the service and check the log to ensure that the configuration works as expected. If working, information-level log events indicate when the remote resource is used, with the following event description:

Downloading remote resource from http://swan.example.com:80//docs/remoteIdXform.xsl

Using Dynamically Selected Remote XSLT Retrieval

With dynamically selected XSLTs, instead of specifying a particular XSLT as the transformation resource, you configure a remote XSLT host and the "key" that the host should use to choose an XSLT at request processing time. As indicated, using this feature implies the following conditions external to your policy configuration:

Incoming consumer request must include a value that can be used as a key for selecting an XSLT. This value can be an HTTP header, a request argument, or a value in a location in the message identified by XPath.

A remote server must be available that can return an XSLT in response to the ACE XML Gateway's HTTP GET request. The server should understand the key value passed by the ACE XML Gateway (which appears in a configurable form in the URL of the GET request).

With these resources available, you can configure dynamic XSLT selection as follows:


Step 1 Click the XSL Transformations link in the navigation menu.

Step 2 Click the Add a New Resource Server button.

Step 3 In the Name field, enter a name that is unique for resource servers.

Step 4 In the Host field, type the hostname or IP address of the server on which the XSLT resources reside, such as: host.mycompany.com

Step 5 Type the listening port on which the web application on the host will listen for requests for the XSLT resource.

Step 6 If the connection use secure socket layer, select the SSL check box.

Step 7 In the Path field, enter the path to the web application that serves the XSLT. Specify the key in the URL using the variable REACT_RES_KEY. The braces are required, such as:

/resource/xslt/{REACT_RES_KEY}

The page should appear as follows:

Figure 13-4 Remote transformation resource server configuration

Step 8 Click Save Changes.


Now configure the remote XSLT resource, as follows. This process is similar to the one described in "Using Remote XSLT Retrieval" section, except in this case you specify a resource server instead of a fixed URL as the target resource:


Step 1 From the navigation menu, click XSL Transformations link.

Step 2 In the XSL Transformations page, click the Add a New Remote XSLT Resource.

Step 3 Provide a name for the resource that is unique for both remote and local XSLT files.

Step 4 Choose Resource Server from the Remote Source menu.

Step 5 Select the resource server you defined from the Resource Server list, or click the New Resource Server button to add a new one.

Step 6 Identify the resource key in the message, as an HTTP header, by XPath, or URL argument of either the incoming request or the response from the back-end server.

This value is used as the substitute value for the {REACT_RES_KEY} variable you have configured in the path to the remote resource.

Keep in mind that not all resource key types may be available for all service definitions. For example, a resource key identified by XPath could not be used against an HTTP GET request.

Step 7 Specify what action the ACE XML Gateway should take if the remote server is non-responsive. Options are:

return an error message. The client gets an error message indicating that a transformation error occurred while processing the message.

continue processing. The message continues processing without the transformation.

apply local XSLT. An XSLT that has been uploaded to the ACE XML Manager is used if the preferred remote one is not available.

Figure 13-5 Remote transformation configuration

Step 8 Click Save Changes.


The resource can now be applied in service definitions. It is available wherever the policy allows for XSLTs to be applied to content processing.