Thursday Feb 26, 2009

A quick post to let my reader know that XsltSE now offers basic fault handling transformation capabilities. When a transformation process does an Invoke to an operation that defines a wsdl:fault, that invocation can then return with a fault message.  The new feature of which I speak is the ability to apply a Transform activity against the fault message before returning it to the consumer of the transformation process.

There's more details on how to configure your transformmap on the Tranform Fault Handling wiki, but normal fault handling is determined by the operation implemented by the transformation process.  If the implemented operation is one-way or two-way with no wsdl:fault definition, then the fault message is set as the error detail property on the message exchange (MEx), which is sent back on the NMR with a status of ERROR.  However, if a wsdl:fault is defined on the implemented operation, then the fault is propagated back to the consumer (i.e. the invoker of the implemented operation a.k.a. transformation process).  If a Transform activity is configured for the received fault, the fault message will be transformed accordingly regardless of whether it's sent back as an MEx property or Fault.  Try it out and post any questions to the OpenESB Users Forum.  Ciao!

Saturday Dec 13, 2008

A quick (and again, long overdue....apologies) post to let my hypothetical reader know that the Saxon bug has been fixed and Xslt 2.0 support is available in XsltSE and BPELSE.  That's it...nothing earth shattering.  Just choose "XSLT_2_0" for the TransformEngine configuration property in either engine when you install it.  Auf wiedersehen.

Monday Sep 22, 2008

So I'm still alive...  Looking at the date of my last blog, you're likely as surprised as I am some mornings.  I wanted to post a quick entry letting what few readers I have left know that Xslt 2.0 support has been added to XsltSE and BPELSE in the form of new shared library, SaxonSL, which makes version 9.1.0.1 of the Saxon-B library available.  There is, however, a catch...

It doesn't work. [UPDATE: Yes it does.] There's a bug in Saxon that prevents a DOMSource created with an Element (versus Document) to be used as the transformation source; details can be found on this thread.  A workaround can be made available, one that would cause performance issues as the transformation source would have to be copied for each transformation, but only if requests come rushing in.  I did notice this morning that there's a 9.1.0.2 version, which will be tested and checked in if the bug is resolved.

To enable Xslt 2.0 support in XsltSE (once it's working, of course), simply choose the XSLT_2_0 option for the Transform Engine property when installing XsltSE.  Same goes for BPELSE, whose Xslt 2.0 support applies only to the doXslTransform() function defined by the BPEL spec.

Enjoy!  I'll update this post once a fix for the Saxon bug is acquired.

Wednesday May 07, 2008

For some time, I've been wanting to write a blog entry about the use of PartnerLinkTypes in XsltSE's custom configuration file, transformmap.  Enough time has passed, however, that this usage has been completely refactored out of TransformSL (the framework upon which XsltSE is based).  With that said, there's still two very important reasons why the transformmap configuration exists and though tooling will (eventually) make much of this knowledge almost useless, perhaps it will help XsltSE users when they're creating their transformation processes.

The primary reason for the transformmap configuration is the definition of transformation processes (TP).  Each TP is the implementation of a WSDL-defined operation; there's always a 1-to-1 relationship.  Any activities defined within an operation element are executed sequentially when the TP instance is created at runtime.  Fairly straightforward conceptually; if only we had tooling like BPEL's editor to start building these things...  In time, I hope.

The secondary reason is the definition of XsltSE endpoints.  Each transformmap configuration gets converted to a JBI service unit descriptor when the Xslt Project gets built.  This gets into the JBI side of things which, again, should be totally transparent with the right tooling.  But understanding how the transformmap is used to configure XsltSE endpoints will help you design your transformation processes (TPs) more easily.  Just as there's a 1-to-1 relationship between TPs and "operation" elements, there's also a 1-to-1 relationship between the "service" element(s) and provisioning endpoints.  There's similarly a 1-to-1 relationship between Invoke activities and consuming endpoints.  Let's look at a simple example to illustrate these relationships.

Here's a sample transformmap configuration for us to review:

1.     <transformmap xmlns="http://www.sun.com/jbi/xsltse/transformmap"
2. xmlns:ns0="http://j2ee.netbeans.org/wsdl/tp-example"
3. targetNamespace="http://sun.com/processDescriptor/tmap-example">
4. <import namespace="http://www.sun.com/tp-example" location="tp-example.wsdl"/>
5. <service name="ExampleService" portType="ns0:XsltsePort">
6. <operation opName="operation1">
7. <transform name="Transform1" ..../>
8. </operation>
9. <operation opName="operation2">
10. <transform name="Transform2" ..../>
11. <invoke name="Invoke2" opName="invokedOperation" ..../>
12. </operation>
13. </service>
14. </transformmap>
First, note the newly added 'targetNamespace' attribute; this qualifies the service definitions for this XsltSE project/service unit within the JBI runtime environment.  Note also that all wsdls are imported explicitly because 1) increases similarity to bpel, reducing the learning curve; and 2) it's easier for the tooling (which we don't have... I'm unhappy with this; can you tell?).

