Novell Nsure® Identity Manager 2 Driver Development

Bill Bodine

Senior Consultant

bbodine@novell.com

Session Agenda

IDM2 driver development intro

Getting started – the Bare-Bones-Do-Nothing driver

Introduction to the FileHRSystem application

Hands-On

Agenda

What this course IS.

This course IS:

Driver development for IDM2

It is NOT:

A IDM2 introduction

A lesson in XSL

Assumptions

eDirectory™, IDM2 admin (inc. XSLT)

Java knowledge

Nsure Identity Manager 2

Provides flexible synchronization between disparate systems so that all enterprise data can be kept up-to-date with minimal maintenance costs

Application

Shim

IDM2 Architecture

DirXML

Join

Engine

Publisher

Subscribe

Application or

directory or

database

NDS

Datastore

Policies and Stylesheets

Policies and Stylesheets

Driver and eDirectory Comms

An XML format called XDS is used as the common denominator.

XDS is eDirectory-flavored XML with elements to represent directory objects and the operations you might perform on them.

Goal of an IDM2 driver

For each event that occurs in your application, pass the DirXML® engine an XDS document that explains the event

For each command received from the DirXML engine as an XDS document, translate the document into API calls to execute the command

XDS to

APP API

APP API

to XDS

Event

External Application

DirXML Driver

Engine / Driver Communication

DirXML Engine

DirXML Driver

Subscribe

Publisher

Code:

Check for changes,

Submit them to the

DirXML engine

using DirXML APIs.

Code:

Receive changes, submit them to the application using the application's APIs.

Event

Command

XDS

XDS

Driver Design Considerations

Know your application and understand the interface

API’s

Events

Security Issues

Schema

Driver Design Considerations

Data conversion

As much data conversion handled with policies and style sheets as possible.

Passwords

External application may require password authentication.

Loopback detection

DirXML engine detects application loopback.

Driver is responsible for eDirectory loopback, ensuring that a change sent by eDirectory to the driver is not sent back by the driver as a change needed in eDirectory.

Driver Design Considerations

Schema differences

Design your driver to handle the differences between eDirectory and the application

Example:

An eDirectory attribute definition can flag an attribute as naming, single-valued, or multi-valued

Application may have no concept of any of these, thus the driver must be designed to handle the differences

Driver Considerations : Subscriber

Converting

Convert from XDS to namespace API for application

Don’t convert data! - should be handled in policies and style sheets

Data Sending

The driver needs to use the interface of the external application to send the data to the application

The driver should not return to the DirXML engine until the application returns a response or a reasonable timeout expires

Response Handling

The driver needs to convert the response from the application into an XDS document and return it to the DirXML engine

Driver Considerations: Publisher

Changes

Driver needs to be informed of changes to the information in the external application

Filtering

Don’t if possible!

Converting

Convert the data from the application namespace API to XDS format and then send the data to the DirXML engine

Sending

Your driver sends the data to the DirXML engine and receives an XML response document

Driver filtering vs Policies/Stylesheets

Report all events, don’t filter in the driver

Administrator then has full control over filtering via policies

Don’t have to rebuild to make changes

Require less coding effort

Won’t filter out events which are of no use today but may be important tomorrow

There are exceptions – limit the amount of data a driver transfers for a verbose application or over WAN (Remote Driver)

Driver and Stylesheets

An IDM2 driver does not need to understand policies and style sheets because the driver has no responsibility for processing them

The DirXML engine is responsible for all policy and style sheet processing

Parsing XML

IDM2 drivers can use one of four methods to parse XML documents: DOM, SAX, XDS Libraries, or Serial

Novell has developed a custom XML parsing API, called XDS Libraries, which extends DOM functionality.

The XDS Libraries are designed to work specifically with the NDS.DTD

Application Changes

How Do I Know What Has Changed in My Application?

Typically the hardest part of creating a custom driver

