From 2979443e32780f1fb31eb9edde00af7c50a5d4ab Mon Sep 17 00:00:00 2001
From: Mark Craig <mark.craig@forgerock.com>
Date: Tue, 14 May 2013 14:14:32 +0000
Subject: [PATCH] CR-1681 Fix for OPENDJ-896: Document patch support for REST

---
 opendj3/src/main/docbkx/admin-guide/chap-rest-operations.xml |  254 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 253 insertions(+), 1 deletions(-)

diff --git a/opendj3/src/main/docbkx/admin-guide/chap-rest-operations.xml b/opendj3/src/main/docbkx/admin-guide/chap-rest-operations.xml
index bdde21b..712288a 100644
--- a/opendj3/src/main/docbkx/admin-guide/chap-rest-operations.xml
+++ b/opendj3/src/main/docbkx/admin-guide/chap-rest-operations.xml
@@ -512,7 +512,259 @@
  <section xml:id="patch-rest">
   <title>Patching Resources</title>
 
-  <para>TODO, https://bugster.forgerock.org/jira/browse/CREST-3</para>
+  <para>OpenDJ lets you patch JSON resources, updating part of the resource
+  rather than replacing it. For example, you could change Babs Jensen's
+  email address by issuing an HTTP PATCH request, as in the example that
+  follows.</para>
+
+  <para>Notice that the data sent specifies the type of patch operation, the
+  field to change, and a value that depends on the field you change and on the
+  operation. A single-valued field takes an object, boolean, string, or number
+  depending on its type, whereas a multi-valued field takes an array of values.
+  Getting the type wrong results in an error. Also notice that the patch data is
+  itself an array, since you could patch more than one part of the resource by
+  using a set of patch operations in the same request.</para>
+
+  <screen>$ curl
+ --user kvaughan:bribery
+ --request PATCH
+ --header "Content-Type: application/json"
+ --data '[
+  {
+    "operation": "replace",
+    "field": "/contactInformation/emailAddress",
+    "value": "babs@example.com"
+  }
+ ]'
+ http://opendj.example.com:8080/users/bjensen?_prettyPrint=true
+{
+  "_rev" : "00000000f3fdd370",
+  "schemas" : [ "urn:scim:schemas:core:1.0" ],
+  "contactInformation" : {
+    "telephoneNumber" : "+1 408 555 1862",
+    "emailAddress" : "babs@example.com"
+  },
+  "_id" : "bjensen",
+  "name" : {
+    "familyName" : "Jensen",
+    "givenName" : "Barbara"
+  },
+  "userName" : "babs@example.com",
+  "displayName" : "Barbara Jensen",
+  "meta" : {
+    "lastModified" : "2013-05-13T14:35:31Z"
+  },
+  "manager" : [ {
+    "_id" : "trigden",
+    "displayName" : "Torrey Rigden"
+  } ]
+}</screen>
+
+  <variablelist>
+   <para>OpenDJ supports four types of patch operation.</para>
+
+   <varlistentry>
+    <term>"add"</term>
+    <listitem>
+     <para>The add operation ensures that the target field contains the value
+     provided, creating parent fields as necessary.</para>
+
+     <para>If the target field is single-valued and a value already exists, then
+     that value is replaced with the value you provide. <emphasis
+     role="strong">Note that you do not get an error when adding a value to a
+     single-valued field that already has a value.</emphasis> A single-valued
+     field is one whose value is not an array (an object, string, boolean, or
+     number).</para>
+
+     <para>If the target field is multi-valued, then the array of values you
+     provide is merged with the set of values already in the resource. New
+     values are added, and duplicate values are ignored. A multi-valued field
+     takes an array value.</para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term>"remove"</term>
+    <listitem>
+     <para>The remove operation ensures that the target field does not contain
+     the value provided. If you do not provide a value, the entire field is
+     removed if it already exists.</para>
+
+     <para>If the target field is single-valued and a value is provided, then
+     the provided value must match the existing value to remove, otherwise the
+     field is left unchanged.</para>
+
+     <para>If the target field is multi-valued, then values in the array you
+     provide are removed from the existing set of values.</para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term>"replace"</term>
+    <listitem>
+     <para>The replace operation removes existing values on the target field,
+     and replaces them with the values you provide. It is equivalent to
+     performing a remove on the field, then an add with the values you
+     provide.</para>
+    </listitem>
+   </varlistentry>
+
+   <varlistentry>
+    <term>"increment"</term>
+    <listitem>
+     <para>The increment operation increments or decrements the value or values
+     in the target field by the amount you specify, which is positive to
+     increment, negative to decrement. The target field must be a number or
+     a set of numbers. The value you provide must be a single number.</para>
+    </listitem>
+   </varlistentry>
+  </variablelist>
+
+  <para>One key nuance in how patch works with OpenDJ has to do with
+  multi-valued fields. Although JSON resources represent multi-valued fields as
+  <emphasis>arrays</emphasis>, OpenDJ treats those values as
+  <emphasis>sets</emphasis>. In other words, values in the field are unique,
+  and the ordering of an array of values is not meaningful in the context of
+  patch operations. If you reference array values by index, OpenDJ returns
+  an error.<footnote><para>OpenDJ does let you use a hyphen as the last element
+  of the "field" JSON pointer value to add an element to the set, as in
+  <command>curl --user kvaughan:bribery --request PATCH --header "Content-Type:
+  application/json" --data '[{ "operation" : "add", "field" : "/members/-",
+  "value" : { "_id" : "bjensen" } }]'
+  http://opendj.example.com:8080/groups/Directory%20Administrators</command>.</para>
+  </footnote></para>
+
+  <para>Instead use the patch operations as if arrays values were sets. For
+  example, you can include Barbara Jensen in a group by adding her to the set
+  of members.</para>
+
+  <screen>$ curl
+ --user kvaughan:bribery
+ --request PATCH
+ --header "Content-Type: application/json"
+ --data '[
+  {
+    "operation": "add",
+    "field": "/members",
+    "value": [
+      {
+        "_id": "bjensen"
+      }
+    ]
+  }
+ ]'
+ http://opendj.example.com:8080/groups/Directory%20Administrators
+ ?_prettyPrint=true
+{
+  "_rev" : "00000000b70c881a",
+  "schemas" : [ "urn:scim:schemas:core:1.0" ],
+  "_id" : "Directory Administrators",
+  "displayName" : "Directory Administrators",
+  "meta" : {
+    "lastModified" : "2013-05-13T16:40:23Z"
+  },
+  "members" : [ {
+    "_id" : "kvaughan",
+    "displayName" : "Kirsten Vaughan"
+  }, {
+    "_id" : "rdaugherty",
+    "displayName" : "Robert Daugherty"
+  }, {
+    "_id" : "bjensen",
+    "displayName" : "Barbara Jensen"
+  }, {
+    "_id" : "hmiller",
+    "displayName" : "Harry Miller"
+  } ]
+}</screen>
+
+  <para>Removing her from the group is similar.</para>
+
+  <screen>$ curl
+ --user kvaughan:bribery
+ --request PATCH
+ --header "Content-Type: application/json"
+ --data '[
+  {
+    "operation": "remove",
+    "field": "/members",
+    "value": [
+      {
+        "_id": "bjensen"
+      }
+    ]
+  }
+ ]'
+ http://opendj.example.com:8080/groups/Directory%20Administrators
+ ?_prettyPrint=true
+{
+  "_rev" : "00000000e241797e",
+  "schemas" : [ "urn:scim:schemas:core:1.0" ],
+  "_id" : "Directory Administrators",
+  "displayName" : "Directory Administrators",
+  "meta" : {
+    "lastModified" : "2013-05-13T16:40:55Z"
+  },
+  "members" : [ {
+    "_id" : "kvaughan",
+    "displayName" : "Kirsten Vaughan"
+  }, {
+    "_id" : "rdaugherty",
+    "displayName" : "Robert Daugherty"
+  }, {
+    "_id" : "hmiller",
+    "displayName" : "Harry Miller"
+  } ]
+}</screen>
+
+  <para>You can use resource revision numbers in <literal>If-Match:
+  <replaceable>revision</replaceable></literal> headers to patch the resource
+  only if the resource matches a particular version.</para>
+
+  <screen>$ curl
+ --user kvaughan:bribery
+ "http://opendj.example.com:8080/users/bjensen?_prettyPrint=true&amp;_fields=_rev"
+{
+  "_rev" : "00000000c1b6d4c7"
+}
+$ curl
+ --user kvaughan:bribery
+ --request PATCH
+ --header "If-Match: 00000000c1b6d4c7"
+ --header "Content-Type: application/json"
+ --data '[
+  {
+    "operation": "add",
+    "field": "/contactInformation/emailAddress",
+    "value": "babs@example.com"
+  }
+ ]'
+ http://opendj.example.com:8080/users/bjensen?_prettyPrint=true
+{
+  "_rev" : "00000000f946d377",
+  "schemas" : [ "urn:scim:schemas:core:1.0" ],
+  "contactInformation" : {
+    "telephoneNumber" : "+1 408 555 1862",
+    "emailAddress" : "babs@example.com"
+  },
+  "_id" : "bjensen",
+  "name" : {
+    "familyName" : "Jensen",
+    "givenName" : "Barbara"
+  },
+  "userName" : "babs@example.com",
+  "displayName" : "Barbara Jensen",
+  "meta" : {
+    "lastModified" : "2013-05-13T16:56:33Z"
+  },
+  "manager" : [ {
+    "_id" : "trigden",
+    "displayName" : "Torrey Rigden"
+  } ]
+}</screen>
+
+  <para>The resource revision changes after you successfully perform the patch
+  operation.</para>
  </section>
 
  <section xml:id="action-rest">

--
Gitblit v1.10.0