.. raw:: latex
\newpage
Identifier Management
=====================
.. index:: Identifiers
Author
Matthew B. Jones
Date
- 20100301 [MBJ] Initial draft of Identifier documentation
Goal
Extend Metacat to support identifiers with arbitrary syntax
Summary
Metacat currently supports identifier strings called 'docids' that have
the syntax 'scope.object.revision', such as 'foo.34.1' (we will refer to
these as 'LocalIDs'). We now want Metacat to support identifiers that are
arbitrary strings, but still enforce uniqueness and proper revision
handling (refer to these as GUIDs). Metacat must be able to accept
these strings as identifiers for all CRUD operations, and reference them
in search results.
Identifier Resolution
---------------------
Because Metacat uses LocalIDs throughout the code for references to objects,
and that LocalID has a constrained structure that includes semantics about
revisions in the identifier, it is difficult to wholesale replace it with
less-constrained string identifiers without re-writing much of Metacat.
Thus, our alternate strategy is to wrap the Metacat APIs with a
identifier resolution layer that keeps track of the unconstrained GUIDs and
maps them to constrained local identifiers which are used internally within
Metacat. The basic identifer table model is shown in Figure 1, while the
basic strategy for retrieving an object is shown in Figure 2, creating an
object is shown in Figure 3, updating an object in Figure 4, and deleting
an object is shown in Figure 5.
Identifier Table Structure
~~~~~~~~~~~~~~~~~~~~~~~~~~
.. figure:: images/identifiers.png
Figure 1. Table structure for identifiers.
..
This block defines the table structure diagram referenced above.
@startuml images/identifiers.png
identifiers "*" -- "1" xml_documents
identifiers : String identifier
identifiers : String docid
identifiers : Integer rev
xml_documents : String docid
xml_documents : String rev
note right of identifiers
"identifiers.(docid,rev) is a foreign key into xml_documents"
end note
@enduml
.. raw:: latex
\newpage
.. raw:: pdf
PageBreak
Handling document read operations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An overview of the process needed to read an object using a GUID.
.. figure:: images/guid_read.png
Figure 2. Basic handling for string identifiers (GUIDs) as mapped to
docids (LocalIDs) to retrieve an object.
..
@startuml images/guid_read.png
!include plantuml.conf
actor User
participant "Client" as app_client << Application >>
participant "CRUD API" as c_crud << MetacatRestServlet >>
participant "Identifier Manager" as ident_man << IdentifierManager >>
participant "Handler" as handler << MetacatHandler >>
User -> app_client
app_client -> c_crud: get(token, GUID)
c_crud -> ident_man: getLocalID(GUID)
c_crud <-- ident_man: localID
c_crud -> handler: handleReadAction(localID)
c_crud <-- handler: object
c_crud --> app_client: object
@enduml
Handling document create operations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An overview of the process needed to create an object using a GUID.
.. figure:: images/guid_insert.png
Figure 3. Basic handling for string identifiers (GUIDs) as mapped to
docids (LocalIDs) to create an object.
..
@startuml images/guid_insert.png
!include plantuml.conf
actor User
participant "Client" as app_client << Application >>
participant "CRUD API" as c_crud << MetacatRestServlet >>
participant "Identifier Manager" as ident_man << IdentifierManager >>
participant "Handler" as handler << MetacatHandler >>
User -> app_client
app_client -> c_crud: create(token, GUID, object, sysmeta)
c_crud -> ident_man: identifierExists(GUID)
c_crud <-- ident_man: T or F
alt identifierExists == "F"
c_crud -> ident_man: mapToLocalId(GUID)
c_crud <-- ident_man: localID
c_crud -> handler: handleInsertAction(localID)
c_crud <-- handler: success
note right of c_crud
"Also need to address how to handle the sysmeta information wrt insertion methods"
end note
app_client <-- c_crud: success
else identifierExists == "T"
app_client <-- c_crud: IdentifierNotUnique
end
@enduml
Handling document update operations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An overview of the process needed to update an object using a GUID.
.. figure:: images/guid_update.png
Figure 4. Basic handling for string identifiers (GUIDs) as mapped to
docids (LocalIDs) to update an object.
..
@startuml images/guid_update.png
!include plantuml.conf
actor User
participant "Client" as app_client << Application >>
participant "CRUD API" as c_crud << MetacatRestServlet >>
participant "Identifier Manager" as ident_man << IdentifierManager >>
participant "Handler" as handler << MetacatHandler >>
User -> app_client
app_client -> c_crud: update(token, GUID, object, obsoletedGUID, sysmeta)
c_crud -> ident_man: identifierExists(obsoletedGUID)
c_crud <-- ident_man: T or F
alt identifierExists == "T"
c_crud -> ident_man: identifierExists(GUID)
c_crud <-- ident_man: T or F
alt identifierExists == "F"
c_crud -> ident_man: mapToLocalId(GUID, obsoletedGUID)
c_crud <-- ident_man: localID
c_crud -> handler: handleUpdateAction(localID)
c_crud <-- handler: success
note right of c_crud
"Also need to address how to handle the sysmeta information wrt update methods"
end note
app_client <-- c_crud: success
else identifierExists == "T"
app_client <-- c_crud: IdentifierNotUnique
end
else identifierExists == "F"
app_client <-- c_crud: NotFound
end
@enduml
Handling document delete operations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An overview of the process needed to delete an object using a GUID.
.. figure:: images/guid_delete.png
Figure 5. Basic handling for string identifiers (GUIDs) as mapped to
docids (LocalIDs) to delete an object.
..
@startuml images/guid_delete.png
!include plantuml.conf
actor User
participant "Client" as app_client << Application >>
participant "CRUD API" as c_crud << MetacatRestServlet >>
participant "Identifier Manager" as ident_man << IdentifierManager >>
participant "Handler" as handler << MetacatHandler >>
User -> app_client
app_client -> c_crud: delete(token, GUID)
c_crud -> ident_man: identifierExists(GUID)
c_crud <-- ident_man: T or F
alt identifierExists == "T"
c_crud -> ident_man: mapToLocalId(GUID)
c_crud <-- ident_man: localID
c_crud -> handler: handleDeleteAction(localID)
c_crud <-- handler: success
app_client <-- c_crud: success
else identifierExists == "F"
app_client <-- c_crud: NotFound
end
@enduml
..
This block defines the interaction diagram referenced above.
startuml images/01_interaction.png
!include plantuml.conf
actor User
participant "Client" as app_client << Application >>
User -> app_client
participant "CRUD API" as c_crud << Coordinating Node >>
activate c_crud
app_client -> c_crud: resolve(GUID, auth_token)
participant "Authorization API" as c_authorize << Coordinating Node >>
c_crud -> c_authorize: isAuth(auth_token, GUID)
participant "Verify API" as c_ver << Coordinating Node >>
c_authorize -> c_ver: isValidToken (token)
c_authorize <-- c_ver: T or F
c_crud <-- c_authorize: T or F
app_client <-- c_crud: handle_list
deactivate c_crud
participant "CRUD API" as m_crud << Member Node >>
activate m_crud
app_client -> m_crud: get(auth_token, handle)
participant "Server Authentication API" as m_authenticate << Member Node >>
m_crud -> m_authenticate: isAuth(auth_token, GUID)
m_crud <-- m_authenticate: T or F
m_crud -> m_crud: log(get, UserID, GUID)
app_client <-- m_crud: object or unauth or doesNotExist
deactivate m_crud
enduml