Adding association in SOAP driver


Hello,

I am creating objects with a SOAP driver on a remote system with a
webservice. When the create is done and i get a message back from the
server, indicating the create was successful, I want to add an
association in the driver.

I do it like so:


Code:
--------------------

<xsl:if test="$result//*[local-name()='AddDepartmentResult'] = 'true'">
<xsl:message>AddAssociation DeptID: <xsl:value-of select="$lDeptID"/>
<xsl:message>AddAssociation DN: <xsl:value-of select="$lDN"/></xsl:message>
<xsl:message>AddAssociation src-entry-id: <xsl:value-of select="$lSrcEntryID"/></xsl:message>
</xsl:message>
<xsl:variable name="add-association">
<add-association>
<xsl:attribute name="dest-dn">
<xsl:value-of select="$lDN"/>
</xsl:attribute>
<xsl:attribute name="event-id">0</xsl:attribute>
<xsl:attribute name="src-entry-id">
<xsl:value-of select="$lSrcEntryID"/>
</xsl:attribute>
<xsl:value-of select="$result//*[local-name()='AddDepartmentResult']"/>
</add-association>
</xsl:variable>
<xsl:variable name="results" select="cmd:execute($srcCommandProcessor, $add-association)"/>
</xsl:if>

--------------------


I have the following namespaces and parameters in my document at the
top:


Code:
--------------------

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
exclude-result-prefixes="query cmd dncv"
version="1.0"
xmlns:cmd="">www.novell.com/.../com.novell.nds.dirxml.driver.XdsCommandProcessor"
xmlns:dncv="">www.novell.com/.../com.novell.nds.dirxml.driver.DNConverter"
xmlns:query="">www.novell.com/.../com.novell.nds.dirxml.driver.XdsQueryProcessor"
xmlns:xsl="">www.w3.org/.../Transform">
<!-- parameters passed in from the DirXML engine -->
<xsl:param name="srcQueryProcessor"/>
<xsl:param name="destQueryProcessor"/>
<xsl:param name="srcCommandProcessor"/>
<xsl:param name="destCommandProcessor"/>
<xsl:param name="dnConverter"/>
<xsl:param name="fromNds"/>

--------------------


The trace:


Code:
--------------------

<nds dtdversion="2.0">
<source>
<product build="20141121_0927" instance="soapIntra01" version="4.0.0.3">Identity Manager Driver for SOAP
</product>
<contact>NetIQ Corporation</contact>
</source>
<output>
<s:Envelope xmlns:s="">schemas.xmlsoap.org/.../">
<s:Body>
<AddDepartmentResponse xmlns="">http://tempuri.org/">
<AddDepartmentResult>true</AddDepartmentResult>
</AddDepartmentResponse>
</s:Body>
</s:Envelope>
</output>
<operation-data event-id="1" url="">test.customer.dk/.../DepartmentService.svc" xm
lns:soap="">www.w3.org/.../>
<operation-data event-id="2" soap-action="">tempuri.org/.../AddDepartment" xmlns:soap=
"">www.w3.org/.../>
</nds>
[08/27/15 18:06:22.540]:soapIntra01 ST: Cxsl:message -> Add Department - true
[08/27/15 18:06:22.540]:soapIntra01 ST: Cxsl:message -> AddAssociation DN: \IDVTREE\top\idv\structures\d
epartments\23395C1857F14792B6501F0BAF6FFFD2
[08/27/15 18:06:22.541]:soapIntra01 ST: Cxsl:message -> AddAssociation src-entry-id: 48679
[08/27/15 18:06:22.541]:soapIntra01 ST: Cxsl:message -> AddAssociation DeptID: 23395C1857F14792B6501F0BA
F6FFFD2
[08/27/15 18:06:22.542]:soapIntra01 ST: Direct command from policy
[08/27/15 18:06:22.543]:soapIntra01 ST:
<nds dtdversion="4.0" ndsversion="8.x">
<input>
<add-association dest-dn="\IDVTREE\top\idv\structures\departments\23395C1857F14792B6501F0BAF6FFFD2" even
t-id="0" src-entry-id="48679" xmlns:soap="">www.w3.org/.../add-association>
</input>
</nds>
[08/27/15 18:06:22.545]:soapIntra01 ST: Pumping XDS to eDirectory.
[08/27/15 18:06:22.545]:soapIntra01 ST:
DirXML Log Event -------------------
Driver: \IDVTREE\top\system\IDMDriverSet01\soapIntra01
Channel: Subscriber
Object: \IDVTREE\top\idv\structures\departments\23395C1857F14792B6501F0BAF6FFFD2
Status: Error
Message: Code(-9061) Error processing XSLT policy: vnd.nds.stream://IDVTREE/top/system/IDMDriverSet01/
soapIntra01/Subscriber/itq-sub-output#XmlData (117): <xsl:variable>: expression evaluation error: function c
all to 'cmd:execute' resulted in an error: 'java.lang.NullPointerException'
[08/27/15 18:06:22.557]:soapIntra01 ST:Processing returned document.
[08/27/15 18:06:22.558]:soapIntra01 ST:Processing operation <status> for .
[08/27/15 18:06:22.558]:soapIntra01 ST:
DirXML Log Event -------------------
Driver: \IDVTREE\top\system\IDMDriverSet01\soapIntra01
Channel: Subscriber
Object: \IDVTREE\top\idv\structures\departments\23395C1857F14792B6501F0BAF6FFFD2
Status: Error
Message: Code(-9037) One or more errors occurred while processing an XSLT policy.
[08/27/15 18:06:22.568]:soapIntra01 ST:End transaction.