The <service> element on line 5 defines a provisioning endpoint, meaning it will handle incoming messages for the defined operations (on lines 6 and 9).  The <invoke> activity on line 11 defines a consuming endpoint.  In case the whole provisioning/consuming terminology is a little confusing, remember that a provisioning endpoint accepts messages (and sends a response when the wsdl operation has output) whereas a consuming endpoint sends out messages as requests (thereby consuming the provisioning endpoint).  Now that that's all clear...

The two transformation processes are defined inside the <operation> elements.  Only one activity is defined on line 7 for "operation1", which implies this process is request-reply as the transformation result should go somewhere.  There are two activities in "operation2" on lines 10 and 11, which implies a filter one-way scenario.  That covers the transformation processes, but what about...

The endpoint configurations (2nd tab)...  There are two endpoints defined in this example transformmap.  The first is a provisioning endpoint, implementing operations "operation1" and "operation2", and will be represented as a <provides> element in the service unit descriptor.  The second endpoint is consuming: the Invoke activity on line 11 will be uniquely identifiable as a consumer, enabling support for systemic qualities (e.g. redelivery, throttling, et al.).  This endpoint will be represented as a <consumes> element in the service unit descriptor.

What does this all mean for you?  Edification about what's going on with XsltSE, hopefully.  And for me, hopefully a return to more regular blogging...

Friday Nov 16, 2007

Just a quick announcement for the XsltSE users out there.  A new element will be added to the transformmap descriptor: "import".  The purpose of this new construct is to simplify and standardize the use of WSDLs in a transformation process.  Here's the syntax:

<import namespace="anyURI" location="anyURI"/>*

Note that both attributes are required.  Also, the target namespace of the WSDL document specified in 'location' MUST match the namespace specified in 'namespace'.  Some may note the similarity to BPEL's "import" construct; they're almost identical except that only WSDL imports are supported, so no 'importType' attribute.  These changes will likely be in by Thanksgiving, so be sure to update your transformmap descriptors after the break.  Ciao!

Thursday Aug 16, 2007

Four posts in barely over a week!  Uh....lucky you?  Actually, the catalyst for this post is you, my readers; specifically, the commenters.  There are two requests that have popped up: a video demonstrating how to use the runtime and whether/when we'll have XQuery support.  Unfortunately, I have neither to offer you.  Fortunately, the reasons why are simple.  There's no video because there's no tooling for the runtime worth recording.  There's a tree view of the transformmap.xml, but you can't edit it without going to Source view.  So a video just wouldn't provide value right now.  That said, my post about the transformation process syntax describes a filter scenario in detail; a real world example would only change the WSDL information (partnerLinkTypes, operation names, etc.)  As for an XQuerySE, it's under discussion but there's nothing definite as of now.  That said, if/once I get a green light, all I need is an open source XQuery engine to plug in to the TransformSL framework and an XQuerySE we will have.  To reiterate so there's no confusion: it's under discussion, nothing definite.  I'm just saying I'm ready...

I can't provide a video and I can't provide an XQuerySE (at least not yet).  Instead, I'm asking you for your help.  One of the biggest obstacles I'm facing as I work on the XsltSE is trying to ascertain whether a feature will be useful.  Trying to come up with enhancement ideas is especially tough because I have no real world use cases available to me.  I'm in the process of trying to track down a customer project or three, but I'm not having a lot of luck so far.  This is where you come in.  Here's my email:  kevan.simpson@sun.com.  I'm asking those of you even considering using XsltSE to send me an email describing how you would want use it.  Send me your stylesheets, WSDLs, and schemas.  I will use what you send to derive examples, quality standards, you name it.  But more importantly, the information you provide me will help me drive innovation in this service engine.  In a nutshell, I'm offering a figurative golden ticket; since you read my blog, YOU will help determine the course of XsltSE.  Help me out!  Thanks!

