chap-samples.xml revision 006579fc6d904d79ff1065cc8aa5c244a00f41ab
<?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-samples'
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>More OpenIDM Samples</title>
<para>The current distribution of OpenIDM comes with a variety of samples
in <filename>openidm/samples/</filename>. The first,
<filename>openidm/samples/sample1</filename>, is installed by default, and
described in the <link xlink:href="install-guide#chap-sample"
xlink:role="http://docbook.org/xlink/role/olink"><citetitle>First OpenIDM
Sample</citetitle></link> chapter.</para>
<section xml:id="before-you-begin-samples">
<title>Before You Begin</title>
<para>Install 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>
<section xml:id="install-samples">
<title>Installing the Samples</title>
<indexterm>
<primary>Installing</primary>
<secondary>Samples</secondary>
</indexterm>
<para>Each sample folder in <filename>openidm/samples/</filename> contains
a list of sub folders, such as <filename>conf/</filename> and
<filename>script/</filename>, depending on which files you need to run the
sample. The easiest way to configure a new installation for one of the
samples is to copy all files in the sample folder into the appropriate
folder under <filename>openidm/</filename>. Some, but not all samples
require additional software, such as an external LDAP server or
database.</para>
<para>When you move from one sample to the next, bear in mind that you are
changing the OpenIDM configuration. For information on how configuration
changes work, see <link xlink:href="integrators-guide#when-configuring-notes"
xlink:role="http://docbook.org/xlink/role/olink">
<citetitle>Changing the Configuration</citetitle></link> in the
<citetitle>Integrator's Guide</citetitle>.</para>
</section>
<section xml:id="preparing-openidm">
<title>Preparing OpenIDM</title>
<para>Install an instance of OpenIDM specifically to try the samples. That
way you can experiment as much as you like, and discard the result if you
are not satisfied.</para>
<para>Remove the pre-installed <literal>sample1</literal> files before
starting with other samples.</para>
<screen>$ cd /path/to/openidm
$ rm conf/provisioner.openicf-xml.json
conf/sync.json
conf/schedule-reconcile_systemXmlAccounts_managedUser.json</screen>
<para>After removing the <literal>sample1</literal> files, copy the
relevant files from the sample you want to try. For example, if you want to
configure OpenIDM to use <literal>sample2</literal> then copy the
configuration files from that sample</para>
<screen>$ cp -r samples/sample2/conf .</screen>
</section>
</section>
<section xml:id="more-sample1">
<title>Sample 1 - XML File</title>
<para>Sample 1 is described in the chapter, <link
xlink:href="install-guide#chap-sample"
xlink:role="http://docbook.org/xlink/role/olink"><citetitle>First OpenIDM
Sample</citetitle></link>.</para>
</section>
<section xml:id="more-sample2">
<title>Sample 2 - LDAP One Way</title>
<indexterm>
<primary>Samples</primary>
<secondary>Sample 2 - LDAP one way</secondary>
</indexterm>
<para>Sample 2 resembles sample 1, but in sample 2 OpenIDM is connected to
a local LDAP server. The sample has been tested with <link xlink:show="new"
xlink:href="http://www.forgerock.org/opendj.html">OpenDJ</link>, but it should
work with any LDAPv3 compliant server.</para>
<para>Sample 2 demonstrates how OpenIDM can pick up new or changed objects
from an external resource. The sample contains only one mapping, from the
external LDAP server resource to the OpenIDM repository. The sample therefore
does not push any changes made to OpenIDM managed user objects out to the
LDAP server.</para>
<section xml:id="install-sample2">
<title>Install the Sample</title>
<para>Prepare OpenIDM as described in <xref linkend="preparing-openidm"/>,
copying the configuration for sample 2.</para>
<screen>$ cd /path/to/openidm
$ cp -r samples/sample2/conf .</screen>
</section>
<section xml:id="external-ldap-config-2">
<title>LDAP Server Configuration</title>
<itemizedlist>
<para>Sample 2 expects the following configuration for the external LDAP
server:</para>
<listitem><para>The LDAP server runs on the local host.</para></listitem>
<listitem><para>The LDAP server listens on port 1389.</para></listitem>
<listitem><para>A user with DN <literal>cn=Directory Manager</literal>
and password <literal>password</literal> has read access to the LDAP
server.</para></listitem>
<listitem><para>User objects are stored on the LDAP server under base DN
<literal>ou=People,dc=example,dc=com</literal>.</para></listitem>
<listitem><para>User objects have the object class
<literal>inetOrgPerson</literal>.</para></listitem>
<listitem><para>User objects have the following attributes:</para>
<itemizedlist>
<listitem><para><literal>uid</literal></para></listitem>
<listitem><para><literal>sn</literal></para></listitem>
<listitem><para><literal>cn</literal></para></listitem>
<listitem><para><literal>givenName</literal></para></listitem>
<listitem><para><literal>mail</literal></para></listitem>
<listitem><para><literal>description</literal></para></listitem>
</itemizedlist>
<para>An example user object follows.</para>
<programlisting language="ldif">
dn: uid=jdoe,ou=People,dc=example,dc=com
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: top
givenName: John
uid: jdoe
cn: John Doe
telephoneNumber: 12345
sn: Doe
mail: jdoe@example.com
description: Created by OpenIDM</programlisting>
</listitem>
</itemizedlist>
<para>Prepare the LDAP server by creating a base suffix of
<literal>dc=example,dc=com</literal>, and importing these objects from
<filename>samples/sample2/data/Example.ldif</filename>.</para>
<programlisting language="ldif">
dn: dc=com
objectClass: domain
objectClass: top
dc: com
dn: dc=example,dc=com
objectClass: domain
objectClass: top
dc: example
dn: ou=People,dc=example,dc=com
ou: people
description: people
objectclass: organizationalunit
dn: uid=jdoe,ou=People,dc=example,dc=com
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: top
givenName: John
uid: jdoe
cn: John Doe
telephoneNumber: 12345
sn: Doe
mail: jdoe@example.com
description: Created for OpenIDM
</programlisting>
</section>
<section xml:id="run-sample2">
<title>Running the Sample</title>
<para>First start OpenIDM. Then run reconciliation over the REST
interface.</para>
<screen width="91"><?dbfo pgwide="1"?>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request POST
"http://localhost:8080/openidm/recon?_action=recon&amp;mapping=systemLdapAccounts_managedUser"</screen>
<para>Successful reconciliation returns an "_id" object.</para>
<para>With the configuration of sample 2, OpenIDM creates user objects from
LDAP in OpenIDM, assigning the new objects random unique IDs. To list user
objects by ID, run a query over the REST interface.</para>
<screen>
$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request GET
"http://localhost:8080/openidm/managed/user/?_queryId=query-all-ids"</screen>
<para>The resulting JSON object should look something like this, but all on
one line.</para>
<programlisting language="javascript">
{
"query-time-ms": 1,
"result": [
{
"_id": "56f0fb7e-3837-464d-b9ec-9d3b6af665c3",
"_rev": "0"
}
],
"conversion-time-ms": 0
}</programlisting>
<para>To retrieve the user, get the object by ID.</para>
<screen width="83"><?dbfo pgwide="1"?>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request GET
"http://localhost:8080/openidm/managed/user/56f0fb7e-3837-464d-b9ec-9d3b6af665c3"</screen>
<para>Read <filename>openidm/conf/sync.json</filename> and
<filename>openidm/conf/provisioner.openicf-ldap.json</filename> to
understand the layout of the user object in the repository.</para>
</section>
</section>
<section xml:id="more-sample2b">
<title>Sample 2b - LDAP Two Way</title>
<indexterm>
<primary>Samples</primary>
<secondary>Sample 2b - LDAP two way</secondary>
</indexterm>
<para>Like sample 2, sample 2b also connects to an external LDAP
server.</para>
<para>Unlike sample 2, however, sample 2b has two mappings configured, one
from the LDAP server to the OpenIDM repository, and the other from the
OpenIDM repository to the LDAP server.</para>
<section xml:id="install-sample2b">
<title>Install the Sample</title>
<para>Prepare OpenIDM as described in <xref linkend="preparing-openidm"/>.
Copy the sample configuration, and copy the script to the
<filename>script</filename> folder.</para>
<screen>$ cd /path/to/openidm
$ cp -r samples/sample2b/conf samples/sample2b/script .</screen>
<para>If you have already installed sample 2, simply add the second mapping
from sample 2b's <filename>sync.json</filename> file to the current
<filename>sync.json</filename> file, and copy the sample script to the
<filename>script</filename> folder. The script is referenced in the second
mapping.</para>
</section>
<section xml:id="external-ldap-config-2b">
<title>External LDAP Configuration</title>
<para>Configure the LDAP server as for sample 2,
<xref linkend="external-ldap-config-2" />. The LDAP user must have write
access to create users from OpenIDM on the LDAP server.</para>
</section>
<section xml:id="run-sample2b">
<title>Running the Sample</title>
<para>First start OpenIDM, then run reconciliation over the REST
interface.</para>
<screen width="91"><?dbfo pgwide="1"?>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request POST
"http://localhost:8080/openidm/recon?_action=recon&amp;mapping=systemLdapAccounts_managedUser"</screen>
<para>Successful reconciliation returns an "_id" object.</para>
<para>With the configuration of sample 2b, OpenIDM creates user objects from
LDAP in OpenIDM, assigning the new objects random unique IDs. To list user
objects by ID, run a query over the REST interface.</para>
<screen>
$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request GET
"http://localhost:8080/openidm/managed/user/?_queryId=query-all-ids"
</screen>
<para>The resulting JSON object should look something like this, but all on
one line.</para>
<programlisting language="javascript">
{
"query-time-ms": 1,
"result": [
{
"_id": "56f0fb7e-3837-464d-b9ec-9d3b6af665c3",
"_rev": "0"
}
],
"conversion-time-ms": 0
}</programlisting>
<para>To retrieve the user, get the object by ID.</para>
<screen width="83"><?dbfo pgwide="1"?>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request GET
"http://localhost:8080/openidm/managed/user/56f0fb7e-3837-464d-b9ec-9d3b6af665c3"</screen>
<para>Test the second mapping by creating a user in the OpenIDM
repository. On UNIX:</para>
<screen width="100">$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--data '{"email":"fdoe@example.com","familyName":"Doe","userName":"fdoe",
"givenName":"Felicitas","displayName":"Felicitas Doe"}'
--request PUT
"http://localhost:8080/openidm/managed/user/repoUser1"</screen>
<para>On Windows:</para>
<screen width="100">$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request PUT
--data "{\"email\":\"fdoe@example.com\",\"familyName\":\"Doe\", \"userName\":\"fdoe\",
\"givenName\":\"Felicitas\",\"displayName\":\"Felicitas Doe\"}"
"http://localhost:8080/openidm/managed/user/repoUser1"</screen>
<para>Run reconciliation again to create the new user in the LDAP server
as well.</para>
</section>
</section>
<section xml:id="more-sample2c">
<title>Sample 2c - Synchronizing LDAP Group Membership</title>
<indexterm>
<primary>Samples</primary>
<secondary>Sample 2c - Synchronizing LDAP Group Membership</secondary>
</indexterm>
<para>Like sample 2b, sample 2c also connects to an external LDAP
server. The only difference is that in sample 2c, LDAP Group Memberships
are synchronized.</para>
<section xml:id="install-sample2c">
<title>Install the Sample</title>
<para>Prepare OpenIDM as described in <xref linkend="preparing-openidm"/>.
Copy the sample configuration, and copy the script to the
<filename>script</filename> folder.</para>
<screen>$ cd /path/to/openidm
$ cp -r samples/sample2c/conf samples/sample2c/script .</screen>
<para>If you already installed sample 2b, you simply need to add two
properties to both mappings, "systemLdapAccounts_managedUser" and
"managedUser_systemLdapAccounts" (it is the same property because the source
and the target use the same property name!): </para>
<programlisting language="javascript">
{
"source" : "ldapGroups",
"target" : "ldapGroups"
}</programlisting>
<para>In addition the following property must be added to the
"objectTypes"/"accounts" part of the provisioner configuration:</para>
<programlisting language="javascript">
"ldapGroups" : {
"type" : "array",
"items" : {
"type" : "string",
"nativeType" : "string"
},
"nativeName" : "ldapGroups",
"nativeType" : "string"
}</programlisting>
<warning><para>If you change from a previous provisioner configuration,
make sure that the LDAP groups to sync are within the search scope: </para>
<programlisting language="javascript">
"baseContexts" : [
"dc=example,dc=com"
],
"baseContextsToSynchronize" : [
"dc=example,dc=com"
],
</programlisting></warning>
</section>
<section xml:id="external-ldap-config-2c">
<title>External LDAP Configuration</title>
<para>Configure the LDAP server as for sample 2,
<xref linkend="external-ldap-config-2" />. The LDAP user must have write
access to create users from OpenIDM on the LDAP server.</para>
<para>In addition, two LDAP Groups should be created, which can be found in
the LDIF file: <filename>openidm/samples/sample2c/data/Example.ldif</filename>:</para>
<programlisting language="ldif">
dn: ou=Groups,dc=example,dc=com
ou: Groups
objectClass: organizationalUnit
objectClass: top
dn: cn=openidm,ou=Groups,dc=example,dc=com
uniqueMember: uid=jdoe,ou=People,dc=example,dc=com
cn: openidm
objectClass: groupOfUniqueNames
objectClass: top
dn: cn=openidm2,ou=Groups,dc=example,dc=com
cn: openidm2
objectClass: groupOfUniqueNames
objectClass: top</programlisting>
<para>Make sure that the user with the dn
<filename>uid=jdoe,ou=People,dc=example,dc=com</filename> exists before you
import these groups.</para>
</section>
<section xml:id="run-sample2c">
<title>Running the Sample</title>
<para>First start OpenIDM. Then run reconciliation over the REST
interface.</para>
<screen width="91"><?dbfo pgwide="1"?>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request POST
"http://localhost:8080/openidm/recon?_action=recon&amp;mapping=systemLdapAccounts_managedUser"</screen>
<para>Successful reconciliation returns an "_id" object.</para>
<para>With the configuration of sample 2c, OpenIDM creates user objects from
LDAP in OpenIDM, assigning the new objects random unique IDs. To list user
objects by ID, run a query over the REST interface.</para>
<screen>
$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request GET
"http://localhost:8080/openidm/managed/user/?_queryId=query-all-ids"
</screen>
<para>The resulting JSON object should look something like this, but all on
one line.</para>
<programlisting language="javascript">
{
"query-time-ms": 1,
"result": [
{
"_id": "56f0fb7e-3837-464d-b9ec-9d3b6af665c3",
"_rev": "0"
}
],
"conversion-time-ms": 0
}</programlisting>
<para>To retrieve the user, get the object by ID.</para>
<screen width="83"><?dbfo pgwide="1"?>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request GET
"http://localhost:8080/openidm/managed/user/56f0fb7e-3837-464d-b9ec-9d3b6af665c3"</screen>
<para>Your user's object should contain a property like: </para>
<screen>"ldapGroups":["cn=openidm,ou=Groups,dc=example,dc=com"]</screen>
<para>Now change the user on the OpdenIDM side with the following REST
call (on UNIX):</para>
<screen width="100"><?dbfo pgwide="1"?>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request POST
-d '[{"replace":"/ldapGroups","value": ["cn=openidm2,ou=Groups,dc=example,dc=com"]}]'
"http://localhost:8080/openidm/managed/user?_action=patch&amp;_queryId=for-userName&amp;uid=jdoe"
</screen>
<para>On Windows, you might need to escape certain characters, so your REST
call will look like this:</para>
<screen width="100"><?dbfo pgwide="1"?>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request POST
-d "[{\"replace\":\"/ldapGroups\",\"value\": [\"cn=openidm2,ou=Groups,dc=example,dc=com\"]}]"
"http://localhost:8080/openidm/managed/user?_action=patch&amp;_queryId=for-userName&amp;uid=jdoe"
</screen>
<para>This will change the user's ldapGroups property in OpenIDM from
<filename>"cn=openidm,ou=Groups,dc=example,dc=com"</filename> to
<filename>"cn=openidm2,ou=Groups,dc=example,dc=com"</filename> and, as a
result, the user will be removed from the one LDAP group and added to
the other LDAP group on OpenDJ.</para>
</section>
</section>
<section xml:id="more-sample2d">
<title>Sample 2d - Synchronizing LDAP Groups</title>
<indexterm>
<primary>Samples</primary>
<secondary>Sample 2d - Synchronizing LDAP Groups</secondary>
</indexterm>
<para>Sample 2d also connects to an external LDAP
server. This sample focuses on Ldap Group synchronization.</para>
<section xml:id="install-sample2d">
<title>Install the Sample</title>
<para>Prepare OpenIDM as described in <xref linkend="preparing-openidm"/>.
Copy the sample configuration, and copy the script to the
<filename>script</filename> folder.</para>
<screen>$ cd /path/to/openidm
$ cp -r samples/sample2d/conf samples/sample2d/script .</screen>
<para>If you are using OrientDB as an internal repository, update the
<filename>conf/repo.orient.json</filename> file to add a new class for
managed groups. For example, add the following:</para>
<programlisting language="javascript">
...
"managed_group": {
"index": [
{
"propertyName": "_openidm_id",
"propertyType": "string",
"indexType": "unique"
}
]
},
...
</programlisting>
<para>If you have already installed sample 2c, you need only add the managed
groups class and perform the following steps to upgrade to sample 2d:</para>
<itemizedlist>
<listitem><para>Add a mapping for the groups to
<filename>openidm/conf/sync.json</filename>.</para></listitem>
<listitem><para>Add a property for the new managed objects to
<filename>openidm/conf/managed.json</filename>.</para></listitem>
<listitem><para>Add a new property to the <literal>objectTypes</literal>
of <filename>openidm/conf/provisioner.openicf-ldap.json</filename> for the
LDAP Group objects.</para></listitem>
</itemizedlist>
<variablelist>
<varlistentry>
<term>Changes in <filename>sync.json</filename></term>
<listitem>
<para>The following shows a possible mapping which must be added to the
<filename>sync.json</filename> file:</para>
<programlisting language="javascript">
{
"name" : "systemLdapGroups_managedGroup",
"source" : "system/ldap/group",
"target" : "managed/group",
"properties" : [
{
"source" : "dn",
"target" : "dn"
},
{
"source" : "description",
"target" : "description"
},
{
"source" : "uniqueMember",
"target" : "uniqueMember"
},
{
"source" : "cn",
"target" : "name"
}
],
"policies" : [
{
"situation" : "CONFIRMED",
"action" : "UPDATE"
},
{
"situation" : "FOUND",
"action" : "UPDATE"
},
{
"situation" : "ABSENT",
"action" : "CREATE"
},
{
"situation" : "AMBIGUOUS",
"action" : "EXCEPTION"
},
{
"situation" : "MISSING",
"action" : "UNLINK"
},
{
"situation" : "SOURCE_MISSING",
"action" : "EXCEPTION"
},
{
"situation" : "UNQUALIFIED",
"action" : "IGNORE"
},
{
"situation" : "UNASSIGNED",
"action" : "IGNORE"
}
]
}
</programlisting>
</listitem>
</varlistentry>
<varlistentry>
<term>Changes in <filename>managed.json</filename></term>
<listitem>
<para>The <filename>managed.json</filename> file looks like this after
the change:</para>
<programlisting language="javascript">
{
"objects" : [
{
"name" : "user"
},
{
"name" : "group"
}
]
}
</programlisting>
</listitem>
</varlistentry>
<varlistentry>
<term>Changes in <filename>provisioner.openicf-ldap.json</filename></term>
<listitem>
<para>Add a new <literal>objectTypes</literal>-entry to
<filename>provisioner.openicf-ldap.json</filename>:</para>
<programlisting language="javascript">
"group" : {
"$schema" : "http://json-schema.org/draft-03/schema",
"id" : "__GROUP__",
"type" : "object",
"nativeType" : "__GROUP__",
"properties" : {
"seeAlso" : {
"type" : "array",
"items" : {
"type" : "string",
"nativeType" : "string"
},
"nativeName" : "seeAlso",
"nativeType" : "string"
},
"description" : {
"type" : "array",
"items" : {
"type" : "string",
"nativeType" : "string"
},
"nativeName" : "description",
"nativeType" : "string"
},
"uniqueMember" : {
"type" : "array",
"items" : {
"type" : "string",
"nativeType" : "string"
},
"nativeName" : "uniqueMember",
"nativeType" : "string"
},
"dn" : {
"type" : "string",
"required" : true,
"nativeName" : "__NAME__",
"nativeType" : "string"
},
"o" : {
"type" : "array",
"items" : {
"type" : "string",
"nativeType" : "string"
},
"nativeName" : "o",
"nativeType" : "string"
},
"ou" : {
"type" : "array",
"items" : {
"type" : "string",
"nativeType" : "string"
},
"nativeName" : "ou",
"nativeType" : "string"
},
"businessCategory" : {
"type" : "array",
"items" : {
"type" : "string",
"nativeType" : "string"
},
"nativeName" : "businessCategory",
"nativeType" : "string"
},
"owner" : {
"type" : "array",
"items" : {
"type" : "string",
"nativeType" : "string"
},
"nativeName" : "owner",
"nativeType" : "string"
},
"cn" : {
"type" : "array",
"items" : {
"type" : "string",
"nativeType" : "string"
},
"required" : true,
"nativeName" : "cn",
"nativeType" : "string"
}
}
}
</programlisting>
</listitem>
</varlistentry>
</variablelist>
</section>
<section xml:id="external-ldap-config-2d">
<title>External LDAP Configuration</title>
<para>Configure the LDAP server as for sample 2,
<xref linkend="external-ldap-config-2" />. The LDAP user must have write
access to create users from OpenIDM on the LDAP server.</para>
<para>In addition, two LDAP Groups should be created, which can be found in
the LDIF file: <filename>openidm/samples/sample2d/data/Example.ldif</filename>
(if they have not already been added through sample 2c):</para>
<programlisting language="ldif">
dn: ou=Groups,dc=example,dc=com
ou: Groups
objectClass: organizationalUnit
objectClass: top
dn: cn=openidm,ou=Groups,dc=example,dc=com
uniqueMember: uid=jdoe,ou=People,dc=example,dc=com
cn: openidm
objectClass: groupOfUniqueNames
objectClass: top
dn: cn=openidm2,ou=Groups,dc=example,dc=com
uniqueMember: uid=jdoe,ou=People,dc=example,dc=com
cn: openidm2
objectClass: groupOfUniqueNames
objectClass: top
</programlisting>
<para>Make sure that the user with the dn
<filename>uid=jdoe,ou=People,dc=example,dc=com</filename> exists before you
import these groups.</para>
</section>
<section xml:id="run-sample2d">
<title>Running the Sample</title>
<para>First start OpenIDM, then run reconciliation
<emphasis>for the groups mapping</emphasis> over the REST interface.</para>
<screen width="91"><?dbfo pgwide="1"?>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request POST
"http://localhost:8080/openidm/recon?_action=recon&amp;mapping=systemLdapGroups_managedGroup"</screen>
<para>Successful reconciliation returns an "_id" object.</para>
<para>With the configuration of sample 2d, OpenIDM creates group objects from
LDAP in OpenIDM. To list group objects by ID, run a query over the REST interface.</para>
<screen>
$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request GET
"http://localhost:8080/openidm/managed/group/?_queryId=query-all-ids"
</screen>
<para>The resulting JSON object should look something like this, but all on
one line.</para>
<programlisting language="javascript">
{
"query-time-ms":1,
"result":[
{
"_id":"3c704429-aacd-4995-816a-fac33451c642"
},
{
"_id":"b0982152-5099-4358-bdd1-45a39ebe0d77"
}
]
}</programlisting>
<para>To retrieve a group, get the object by ID.</para>
<screen width="83"><?dbfo pgwide="1"?>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request GET
"http://localhost:8080/openidm/managed/group/b0982152-5099-4358-bdd1-45a39ebe0d77"</screen>
<para>Your group's object should look like: </para>
<programlisting language="javascript">
{
"_rev":"1",
"dn":"cn=openidm2,ou=Groups,dc=example,dc=com",
"_id":"b0982152-5099-4358-bdd1-45a39ebe0d77",
"description":[
"openidm test group"
],
"uniqueMember":[
"uid=jdoe,ou=People,dc=example,dc=com",
],
"name":[
"openidm2"
]
}
</programlisting>
</section>
</section>
<section xml:id="more-sample3">
<title>Sample 3 - Scripted SQL</title>
<indexterm>
<primary>Samples</primary>
<secondary>Sample 3 - Scripted SQL</secondary>
</indexterm>
<para>Sample 3 shows an example configuration for the Scripted SQL connector.
The Scripted SQL connector communicates with the database through
configurable SQL scripts. Each operation, like create or delete, is
represented by its own script.</para>
<para>Scripts are located in the
<filename>openidm/samples/sample3/tools/</filename> folder. The
<filename>openidm/samples/sample3/data/</filename> folder contains a data
definition language script for setting up the MySQL database schema to hold
the external user objects.</para>
<para>Prepare a fresh installation of OpenIDM before trying this
sample.</para>
<section xml:id="install-sample3">
<title>Install the Sample</title>
<para>Prepare OpenIDM as described in <xref linkend="preparing-openidm"/>.
Copy the <filename>conf</filename> and <filename>tools</filename>
folders.</para>
<screen>$ cd /path/to/openidm
$ cp -r samples/sample3/conf samples/sample3/tools .</screen>
<para>In <filename>conf/provisioner.openicf-scriptedsql.json</filename>,
edit the paths starting with <literal>/opt/111</literal> to match your
installation.</para>
<para>You do not need to copy the <filename>sample3/data/</filename> folder,
as its content is needed only to set up the external user database.</para>
<para>In this example OpenIDM communicates with a MySQL database server.
OpenIDM requires a MySQL driver, the MySQL Connector/J. Download <link
xlink:show="new" xlink:href="http://www.mysql.com/downloads/connector/j/"
>MySQL Connector/J</link>, unpack the delivery, and copy the .jar into the
<filename>openidm/bundle</filename> directory.</para>
<screen>$ cp mysql-connector-java-5.1.18-bin.jar /path/to/openidm/bundle/</screen>
</section>
<section xml:id="external-mysql-config-sample3">
<title>External Configuration</title>
<itemizedlist>
<para>For this sample, OpenIDM connects to an external MySQL database
server. Sample 3 expects the following configuration for MySQL:</para>
<listitem><para>The database is available on the local host.</para></listitem>
<listitem><para>The database listens on port 3306.</para></listitem>
<listitem><para>You can connect over the network to the database with user
<literal>root</literal> and password <literal>password</literal>.</para></listitem>
<listitem><para>MySQL serves a database called <literal>HRDB</literal> with
a table called <literal>Users</literal>.</para></listitem>
<listitem><para>The database schema is as described in the data definition
language file,
<filename>openidm/samples/sample3/data/sample_HR_DB.mysql</filename>.
Import the file into MySQL before running the sample.</para>
<screen width="84"><?dbfo pgwide="1"?>$ /bin/mysql -u root -p &lt; /path/to/openidm/samples/sample3/data/sample_HR_DB.mysql
Enter password:
$ </screen>
</listitem>
</itemizedlist>
<para>Make sure MySQL is running, and then restart OpenIDM to make sure
the Connector/J bundle is picked up.</para>
<screen>-&gt; shutdown
-&gt;
$ /startup.sh</screen>
<para>If the configuration of the external database is correct, then
OpenIDM should show five users during startup, for example:</para>
<screen>/startup.sh
Using OPENIDM_HOME: /path/to/openidm
Using OPENIDM_OPTS: -Xmx1024m
Using LOGGING_CONFIG: -Djava.util.logging.config.file=/path/to/openidm/conf/logging.properties
Using boot properties at /path/to/openidm/conf/boot/boot.properties
OpenIDM version "2.1.0-SNAPSHOT" (revision: 1096)
bob
rowley
louis
john
jdoe</screen>
<para>The check method, executed
for each connected resource, executes a
<literal>select * from Users</literal> statement.</para>
</section>
<section xml:id="run-sample3">
<title>Run the Sample</title>
<para>The sample 3 <filename>sync.json</filename> configuration file
contains a mapping to reconcile OpenIDM and the external database.
Run the reconciliation with the following command.</para>
<screen width="83"><?dbfo pgwide="1"?>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request POST
"http://localhost:8080/openidm/recon?_action=recon&amp;mapping=systemHrdb_managedUser"</screen>
<para>Reconciliation creates the five users from the database in the
OpenIDM repository. Check the result with the following command.</para>
<screen>
$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request GET
"http://localhost:8080/openidm/managed/user/?_queryId=query-all-ids"</screen>
<para>The result should resemble the following JSON object.</para>
<programlisting language="javascript">
{"query-time-ms":2,"result":[
{"_id":"dc870bff-c2e9-4378-8ac1-45ee085b09bf","_rev":"0"},
{"_id":"9046dea4-1dea-4ae8-8335-070839b12b9c","_rev":"0"},
{"_id":"17fc954f-828a-454c-b05e-f8e9934c6e64","_rev":"0"},
{"_id":"371855d1-44c9-4854-a576-3397275211e4","_rev":"0"},
{"_id":"97066201-e0de-48d9-8c9e-bdf7f0f0c7e5","_rev":"0"}],
"conversion-time-ms":0}</programlisting>
<para>To view the JSON for one of the users, get the user by
the value of the <literal>_id</literal>.</para>
<screen width="83"><?dbfo pgwide="1"?>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request GET
"http://localhost:8080/openidm/managed/user/dc870bff-c2e9-4378-8ac1-45ee085b09bf"</screen>
</section>
</section>
<section xml:id="more-sample4">
<title>Sample 4 - CSV File</title>
<indexterm>
<primary>Samples</primary>
<secondary>Sample 4 - CSV file</secondary>
</indexterm>
<para>Sample 4 deals with a comma-separated value file as the external
resource. The file name is part of the sample configuration. Therefore you
do not need to manage any other external resources.</para>
<section xml:id="install-sample4">
<title>Install the Sample</title>
<para>Prepare OpenIDM as described in <xref linkend="preparing-openidm"/>.
Copy the configuration, and copy the <filename>data</filename> folder
holding the .csv file.</para>
<screen>$ cd /path/to/openidm
$ cp -r samples/sample4/conf samples/sample4/data .</screen>
</section>
<section xml:id="csv-file-sample4">
<title>External Configuration</title>
<para>The only external resource you need is the
<filename>data/hr.csv</filename> file that you copied in the previous step.</para>
</section>
<section xml:id="run-sample4">
<title>Run the Sample</title>
<para>Start up OpenIDM before running the sample if you have not already
done so.</para>
<screen>$ /startup.sh
/startup.sh
Using OPENIDM_HOME: /path/to/openidm
Using OPENIDM_OPTS: -Xmx1024m
Using LOGGING_CONFIG:
-Djava.util.logging.config.file=/path/to/openidm/conf/logging.properties
Using boot properties at /path/to/openidm/conf/boot/boot.properties
-&gt;</screen>
<para>The <filename>sample4/data/hr.csv</filename> file contains two example
users. The first line of the file sets the attribute names. Running
reconciliation creates two users in the OpenIDM repository</para>
<screen width="89"><?dbfo pgwide="1"?>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request POST
"http://localhost:8080/openidm/recon?_action=recon&amp;mapping=systemHrAccounts_managedUser"</screen>
<para>Check the results of reconciliation with the following command.</para>
<screen>
$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request GET
"http://localhost:8080/openidm/managed/user/?_queryId=query-all-ids"</screen>
<para>The result should resemble the following JSON object, but all on one
line.</para>
<programlisting language="javascript">
{
"query-time-ms": 1,
"result": [
{
"_id": "a8c6a158-3e82-450e-8e28-6ebf5a01a1a6",
"_rev": "0"
},
{
"_id": "750a2375-6983-4e5f-bdbd-7e121e94cf74",
"_rev": "0"
}
],
"conversion-time-ms": 0
}</programlisting>
<para>To view the JSON for one of the users, get the user by
the value of the <literal>_id</literal>.</para>
<screen width="83"><?dbfo pgwide="1"?>
$ curl
--header "X-OpenIDM-Username-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request GET
"http://localhost:8080/openidm/managed/user/a8c6a158-3e82-450e-8e28-6ebf5a01a1a6"
{
"userName": "Doe",
"givenName": "Darth",
"employeeNumber": "123456",
"_id": "a8c6a158-3e82-450e-8e28-6ebf5a01a1a6",
"_rev": "0",
"email": "doe@forgerock.org"
}</screen>
</section>
</section>
<section xml:id="more-sample5">
<title>Sample 5 - Synchronization of Two Resources</title>
<indexterm>
<primary>Samples</primary>
<secondary>Sample 5 - Synchronization of two resources</secondary>
</indexterm>
<para>Sample 5 demonstrates the flow of data from one external resource to
another. The resources are called LDAP and AD, but in the sample both
directory-like resources are simulated with XML files.</para>
<section xml:id="install-sample5">
<title>Install the Sample</title>
<para>Prepare OpenIDM as described in <xref linkend="preparing-openidm"/>.
Copy the configuration, and copy the <filename>script</filename> folder
that holds sample JavaScript files.</para>
<screen>$ cd /path/to/openidm
$ cp -r samples/sample5/conf samples/sample5/script .</screen>
</section>
<section xml:id="ext-config-sample5">
<title>External Configuration</title>
<para>No extra external resource needs configuration for this example.
The XML files used are located in the
<filename>openidm/samples/sample5/data/</filename> folder. When you start
OpenIDM with the sample 5 configuration, it creates
<filename>xml_AD_Data.xml</filename>, which does not contain users until
you run reconciliation.</para>
</section>
<section xml:id="run-sample5">
<title>Run the Sample</title>
<para>Start up OpenIDM before running the sample if you have not already
done so.</para>
<screen>$ /startup.sh
/startup.sh
Using OPENIDM_HOME: /path/to/openidm
Using OPENIDM_OPTS: -Xmx1024m
Using LOGGING_CONFIG:
-Djava.util.logging.config.file=/path/to/openidm/conf/logging.properties
Using boot properties at /path/to/openidm/conf/boot/boot.properties
-&gt;</screen>
<para>Run reconciliation between OpenIDM and the pseudo-LDAP resource.</para>
<screen width="91"><?dbfo pgwide="1"?>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request POST
"http://localhost:8080/openidm/recon?_action=recon&amp;mapping=systemLdapAccounts_managedUser"</screen>
<para>This command creates a user in the repository and also in the pseudo
AD resource, represented by the
<filename>samples/sample5/data/xml_AD_Data.xml</filename> file.</para>
</section>
</section>
<section xml:id="more-sample6">
<title>Sample 6 - LiveSync Between Two LDAP Servers</title>
<indexterm>
<primary>Samples</primary>
<secondary>Sample 6 - LiveSync between two LDAP servers</secondary>
</indexterm>
<para>Sample 6 resembles sample 5, but sample 6 uses two real LDAP
connections. The default sample configuration assumes two LDAP
server instances running on the local host, but listening on different
LDAP ports.</para>
<para>To simplify setup, you can configure both provisioners to point to the
same LDAP server, and only use different base DNs, so you can simulate use of two
directory servers with a single <link xlink:show="new"
xlink:href="http://www.forgerock.org/opendj.html">OpenDJ</link> server,
for example.</para>
<para>Sample 6 picks up new and changed users from the LDAP suffix,
<literal>ou=people,dc=example,dc=com</literal>, and sends updates to the
"Active Directory" suffix <literal>ou=people,o=ad</literal>. To keep the
example relatively simple, no configuration is provided for the flow from
AD to LDAP.</para>
<section xml:id="install-sample6">
<title>Install the Sample</title>
<para>Prepare OpenIDM as described in
<xref linkend="preparing-openidm"/>. Copy the configuration for sample
6.</para>
<screen>$ cd /path/to/openidm
$ cp -r samples/sample6/conf .</screen>
</section>
<section xml:id="external-resource-sample6">
<title>External Configuration</title>
<para>Out of the box, the sample provisioners are configured to use two
independent LDAP servers, one listening on port 1389 and one on port 4389.</para>
<para>To simplify your setup, you can change the sample to connect to a single LDAP
server representing both external resources by using the same port numbers
in both provisioner .json files. For example, change
<filename>conf/provisioner.openicf-ad.json</filename> so that the port number
line reads <literal>"port" : 1389</literal>.</para>
<section xml:id="prepare-livesync-sample6">
<title>Prepare OpenDJ For LiveSync</title>
<para>With LiveSync, OpenIDM detects changes in an external resource as they
happen. OpenIDM detects changes in OpenDJ by reading the External Change Log
(ECL). The ECL is presented as an LDAP subtree with base DN
<literal>cn=changelog</literal>. Each change is represented as an
entry in the subtree. Each change entry remains in the subtree until the
log is purged (by default every three days).</para>
<para>You turn on the external change log in OpenDJ by enabling replication. OpenDJ
provides the change log even if it does not, in fact, replicate data to
another OpenDJ server. Note that OpenDJ will log, in this case, harmless error
messages if replication is enabled without a connection to another replica.</para>
<para>To enable replication without another server, set up replication when
you install OpenDJ.</para>
<mediaobject xml:id="figure-replication-setup">
<alt>Topology Options screen from the OpenDJ QuickSetup wizard</alt>
<imageobject>
<imagedata fileref="images/replication-setup.png" format="PNG" />
</imageobject>
<textobject>
<para>The OpenDJ QuickSetup wizard lets you set up replication at
installation time.</para>
</textobject>
</mediaobject>
</section>
<section xml:id="ldap-configuration-sample6">
<title>LDAP Configuration</title>
<itemizedlist>
<para>Sample 6 provides the configuration for two external LDAP servers, set up as
follows.</para>
<listitem><para>Both LDAP servers run on the local host.</para></listitem>
<listitem><para>The LDAP server "LDAP" listens on port 1389.</para></listitem>
<listitem><para>The LDAP server "AD" listens on port 4389. (If you want to
use a single LDAP server instance, change this to 1389.)</para></listitem>
<listitem><para>Both LDAP servers have a user with DN
<literal>cn=Directory Manager</literal> and password
<literal>password</literal> who can read and write to the data and read
the change log.</para></listitem>
<listitem><para>User objects are stored under:</para> <itemizedlist>
<listitem><para>Base DN <literal>ou=people,o=ad</literal> for the
connector called "AD".</para></listitem>
<listitem><para>Base DN <literal>ou=people,dc=example,dc=com</literal>
for the connector called "LDAP".</para></listitem>
</itemizedlist></listitem>
<listitem><para>User objects have the object class
<literal>inetOrgPerson</literal>.</para></listitem>
<listitem><para>User objects have the following attributes:</para>
<itemizedlist>
<listitem><para><literal>uid</literal></para></listitem>
<listitem><para><literal>sn</literal></para></listitem>
<listitem><para><literal>cn</literal></para></listitem>
<listitem><para><literal>givenName</literal></para></listitem>
<listitem><para><literal>mail</literal></para></listitem>
<listitem><para><literal>description</literal></para></listitem>
</itemizedlist>
<para>The LDIF representation of an example user is as follows.</para>
<programlisting language="ldif">
dn: uid=jdoe,ou=People,dc=example,dc=com
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: top
givenName: John
uid: jdoe
cn: John Doe
telephoneNumber: 12345
sn: Doe
mail: ddoe@example.com
description: Created by OpenIDM
</programlisting>
</listitem>
</itemizedlist>
<para>Prepare the LDAP servers by creating the base DN
<literal>dc=example,dc=com</literal> on the first server and
<literal>o=AD</literal> on the second server, and then importing the following objects.</para>
<para>For the "LDAP" directory, import
<filename>samples/sample6/data/Example.ldif</filename>.</para>
<programlisting language="ldif">
dn: dc=com
objectClass: domain
objectClass: top
dc: com
dn: dc=example,dc=com
objectClass: domain
objectClass: top
dc: example
dn: ou=People,dc=example,dc=com
ou: people
description: people
objectclass: organizationalunit
dn: uid=jdoe,ou=People,dc=example,dc=com
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: top
givenName: John
uid: jdoe
cn: John Doe
telephoneNumber: 12345
sn: Doe
mail: jdoe@example.com
description: Created for OpenIDM
</programlisting>
<para>For the "AD" directory import
<filename>samples/sample6/data/AD.ldif</filename>.</para>
<programlisting language="ldif">
dn: o=AD
objectClass: domain
objectClass: top
dc: organization
dn: ou=People,o=AD
ou: people
description: people
objectclass: organizationalunit
</programlisting>
</section>
</section>
<section xml:id="run-sample6">
<title>Running the Sample</title>
<para>The following sections show how to run the sample once off, with
reconciliation, and continuously with LiveSync.</para>
<section xml:id="run-sample6-reconciliation">
<title>Using Reconciliation</title>
<para>Start up OpenIDM, and then run reconciliation over the REST interface.</para>
<screen width="91"><?dbfo pgwide="1"?>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request POST
"http://localhost:8080/openidm/recon?_action=recon&amp;mapping=systemLdapAccounts_managedUser"</screen>
<para>The result of a successful reconciliation is an
<literal>_id</literal> object.</para>
<programlisting language="javascript"
>{"reconId":"7da56fc0-54de-4c7b-bae3-de7c7a999387"}</programlisting>
<para>With the configuration for sample 6, OpenIDM creates user objects
from LDAP in the internal repository, and also in the target AD suffix.</para>
<para>After reconciliation, list all users in the repository.</para>
<screen>
$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request GET
"http://localhost:8080/openidm/managed/user/?_queryId=query-all-ids"</screen>
<para>The result should resemble the following JSON object, though all
on one line.</para>
<programlisting language="javascript">
{
"query-time-ms": 1,
"result": [
{
"_id": "56f0fb7e-3837-464d-b9ec-9d3b6af665c3",
"_rev": "0"
}
],
"conversion-time-ms": 0
}</programlisting>
<para>To read the user object, use the <literal>_id</literal> value.</para>
<screen width="83"><?dbfo pgwide="1"?>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request GET
"http://localhost:8080/openidm/managed/user/56f0fb7e-3837-464d-b9ec-9d3b6af665c3"</screen>
<para>The result should resemble the following JSON object, though all
on one line.</para>
<programlisting language="javascript">
{
"_id": "56f0fb7e-3837-464d-b9ec-9d3b6af665c3",
"_rev":"0",
"email":"jdoe@example.com",
"description":"Created for OpenIDM",
"familyName":"Doe",
"userName":"jdoe",
"givenName":"John",
"displayName":"John Doe"
}</programlisting>
<para>You can also view users created in the AD suffix with the following
<literal>ldapsearch</literal> command:</para>
<screen>$ /path/to/OpenDJ/bin/ldapsearch
--bindDN "cn=Directory Manager"
--bindPassword password
--hostname `hostname`
--port 4389
--baseDN o=AD
"(uid=*)"
dn: uid=jdoe,ou=people,o=ad
objectClass: person
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: top
givenName: John
description: Created for OpenIDM
uid: jdoe
cn: John Doe
sn: Doe
mail: jdoe@example.com
</screen>
</section>
<section xml:id="run-sample6-live-sync">
<title>Using LiveSync</title>
<para>You can start reconciliation by using a schedule configuration or
by using the REST interface directly. However, you must start LiveSync
by using a schedule. The sample comes with the following schedule
configuration file for LiveSync in
<filename>conf/schedule-activeSynchroniser_systemLdapAccount.json</filename>.</para>
<programlisting language="javascript">
{
"enabled" : false,
"type" : "cron",
"schedule" : "0/15 * * * * ?",
"invokeService" : "provisioner",
"invokeContext" : {
"action" : "liveSync",
"source" : "system/ldap/account"
}
}</programlisting>
<para>LiveSync is disabled by default. Activate LiveSync by editing the file,
<filename>conf/schedule-activeSynchroniser_systemLdapAccount.json</filename>,
to change the "enabled" property value to <literal>true</literal>. With
LiveSync enabled, you can add and change LDAP users, and see the changes in AD
as OpenIDM flows the data between resources dynamically.</para>
</section>
</section>
</section>
<section xml:id="more-sample7">
<title>Sample 7 - Scripting a SCIM-like Schema</title>
<indexterm>
<primary>Samples</primary>
<secondary>Sample 7 - Scripting a SCIM-like Schema</secondary>
</indexterm>
<para>Sample 7 demonstrates how you can use OpenIDM to expose user data with a
SCIM-like schema. The sample uses the XML file connector to read in attributes
from external accounts and construct a JSON object for users stored in the
OpenIDM repository. For more information about SCIM schema, see <link xlink:show="new"
xlink:href='http://www.simplecloud.info/specs/draft-scim-core-schema-01.html'
>SCIM schema 1.0 - draft</link>.</para>
<note>
<para>This sample requires that you set up MySQL to hold the OpenIDM internal
repository, as described in the chapter, <link
xlink:href="install-guide#chap-repository"
xlink:role="http://docbook.org/xlink/role/olink"><citetitle>Installing a
Repository For Production</citetitle></link>.</para>
</note>
<section xml:id="install-sample7">
<title>Install the Sample</title>
<para>Prepare OpenIDM as described in <xref linkend="preparing-openidm"/>,
and set up MySQL to hold the OpenIDM internal repository.</para>
<para>Copy the configuration for sample 7.</para>
<screen>$ cd /path/to/openidm
$ cp -r samples/sample7/conf samples/sample7/data samples/sample7/script .</screen>
</section>
<section xml:id="run-sample7">
<title>Running the Sample</title>
<para>Start OpenIDM, and then run the reconciliation to pull the user from
<filename>data/xmlConnectorData.xml</filename> into the OpenIDM internal
repository.</para>
<screen width="94"><?dbfo pgwide="1"?>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request POST
"http://localhost:8080/openidm/recon?_action=recon&amp;mapping=systemXmlfileAccounts_managedUser"</screen>
<para>Reconciliation creates a user object in the repository. Retrieve the
user from the repository.</para>
<screen>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request GET
"http://localhost:8080/openidm/managed/user/DDOE1"</screen>
<para>The user object has the following JSON representation.</para>
<programlisting language="javascript">{
"schemas": "['urn:scim:schemas:core:1.0']",
"ims": [
{
"value": "jonyOnAim",
"type": "aim"
},
{
"value": "skyperHiasl",
"type": "skype"
}
],
"locale": null,
"phoneNumbers": [
{
"value": "1234567",
"type": "work"
},
{
"value": "1234568",
"type": "home"
}
],
"emails": [
{
"type": "work",
"value": "hallo@example.com",
"primary": true
},
{
"value": "jdoe@forgerock.com",
"type": "home"
}
],
"externalId": "DDOE1",
"preferredLanguage": "en_US",
"meta": {
"lastModified": "Mon May 28 2012 12:45:45 GMT+0200 (CEST)"
},
"userType": "permanent",
"_rev": "0",
"photos": [
{
"value": "https://photos.example.com/profilephoto/72930000000Ccne/F",
"type": "photo"
},
{
"value": "https://photos.example.com/profilephoto/72930000000Ccne/T",
"type": "thumbnail"
}
],
"title": "Mr.Univers",
"timezone": "America/Denver",
"_id": "DDOE1",
"profileUrl": "https://login.example.com/DDOE1",
"nickName": "Jonny",
"name": {
"familyName": "Doe",
"middleName": "Hias",
"formatted": "Dr. John H Doe III",
"givenName": "John",
"honorificSuffix": "III",
"honorificPrefix": "Dr."
},
"userName": "DDOE1",
"displayName": "John Doe",
"addresses": [
{
"streetAddress": "100 Universal City Plaza",
"region": "CA",
"formatted": "100 Universal City Plaza\nHollywood, CA 91608 USA",
"postalCode": "91608",
"primary": "true",
"locality": "Hollywood",
"type": "work",
"country": "USA"
},
{
"streetAddress": "222 Universal City Plaza",
"region": "CA",
"formatted": "222 Universal City Plaza\nHollywood, CA 91622 USA",
"postalCode": "91622",
"primary": "false",
"locality": "Hollywood",
"type": "home",
"country": "USA"
}
],
"groups": [
{
"value": "usemploys",
"display": "US Employees"
},
{
"value": "euemploys",
"display": "EU Employees"
}
]
}</programlisting>
<para>The sample scripts you copied to
<filename>/path/to/openidm/script/setScim*.js</filename> transform the user
data from the resource into the JSON object layout required by SCIM
schema.</para>
</section>
</section>
<section xml:id="more-sample8">
<title>Sample 8 - Logging in Scripts</title>
<indexterm>
<primary>Samples</primary>
<secondary>Sample 8 - Logging in Scripts</secondary>
</indexterm>
<para>OpenIDM provides a <literal>logger</literal> object with
<literal>debug()</literal>, <literal>error()</literal>,
<literal>info()</literal>, <literal>trace()</literal>, and
<literal>warn()</literal> functions that you can use to log messages to
the OpenIDM console from your scripts.</para>
<section xml:id="install-sample8">
<title>Install the Sample</title>
<para>Prepare OpenIDM as described in <xref linkend="preparing-openidm"/>,
copying the configuration for sample 8.</para>
<screen>$ cd /path/to/openidm
$ cp -r samples/sample8/conf samples/sample8/script .</screen>
<para>The scripts under <filename>samples/sample8/script/</filename>
show brief log message examples.</para>
</section>
<section xml:id="run-sample8">
<title>Running the Sample</title>
<para>First start OpenIDM. Then run reconciliation over the REST
interface.</para>
<screen width="99"><?dbfo pgwide="1"?>$ curl
--header "X-OpenIDM-Username: openidm-admin"
--header "X-OpenIDM-Password: openidm-admin"
--request POST
"http://localhost:8080/openidm/recon?_action=recon&amp;mapping=systemXmlfileAccounts_managedUser"</screen>
<para>Successful reconciliation returns an "_id" object.</para>
<para>Notice the log messages displayed on the OpenIDM (Felix) console.
The following example omits timestamps and so forth to show only the message
strings.</para>
<programlisting language="none">-&gt;
...Case no Source: the source object contains: = null
...Case emptySource: the source object contains: = {__UID__=1, email=[mail1@...
...Case sourceDescription: the source object contains: = Created By XML1
...Case onCreate: the source object contains: = {__UID__=1, email=[mail1@...
...Case result: the source object contains: = {UNQUALIFIED={count=0, ids=[]},...
</programlisting>
</section>
</section>
</chapter>