Web Services Provisioning (WS-Provisioning)

DRAFT Version 0.7

01 October 2003

Authors

Gearard Woods, IBM
Tony Gullotta, IBM

Abstract

WS-Provisioning describes the APIs and schemas necessary to facilitate interoperability between provisioning systems and to allow software vendors to provide provisioning facilities in a consistent way.  The specification addresses many of the problems faced by provisioning vendors in their use of existing protocols, commonly based on directory concepts, and confronts the challenges involved in provisioning Web Services described using WSDL and XML Schema. 

The specification defines a model for the primary entities and operations common to provisioning systems including the provisioning and de-provisioning of resources, retrieval of target data and target schema information, and provides a mechanism to describe and control the lifecycle of provisioned state.

Table of Contents

  1.0 Introduction
  2.0 Related Standards
      2.1 Terminology
      2.2 Use of DSML
  3.0 Security
  4.0  Architectural Overview
      4.1 Applicability of this Specification
      4.2 Services and Schemas
        4.2.1 Versioning
      4.3 Conformance
  5.0 The Core Schema
      5.1 ProvisionedItem Objects
          5.1.1 The State of ProvisionedItem Objects
          5.1.2 ProvisionedItem Object Lifecycle
      5.2 Provisioning Targets
          5.2.1 Target Schema
            5.2.1.1 Referencing External Schema
            5.2.1.2 Embedding Schema
      5.3 The Extensible Type
      5.4 Identifiers
      5.5 Human Readable Messages
      5.6 Provisioning Events
  6.0 Service API General Considerations
      6.1 Error and Status Reporting
          6.1.1 Result Codes
      6.2 Iterating Across Large Result Sets
      6.3 Asynchronous Operation
      6.4 ProvisionedItem Filters
      6.5 Identifying and Filtering Objects Using XPath
  7.0 The Provisioning Service API
      7.1 Synchronous Operations
          7.1.1 listTargets()
          7.1.2 fetchTargets()
          7.1.3 listProvisionedItems()
          7.1.4 fetchProvisionedItems()
          7.1.5 listProvisionedLifecycle()
          7.1.6 listRequestStatus()
          7.1.7 fetchRequestStatus()
          7.1.8 cancelRequest()
      7.2 Asynchronous Operations
          7.2.1 provision()
          7.2.2 deprovision()
          7.2.3 modifyProvisionedState()
          7.2.4 modifyProvisionedParameters()
            7.2.4.1 Add Modifications
            7.2.4.2 Replace Modifications
            7.2.4.3 Delete Modifications
      7.3 Sample Usage Scenario
          7.3.1 Retrieving the Targets
          7.3.2 Getting the schema
          7.3.3 Provisioning
          7.3.4 Modifying Target Data
          7.3.5 Alternative Approaches
  8.0 The Notification Service APIs
      8.1 The ProvisioningNotification API
          8.1.1 Subscribe 
          8.1.2 Unsubscribe
      8.2 The NotificationListener API
          8.2.1 Notify Result Codes
      8.3 Connection Behavior

  Appendix A. Core WS-Provisioning Schema
  Appendix B. Provisioning Notification Schema
  Appendix C. API Schema
  Appendix D. Provisioning Service Point Schema and WSDL
  Appendix E. Examples
  Appendix F. Glossary of Terms
  References

1. Introduction

This document presents a provisioning service interface that is based on the Web Services Description Language (WSDL) as the interface definition language, the Simple Object Access Protocol (SOAP) as the transport of choice, and XML Schema as the preferred schema description language.  These standards are important because some of the most commonly used protocols in provisioning are based on directory standards, such as LDAP and DSMLv2, which have significant limitations. Vendors currently work around these limitations.  With the availability and widespread use of Web Services standards, there is an opportunity to create an interface that specifically targets the task of provisioning and promises not only to allow products from different vendors to interoperate seamlessly, but to also describe and manage services built upon these emerging standards.

2. Related Standards

There are few widely accepted standards for provisioning.  The most important effort to date is probably the work done by the Provisioning Service Technical Committee (PSTC) at Oasis.  As part of this effort, the PSTC has defined a set of Use Cases that reflect the operational requirements of a provisioning system.  This specification is compatible with those Use Cases. 

2.1 Terminology

To reduce a proliferation of different naming schemes, and since the work done by the PSTC may one day converge with this specification, the terminology defined in the PSTC Use Cases is frequently used here.  The principal entites identified by the PSTC are:

The terms MUST, MUST NOT,  REQUIRED, SHALL, SHALL NOT, SHOULD NOT, MAY, MAY NOT, RECOMMENDED and OPTIONAL are used in the manner described in RFC 2119

2.2 Use of DSML

This specification is quite open-ended and makes no assumptions about the schema language used to define the metadata for targets or users. As a later example will show, it is perfectly acceptable to use the schema language defined in DSML (version 1) as the means to communicate metadata within the context of this submission.  In fact, a target resource may elect to use multiple schema languages.  To illustrate how DSML might be used with this specification, an example is included in the text. DSML version 2 (DSMLv2) is not directly supported by this specification but there is at least one implementation that allows WS-Provisioning to be used with DSMLv2 repositories through the use of the Java Naming and Directory Interface (JNDI).

3. Security

Security is critical to provisioning.  For the purposes of this specification, it is assumed that current work on security, as it applies to the Web Services standards used here, will provide the necessary support for message integrity, confidentiality, and authentication. In particular, the Web Services security stack, WS-Security (see references), provides an extensible framework of standards that allows a wide range of security models to be created. These standards, along with common practices such as the use of SOAP over an SSL-secured HTTP connection, should be used in any practical applications to provide data security and authentication.

4. Architectural Overview

4.1 Applicability of this Specification

This specification is intended to facilitate the communication of provisioning information between the three primary entities involved in the provisioning process: the client, provisioning services (PSPs) and targets. The conventional deployment approach would be to have the PSP act as an aggregator of targets and the client would then communicate only with the PSP. If the ProvisioningService interface described in this specification is implemented by a target such as a software application, then it is possible that clients might address the target directly rather than through a PSP. However, it is unlikely that simple targets will provide some of the higher level features supported by this specification, such as lifecycle management. This specification does not assume a particular deployment architecture.

4.2 Services and Schemas

This specification describes three service interfaces: 

Each service definition is comprised of a number of schemas and interface descriptions.  At the root of the specification is the core WS-Provisioning schema that defines the basic data model.  On top of the core schema sits an API specification that identifies the basic messages used by the central Provisioning Service.  The Notification service has additional schemas which also depend on the core schema.

WS-Provisioning uses WSDL to describe the service interfaces and the XML Schema Language (see references ) as the formal description language used in all schema documents.  Because of the use of XML Schema import elements throughout the WS-Provisioning documents, any XML processors used with this specification must support this construct as described in XML Schema Part 1:Structures, section 4.2.3 .

For convenience throughout this document, type definitions in the core schema will use a prefix of "core", definitions in the API schema will use the prefix "api", and those definitions from the notification schema will use the prefix "notify".

4.2.1 Versioning

The WS-Provisioning schemas and WSDL observe the conventional mechanism of using the namespace to indicate the version number. Currently, a fictitious URI is used: "urn:ibm:names:ws:provisioning:0.1", where the final digits indicate the version and revision numbers respectively. In future versions of the specification, this will be updated to conform with IBM naming policies.

4.3 Conformance

Implementations of this specification are required only to provide the ProvisioningService API.

5. The Core Schema

The core schema defines the central objects in the WS-Provisioning data model.  There are three main types:

The ProvisionedItem type represents the state of a provisioned target resource.  This is roughly equivalent to the Provisioning Service Object Identifier (PSO-ID) in the PSTC Use Cases, but also encapsulates the provisioning data for a target, which corresponds to the Provisioning Service Target Data (PSTD).

The ProvisioningTarget type represents a provisionable resource such as an account or service and corresponds to the Provisioning Service Target (PST) identified by the PSTC.

Each ProvisioningTarget may publish its schema in  ProvisioningTargetSchema objects.  Each ProvisioningTarget may have any number of schema structures, potentially using different schema languages.

5.1 ProvisionedItem Objects

The ProvisionedItem type is the focus of provisioning operations. Instances of this type hold an identifier that uniquely identifies the object for a given service instance. The simplest ProvisionedItem instance MUST contain an identifier and a target identifier. Instances MAY include the current state of the object in a ProvisionedState, and any parameters required to provision the target resource. These parameters MUST satisfy the published schema for the provisioned target associated with the ProvisionedItem instance. Any attempt to create or modify a ProvisionedItem instance by specifying a set of parameters that do not conform to the target schema WILL result in an error. Each ProvisionedItem instance MAY also have an owner that is identified by a ProvisioningIdentifier.

