Transformation Process Syntax
Let's begin with an announcement: TransformSL wiki pages are available. That link will take you to a table of contents for TransformSL; I suggest, since I'm delving a little deep in this post, at least a passing familiarity with transformation processes and the transformmap.xml configuration file. This won't quite be a tutorial, because tooling should hide much of what I'm going to cover. But the tooling's not done yet, so I'll walk through what was once known as a filterRequestReply scenario. In fact, I just added another wiki page to describe the most common transformation usage scenarios. To save you the trip, this scenario describes a service adapter pattern. That is, the input message you have doesn't match the message you need to invoke a needed service; neither does the reply have the right structure. The solution is to transform the input message into the right structure, invoke the service, and then transform the reply as well.
In the new "process"-oriented terminology, a filterRequestReply is simply a transform-invoke-transform process. You can assume, for the purposes of this example, that a WSDL exists with a PartnerLinkType defined. This PLT's role points to a PortType definition containing the operation this example transformation process is implementing. Keep in mind, there is a 1:1 relationship between a WSDL operation and a transformation process; the latter implements the former. Take a sec to peruse the syntax below and then we'll review each activity one at a time:
01 <transformmap xmlns:ns1="http://enterprise.sun.com"
02 xmlns:ns2="http://sun.partner.org">
03 <service partnerLinkType="ns1:MyPartnerLinkType" roleName="opImpl">
04 <operation opName="MyXsltOperation"
05 inputVariable="inputMsg" outputVariable="outputMsg">
06 <transform file="convertRequest.xsl"
07 source="$inputMsg.part1" result="$invokeRequest.part1"/>
08 <invoke partnerLinkType="ns2:MyPartnerPLT" roleName="provisioner" opName="partnerOp"
09 inputVariable="invokeRequest" outputVariable="invokeReply"/>
10 <transform file="convertReply.xsl"
11 source="$invokeReply.part1" result="$outputMsg.part1"/>
12 </operation>
13 </service>
14 </transformmap>
The <transformmap> element [01] represents the collection of services implemented in a particular Xslt service unit. The <service> element [03] describes the PortType via the PartnerLinkType and Role name values. Within each service, you have a transform process defined for each implemented operation. (There's a bug right now where multiple operations aren't supported, but I'm fixing that in the next week or so. There's also an issue with service implementations split across service units, but how often does that occur? It'll get fixed as well, but it'll take a little longer because it's a CRL fix.) So in this example, we're implementing a single operation, "MyXsltOperation", starting on [04]. The 'inputVariable' and 'outputVariable' attributes declare variable names for the messages involved in an invocation of this service's operation. The first refers to the message that is received by and starts the transformation process, whereas the second refers to the reply message sent when the process completes. The variable declarations are also important because they identify the messages, and more importantly the message's parts, which are transformed by XSL stylesheets.
The implementation of this operation (I hope) is fairly straightforward. The three activities ([06], [08], and [10]) transform the incoming message, invoke a service, and transform the invocation's reply, respectively. This sequence satisfies the service adapter pattern, but let's look at each activity in more detail. The first transform activity [06] applies a stylesheet to the input message's normalized data, referenced by "$inputMsg.part1". This is our first variable reference; that is, we're using the variable declared via the 'inputVariable' attribute on [05]. Variables do NOT need to be declared prior to their initial use, provided (and this is key) that the initial use is an assignment, not an evaluation. Our example demonstrates this on [07] in the 'result' attribute. The result of applying the XSL stylesheet ( to "$inputMsg.part1" ) is assigned to "part1" of "invokeRequest", which isn't defined until [09].
Even more important is properly initializing an outgoing message. An outgoing message is one of two things: 1) the input message of a service invocation, or 2) the output message of the implemented Xslt operation. The first transform [06] assigns the result of the transformation to the invocation's input message, "invokeRequest". If the value of all the "invokeRequest" message parts is not set prior to the invocation at [08], then that service is invoked with a data-less message. Don't expect that service invocation to turn out well. The same applies to the operation's reply; whoever is consuming your service expects some data in the message it receives. If the process hasn't properly initialized (in this case) "outputMsg", that data won't be there. That's the first transform....what about that service invocation.
The process consumes a service via the invoke activity at [08]. Notice the "inputVariable"/"outputVariable" attributes at [09]; they're used in much the same way as in <operation> at [05], except they define variables for the invoked operation's messages, not the operation the process implements. The partnerLinkType/roleName/opName combination uniquely identifies the operation the process is invoking. The invocation's reply returns and is assigned to "invokeReply". In this case, the invoked operation is two-way and has data content in both input and output messages. Were the invoked operation one-way, then the status of the invocation is assigned to the "outputVariable". Admittedly, this is a JBI thing creeping in ( because the status will be a string with a value of "DONE", "ACTIVE", or "ERROR" ), but I'm not anticipating much use of variables with status values. You can't transform it; maybe it could be used as a parameter? So now we've invoked the service we really needed and have a reply we can't use. What to do, what to do?
Our third and final activity, the transform at [10], applies a second stylesheet to the invocation's reply. Take a minute and walk through it yourself; you know for the service adapter pattern that the second transformation has to convert the reply to something useful. Does what you see in the example syntax on [10-11] make sense? The invocation's reply, "$invokeReply.part1", is the data to which the stylesheet ('convertReply.xsl') is applied. The result of that transformation is stored in "$outputMessage.part1". We've now properly initialized our other outgoing message, which is the reply sent back to the consumer of our process' service.
That's it. As always, I've probably inundated you with too much information, but I'm confident that there's enough here to dive in to some of the new features of XsltSE without waiting for the tooling. And again, as always, I appreciate you taking the time to read my blog.