Monday Aug 13, 2007

I have spent a considerable amount of time over the last year trying to educate people about the wonders of XsltSE.  I do this because A) I enjoy my work; B) I'm actually paid to transfer knowledge; C) once I get going, it's difficult to shut me up; D) it allows me the chance to abuse the word "wonders" above; and E) because who else would talk about XsltSE?  I've specifically spent a great deal of time providing backwards compatibility with older versions of transformmap.xml (and xsltmap.xml), even going so far as to provide a utility which converted one format to another.  Suffice to say, an investiture was made.

So it is with a heavy heart I announce that backwards compatibility will no longer be supported from this point forward.  This manifests in two distinct ways: 1) older versions of transformmap.xml (i.e. "file" attribute in operation and invoke elements) will not work in runtime any longer; and 2) older versions of Xslt Project will not build because a necessary Ant task was retired.  So even though the runtime supported the older version of transformmap.xml, there's no Xslt service unit available to deploy.  Discussions were had about the work effort, which eventually led to one of those "well, who's using it?" conversations.  That's the point where I sheepishly admit that XsltSE usage is not voluminous and the impact of not supporting backwards compatibility is consequently not high.  This "usage" conversation occurred earlier today; the decision to move forward and focus on more important aspects of Xslt Designer and tooling for transformmap.xml was not far behind.

My apologies to the few of you who've become early adopters of XsltSE and I regret any inconvenience you encounter as you transition any existing Xslt projects.  On the plus side, it means that tooling for some of the recent enhancements should be coming faster and more furious.  In the meantime, how can you upgrade your transformmap.xml files?  Read on...

There are only a few things you need to do with an older version of transformmap.xml.  Some of these steps aren't strictly necessary; I'm focusing on simpler to get you back up and running more quickly.  Here's a checklist of the changes to make:

  • Add two attributes to the <operation> element: "inputVariable" and "outputVariable"
    • The values are arbitrary names for the incoming and outgoing messages, respectively.  I usually choose 'input' and 'output' as values, and will again for the purposes of this checklist.
  • The "file" attribute in <operation> must be converted to a <transform> activity:
    • Start with a <transform> element as the first child of <operation>, like this: <transform file="stylesheet.xsl"/>
    • Add two attributes to the new <transform>: "source" and "result".  These are variable references to the input and output of the transformation.  Remember, variable references are prefixed with a $.
    • "source" should specify the message and part to be transformed.  The message value will be the same as the "inputVariable", in this case 'input'.  The part value MUST match the name specified in the WSDL message definition.
    • "result" specifies where the output of the transformation is assigned.  The value is dependent on whether or not your process has an Invoke.
      • NO Invoke: the transformation output should be assigned to the outgoing message.  The <transform> will look something like: <transform file="stylesheet.xsl" source="$input.part1" result="$output.part1"/>
      • WITH Invoke: the transformation output MUST be assigned to the invocation's incoming message, specified by the "inputVariable" attribute you'll be adding to the <invoke>.  The new <transform>: <transform file="stylesheet.xsl" source="$input.part1" result="$invokeInput.part1"/>
  • Modify <invokes> to <invoke> without the 's'.  The <invoke> will only be present for filterOneWay and filterRequestReply scenarios.
  • Add two attributes to the <invoke> element: "inputVariable" and "outputVariable" with values 'invokeInput' and 'invokeOutput', respectively.
  • The "file" attribute in <invoke> must be converted to a <transform> activity.  If your process is a filterOneWay, the "file" attribute may not be specified, as there's no reply to transform (only a status is returned)
    • Add a new <transform> element as a sibling and immediately following the <invoke>, such as: <transform file="reply.xsl" source="" result="" />
    • The values for "source" and "result" are a little different.  You're transforming the <invoke>'s reply and assigning the output to the outgoing message of your process.
    • Your second <transform> should look like this: <transform file="reply.xsl" source="$invokeOutput.part1" result="$output.part1" />
  • The "transformJBI" attribute is obsolete.  If it's missing or 'false', you're done.  If the value was 'true', the only change it causes is to remove the part qualifier on your variable references because the whole message (not just one part) is transformed by your stylesheet.  Your <transform> activities will look like below instead:
    • No Invoke Transform: <transform file="stylesheet.xsl" source="$input" result="$output" />
    • Pre-Invoke Transform: <transform file="stylesheet.xsl" source="$input" result="$invokeInput" />
    • Post-Invoke Transform: <transform file="reply.xsl" source="$invokeOutput" result="$output" />
