<?xml version='1.0' ?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
]>

  <article id="ext-auth-design">
    <title>Design</title>

    <authorblurb>
      by <ulink url="mailto:joel@aufrecht.org">Joel Aufrecht</ulink>
    </authorblurb>

    <sect1 id="ims-sync-driver-design">
      <title>IMS Sync driver design</title>
      <authorblurb>
        by <ulink url="mailto:lars@collaboraid.biz">Lars Pind</ulink>
      </authorblurb>

      <sect2>
        <title>TODO</title>
        <para> We need examples of how the communication would be done from our
clients. </para>

        <para> The "GetDocument" communications service contract could be a
generic system-wide service contract. </para>

        <para> We might need a source/ID column in the users table to identify
where they're imported from for doing updates, particularly if
importing from multiple sources (or when some users are local.) </para>

      </sect2>

      <sect2>
        <title>Execution Story</title>
        <orderedlist>


        <listitem><para> We will parse a document in the <ulink url="http://www.imsglobal.org/enterprise/index.cfm">IMS Enterprise
  Specification</ulink> format (<ulink url="http://www.imsglobal.org/enterprise/entv1p1/imsent_bestv1p1.html#1404584">example
  XML document</ulink>), and translate it into calls to the batch user
  sync API. </para></listitem>

        <listitem><para> The document will contain either the complete user listitemst (IMS:
  "snapshot"), or an incremental user listitemst (IMS: "Event Driven" --
  contains only adds, edits, and deletes). You could for example do a
  complete transfer once a month, and incrementals every night. The
  invocation should decide which type is returned. </para></listitem>
        </orderedlist>

        <para> The design should favor interoperability, reliability and robustness. </para>


        <programlisting>
&lt;enterprise&gt;

  &lt;properties&gt;
    &lt;datasource&gt;Dunelm Services Limited&lt;/datasource&gt;
    &lt;target&gt;Telecommunications LMS&lt;/target&gt;
    &lt;type&gt;DATABASE UPDATE&lt;/type&gt;

    &lt;datetime&gt;2001-08-08&lt;/datetime&gt;
  &lt;/properties&gt;
  &lt;person recstatus = "1"&gt;
    &lt;comments&gt;Add a new Person record.&lt;/comments&gt;
    &lt;sourcedid&gt;

      &lt;source&gt;Dunelm Services Limited&lt;/source&gt;
      &lt;id&gt;CK1&lt;/id&gt;
    &lt;/sourcedid&gt;
    &lt;name&gt;
      &lt;fn&gt;Clark Kent&lt;/fn&gt;

      &lt;sort&gt;Kent, C&lt;/sort&gt;
      &lt;nickname&gt;Superman&lt;/nickname&gt;
    &lt;/name&gt;
    &lt;demographics&gt;
      &lt;gender&gt;2&lt;/gender&gt;

    &lt;/demographics&gt;
    &lt;adr&gt;
      &lt;extadd&gt;The Daily Planet&lt;/extadd&gt;
      &lt;locality&gt;Metropolis&lt;/locality&gt;
      &lt;country&gt;USA&lt;/country&gt;

    &lt;/adr&gt;
  &lt;/person&gt;
  &lt;person recstatus = "2"&gt;
    &lt;comments&gt;Update a previously created record.&lt;/comments&gt;
    &lt;sourcedid&gt;

      &lt;source&gt;Dunelm Services Limited&lt;/source&gt;
      &lt;id&gt;CS1&lt;/id&gt;
    &lt;/sourcedid&gt;
    &lt;name&gt;
      &lt;fn&gt;Colin Smythe&lt;/fn&gt;

      &lt;sort&gt;Smythe, C&lt;/sort&gt;
      &lt;nickname&gt;Colin&lt;/nickname&gt;
      &lt;n&gt;
        &lt;family&gt;Smythe&lt;/family&gt;

        &lt;given&gt;Colin&lt;/given&gt;
        &lt;other&gt;Manfred&lt;/other&gt;
        &lt;other&gt;Wingarde&lt;/other&gt;
        &lt;prefix&gt;Dr.&lt;/prefix&gt;

        &lt;suffix&gt;C.Eng&lt;/suffix&gt;
        &lt;partname partnametype = "Initials"&gt;C.M.W.&lt;/partname&gt;
      &lt;/n&gt;
    &lt;/name&gt;
    &lt;demographics&gt;

      &lt;gender&gt;2&lt;/gender&gt;
      &lt;bday&gt;1958-02-18&lt;/bday&gt;
      &lt;disability&gt;None.&lt;/disability&gt;
    &lt;/demographics&gt;

    &lt;email&gt;colin@dunelm.com&lt;/email&gt;
    &lt;url&gt;http://www.dunelm.com&lt;/url&gt;
    &lt;tel teltype = "Mobile"&gt;4477932335019&lt;/tel&gt;
    &lt;adr&gt;

      &lt;extadd&gt;Dunelm Services Limited&lt;/extadd&gt;
      &lt;street&gt;34 Acorn Drive&lt;/street&gt;
      &lt;street&gt;Stannington&lt;/street&gt;
      &lt;locality&gt; Sheffield&lt;/locality&gt;

      &lt;region&gt;S.Yorks&lt;/region&gt;
      &lt;pcode&gt;S7 6WA&lt;/pcode&gt;
      &lt;country&gt;UK&lt;/country&gt;
    &lt;/adr&gt;

    &lt;photo imgtype = "gif"&gt;
      &lt;extref&gt;http://www.dunelm.com/staff/colin2.gif&lt;/extref&gt;
    &lt;/photo&gt;
    &lt;institutionrole primaryrole = "No" institutionroletype = "Alumni"/&gt;
    &lt;datasource&gt;dunelm:colinsmythe:1&lt;/datasource&gt;

  &lt;/person&gt;
  &lt;person recstatus = "3"&gt;
    &lt;comments&gt;Delete this record.&lt;/comments&gt;
    &lt;sourcedid&gt;
      &lt;source&gt;Dunelm Services Limited&lt;/source&gt;

      &lt;id&gt;LL1&lt;/id&gt;
    &lt;/sourcedid&gt;
    &lt;name&gt;
      &lt;fn&gt;Lois Lane&lt;/fn&gt;
      &lt;sort&gt;Lane, L&lt;/sort&gt;

    &lt;/name&gt;
  &lt;/person&gt;
