Oracle Waveset 8.1.1 Web Services

Basic SPML 2.0 Concepts

This section explains some basic concepts about SPML 2.0:

How SPML 2.0 Compares to SPML 1.0

Waveset Web Services support both SPML Version 1.0 and Version 2.0 protocols (open standards for service provisioning using XML) for communication with provisioning systems.


Note –

See Chapter 1, Using SPML 1.0 with Oracle Waveset Web Services for information about using SPML Version 1.0.


SPML 2.0 offers many improvements over SPML 1.0, including the following:

Table 2–1 SPML Capabilities

SPML 1.0 Capabilities 

SPML 2.0 Capabilities 

Add

Add

Modify

Modify

Delete

Delete

Lookup

Lookup

SchemaRequest

ListTargets

Search

Search

ExtendedRequest

 

Captured in “standard” capabilities: 

  • Async – Process requirements asynchronously

  • Batch – Process a batch of requests

  • Bulk – Process modifies or deletes using iteration

  • Password – Change, set, reset, validate, or expire passwords

  • Reference – Refer to PSOs between targets

  • Suspend – Enable or disable PSOs

  • Update – Find change records for objects that have been updated (can also be captured in “custom” capabilities)

How SPML 2.0 Concepts Are Mapped to Waveset

SPML 2.0 uses its own terminology to discuss the objects that are managed by a provisioning system.


Note –

See the OASIS SPML 2.0 specifications at http://www.openspml.org/.


The following sections describe how SPML 2.0 concepts are mapped into Waveset:

Understanding Targets

A target is a logical end point in the server. Every target is named and declares the schema of the objects that it manages. Targets also declare which capabilities (a set of requests) are supported. See Understanding PSOs for more information.

Currently, Waveset supports only one target. You cannot declare multiple targets. You can name this target anything you want, but the data objects’ format must conform to the DSML profile.

A supported target is the one target defined in the spml2.xml file (Configuration:SPML2 object). For example, in ListTargetsRequest Examples, ListTargetResponse returns one target, spml2-DSML-Target.

Understanding PSOs

As mentioned in the previous section, targets manage Provisioning Service Objects (PSOs). A PSO is somewhat analogous to a view in Waveset, but without behavior. Consequently, you can think of a PSO as the data portion of an Waveset view, a User view in particular.


Note –

Waveset only manages Users and requires you to define a user extended attribute called spml2ObjectClass.


For Waveset’s purposes, a PSO is a collection of attributes that are mapped (using a form) to and from a User view. Each object specifies an objectclass attribute that is used to map the object to an objectclass definition in the schema defined for the target.

The objectclass attribute is used to find the following:

Understanding PSOIdentifiers

SPML includes an object ID that is called a PSOIdentifier (PsoID).

OASIS SPML 2.0 specifications recommend that PsoIDs be opaque to a requestor (client). Consequently, Waveset uses repository IDs (repoIDs) as PsoIDs when adding PSOs to the system.

A repoID is distinct and it is not meant for presentation to a user. When displaying a PSO to a user, the requestor should use the equivalent of the waveset.accountid or whatever attributes are used in the Identity template to present the object’s ID.

When identifying the PSO (as in a ModifyRequest), the requestor should use the repoID and not the waveset.accountId. Although the requestor can use the waveset.accountId as a PsoID, doing so is not recommended and it might change in a future release. Requestors should try to keep the PsoID opaque.

PSOs use an objectclass attribute to specify the object type. If this attribute is not present when a request is made, Waveset allows you to specify and use a “default” object class, such as SPMLUser. Internally, the objectclass value is maintained as an spml2ObjectClass attribute for users. For Waveset this attribute must be a user extended attribute. You might not see an spml2ObjectClass attribute for users that existed before you enabled SPML 2.0.

Understanding Open Content and OperationalAttributes

SPML makes heavy use of xsd:any elements in the .xsds file to provide what the specification refers to as Open Content. In SPML, Open Content means that most elements can contain elements of any type. Waveset uses this idea to provide OperationalNVPs (NameValuePairs) and OperationalAttributes that control processing. OperationalNVPs appear as elements in the XML, while OperationalAttributes appear as attributes. See the OpenSPML 2.0 Toolkit at http://www.openspml.org for more information.

You can use one NVP in all requests except ListTargetsRequests, and in all responses. Waveset stores a sessionToken in an OperationalNVPs called session that allows the system to cache sessions on behalf of the user and improves efficiency. For more information about OperationalNVPs and OperationalAttributes, see Supported SPML 2.0 Capabilities.