To monitor changes, you first need to determine how the application stores data, what APIs are exposed and in what languages, if the application logs data or supplies an event system, and so on

If you are lucky, your application stores information in XML and has a full-featured event system

Sometimes, the application does not have even a suitable event log

Objects and Threads

A driver is typically implemented as three objects:

the driver object

the subscriber object

the publisher object

Each channel runs on a separate thread of execution, referred to as the subscriber thread and publisher thread

The Driver Object

Responsible for initializing that which is common to both channels

Creates the subscriber object and the publisher object

Shuts down the driver when instructed by the engine to do so

Implements com.novell.nds.dirxml.driver.DriverShim

The Publisher Object

Application API to XDS

The publisher object typically implements the

XmlQueryProcessor interface as well.

Implements com.novell.nds.dirxml.driver.PublicationShim

The Subscriber Object

XDS to application API

implements com.novell.nds.dirxml.driver.SubscriptionShim

The Subscriber Thread

The subscriber thread is the thread on which

the driver object is constructed

the driver object methods are called

the subscriber methods are called

Spends most of its time in DirXML engine code waiting for eDirectory events

The DirXML engine also uses the subscriber thread to instruct the driver to shut down by calling the driver object’s shutdown method

The driver object’s shutdown method is responsible for causing the publisher thread to return from the publisher object’s start method

The Publisher Thread

The publisher thread is the thread on which the publisher methods are called

The publisher thread spends most of its time in the publisher object’s start method

When an application change is detected, the publisher object calls the DirXML engine to inform the engine of the event using an object passed to the start method

Driver Life Cycle

There are two separate modes of operations that a driver object must support:

Normal synchronization

Schema query

A single driver instance will only be required to operate in a single mode.

Each time a driver is run, a new instance is obtained.

Multiple instances of the same driver may run on a single DirXML server

The driver should have no modifiable global or static data - may prevent driver from operating properly when restarted or when multiple instances are running on the same server

Driver Language

C++

Java

Java Considerations

Packages

DirXML - com.novell.nds.dirxml.driver

XML/XSL - com.novell.xml

Standard DOM and SAX bindings - org.w3c.dom and org.xml.sax

Jars

dirxml.jar and nxsl.jar

J2SE

Compile against JDK version 1.1.7b for support on NetWare® (no Java 2 features)

Otherwise compile against J2SE1.3

Deployment

Although in IDM2, a new jar may be added without shutting down eDirectory, you will still need to shut down eDirectory to update an existing jar file

Exercises

Getting Started

Novell provides a "skeleton" driver as a place to start writing a driver

The skeleton driver is implemented in both Java and C++ and has implementations using both DOM and the XDS Library for parsing

Comes as part of the NDK

Provides some plumbing code

*For instructional purposes, we will be using a slightly different driver than the skeleton driver for this class

HRFileSystem
The Application

FileHRSystem

FileHRSystem is a simple mockup of a HR application

It records various attributes on employees

It has a simplistic API for events and data manipulation

The aim is to concentrate on writing the driver and not worry too much about the application

FileHRSystem

Objects and Attributes

There is only one object type, that is Employee

Attributes are:

First Name, Last Name (required)

Location, Phone Number, Department, Job Function, Supervisor (optional)

Employee Number, eMail Address (non editable in the application)

Objects and Attributes

Given Name and Surname are naming attributes

Internally

EmployeeName = <Given Name> + <Surname>

eMail Address is another unique key (see JavaDocs)

The application as a flat namespace

Data

The employees are stored on the filesystem in the data directory (see configuration)

The employee data file naming convention is: <EmployeeName>.hrf

Events

Each employee has an associated event log stored on the filesystem in the log directory (see configuration)

The employee log file naming convention is: <EmployeeName>.chg

Monitored events consist of ADD, MODIFY and EXPIRE

Configuration

The location of the data and log files is configured via the application, as is the configuration file

Configuration

The configuration file gives the range of values for the pull down menus

Schema