That's it!  I say that tongue in cheek, as it's clearly not trivial.  As always, email me with questions/comments/etc.  Thanks for reading...

Thursday Aug 09, 2007

I've been meaning to blog about this for weeks, but BPELSE now has support for the function "doXslTransform".  Why am I, Mr. XsltSE, blogging about BPEL?  I've alluded to in previous blog entries, and will now confirm, I was part of the BPELSE team for a while last year and one of my many (fascinating and absolutely critical) contributions was implementing this particular function.  So this blog is not only to announce (again, to a stunningly large audience) the inclusion of this feature but also walk through what it does and how to use it.

First, for those of you who've not spent countless hours reading the BPEL spec (which is hopefully most of you), the purpose of the doXslTransform() function is to account for BPEL's inability to perform complex XML transformation via its <copy> construct.  By providing the means for a user to embed an externally defined XSL stylesheet inside the process, these complex transformations can be specified in a portable fashion.  But so far, I'm just paraphrasing the spec, specifically the latter part of section 8.4; let's look at the function signature in detail.

        object bpel:doXslTransform(file-name, node-set, (param-name, param-value)*) 

The first parameter specifies the URI of the XSL stylesheet to apply and MUST be a string literal.  The second parameter is the data to be transformed and is expected to be a single element ( "an XPath node set... [containing] a single EII" ).  The additional parameters represent xsl:param values passed to the XSL stylesheet and are a little trickier: they MUST be specified in name-value pairs.  To put it another way, if your stylesheet has a global xsl:param declaration, the only way to specify a value is to pass in two additional parameters to doXslTransform().  The first is the name of the param, which MUST match the name attribute in the xsl:param, and the second is the value, which can be an XPath expression.  For a little more information about xsl parameters, please take a gander at this reference.

There is tooling for this feature, but there are currently some minor issues (which bug 112503 is tracking).  The functoid is there and can be dragged onto the mapper canvas, which will get the function declared in your BPEL.  But there are no fields for the additional parameters yet, so you'll have to specify them manually.  Also, the mapper allows you to drag non-string-literals into the stylesheet field, which won't work at all.  As always, I urge you to go give it a test spin and see how much more robust your business process can be.  In the interest of full disclosure, this particular BPEL feature makes XsltSE technically unnecessary (i.e. each Transform activity in a transformation process is functionally equivalent to an Assign activity using doXslTransform() in a business process).  That said, transformation processes are still a simpler alternative to BPEL and will (hopefully) provide functionality and an ease of use that will encourage their use.  Otherwise I'm back on BPELSE this time next year (likely wearing a dunce cap)...  Thanks for reading!

Wednesday Aug 08, 2007

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.

Thursday Jul 12, 2007

I mentioned in a recent post about the transformsl shared library that I rewrote XsltSE... again.  I'm going to run through the new enhancements that are available, of which there are three:

  1. Transformation processes - no longer tied to the filterRequestReply/etc predefined use cases, a sequential list of activities can be executed as a transformation process, akin to (but much simpler than) a BPEL process.
  2. Transformation by part - XSL stylesheets can now be applied to individual message parts, referenced by name, and explicitly assigned to other messages.
  3. Runtime parameter support - values for parameters defined in XSL stylesheets can be provided during application of the transformation.

Everyone's clear now, right?  No?  Ok, I suppose I can go into a little more detail.  We'll start with the transformation processes (TPs).  If you're familiar with BPEL, the idea of a process won't be too foreign.  A "process" is a list of activities executed in order.  As of now, there are only two activities supported: transform and invoke.  The former activity, transform, is how XSL stylesheets are applied.  The latter activity, invoke, allows the process to consume other service endpoints during execution.  Neither of these activities are new to XsltSE in terms of functionality, but they are defined in a very different manner.  To keep this blog from being too lengthy, I promise to do a follow-up blog post about the syntax of both activities, including how to define a transformation process.  I'll also be updating the wiki pages on the OpenESB site in the next week or two.