<element name="ProvisionedItem" type="prov:ProvisionedItemType"/>
<complexType name="ProvisionedItemType">
    <annotation>
        <documentation>Holds the state of a provisioned target.</documentation>
    </annotation>
    <sequence>
        <element name="identifier" type="prov:ProvisioningIdentifierType" minOccurs="1" maxOccurs="1"/>
        <element name="target" type="prov:ProvisioningIdentifierType" minOccurs="1" maxOccurs="1"/>
        <element name="owner" type="core:ProvisioningIdentifierType" minOccurs="0" maxOccurs="1"/>            
        <element name="state" type="prov:ProvisioningStateType" minOccurs="0" maxOccurs="1"/>
        <element name="parameters" type="prov:ProvisioningServiceParametersType" minOccurs="0" maxOccurs="1"/>
    </sequence>
</complexType>

5.1.1 State of ProvisionedItem Objects

The state of a ProvisionedItem is indicated by an enumeration named ProvisioningState. Since the allowed states of a ProvisionedItem is determined primarily by the server and target, this enumeration is extensible to allow targets to define any additional states. The state of a ProvisionedItem instance may be changed through requests to the ProvisioningService modifyProvisionedState method or based on internal conditions in the provisioning system.

<Element name="ProvisioningState" type="core:ProvisioningStateType"/> 
<simpleType name="ProvisioningStateType">
    <union>
        <simpleType>
            <restriction base="string">
                <enumeration value="created"/>  
                <enumeration value="active"/>                    
                <enumeration value="suspended"/>
                <enumeration value="locked"/>
                <enumeration value="terminated"/>
            </restriction>
        </simpleType>
        <simpleType>
            <restriction base="string"/>
        </simpleType>
    </union>
</simpleType>

The meaning of the enumerated states should be interpreted as follows:

These states and the transitions between them are represented by the following state diagram:

The initial state is the result of the execution of a provision() operation and the final state results from a deprovision() operation. Service implementations are not required to support the publishing of state for a ProvisionedItem but, if implemented, are free to allow any path through this state diagram that reflects the allowed states for a given target and observes the allowed transitions. One of the simplest valid paths is:

5.1.2 Lifecycle of ProvisionedItem Objects 

WS-Provisioning allows the lifecycle of a ProvisionedItem to be described for auditing purposes.  This is an OPTIONAL feature that uses a set of ProvisioningEvent instances to track state changes or other modifications to ProvisionedItem objects.  The extent and level of detail of the history maintained for any given ProvisionedItem instance is a matter of server policy. Lifecycle information is retrieved from a service using the listProvisionedLifecycle method with an appropriate lifecycle interval specified. ProvisioningEvents are described in more detail later in this document.

5.2 Provisioning Targets

A ProvisioningTarget describes a resource that may be provisioned. This can include almost any computing resource including accounts for an application or service, resources that represent physical devices such as telephones, computing nodes, switches, and so on. The target data MUST be identifiable, in other words, targets must have a name that can be treated as a unique identifier within some domain. Each target SHOULD provide a schema describing the prerequisites that must be provided to allow the target to be provisioned. The ProvisioningTarget structure also allows any number of human-readable descriptions of the target to be communicated.

<Element name="ProvisioningTarget" type="core:ProvisioningTargetType"/>
<complexType name="ProvisioningTargetType">
    <sequence>
        <element name="identifier" type="core:ProvisioningIdentifierType" minOccurs="1" maxOccurs="1"/>
        <element name="description" type="core:ProvisioningTextType" minOccurs="0" maxOccurs="unbounded"/>
        <element name="schema" type="core:ProvisioningTargetSchemaType" minOccurs="0" maxOccurs="unbounded"/>
    </sequence>
</complexType>

5.2.1 Target Schema

One of the objectives of WS-Provisioning is to allow the use of any of the popular XML schema languages, such as XML Schema or Relax NG, to express target schema. It was also considered important to accommodate the legacy schema languages that have found some use in the provisioning world, such as DSMLv1 schema. However, the preferred schema language is XML Schema since that is becoming the schema language of choice for a majority of Web Services. It is possible that a target may wish to publish schema using multiple languages to satisfy the needs of different clients so no restrictions are placed on the number of schemas that a target may publish.

<complexType name="ProvisioningTargetSchema">
    <sequence>
      <element name="root" type="core:ProvisioningSelectorType" minOccurs="0" maxOccurs="1"/>
      <any namespace="##other" id="targetSchema" minOccurs="0"/>
    </sequence>		
    <attribute name="ref" type="QName" use="optional"/>
    <attribute name="location" type="anyURI" use="optional"/>
    <attribute name="namespace" type="anyURI" use="optional"/>
</complexType>	

The ProvisioningTargetSchema type allows the schema for a target to be encapsulated or referenced by URI. If supported by the schema language, a qualified name attribute named "ref" MAY be used to hold the name of the root element. For schema languages where this is not feasible, such as DSMLv1, an XPath expression MAY be provided in a root element. This OPTIONAL feature allows clients to determine the specific type of the target. The ref attribute and root element are mutually exclusive. The ProvisioningTargetSchema also has an OPTIONAL namespace attribute that is used to specify the namespace of the schema language.

5.2.1.1 Referencing External Schema

External schema documents may be referenced using the ProvisioningTargetSchema location attribute which holds the location URI of the schema document. If a location URI is provided, the schema MUST NOT include an embedded schema document. If the location attribute is specified, the ProvisioningTargetSchema element MUST include a value for the namespace attribute.

5.2.1.2 Embedding Schema

It is anticipated that provisioning services will usually embed the schema in the ProvisioningTargetSchema provided to the client. For example, a service that allows the provisioning of mailboxes of multiple sizes and offers two associated services, mail forwarding and the ability to receive faxes, might publish the following schemas. The schemas are available in DSMLv1, XML Schema, and Relax NG, and would be provided in response to a fetchTargets() request without any preferred schema URIs:

<target>
    <core:identifier name="mailbox"/>
    <core:description xml:lang="en">Mailboxes are available in many sizes</core:description>
    <core:schema>
        <core:root>
            <core:select>//class[name='mailbox']</core:select>
        </core:root>
        <dsml xmlns="http://www.dsml.org/DSML">
            <directory-schema>
                <attribute-type single-value="true">
                    <name>size</name>
                    <syntax>1.3.6.1.4.1.1466.115.121.1.15</syntax>
                </attribute-type>
                <attribute-type single-value="true">
                    <name>forwarding</name>
                    <syntax>1.3.6.1.4.1.1466.115.121.1.15</syntax>
                </attribute-type>
                <attribute-type single-value="true">
                    <name>fax</name>
                    <syntax>1.3.6.1.4.1.1466.115.121.1.15</syntax>
                </attribute-type>
                <class superior="top" type="structural">
                    <name>mailbox</name>
                    <object-identifier>1.2.3.4.5.6.7.8.9.10</object-identifier>
                    <attribute ref="size" required="true" />
                    <attribute ref="forwarding" required="false" />
                    <attribute ref="fax" required="false" />
                </class>
            </directory-schema>
        </dsml>
    </core:schema>
    <core:schema ref="mailbox:Mailbox" xmlns:mailbox="http://www.mailboxes.com/schema/mailbox">
        <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.mailboxes.com/schema/mailbox">
            <simpleType name="size">
                <restriction base="xsd:string">
                    <enumeration value="small"/>
                    <enumeration value="medium"/>
                    <enumeration value="large"/>
                </restriction>
            </simpleType>
           <complexType name="MailboxType">
               <sequence>
                    <element name="size" type="mailbox:size" minOccurs="1" maxOccurs="1"/>
                    <element name="forwarding" type="boolean" minOccurs="0" maxOccurs="1"/>
                    <element name="fax" type="boolean" minOccurs="0" maxOccurs="1"/>                    
                </sequence>
            </complexType>
            <element name="Mailbox" type="mailbox:MailboxType"/>
        </schema>
    </core:schema>
    <core:schema ref="mailbox:Mailbox" xmlns:mailbox="http://www.mailboxes.com/schema/mailbox">
        <grammar xmlns="http://relaxng.org/ns/structure/1.0" ns="http://www.mailboxes.com/schema/mailbox">
            <element name="Mailbox" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
                <element name="size">
                  <choice>
                    <value>small</value>
                    <value>medium</value>
                    <value>large</value>
                  </choice>
                </element>
                <element name="forwarding">
                  <data type="boolean"/>
                </element>
                <element name="fax">
                  <data type="boolean"/>
                </element>                
            </element>
        </grammar>
    </core:schema>
