1
|
.. raw:: latex
|
2
|
|
3
|
\newpage
|
4
|
|
5
|
|
6
|
Identifier Management
|
7
|
=====================
|
8
|
|
9
|
.. index:: Identifiers
|
10
|
|
11
|
Author
|
12
|
Matthew B. Jones
|
13
|
|
14
|
Date
|
15
|
- 20100301 [MBJ] Initial draft of Identifier documentation
|
16
|
|
17
|
Goal
|
18
|
Extend Metacat to support identifiers with arbitrary syntax
|
19
|
|
20
|
Summary
|
21
|
Metacat currently supports identifier strings called 'docids' that have
|
22
|
the syntax 'scope.object.revision', such as 'foo.34.1' (we will refer to
|
23
|
these as 'LocalIDs'). We now want Metacat to support identifiers that are
|
24
|
arbitrary strings, but still enforce uniqueness and proper revision
|
25
|
handling (refer to these as GUIDs). Metacat must be able to accept
|
26
|
these strings as identifiers for all CRUD operations, and reference them
|
27
|
in search results.
|
28
|
|
29
|
Identifier Resolution
|
30
|
---------------------
|
31
|
Because Metacat uses LocalIDs throughout the code for references to objects,
|
32
|
and that LocalID has a constrained structure that includes semantics about
|
33
|
revisions in the identifier, it is difficult to wholesale replace it with
|
34
|
less-constrained string identifiers without re-writing much of Metacat.
|
35
|
Thus, our alternate strategy is to wrap the Metacat APIs with a
|
36
|
identifier resolution layer that keeps track of the unconstrained GUIDs and
|
37
|
maps them to constrained local identifiers which are used internally within
|
38
|
Metacat. The basic identifer table model is shown in Figure 1, while the
|
39
|
basic strategy for retrieving an object is shown in Figure 2, creating an
|
40
|
object is shown in Figure 3, updating an object in Figure 4, and deleting
|
41
|
an object is shown in Figure 5.
|
42
|
|
43
|
|
44
|
Identifier Table Structure
|
45
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
46
|
|
47
|
.. figure:: images/identifiers.png
|
48
|
|
49
|
Figure 1. Table structure for identifiers.
|
50
|
|
51
|
..
|
52
|
This block defines the table structure diagram referenced above.
|
53
|
@startuml images/identifiers.png
|
54
|
|
55
|
identifiers "*" -- "1" xml_documents
|
56
|
|
57
|
identifiers : String identifier
|
58
|
identifiers : String docid
|
59
|
identifiers : Integer rev
|
60
|
|
61
|
xml_documents : String docid
|
62
|
xml_documents : String rev
|
63
|
|
64
|
note right of identifiers
|
65
|
"identifiers.(docid,rev) is a foreign key into xml_documents"
|
66
|
end note
|
67
|
@enduml
|
68
|
|
69
|
.. raw:: latex
|
70
|
|
71
|
\newpage
|
72
|
|
73
|
.. raw:: pdf
|
74
|
|
75
|
PageBreak
|
76
|
|
77
|
|
78
|
Handling document read operations
|
79
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
80
|
|
81
|
An overview of the process needed to read an object using a GUID.
|
82
|
|
83
|
|
84
|
.. figure:: images/guid_read.png
|
85
|
|
86
|
Figure 2. Basic handling for string identifiers (GUIDs) as mapped to
|
87
|
docids (LocalIDs) to retrieve an object.
|
88
|
|
89
|
..
|
90
|
@startuml images/guid_read.png
|
91
|
!include plantuml.conf
|
92
|
actor User
|
93
|
participant "Client" as app_client << Application >>
|
94
|
participant "CRUD API" as c_crud << MetacatRestServlet >>
|
95
|
participant "Identifier Manager" as ident_man << IdentifierManager >>
|
96
|
participant "Handler" as handler << MetacatHandler >>
|
97
|
User -> app_client
|
98
|
app_client -> c_crud: get(token, GUID)
|
99
|
c_crud -> ident_man: getLocalID(GUID)
|
100
|
c_crud <-- ident_man: localID
|
101
|
c_crud -> handler: handleReadAction(localID)
|
102
|
c_crud <-- handler: object
|
103
|
c_crud --> app_client: object
|
104
|
|
105
|
@enduml
|
106
|
|
107
|
Handling document create operations
|
108
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
109
|
|
110
|
An overview of the process needed to create an object using a GUID.
|
111
|
|
112
|
.. figure:: images/guid_insert.png
|
113
|
|
114
|
Figure 3. Basic handling for string identifiers (GUIDs) as mapped to
|
115
|
docids (LocalIDs) to create an object.
|
116
|
|
117
|
..
|
118
|
@startuml images/guid_insert.png
|
119
|
!include plantuml.conf
|
120
|
actor User
|
121
|
participant "Client" as app_client << Application >>
|
122
|
participant "CRUD API" as c_crud << MetacatRestServlet >>
|
123
|
participant "Identifier Manager" as ident_man << IdentifierManager >>
|
124
|
participant "Handler" as handler << MetacatHandler >>
|
125
|
User -> app_client
|
126
|
app_client -> c_crud: create(token, GUID, object, sysmeta)
|
127
|
c_crud -> ident_man: identifierExists(GUID)
|
128
|
c_crud <-- ident_man: T or F
|
129
|
alt identifierExists == "F"
|
130
|
c_crud -> ident_man: mapToLocalId(GUID)
|
131
|
c_crud <-- ident_man: localID
|
132
|
c_crud -> handler: handleInsertAction(localID)
|
133
|
c_crud <-- handler: success
|
134
|
note right of c_crud
|
135
|
"Also need to address how to handle the sysmeta information wrt insertion methods"
|
136
|
end note
|
137
|
app_client <-- c_crud: success
|
138
|
else identifierExists == "T"
|
139
|
app_client <-- c_crud: IdentifierNotUnique
|
140
|
end
|
141
|
@enduml
|
142
|
|
143
|
Handling document update operations
|
144
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
145
|
|
146
|
An overview of the process needed to update an object using a GUID.
|
147
|
|
148
|
.. figure:: images/guid_update.png
|
149
|
|
150
|
Figure 4. Basic handling for string identifiers (GUIDs) as mapped to
|
151
|
docids (LocalIDs) to update an object.
|
152
|
|
153
|
..
|
154
|
@startuml images/guid_update.png
|
155
|
!include plantuml.conf
|
156
|
actor User
|
157
|
participant "Client" as app_client << Application >>
|
158
|
participant "CRUD API" as c_crud << MetacatRestServlet >>
|
159
|
participant "Identifier Manager" as ident_man << IdentifierManager >>
|
160
|
participant "Handler" as handler << MetacatHandler >>
|
161
|
User -> app_client
|
162
|
app_client -> c_crud: update(token, GUID, object, obsoletedGUID, sysmeta)
|
163
|
|
164
|
c_crud -> ident_man: identifierExists(obsoletedGUID)
|
165
|
c_crud <-- ident_man: T or F
|
166
|
alt identifierExists == "T"
|
167
|
|
168
|
c_crud -> ident_man: identifierExists(GUID)
|
169
|
c_crud <-- ident_man: T or F
|
170
|
alt identifierExists == "F"
|
171
|
c_crud -> ident_man: mapToLocalId(GUID, obsoletedGUID)
|
172
|
c_crud <-- ident_man: localID
|
173
|
c_crud -> handler: handleUpdateAction(localID)
|
174
|
c_crud <-- handler: success
|
175
|
note right of c_crud
|
176
|
"Also need to address how to handle the sysmeta information wrt update methods"
|
177
|
end note
|
178
|
app_client <-- c_crud: success
|
179
|
else identifierExists == "T"
|
180
|
app_client <-- c_crud: IdentifierNotUnique
|
181
|
end
|
182
|
else identifierExists == "F"
|
183
|
app_client <-- c_crud: NotFound
|
184
|
end
|
185
|
@enduml
|
186
|
|
187
|
Handling document delete operations
|
188
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
189
|
|
190
|
An overview of the process needed to delete an object using a GUID.
|
191
|
|
192
|
.. figure:: images/guid_delete.png
|
193
|
|
194
|
Figure 5. Basic handling for string identifiers (GUIDs) as mapped to
|
195
|
docids (LocalIDs) to delete an object.
|
196
|
|
197
|
..
|
198
|
@startuml images/guid_delete.png
|
199
|
!include plantuml.conf
|
200
|
actor User
|
201
|
participant "Client" as app_client << Application >>
|
202
|
participant "CRUD API" as c_crud << MetacatRestServlet >>
|
203
|
participant "Identifier Manager" as ident_man << IdentifierManager >>
|
204
|
participant "Handler" as handler << MetacatHandler >>
|
205
|
User -> app_client
|
206
|
app_client -> c_crud: delete(token, GUID)
|
207
|
c_crud -> ident_man: identifierExists(GUID)
|
208
|
c_crud <-- ident_man: T or F
|
209
|
alt identifierExists == "T"
|
210
|
c_crud -> ident_man: mapToLocalId(GUID)
|
211
|
c_crud <-- ident_man: localID
|
212
|
c_crud -> handler: handleDeleteAction(localID)
|
213
|
c_crud <-- handler: success
|
214
|
app_client <-- c_crud: success
|
215
|
else identifierExists == "F"
|
216
|
app_client <-- c_crud: NotFound
|
217
|
end
|
218
|
@enduml
|
219
|
|
220
|
..
|
221
|
This block defines the interaction diagram referenced above.
|
222
|
startuml images/01_interaction.png
|
223
|
!include plantuml.conf
|
224
|
actor User
|
225
|
participant "Client" as app_client << Application >>
|
226
|
User -> app_client
|
227
|
|
228
|
participant "CRUD API" as c_crud << Coordinating Node >>
|
229
|
activate c_crud
|
230
|
app_client -> c_crud: resolve(GUID, auth_token)
|
231
|
participant "Authorization API" as c_authorize << Coordinating Node >>
|
232
|
c_crud -> c_authorize: isAuth(auth_token, GUID)
|
233
|
participant "Verify API" as c_ver << Coordinating Node >>
|
234
|
c_authorize -> c_ver: isValidToken (token)
|
235
|
c_authorize <-- c_ver: T or F
|
236
|
c_crud <-- c_authorize: T or F
|
237
|
app_client <-- c_crud: handle_list
|
238
|
deactivate c_crud
|
239
|
|
240
|
participant "CRUD API" as m_crud << Member Node >>
|
241
|
activate m_crud
|
242
|
app_client -> m_crud: get(auth_token, handle)
|
243
|
participant "Server Authentication API" as m_authenticate << Member Node >>
|
244
|
m_crud -> m_authenticate: isAuth(auth_token, GUID)
|
245
|
m_crud <-- m_authenticate: T or F
|
246
|
m_crud -> m_crud: log(get, UserID, GUID)
|
247
|
app_client <-- m_crud: object or unauth or doesNotExist
|
248
|
deactivate m_crud
|
249
|
enduml
|