So you can execute a sequence of transformations.  Big deal, right?  Well, sort of...multiple transformations per Xslt operation means that the entire message exchange doesn't need to be transformed all at once.  This was not a big deal for single-part messages, but multi-part messages required an entire blog entry to explain how to create a JBI-specific XSL stylesheet.  Wasn't THAT portable?  Ooof.  (Mind you, it's still supported but hardly ideal.)  Anyhoo, now you can deploy XSL stylesheets capable of transforming one message part to another, ignoring the rest of the message.  Let's walk through a simple example, a request-reply with the incoming message containing three parts and the outgoing only containing two parts.  In the past, you'd have an awkward XSL stylesheet that created a jbi:message element and two jbi:part elements as children.  Now, you'll need at least two stylesheets, one for each message part coming back in the reply.  For this example, let's refer to the incoming message as "input" and the outgoing message as "output".  Stylesheet #1 will transform "input.part1" and store the result in "output.part2", while Stylesheet #2 will transform "input.part2" and store the result in "output.part1".  Notice two things: 1) there's no limitation on which message part gets transformed, nor to which message part the transformation result is stored; and 2) we're purposely ignoring (for now) the third part in the incoming message ( "input.part3" ).  Ok, three things: you could apply a different stylesheet to the same message part multiple times.  Don't have a use case for the last thing, but you can do it.  So what happened to the unused message part?  (I swear, if I knew how to transition from one paragraph to another more gracefully, I would...)

Did I hear somebody say parameters?  For anyone who isn't aware that XSL stylesheets can take parameters, check out this reference to get up to speed.  The last enhancement to XsltSE is to provide a mechanism to declare the values for global parameters (i.e. defined at the top level of the stylesheet), which are passed to the stylesheet when the transformation is applied.  There are three sources from which a parameter value can be drawn: 1) literal element; 2) loaded from a file; or 3) another message part.  Let's focus on that last one first.  Remember "input.part3" we didn't use?  You can specify that message part as the value of the parameter passed to a stylesheet.  Any message part can be specified as a parameter, even parts not explicitly involved in the transformation.  As for the other two parameter sources, they're much more straightforward.  A literal parameter is specified in the transformation process itself and is parsed into a DOM element at runtime.  Same thing with loading a parameter from a file: deploy a file containing XML content and it'll be parsed and passed to the stylesheet.  I'll go into much more detail when I blog about the syntax of the transformation process.

So that's the summary of the new XsltSE enhancements.  I know I've glossed over a lot, but I'll get more low-level in the follow-up post I promised about the transformation process syntax.  And, though this may be burying the lead, here's one more tidbit: the transformation process is defined in the transformmap.xml configuration file, of which we're on the second revision.  Older versions of transformmap.xml will be supported, but with one primary constraint: you can't use these new enhancements with the older versions.  Without changes, older versions will still execute in the same way (because "filterRequestReply" is just a "transform-invoke-transform" process), but as soon as you want the new stuff, you're going to have to convert.  Hopefully we'll have a migration strategy, but it's still a bit ripe today.  Mind you, all this backwards compatibility is only an issue if you have existing Xslt projects and you want the new stuff.  Otherwise, create a new Xslt project and dig in!  Thanks for reading!

UPDATE:  For those who've asked for videos demonstrating XsltSE usage, the absence of tooling around the transformmap.xml configuration file makes a video premature at this time.  I have to watch me type; it's not that interesting so a video of me typing IMO would not be helpful.  Most of the tooling efforts have been focused on the Xslt Editor, which is a separate component and not related to the XsltSE directly.  The transformmap.xml file is how the user interacts with the runtime and, as it's a relatively new enhancement, the tooling is in progress.

Monday Jun 18, 2007

So that was me breaking the build last week...hehe.  Haven't quite wrapped my head around the obtuse labyrinth that is Maven, so I missed checking in a change to one of the higher-level pom files.  I'm starting to suspect that pom actually stands for something....piece of man you are easily fooled if you think I'm finishing that sentence...lol.  But Kevan, you ask, what is this wondrous module that you inexpertly checked in?  Well...

The Transform Shared Library (TSL or transformsl) is a JBI shared library that contains the framework for a simple runtime engine easily plugged in to a JBI component.  The catalyst for creating this library was the idea that there will be other transformation-based service engines, for which I'm likely to be responsible, and I dig reuse.  If you've read my CRL blog posts, you know I loathe copy-paste coding and certainly wasn't going to do it with my own work.  So I rewrote Xslt SE again.  Consequently, it's no longer an example of the CRL processors (previously described in this post).  On the plus side, it's simpler and provides a great deal more functionality. 