</target>

Note that the namespace attribute is optional for the target schema element and, since the client can easily determine the namespace of the schema element in this case, has not been included.

5.3 The Extensible Type

To allow objects to include any arbitrary data elements and attributes that may be useful to the client or service, an Extensible type has been defined. A number of the types defined in the core schema extend this type.

<complexType name="ExtensibleType">
    <sequence>
        <any namespace="##other" minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
    </sequence>
    <anyAttribute namespace="##other" processContents="lax"/>
</complexType>

5.4 Identifiers

The ProvisioningIdentifier structure is used throughout the schemas to hold identifying information for different types of objects. This specification makes no assumptions about the global uniqueness of any identifier, the scope of an identifier is defined by service implementations.  The ProvisioningIdentifier type is extensible so each instance MAY hold additional data used by the provisioning service or target to further qualify the identity of the object it is associated with. ProvisioningIdentifier instances MUST be viewed as immutable by the client.  Clients SHOULD also treat identifiers as opaque.

<element name="ProvisioningIdentifier" type="core:ProvisioningIdentifierType"/>    
<complexType name="ProvisioningIdentifierType">    
    <complexContent>
        <extension base="core:ExtensibleType">        
            <attribute name="name" type="string" use="required"/>
        </extension>
    </complexContent>
</complexType>

5.5 Human Readable Messages

The ProvisioningText type is a specialization of the XML Schema string type that is used to hold any human-readable message that MAY include a language specifier (as defined in "The xml: Namespace ").  In all cases where a ProvisioningText element is used within the WS-Provisioning schemas, it may appear any number of times, allowing messages in multiple locales to be communicated, if necessary.  

<complexType name="ProvisioningTextType">
    <simpleContent>
        <extension base="string">
            <attribute ref="xml:Lang" use="optional"/>
        </extension>
    </simpleContent>
</complexType>

5.6 Provisioning Events

Provisioning events are used to track the lifecycle of a ProvisionedItem and to notify subscribers of events through the Notification APIs. Events are normally communicated in a collection, the ProvisioningEventSet, that identifies the item associated with the events. The collection also OPTIONALLY contains an interval specifier that holds the time window for which the events are relevant.

Each ProvisioningEvent structure SHOULD contain a ProvisioningState that indicates the state of the ProvisionedItem associated with the event, even if the event is not due to a state change.  The time of the event SHOULD be recorded by the server to reflect the time that the cause of the event actually occurred. If the event was generated in response to the execution of an operation, the time SHOULD NOT be the time that the operation was submitted, it SHOULD be the time that the operation was finally executed. Any number of potentially localized human readable messages MAY also be used to describe the event.  A status that reflects the results of any operations that resulted in or are associated with this event object MAY be included.

The schema explicitly allows an instance of a type from the API schema to be included in the event as a reflection of the request or response objects. This mechanism may be used to include the operation, or schema-compliant portion of the operation, that caused the event. The response element may be used to hold the response, or schema-compliant portion of the response, for the operation. It is RECOMMENDED that if a response element is used to reflect the response to an operation, the reason element should be omitted from the event unless explicitly passed in as part of a modifyProvisionedState request.

<element name="ProvisioningEvent" type="core:ProvisioningEventType"/>
<complexType name="ProvisioningEventType">
    <annotation>
        <documentation>An event on a provisioned item.</documentation>
    </annotation>
    <complexContent>
        <extension base="core:ExtensibleType">         
            <sequence>
                <element name="reason" type="core:ProvisioningRequestStatusType" minOccurs="0"/>
                <element name="state" type="core:ProvisioningStateType" minOccurs="0"/>
                <element name="date" type="dateTime" minOccurs="0"/>
                <element name="description" type="core:ProvisioningTextType" minOccurs="0" maxOccurs="unbounded"/>           
                <element name="request" type="core:ProvisioningOperation" minOccurs="0"/>
                <element name="response" type="core:ProvisioningOperation" minOccurs="0"/> 
            </sequence> 
        </extension>
    </complexContent>                
</complexType>

<complexType name="ProvisioningOperation">
    <sequence>
        <any id="operation" namespace="urn:ibm:names:ws:provisioning:0.1:api">
            <annotation>
                <documentation>Container for any type from the API schema.</documentation>
            </annotation>
        </any>
    </sequence>
</complexType>

The ProvisioningEvent type may be used to communicate the following conditions:

Additions

The addition of a new ProvisionedItem instance to the system will be indicated by a ProvisioningEvent with a state value reflecting the initial state assigned by the service implementation. If the addition was the result of a provision operation, the server MAY include the ProvisionRequest structure in the event and SHOULD include the request identifier in the reason element if the provision operation executed asynchronously.

Modifications

Modification of the parameters of a ProvisionedItem object is communicated using a ProvisioningEvent which MAY include a copy of the ModifyProvisonedParametersRequest structure in the request element. The server SHOULD include the response element reflecting the results of any modifications so that the client can correlate the event to the specific portions of an asynchronous modify request.

Deletions

The deletion of a ProvisionedItem instance as a result of a deprovision request will be communicated through a ProvisioningEvent with a state of "terminated".

Errors

Errors in the execution of an operation will generate a ProvisioningEvent with an appropriate error code in the reason element. The event SHOULD include any request identifiers for the request operation if it executed asynchronously. The event MAY include the request instance, or any schem-compliant portion thereof, in the request element.

State Transitions

A ProvisioningEvent due to a state change of a ProvisionedItem MUST contain the final state of the item. The result of the operation that caused the state transition SHOULD be included in the reason element.

6. Service API General Considerations

6.1 Error and Status Reporting

The ProvisioningRequestStatus structure is used to return status information for all operations. The structure consists of a MANDATORY result code and any human-readable text messages describing the status. The status messages are returned using a ProvisioningText type and any number may be included, encoded for different locales if required. If the request executes asynchronously, the ProvisioningRequestStatus MUST include a request identifier string. This is used by the client to manage outstanding asynchronous requests. The absence of this request identifier in any response is an indicator to the client that the operation has executed synchronously. The syntax of the requestId string is at the discretion of the service and this value SHOULD be treated as opaque and immutable by the client. The ProvisioningRequestStatus type is derived from the Extensible type to OPTIONALLY allow any relevant data to be returned by the service.

6.1.1 Result Codes

The ProvisioningRequestStatus class holds an enumerated status code.  The possible values for this code are defined in the core schema as ProvisioningServiceStatusCode:

6.2 Iterating Across Large Result Sets

A number of operations in the Provisioning Service API can return a large number of results. These operations may use an iterator to allow the results to be returned in a number of successive requests rather than in a single response message. Iterators are normally returned to the client as part of a ProvisioningIteratedResult structure.

An iterator is simply an identifier that is used by the service implementation to locate the resources associated with the result set. Clients MUST treat the iterator as an opaque object. The sequence of messages in cases where an iterator is used will generally consist of a request operation which returns an iterator object in the result structure. The client then uses the iterator to initiate a request to receive the next set of results from the server. On each request, the service MAY return a new iterator instance so the client MUST use the iterator returned in a response in the next request message.

The ability to return results using an iterator is an OPTIONAL feature and may not be supported by all service implementations. If this feature is supported, the number of simultaneous iterated result sets that may be in use by a single client is a matter of server policy. Since clients do not have the ability to explicitly close an iterator and each instance may consume server resources, the lifetime of a given result set is also a matter of server policy.

6.3 Asynchronous Operation

The services defined in this proposal rely on SOAP's request-response calling convention but make provisions for asynchronous operation by providing a polling method to check the status of a request.  All operations that execute asynchronously are required to return a request ID that may be used to identify the request.   While the specification explicitly identifies certain operations as primarily asynchronous, and provides the means to poll for completion, implementations are free to perform these operations in a synchronous manner.   The specification does not impose either synchronous or asynchronous behavior, allowing the execution mode to be determined by the service implementation.

6.4 ProvisionedItem Filters

A number of places in this specification allow a filter to be used to constrain the set of ProvisionedItem instances reported or operated on. A filter is encapsulated in a ProvisionedItemFilter structure.

