The Solution
Fortunately for us, there did exist a Connector which could handle our situation. It’s a custom developed Connector that works not only CSV format, but XML format (great!) and XLS as well. It’s the Generic File Driver, and it’s available for download from the NetIQ Cool Solutions web site here.
We have got a working example Driver coded for you already, and the Generic_File_Driver.xml Driver code can be freely downloaded. If you would like to arrange a call with Belkast to discuss your own requirements, please use our Contact Us form, email us at keith@belkast.com, or telephone us on +44.751.445.9728.
When processing a file, the most important configuration setting on the Driver is XMLFileReader: xsl to apply prior to processing the XML file (leave empty for no pre-processing). You might have figured out what this configuration setting does: it applies an XSLT StyleSheet to the import file before the file is processed by the Driver SHIM.
Installing the Driver
Once the Driver file has been downloaded from the Cool Solutions site, if you want to start from scratch and import a custom format XML file, you will need to:
- [External] Stop eDirectory, copy the SHIM JAR file to the Identity Manager server, and restart eDirectory
- [Designer] Import the new SVCGENFILEB_0.0.6.20140508075632.jar package in to Designer
- [Designer] Add the Delimited Text Driver to the DriverSet and select the Generic File Base package
- [Designer] Answer all the presented questions as needed
- [Designer] Deploy the Driver
- [Designer or iManager] Change the GCVs as shown in the table below
- [External] Write an XSLT StyleSheet to match up with your XML input document
Global Configuration Values
Shown below are the Global Configuration Values which are set on the working example Driver.
Global Configuration Value | Configured Setting |
---|---|
Field Name (Field1,Field2,Field3) | FirstName, EmailAddress, LastName, Id, Status, AccountType, ValidFrom, ValidTo, ManagerId, CompanyCode, JobId, DepartmentId, class_type, member, System, timestamp, GroupName |
Object Class Name | User |
Association ECMA script | <no value> |
Src-dn ECMA script | <no value> |
ECMA script field identifiers processing | NoProcessing |
Include ECMA libraries in ECMA evaluation | FALSE |
Heartbeat interval (minutes) | 1 |
Enable publisher channel | TRUE |
File Locator Strategy | RegExpFileLocator |
Source folder for files | /installs/idm/input |
Regular expression for matching files | LTGT_FULL.*$ |
File Sorter Strategy | FilePropertySorter |
File sort method | getName |
Sort ascending (true/false) | FALSE |
File Reader Strategy | XMLFileReader |
Use the tag names from the XML document (true) or use the driver schema given (false) | TRUE |
Pre-xslt | <the actual XSLT StyleSheet> |
File encoding | UTF-8 |
Polling interval (seconds) | 20 |
List of meta data elements that should be added | <no value> |
Temporary work folder | /installs/idm/work |
Generated command | Add (default) |
File Removal Strategy | Do not remove |
Example XML input file
Shown below is an example input file, and as you can see the file is not a Delimited Text file.
Pre-processor XSLT StyleSheet
The XSLT StyleSheet which we used to import the file is shown below. You can test whether the XSLT will work against an input file using the bash script referenced here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:variable name="varUserStart" select="'cn='"/> <xsl:variable name="varDelimiter" select="'##'"/> <xsl:variable name="varGroupMemberAttrName" select="'member'"/> <xsl:variable name="varClassTypeAttr" select="'class_type'"/> <xsl:variable name="varUserTag" select="'user'"/> <xsl:variable name="varGroupTag" select="'group'"/> <xsl:template match="root"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="users/user"> <record> <!-- Add the attribute information as new nodes --> <!-- Cycle around the @ tags, add a <name()> tag in to the XML --> <xsl:for-each select="@*"> <xsl:variable name="varAttrName" select="name()" /> <!-- The <xsl:element> code actually writes the node --> <xsl:element name="{$varAttrName}"> <xsl:value-of select="."/> </xsl:element> </xsl:for-each> <!-- Now we add the 'class_tpye' node so we can use it later --> <xsl:element name="{$varClassTypeAttr}"> <xsl:value-of select="$varUserTag"/> </xsl:element> </record> </xsl:template> <xsl:template match="groups/group"> <record> <!-- Add the attribute information as new nodes --> <xsl:for-each select="@*"> <xsl:variable name="varAttrName" select="name()" /> <!-- The <xsl:element> code actually writes the node --> <xsl:element name="{$varAttrName}"> <xsl:value-of select="."/> </xsl:element> </xsl:for-each> <!-- Now we add the 'class_tpye' node so we can use it later --> <xsl:element name="{$varClassTypeAttr}"> <xsl:value-of select="$varGroupTag"/> </xsl:element> <!-- If there is more than one 'member' node, concatenate them all --> <xsl:choose> <xsl:when test="count(./member) > 0"> <!-- Now just add in a tag with the name of the attribute --> <xsl:element name="{$varGroupMemberAttrName}"> <xsl:variable name="varValueGood"> <xsl:for-each select="./member"> <xsl:variable name="varValueTemp" select="./text()" /> <xsl:value-of select="concat($varDelimiter, $varValueTemp)"/> </xsl:for-each> </xsl:variable> <!-- Add in the actual value, remembering to add the delimeter --> <xsl:value-of select="substring-after($varValueGood, $varDelimiter)"/> </xsl:element> </xsl:when> <!-- We do not need to do anything - we do not have any 'members' --> <xsl:otherwise/> </xsl:choose> </record> </xsl:template> <xsl:template match="node()|@*"> <xsl:apply-templates select="@*|node()"/> </xsl:template> </xsl:stylesheet> |
XDS document processed by SHIM
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
<?xml version="1.0" encoding="UTF-8"?> <users> <user> <attr attr-name="id"> <value>AA11BB</value> </attr> <attr attr-name="accountType"> <value>primary</value> </attr> <attr attr-name="firstName"> <value>Joe</value> </attr> <attr attr-name="lastName"> <value>Bloggs</value> </attr> <attr attr-name="emailAddress"> <value>joe.bloggs@belkast.com</value> </attr> <attr attr-name="status"> <value>active</value> </attr> <attr attr-name="jobId"> <value>900101</value> </attr> <attr attr-name="departmentId"> <value>300067</value> </attr> <attr attr-name="validFrom"> <value>2002-09-24</value> </attr> <attr attr-name="validTo"> <value>9999-12-31</value> </attr> <attr attr-name="managerId"> <value>AA11BB</value> </attr> <attr attr-name="companyCode"> <value>I59</value> </attr> </user> <user> <attr attr-name="id"> <value>CC22DD</value> </attr> <attr attr-name="accountType"> <value>primary</value> </attr> <attr attr-name="firstName"> <value>Jane</value> </attr> <attr attr-name="lastName"> <value>Jeffers</value> </attr> <attr attr-name="emailAddress"> <value>jane.jeffers@belkast.com</value> </attr> <attr attr-name="status"> <value>active</value> </attr> <attr attr-name="jobId"> <value>900101</value> </attr> <attr attr-name="departmentId"> <value>300067</value> </attr> <attr attr-name="validFrom"> <value>2010-02-03</value> </attr><attr attr-name="validTo"> <value>2013-12-15</value> </attr> <attr attr-name="managerId"> <value>AA11BB</value> </attr> <attr attr-name="companyCode"> <value>I58</value> </attr> </user> </users> <groups> <group> <attr attr-name="id"> <value>KDFJ9889JD</value> </attr> <attr attr-name="name"> <value>Easyweb-USL-48-3</value> </attr> <attr attr-name="system"> <value>INSIM</value> </attr> <attr attr-name="Member"> <value>AA11BB</value> <value>CC22DD</value> </attr> </group> <group> <attr attr-name="id"> <value>KDFJ9889JD</value> </attr> <attr attr-name="name"> <value>Easyweb-USL-48-3</value> </attr> <attr attr-name="system"> <value>EDS</value> </attr> <attr attr-name="Member"> <value>AA11BB</value> </attr> </group> </groups> |