The schema for FileHRSystem is non variant (it doesn't change)

There is no functionality in the API to report this schema

HRFileSystem
Writing the Driver

Exercise 1

Create a
Bare-Bones-Do-Nothing Driver

Implement the following interfaces

com.novell.nds.dirxml.driver.DriverShim;

com.novell.nds.dirxml.driver. PublicationShim

com.novell.nds.dirxml.driver. SubscriptionShim

Most of the methods at this stage will contain a simple call that returns the document created by CommonImpl’s CreateSuccessDocument() method (with a few exceptions)

Driver Shim

Package

com.novell.dirxml.driver.hrdirxml.stage1

Class

Access modifier

Public

Name

HRFileDriverShim

Superclass

CommonImpl

Interfaces

DriverShim

Constructor

No args

Call to super class with name of this object

super(“HRFileDriverShim”);

DriverShim…cont.

init(XmlDocument arg0) method

Instantiate the other two objects

HRFileSubscriptionShim

HRFilePublicationShim

Return a ‘Success’ document to engine

getSchema(XmlDocument arg0) method

Return a ‘Success’ document to engine

We will implement this method later

getPublicationShim

Return the reference instantiated in the init method

getSubscriptionShim

Return the reference instantiated in the init method

shutdown(XmlDocument arg0) method

Call to publication method that will stop the driver

publicationShim.stop()

Return a ‘Success’ document to engine

SubscriptionShim

Package

com.novell.dirxml.driver.hrdirxml.stage1

Class

Access modifier

public

Name

HRFileSubscriptionShim

Superclass

CommonImpl

Interfaces

SubscriptionShim

Constructor

No args

Call to super class with name of this object

super(“HRFileSubscription”);

SubscriptionShim…cont.

init(XmlDocument arg0) method

Return a ‘Success’ document to the DirXML engine

execute( XmlDocument arg0,

XmlQueryProcessor arg1 )

Return a ‘Success’ document to the DirXML engine

This method will be more completely implemented in another exercise.

PublicationShim

Package

com.novell.dirxml.driver.hrdirxml.stage1

Class

Access modifier

public

Name

HRFilePublicationShim

Superclass

CommonImpl

Interfaces

PublicationShim

Constructor

No args

Call to super class with name of this object

super(“HRFilePublication”);

PublicationShim…cont.

init(XmlDocument arg0) method

Return a ‘Success’ document to the DirXML engine

start( XmlCommandProcessor arg0 )

Implement some looping logic that will run until signaled to stop by the engine

while ( shutdown == false ) {

try {

synchronized ( semaphore ) { semaphore.wait(1000);}

catch(…){}

}

Return a ‘Success’ document to the DirXML engine

This method will be more completely implemented in another exercise.

stop

Method that can be called to signal the semaphore in the start method

Do the Exercise Now

Create source for Driver

Build driver

Copy driver to c:\novell\nds\lib

Create eDirectory objects needed for this driver

Driver Object

Publisher Object

Subscriber Object

Start/Test driver

At this point, to be successful all the driver does is start and run until it is stopped.

Exercise 2

Driver Configuration

DirXML engine provides a mechanism to define driver-specific configuration parameters.

Parameters are defined within an XML file that is validated to the NDS.dtd

<!ELEMENT <driver-config> (	driver-options?,

subscriber-options?,

publisher-options?) >

Parameters are set from within iManager

The ‘display-name’ attribute is used as the label on the entry field within the management tool.

Driver Configuration example

<?xml version=“1.0” encoding=“UTF-8” ?>

<driver-config name=“Java Skeleton Driver”>

<driver-options>

<option-1 display-name=“Sample String option”>Some Default Value</option-1>

<option-2 display-name=“Sample int option”>10</option-2>

</driver-options>

<subscriber-options>

<sub-option-1 display-name=“Sample Subscriber Option”/> <!– No default 

</subscriber-options>

<publisher-options>

<pub-opt-1 display-name=“Sample Publisher Option”>Some default</pub-opt-1>

</publisher-options>

</driver-config>

Driver State

Provides a mechanism for DirXML driver to save state information between invocations.

State may be saved separately for Driver, Subscriber, and Publisher objects.

State info is passed to the object’s init method as part of initialization parameters document.

Elements used:

<!ELEMENT init-params (…, driver-state?,

publisher-state?,

subscriber-state?) >

<!ELEMENT driver-state ANY>

<!ELEMENT publisher-state ANY>

<!ELEMENT subscriber-state ANY>

Driver State cont.

Content of these elements can be anything that makes sense for your driver.

State for all three elements can be written on the subscriber channel in an <output> document.

State for Publisher channel can also be written on the publisher channel in an <input> document.

Driver State example

<nds dtdversion=“1.1” ndsversion=“8.6”>

<output>

<init-params>

<driver-state>

<some-state>Some value</some-state>

</driver-state>

</init-params>

</output>

</nds>

Adding State and Configuration Parameters

In the DriverShim init() method add the following state values

A run count

This should increment each time the init method is run and it will be a tally of how many times this driver has been started

Time stamp

This will give a time stamp indicating when the driver was last started

Use the following helper methods from CommonImpl (replace the createSuccessDocument() method.

Element output = createOutputDocument();

addState( output, “driver-state”, dateElementName*, derivedDateString*);

addState( output, “driver-state”, runCountElementName*, runCount* );

addStatusElement( output, STATUS_SUCCESS, null, null );

return new XmlDocument( output.getOwnerDocument() );

*variables defined within your code

Reading state value

Following is an example of how the current runCount state may be read by DriverShim code

From within the init() method:

String sRunCount = getStateInfo( runCountElementName,

(Element)arg0.getDocument().getElementsByTagName(“input”).item(0));

Add the following method:

public String getStateInfo( String stateElementName, Element inputElement )

{

Element returnElement = inputElement.getElementsByTagName(stateElementName).item(0);

if ( returnElement == null )

return null;

Node configTextNode = returnElement.getFirstChild();

return configTextNode.getNodeValue();

}

In the DriverShim init() method add the following configuration values

dbDirectoryPath

statusDirectoryPath

Use the following CommonImpl helper method to retrieve these configuration values.

driverParams = getShimParams( arg0*.getDocument(), “driver”, paramValues** );

Modify the Subscriber and Publisher constructors to received and store these ‘driverParams’

*Argument passed into init() method

**ShimParamDesc array

Adding State and Configuration Parameters (cont.)

Do the Exercise Now

Modify DriverShim init() method

Read configuration values

Read and set state values

Pass configuration values into Publisher and Subscriber constructors

Build an <output> document with appropriate elements rather than just a success document

Update Publisher and Subscriber constructors to accept configuration parameters

Add getStateInfo method

Build Driver and copy to c:\novell\nds\lib

Stop and Restart eDirectory

Start/test the driver

Exercise 3

Getting the Application Schema

getShema interface method

Returns an XML document that defines the schema of the application

DirXML engine calls the getShema method

The first time the driver is run

When the administrator explicitly (via ConsoleOne or iManager) invokes a getSchema query.

Runs on a dedicated instance of the driver object

If driver is already currently running, it is temporarily stopped to fulfill this request and is then restarted again.

The “initParameters” that are passed in are the same parameters that are sent to the driver on initialization

Variant vs. non-Variant Schemas

Variant

If the application has a modifiable schema the driver should query the application within the getSchema call to retrieve the most up-to-date version of the schema

Non-Variant

If the application schema does not change it may be appropriate to place a serialized representation of the schema in the driver that the getSchema method can return to the DirXML engine.

Schema XML Document

<!ELEMENT schema-def (class-def)*>

<!ATTLIST schema-def

hierarchical (%Boolean;) “true”

application-name CDATA #IMPLIED

<!ELEMENT class-def (attr-def)*>

<!ATTLIST class-def

class-name CDATA #REQUIRED

asn1id CDATA #IMPLIED

container (%Boolean;) “false”

<!ELEMENT attr-def EMPTY>

<!ATTLIST attr-def

Attr-name CDATA #REQUIRED

Asn1id CDATA #IMPLLED

Type (%Attr-type;) “string”

Required (%Boolean;) “false”

Naming (%Boolean;) “false

Multi-valued (%Boolean;) “true”

Case-sensitive (%Boolean;) “false”

Read-only (%Boolean;) “false”

Implement getShema method

We have an invariant schema for this application with the following class and attributes

Class

Employee (Not hierarchical)

Attributes (non default values)

First Name – ( multi-valued – false, naming – true, required - true )

Last Name – ( multi-valued – false, naming – true required – true )

Location – ( multi-valued – false )

Department – ( multi-valued – false, required – true )

Job Function – ( multi-valued – false )

Phone Number – ( multi-valued – false )

eMail Address – ( multi-valued – false )

Is Supervisor – ( multi-valued – false )

Employee Number – ( multi-valued – false )

Supervisor – ( multi-valued – false )

Do the Exercise Now

Implement the getSchema method

Create a string containing an XML document with the schema defined on the previous slide

Create an XML document:

XmlDocument fileHRSchemaXMLDoc = new XmlDocument( fileHRSchemaStr* );

Return the fileHRSchemaStr* variable to the DirXML engine

Using iManager, map the application attributes to the appropriate eDirectory attributes

* String containing the schema XML document

Exercise 4

XMLQueryProcessor interface

Developer provided interface to allow NDS® to query the application

All queries are XML documents

NDS

APP

XML Query Processor Interface

This is a required interface

Method

query

Do the Exercise Now

FileHRMisc

Class that contains “API’s” to access the HRFileSystem data.

Use this class to check for updates to the application

org.w3c.dom.*;

Use this class package along with CommonImpl to create XDS documents to be sent to the DirXML engine

Events

Use FileHRMisc.CheckForApplicationUpdate() to determine if a change has occurred in the application.

If a change has occurred then an XDS document needs to be sent to the DirXML engine

Use FileHRMisc.GetEmployeeEvents() to get a vector containing the application changes.

Exercise 5

XMLCommandProcessor Interface

DirXML provided interface

Subscriber uses this interface to query NDS

NDS

APP

XML Command Processor Interface

Executes an XDS-encoded command and returns an XDS-encoded result

NDS sends events to the subscriber shim for processing

Publisher shim sends events to NDS

One method

execute

Do the Exercise Now

Exporting DirXML Driver

Export from within iManager tool

Use <variable-decl> and <text-var> elements to supply prompts during installation of your driver in management wizard

General Disclaimer

This document is not to be construed as a promise by any participating company to develop, deliver, or market a product. Novell, Inc., makes no representations or warranties with respect to the contents of this document, and specifically disclaims any express or implied warranties of merchantability or fitness for any particular purpose. Further, Novell, Inc., reserves the right to revise this document and to make changes to its content, at any time, without obligation to notify any person or entity of such revisions or changes. All Novell marks referenced in this presentation are trademarks or registered trademarks of Novell, Inc. in the United States and other countries. All third-party trademarks are the property of their respective owners.

No part of this work may be practiced, performed, copied, distributed, revised, modified, translated, abridged, condensed, expanded, collected, or adapted without the prior written consent of Novell, Inc. Any use or exploitation of this work without authorization could subject the perpetrator to criminal and civil liability.

This means that no work is lost with either the Novell Nsure UDDI corporate or testing solution.

Enterprises that build their UDDI solutions with Novell Nsure UDDI Server, are not only leveraging the deep experience Novell Identity Management foundation brings to the standard, they are securing their own future by building on an open standard implementation that will grow and scale with their corporate needs.

2003-12-08T12:43:39