The filter implies a logical and relationship between the set of specified criteria, i.e. ProvisionedItem instances must match all of the combined filter criteria specified. However, filter elements are all optional. For a request which requires a filter instance, the absence of all filter qualifiers indicates that all accessible provisioned objects should be returned by the server. If the service implementation does not support a specified field, such as owner or state for example, the field SHOULD be ignored. The filter fields will be interpreted by the server as follows:

target

The filter MAY include a target identifier. If provided, the filter WILL pertain only to those ProvisionedItem instances that reference the specified target.

owner

The filter MAY include an identifier for the owner of the ProvisionedItem object, as specified when the ProvisionedItem instance was created. If provided, the filter WILL pertain only to those ProvisionedItem instances that belong to the specified owner.

states

The filter MAY specify a set of states. Only ProvisionedItem instances that satisfy the other filter criteria and have one of the specified states WILL be returned. The absence of any state specification indicates that the server MUST ignore the ProvisionedItem state when selecting the result set.

selector

An XPath expression that will filter ProvisionedItem objects based on the values of their parameters MAY be included. The root for the XPath expression is the child of the parameters element in the ProvisionedItem object. If not specified, the server WILL ignore ProvisionedItem parameters.

6.5 Identifying and Filtering Objects Using XPath

Because targets, and therefore ProvisionedItem instances, do not have a fixed schema, XPath may be used to identify specific ProvisionedItem instances based on the values of its target parameters. The core schema defines the ProvisioningSelector to facilitate this.  Essentially, the ProvisioningSelector is an XPath expression and an optional number of namespace identifiers that can be used by implementations to set the namespaces used in the selector. 

<complexType name="NamespaceSpecifier">
    <attribute name="uri" type="anyURI" use="required"/>
    <attribute name="prefix" type="string" use="required"/>
</complexType>

<element name="ProvisioningSelector" type="core:ProvisioningSelectorType"/>
<complexType name="ProvisioningSelectorType">
    <sequence>
        <element name="select" type="string" minOccurs="1"/>
        <element name="namespace" type="core:NamespaceSpecifier" minOccurs="0" maxOccurs="unbounded"/>
    </sequence>
</complexType>

7. The Provisioning Service API

The interface to the Provisioning Service is defined in a WSDL document and consists of a set of operations which will generally be invoked in a synchronous manner, and a set of operations that are expected to be primarily asynchronous. The synchronous operations are all designed to retrieve information from the provisioning service. These are:

The asynchronous operations are those that alter the state of a target or the internal state of the provisioning systems and may therefore demand some workflow or approval processes to complete. These operations are:

 

7.1 Synchronous Operations

Synchronous operations fall into two general categories, those that return a well-defined and finite set of results, and those can can return any number of results. In general, the former are named using a "fetch" prefix, such as fetchTargets and fetchProvisionedItems, and the others have a "list" prefix such as listTargets. All of the "list" methods may use an iterator, if supported by the service implementation, to allow large data sets to be retrieved as described in the "Iterating Across Large Result Sets" section.

7.1.1 listTargets()

The listTargets method allows a client to request a list of all available targets in the system.  The API schema defines a ListTargetsRequest and ListTargetsResponse structure which are used to convey the request and response information respectively. 

Request

A ListTargetsRequest MAY contain a single ProvisioningIterator which MUST have been returned from a previous invocation of listTargets.  If the list of targets is large, or larger than the service wishes to return in a single request, the service implementation MAY return an iterator to allow the list to be retrieved in pages.  In that case, passing a previously returned iterator to the listTargets method will return the next iterator page.  However, the server is NOT REQUIRED to support this mode of operation. 

Response

The response to a listTargets request is encapsulated in a ListTargetsResponse structure and includes a ProvisioningTargetSet containing the set of targets for this request.  The server MUST also return a ProvisioningIteratedResult structure.  The ProvisioningIteratedResult will indicate the status of the request and MAY include an iterator if the set of all available targets was not exhausted by this request.  This iterator may be used in future listTargets requests to retrieve any remaining target data.  As defined in the schema, the ProvisioningIteratedResult MAY include a remaining count to indicate the total number of targets available at the server following this request and MAY include a size integer holding the number of targets in the returned ProvisioningTargetSet.  If the service implementation does not wish to return, or cannot determine, the remaining count or result set size, it MAY return -1 as the value for these elements. If the targets encapsulated in the ListTargetResponse exhausts the set of targets at the service, the ProvisioningIteratedResult MUST NOT include an iterator. 

If the operation is successful and the service has additional targets to return following this request and the service supports iterated operation, an iterator WILL be returned in the result structure.  In this case the client MUST use the returned iterator in the next listTargets request.

Target data returned in the ListTargetsResponse MAY include only the minimum set of schema-conforming target data, which is simply the target identifier.  However, it is RECOMMENDED that if the service supports multiple schema languages, the ProvisioningTarget elements in the response include a schema element for all supported schema languages, each identifying the language using the namespace attribute. The level of detail for additional target data is at the discretion of server policy. The server WILL return only those targets which are accessible by the authenticated user issuing the request.

Error Conditions

The server SHOULD provide the following exception indicators in response to the listTargets request:

7.1.2 fetchTargets()

The fetchTargets method retrieves a specified set of target instances from the provisioning service.  The FetchTargetsRequest and FetchTargetsResponse structures have been defined in the API schema to encapsulate the request and response data respectively for this operation. 

Request

The FetchTargetsRequest structure MUST include at least one identifier that is associated with a target instance for the service receiving the request, but may include any number of identifiers. The request may also OPTIONALLY include a set of schema specifiers which should be the namespace URIs of the requester's preferred schema languages.

Response

In response to a FetchTargetsRequest the service will return a FetchTargetsResponse structure that MUST contain a ProvisioningRequestStatus instance indicating the result of the operation.  In the absence of an error, the response WILL also include a ProvisioningTargetSet instance containing the set of targets identified by the ProvisioningIdentifier instances passed in the request structure.  The resulting target objects MUST include any available schema information that the service can determine for the target.  However, if any schema URIs are provided in the request, the server SHOULD only return the schemas corresponding to the specified namespaces, if the specified set contains any supported schema languages. The service MAY include any description strings it finds appropriate based on the service locale, any locale information propagated from the client, or all description strings available at the service.

If a target is unavailable, the service implementation MUST return its identifier and a status code indicating the reason that the service can not return the instance in a ProvisioningObjectStatus structure. If a set of schema URIs are provided and the server does not support any of the specified schema languages for a given target, an unsupportedSchema error WILL be returned in the status for that target.

Error Conditions

The server SHOULD provide the following exception indicators in response to the fetchTarget request:

The service implementation SHOULD return success if the request could be satisfied for all of the identifiers passed in the request. Error conditions for specific targets should be reflected in the ProvisioningObjectStatus corresponding to the target identifier. These error indicators include:

7.1.3 listProvisionedItems()

The listProvisionedItems method is similar in operation to the listTargets method but allows a client to request a list of all accessible ProvisionedItem object instances in the system, optionally specifying a set of filter criteria.  The API schema defines a ListProvisionedItemsRequest and ListProvisionedItemsResponse structure that are used to convey the request and response information, respectively. 

Request

A ListProvisionedItemsRequest MAY contain a single ProvisioningIterator or a single filter structure. If an iterator is included, it MUST have been returned from a previous invocation of listProvisionedItems.  Iterators MAY be used by the service if the list of ProvisionedItem objects is larger than the service wishes to return in a single request.  Passing a previously returned iterator to the listProvisionedItems method will return the next iterator page.  However, the server is NOT REQUIRED to support this iterated mode of operation. 

An initial invocation of listProvisionedItems MUST include a filter. Any ProvisionedItem instances that match the combined filter criteria specified will be returned by the server. If the filter is empty, i.e. no criteria are specified, the server WILL return all accessible ProvisionedItem instances. Filters are described in more detail in the ProvisionedItem Filters section.

Response

The response to a listProvisionedItems request is encapsulated in a ListProvisionedItemsResponse structure and includes a ProvisionedItemSet containing the set of ProvisionedItem objects for this request.  The server MUST also return a ProvisioningIteratedResult structure, as defined in the Core Schema.  The ProvisioningIteratedResult will indicate the status of the request and MAY include an iterator if the set of all available ProvisionedItem objects was not exhausted by this request.  This iterator may be used in future listProvisionedItems requests to retrieve the next set of ProvisionedItem instances.  The ProvisioningIteratedResult MAY include a remaining count to indicate the total number of ProvisionedItem objects available at the server following this request and MAY include a size integer holding the number of instances in the returned ProvisionedItemSet. If the service implementation does not wish to return, or cannot determine, the remaining count or result set size, it MAY return -1 as the value for these elements. If the objects encapsulated in the ListProvisionedItemsResponse exhausts the set of objects at the service, the ProvisioningIteratedResult MUST NOT include an iterator and MUST set the result remaining attribute to 0. 

