SPML Version 2 (SPMLv2) defines a core protocol [SPMLv2] over which different data models can be used to define the actual provisioning data. The combination of a data model with the SPML core specification is referred to as a profile. The use of SPML requires that a specific profile is used, although the choice of which profile is used to negotiated out-of-band by the participating parties.
The DSML v2 protocol [DSMLV2] was designed to perform LDAP type operations using web services. The DSML V2 protocol defines synchronous request/response semantics and a data model based on attribute/value pairs. DSML V2 does not define an attribute/value pairs schema mechanism.
The SPMLv2 Parser supports the SPMLv2 DSMLv2 Profile. It is a TDI Parser component that parses and creates SPMLv2 messages, that is, it is intended to parse individual SPMLv2 requests and responses or write SPMLv2 requests and responses.
The SPMLv2 Parser supports core operations as specified in the "(SPML) v2 - DSML v2 Profile" specification. Explicit TDI Entry schemas are defined for each of the supported operations.
The Parser extends the XML Parser and has the ability to read enormous requests/responses without creating all the SPML messages in the memory. In addition, it has been implemented on top of the OpenSPML 2.0 Toolkit.
The Parser is capable of reading/writing Batch messages. The following types from the toolkit have been used:
org.openspml.v2.msg.spmlbatch.BatchRequest; org.openspml.v2.msg.spmlbatch.BatchResponse;
On each readEntry call the Parser will return an Entry representing the individual request(s) or response(s) contained in the batch message. On writeEntry the Parser will write individual request(s) or response(s) inside the appropriate batch message.
This component is not available in the TDI 7.1 General Purpose Edition.
A conformant provider must implement all the operations defined in the Core XSD. The following are the core operations:
The Parser also supports Search operations:
Entries with the following structure are parsed (on read) and created (on write) by the Parser for Add Requests:
Attribute | Value |
---|---|
spml.operation | set to Add |
spml.operation.type | set to Request |
spml.containerID | set to the ID attribute's value of a containerID element if it is present as a subelement of the addRequest element. |
spml.containerID.targetID | set to the ID attribute's value if a targetID attribute is present in the containerID element. |
spml.requestID | a reasonably unique value that identifies each outstanding request. |
Additionally, for each DSML attr element: an attribute named as the "name" XML attribute of the DSML "attr" element and as value(s) specified for the "attr" DSML element.
Entries with the following structure are parsed (on read) and created (on write) by the Parser for Add Response:
Attribute | Value |
---|---|
spml.operation | set to Add |
spml.operation.type | set to Response |
spml.psoID | set to the ID attribute's value of the "psoID" element if a "psoID" element is available in the response. |
spml.pso.targetID | set to the targetID attribute's value of the psoID element if the provider supports more than one target. |
spml.requestID | reasonably unique value that identifies each outstanding request. |
spml.errorCode | created if the add request has failed. The value of this must characterize the failure. |
spml.status | holds the status attribute's value of the AddResponse element. |
spml.errorMessages | an array of string objects that provides additional information about the status or failure of the requested operation. |
One important thing to mention is that the modify operation may change the identifier of the modified object.
Entries with the following structure are parsed (on read) and created (on write) by the Parser for Modify Requests:
Attribute | Value |
---|---|
spml.operation | set to Modify |
spml.operation.type | set to Request |
spml.psoID | set to the ID attribute's value. The Modify Request must always contain a <psoID> element that identifies an object that exists on a target, exposed by the provider. |
spml.pso.targetID | this attribute may not be specified if the provider supports only one target. |
spml.requestID | a reasonably unique value that identifies each outstanding request. |
In addition, for each modification item: an attribute named as the "name" XML attribute of the DSML "modification" element, with the values specified for the "modification" DSML element and TDI attribute's operation set as the "operation" XML attribute of the DSML "modification" element.
Entries with the following structure are parsed (on read) and created (on write) by the Parser for Modify Responses:
Attribute | Value |
---|---|
spml.operation | set to Modify |
spml.operation.type | set to Response |
spml.psoID | If the provider successfully modified the requested object, the <modifyResponse> must contain a <pso> element. The <pso> contains the subset of (the XML representation of) a requested object that the "returnData" attribute of the <modifyRequest> specified. |
spml.pso.targetID | this attribute may not be specified if the provider supports only one target. |
spml.status | the status attribute's value of the ModifyResponse element |
spml.errorCode | created if the request has failed. The value of this must characterize the failure. This attribute may have one of predefined values by the SPML specification. |
spml.errorMessages | an array of string objects that provides additional information about the status or failure of the requested operation. This attribute is optional. |
spml.requestID | reasonably unique value that identifies each outstanding request. |
Entries with the following structure are parsed (on read) and created (on write) by the Parser for Delete Requests:
Attribute | Value |
---|---|
spml.operation | set to Delete |
spml.operation.type | set to Request |
spml.psoID | set to the ID attribute' value of the <psoID> element. The Delete Request must always contain the PSO Identifier. |
spml.pso.targetID | attribute may not be specified if the provider supports only one target. |
spml.requestID | a reasonably unique value that identifies each outstanding request. |
Entries with the following structure are parsed (on read) and created (on write) by the Parser for Delete Responses:
Attribute | Value |
---|---|
spml.operation | set to Delete |
spml.operation.type | set to Response |
spml.errorCode | created if the request has failed. The value of this must characterize the failure. This attribute may have one of predefined values by the SPML specification. |
spml.status | holds the status attribute's value of the DeleteResponse element. |
spml.errorMessages | an array of string objects that provides additional information about the status or failure of the requested operation. This attribute is optional. |
spml.requestID | a reasonably unique value that identifies each outstanding request. |
Entries with the following structure are parsed (on read) and created (on write) by the Parser for Lookup Requests:
Attribute | Value |
---|---|
spml.operation | set to Lookup |
spml.operation.type | set to Request |
spml.psoID | set to the ID attribute's value of the <psoID> element. The Lookup Request must always specify PSO identifier. |
spml.pso.targetID | attribute may not be specified if the provider supports only one target. |
spml.requestID | a reasonably unique value that identifies each outstanding request. |
Entries with the following structure are parsed (on read) and created (on write) by the Parser for Lookup Response:
Attribute | Value |
---|---|
spml.operation | set to Lookup |
spml.operation.type | set to Response |
spml.psoID | set to the ID attribute's value of the <psoID> element. |
spml.pso.targetID | equal to the "targetID" attribute of the <psoID> element. It may be not specified if the provider supports only one target. |
spml.status | holds the status attribute's value of the LookupResponse element |
spml.requestID | a reasonably unique value for the "requestID" attribute in each request. A "requestID" value need not be globally unique. A "requestID" needs only be sufficiently unique to identify each outstanding request. |
spml.errorMessage | an array of string objects that provides additional information about the status or failure of the requested operation. This attribute is optional. |
Entries with the following structure are parsed (on read) and created (on write) by the Parser for Search Requests:
Attribute | Value |
---|---|
spml.operation | set to Search |
spml.operation.type | set to Request |
spml.scope | search scope |
spml.containerID | contains value of the ID attribute of the "basePsoID" element of the Search Request |
spml.containerID.targetID | contains value of the targetID attribute of the "basePsoID" element of the Search Request |
spml.attributeDescription | multi-valued Attribute whose String values hold the names of the attributes listed in the "attributes" element of the Search Request. |
spml.filter.substrings.name | contains the value of the Name of the Filter Substrings element |
spml.filter.substrings.initial | the value of the Initial element of the Filter Substrings element |
spml.filter.substrings.any | multi-valued Attribute which contains the values of the Any element of the Filter Substrings element |
spml.filter.substrings.final | contains the value of the Final of the Filter Substrings element |
spml.filter | contains the value of the Filter element as a hierarchical Attribute object; this uses v7.0 hierarchical objects |
See Search Filter capabilities for a more thorough discussion of search filters.
Entries with the following structure are parsed (on read) and created (on write) by the Parser for Search Responses:
Attribute | Value |
---|---|
spml.operation | set to Search |
spml.operation.type | set to Response |
spml.resultEntries | a multi valued attribute, each of its values is an Entry whose attributes correspond to the "<spml:data>\attr" elements of the individual "<spml:pso>" element. |
spml.errorCode | created if the request has failed. The value of this must characterize the failure. This attribute may have one of predefined values by the SPML specification. |
spml.status | holds the status attribute's value of the SearchResponse element. |
spml.errorMessages | an array of string objects that provides additional information about the status or failure of the requested operation. This attribute is optional. |
spml.requestID | a reasonably unique value that identifies each outstanding request. |
When parsing SPML messages, attributes tagged as binary by the Binary Attributes Parser parameter are Base64 decoded, that is, the string value from the SPML message is Base64 decoded to Java byte array.
When creating SPML messages, all Attributes whose value is Java byte array are Base64 encoded to String before being written in the SPML message.
If when creating a SPML message an Attribute is passed whose value's type is neither String, nor Java byte array, the value is converted to String by calling the object's toString() method and this String value is stored in the SPML message.
The SPMLv2 Parser handles the different modification operations
by tagging the Entry attributes according to the dsml:modification operation
attribute value in the SPMLv2 document.
For example, when reading the following SPML structure:
If you parse this SPML extract into an Entry we will have to map
three Attributes named "member", "member2 " and "member3"; each one
will be tagged with the according operation (that is, delete, add
, replace). The value of the modification operation can also be accessed
via script:
When parsing an Entry to a SPML document the attribute will be
tagged with the attribute operation provided in the work Entry. If
this modification operation is not set, the default is used - "replace".
Alternatively we can set it manually via script:
In earlier versions of TDI, the SPMLv2 Parser supported the Substrings
Filter element only in Search requests and used the following attributes:
spml.filter.substrings.name, spml.filter.substrings.initial, spml.filter.substrings.final
and spml.filter.substrings.any to contain the Substrings subelements
values.
The current version of the SPMLv2 Parser can parse the other filtering
features provided by DSMLv2:
When reading a Filter element, the parser creates a corresponding
hierarchical Attribute named "spml.filter". For every filter item
a separate Attribute object is created and appended as a child; correspondingly, for every subelement or another filter item contained in a filter
item separate Attributes are created and added as its children.
According to the DSMLv2 schema the not element
can contain only one filter item.
The following attributes: spml.filter.substrings.name, spml.filter.substrings.initial, spml.filter.substrings.final and spml.filter.substrings.any are created
only when the Filter element contains a single Substrings element;
otherwise a spml.filter hierarchical attribute is created.
Limitation: When reading the SPMLv2 Parser
cannot read the matchingRule and dnAttributes (always has default
value of false) attributes of the extensibleMatch element. This is
caused by the underlying Open SPML 2.0 library that tries to read
the matchingRule and dnAttributes as values instead of attributes.
However when writing these attributes are written correctly.
When writing, if a smpl.filter attribute is present in the provided
entry it is used and spml.filter.substrings.name, spml.filter.substrings.initial, spml.filter.substrings.final and spml.filter.substrings.any attributes
are ignored. If a smpl.filter attribute is not present the spml.filter.*
attributes are used (backward compatibility).
Here is an example hierarchical spml.filter attribute and the corresponding
XML generated from it:
'"and": { The Parser needs the following configuration parameters:
This parameter has the following default list of
attributes that we can change: photo, personalSignature, audio, jpegPhoto, javaSerializedData, thumbnailPhoto, thumbnailLogo, userPassword, userCertificate, authorityRevocationList, certificateRevocationList, crossCertificatePair, x500UniqueIdentifier, objectGUID, objectSid.
Examples of how to use this Parser have been provided in the TDI_install_dir/examples/SPMLv2Parser directory.
<modifyRequest xmlns='urn:oasis:names:tc:SPML:2:0' returnData='everything'>
<psoID ID='CN=DnsUpdateProxy,OU=Groups,DC=2k3,DC=dom'/>
<modification>
<dsml:modification xmlns:dsml='urn:oasis:names:tc:DSML:2:0:core' name='member' operation='delete'>
<dsml:value>CN=Eric Clapton,CN=Users,DC=2k3,DC=dom</dsml:value>
</dsml:modification>
<dsml:modification xmlns:dsml='urn:oasis:names:tc:DSML:2:0:core' name='member2' operation='add'>
<dsml:value>CN=Eric Adams,CN=Users,DC=2k3,DC=dom</dsml:value>
</dsml:modification>
<dsml:modification xmlns:dsml='urn:oasis:names:tc:DSML:2:0:core' name='member3' operation='replace'>
<dsml:value>CN=Joey DeMaio,CN=Users,DC=2k3,DC=dom</dsml:value>
</dsml:modification>
</modification>
</modifyRequest>
work.getAttribute("member").getOperation();
work.getAttribute("member").setOperation("add");
Search Filter capabilities
Reading
Writing
Table 65. Hierarchical spml.filter attribute
spml.filter attribute
Filter element
"or": {
"substrings": {
"name": "cn",
"initial": "J"
},
"not": {
"and": {
"lessOrEqual": {
"name": "roomnumber",
"value": "2000"
},
"greaterOrEqual": {
"name": "roomnumber",
"value": "3000"
}
}
},
"approxMatch": {
"name": "sn",
"value": "Smith"
}
},
"equalityMatch": {
"name": "objectClass",
"value": "inetorgperson"
}
}'
<dsml:filter xmlns:dsml='urn:oasis:names:tc:DSML:2:0:core'>
<dsml:and>
<dsml:or>
<dsml:substrings name='cn'>
<dsml:initial>J</dsml:initial>
</dsml:substrings>
<dsml:not>
<dsml:and>
<dsml:lessOrEqual name='roomnumber'>
<dsml:value>2000</dsml:value>
</dsml:lessOrEqual>
<dsml:greaterOrEqual name='roomnumber'>
<dsml:value>3000</dsml:value>
</dsml:greaterOrEqual>
</dsml:and>
</dsml:not>
<dsml:approxMatch name='sn'>
<dsml:value>Smith</dsml:value>
</dsml:approxMatch>
</dsml:or>
<dsml:equalityMatch name='objectClass'>
<dsml:value>inetorgperson</dsml:value>
</dsml:equalityMatch>
</dsml:and>
</dsml:filter>
Configuration
Example
See also