Supported SPML 2.0 Capabilities

Waveset supports all Core capabilities in the SPML 2.0 specification that use the DSML profile. Waveset also supports some of the optional standard capabilities (such as Batch and Async) and partially supports some standard capabilities (such as Bulk).

This section describes which SPML 2.0 capabilities are supported in Waveset (where Waveset knowingly varies from the specification and profile documents) and which OperationalAttributes are required by Waveset.

The topics in this section include the following:


Note –

Waveset does not support the Reference capability, the Updates capability, or the CapabilityData class.

The CapabilityData class is used to implement custom capabilities. Waveset does not support the CapabilityData class because none of the supported capabilities use this class.

The OpenSPML 2.0 Toolkit supports CapabilityData in the marshallers, unmarshallers, and so forth.


Core Capabilities

Waveset supports the Core capabilities described in the following table.

Table 2–2 Core Capabilities

Capability  

Description  

Caveats  

AddRequest

Adds a specified PSO to the system. 

Waveset officially supports only a single target. 

DeleteRequest

Deletes a specified PSO from the system. 

Waveset officially supports only a single target. 

ListTargetsRequest

Lists the targets that are available through Waveset. 

  • Waveset officially supports a single target.

  • Waveset does not require you to use ListTargets as the first call in a conversation. However, it does allow operationalAttributes on this request to specify a username/password pair for establishing a session with the server. (You can also use Waveset.properties.) In general, it is more efficient to log in and use the session token. Waveset provides a class called SessionAwareSpml2Client for this purpose.

LookupRequest

Finds and returns the attributes of the named PSO. 

None 

ModifyRequest

Modifies specified PSO attributes. 

Due to a discrepancy between the main SPML 2.0 specification and the DSML Profile specification, Waveset does not support select, component, and so forth. Instead Waveset uses DSML Modification Mode and elements according to the DSML Profile.


Note –

General caveats include the following:

AddRequest and ListTargetsRequest examples follow.


Core Capability Examples

This section provides several Java, XML, and JSP examples.

The following examples adds a user with several attributes. The first example returns all data, while the second returns only the identifier.


Example 2–1 Example AddRequest