If the operation is successful and the service has additional objects to return following the request and the service supports iterated operation, an iterator WILL be returned in the result structure.  The client MUST use the iterator returned from each listProvisionedItems invocation in the next listProvisionedItems request.

ProvisionedItem instances returned in the ListProvisionedItemsResponse SHOULD only include the minimum set of schema-conforming ProvisionedItem data, which is simply the item identifier and the target identifier.  The level of detail is at the discretion of server policy but it is RECOMMENDED that any available description information be returned to facilitate user interaction.

Error Conditions

The server SHOULD provide the following exception indicators in response to the listProvisionedItems request:

7.1.4 fetchProvisionedItems()

The fetchProvisionedItems operation retrieves detailed information for a specific set of ProvisionedItem instances from the provisioning service.  The FetchProvisionedItemsRequest and FetchProvisionedItemsResponse structures have been defined in the API schema to encapsulate the request and response data respectively for this operation. 

Request

The FetchProvisionedItemsRequest may include any number of items which identify the ProvisionedItem instances to be retrieved. The request MUST include at least one. Each item in the request MUST contain the ProvisionedItem identifier and the item's target identifier.

 

Response

In response to a FetchProvisionedItemsRequest, the service will return a FetchProvisionedItemsResponse structure that MUST contain a ProvisioningRequestStatus instance indicating the result of the operation.  In the absence of a fault condition, the response WILL also include a ProvisionedItemSet instance containing the ProvisionedItems identified in the request structure.  The resulting ProvisionedItem objects MUST include all available parameter information that the service can determine for each object.  Additionally, the service SHOULD return the current state of the object and any owner information.

If a ProvisionedItem can not be returned for any reason, it should be listed in an unavailable element, which is an instance of ProvisioningObjectStatus, along with a status code indicating the reason.

Error Conditions

The server SHOULD provide the following exception indicators in response to the getProvisionedItem request:

The service implementation SHOULD return success if the request could be satisfied for all of the identifiers passed in the request. Error conditions for specific ProvisionedItems should be reflected in the ProvisioningObjectStatus corresponding to the item identifier. These error indicators include:

7.1.5 listProvisionedLifecycle()

The listPRovisionedLifecycle operation retrieves a list of any lifecycle information available for a ProvisionedItem instance. The ListProvisionedLifecycleRequest and ListProvisionedLifecycleResponse structures have been defined in the API schema to encapsulate the request and response data, respectively, for this operation.

Request

A ListProvisionedLifecycleRequest MAY contain an iterator, returned from a previous invocation of listProvisionedLifecycle, or an identifier for a specific ProvisionedItem for which lifecycle information is to be retrieved. An interval parameter is OPTIONAL and may only be included if a ProvisionedItem identifier is supplied. The interval is used to indicate the start and end dates and times for the lifecycle information. If the specified interval includes a start date without an end date, then the client is indicating that all lifecycle information available from the specified start date onwards should be returned. If an end date is specified without a start date, all lifecycle data up to the specified end date should be returned. If a ProvisionedItem identifier is supplied but an interval is not specified, then the service implementation should view this as a request for all available lifecycle information for the specified item.

Response

The result of a listProvisionedLifecycle request is a ListProvisionedLifecycleResponse object that MUST contain a status structure, which is an instance of ProvisioningIteratorResult. This will contain a status code reflecting the status of the operation and MAY include an iterator if the result set is large and the server wishes to return the results in iterated mode.

Lifecycle information is returned in an instance of the ProvisioningEventSet type, which includes an identifier for the ProvisionedItem in question and any number of ProvisioningEvent structures. The event set also includes an interval specifier that identifies the period of time covered by the ProvisioningEventSet. These types are described in more detail in the Provisioning Events section.

If lifecycle is supported, the server MUST report all available lifecycle information as constrained by the specified interval.  If no lifecycle interval is specified by the client, the service SHOULD return all available lifecycle information for the identified ProvisionedItem.

Error Conditions

The server SHOULD provide the following exception indicators in response to the getRequestStatus request:

7.1.6 listRequestStatus()

The listRequestStatus operation retrieves a list of the status of all outstanding asynchronous requests. The ListStatusRequest and ListStatusResponse structures have been defined in the API schema to encapsulate the request and response data, respectively, for this operation.

Request

The request structure MAY include an iterator returned in response to a previous invocation of listRequestStatus().

Response

The result of a listStatusRequest call is a ListStatusResponse object that MUST contain an iterated result object reflecting the status of the listRequestStatus operation and MAY include an iterator if the remaining list of outstanding requests is to be returned in successive calls to listRequestStatus(). An iterator MUST NOT be included if this request invocation exhausts the set of outstanding requests. If successful, the response will include a set of ProvisioningObjectStatus objects that correspond to outstanding requests. Each ProvisioningObjectStatus instance WILL contain the status and identifier for a single request and MAY include a ProvisionedItem identifier if the service implementation has reached a point where an identifier has been assigned. An identifier SHOULD NOT be returned by the service unless it is prepared to honor fetchProvisionedItems() requests for the specified identifier.

Error Conditions

The server SHOULD provide the following exception indicators in response to the getRequestStatus request:

7.1.7 fetchRequestStatus()

The fetchRequestStatus method allows the client to determine the current status of a previously submitted asynchronous request or set of asynchronous requests. The FetchStatusRequest and FetchStatusResponse structures have been defined in the API schema to encapsulate the request and response data, respectively, for this operation.

Request

The request structure may include any number of request ID strings as returned in response to asynchronous method calls. The request is REQUIRED to provide at least one request identifier.

Response

The result of a fetchStatusRequest call is a FetchStatusResponse object that MUST contain a status object reflecting the status of the fetchRequestStatus operation. If the request is successful, a ProvisioningObjectStatus structure should be returned for each request identifier supplied in the request. Each status MUST include the request identifier and status code reflecting the server's view of the status of the request. If the request has proceeded to the point where the server has an available ProvisionedItem instance associated with the request, the identifier for the item SHOULD be included in the response. An identifier SHOULD NOT be returned by the service unless it is prepared to honor fetchProvisionedItems() requests for the specified identifier.

Error Conditions

The server SHOULD provide the following exception indicators in response to the getRequestStatus request:

Additionally, each response status instance corresponding to a specific request identifier SHOULD indicate the following errors:

7.1.8 cancelRequest()

The cancelRequest operation cancels a set of outstanding asynchronous requests. The CancelRequest and CancelResponse structures have been defined in the API schema to encapsulate the request and response data, respectively, for this operation.

Request

The request structure contains a set of request ID strings identifying the asynchronous requests that will be canceled. At least one request identifier must be specified.

Response

The result of a cancelRequest call is a CancelResponse object that MUST contain a status object reflecting the status of the operation for each request that was to be canceled. The status objects MUST contain the corresponding request identifier.

Error Conditions

The server SHOULD provide the following exception indicators in response to the cancelRequest operation:

7.2 Asynchronous Operations

7.2.1 provision()

Execution of a provision method indicates to the server that a target resource should be provisioned with a specific set of parameters. 

Request

The ProvisionRequest structure contains the necessary information to complete the provisioning operation, including the target identification information, any parameters required to satisfy the target schema requirements, and possibly an owner identifier.  It is an error to include data in the parameters that does not comply with the schema for the identified target.

Response

The response message from a provision request, ProvisionResponse, MUST include a ProvisioningRequestStatus instance.  If the request executes asynchronously, the response MUST include a request identifier string. If the request executes synchronously, the service SHOULD return the resulting ProvisionedItem in the response and MUST NOT return a request identifier.

If the server executes this request asynchronously, it may be some time before a ProvisionedItem object is available with an assigned identifier.  Because of this, service instances are NOT REQUIRED to list ProvisionedItem objects (in response to listProvisionedItems() or fetchProvisionedItems() requests) that may result from this operation until they have been activated at the server.  If ProvisionedItem instances are exposed through the listProvisionedItems() and fetchProvisionedItems() methods before they have been fully provisioned, the server is REQUIRED to maintain the same identifier for the remainder of the instance's lifetime.  

Error Conditions

The server SHOULD provide the following exception indicators in response to the provision request:

