chap-sample.xml revision 257fb98c1b07e1a4385519dbff0477b1e553618a
<?xml version="1.0" encoding="UTF-8"?>
<!--
! CCPL HEADER START
!
! This work is licensed under the Creative Commons
! Attribution-NonCommercial-NoDerivs 3.0 Unported License.
! To view a copy of this license, visit
! http://creativecommons.org/licenses/by-nc-nd/3.0/
! or send a letter to Creative Commons, 444 Castro Street,
! Suite 900, Mountain View, California, 94041, USA.
!
! You can also obtain a copy of the license at
! legal/CC-BY-NC-ND.txt.
! See the License for the specific language governing permissions
! and limitations under the License.
!
! If applicable, add the following below this CCPL HEADER, with the fields
! enclosed by brackets "[]" replaced with your own identifying information:
! Portions Copyright [yyyy] [name of copyright owner]
!
! CCPL HEADER END
!
! Copyright 2011-2012 ForgeRock AS
!
-->
<chapter xml:id='chap-sample'
xmlns='http://docbook.org/ns/docbook'
version='5.0' xml:lang='en'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:schemaLocation='http://docbook.org/ns/docbook http://docbook.org/xml/5.0/xsd/docbook.xsd'
xmlns:xlink='http://www.w3.org/1999/xlink'
xmlns:xinclude='http://www.w3.org/2001/XInclude'>
<title>First OpenIDM Sample</title>
<indexterm>
<primary>Getting started</primary>
</indexterm>
<indexterm>
<primary>Samples</primary>
<secondary>Sample 1 - XML file</secondary>
</indexterm>
<indexterm>
<primary>Repository database</primary>
<secondary>Evaluation version</secondary>
</indexterm>
<para>In OpenIDM <?eval ${docTargetVersion}?>, the sample in
<filename>openidm/samples/sample1</filename> is configured and enabled by
default. This chapter provides an overview of the sample and how it is
configured. To see a listing and an overview of the rest of the samples
provided see the README found in <filename>openidm/samples</filename> and in
the chapter <link xlink:href="install-guide#chap-samples"
xlink:role="http://docbook.org/xlink/role/olink"><citetitle>More OpenIDM
Samples</citetitle></link>.</para>
<section xml:id="before-you-begin-sample">
<title>Before You Begin</title>
<para>Install and start OpenIDM as described in the chapter on <link
xlink:href="install-guide#chap-install"
xlink:role="http://docbook.org/xlink/role/olink"><citetitle>Installing
OpenIDM Services</citetitle></link>.</para>
<para>OpenIDM comes with an internal noSQL database, OrientDB for use as
the internal repository out of the box. This makes it easy to get started
with OpenIDM. OrientDB is not yet supported for production use, however,
so use a supported JDBC database when moving to production.</para>
<para>If you want to query the internal noSQL database, download and unzip
<link xlink:href="http://code.google.com/p/orient/wiki/Download"
xlink:show="new">OrientDB <?eval ${orientdbVersion}?></link>. Once you have
downloaded and unzipped OrientDB, you can find the shell console in the
<filename>bin</filename> directory. Start OrientDB console using either
<command>console.sh</command> or <command>console.bat</command>, and then
connect to the running OpenIDM with the <command>connect</command>
command.</para>
<screen>$ /path/to/orientdb-<?eval ${orientdbVersion}?>/bin/console.sh
&gt;
&gt; connect remote:localhost/openidm admin admin
Connecting to database [remote:localhost/openidm] with user 'admin'...OK
&gt;</screen>
<variablelist>
<para>Once connected to the database, you might find the following
commands useful.</para>
<varlistentry>
<term><command>info</command></term>
<listitem><para>Shows classes and records</para></listitem>
</varlistentry>
<varlistentry>
<term><command>select * from managed_user</command></term>
<listitem><para>Shows all users in the OpenIDM repository</para></listitem>
</varlistentry>
<varlistentry>
<term><command>select * from audit_activity</command></term>
<listitem><para>Shows all activity audit records</para>
<para>This table is created when there is some activity.</para></listitem>
</varlistentry>
<varlistentry>
<term><command>select * from audit_recon</command></term>
<listitem><para>Shows all reconciliation audit records</para>
<para>This table is created when you run reconciliation.</para></listitem>
</varlistentry>
</variablelist>
</section>
<section xml:id="about-the-sample">
<title>About the Sample</title>
<para>OpenIDM connects identity data objects held in external resources
by mapping one object to another. To connect to external resources,
OpenIDM uses <link xlink:href="http://openicf.forgerock.org">OpenICF</link>
connectors configured for use with the external resources.</para>
<para>When objects in one external resource change, OpenIDM determines how
the changes affect other objects, and can make the changes as necessary.
This sample demonstrates how OpenIDM does this by using
<firstterm>reconciliation</firstterm> and
<firstterm>synchronization</firstterm>. OpenIDM reconciliation compares
objects in one object set to mapped objects in another object set.
Reconciliation can work in write mode, where OpenIDM writes changes to
affected objects, or in report mode, where OpenIDM reports on what changes
would be written without making the changes. OpenIDM synchronization reflects
changes in objects to any mapped objects, making changes as necessary to
create or remove mapped objects and links to associate them. For a more
thorough explanation of reconciliation and synchronization, the section on
<link xlink:href="integrators-guide#sync-types"
xlink:role="http://docbook.org/xlink/role/olink"><citetitle>Types of
Synchronization</citetitle></link> in the <citetitle>Integrator's
Guide</citetitle>.</para>
<para>This sample connects to an XML file holding sample user data. The XML
file is configured as the authoritative source. In this sample, users are
created in the local repository to show you how you can manage local users
through the REST APIs. You can also use OpenIDM without storing managed
objects for users in the local repository, instead reconciling and
synchronizing objects directly through connectors to external
resources.</para>
<para>Furthermore, this sample involves only one external resource. In
practice, you can connect as many resources as needed for your
deployment.</para>
<variablelist xml:id="about-the-sample-configuration">
<title>Sample Configuration Files</title>
<para>You can find configuration files for the sample under the
<filename>openidm/samples/sample1/conf</filename> directory. As you review
the samples, keep the following in mind.</para>
<orderedlist>
<listitem>
<para>OpenIDM regularly scans for any scheduler configuration files in the
<filename>openidm/conf</filename> directory.</para>
</listitem>
<listitem>
<para>OpenIDM's reconciliation service reads the mappings and actions for
the source and target users from
<filename>openidm/conf/sync.json</filename>.</para>
</listitem>
<listitem>
<para>Reconciliation runs, querying all users in the source, and then
creating, deleting, or modifying users in the local OpenIDM repository
according to the synchronization mappings.</para>
</listitem>
<listitem>
<para>OpenIDM writes all operations to the audit logs in both the internal
database and also the flat files in the <filename>openidm/audit</filename>
directory.</para>
</listitem>
</orderedlist>
<para>The following configuration files play important roles in this
sample.</para>
<varlistentry>
<term><filename>openidm/conf/provisioner.openicf-xml.json</filename></term>
<listitem>
<para>This connector configuration file serves for the XML file resource.
In this sample, this connector instance acts as the authoritative source
for users. In the configuration file you can see that the
<literal>xmlFilePath</literal> is set to
<filename>samples/sample1/data/xmlConnectorData.xml</filename>, which
contains users in XML format.</para>
<para>For details on the OpenICF connector configuration files see the
<link xlink:href="integrators-guide#chap-resource-conf"
xlink:role="http://docbook.org/xlink/role/olink"
><citetitle>Connecting to External Resources</citetitle></link> chapter in
the <citetitle>Integrator's Guide</citetitle>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>openidm/conf/scheduler-reconcile_systemXmlAccounts_managedUser.json</filename></term>
<listitem>
<para>The sample scheduler configuration file defines a reconciliation
job that, if enabled by setting <literal>"enabled" : true</literal>,
starts a reconciliation each minute for the mapping named
<literal>systemXmlAccounts_managedUser</literal>. The mapping is defined
in the configuration file, <filename>conf/sync.json</filename>.</para>
<programlisting language="javascript">{
"enabled" : false,
"type": "cron",
"schedule": "0 0/1 * * * ?",
"invokeService": "org.forgerock.openidm.sync",
"invokeContext": {
"action": "reconcile",
"mapping": "systemXmlfileAccounts_managedUser"
}
}</programlisting>
<para>You can also start reconciliation through the REST interface. The
call to the REST interface is an HTTP POST such as the following.</para>
<screen width="100">$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request POST
"http://localhost:8080/openidm/sync?_action=recon&amp;mapping=systemXmlfileAccounts_managedUser"</screen>
<para>For details on the scheduler configuration see the <link
xlink:href="integrators-guide#chap-scheduler-conf"
xlink:role="http://docbook.org/xlink/role/olink"
><citetitle>Scheduling Synchronization</citetitle></link> chapter in the
<citetitle>Integrator's Guide</citetitle>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>openidm/conf/sync.json</filename></term>
<listitem>
<para>This sample configuration file defines the configuration for
reconciliation and synchronization. The
<literal>systemXmlAccounts_managedUser</literal> is the mapping for
the reconciliation in the scheduler configuration. This entry in
<filename>conf/sync.json</filename> defines the synchronization mappings
between the XML file connector (source) and the local repository
(target).</para>
<programlisting language="javascript">
{
"mappings": [
{
"name": "systemXmlfileAccounts_managedUser",
"source": "system/xmlfile/account",
"target": "managed/user",
"correlationQuery": {
"type": "text/javascript",
"source": "var query = {'_query-id' : 'for-userName',
'userName' : source.name};query;"
},
"properties": [
{
"source": "description",
"target": "description"
},
{
"source": "firstname",
"target": "givenName"
},
{
"source": "email",
"target": "email"
},
{
"source": "lastname",
"target": "familyName"
},
{
"source": "name",
"target": "userName"
},
{
"source": "name",
"target": "_id"
}
],
"policies": [
{
"situation": "CONFIRMED",
"action": "UPDATE"
},
{
"situation": "FOUND",
"action": "IGNORE"
},
{
"situation": "ABSENT",
"action": "CREATE"
},
{
"situation": "AMBIGUOUS",
"action": "IGNORE"
},
{
"situation": "MISSING",
"action": "IGNORE"
},
{
"situation": "SOURCE_MISSING",
"action": "IGNORE"
},
{
"situation": "UNQUALIFIED",
"action": "IGNORE"
},
{
"situation": "UNASSIGNED",
"action": "IGNORE"
}
]
}
]
}</programlisting>
<para>Source and target paths starting with <literal>managed</literal>,
such as <literal>managed/user</literal>, always refer to objects in the
local OpenIDM repository, whereas paths starting with
<literal>system</literal>, such as <literal>system/xmlfile/account</literal>,
refer to connector objects, in this case the XML file connector.</para>
<para>To filter objects from the resource for a particular target, you can
use the <literal>validTarget</literal> script in the mapping to ensure
only users matching specified criteria are considered part of the
reconciliation. You can use an <literal>onCreate</literal> script in a
mapping to set default values for a user created in the target resource.
For details on scripting see the <link
xlink:href="integrators-guide#appendix-scripting"
xlink:role="http://docbook.org/xlink/role/olink"
><citetitle>Scripting Reference</citetitle></link> appendix in the
<citetitle>Integrator's Guide</citetitle>.</para>
<para>For details on synchronization, reconciliation, and
<filename>sync.json</filename>, see the <link
xlink:href="integrators-guide#chap-synchronization"
xlink:role="http://docbook.org/xlink/role/olink"
><citetitle>Configuring Synchronization</citetitle></link> chapter in the
<citetitle>Integrator's Guide</citetitle>.</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section xml:id="sample-running-reconciliation">
<title>Running Reconciliation</title>
<para>If OpenIDM is not running, start it as described in the procedure
<link xlink:href="install-guide#run-openidm"
xlink:role="http://docbook.org/xlink/role/olink"><citetitle>To Start OpenIDM
Services</citetitle></link>.</para>
<para>Reconcile the objects in the resources either by editing
<filename>conf/sync.json</filename> to set <literal>"enabled" : true</literal>
and then waiting until the scheduled reconciliation happens, or by using the
REST interface.</para>
<screen width="100"><?dbfo pgwide="1"?>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request POST
"http://localhost:8080/openidm/sync?_action=recon&amp;mapping=systemXmlfileAccounts_managedUser"</screen>
<para>To see what happened, review CSV format log,
<filename>openidm/audit/recon.csv</filename>.</para>
</section>
<section xml:id="sample-viewing-users-logs">
<title>Viewing Users &amp; Logs</title>
<para>After reconciliation runs, you can use the REST interface to display
all users in the local repository, by performing an HTTP GET on the following
URL:
<literal>http://localhost:8080/openidm/managed/user/?_query-id=query-all-ids</literal>.</para>
<para>OpenIDM returns a JSON file. Depending on your browser, it can display
the JSON or download it as a file. Alternatively, you can use the following
<link xlink:href="http://curl.haxx.se/"><command>curl</command></link>
command to get the JSON file.</para>
<screen>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request GET
http://localhost:8080/openidm/managed/user/?_query-id=query-all-ids
{
"query-time-ms":1,
"result":[
{
"_id":"joe",
"_rev":"0"
},{
"_id":"DDOE1",
"_rev":"0"
}],
"conversion-time-ms":0
}
</screen>
<para>If you created user <literal>joe</literal> as described previously in
this guide, you see IDs for two users, the second user
<literal>DDOE1</literal> created during reconcililation. Now try a RESTful
GET of user <literal>DDOE1</literal> by appending the user ID to the managed
user URL,
<literal>http://localhost:8080/openidm/managed/user/</literal>.</para>
<screen>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
http://localhost:8080/openidm/managed/user/DDOE1
{
"familyName": "Doe1",
"userName": "DDOE1",
"givenName": "Darth1",
"_id": "DDOE1",
"_rev": "0",
"email": [ "mail1@example.com" ],
"description": "Created By XML1"
}</screen>
<para>In the OrientDB console, connect to the database, and then query the
users and audit logs. The following shows edited excerpts from a console
session querying OrientDB.</para>
<screen>&gt; connect remote:localhost/openidm admin admin
Connecting to database [remote:localhost/openidm] with user 'admin'...OK
&gt; select * from managed_user
---+---------+--------------------+...+--------------------+--------------------
#| RID |familyName |...|email |description
---+---------+--------------------+...+--------------------+--------------------
0| #6:0|smith |...|[1] |My first user
1| #6:1|Doe1 |...|[1] |Created By XML1
---+---------+--------------------+...+--------------------+--------------------
2 item(s) found. Query executed in 0.011 sec(s).
&gt; select * from audit_activity
---+---------+--------------------+--------------------+--------------------+...
#| RID |rev |status |timestamp |...
---+---------+--------------------+--------------------+--------------------+...
0| #11:0|0 |SUCCESS |2011-12-02T07:34:19 |...
1| #11:1|0 |SUCCESS |2011-12-02T07:34:46 |...
---+---------+--------------------+--------------------+--------------------+...
2 item(s) found. Query executed in 0.013 sec(s).
&gt; select * from audit_recon
---+---------+--------------------+--------------------+--------------------+...
#| RID |timestamp |sourceObjectId |_openidm_id |...
---+---------+--------------------+--------------------+--------------------+...
0| #12:0|2011-12-02T07:34:46 |system/xmlfile/account/1|02f5c8fd-0cc4-4a5...
1| #12:1|2011-12-02T07:34:46 |null |4707745d-6b10-4c75-9b...
---+---------+--------------------+--------------------+--------------------+...
2 item(s) found. Query executed in 0.01 sec(s).</screen>
<para>Again, this information is also available in the CSV format audit logs
located in the <filename>openidm/audit</filename> directory.</para>
<screen>$ ls /path/to/openidm/audit/
access.csv activity.csv recon.csv</screen>
</section>
<section xml:id="sample-adding-users-resource">
<title>Adding Users in a Resource</title>
<para>Add a user to the source connector XML data file to see reconciliation
in action. During the next reconciliation, OpenIDM finds the new user in the
source connector, and creates the user in the local repository. To add the
user, copy the following XML into
<filename>openidm/samples/sample1/data/xmlConnectorData.xml</filename>.</para>
<programlisting language="xml">&lt;ri:__ACCOUNT__&gt;
&lt;icf:__UID__&gt;12345&lt;/icf:__UID__&gt;
&lt;icf:__NAME__&gt;Daffy Duck&lt;/icf:__NAME__&gt;
&lt;icf:__PASSWORD__&gt;123456789&lt;/icf:__PASSWORD__&gt;
&lt;ri:email&gt;daffy.duck@forgerock.com&lt;/ri:email&gt;
&lt;ri:lastname&gt;Duck&lt;/ri:lastname&gt;
&lt;ri:firstname&gt;Daffy&lt;/ri:firstname&gt;
&lt;/ri:__ACCOUNT__&gt;</programlisting>
<para>Run reconciliation as described in the section on <link
linkend="sample-running-reconciliation"><citetitle>Running
Reconciliation</citetitle></link>. After reconciliation has run, query the
local repository to see the new user appear in the list of all users under
<literal>http://localhost:8080/openidm/managed/user/?_query-id=query-all-ids</literal>.</para>
<screen>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request GET
http://localhost:8080/openidm/managed/user/?_query-id=query-all-ids
{
"query-time-ms":1,
"result":[{
"_id":"DDOE1",
"_rev":"0"
},{
"_id":"joe",
"_rev":"0"
},{
"_id":"Daffy Duck",
"_rev":"0"
}],
"conversion-time-ms":0
}</screen>
<para>Also look at the reconciliation audit log,
<filename>openidm/audit/recon.csv</filename> to see what took place during
reconciliation. This formatted excerpt from the log covers two
reconciliation runs.</para>
<programlisting width="110"><?dbfo pgwide="1"?>
"_id", "action",...,"reconId","situation","sourceObjectId",..., "targetObjectId","timestamp";
"02...","CREATE",...,"cc0...", "ABSENT", "system/xmlfile/account/1",..., "managed/user/DDOE1",...;
"47...","IGNORE",...,"cc0...", "UNQUALIFIED","" ,..., "managed/user/joe",...;
"79...","UPDATE",...,"d15...", "CONFIRMED","system/xmlfile/account/1",..., "managed/user/DDOE1",...;
"af...","CREATE",...,"d15...", "ABSENT", "system/xmlfile/account/12345",...,"managed/user/Daffy Duck",...;
"23...","IGNORE",...,"d15...", "UNQUALIFIED","",..., "managed/user/joe",...;
</programlisting>
<para>The important fields in the audit log are the action, the situation,
the source <literal>sourceObjectId</literal>, and the target
<literal>targetObjectId</literal>. For each object in the source,
reconciliation results in a situation that leads to an action on the
target.</para>
<para>In the first reconciliation run (the abbreviated
<literal>reconID</literal> is shown as <literal>cc0...</literal>), the source
object does not exist in the target, resulting in an ABSENT situation and an
action to CREATE the object in the target. The object created earlier in the
target does not exist in the source, and so is IGNORED.</para>
<para>In the second reconciliation run (the abbreviated
<literal>reconID</literal> is shown as <literal>d15...</literal>) after you
added a user to the source XML, OpenIDM performs an UPDATE on the user object
<literal>DDOE1</literal> that already exists in the target, in this case
changing the internal ID. OpenIDM performs a CREATE on the target for the
new user.</para>
<para>You configure the action that OpenIDM takes based on an object's
situation in the configuration file, <filename>conf/sync.json</filename>.
For the list of all possible situations and actions, see the <link
xlink:href="integrators-guide#chap-synchronization"
xlink:role="http://docbook.org/xlink/role/olink"
><citetitle>Configuring Synchronization</citetitle></link> chapter in the
<citetitle>Integrator's Guide</citetitle>.</para>
<para>For details on auditing, see the <link
xlink:href="integrators-guide#chap-auditing"
xlink:role="http://docbook.org/xlink/role/olink"
><citetitle>Using Audit Logs</citetitle></link> chapter in the
<citetitle>Integrator's Guide</citetitle>.</para>
</section>
<section xml:id="sample-adding-users-rest">
<title>Adding Users Through REST</title>
<para>You can also add users directly to the local repository through the
REST interface. The following example adds a user named James Berg.</para>
<para>Create <literal>james</literal> (UNIX).</para>
<screen>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request PUT
--data '{
"name":"james",
"lastname":"Berg",
"firstname":"James",
"email":"james2@examplerock.com",
"fullname":"hallo2",
"description":"Created by OpenIDM REST.",
"userPassword":"asdfkj23"
}'
http://localhost:8080/openidm/managed/user/james
{"_id":"james","_rev":"0"}</screen>
<para>Create <literal>james</literal> (Windows).</para>
<screen>C:\&gt;curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request PUT
--data "{
\"name\":\"james\",
\"lastname\":\"Berg\",
\"firstname\":\"James\",
\"email\":\"james2@examplerock.com\",
\"fullname\":\"hallo2\",
\"description\":\"Created by OpenIDM REST.\",
\"userPassword\":\"asdfkj23\"
}"
http://localhost:8080/openidm/managed/user/james
{"_id":"james","_rev":"0"}</screen>
<para>OpenIDM creates the new user in the repository. If you configure a
mapping to apply changes from the local repository to the XML file connector
as a target, OpenAM next updates the XML file to add the new user.</para>
</section>
</chapter>