--------------------


So it looks like the data for the assicoation attribute is okay, but for
some reason I get a "java.lang.NullPointerException".

This is an IDM 4.5.1 system. In production this driver works, and the
association add works aswell. So, I might think that the upgrade has
broken this functionality. I don't know how though.

Driver is version 4.0.0.3.

Any ideas?

thanks in advance,

Jacob.


--
jacmarpet
------------------------------------------------------------------------
jacmarpet's Profile: https://forums.netiq.com/member.php?userid=415
View this thread: https://forums.netiq.com/showthread.php?t=54150


  • I suspect the xmlns:soap="www.w3.org/.../soap-envelope in the
    association event for being the problem. I wonder why that is added.


    --
    jacmarpet
    ------------------------------------------------------------------------
    jacmarpet's Profile: https://forums.netiq.com/member.php?userid=415
    View this thread: https://forums.netiq.com/showthread.php?t=54150


  • A note to add:

    This code works in production but not in test. The environment has been
    upgraded in test and now this does not work. Here is a trace from
    production where it works:


    Code:
    --------------------

    <nds dtdversion="4.0" ndsversion="8.x">
    <input>
    <add-association dest-dn="\IDVTREE\top\idv\entities\users\dg4841" event-id="0" src-entry-id="46941" xmlns:soap="">www.w3.org/.../add-association>
    </input>
    </nds>

    --------------------


    and in test where it doesn't and I get the null pointer:


    Code:
    --------------------

    <nds dtdversion="4.0" ndsversion="8.x">
    <input>
    <add-association dest-dn="\IDVTREE\top\idv\structures\departments\006F67370CD44C968555C8D985802FE7" event-id="0" src-entry-id="48681" xmlns:soap="">www.w3.org/.../add-association>
    </input>
    </nds>

    --------------------


    Did something change in IDM 4.5 maybe?


    --
    jacmarpet
    ------------------------------------------------------------------------
    jacmarpet's Profile: https://forums.netiq.com/member.php?userid=415
    View this thread: https://forums.netiq.com/showthread.php?t=54150

  • jacmarpet wrote:

    >
    > I suspect the xmlns:soap="www.w3.org/.../soap-envelope in the
    > association event for being the problem. I wonder why that is added.


    Hard to answer without seeing the entire stylesheet.

    Definitely the soap-envelope part is problematic. you need to change

    exclude-result-prefixes="query cmd dncv"

    to
    exclude-result-prefixes="query cmd dncv soap"

    Also, note your add-association does not have a corresponding status event (with same event id). It really should.



    As a general comment, I usually approach this by using two stylesheets in the input transform.

    First a generic stylesheet that just strips the soap envelope wrapper. (this is identical to the one distributed with the NetIQ SPML 2.0 package)

    <?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet exclude-result-prefixes="query cmd dncv soap-env" version="1.0" xmlns:cmd="">www.novell.com/.../com.novell.nds.dirxml.driver.XdsCommandProcessor" xmlns:dncv="">www.novell.com/.../com.novell.nds.dirxml.driver.DNConverter" xmlns:query="">www.novell.com/.../com.novell.nds.dirxml.driver.XdsQueryProcessor" xmlns:soap-env="">schemas.xmlsoap.org/.../" xmlns:xsl="">www.w3.org/.../Transform">
    <!-- parameters passed in from the Identity Manager engine -->
    <xsl:param name="srcQueryProcessor"/>
    <xsl:param name="destQueryProcessor"/>
    <xsl:param name="srcCommandProcessor"/>
    <xsl:param name="destCommandProcessor"/>
    <xsl:param name="dnConverter"/>
    <xsl:param name="fromNds"/>
    <!-- This is for testing the stylesheet outside of Identity Manager so things are pretty to look at -->
    <xsl:strip-space elements="*"/>
    <xsl:preserve-space elements="value,component"/>
    <xsl:output indent="yes" method="xml"/>
    <!-- *********************** -->
    <!-- Strip off SOAP header -->
    <!-- *********************** -->
    <xsl:template match="soap-env:Envelope">
    <!-- ignore this element but process all children -->
    <xsl:apply-templates select="soap-env:Body/*"/>
    <xsl:apply-templates select="operation-data"/>
    </xsl:template>
    <xsl:template match="soap-env:Fault">
    <status level="error">
    <xsl:if test="../operation-data/@event-id">
    <xsl:attribute name="event-id">
    <xsl:value-of select="../operation-data/@event-id"/>
    </xsl:attribute>
    </xsl:if>
    <xsl:apply-templates select="node()"/>
    </status>
    </xsl:template>
    <!-- identity transformation template -->
    <!-- in the absence of any other templates this will cause -->
    <!-- the stylesheet to copy the input through unchanged to the output -->
    <xsl:template match="node()|@*">
    <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
    </xsl:template>
    </xsl:stylesheet>


    Then a second stylesheet that transforms the response and generates a status either instance or add association depending on the request.

    I find that approach cleaner.
  • jacmarpet <jacmarpet@no-mx.forums.microfocus.com> wrote:


    > Did something change in IDM 4.5 maybe?
    >


    Lots of association code got touched in 4.5 because they added a new
    (optional) way to handle associations.

    It is definitely possible.

    Also, why is your association value set to 'true'? That seems problematic
    and likely non-unique

    --
    If you find this post helpful and are logged into the web interface, show
    your appreciation and click on the star below...
  • jacmarpet <jacmarpet@no-mx.forums.microfocus.com> wrote:


    > Did something change in IDM 4.5 maybe?
    >


    Lots of association code got touched in 4.5 because they added a new
    (optional) way to handle associations.

    It is definitely possible.

    Also, why is your association value set to 'true'? That seems problematic
    and likely non-unique

    --
    If you find this post helpful and are logged into the web interface, show
    your appreciation and click on the star below...
  • On Thu, 27 Aug 2015 16:44:01 0000, jacmarpet wrote:

    > <xsl:variable name="add-association">
    > <add-association>
    > <xsl:attribute name="dest-

    dn">
    > <xsl:value-of

    select="$lDN"/>
    > </xsl:attribute>
    > <xsl:attribute

    name="event-id">0</xsl:attribute> <xsl:attribute
    > name="src-entry-id">
    > <xsl:value-of

    select="$lSrcEntryID"/>
    > </xsl:attribute>
    > <xsl:value-of
    > select="$result//*[local-

    name()='AddDepartmentResult']"/>
    > </add-association>
    > </xsl:variable>


    I think this is your problem. Take out the <xsl:variable> here. You just
    want the XSLT to output the <add-association> in the XDS. I have
    something similar here, like:


    <xsl:if test="$association and $dn and $code = 'SUCCESS'">
    <add-association>
    <xsl:attribute name="dest-dn">
    <xsl:value-of select="$dn"/>
    </xsl:attribute>
    <xsl:attribute name="event-id">
    <xsl:value-of select="$eventID"/>
    </xsl:attribute>
    <xsl:attribute name="dest-entry-id">
    <xsl:value-of select="$entryID"/>
    </xsl:attribute>
    <xsl:value-of select="$association"/>
    </add-association>
    </xsl:if>


    where the association value is calculated elsewhere in the XSLT.


    --
    --------------------------------------------------------------------------
    David Gersic dgersic_@_niu.edu
    Knowledge Partner http://forums.microfocus.com

    Please post questions in the forums. No support provided via email.
    If you find this post helpful, please click on the star below.

  • dgersic;260307 Wrote:
    > On Thu, 27 Aug 2015 16:44:01 0000, jacmarpet wrote:
    >
    > > <xsl:variable name="add-association">
    > > <add-association>
    > > <xsl:attribute name="dest-

    > dn">
    > > <xsl:value-of

    > select="$lDN"/>
    > > </xsl:attribute>
    > > <xsl:attribute

    > name="event-id">0</xsl:attribute> <xsl:attribute
    > > name="src-entry-id">
    > > <xsl:value-of

    > select="$lSrcEntryID"/>
    > > </xsl:attribute>
    > > <xsl:value-of
    > > select="$result//*[local-

    > name()='AddDepartmentResult']"/>
    > > </add-association>
    > > </xsl:variable>

    >
    > I think this is your problem. Take out the <xsl:variable> here. You
    > just
    > want the XSLT to output the <add-association> in the XDS. I have
    > something similar here, like:
    >
    > >

    Code:
    --------------------
    > >

    > <xsl:if test="$association and $dn and $code = 'SUCCESS'">
    > <add-association>
    > <xsl:attribute name="dest-dn">
    > <xsl:value-of select="$dn"/>
    > </xsl:attribute>
    > <xsl:attribute name="event-id">
    > <xsl:value-of select="$eventID"/>
    > </xsl:attribute>
    > <xsl:attribute name="dest-entry-id">
    > <xsl:value-of select="$entryID"/>
    > </xsl:attribute>
    > <xsl:value-of select="$association"/>
    > </add-association>
    > </xsl:if>
    >

    --------------------
    > >

    >
    > where the association value is calculated elsewhere in the XSLT.
    >
    >
    > --
    > --------------------------------------------------------------------------
    > David Gersic
    > dgersic_@_niu.edu
    > Knowledge Partner
    > http://forums.microfocus.com
    >
    > Please post questions in the forums. No support provided via
    > email.
    > If you find this post helpful, please click on the star below.


    Hmm. But, if I do that, no actual NDS document is generated. If I change
    my code from:


    Code:
    --------------------

    <xsl:if test="$result//*[local-name()='AddDepartmentResult'] = 'true'">
    <xsl:message>AddAssociation DeptID: <xsl:value-of select="$lDeptID"/>
    <xsl:message>AddAssociation DN: <xsl:value-of select="$lDN"/></xsl:message>
    <xsl:message>AddAssociation src-entry-id: <xsl:value-of select="$lSrcEntryID"/></xsl:message>
    </xsl:message>
    <xsl:variable name="add-association">
    <add-association>
    <xsl:attribute name="dest-dn">
    <xsl:value-of select="$lDN"/>
    </xsl:attribute>
    <xsl:attribute name="event-id">0</xsl:attribute>
    <xsl:attribute name="src-entry-id">
    <xsl:value-of select="$lSrcEntryID"/>
    </xsl:attribute>
    <xsl:value-of select="$lDeptID"/>
    </add-association>
    </xsl:variable>
    <xsl:message>Event: <xsl:value-of select="$add-association"/></xsl:message>
    <xsl:variable name="results" select="cmd:execute($srcCommandProcessor, $add-association)"/>
    </xsl:if>

    --------------------


    to:


    Code:
    --------------------

    <xsl:if test="$result//*[local-name()='AddDepartmentResult'] = 'true'">
    <xsl:message>AddAssociation DeptID: <xsl:value-of select="$lDeptID"/>
    <xsl:message>AddAssociation DN: <xsl:value-of select="$lDN"/></xsl:message>
    <xsl:message>AddAssociation src-entry-id: <xsl:value-of select="$lSrcEntryID"/></xsl:message>
    </xsl:message>
    <add-association>
    <xsl:attribute name="dest-dn">
    <xsl:value-of select="$lDN"/>
    </xsl:attribute>
    <xsl:attribute name="event-id">0</xsl:attribute>
    <xsl:attribute name="src-entry-id">
    <xsl:value-of select="$lSrcEntryID"/>
    </xsl:attribute>
    <xsl:value-of select="$lDeptID"/>
    </add-association>
    </xsl:if>

    --------------------


    That results in a document that looks like:


    Code:
    --------------------

    <add-association dest-dn="\IDVTREE\top\idv\structures\departments\006F67370CD44C968555C8D985802FF3" even
    t-id="0" src-entry-id="48681" xmlns:soap="">www.w3.org/.../soap-envelope">006F67370CD44C968555C8D98
    5802FF3</add-association>

    --------------------


    instead of:


    Code:
    --------------------

    <nds dtdversion="4.0" ndsversion="8.x">
    <input>
    <add-association dest-dn="\IDVTREE\top\idv\structures\departments\006F67370CD44C968555C8D985802FF3" even
    t-id="0" src-entry-id="48681" xmlns:soap="">www.w3.org/.../soap-envelope">006F67370CD44C968555C8D98
    5802FF3</add-association>
    </input>
    </nds>

    --------------------


    I might misunderstand you though.


    --
    jacmarpet
    ------------------------------------------------------------------------
    jacmarpet's Profile: https://forums.netiq.com/member.php?userid=415
    View this thread: https://forums.netiq.com/showthread.php?t=54150


  • Okay, so now it works. I changed the value of the actual association to
    not just set the value to true. It is correct that it is not the correct
    thing to write. I instead write the CN of the object, which is a GUID.

    I the changed the stylesheet header to also exclude soap-env. That made
    no difference. Then i tried doing what you suggested Alex, with
    stripping the SOAP header, but without luck.

    Just for fun, I thought that maybe the src-entry-id or the event-id
    might be a problem. Removing the src-entry-id from the event removes the
    null pointer exception. So my code is now:


    Code:
    --------------------

    <xsl:if test="$result//*[local-name()='AddDepartmentResult'] = 'true'">
    <xsl:message>AddAssociation DeptID: <xsl:value-of select="$lDeptID"/>
    <xsl:message>AddAssociation DN: <xsl:value-of select="$lDN"/></xsl:message>
    <xsl:message>AddAssociation src-entry-id: <xsl:value-of select="$lSrcEntryID"/></xsl:message>
    </xsl:message>
    <xsl:variable name="add-association">
    <add-association>
    <xsl:attribute name="dest-dn">
    <xsl:value-of select="$lDN"/>
    </xsl:attribute>
    <xsl:attribute name="event-id">0</xsl:attribute>
    <!--
    <xsl:attribute name="src-entry-id">
    <xsl:value-of select="$lSrcEntryID"/>
    </xsl:attribute>
    -->
    <xsl:value-of select="$lDeptID"/>
    </add-association>
    </xsl:variable>
    <xsl:variable name="results" select="cmd:execute($srcCommandProcessor, $add-association)"/>
    </xsl:if>

    --------------------


    I do not understand why removing that actually works. I would have
    thought it was mandatory to have that in the document header.

    The trace:


    Code:
    --------------------

    [08/28/15 16:59:23.089]:soapIntra01 ST:
    <nds dtdversion="4.0" ndsversion="8.x">
    <input>
    <add-association dest-dn="\IDVTREE\top\idv\structures\departments\006F67370CD44C968555C8D985802FE0" even
    t-id="0" xmlns:soap="">www.w3.org/.../add-associat
    ion>
    </input>
    </nds>
    [08/28/15 16:59:23.091]:soapIntra01 ST: Pumping XDS to eDirectory.
    [08/28/15 16:59:23.092]:soapIntra01 ST: Performing operation add-association for \IDVTREE\top\idv\structure
    s\departments\006F67370CD44C968555C8D985802FE0.
    [08/28/15 16:59:23.118]:soapIntra01 ST: Processing returned document.
    [08/28/15 16:59:23.119]:soapIntra01 ST: Processing operation <status> for .
    [08/28/15 16:59:23.120]:soapIntra01 ST:
    DirXML Log Event -------------------
    Driver: \IDVTREE\top\system\IDMDriverSet01\soapIntra01
    Channel: Subscriber
    Object: \IDVTREE\top\idv\structures\departments\006F67370CD44C968555C8D985802FE0
    Status: Success

    --------------------


    Any idea what might be wrong with the way I set the src-entry-id?

    Full stylesheet:

    http://dumptext.com/lLmOLrmn

    Jacob.


    --
    jacmarpet
    ------------------------------------------------------------------------
    jacmarpet's Profile: https://forums.netiq.com/member.php?userid=415
    View this thread: https://forums.netiq.com/showthread.php?t=54150

  • jacmarpet wrote:

    >
    > Okay, so now it works. I changed the value of the actual association to
    > not just set the value to true. It is correct that it is not the correct
    > thing to write. I instead write the CN of the object, which is a GUID.
    >
    > I the changed the stylesheet header to also exclude soap-env. That made
    > no difference. Then i tried doing what you suggested Alex, with
    > stripping the SOAP header, but without luck.


    Looking moreclosely, I think the specific header value needs to be s not soap-env

    > Just for fun, I thought that maybe the src-entry-id or the event-id
    > might be a problem. Removing the src-entry-id from the event removes the
    > null pointer exception. So my code is now:


    .....
    >
    >
    > Any idea what might be wrong with the way I set the src-entry-id?
    >



    If you look at what is documented as allowed in an add-association, it shows you need to use dest-entry-id and set it to the src-entry-id of the <add>
    So likely they are now more strictly enforcing invalid attributes in 4.5

    > Full stylesheet:
    >
    > http://dumptext.com/lLmOLrmn
    >


    I have some more comments about the stylesheet - may reply a bit later with some feedback.
  • jacmarpet wrote:

    >
    > Then i tried doing what you suggested Alex, with
    > stripping the SOAP header, but without luck.


    I misunderstood how you were trying to do this. Your approach is to be honest quite unusual.

    >
    >
    > Full stylesheet:
    >
    > http://dumptext.com/lLmOLrmn


    Now I see the stylesheet - I can see that you do everything in an output transform stylesheet. Which is odd, but can make sense in some scenarios. I don't think it makes sense here though.

    It seems that you got this to work - which is great, but it smacks of the "when you have a hammer everything is a nail" approach.

    The one aspect that I think is clearly asking for trouble is how you use the dest-query processor (ie read-only) to execute a write-command.

    I do seem to recall you had another SOAP driver where you polled the app from within a stylesheet. This isn't the same driver is it?


    Essentially - in plain terms - what you do is:

    1. Parse an add from the engine and convert it to the format as required by the web service.
    2. Save that to a variable
    3. Write this to the web service, using a mechanism designed for read-only queries. Assign response to a variable.
    4. Read the response from the read-only query response variable and optionally generate an add-association operation (again in a variable)
    5. Write the add-association back to the engine using a mechanism designed for write-commands.

    I'm not entirely sure why you feel the need to do all of this via direct operations in one stylesheet. As you can see it is definitely possible, but hard to troubleshoot and not at all necessary.

    The more traditional approach is:

    1. Start transaction and regular driver logic until the operation passes the schema mapping.
    2. Parse an operation from the engine and convert it to the format as required by the web service (handled in output transform). Use operation-data/return-to-me to track key properties of original event.
    2a. Wrap the result in a soap-envelope (handled in output transform)
    3. Let the driver shim submit it to the web service as a regular operation.
    4. The shim returns the result and passes it to the input transform.
    5a. Strip the soap envelope
    5b. Parse the result and transform it into relevant XDS (normally a status optionaly other operations). Restore/utilize operation-data/return-to-me as necessary.
    5. Engine parses the status other options and notes the end of the transaction.

    This leverages the built-in functionality as much as possible (which is generally a good idea).

    Here is how I would construct the output stylesheet. (any true XSLT gurus please advise of a more efficient approach if one exists)


    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:cmd="">www.novell.com/.../com.novell.nds.dirxml.driver.XdsCommandProcessor" xmlns:dis="">schemas.datacontract.org/.../DisPlay.NordfynsKommune.Presentation.Services.Import" xmlns:dncv="">www.novell.com/.../com.novell.nds.dirxml.driver.DNConverter" xmlns:query="">www.novell.com/.../com.novell.nds.dirxml.driver.XdsQueryProcessor" xmlns:tem="">http://tempuri.org/" xmlns:soapenv="">schemas.xmlsoap.org/.../" xmlns:xsl="">www.w3.org/.../Transform" version="1.0" exclude-result-prefixes="query cmd dncv">
    <!-- parameters passed in from the Identity Manager engine -->
    <xsl:param name="srcQueryProcessor"/>
    <xsl:param name="destQueryProcessor"/>
    <xsl:param name="srcCommandProcessor"/>
    <xsl:param name="destCommandProcessor"/>
    <xsl:param name="dnConverter"/>
    <xsl:param name="fromNds"/>
    <!-- ADD Templates -->
    <!-- convert XDS add-attr to DisPlay-attr -->
    <xsl:template match="add-attr[not(string(value)='')]" mode="to-DisPlay">
    <xsl:element name="{concat('dis:',@attr-name)}">
    <xsl:value-of select="value[1]"/>
    </xsl:element>
    </xsl:template>
    <xsl:template match="add[@class-name='Department']">
    <!-- ADD Department Template -->
    <xsl:message>Add Department</xsl:message>
    <xsl:element name="soapenv:Envelope">
    <xsl:element name="soapenv:Header"/>
    <soapenv:Body>
    <tem:AddDepartment>
    <tem:department>
    <xsl:apply-templates select="add-attr" mode="to-DisPlay"/>
    </tem:department>
    <xsl:element name="operation-data" >
    <xsl:attribute name="event-id">
    <xsl:value-of select="@event-id"/>
    </xsl:attribute>
    <xsl:attribute name="url">~url.dept~</xsl:attribute>
    <xsl:attribute name="soap-action">~action.dept.add~</xsl:attribute>
    <xsl:attribute name="parent-node-1">AddDepartmentResult</xsl:attribute>
    <xsl:call-template name="extend-operation-data">
    <xsl:with-param name="theCmd" select="local-name()"/>
    </xsl:call-template>
    </xsl:element>
    </tem:AddDepartment>
    </soapenv:Body>
    </xsl:element>
    </xsl:template>
    <xsl:template name="extend-operation-data">
    <xsl:param name="theCmd" select="'unknown'"/>
    <xsl:attribute name="event-id">
    <xsl:value-of select="@event-id"/>
    </xsl:attribute>
    <xsl:apply-templates select="operation-data/@*|operation-data/node()"/>
    <return-to-me command="{$theCmd}">
    <xsl:apply-templates select="@*"/>
    </return-to-me>
    </xsl:template>
    <!-- identity transformation template -->
    <!-- in the absence of any other templates this will cause -->
    <!-- the stylesheet to copy the input through unchanged to the output -->
    <xsl:template match="node()|@*">
    <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
    </xsl:template>
    </xsl:stylesheet>


    The input stylesheet might look something like this:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet exclude-result-prefixes="query cmd dncv s tem" version="1.0" xmlns:cmd="">www.novell.com/.../com.novell.nds.dirxml.driver.XdsCommandProcessor" xmlns:dncv="">www.novell.com/.../com.novell.nds.dirxml.driver.DNConverter" xmlns:query="">www.novell.com/.../com.novell.nds.dirxml.driver.XdsQueryProcessor" xmlns:s="">schemas.xmlsoap.org/.../" xmlns:tem="">http://tempuri.org/" xmlns:xsl="">www.w3.org/.../Transform">
    <!-- parameters passed in from the Identity Manager engine -->
    <xsl:param name="srcQueryProcessor"/>
    <xsl:param name="destQueryProcessor"/>
    <xsl:param name="srcCommandProcessor"/>
    <xsl:param name="destCommandProcessor"/>
    <xsl:param name="dnConverter"/>
    <xsl:param name="fromNds"/>
    <!-- strip operation data that shim adds under the input element, it is against DTD -->
    <xsl:template match="input/operation-data"/>
    <!-- *********************** -->
    <!-- Strip off SOAP header -->
    <!-- Assumes soap namespace prefix is 's' , change this as required-->
    <!-- *********************** -->
    <xsl:template match="s:Envelope">
    <!-- ignore this element but process all children -->
    <xsl:apply-templates select="s:Body/*"/>
    </xsl:template>
    <xsl:template match="s:Fault">
    <status level="error">
    <xsl:if test="../operation-data/@event-id">
    <xsl:attribute name="event-id">
    <xsl:value-of select="../operation-data/@event-id"/>
    </xsl:attribute>
    </xsl:if>
    <xsl:apply-templates select="node()"/>
    </status>
    </xsl:template>
    <!-- handle a result, assumes it isn't wrapped in yet another node. -->
    <xsl:template match="*[local-name()='AddDepartmentResult']">
    <xsl:variable name="dn" select="//return-to-me/@src-dn"/>
    <xsl:variable name="eventID" select="//return-to-me/@event-id"/>
    <xsl:variable name="entryID" select="//return-to-me/@src-entry-id"/>
    <xsl:variable name="code" select="./text()"/>
    <status event-id="{$eventID}">
    <xsl:choose>
    <xsl:when test="$code = 'true'">
    <xsl:attribute name="level">success</xsl:attribute>
    </xsl:when>
    <xsl:otherwise>
    <xsl:attribute name="level">error</xsl:attribute>
    <xsl:attribute name="type">app-general</xsl:attribute>
    </xsl:otherwise>
    </xsl:choose>
    <xsl:call-template name="set-operation-data"/>
    </status>
    <xsl:if test="$entryID">
    <add-association event-id="{$eventID}" dest-entry-id="{$entryID}">
    <xsl:if test="$dn">
    <xsl:attribute name="dest-dn">
    <xsl:value-of select="$dn"/>
    </xsl:attribute>
    </xsl:if>
    <!-- Wouldn't use this as an actual assoc value, just an example -->
    <xsl:value-of select="$entryID"/>
    <xsl:call-template name="set-operation-data"/>
    </add-association>
    </xsl:if>
    </xsl:template>
    <xsl:template name="set-return-to-me">
    <xsl:param name="call-additional" select="false()"/>
    <return-to-me request="{local-name(.)}">
    <xsl:if test="$call-additional">
    <xsl:apply-templates mode="additional-return-to-me" select="."/>
    </xsl:if>
    </return-to-me>
    </xsl:template>
    <xsl:template name="set-operation-data">
    <xsl:param name="call-additional" select="false()"/>
    <xsl:element name="operation-data">
    <xsl:choose>
    <xsl:when test="operation-data">
    <xsl:apply-templates select="operation-data/@*|operation-data/node()"/>
    </xsl:when>
    <xsl:when test="../operation-data">
    <xsl:apply-templates select="../operation-data/@*|../operation-data/node()"/>
    </xsl:when>
    </xsl:choose>
    <xsl:call-template name="set-return-to-me">
    <xsl:with-param name="call-additional" select="$call-additional"/>
    </xsl:call-template>
    </xsl:element>
    </xsl:template>
    <!-- Heartbeat -->
    <xsl:template match="status[@level='success' and @type='heartbeat']">
    <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
    <operation-data xmlns="">
    <xsl:apply-templates select="../operation-data/@*|../operation-data/node()"/>
    <return-to-me command="heartbeat"/>
    </operation-data>
    </xsl:copy>
    </xsl:template>
    <!-- Remote Loader Query -->
    <xsl:template match="query[@scope='entry' and read-attr[@attr-name='Public Key']]">
    <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
    <operation-data xmlns="">
    <xsl:apply-templates select="../../operation-data/@*|../../operation-data/node()"/>
    <return-to-me command="remote-loader-query"/>
    </operation-data>
    </xsl:copy>
    </xsl:template>
    <!-- strip operation data that shim adds under the output element, it is against DTD -->
    <xsl:template match="output/operation-data"/>
    <!-- identity transformation template -->
    <!-- in the absence of any other templates this will cause -->
    <!-- the stylesheet to copy the input through unchanged to the output -->
    <xsl:template match="node()|@*">
    <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
    </xsl:template>
    </xsl:stylesheet>