7.2.2 deprovision()

The deprovision operation removes a ProvisionedItem object from the system.

Request

The DeprovisionRequest structure is used to communicate the ProvisionedItem object to be deleted and, optionally, a set of parameters that may be used by the Provisioning service to execute the request. The item structure should include only the minimal schema-conformant data set for the item to be deprovisioned.

Response

The response message from a deprovision request, DeprovisionResponse, MUST include a status object indicating the outcome of the request. If the request completes synchronously and is successful, the response MAY include the ProvisionedItem that was deprovisioned, at the server's discretion. If the request executes asynchronously, the status object returned MUST include a request identifier for the operation and SHOULD NOT include the ProvisionedItem instance.

Error Conditions

The server SHOULD provide the following exception indicators in response to the deprovision request:

7.2.3 modifyProvisionedState()

The modifyProvisionedState method allows a client to control the state of a ProvisionedItem object. This is the mechanism by which operations such as suspension or termination of, for example, an account might be effected.

Request

The modification of the state of a ProvisionedItem object is performed using a ModifyProvisionedStateRequest structure containing the desired final state as one of the values enumerated in the values returned for a ProvisioningTarget and an identifier for the ProvisionedItem instance to modify. The request object MAY include a reason specifier which is an instance of the ProvisioningRequestStatus structure. If included in the request and the request completes without error, the reason structure will be used in any lifecycle reports returned from listProvisionedLifecycle for the specified ProvisionedItem object.

Response

The response message from a modifyProvisionedState request, ModifyProvisionedStateResponse, MUST include a status object reflecting the outcome of the request. In the absence of any errors, if the request is to execute asynchronously, the status object WILL include a request identifier. If the request executes synchronously, the status object MUST NOT include a request identifier and, if successful, the response structure SHOULD include the ProvisionedItem instance reflecting the new state at the server.

Error Conditions

The server SHOULD provide the following exception indicators in response to the modifyProvisionedState request:

7.2.4 modifyProvisionedParameters()

The modification of parameters associated with a provisioned resource is the most complex of the operations defined by this specification. This operation allows specific portions of a ProvisionedItem parameters to be modified or deleted.

Request

The request requires that the client identify:

The ModifyProvisonedParametersRequest structure encapsulates these data items. A ProvisionedItem instance is required to identify the item and target to be modified. This item SHOULD include only the minimal schema-compliant data set for the ProvisionedItem type. The request may contain any number of ParameterModification objects, each holding a single modification description. The ParameterModification structure uses an XPath expression to identify the elements to be operated on, which is contained in a ProvisioningSelector instance. The root element for the expression is the child element of the ProvisionedItem parameters element. Each modification has an operation enumerated that describes how the parameters are to be modified (add, replace, or delete)and a set of parameters which constitute the modification data. Note that it is permitted to include parameters with all modification operations including delete.

The schema allows each ParameterModification structure to contain an identifier. This allows clients to identify the status of particular modifications in the response when multiple modifications are submitted in a single request. Clients may wish to omit this identifier when submitting a single modification request.

The following examples show how a set of modification requests might be created for a ProvisionedItem instance that is used by a fictitious milk delivery service called MilkMan.com. For this example, the company provides a target that represents the milk products that the service can deliver.

<ProvisioningTarget xmlns="urn:ibm:names:ws:provisioning:0.1:core">
    <identifier name="http://www.milkman.com/targets/milkonly"/>
    <description xml:Lang="en">Milk deliveries from MilkMan.com</description>
    <schema ref="milk:Deliveries" namespace="http://www.w3.org/2001/XMLSchema" 
            xmlns:milk="http://www.milkman.com/schema/milk">
        <schema xmlns="http://www.w3.org/2001/XMLSchema" 
            targetNamespace="http://www.milkman.com/schema/milk" elementFormDefault="qualified">
            <simpleType name="FatContentType">
                <restriction base="string">
                <enumeration value="nonfat"/>                 
                <enumeration value="lowfat"/>
                <enumeration value="whole"/>
                </restriction>
            </simpleType>
            <simpleType name="ProductionType">
                <restriction base="string">
                <enumeration value="organic"/>                    
                <enumeration value="conventional"/>
                </restriction>
            </simpleType> 
            <simpleType name="VendorType">
                <restriction base="string">
                <enumeration value="Horizon"/>                    
                <enumeration value="AltaDena"/>
                <enumeration value="Knudsen"/>
                </restriction>
            </simpleType> 
            <simpleType name="ContainerType">
                <restriction base="string">
                <enumeration value="gallon"/>                 
                <enumeration value="half-gallon"/>
                <enumeration value="quart"/>
                <enumeration value="pint"/>                       
                </restriction>
            </simpleType> 
            <complexType name="MilkType">
                <sequence>
                <element name="fatContent" type="milk:FatContentType" minOccurs="0" maxOccurs="1"/>
                <element name="production" type="milk:ProductionType" minOccurs="0" maxOccurs="1"/>
                <element name="vendor" type="milk:VendorType" minOccurs="0" maxOccurs="1"/>
                <element name="size" type="milk:ContainerType" minOccurs="1" maxOccurs="1"/>                      
                <element name="quantity" type="int" minOccurs="1" maxOccurs="1"/>
                </sequence>
            </complexType>
            <element name="Deliveries">
                <complexType>
                    <sequence>
                        <element name="item" type="milk:MilkType" minOccurs="0" maxOccurs="unbounded"/>
                    </sequence>
                </complexType> 
            </element>
        </schema>
    </schema>     
</ProvisioningTarget>

The target schema identifies the Deliveries element as the target type using the ref attribute. The Simpson family already has an account with MilkMan.com, represented by the following ProvisionedItem which indicates that the family has a gallon of nonfat and a gallon of whole milk delivered.

<ProvisionedItem>
    <identifier name="Simpsons:001"/>
    <target name="http://www.milkman.com/targets/milkonly"/>
    <state>active</state>
    <parameters>
        <Deliveries xmlns="http://www.milkman.com/schema/milk">
            <item>
                <fatContent>nonfat</fatContent>
                <production>organic</production>
                <vendor>Horizon</vendor>
                <size>gallon</size>
                <quantity>1</quantity>
            </item>
            <item>
                <fatContent>whole</fatContent>
                <production>organic</production>
                <vendor>Horizon</vendor>
                <size>gallon</size>
                <quantity>1</quantity>
            </item>
        </Deliveries>
    </parameters>    
</ProvisionedItem>

7.2.4.1 Add Modifications

To add a data item to a ProvisionedItem instance's set of parameters, the XPath expression in the request must identify the parent element that will receive the additional data. For our example, we might want to add another milk delivery of a pint of lowfat milk. The request might look like the following:

<ModifyProvisionedParametersRequest xmlns="urn:ibm:names:ws:0.1:provisioning:api"
                                    xmlns:core="urn:ibm:names:ws:0.1:provisioning:core">
    <item>
        <identifier name="Simpsons:001"/>
        <target name="http://www.milkman.com/targets/milkonly"/>
    </item>
    <modification operation="add">
        <selector>
            <core:select>/milk:Deliveries</core:select>
            <core:namespace prefix="milk" uri="http://www.milkman.com/schema/milk"/>
        </selector>
        <parameters>
            <Milk xmlns="http://www.milkman.com/schema/milk">
                <fatContent>lowfat</fatContent>
                <quantity>1</quantity>	
                <vendor>Horizon</vendor>
                <size>pint</size>						
            </Milk>
        </parameters>
    </modification>
</ModifyProvisionedParametersRequest>
7.2.4.2 Replace Modifications

When replacing an element in the ProvisionedItem parameters, the XPath expression must identify the top-level element to be replaced. For this example, we will replace the original production specifier of "conventional" for the gallon of whole milk with an organic specifier.

<ModifyProvisionedParametersRequest xmlns="urn:ibm:names:ws:0.1:provisioning:api"
                                    xmlns:core="urn:ibm:names:ws:0.1:provisioning:core">
    <item>
        <identifier name="Simpsons:001"/>
        <target name="http://www.milkman.com/targets/milkonly"/>
    </item>
    <modification operation="replace">
        <selector>
            <core:select>/milk:Deliveries/milk:item[1]/production</core:select>
            <core:namespace prefix="milk" uri="http://www.milkman.com/schema/milk"/>
        </selector>
        <parameters>
            <production xmlns="http://www.milkman.com/schema/milk">organic</production>
        </parameters>
    </modification>
</ModifyProvisionedParametersRequest>

