A driver is an application shim, combined with policies, that allows Identity Manager to communicate with an external application in
order to synchronize data between that application and the Identity Vault. Note that the term driver is often used
when shim is meant.

Identity Manager can be thought of as two separate black boxes called channels. Each channel takes an event on its input
and issues a (possibly empty) set of commands on its output. The goal of the transformation from events to commands is to propagate
the changes made by the application connected to the channel input into the application connected to the channel
output. The transformation involves fixed logic in the Identity Manager Engine together with a set of configurable policies that guide
the transformation of events to commands.

The first channel is the Subscriber channel. The Identity Vault acts as the Subscriber channel input and a shim's
SubscriptionShim
acts as the Subscriber channel output. The Subscriber channel therefore accepts Identity Vault events, generates commands with
the help of the policies, and issues those commands to the
SubscriptionShim
which then updates the application.

The second channel is the Publisher channel. The shim's
PublicationShim
acts as the Publisher channel input and the Identity Vault acts as the Publisher channel output. The Publisher channel therefore
accepts events for the application through the
PublicationShim,
generates commands with the help of the rules, and issues those commands to update the Identity Vault.

No. It is useful for the shim author to understand what policies do, but the shim has no responsibility for
policy processing. The shim author should have a good understanding of the responsibilities of the shim before
worrying about policies.

Associations are the mechanism used by Identity Manager to establish and maintain a linkage between an object in
the Identity Vault and an application object. The shim provides a unique key value for each application object and the Identity Manager
Engine manages the storage of those key values in the Identity Vault.

A shim's responsibility with respect to associations is to provide a unique key value for each object and
to notify the Identity Manager Engine whenever something happens that affects that unique key. In practice this means:

Provide the unique key value for the object whenever communicating any information about the object to
the Identity Manager Engine (events and queries).

Report to the Identity Manager Engine whenever the unique key value of a relevant object changes using
<modify-association>.

Report to the Identity Manager Engine the unique key value of an object created as a result of processing and <add>
command in the SubscriptionShim using <add-association>
in the result document returned from the add processing.

DriverShim - The top-level interface responsible
for starting up and shutting down the driver.

SubscriptionShim - The interface
responsible for accepting and processing commands from Identity Manager.

PublicationShim - The interface responsible
for notifying Identity Manager of events that occur in the application.

XmlQueryProcessor - The interface
passed by the PublicationShim into XmlCommandProcessor.execute
when calling Identity Manager to report an application event. Identity Manager uses the XmlQueryProcessor interface to query the PublicationShim
for any additional information that Identity Manager may need to process the application event.

Identity Manager monitors the Identity Vault for relevant events and invokes
SubscriptionShim.execute
when an application object must be created or a change must be made to an application object. In addition, Identity Manager
invokes SubscriptionShim.execute() to query the application for information about application objects.