The basic premise of transformsl is the idea of a "transformation process".  A transformation process, or TP, is simply a list of activities to be executed sequentially, just like BPEL.  The difference is in the utter lack of complexity.  Only two activities are supported: transform and invoke.  No partnerlinks, correlations, scope...none of it.  There are variables, following the same naming convention as BPEL (i.e. "$var.part" ), but their scope is limited and easy to use.  Other activities may be supported in the future, but the more functionality that gets added, the more it resembles BPEL and I'm not going too far down that path.

The primary benefit of having a transformation process is the flexibility it gives the user.  Initially, Xslt SE only supported three usage scenarios, of which two supported only one invocation to another service endpoint.  Now, you can apply a stylesheet or three to some data, invoke a service, apply another stylesheet, invoke another service, ad nauseum.  You're also not limited in which services are invoked.  One of the limitations previously was that a two-way Xslt operation could only invoke other two-way operations; likewise with one-way Xslt operations.  Any Xslt operation can now invoke any other operation in any order.

I'll go into more detail in future posts, focusing more on specific features now available to Xslt SE.  But this post will serve as a high-level intro to this new shared library.  I'll update when there are wiki pages with technical details on using transformsl.  Until then...

Monday Mar 26, 2007

For anyone using XSLT SE: The configuration file for XSLT projects, xsltmap.xml, has changed.  Not only does it have a different name, transformmap.xml, but also an entirely new structure, detailed here: http://www.glassfishwiki.org/jbiwiki/Wiki.jsp?page=XsltProject
The design-time changes are not quite there yet (as it's much more complex a change), but I created an upgrade tool to migrate existing projects to the new configuration. To use it, you'll need to grab the latest XSLT SE code and build it from source.  Once you have the "xsltse-jbiadapter.jar" (located in the project's dist folder) type the following at the command-line :

java -jar xsltse-jbiadapter.jar <project-path>

where <project-path> is the directory of your XSLT project.  The upgrade tool will recursively search for any file named xsltmap.xml and rewrite it as transformmap.xml, so if you have multiple XSLT projects, simply change <project-path> to a directory containing your XSLT projects.
The XSLT SE is also backwards-compatible in regards to this change.  So if you don't upgrade your projects, they'll be upgraded for you at runtime.  If anyone has any questions or encounters any issues, please do not hesitate to contact me.

Friday Mar 02, 2007

Having only devoted a single paragraph to multi-part messages in the previous "how to" post, as well as promising the XSLT design-time team a synopsis of how it works, a follow-up blog entry to which I can refer people seemed appropriate.  I'll start with the message wrapper element schema copied directly from section 5.5.1.1.4 of the JBI spec:

default namespace jbi = "http://java.sun.com/xml/ns/jbi/wsdl-11-wrapper"
start =
element message {
attribute version { xsd:decimal },
attribute type { xsd:QName },
attribute name { xsd:nmtoken }?,
part*
}
part =
element part {
# part value
( (element* { text }) | text)
}

Each jbi:part element corresponds to a message part as defined in the WSDL, just as the content of each jbi:part element corresponds to the type/element of a message part.  The output of your stylesheet's transformation must create a document matching this schema, as it is the normalized message structure with which message exchanges are routed in JBI.  This does not affect how the parts' content is transformed, but it does require the stylesheet to account for a few things related to JBI.  First off, make sure the jbi namespace is declared in your stylesheet. Next, define a root template ( i.e. match="/" ) to create the wrapper element, something like the following which assumes two message parts:

<xsl:template match="/">
<jbi:message xmlns:ns2="http://sun.com/EmplOutput" type="ns2:output-msg" version="1.0"
xmlns:jbi="http://java.sun.com/xml/ns/jbi/wsdl-11-wrapper">
<jbi:part>
<xsl:apply-templates />
</jbi:part>
<jbi:part>
<xsl:apply-templates />
</jbi:part>
</jbi:message>
</xsl:template> 

The rest of your stylesheet should include templates for each of the types used to define message parts.  The results of applying each of these templates will be inserted into the jbi:part elements and you'll have yourself a properly defined JBI message wrapper element capable of being routed to the appropriate service endpoint.  This root template is relatively straightforward, but pay special attention to the "type" attribute in the jbi:message element.  The value of this attribute MUST match the qualified name of the output message definition; that is, it corresponds to the wsdl:output message attribute value.

One last suggestion: I found it easier in the case of a different number of parts between the input and output messages to use xsl:call-template rather than xsl:apply-templates to transform each jbi:part content.  And don't forget to set the 'transformJBI' attribute to "true" in the xsltmap.xml configuration file!

This blog copyright 2009 by kevansplace