This example highlights a potential hazard with this kind of modification when using positional selection expressions. Our previous add operation, for example, gave no guarantees about the position in which the add would take place. In practice, operations like this should use positional parameters only when there is certainty about the format of the parameters. It would be wiser in most cases to use a more unique expression for the modification. Another alternative would be to publish the target as a single milk request rather than as a list, then each ProvisionedItem object would have an assigned identifier which would aid in the identification of the specific parameters to be changed.

7.2.4.3 Delete Modifications

A delete modification simply removes a specified element from the ProvisionedItem instance's parameters. In this case we remove the delivery of all nonfat milk and no additional parameters are required.

<ModifyProvisionedParametersRequest xmlns="urn:ibm:names:ws:0.1:provisioning:api"
                                    xmlns:core="urn:ibm:names:ws:0.1:provisioning:core">
    <item>
        <identifier name="Simpsons:001"/>
        <target name="http://www.milkman.com/targets/milkonly"/>
    </item>
    <modification operation="delete">
        <selector>
            <core:select>/milk:Deliveries/milk:item[milk:fatContent='nonfat']</core:select>
            <core:namespace prefix="milk" uri="http://www.milkman.com/schema/milk"/>
        </selector>
    </modification>
</ModifyProvisionedParametersRequest>
Response

In response to a modifyProvisionedParameters request, the service returns a ModifyProvisionedParametersResponse. The response includes an overall status for the request and a set of ProvisioningObjectStatus structures, one for each of the ParameterModification elements submitted in the request. If the request ParameterModification includs an identifier, the service implementation MUST return the identifier provided in the ParameterModification in the corresponding ProvisioningObjectStatus.

The final ProvisioningServiceResponse for this request, whether it executes synchronously or asynchronously, will indicate the overall success or failure of the complete request. Note that the server SHOULD, but is NOT REQUIRED to, execute a set of modification operations for a single request atomically, i.e. they should all fail or all succeed.

The response also includes the ability to OPTIONALLY return the current state of the modified ProvisionedItem to the client.

Error Conditions

The server SHOULD provide the following exception indicators in response to the modifyProvisionedParameters request:

7.3 Sample Usage Scenario (non-normative)

The following scenario illustrates the use of WS-Provisoning in conjunction with a target that is restricted to LDAP-type operations and schema.  Since there is a large number of existing systems in the market based on directories, this might be a useful illustration of how WS-Provisioning allows legacy systems to be provisioned.  For more extensive examples please refer to the examples section later in this document.  Note that for clarity and brevity, the XML segments in the following examples have been abbreviated slightly and most of the SOAP encapsulation has been omitted.

7.3.1 Retrieving the Targets

The server for this example is acting as an adapter between the WS-Provisioning ProvisioningService and an LDAP directory.  For the purposes of this example, the service will publish three targets which correspond to different portions of a Directory Information Tree (DIT) that the server wishes to expose.  Two sub-trees contain an LDAP standard representation of a person, object class 'person', and the other instances of an object class for groups, 'groupOfNames'.  The listTargets request would look something like the following: 

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <SOAP-ENV:Body>
    <ListTargetsRequest xmlns="urn:ibm:names:ws:0.1:provisioning:api"/>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

In this case there are no parameters to the operation.  The response lists the targets in short form, indicating that it will provide schema using DSML version 1.

<ListTargetsResponse xmlns="urn:ibm:names:ws:0.1:provisioning:api"
                     xmlns:core="urn:ibm:names:ws:0.1:provisioning:core"
                     remaining="0">
    <targets>
        <core:ProvisioningTarget name="Buffalo People">
            <core:identifier name="ou=People,dc=buffalo,dc=bovine,dc=com"/>
            <core:schema namespace="http://www.dsml.org/DSML"/>
        </core:ProvisioningTarget>
        <core:ProvisioningTarget name="Cat People">
            <core:identifier name="ou=People,dc=panther,dc=feline,dc=com"/>
            <core:schema namespace="http://www.dsml.org/DSML"/>
        </core:ProvisioningTarget>
        <core:ProvisioningTarget name="Cat Managers">
            <core:identifier name="ou=Managers,dc=panther,dc=feline,dc=com"/>
            <core:schema namespace="http://www.dsml.org/DSML"/>
        </core:ProvisioningTarget>
    </targets>
    <status>
        <core:code>success</core:code>
    </status>
</ListTargetsResponse>

7.3.2 Getting the Schema

Once the client has the target identifiers, it can retrieve any details about each target using the fetchTarget operation.  For example:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <SOAP-ENV:Body>
        <FetchTargetRequest xmlns="urn:ibm:names:ws:0.1:provisioning:api">
            <identifier name="ou=People,dc=buffalo,dc=bovine,dc=com"/>
        </FetchTargetRequest>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

The server will then return all available information about the identified target.  In this case, the server uses DSML version 1 schema to describe the target.

<FetchTargetResponse xmlns="urn:ibm:names:ws:0.1:provisioning:api"
                     xmlns:core="urn:ibm:names:ws:0.1:provisioning:core">
    <status>
        <core:code>success</core:code>
    </status>
    <target name="Buffalo People">
        <core:identifier name="ou=People,dc=buffalo,dc=bovine,dc=com"/>
        <core:description xml:Lang="en">The people in Buffalo</core:description>
        <core:description xml:Lang="fr">Les gens de Buffalo</core:description>
        <core:description xml:Lang="ga">Daoine as Buffalo</core:description>
        <core:schema namespace="http://www.dsml.org/DSML">
            <core:element>
                <core:select>"//class[name='person']"</core:select>
            </core:element>
            <dsml xmlns="http://www.dsml.org/DSML">
                <directory-schema>
                    <attribute-type>
                        <name>name</name>
                        <object-identifier>2.5.4.41</object-identifier>
                        <syntax>1.3.6.1.4.1.1466.115.121.1.15{32768}</syntax>
                    </attribute-type>

                    <!-- Other attribute type definitions omitted -->

                    <class superior="top" type="structural">
                        <name>person</name>
                        <object-identifier>2.5.6.6</object-identifier>
                        <attribute ref="sn" required="true" />
                        <attribute ref="cn" required="true" />
                        <attribute ref="userPassword" required="false" />
                        <attribute ref="telephoneNumber" required="false" />
                        <attribute ref="seeAlso" required="false"/>
                        <attribute ref="description" required="false" />
                    </class>
                </directory-schema>
            </dsml>
        </core:schema>
    </target>
</FetchTargetResponse>

The server identifies the root schema element using an XPath expression that indicates that the class element with a child name element of 'person' is the root.  A similar fetchTarget request and response sequence can be repeated for the other targets reported by listTargets. 

7.3.3 Provisioning

Ultimately, the client will wish to provision a person, group or both, possibly after retrieving data from a user.  This is accomplished using the provision method which takes a ProvisionRequest. 

<ProvisionRequest xmlns="urn:ibm:names:ws:0.1:provisioning:api"
                  xmlns:core="urn:ibm:names:ws:0.1:provisioning:core">
    <target name="ou=People,dc=buffalo,dc=bovine,dc=com"/>
    <parameters>
        <dsml:dsml xmlns:dsml="http://www.dsml.org/DSML">
            <dsml:directory-entries>
                <dsml:entry dn="uid=scarter,ou=People,dc=buffalo,dc=bovine,dc=com">
                    <dsml:objectclass>
                        <dsml:oc-value>top</dsml:oc-value>
                        <dsml:oc-value>person</dsml:oc-value>
                    </dsml:objectclass>
                    <dsml:attr name="sn">
                        <dsml:value>Carter</dsml:value>
                    </dsml:attr>
                    <dsml:attr name="telephoneNumber">
                        <dsml:value>+1 408 555 4798</dsml:value>
                    </dsml:attr>
                    <dsml:attr name="cn">
                        <dsml:value>Sam Carter</dsml:value>
                    </dsml:attr>
                    <dsml:attr name="userPassword">
                        <dsml:value encoding="base64">c3ByYWlu</dsml:value>
                    </dsml:attr>
                </dsml:entry>
            </dsml:directory-entries>
        </dsml:dsml>
    </parameters>
</ProvisionRequest>

The response in this case includes a ProvisionedItem instance because, for this example, the service does not have any workflow so the request is satisfied immediately.  The actual state of the data in the target is reflected in the parameters.