At some time in the future Identity Manager to shuts down the
shim. DriverShim.shutdown
is called which performs whatever shim-specific cleanup is needed (including
signaling PublicationShim.start to return.

XmlDocument is a high level
abstraction representing an XML document. It allows for easy conversions between several common representations
of XML, notably Document Object Model (DOM), Simple API for
XML 1.0 (SAX), and a serialized, human-readable form.
This allows shims to create and consume XML documents in the form that is most convenient for the particular
application. Identity Manager predominantly uses DOM internally, but uses the serialized form when logging messages to DSTRACE.
Most shims will probably also use DOM internally, but shims which must pass the XML to external or remote processes
will likely use the serialized form as well.

Note that support for SAX 2.0 has not been added because all shims to date have used either the DOM representation or
a serialized representation.

The implementation of DOM used by Identity Manager is provided by nxsl.jar (which contains Novell's XSLT processor as
well as many XML utility classes). To create a document that uses the same implementation as Identity Manager,
use com.novell.xml.dom.DocumentFactory.newDocument.

It is possible for a shim to use a different implementation of DOM. However, keep in mind that documents that
are passed to the shim by Identity Manager will always use the nxsl.jar implementation, so any extensions to DOM that might
be available in another implementation will not be available in documents received from Identity Manager. Note also that
the performance of the Novell XSLT processor is significantly better on documents created using the nxsl.jar implementation.

The documents passed to and from the various methods have a structure defined by
nds.dtd.
All documents use <nds> as the document (top-level) element, which may contain
an optional <source> element. Documents that are passed as parameters to
interface methods also contain a single <input> element that contains an
arbitrary number of events or commands as applicable. Documents that are returned from interface methods contain
a single <output> element which contains the results of the processing the
events or commands contained in the input document and may contain a limited set of commands.

The distinction is subtle but important. Many of the possible child elements of <input>
can be interpreted either as commands or as events, depending on the context, and have essentially the same syntax.
In general, for elements that can be used as either a command or as notification of an event the following applies:
If the element is being sent to the shim then the element is a command and if the element is being sent to Identity Manager
then the element is an event notification. When the shim sends an event notification to Identity Manager the shim is informing
Identity Manager of something that occurred in the application. Identity Manager will then determine, based on configurable policies,
which commands, if any, must be sent to the Identity Vault. When Identity Manager sends a command to the shim, Identity Manager has already taken
an Identity Vault event as input, applied the appropriate policies, and determined that the change in the application represented
by the command is necessary.

Policies help Identity Manager transform an event on a channel input into a set
of commands on the channel output. Policies
are configurable by the System Administrator so that the policies can be customized to do whatever an individual installation
requires. Some policies perform a well-defined role in the event-to-command transformation process while others allow for
more general customization.

Policies may be implemented in two languages: DirXML Script and
XSLT. DirXML Script is a language that is specific to Identity Manager and
to the operations necessary in Identity Manager policies. XSLT is a general XML transformation language. The Schema Mapping Policy also has
a table-like XML structure suited for one-to-one mapping of names.

Many policies are evaluated either on the Subscriber channel or on the Publisher channel but not both. However, the Schema Mapping Policy,
the Input Transformation Policy, and the Output Transformation Policy are evaluated on both channels.

The Schema Mapping Policy applies to both the Subscriber channel and to
the Publisher channel. The purpose of the Schema Mapping Policy is to map schema names (particularly attribute names
and class names) between the Identity Vault namespace and the application namespace. The default policy syntax is defined by the documentation
for <attr-name-map>. The Schema Mapping Policy is applied to the
XML documents sent to and returned from SubscriptionShim.execute,
XmlQueryProcessor.query, and
XmlCommandProcessor().execute(). The
Schema Mapping Policy is also applied to XML sent to (but not to XML returned from)
SubscriptionShim.init
and PublicationShim().init(). The Schema
Mapping Policy is applied before the Output Transformation Policy when Identity Manager submits or returns a document to the shim and before
the Input Transformation Policy when the driver submits or returns a document to Identity Manager.

The Input Transformation Policy applies to both the Subscriber channel
and to the Publisher channel. The purpose of the Input Transformation Policy is to perform a preliminary transformation
on all XML documents sent to Identity Manager by the driver and returned to Identity Manager from the driver. The Input Transformation
Policy is applied to the XML documents sent to XmlCommandProcessor.execute
and XmlQueryProcessor.query (when
called by the driver) and to the XML documents returned from SubscriptionShim.execute,
and XmlQueryProcessor.query (when
called by Identity Manager). The Input Transformation Policy is applied before the Schema Mapping Policy.

The Input Transformation Policy is often used to transform data from the application format into the Identity Vault format. When
the Input Transformation is used for data format transformations the Output Transformation Policy usually performs the data transformation
in the opposite
direction (i.e., transforms from the Identity Vault format to the application format). The
Input Transformation Policy is also used to perform actions in response to the results of commands sent to the shim. Note that schema names
will always be in the application namespace in the XML processed by
the Input Transformation Policy.

It is also possible to use the Input Transformation Policy to transform an arbitrary XML format native to the connected
application to the format expected by Identity Manager. Such transformations must be written in XSLT because DirXML-Script
operates only on the Identity Manager-specific XML vocabulary.

The Output Transformation Policy applies to both the Subscriber channel
and to the Publisher channel. The purpose of the Output Transformation Policy is to perform a final transformation
on all XML documents sent to the shim by Identity Manager and returned to the shim by Identity Manager. The Output Transformation
Policy is applied to the XML documents sent to SubscriptionShim.execute
and XmlQueryProcessor.query (when
called by Identity Manager) and to the XML documents returned from
XmlCommandProcessor.execute
and XmlQueryProcessor.query (when
called by the shim). The Output Transformation Policy is applied after the Schema Mapping Rule.

The Output Transformation Policy is often used to transform data from the Identity Vault format into the application format. When
the Output Transformation is used for data format transformations the Input Transformation Policy usually performs the data transformation
in the opposite
direction (i.e., transforms from the application format to the Identity Vault format). The
Output Transformation Policy is also used to perform actions in response to the results of commands sent to the Identity Vault.
Note that schema names
will always be in the application namespace in the XML processed by
the Input Transformation Policy.

It is also possible to use the Output Transformation Policy to transform from the format used by Identity Manager to an
arbitrary XML format native to the connected application. Such transformations must be written in XSLT because DirXML-Script
operates only on the Identity Manager-specific XML vocabulary.

The Event Transformation Policy operates on events reported on a channel input. The Subscriber and
Publisher channels usually have different Event Transformation Policies. The purpose of the Event Transformation Policy is
to modify the report of what happened (the events) before the events are processed further by Identity Manager.

On the Subscriber channel the Event Transformation
Policy is applied to events received by Identity Manager from Identity Vault and is applied before any other policy-based event processing.

On the Publisher channel the Event Transformation Policy is applied to events issued by the shim to Identity Manager and is applied
after the Input Transformation Policy and Schema Mapping Policy, but before any other policy-based event processing.

There are many common applications
for the Event Transformation Policy, including:

scope filtering (e.g., only allow events on objects in a particular subtree, or with a particular attribute value)

custom event filtering (e.g., disallow moves or deletes)

transforming the event directly into a custom command to be passed to the application

The Command Transformation Policy operates on commands that are about to be issued to a channel output. The Subscriber and
Publisher channels usually have different Event Transformation Policies. The purpose of the Command Transformation Policy
is to provide final processing on commands before the commands are sent to the Identity Vault or to the application.

The Command Transformation Policy on the Publisher channel is executed after all other policies and is executed directly
before the Identity Manager Engine applies the command document to the Identity Vault. It is the "last chance" to modify
a command before the command is applied to the Identity Vault.

The Command Transformation Policy on the Subscriber channel is executed directly before the Schema Mapping Policy. Both
the Schema Mapping Policy and the Output Transformation Policy are executed after the Command Transformation Policy on the
Subscriber channel.

Some possible applications for the Command Transformation Rule include:

changing the command type (for example, an object delete command might be transformed into a modification that
will cause the object to be archived)

blocking commands

adding additional commands

controlling the output of the Identity Manager Engine's "merge" process

The Matching Policy is applied to <add> events and serves to automatically link an
object in the Identity Vault with the corresponding object in the application. The Subscriber and Publisher channels usually
have different Matching Polcies. The policy is usually implemented using the DirXML Script action
<do-find-matching-object>.

The Matching Policy is executed after the Event Transformation Policy and before the Create Policy.

The Create Policy is applied to <add> events and serves to disallow (veto) the creation of a new object if
an already existing object was not found using the Matching Policy. The Subscriber and Publisher channels usually
have different Create Polcies.

The Create Policy is often used to examine the attributes available for the new object (from the source event) and vetoes the creation of
the new object is one or more required attributes is missing.

The Create Policy is also used to supply default values for attributes and may specify a template to be used in the
creation of the new object.

The Create Policy is executed after the Matching Policy and before the Placement Policy. Note that the Create Policy will not
be executed if the Matching Policy finds a matching object in the channel destination.

The Placement Policy is applied to <add> events and serves to generate a name for a new object and
to generate a placement in the target object hierarchy The Subscriber and Publisher channels usually
have different Placement Polcies.

The Placement Policy is executed after the Create Policy and before the Command Transformation Policy. Note that the
Placement Policy will not be executed if the Create Policy vetoes the <add> event.

The driver filter specifies the classes of objects and the attributes of those objects for which Identity Manager will process
events and commands. Separate filter behavior may be specified for the Subscriber and Publisher channels.

The filter for a channel specifies how each class and how each attribute in the filter is to be handled by Identity Manager. The
filter is defined by the <filter> element.

The following is the general order of filter and policy processing. Note that this is an extreme over-simplification of the
processing that actually occurs and that processing may stop at any point or skip to the last step if the result
of processing a policy dictates it.

Policies and filters must be explicitly constructed to complement each other. What this means really depends
on the particular requirements of the installation and on the requirements of the application, but here are a few
general things to keep in mind:

If a policy operates on attribute values or uses attribute values to make a decision, those attributes need to
be set to "synchronize" or "notify" in the filter settings for the channel containing the policy.

Usually the Create Policy should require all the attributes used by the Matching Policy. This forces the creation of
a new object to be deferred until enough is known about the object to allow a reasonable attempt at finding a
matching object in the target space.

On the Subscriber channel the policy must add an <association> to the <add>
for all matches that are found in the application.

On the Publisher channel the policy must add the dest-dn attribute of the <add> if
a match is found in the Identity Vault. The special value of a single unicode character &#xFFFD; signals that multiple matches
were found.

Unless you are translating to/from an XML format that is completely different from the Identity Manager format in the
Input and Output Transformation Policies, you will want to start your stylesheet with templates that implement the
identity transformation. This is so that anything in the document that you don't specifically try to intercept
and change will be passed through as is.

The following two templates together implement the identity transform:

Except for the Input and Output Transformation Policies, rules implemented as stylesheets are passed several parameters
from Identity Manager that the stylesheet can use:

fromNDS - boolean value that is true if the rule is being processed by the Subscriber channel and false if
the rule is being processed by the Publisher channel.

srcQueryProcessor - a Java object of class com.novell.nds.dirxml.driver.XdsQueryProcessor.
This allows the stylesheet to query the event source for more information.

destQueryProcessor - a Java object class com.novell.nds.dirxml.driver.XdsQueryProcessor.
This allows the stylesheet to query the event target for more information.

srcCommandProcessor - a Java object class com.novell.nds.dirxml.driver.XdsCommandProcessor.
This allows the stylesheet to "write-back" a command to the event source.

destCommandProcessor - a Java object class com.novell.nds.dirxml.driver.XdsCommandProcessor.
This allows the stylesheet to issue a command to the command destination directly, bypassing most other policies.

dnConverter - a Java object implementing interface com.novell.nds.dirxml.driver.DNConverter.
This allows the stylesheet to convert eDirectory DNs from one DN format to another.

To use these parameters include the following at the top level of your stylesheet:

Use of the query processors depends on the Novell XSLT implementation of extension functions. In order to make
a query you need to declare a namespace for the Java interfaces used. For example, to use the XdsQueryProcessor interface add xmlns:query="http://www.novell.com/nxsl/java/com.novell.nds.dirxml.driver.XdsQueryProcessor"
to the <xsl:stylesheet> or <xsl:transform> element of the stylesheet.

An example of using one of the query processors:

<!-- query object name queries the Identity Vault for the passed object-name. Ideally, this would -->
<!-- not depend on "CN": to do this, add another parameter that is the name of the -->
<!-- naming attribute. -->
<xsl:template name="query-object-name">
<xsl:param name="object-name"/>
<!-- build an xds query as a result tree fragment -->
<xsl:variable name="query">
<query>
<search-class class-name="{ancestor-or-self::add/@class-name}"/>
<!-- NOTE: depends on CN being the naming attribute -->
<search-attr attr-name="CN">
<value><xsl:value-of select="$object-name"/></value>
</search-attr>
<!-- put an empty read attribute in so that we don't get the whole object back -->
<read-attr/>
</query>
</xsl:variable>
<!-- query NDS -->
<xsl:variable name="result" select="query:query($destQueryProcessor,$query)"/>
<!-- return an empty or non-empty result tree fragment depending on result of query -->
<xsl:value-of select="$result//instance"/>
</xsl:template>

Use of the command processors depends on the Novell XSLT implementation of extension functions. In order to issue
a command you need to declare a namespace for the XdsCommandProcessor interface: this is done by adding xmlns:command="http://www.novell.com/nxsl/java/com.novell.nds.dirxml.driver.XdsCommandProcessor"
to the <xsl:stylesheet> or <xsl:transform> element of the stylesheet.

XSLT is an excellent tool for performing some kinds of transformations and a rather poor tool for other types
of transformations (non-trivial string manipulation, iterative processes, etc.). Fortunately the Novell XSLT processor
implements extension functions which allow the stylesheet to call a function implemented in Java (and by extension
any other language that can be accessed through JNI).

Additional documentation on using extension functions with Novell's XSLT implementation can be found elsewhere.
For specific examples see the above example using the query processor, and the following example that illustrates
using Java for string manipulation:

<!-- get-dn-prefix places the part of the passed dn that precedes the -->
<!-- last occurrence of '\' in the passed dn in a result tree fragment -->
<!-- meaning that it can be used to assign a variable value -->
<xsl:template name="get-dn-prefix" xmlns:jstring="http://www.novell.com/nxsl/java/java.lang.String">
<xsl:param name="src-dn"/>
<!-- use java string stuff to make this much easier -->
<xsl:variable name="dn" select="jstring:new($src-dn)"/>
<xsl:variable name="index" select="jstring:lastIndexOf($dn,'\')"/>
<xsl:if test="$index != -1">
<xsl:value-of select="jstring:substring($dn,0,$index)"/>
</xsl:if>
</xsl:template>

Shims can invoke the Novell XSLT processor directly by using the com.novell.xsl.Stylesheet
class. There are various ways in which this can be set up and invoked so it pays to read the documentation, but
a typical invocation is illustrated by the following code fragment.

The long answer is: If your shim makes assumptions about where it is running it may need to be modified. If, for
example, your shim uses a "side-band" connection to the Identity Vault via LDAP and assumes it can do so on "localhost" then your shim
won't work correctly with the Remote Loader. In general, if your shim strictly adheres to the Identity Manager interfaces and doesn't assume
that it is running on the same machine as the Identity Vault then your shim will function properly with the Identity Manager Remote Loader.

Messages originating from Identity Manager show up in DSTRACE if you enable the "DirXML Drivers" events (DVRS on NetWARE).
By default very little information is given, mostly just the status of events. To enable more verbose output, set the trace level
for the driver set or for the driver using the "Trace" settings in Designer, or the "Misc" settings in iManager.
Useful values for the trace level are:

1 - Informational messages about what Identity Manager is doing;

2 - adds dumps of the XML passed to/from the driver;

3 - adds XML dumps after a policy is applied and more verbose output during policy evaluation.

Shims may also send messages to DSTRACE by creating and using an instance of
com.novell.nds.dirxml.driver.Trace.
It is recommended that shims not write directly to System.out or System.err (even though this will currently
send the output to DSTRACE) because this may not be supported in future releases.

Trace messages may also be directed to a file (in addition to DSTRACE) by entering the name and path of a file
in the trace settings for the driver or driver set.

Set a TCP port number in the DirXML-JavaDebugPort attribute on the DirXML-DriverSet object. Restart eDirectory.
This will cause the Identity Manager JRE to be started with the equivalent of the following Java command line options:
-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,address=8080,suspend=n
Alternatively, use the DHOST_JVM_OPTIONS environment variable (DIRXML_JVM_OPTIONS on NetWare) to set any debugger options desired.
Attach a Java debugger to the Identity Manager JRE using the port number specified.

The following environment variables can be used (NetWare names appear in parentheses if available):

DHOST_JVM_USE_VFPRINTF

If set to a value other than "0"; will cause installation of a vfprintf hook function that will write
to a log file named "jvm_vfprintf.log"; in the temp directory. This will also enable verbose class and
JNI messages.

DHOST_JVM_VERBOSE_GC

If set to a value other than "0"; will enable verbose garbage collector messages. This is only useful
in conjunction with JVM_USE_VFPRINTF.

DHOST_JVM_INITIAL_HEAP (NetWare: DIRXML_JVM_INITIAL_HEAP)

Set to the value in number of bytes of initial JVM heap size.
Example: DHOST_JVM_INITIAL_HEAP=128M

DHOST_JVM_MAX_HEAP (NetWare: DIRXML_JVM_MAX_HEAP)

Set to the value in number of bytes of maximum JVM heap size.
Example: DHOST_JVM_MAX_HEAP=256M

DHOST_JVM_OPTIONS (NetWare: DIRXML_JVM_OPTIONS)

Set to command line arguments for the JRE.
Example: -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,address=8080,suspend=n
Each option string is separated by whitespace. If an option string contains whitespace, it must be enclosed in
double quotes.

The following options are available only on NetWare:

DIRXML_JVM_VIRTUAL_HEAP

set to the value in bytes of virtual java heap size.

Example: DIRXML_JVM_VIRTUAL_HEAP=512M

DIRXML_JVM_C_STACK_SIZE

set to the value in bytes of the java C process stack size.
Example: DIRXML_JVM_C_STACK_SIZE=256K