// ReturnData.EVERYTHING example
SessionAwareSpml2Client client = new SessionAwareSpml2Client("http://example.com:8080/
idm/servlet/openspml2");
ListTargetsResponse loginInfo = client.login("Configurator", "configurator");

AddRequest req = new AddRequest();
req.setReturnData(ReturnData.EVERYTHING);
Extensible attrs = new Extensible();
attrs.addOpenContentElement(new DSMLAttr("objectclass", "spml2Person"));
attrs.addOpenContentElement(new DSMLAttr("accountId", "sempiricus"));
attrs.addOpenContentElement(new DSMLAttr("credentials", "password"));
attrs.addOpenContentElement(new DSMLAttr("firstname", "Sextus"));
attrs.addOpenContentElement(new DSMLAttr("lastname", "Empiricus"));
req.setData(attrs);

AddResponse res = (AddResponse) client.request(req);
if (res.getStatus().equals(StatusCode.SUCCESS)) {
    System.out.println("Received positive add response.");
}

PSO pso = res.getPso();
System.out.println("PSO ID: " + pso.getPsoID().getID());
Extensible psoData = pso.getData();
for (OpenContentElement oce : psoData.getOpenContentElements()) {
    if (oce instanceof DSMLAttr) {
        DSMLAttr attr = (DSMLAttr) oce;
        System.out.println(attr.getName() + ": " + attr.getValues()[0].getValue());
    }
}

// ReturnData.IDENTIFIER example
SessionAwareSpml2Client client = new SessionAwareSpml2Client("http://example.com:8080/
idm/servlet/openspml2");
ListTargetsResponse loginInfo = client.login("Configurator", "configurator");

AddRequest req = new AddRequest();
req.setReturnData(ReturnData.IDENTIFIER);
Extensible attrs = new Extensible();
attrs.addOpenContentElement(new DSMLAttr("objectclass", "spml2Person"));
attrs.addOpenContentElement(new DSMLAttr("accountId", "catullus"));
attrs.addOpenContentElement(new DSMLAttr("credentials", "password"));
attrs.addOpenContentElement(new DSMLAttr("firstname", "Gaius"));
attrs.addOpenContentElement(new DSMLAttr("lastname", "Catullus"));
req.setData(attrs);

AddResponse res = (AddResponse) client.request(req);
if (res.getStatus().equals(StatusCode.SUCCESS)) {
    System.out.println("Received positive add response.");
}

PSO pso = res.getPso();
System.out.println("PSO ID: " + pso.getPsoID().getID());
Extensible psoData = pso.getData();
if (psoData == null) {
    System.out.println("PSO contains no data, as expected.");
}

The following example shows an account lookup.


Example 2–2 Example LookupRequest

// Lookup example
SessionAwareSpml2Client client = new 
     SessionAwareSpml2Client("http://example.com:8080/idm/servlet/openspml2");
ListTargetsResponse loginInfo = client.login("Configurator", "configurator");

PSOIdentifier psoId = new PSOIdentifier("maurelius", null, null);

LookupRequest req = new LookupRequest();
req.setPsoID(psoId);
req.setExecutionMode(ExecutionMode.SYNCHRONOUS);

try {
    LookupResponse res = (LookupResponse) client.request(req);
    if (res.getStatus().equals(StatusCode.SUCCESS)) {
        System.out.println("Performed account lookup.");
    }
    PSO pso = res.getPso();
} catch (Spml2ExceptionWithResponse e) {
    System.out.println("Lookup failed: " + e.getMessage());
    LookupResponse res = (LookupResponse) e.getResponse();
}

The following example changes the lastname parameter to Antoninus.


Example 2–3 Example ModifyRequest

SessionAwareSpml2Client client = new 
     SessionAwareSpml2Client("http://example.com:8080/idm/servlet/openspml2");
ListTargetsResponse loginInfo = client.login("Configurator", "configurator");

PSOIdentifier psoId = new PSOIdentifier("maurelius", null, null);

ModifyRequest req = new ModifyRequest();
req.setPsoID(psoId);
Modification modification = new Modification();
modification.addOpenContentElement(new DSMLModification("lastname", "Antoninus", 
                                                        ModificationMode.REPLACE));
req.addModification(modification);

ModifyResponse res = (ModifyResponse) client.request(req);
if (res.getStatus().equals(StatusCode.SUCCESS)) {
    System.out.println("Modified account.");
}

The following example shows the SPML 2.0 request that was sent.


Example 2–4 Example Request XML

<addRequest xmlns='urn:oasis:names:tc:SPML:2:0' requestID='rid-spmlv2' 
executionMode='synchronous'>
  <openspml:operationalNameValuePair xmlns:openspml='urn:org:openspml:v2:util:xml
    name='session' value='AAALPgAAYD0A...'/>
  <data>
    <dsml:attr xmlns:dsml='urn:oasis:names:tc:DSML:2:0:core' name='accountId'>
      <dsml:value>exampleSpml2Person</dsml:value>
    </dsml:attr>
    <dsml:attr xmlns:dsml='urn:oasis:names:tc:DSML:2:0:core' name='objectclass'>
      <dsml:value>spml2Person</dsml:value>
    </dsml:attr>
    <dsml:attr xmlns:dsml='urn:oasis:names:tc:DSML:2:0:core' name='credentials'>
      <dsml:value>pwdpwd</dsml:value>
    </dsml:attr>
  </data>
</addRequest>

This example shows the body of the SPML response that was returned to the client.


Example 2–5 Example Response XML

<addResponse xmlns='urn:oasis:names:tc:SPML:2:0' status='success' 
requestID='rid-spmlv2'>
  <openspml:operationalNameValuePair xmlns:openspml='urn:org:openspml:v2:util:xml'
    name='session' value='AAALPgAAYD0A...'/>
  <pso>
    <psoID ID='anSpml2Person'/>
    <data>
      <dsml:attr xmlns:dsml='urn:oasis:names:tc:DSML:2:0:core' name='accountId'>
        <dsml:value>anSpml2Person</dsml:value>
      </dsml:attr>
      <dsml:attr xmlns:dsml='urn:oasis:names:tc:DSML:2:0:core' name='objectclass'>
        <dsml:value>spml2Person</dsml:value>
      </dsml:attr>
      <dsml:attr xmlns:dsml='urn:oasis:names:tc:DSML:2:0:core' name='credentials'>
        <dsml:value>pwdpwd</dsml:value>
      </dsml:attr>
    </data>
  </pso>
</addResponse>


Example 2–6 Example JSP

The following example consists of a .jsp file that invokes an AddRequest through Waveset’s SessionAwareSpml2Client class.

<%@page contentType="text/html"%>
<%@page import="org.openspml.v2.client.*,
                com.sun.idm.rpc.spml2.SessionAwareSpml2Client"%>
<%@page import="org.openspml.v2.profiles.dsml.*"%>
<%@page import="org.openspml.v2.profiles.*"%>
<%@page import="org.openspml.v2.util.xml.*"%>
<%@page import="org.openspml.v2.msg.*"%>
<%@page import="org.openspml.v2.msg.spml.*"%>
<%@page import="org.openspml.v2.util.*"%>

<%
final String url = "http://host:port/idm/servlet/openspml2";
%>

<html>
<head><title>SPML2 Test</title></head>
<body>
<%

 // need a client.
 SessionAwareSpml2Client client = new SessionAwareSpml2Client( url );

 // login
 client.login("configurator", "password");

 // AddRequest
 String rid = "rid-spmlv2"; // The RequestId is not strictly required.

 Extensible data = new Extensible();
 data.addOpenContentElement(new DSMLAttr("accountId", user));
 data.addOpenContentElement(new DSMLAttr("objectclass", "spml2Person"));
 data.addOpenContentElement(new DSMLAttr("credentials", password));

 AddRequest add = new AddRequest(rid, // String requestId,
                ExecutionMode.SYNCHRONOUS, // ExecutionMode executionMode,
                null, // PSOIdentifier type,
                null, // PSOIdentifier containerID,
                data, // Extensible data,
                null, // CapabilityData[] capabilityData,
                null,  // String targetId,
                null  // ReturnData returnData
            );

    // Submit the request
    Response res = client.request( add );
%>
<%= res.toString()%>
</body>
</html>

ListTargetsRequest Examples

The examples in this section illustrate the ListsTargetsRequest capabilities that are available using Waveset.


Example 2–7 Example Client Code

The following example shows how a .jsp file invokes a ListTargetsRequest through Waveset’s SessionAwareSpml2Client class.

<%@page contentType="text/html"%>
<%@page import="org.openspml.v2.client.*,
                com.sun.idm.rpc.spml2.SessionAwareSpml2Client"%>
<%@page import="org.openspml.v2.profiles.dsml.*"%>
<%@page import="org.openspml.v2.profiles.*"%>
<%@page import="org.openspml.v2.util.xml.*"%>
<%@page import="org.openspml.v2.msg.*"%>
<%@page import="org.openspml.v2.msg.spml.*"%>
<%@page import="org.openspml.v2.util.*"%>
<%
final String url = "http://host:port/idm/servlet/openspml2";
%>
<html>
<head><title>SPML2 Test</title></head>
<body>
<%
 // need a client.
 SessionAwareSpml2Client client = new SessionAwareSpml2Client( url );
 // login (sends a ListTargetsRequest)
 Response res = client.login("configurator", "password");
%>
<%= res.toString()%>

// logout
client.logout();
</body>
</html>


Example 2–8 Example Request XML

This next example shows the body of the SPML request that is sent for login.

<listTargetsRequest xmlns='urn:oasis:names:tc:SPML:2:0' requestID='rid[7013]' 
    executionMode='synchronous'>
  <openspml:operationalNameValuePair xmlns:openspml='urn:org:openspml:v2:util:xml'
    name='accountId' value='configurator'/>
  <openspml:operationalNameValuePair xmlns:openspml='urn:org:openspml:v2:util:xml'
    name='password' value='password'/>
</listTargetsRequest>

This example shows the body of the SPML response that is received by or returned to the client.


Example 2–9 Example Response XML

   <openspml:operationalNameValuePair 
xmlns:openspml="urn:org:openspml:v2:util:xml" name="session" value="AAAM+wAAaC..."/>
   <target targetID="spml2-DSML-Target" profile="urn:oasis:names:tc:SPML:2:0:DSML">
      <schema>
         <spmldsml:schema xmlns:spmldsml="urn:oasis:names:tc:SPML:2:0:DSML">
            <spmldsml:objectClassDefinition name="spml2Person">
               <spmldsml:memberAttributes>
                  <spmldsml:attributeDefinitionReference required="true" 
name="objectclass"/>
                  <spmldsml:attributeDefinitionReference required="true" 
name="accountId"/>
                  <spmldsml:attributeDefinitionReference required="true" 
name="credentials"/>
                  <spmldsml:attributeDefinitionReference name="firstname"/>
                  <spmldsml:attributeDefinitionReference name="lastname"/>
                  <spmldsml:attributeDefinitionReference name="emailAddress"/>
               </spmldsml:memberAttributes>
            </spmldsml:objectClassDefinition>
            <spmldsml:attributeDefinition name="objectclass"/>
            <spmldsml:attributeDefinition description="Account Id" name="accountId"/>
            <spmldsml:attributeDefinition description="Credentials, e.g. password" 
name="credentials"/>
            <spmldsml:attributeDefinition description="First Name" name="firstname"/>
            <spmldsml:attributeDefinition description="Last Name" name="lastname"/>
            <spmldsml:attributeDefinition description="Email Address" 
name="emailAddress"/>
         </spmldsml:schema>
         <supportedSchemaEntity entityName="spml2Person"/>
      </schema>
      <capabilities>
         <capability namespaceURI="urn:oasis:names:tc:SPML:2:0:async"/>
         <capability namespaceURI="urn:oasis:names:tc:SPML:2:0:batch"/>
         <capability namespaceURI="urn:oasis:names:tc:SPML:2:0:bulk"/>
         <capability namespaceURI="urn:oasis:names:tc:SPML:2:0:password"/>
         <capability namespaceURI="urn:oasis:names:tc:SPML:2:0:suspend"/>
         <capability namespaceURI="urn:oasis:names:tc:SPML:2:0:search"/>
      </capabilities>
   </target>
</listTargetsResponse>

Async Capabilities

Waveset supports the Async capabilities described in the following table.

Table 2–3 Async Capabilities

Capability 

Description 

OperationalAttributes

CancelRequest

Cancels a request, using the request ID. 

None 

StatusRequest

Returns the status of a request, using the request ID. 

None 

The following example performs an asynchronous status request.


Example 2–10 Example Async Requests

String REQUEST_ID = "test-req-id-00000000000001";
String PRE_ASYNC_DELAY = "45";
String POST_ASYNC_DELAY = "15";

SessionAwareSpml2Client client = new 
   SessionAwareSpml2Client("http://example.com:8080/idm/servlet/openspml2");
ListTargetsResponse loginInfo = client.login("Configurator", "configurator");

PSOIdentifier psoId = new PSOIdentifier("maurelius", null, null);
LookupRequest lookupReq = new LookupRequest();
lookupReq.setPsoID(psoId);
lookupReq.setReturnData(ReturnData.EVERYTHING);
lookupReq.setRequestID(REQUEST_ID);
lookupReq.setExecutionMode(ExecutionMode.ASYNCHRONOUS);

lookupReq.addOpenContentElement(
    new OperationalNameValuePair(
        com.sun.idm.rpc.spml2.async.AsyncExecutorTask.IDM_BEFORE_ASYNC_DELAY_NAME, 
        PRE_ASYNC_DELAY
    )
);
lookupReq.addOpenContentElement(
    new OperationalNameValuePair(
        com.sun.idm.rpc.spml2.async.AsyncExecutorTask.IDM_AFTER_ASYNC_DELAY_NAME, 
        POST_ASYNC_DELAY
    )
);

LookupResponse lookupRes = (LookupResponse) client.request(lookupReq);
if (lookupRes.getStatus().equals(StatusCode.SUCCESS)) {
    System.out.println("Lookup response is pending.");
}

StatusRequest statusReq = new StatusRequest();
statusReq.setAsyncRequestID(REQUEST_ID);
statusReq.setReturnResults(false);
statusReq.setExecutionMode(ExecutionMode.SYNCHRONOUS);
StatusResponse statusRes = (StatusResponse) client.request(statusReq);
if (lookupRes.getStatus().equals(StatusCode.SUCCESS)) {
    System.out.println("Status response received.");
}

java.util.Iterator responseIterator = statusRes.responseIterator();
while (responseIterator.hasNext()) {
    Response nestedResponse = (Response) responseIterator.next();
    if (nestedResponse instanceof LookupResponse) {
        if (nestedResponse.getStatus().equals(StatusCode.SUCCESS)) {
            System.out.println("Successfully received nested lookup response.");
        }
    }
}

Batch Capability

Waveset supports the Batch capability described in the following table.

Table 2–4 Batch Capability

Capability  

Description 

OperationalAttributes

BatchRequest

Executes a batch of requests. 

None 

The following example performs a batch add operation.


Example 2–11 Example Batch Request

SessionAwareSpml2Client client = new 
    SessionAwareSpml2Client("http://example.com:8080/idm/servlet/openspml2");
ListTargetsResponse loginInfo = client.login("Configurator", "configurator");

BatchRequest batchReq = new BatchRequest();
for (int i = 1; i <= 10; i++) {
    AddRequest addReq = new AddRequest();
    Extensible attrs = new Extensible();
    attrs.addOpenContentElement(new DSMLAttr("objectclass", "spml2Person"));
    attrs.addOpenContentElement(new DSMLAttr("accountId", "test_" + 
       String.format("%03d", i)));
    attrs.addOpenContentElement(new DSMLAttr("credentials", "password"));
    addReq.setData(attrs);
    addReq.setReturnData(ReturnData.EVERYTHING);
    batchReq.addRequest(addReq);
}
BatchResponse batchRes = (BatchResponse) client.request(batchReq);
if (batchRes.getStatus().equals(StatusCode.SUCCESS)) {
    System.out.println("Successfully performed batch add operation.");
}

Bulk Capabilities

Waveset supports the Bulk capabilities described in the following table.

Table 2–5 Bulk Capabilities

Capability 

Description 

OperationalAttributes

BulkDeleteRequest

Executes a bulk delete of PSOs. 

None 

BulkModifyRequest

Executes a bulk modify of matching PSOs. 

None 


Example 2–12 Example Bulk Delete Request

The following example bulk deletes all users with the lastname Aurelius.

SessionAwareSpml2Client client = new SessionAwareSpml2Client("http://example.com:8080/
idm/servlet/openspml2");
ListTargetsResponse loginInfo = client.login("Configurator", "configurator");

BulkDeleteRequest req = new BulkDeleteRequest();

Substrings term = new Substrings();
term.setName("lastname");
term.setInitial(new DSMLValue("Aurelius"));
Filter filter = new Filter(term);
Query q = new Query();
q.setScope(Scope.ONELEVEL);
q.addQueryClause(filter);

req.setExecutionMode(ExecutionMode.SYNCHRONOUS);
req.setQuery(q);

BulkDeleteResponse res = (BulkDeleteResponse) client.request(req);
if (res.getStatus().equals(StatusCode.SUCCESS)) {
    System.out.println("Successfully performed bulk delete operation.");
}

Password Capabilities

Waveset supports the Password capabilities described in the following table.

Table 2–6 Password Capabilities

Capability 

Description 

Caveats 

ExpirePasswordRequest

Expires a password. 

  • You cannot specify resources or targets. Doing so causes the Waveset User object password to expire; which then causes the password on all of the user’s resources to expire.

  • Waveset does not support the remainingLogins attribute. If you set this attribute to anything other than the default (1 or less), an OperationNotSupported error occurs.

ResetPasswordRequest

Resets a password and returns the new value on all accounts. 

Passwords are sensitive. Use SSL or some other secure transport. 

SetPasswordRequest

Sets a password as an Waveset administrator.  

  • The Waveset server ignores the current password if it is specified with the setCurrentPassword method.

  • Passwords are sensitive. Use SSL or some other secure transport.

ValidatePasswordRequest

Determines whether a given password is valid. 

Passwords are sensitive. Use SSL or some other secure transport. 

Example Password capabilities follow.

ResetPasswordRequest Example

The following example illustrates a typical ResetPasswordRequest.


Example 2–13 Example ResetPasswordRequest

ResetPasswordRequest rpr = new ResetPasswordRequest();
...
PSOIdentifier psoId = new PSOIdentifier(accountId, null, null);
 rpr.setPsoID(psoId);
...

SetPasswordRequest Example

The following example illustrates a typical SetPasswordRequest.


Example 2–14 Example SetPasswordRequest

SetPasswordRequest spr = new SetPasswordRequest();
...
PSOIdentifier psoId = new PSOIdentifier(accountId, null, null);
spr.setPsoID(psoId);
spr.setPassword("newpassword");
...

ValidatePasswordRequest Example

The following example illustrates a typical ValidatePasswordRequest.


Example 2–15 Example ValidatePasswordRequest

ValidatePasswordRequest vpr = new ValidatePasswordRequest();
...
PSOIdentifier psoId = new PSOIdentifier(accountId, null, null);
vpr.setPsoID(psoId);
vpr.setPassword("apassword");
...

Suspend Capabilities

Waveset supports the Suspend capabilities described in the following table.

Table 2–7 Suspend Capabilities

Capability 

Description 

Caveats 

ActiveRequest

Returns a boolean value that indicates whether the user is enabled. 

None 

ResumeRequest

Resumes (enables) a PSO user. 

Does not support EffectiveDate.

If you set EffectiveDate, Waveset returns an OperationNotSupported error.

SuspendRequest

Suspends an account/PSO (disables). 

Does not support EffectiveDate.

If you set EffectiveDate, Waveset returns an OperationNotSupported error.


Example 2–16 Suspend Examples

The following examples suspend and resume a request.


// Disable example
SessionAwareSpml2Client client = new SessionAwareSpml2Client("http://example.com:8080
/idm/servlet/openspml2");
ListTargetsResponse loginInfo = client.login("Configurator", "configurator");

PSOIdentifier psoId = new PSOIdentifier("maurelius", null, null);
SuspendRequest req = new SuspendRequest();
req.setPsoID(psoId);

SuspendResponse res = (SuspendResponse) client.request(req);
if (res.getStatus().equals(StatusCode.SUCCESS)) {
    System.out.println("Account successfully disabled.");
}

// Enable example
SessionAwareSpml2Client client = new SessionAwareSpml2Client("http://example.com:8080
/idm/servlet/openspml2");
ListTargetsResponse loginInfo = client.login("Configurator", "configurator");

PSOIdentifier psoId = new PSOIdentifier("maurelius", null, null);
ResumeRequest req = new ResumeRequest();
req.setPsoID(psoId);

ResumeResponse res = (ResumeResponse) client.request(req);
if (res.getStatus().equals(StatusCode.SUCCESS)) {
    System.out.println("Account successfully enabled.");
}

Search Capability

Waveset supports the Search capabilities described in the following table.

Table 2–8 Search Capabilities

Capability 

Description 

OperationalAttributes

SearchRequest

Returns as many users as it can find that match the specified criteria within the allotted amount of time. If additional users exist, the request also returns a handle that can be used within an IterateRequest.

None 

IterateRequest

Continues an existing incomplete SearchRequest or IterateRequest.

None 

CloseIteratorRequest

Ends an IterateRequest. You may terminate an IterateRequest before it terminates.

None 

Search Filter Configuration

The DSML search filter is translated to a set of repository attribute conditions. A necessary part of the translation involves mapping the external DSML attribute name to a queryable repository attribute. A set of attribute mappings for each searchable type must be defined in the configuration.

The filter is analyzed and processed according to one of the following categories:

The SPML2 configuration object contains the following properties

The following capabilities are not supported:

Search Examples

The following examples illustrate how to perform searches.


Example 2–17 SearchRequest Example

ArrayList<PSO> psos = new ArrayList<PSO>();

SessionAwareSpml2Client client = new SessionAwareSpml2Client("http://example.com:8080
/idm/servlet/openspml2");
ListTargetsResponse loginInfo = client.login("Configurator", "configurator");

SearchRequest searchReq = new SearchRequest();
EqualityMatch acctIdTerm = new EqualityMatch("firstname", new DSMLValue("Marcus"));
Present emailTerm = new Present("emailAddress");
org.openspml.v2.profiles.dsml.And terms = new 
    org.openspml.v2.profiles.dsml.And(new FilterItem[] { acctIdTerm, emailTerm });
Filter filter = new Filter(terms);
Query q = new Query();
q.setScope(Scope.ONELEVEL);
q.addQueryClause(filter);

searchReq.setQuery(q);
searchReq.setReturnData(ReturnData.IDENTIFIER);
searchReq.setExecutionMode(ExecutionMode.SYNCHRONOUS);

SearchResponse searchRes = (SearchResponse) client.request(searchReq);
if (searchRes.getStatus().equals(StatusCode.SUCCESS)) {
    System.out.println("Received search response.");
    for (PSO pso : searchRes.getPSOs()) {
        psos.add(pso);
    }
    
    ResultsIterator iterator = searchRes.getIterator();

    while (iterator != null) {
        IterateRequest iterReq = new IterateRequest();
        iterReq.setIterator(iterator);
        iterReq.setExecutionMode(ExecutionMode.SYNCHRONOUS);
        IterateResponse iterRes = (IterateResponse) client.request(iterReq);
        if (iterRes.getStatus().equals(StatusCode.SUCCESS)) {
            System.out.println("Found an iterator.");
        }
        for (PSO pso : iterRes.getPSOs()) {
            psos.add(pso);
        }
        iterator = iterRes.getIterator();
    }
}


Example 2–18 CloseIterator Example

// Close iterator example
ArrayList<PSO> psos = new ArrayList<PSO>();

SessionAwareSpml2Client client = new 
SessionAwareSpml2Client("http://example.com:8080/idm/servlet/openspml2");
ListTargetsResponse loginInfo = client.login("Configurator", "configurator");

SearchRequest searchReq = new SearchRequest();

Present term = new Present("emailAddress");
Filter filter = new Filter(term);
Query q = new Query();
q.setScope(Scope.ONELEVEL);
q.addQueryClause(filter);

searchReq.setQuery(q);
searchReq.setReturnData(ReturnData.EVERYTHING);
searchReq.setExecutionMode(ExecutionMode.SYNCHRONOUS);

SearchResponse searchRes = (SearchResponse) client.request(searchReq);
if (searchRes.getStatus().equals(StatusCode.SUCCESS)) {
    System.out.println("Received search response.");
    for (PSO pso : searchRes.getPSOs()) {
        psos.add(pso);
    }
    
    ResultsIterator iterator = searchRes.getIterator();

    while (iterator != null) {
        IterateRequest iterReq = new IterateRequest();
        iterReq.setIterator(iterator);
        iterReq.setExecutionMode(ExecutionMode.SYNCHRONOUS);
        IterateResponse iterRes = (IterateResponse) client.request(iterReq);
        if (iterRes.getStatus().equals(StatusCode.SUCCESS)) {
            System.out.println("Found an iterator.");
        }
        for (PSO pso : iterRes.getPSOs()) {
            psos.add(pso);
        }
        iterator = iterRes.getIterator();
        
        // For this example, always close the iterator
        if (true) {
            CloseIteratorRequest closeIterReq = new CloseIteratorRequest();
            closeIterReq.setIterator(iterator);
            closeIterReq.setExecutionMode(ExecutionMode.SYNCHRONOUS);
            CloseIteratorResponse closeIterRes = (CloseIteratorResponse) 
                client.request(closeIterReq);
            if (closeIterRes.getStatus().equals(StatusCode.SUCCESS)) {
                System.out.println("Closed iterator.");
                break;
            }
        }
    }
}

SPML Logging

Waveset can be configured to log SPML requests and responses. If Waveset receives a request or response that is known to the system, it writes pertinent information about the request to SPML log file. If it receives an unrecognized request, then it logs all the available information.

The SPML log is configured by editing the SPML configuration object. You cannot manage SPML logging from the administrator interface.

Access Log Configuration

Edit the following paramters in the SPML configuration object to enable and maintain logging.

Access Log Example

The following sample shows a variety of logged requests.

# ListTargetsRequest
2009-02-03T01:16:12.083Z ListTargetsRequest requestID='rid[9964]' protocol='v2' 
executionMode='synchronous' data='(accountId=Configurator,password=...)'
2009-02-03T01:16:12.089Z ListTargetsResponse requestID='rid[9964]' protocol='v2' 
status='success' errorCode='null' targets='((spml2Person(objectclass(required=true),
accountId(required=true),credentials(required=true),firstname(required=null),
lastname(required=null),emailAddress(required=null))))' etime=40

# AddRequest
2009-02-03T01:16:12.582Z AddRequest requestID='null' protocol='v2' 
executionMode='null' returnData='everything' 
data='everything'2009-02-03T01:16:13.154Z 
AddResponse requestID='Gen7951-1233623773152' protocol='v2' status='success' 
errorCode='null' psoId='spml2Person:#ID#E413:20EBCB32F11:783B7992-:46D19511056F6FB3' 
etime=578

# LookupRequest
2009-02-03T01:16:15.024Z LookupRequest requestID='null' protocol='v2'
 executionMode='synchronous' returnData='everything'
2009-02-03T01:16:15.130Z LookupResponse requestID='Gen7953-1233623775127' protocol='v2' 
status='success' errorCode='null' 
psoId='spml2Person:#ID#8092:20EBCB32F11:783B7992-:46D19511056F6FB3' etime=112

# ModifyRequest
2009-02-03T01:16:15.253Z ModifyRequest requestID='null' protocol='v2' executionMode='null' 
returnData='everything' psoId='maurelius' modifications='(lastname=(Antoninus))'
2009-02-03T01:16:15.915Z ModifyResponse requestID='Gen7954-1233623775912' protocol='v2' 
status='success' errorCode='null' 
psoId='spml2Person:#ID#8092:20EBCB32F11:783B7992-:46D19511056F6FB3' etime=668