&lt;/enterprise&gt;
</programlisting>

        <para> Above would get translated into calls to the batch sync API as
follows: </para>

        <programlisting>
for { ... loop over persons in the document ... } {
        auth::batch::transaction \
            -job_id $job_id \
            -operation [ad_decode $recstatus 2 "update" 3 "delete" "insert"] \
            -authority_id $authority_id \
            -username { $userid if present, otherwise $sourcedid.id } \
            -first_names { $name.given if present, otherwise all except last part of $name.fn } \
            -last_name { $name.family if present, otherwise last part of $name.fn } \
            -email { $person.email ; we require this, even though the specification does not } \
            -url { $url, if present } \
            -portrait_url { $photo.imgtype/$photo.extref -- grab photo, store in DB }
    }
}
</programlisting>

        <para> Mandatory fields which we can rely on are: </para>

        <orderedlist>
          <listitem><para> sourcedid: ID as defined by the source system. Used for username. </para></listitem>
          <listitem><para> name.fn (formatted name). Used for first_names, last_name </para></listitem>
        </orderedlist>

        <para> Note that we require 'email' attribute, but the IMS Enterprise
spec does not. Hence, unless we change our data model to allow users
without an email address, we will have to throw an error. </para>

        <para> Here's how we map IMS enterprise to OpenACS tables. </para>

        <orderedlist>
          
          <listitem><para>username: </para>
            <orderedlist>
              <listitem><para>&lt;userid&gt;  <emphasis style="bold">...</emphasis> &lt;/userid&gt; if present.</para></listitem>
              
              <listitem><para>&lt;sourcedid&gt;&lt;id&gt; <emphasis
        style="bold">...</emphasis> &lt;/id&gt;&lt;/sourcedid&gt; otherwise</para></listitem>
            </orderedlist>
          </listitem>
          <listitem><para>first_names:</para>
            <orderedlist>
              <listitem><para>&lt;name&gt;&lt;given&gt; <emphasis style="bold">...</emphasis>&lt;/given&gt;&lt;/name&gt; if present.</para></listitem>
              <listitem><para>&lt;name&gt;&lt;fn&gt; <emphasis style="bold">...</emphasis> ...&lt;/fn&gt;&lt;/name&gt; otherwise</para></listitem>
              
            </orderedlist>
          </listitem>
          <listitem><para>    last_name:</para>
            <orderedlist>
              <listitem><para>&lt;name&gt;&lt;family&gt; <emphasis style="bold">...</emphasis>&lt;/family&gt;&lt;/name&gt; if present.</para></listitem>
              
              <listitem><para>&lt;name&gt;&lt;fn&gt;...  <emphasis style="bold">...</emphasis>&lt;/fn&gt;&lt;/name&gt; otherwise</para></listitem>
            </orderedlist>
          </listitem>
          
          <listitem><para>    email:</para>
            <orderedlist>
              
              <listitem><para>&lt;email&gt; <emphasis style="bold">...</emphasis>&lt;/email&gt; if present.</para></listitem>
              <listitem><para>Blank/unchanged if not.</para></listitem>
            </orderedlist>
          </listitem>
          <listitem><para>    url:</para>
            <orderedlist>
              <listitem><para>&lt;url&gt; <emphasis style="bold">...</emphasis>&lt;/url&gt; if present.</para></listitem>
              <listitem><para>Blank/unchanged if not.</para></listitem>
            </orderedlist>
          </listitem>
          
          <listitem><para>    portrait:</para>
            <orderedlist>
              <listitem><para>
        &lt;photo imgtype="gif"&gt;&lt;extref&gt;<emphasis style="bold">...</emphasis>&lt;/extref&gt;&lt;/photo&gt; if present:
        HTTP GET the photo, insert it into the system. (Do we do this,
        then, with all users when doing a snapshot update?)
      </para></listitem>
            </orderedlist>
          </listitem>
        </orderedlist>

      </sect2>
      <sect2>
        <title>        Resources</title>

        <itemizedlist>
          <listitem><para><para> <ulink url="http://www.cetis.ac.uk/content/20020524162233">Consolidation
  before the leap; IMS Enterprise 1.1</ulink>:  This article says that IMS
  Enterprise 1.1 (current version) does not address the communication
  model, which is critically missing for real seamless
  interoperability. IMS Enterprise 2.0 will address this, but
  Blackboard, who's influential in the IMS committee, is adopting
  OKI's programming interrfaces for this. </para></para></listitem>

          <listitem><para><para><ulink url="http://www.cetis.ac.uk/content/20030717185453">IMS and OKI, the wire and the socket</ulink></para></para></listitem>

        </itemizedlist>
      </sect2>
    </sect1>
  </article>