<ProvisionResponse xmlns="urn:ibm:names:ws:0.1:provisioning:api"
                   xmlns:core="urn:ibm:names:ws:0.1:provisioning:core">
    <status>
        <core:code>success</core:code>
        <core:message xml:Lang="en">success</core:message>
    </status>
    <item>
        <core:identifier name="uid=scarter,ou=People,dc=buffalo,dc=bovine,dc=com"/>
        <core:target name="ou=People,dc=buffalo,dc=bovine,dc=com"/>
        <core:state>active</core:state>
        <core:parameters>
            <dsml:dsml xmlns:dsml="http://www.dsml.org/DSML">
                <dsml:directory-entries>
                    <dsml:entry dn="uid=scarter,ou=People,dc=buffalo,dc=bovine,dc=com">
                        <dsml:objectclass>
                            <dsml:oc-value>top</dsml:oc-value>
                            <dsml:oc-value>person</dsml:oc-value>
                        </dsml:objectclass>
                        <dsml:attr name="sn">
                            <dsml:value>Carter</dsml:value>
                        </dsml:attr>
                        <dsml:attr name="telephoneNumber">
                            <dsml:value>+1 408 555 4798</dsml:value>
                        </dsml:attr>
                        <dsml:attr name="cn">
                            <dsml:value>Sam Carter</dsml:value>
                        </dsml:attr>
                        <dsml:attr name="userPassword">
                            <dsml:value encoding="base64">c3ByYWlu</dsml:value>
                        </dsml:attr>
                    </dsml:entry>
                </dsml:directory-entries>
            </dsml:dsml>
        </core:parameters>
    </item>
</ProvisionResponse>

7.3.4 Modifying Target Data

At some point after the provisioning process has completed, the parameters associated with a ProvisionedItem instance may need to be updated.  This is done using the modifyProvisionedParameters method.  In this case, the telephone number associated with our person, Sam Carter, is replaced with another value. 

<ModifyProvisionedParametersRequest xmlns="urn:ibm:names:ws:0.1:provisioning:api"
                                    xmlns:core="urn:ibm:names:ws:0.1:provisioning:core">
    <item name="uid=scarter,ou=People,dc=buffalo,dc=bovine,dc=com"/>
    <modifications operation="replace">
        <selector>
            <core:select>//dsml:attr[@name='telephoneNumber']</core:select>
            <core:namespace prefix="dsml" uri="http://www.dsml.org/DSML"/>
        </selector>
        <parameters>
            <value xmlns="http://www.dsml.org/DSML">+1 408 555 4799</value>
        </parameters>
    </modifications>
</ModifyProvisionedParametersRequest>

7.3.5 Alternative Approaches

This example explores one of many approaches to exposing the provisioning of portions of a directory.  As one alternative, the service could have chosen to hide the details of the Directory Information Tree (DIT) from the client and simply provided the object classes as targets rather than specific sub-trees and then decide internally how the requests map to the physical directory. 

In this case, the targets were quite strict in identifying only a single class as the root type in their schema. The directory that this fictitious service ultimately provisioned to would not impose such constraints. The service could have elected to omit the specification of the root type and allow the client to add instances of any of a number of schema elements to the directory. The service could then have published all of the directory schema as the target schema. If the objective was to provide complete access to the directory in much the same way as a normal directory, but through WS-Provisioning (perhaps the directory was to be aggregated with other WS-Provisoning providers), then the targets could be simply the root naming contexts.

The example was intended to show, among other things, that it is possible to use any XML-based schema languages within WS-Provisioning.  DSMLv1 schema introduces some limitations however, since it is quite restrictive compared to languages such as XML Schema.  For example, it is difficult to convey the relationship between a group and a user in this example.  If the service were to take advantage of a more powerful schema language, the relationship could be much more explicit.  The fact that DSMLv1 provides a directory schema language and not an XML schema language is important distinction here because the act of provisioning in this case requires quite a lot of out-of-band knowledge of the transformation between the schema and the instance data. 

8. The Notification Service APIs

The Notification APIs define an OPTIONAL service that allows clients to register and receive notifications about events within the provisioning system.  While the specification provides for the execution of long running operations in an asynchronous manner using the ProvisioningService APIs, the server must be polled to determine the result of a request.  This approach is sufficient for simple user-initiated interactions, but polling is likely to introduce too much overhead in situations where, for example, a workflow process may be stalled based on the result of an operation.  In those situations the notification API may be used. Only events pertaining to ProvisionedItem objects are available through this API.

8.1 The ProvisioningNotification API

There are two interfaces defined pertaining to notification of events: the ProvisioningNotification service and the NotificationListener API. The ProvisioningNotification Service API offers two operations:

8.1.1 Subscribe

The subscribe method accepts a SubscribeRequest structure. This structure MUST include a valid URL for an implementation of the NotificationListener interface. A filter MAY be included in the request that allows the selection of specific ProvisionedItem instances as sources of events. This is defined using a ProvisionedItemFilter instance. The ProvisionedItemFilter is described earlier in the ProvisionedItem Filters section. Operations that affect any ProvisionedItem instances that match the combined criteria specified will result in an event. Alternatively, a NotificationSubscription instance, returned from a previous subscribe request, may be included to renew a subscription.

The request MAY also specify a notification interval that indicates the maximum frequency with which the listener wishes to be notified of events. If present, the server SHOULD NOT generate events to the listener at intervals less than the specified duration. If not specified, the server MAY notify the listener of events at its own discretion but it is RECOMMENDED that the absence of a notification interval be viewed as a request for synchronous notification.

The subscribe request returns a NotificationSubscription object which may be used to identify the subscription when performing an unsubscribe or when renewing a subscription. An expiration date and time MAY also be included by the server to indicate to the client that the subscription will be terminated by a certain time. To ensure uninterrupted receipt of events, clients should re-subscribe before the expiration time.

8.1.2 Unsubscribe

The unsubscribe operation notifies the server that a client is no longer interested in receiving events. The request MUST contain a NotificationSubscription instance returned from a previous invocation of the subscribe operation.

8.2 The NotificationListener API

The NotificationListener interface defines a single operation, notify. This operation will be invoked by the Notification Service to indicate that a provisioning event has occurred.

The notify operation accepts a ProvisioningEventSet that contains a number of events and an interval element specifying the start and end period for the events. In response to a notify, the listener WILL return a ProvisioningRequestStatus structure to indicate the status of the notify operation. The ProvisioningEventSet and ProvisioningEvent types have been described in more detail earlier.

8.2.1 Notify Result Codes

The listener implementation SHOULD provide the following indicators in response to the notify request:

8.3 Connection Behavior

The notification service operates in a disconnected mode where there is no long-term connection maintained between the service and listeners. Connections will be created from the service to the subscriber when the service wishes to communicate an event or set of events. Failure to establish a connection will result in a postponement of the notification for an interval that is determined by the server. If this interval exceeds the subscription interval, i.e. goes beyond the expiration of the subscription, the server is still obliged to communicate any events that occurred during the subscription interval when a connection can be established.

If multiple connection attempts on the part of the service fail, the server MAY elect to automatically unsubscribe the client. The number and duration of retries is a matter of server policy.

Appendix A. Core WS-Provisioning Schema

The core schema is available in XML form here. Detailed documentation is here.

Appendix B. Notification Service Schema

The Notification Service schema is available in XML form here. Detailed documentation is here.

Appendix C. API Schema

The API schema is available in XML form here. Detailed documentation is here.

Appendix D. Provisioning Services WSDL

The ProvisioningService, NotificationService, and NotificationListener interface definitions are available here.

Appendix E. Examples

Telecom Example

The Telecom example shows how a provider of telephone services might aggregate services from a set of subsidiaries.  This is a fictitious scenario intended to highlight the capabilities of WS-Provisioning when applied to Web Services.

JNDI Bridge Example

This example is a detailed, fully functional, implementation of the ProvisioningService interface that acts as a bridge between WS-Provisioning and JNDI.  The bridge is implemented as a Java Web Application and offers a simple configuration utility that allows the user to select the way in which schema information is published and which aspects of the JNDI namespace may be provisioned.  The example shows how WS-Provisioning can encapsulate legacy APIs to offer a consistent provisioning interface across older systems, particularly directory-based systems. Schema for each target DIT is published using DSMLv1 or XML Schema.

Service Aggregator

The aggregator is a functional implementation of the ProvisioningService interface that allows a set of ProvisioningService instances to be viewed as a single service.

Appendix F. Glossary of Terms

References

PSTC Use Cases

UDDI Version 3

XML Schema

WSDL

XPath

The xml: Namespace

Web Services Security (WS-Security)


Last update: $Date: 2003/10/07 17:47:32 $