Äcdocutils.nodes
document
q)Åq}q(U	nametypesq}q(X���processing replication tasksqNX���replication eventsqNX ���use case 09 - replicate mn to mnqNX���replication auditingq	NX���uc09q
àX���implementation detailsqNX���historyqàuUsubstitution_defsq
}qUparse_messagesq]qUcurrent_sourceqNU
decorationqNUautofootnote_startqKUnameidsq}q(hUprocessing-replication-tasksqhUreplication-eventsqhUuse-case-09-replicate-mn-to-mnqh	Ureplication-auditingqh
Uuc09qhUimplementation-detailsqhUhistoryquUchildrenq]q(cdocutils.nodes
target
q)Åq }q!(U	rawsourceq"X	���.. _UC09:Uparentq#hUsourceq$Xj���/var/lib/jenkins/jobs/API_Documentation_trunk/workspace/api-documentation/source/design/UseCases/09_uc.txtq%Utagnameq&Utargetq'U
attributesq(}q)(Uidsq*]Ubackrefsq+]Udupnamesq,]Uclassesq-]Unamesq.]Urefidq/huUlineq0KUdocumentq1hh]ubcdocutils.nodes
section
q2)Åq3}q4(h"U�h#hh$h%Uexpect_referenced_by_nameq5}q6h
h sh&Usectionq7h(}q8(h,]h-]h+]h*]q9(hheh.]q:(hh
euh0Kh1hUexpect_referenced_by_idq;}q<hh sh]q=(cdocutils.nodes
title
q>)Åq?}q@(h"X ���Use Case 09 - Replicate MN to MNqAh#h3h$h%h&UtitleqBh(}qC(h,]h-]h+]h*]h.]uh0Kh1hh]qDcdocutils.nodes
Text
qEX ���Use Case 09 - Replicate MN to MNqFÖÅqG}qH(h"hAh#h?ubaubcsphinx.addnodes
index
qI)ÅqJ}qK(h"U�h#h3h$h%h&UindexqLh(}qM(h*]h+]h,]h-]h.]UentriesqN]qO((UsingleqPX���Use Case 09Uindex-0qQU�NtqR(hPX���UC09hQU�NtqS(hPX���Replicate MNhQU�NtqT(hPX	���replicatehQU�NtqUeUinlineqVâuh0Kh1hh]ubh)ÅqW}qX(h"U�h#h3h$h%h&h'h(}qY(h*]h+]h,]h-]h.]h/hQuh0Kh1hh]ubcdocutils.nodes
definition_list
qZ)Åq[}q\(h"U�h#h3h$h%h5}h&Udefinition_listq]h(}q^(h,]h-]h+]h*]q_hQah.]uh0Nh1hh;}q`hQhWsh]qa(cdocutils.nodes
definition_list_item
qb)Åqc}qd(h"X+���Revisions
View document revision history_.
h#h[h$h%h&Udefinition_list_itemqeh(}qf(h,]h-]h+]h*]h.]uh0K	h]qg(cdocutils.nodes
term
qh)Åqi}qj(h"X	���Revisionsqkh#hch$h%h&Utermqlh(}qm(h,]h-]h+]h*]h.]uh0K	h]qnhEX	���RevisionsqoÖÅqp}qq(h"hkh#hiubaubcdocutils.nodes
definition
qr)Åqs}qt(h"U�h(}qu(h,]h-]h+]h*]h.]uh#hch]qvcdocutils.nodes
paragraph
qw)Åqx}qy(h"X ���View document revision history_.h#hsh$h%h&U	paragraphqzh(}q{(h,]h-]h+]h*]h.]uh0K	h]q|(hEX���View document revision q}ÖÅq~}q(h"X���View document revision h#hxubcdocutils.nodes
reference
qÄ)ÅqÅ}qÇ(h"X���history_UresolvedqÉKh#hxh&U	referenceqÑh(}qÖ(UnameX���historyqÜUrefuriqáXî���https://redmine.dataone.org/projects/d1/repository/changes/documents/Projects/cicore/architecture/api-documentation/source/design/UseCases/09_uc.txtqàh*]h+]h,]h-]h.]uh]qâhEX���historyqäÖÅqã}qå(h"U�h#hÅubaubhEX���.ÖÅqç}qé(h"X���.h#hxubeubah&U
definitionqèubeubhb)Åqê}që(h"X5���Goal
Replicate data from Member Node to Member Node.
h#h[h$h%h&heh(}qí(h,]h-]h+]h*]h.]uh0Kh1hh]qì(hh)Åqî}qï(h"X���Goalqñh#hêh$h%h&hlh(}qó(h,]h-]h+]h*]h.]uh0Kh]qòhEX���GoalqôÖÅqö}qõ(h"hñh#hîubaubhr)Åqú}qù(h"U�h(}qû(h,]h-]h+]h*]h.]uh#hêh]qühw)Åq†}q°(h"X/���Replicate data from Member Node to Member Node.q¢h#húh$h%h&hzh(}q£(h,]h-]h+]h*]h.]uh0Kh]q§hEX/���Replicate data from Member Node to Member Node.q•ÖÅq¶}qß(h"h¢h#h†ubaubah&hèubeubhb)Åq®}q©(h"X5��Summary
Replication of content between Member Nodes (MN) is done to improve
persistence of information (avoid data loss with loss of MN) and to improve
accessibility (more choices for content retrieval can lower bandwidth
requirements for any particular MN). The process of replication is controlled
by a Coordinating Node (CN).

A full copy of science data and metadata is made during the replication
process, so the original science metadata and data is copied to the
recipient MN.

Data is copied across as an exact copy. Science metadata may be transformed
into another format if the original can not be supported.

It is important that the original metadata is preserved on the CNs, as
it is always possible that the original MN where the content was published
may go offline or be removed from the DataONE system.

h#h[h$h%h&heh(}q™(h,]h-]h+]h*]h.]uh0Kh1hh]q´(hh)Åq¨}q≠(h"X���SummaryqÆh#h®h$h%h&hlh(}qØ(h,]h-]h+]h*]h.]uh0Kh]q∞hEX���Summaryq±ÖÅq≤}q≥(h"hÆh#h¨ubaubhr)Åq¥}qµ(h"U�h(}q∂(h,]h-]h+]h*]h.]uh#h®h]q∑(hw)Åq∏}qπ(h"X@��Replication of content between Member Nodes (MN) is done to improve
persistence of information (avoid data loss with loss of MN) and to improve
accessibility (more choices for content retrieval can lower bandwidth
requirements for any particular MN). The process of replication is controlled
by a Coordinating Node (CN).q∫h#h¥h$h%h&hzh(}qª(h,]h-]h+]h*]h.]uh0Kh]qºhEX@��Replication of content between Member Nodes (MN) is done to improve
persistence of information (avoid data loss with loss of MN) and to improve
accessibility (more choices for content retrieval can lower bandwidth
requirements for any particular MN). The process of replication is controlled
by a Coordinating Node (CN).qΩÖÅqæ}qø(h"h∫h#h∏ubaubhw)Åq¿}q¡(h"Xô���A full copy of science data and metadata is made during the replication
process, so the original science metadata and data is copied to the
recipient MN.q¬h#h¥h$h%h&hzh(}q√(h,]h-]h+]h*]h.]uh0Kh]qƒhEXô���A full copy of science data and metadata is made during the replication
process, so the original science metadata and data is copied to the
recipient MN.q≈ÖÅq∆}q«(h"h¬h#h¿ubaubhw)Åq»}q…(h"XÖ���Data is copied across as an exact copy. Science metadata may be transformed
into another format if the original can not be supported.q h#h¥h$h%h&hzh(}qÀ(h,]h-]h+]h*]h.]uh0Kh]qÃhEXÖ���Data is copied across as an exact copy. Science metadata may be transformed
into another format if the original can not be supported.qÕÖÅqŒ}qœ(h"h h#h»ubaubhw)Åq–}q—(h"X«���It is important that the original metadata is preserved on the CNs, as
it is always possible that the original MN where the content was published
may go offline or be removed from the DataONE system.q“h#h¥h$h%h&hzh(}q”(h,]h-]h+]h*]h.]uh0Kh]q‘hEX«���It is important that the original metadata is preserved on the CNs, as
it is always possible that the original MN where the content was published
may go offline or be removed from the DataONE system.q’ÖÅq÷}q◊(h"h“h#h–ubaubeh&hèubeubhb)Åqÿ}qŸ(h"X8���Actors
Two Member Nodes, one or more Coordinating Nodes
h#h[h$h%h&heh(}q⁄(h,]h-]h+]h*]h.]uh0K"h1hh]q€(hh)Åq‹}q›(h"X���Actorsqfih#hÿh$h%h&hlh(}qfl(h,]h-]h+]h*]h.]uh0K"h]q‡hEX���Actorsq·ÖÅq‚}q„(h"hfih#h‹ubaubhr)Åq‰}qÂ(h"U�h(}qÊ(h,]h-]h+]h*]h.]uh#hÿh]qÁhw)ÅqË}qÈ(h"X0���Two Member Nodes, one or more Coordinating NodesqÍh#h‰h$h%h&hzh(}qÎ(h,]h-]h+]h*]h.]uh0K"h]qÏhEX0���Two Member Nodes, one or more Coordinating NodesqÌÖÅqÓ}qÔ(h"hÍh#hËubaubah&hèubeubhb)Åq}qÒ(h"Xª���Preconditions
- Content is present on a Member Node

- The content has been registered with the DataONE system (i.e. Member Node
  Synchronization has occurred for the data and metadata)
h#h[h$h%h&heh(}qÚ(h,]h-]h+]h*]h.]uh0K(h1hh]qÛ(hh)ÅqÙ}qı(h"X
���Preconditionsqˆh#hh$h%h&hlh(}q˜(h,]h-]h+]h*]h.]uh0K(h]q¯hEX
���Preconditionsq˘ÖÅq˙}q˚(h"hˆh#hÙubaubhr)Åq¸}q˝(h"U�h(}q˛(h,]h-]h+]h*]h.]uh#hh]qˇcdocutils.nodes
bullet_list
r���)År��}r��(h"U�h(}r��(Ubulletr��X���-h*]h+]h,]h-]h.]uh#h¸h]r��(cdocutils.nodes
list_item
r��)År��}r��(h"X$���Content is present on a Member Node
h(}r	��(h,]h-]h+]h*]h.]uh#j��h]r
��hw)År��}r��(h"X#���Content is present on a Member Noder
��h#j��h$h%h&hzh(}r��(h,]h-]h+]h*]h.]uh0K%h]r��hEX#���Content is present on a Member Noder��ÖÅr��}r��(h"j
��h#j��ubaubah&U	list_itemr��ubj��)År��}r��(h"XÇ���The content has been registered with the DataONE system (i.e. Member Node
Synchronization has occurred for the data and metadata)
h(}r��(h,]h-]h+]h*]h.]uh#j��h]r��hw)År��}r��(h"XÅ���The content has been registered with the DataONE system (i.e. Member Node
Synchronization has occurred for the data and metadata)r��h#j��h$h%h&hzh(}r��(h,]h-]h+]h*]h.]uh0K'h]r��hEX���The content has been registered with the DataONE system (i.e. Member Node
Synchronization has occurred for the data and metadata)r��ÖÅr��}r��(h"j��h#j��ubaubah&j��ubeh&Ubullet_listr ��ubah&hèubeubhb)År!��}r"��(h"X8��Triggers
- A Coordinating Node detects that there are insufficient copies of the
  object(s) in question.

- Information on a Member Node is altered

- Capabilities of a Member Node changes (accepting more or less content)

- Replication policy of DataONE or a Member Node changes

- A Member Node goes offline

h#h[h$h%h&heh(}r#��(h,]h-]h+]h*]h.]uh0K5h1hh]r$��(hh)År%��}r&��(h"X���Triggersr'��h#j!��h$h%h&hlh(}r(��(h,]h-]h+]h*]h.]uh0K5h]r)��hEX���Triggersr*��ÖÅr+��}r,��(h"j'��h#j%��ubaubhr)År-��}r.��(h"U�h(}r/��(h,]h-]h+]h*]h.]uh#j!��h]r0��j���)År1��}r2��(h"U�h(}r3��(j��X���-h*]h+]h,]h-]h.]uh#j-��h]r4��(j��)År5��}r6��(h"X]���A Coordinating Node detects that there are insufficient copies of the
object(s) in question.
h(}r7��(h,]h-]h+]h*]h.]uh#j1��h]r8��hw)År9��}r:��(h"X\���A Coordinating Node detects that there are insufficient copies of the
object(s) in question.r;��h#j5��h$h%h&hzh(}r<��(h,]h-]h+]h*]h.]uh0K+h]r=��hEX\���A Coordinating Node detects that there are insufficient copies of the
object(s) in question.r>��ÖÅr?��}r@��(h"j;��h#j9��ubaubah&j��ubj��)ÅrA��}rB��(h"X(���Information on a Member Node is altered
h(}rC��(h,]h-]h+]h*]h.]uh#j1��h]rD��hw)ÅrE��}rF��(h"X'���Information on a Member Node is alteredrG��h#jA��h$h%h&hzh(}rH��(h,]h-]h+]h*]h.]uh0K.h]rI��hEX'���Information on a Member Node is alteredrJ��ÖÅrK��}rL��(h"jG��h#jE��ubaubah&j��ubj��)ÅrM��}rN��(h"XG���Capabilities of a Member Node changes (accepting more or less content)
h(}rO��(h,]h-]h+]h*]h.]uh#j1��h]rP��hw)ÅrQ��}rR��(h"XF���Capabilities of a Member Node changes (accepting more or less content)rS��h#jM��h$h%h&hzh(}rT��(h,]h-]h+]h*]h.]uh0K0h]rU��hEXF���Capabilities of a Member Node changes (accepting more or less content)rV��ÖÅrW��}rX��(h"jS��h#jQ��ubaubah&j��ubj��)ÅrY��}rZ��(h"X7���Replication policy of DataONE or a Member Node changes
h(}r[��(h,]h-]h+]h*]h.]uh#j1��h]r\��hw)År]��}r^��(h"X6���Replication policy of DataONE or a Member Node changesr_��h#jY��h$h%h&hzh(}r`��(h,]h-]h+]h*]h.]uh0K2h]ra��hEX6���Replication policy of DataONE or a Member Node changesrb��ÖÅrc��}rd��(h"j_��h#j]��ubaubah&j��ubj��)Åre��}rf��(h"X���A Member Node goes offline

h(}rg��(h,]h-]h+]h*]h.]uh#j1��h]rh��hw)Åri��}rj��(h"X���A Member Node goes offlinerk��h#je��h$h%h&hzh(}rl��(h,]h-]h+]h*]h.]uh0K4h]rm��hEX���A Member Node goes offlinern��ÖÅro��}rp��(h"jk��h#ji��ubaubah&j��ubeh&j ��ubah&hèubeubhb)Årq��}rr��(h"X‘���Post Conditions
- Content is present on the recipient Member Node

- System metadata is updated to reflect the change

- Watchers are notified of the change

- Member Node and Coordinating Node logs are updated

h#h[h$h%h&heh(}rs��(h,]h-]h+]h*]h.]uh0K?h1hh]rt��(hh)Åru��}rv��(h"X���Post Conditionsrw��h#jq��h$h%h&hlh(}rx��(h,]h-]h+]h*]h.]uh0K?h]ry��hEX���Post Conditionsrz��ÖÅr{��}r|��(h"jw��h#ju��ubaubhr)År}��}r~��(h"U�h(}r��(h,]h-]h+]h*]h.]uh#jq��h]rÄ��j���)ÅrÅ��}rÇ��(h"U�h(}rÉ��(j��X���-h*]h+]h,]h-]h.]uh#j}��h]rÑ��(j��)ÅrÖ��}rÜ��(h"X0���Content is present on the recipient Member Node
h(}rá��(h,]h-]h+]h*]h.]uh#jÅ��h]rà��hw)Årâ��}rä��(h"X/���Content is present on the recipient Member Noderã��h#jÖ��h$h%h&hzh(}rå��(h,]h-]h+]h*]h.]uh0K8h]rç��hEX/���Content is present on the recipient Member Noderé��ÖÅrè��}rê��(h"jã��h#jâ��ubaubah&j��ubj��)Årë��}rí��(h"X1���System metadata is updated to reflect the change
h(}rì��(h,]h-]h+]h*]h.]uh#jÅ��h]rî��hw)Årï��}rñ��(h"X0���System metadata is updated to reflect the changeró��h#jë��h$h%h&hzh(}rò��(h,]h-]h+]h*]h.]uh0K:h]rô��hEX0���System metadata is updated to reflect the changerö��ÖÅrõ��}rú��(h"jó��h#jï��ubaubah&j��ubj��)Årù��}rû��(h"X$���Watchers are notified of the change
h(}rü��(h,]h-]h+]h*]h.]uh#jÅ��h]r†��hw)År°��}r¢��(h"X#���Watchers are notified of the changer£��h#jù��h$h%h&hzh(}r§��(h,]h-]h+]h*]h.]uh0K<h]r•��hEX#���Watchers are notified of the changer¶��ÖÅrß��}r®��(h"j£��h#j°��ubaubah&j��ubj��)År©��}r™��(h"X4���Member Node and Coordinating Node logs are updated

h(}r´��(h,]h-]h+]h*]h.]uh#jÅ��h]r¨��hw)År≠��}rÆ��(h"X2���Member Node and Coordinating Node logs are updatedrØ��h#j©��h$h%h&hzh(}r∞��(h,]h-]h+]h*]h.]uh0K>h]r±��hEX2���Member Node and Coordinating Node logs are updatedr≤��ÖÅr≥��}r¥��(h"jØ��h#j≠��ubaubah&j��ubeh&j ��ubah&hèubeubeubcdocutils.nodes
comment
rµ��)År∂��}r∑��(h"X”��@startuml images/09_uc.png
usecase "12. Authentication" as authen
package "DataONE"
  actor "Coordinating Node" as CN
  actor "Member Node 1" as MN1
  actor "Member Node 2" as MN2
  usecase "13. Authorization" as author
  usecase "01. Get Object" as GET
  usecase "04. Create object" as CREATE
  usecase "06. Synchronize content" as SYNC
  usecase "16. Log event" as log
  usecase "21. Notify subscribers" as subscribe
  CN -- CREATE
  CN -- SYNC
  MN1 -- CREATE
  MN2 -- GET
  MN1 -- GET
  GET ..> author: <<includes>>
  GET ..> authen: <<includes>>
  GET ..> log: <<includes>>
  GET ..> subscribe: <<includes>>
  CREATE ..> author: <<includes>>
  CREATE ..> log: <<includes>>
  CREATE ..> subscribe: <<includes>>
 @endumlh#h3h$h%h&Ucommentr∏��h(}rπ��(U	xml:spacer∫��Upreserverª��h*]h+]h,]h-]h.]uh0K[h1hh]rº��hEX”��@startuml images/09_uc.png
usecase "12. Authentication" as authen
package "DataONE"
  actor "Coordinating Node" as CN
  actor "Member Node 1" as MN1
  actor "Member Node 2" as MN2
  usecase "13. Authorization" as author
  usecase "01. Get Object" as GET
  usecase "04. Create object" as CREATE
  usecase "06. Synchronize content" as SYNC
  usecase "16. Log event" as log
  usecase "21. Notify subscribers" as subscribe
  CN -- CREATE
  CN -- SYNC
  MN1 -- CREATE
  MN2 -- GET
  MN1 -- GET
  GET ..> author: <<includes>>
  GET ..> authen: <<includes>>
  GET ..> log: <<includes>>
  GET ..> subscribe: <<includes>>
  CREATE ..> author: <<includes>>
  CREATE ..> log: <<includes>>
  CREATE ..> subscribe: <<includes>>
 @endumlrΩ��ÖÅræ��}rø��(h"U�h#j∂��ubaubcdocutils.nodes
image
r¿��)År¡��}r¬��(h"X���.. image:: images/09_uc.png
h#h3h$h%h&Uimager√��h(}rƒ��(UuriX ���design/UseCases/images/09_uc.pngr≈��h*]h+]h,]h-]U
candidatesr∆��}r«��U*j≈��sh.]uh0K]h1hh]ubhw)År»��}r…��(h"Xf���*Figure 1.* Use case diagram indicating the actors involved in the process of
Member Node replication.h#h3h$h%h&hzh(}r ��(h,]h-]h+]h*]h.]uh0K^h1hh]rÀ��(cdocutils.nodes
emphasis
rÃ��)ÅrÕ��}rŒ��(h"X���*Figure 1.*h(}rœ��(h,]h-]h+]h*]h.]uh#j»��h]r–��hEX	���Figure 1.r—��ÖÅr“��}r”��(h"U�h#jÕ��ubah&Uemphasisr‘��ubhEX[��� Use case diagram indicating the actors involved in the process of
Member Node replication.r’��ÖÅr÷��}r◊��(h"X[��� Use case diagram indicating the actors involved in the process of
Member Node replication.h#j»��ubeubjµ��)Årÿ��}rŸ��(h"X��@startuml images/09_seq.png
skinparam notebordercolor #AAAAAA
skinparam notefontcolor #222222
title Replicate an object between two Member Nodes\n\n
participant "mnA : MNode" as mnA <<MNode>>
participant "mnB : MNode" as mnB <<MNode>>
participant "cnXReplService : ReplicationService" as cnXrepl <<CNode>>
participant "cnZReplService : ReplicationService" as cnZ <<CNode>>

== Replication Event  ==
[-> cnXrepl : hzSystemMetadata.put(pid, sysmeta)
activate cnXrepl #D74F57

note right
  Synchronization services adds entry to
  SystemMetadata map managed by Hazelcast,
  EntryEvent is fired
end note

cnXrepl -> cnXrepl : entryAdded(EntryEvent<pid, sysmeta>)
cnXrepl -> cnXrepl : queueEvent(pid)
cnXrepl -> cnXrepl : itemAdded(pid)
note right
  hzReplicationEvents.offer(pid) is called to keep track of
  frequent hzSystemMetadata change events. When popped
  off of the queue, identifiers are placed into the
  hzHandledReplicationEvents set until the evaluation
  to create a task or not is complete. This prevents
  multiple task creation across CNs for the same event
end note

cnXrepl -> cnXrepl : createAndQueueTasks(pid)

loop for each ReplicationTask
cnXrepl -> cnXrepl : taskid = idGenerator.newId()
  note right
  Hazelcast.getIdGenerator("task-ids") has been
  called in ReplicationService constructor
end note
cnXrepl -> cnXrepl : hzReplicationTaskQueue.put(taskid, task)
note right
  Hazelcast distributes Replication
  Tasks to all CNs
end note
cnXrepl -> cnXrepl: setReplicationStatus(session, pid,\n    nodeRef, ReplicationStatus.QUEUED)
deactivate cnXrepl
end loop

== Regular Replication Audit ==

 [-> cnXrepl : auditReplicas()
 activate cnXrepl #D74F57

 note right
   Query the Metacat database to receive a short list of
   tasks which have not had their checksums verified in
   greater than 2 months
 end note
 cnXrepl ->] : getAuditShortList()
 cnXrepl <--] : shortList

 note over cnXrepl
 Bin the tasks by NodeReference for
 bulk processing my MNAuditTask
 end note
 loop for each Identifier in shortList
 cnXrepl -> cnXrepl : hzSystemMetadata.get(Identifier).getReplicaList()
 loop for each Replica in List<Replica>
 alt if Replica.replicaVerified is older than 2 months
 alt if auditTaskMap.containsKey(Replica.replicaMemberNode)
 cnXrepl -> cnXrepl : auditTaskMap.get(Replica.replicaMemberNode).add(Identifier)
 else else
 cnXrepl -> cnXrepl : auditTaskMap.put(Replica.replicaMemberNode, new List<Identifier>())\nauditTaskMap.get(Replica.replicaMemberNode).add(Identifier)
 end
 end
 end loop
 end loop
 loop for each NodeReference in auditTaskMap.keySet()
 cnXrepl -> cnXrepl : taskid = idGenerator.newId()
 cnXrepl -> cnXrepl : auditTask = MNAuditTask(NodeReference, List<Identifier>)
 cnXrepl -> cnXrepl : hzAuditTaskQueue.put(taskid, auditTask)
 end loop
 note right
   Hazelcast distributes Audit
   Tasks to all CNs
 end note
 deactivate cnXrepl

== Process Replication Tasks ==

cnZ -> cnZ: itemAdded(task)
activate cnZ #D74F57
cnZ -> cnZ: hzReplicationTaskQueue.poll()
note left
  Each ReplicationService polls the replication task
  queue when events are fired. The first to get the lock
  handles the task.  The others will also get the lock,
  but during evaluation, will not create a task because
  of the new state of the replica in the system metadata
end note

cnZ -> cnZ: ExecutorService.submit(task)
activate cnZ #DarkSalmon
cnZ -> cnZ: replicationTask.call(pid)
cnZ -> mnB: replicate(cnZSession, mnASession, pid)
activate mnB #D74F57
mnB --> cnZ: replicateResponse
deactivate cnZ
cnZ -> cnZ: setReplicationStatus(session, pid,\n    nodeRef, ReplicationStatus.REQUESTED)

note left
 Object's system metadata get's updated
end note

cnZ -> cnZ: updateSystemMetadata(pid)
cnZ --> cnZ: statusResponse

mnB -> mnA: getReplica(mnBSession, pid)
deactivate mnB
activate mnA #D74F57
mnA -> cnZ: isNodeAuthorized(mnASession, mnBSubject, pid)
cnZ --> mnA: authorizationResponse
mnA --> mnB: replicaBytes
deactivate mnA
activate mnB #D74F57

mnB -> cnZ: setReplicationStatus(session, pid,\n    nodeRef, ReplicationStatus.COMPLETE)
deactivate mnB
cnZ -> mnA: mnA.getChecksum(pid)
activate mnA #D74F57
mnA --> cnZ : checksum

note right
Object's system metadata get's updated
end note

deactivate mnA
cnZ -> cnZ: updateSystemMetadata(pid)
cnZ --> cnZ: statusResponse
deactivate cnZ


deactivate cnZ
deactivate cnZ

@endumlh#h3h$h%h&j∏��h(}r⁄��(j∫��jª��h*]h+]h,]h-]h.]uh0Kıh1hh]r€��hEX��@startuml images/09_seq.png
skinparam notebordercolor #AAAAAA
skinparam notefontcolor #222222
title Replicate an object between two Member Nodes\n\n
participant "mnA : MNode" as mnA <<MNode>>
participant "mnB : MNode" as mnB <<MNode>>
participant "cnXReplService : ReplicationService" as cnXrepl <<CNode>>
participant "cnZReplService : ReplicationService" as cnZ <<CNode>>

== Replication Event  ==
[-> cnXrepl : hzSystemMetadata.put(pid, sysmeta)
activate cnXrepl #D74F57

note right
  Synchronization services adds entry to
  SystemMetadata map managed by Hazelcast,
  EntryEvent is fired
end note

cnXrepl -> cnXrepl : entryAdded(EntryEvent<pid, sysmeta>)
cnXrepl -> cnXrepl : queueEvent(pid)
cnXrepl -> cnXrepl : itemAdded(pid)
note right
  hzReplicationEvents.offer(pid) is called to keep track of
  frequent hzSystemMetadata change events. When popped
  off of the queue, identifiers are placed into the
  hzHandledReplicationEvents set until the evaluation
  to create a task or not is complete. This prevents
  multiple task creation across CNs for the same event
end note

cnXrepl -> cnXrepl : createAndQueueTasks(pid)

loop for each ReplicationTask
cnXrepl -> cnXrepl : taskid = idGenerator.newId()
  note right
  Hazelcast.getIdGenerator("task-ids") has been
  called in ReplicationService constructor
end note
cnXrepl -> cnXrepl : hzReplicationTaskQueue.put(taskid, task)
note right
  Hazelcast distributes Replication
  Tasks to all CNs
end note
cnXrepl -> cnXrepl: setReplicationStatus(session, pid,\n    nodeRef, ReplicationStatus.QUEUED)
deactivate cnXrepl
end loop

== Regular Replication Audit ==

 [-> cnXrepl : auditReplicas()
 activate cnXrepl #D74F57

 note right
   Query the Metacat database to receive a short list of
   tasks which have not had their checksums verified in
   greater than 2 months
 end note
 cnXrepl ->] : getAuditShortList()
 cnXrepl <--] : shortList

 note over cnXrepl
 Bin the tasks by NodeReference for
 bulk processing my MNAuditTask
 end note
 loop for each Identifier in shortList
 cnXrepl -> cnXrepl : hzSystemMetadata.get(Identifier).getReplicaList()
 loop for each Replica in List<Replica>
 alt if Replica.replicaVerified is older than 2 months
 alt if auditTaskMap.containsKey(Replica.replicaMemberNode)
 cnXrepl -> cnXrepl : auditTaskMap.get(Replica.replicaMemberNode).add(Identifier)
 else else
 cnXrepl -> cnXrepl : auditTaskMap.put(Replica.replicaMemberNode, new List<Identifier>())\nauditTaskMap.get(Replica.replicaMemberNode).add(Identifier)
 end
 end
 end loop
 end loop
 loop for each NodeReference in auditTaskMap.keySet()
 cnXrepl -> cnXrepl : taskid = idGenerator.newId()
 cnXrepl -> cnXrepl : auditTask = MNAuditTask(NodeReference, List<Identifier>)
 cnXrepl -> cnXrepl : hzAuditTaskQueue.put(taskid, auditTask)
 end loop
 note right
   Hazelcast distributes Audit
   Tasks to all CNs
 end note
 deactivate cnXrepl

== Process Replication Tasks ==

cnZ -> cnZ: itemAdded(task)
activate cnZ #D74F57
cnZ -> cnZ: hzReplicationTaskQueue.poll()
note left
  Each ReplicationService polls the replication task
  queue when events are fired. The first to get the lock
  handles the task.  The others will also get the lock,
  but during evaluation, will not create a task because
  of the new state of the replica in the system metadata
end note

cnZ -> cnZ: ExecutorService.submit(task)
activate cnZ #DarkSalmon
cnZ -> cnZ: replicationTask.call(pid)
cnZ -> mnB: replicate(cnZSession, mnASession, pid)
activate mnB #D74F57
mnB --> cnZ: replicateResponse
deactivate cnZ
cnZ -> cnZ: setReplicationStatus(session, pid,\n    nodeRef, ReplicationStatus.REQUESTED)

note left
 Object's system metadata get's updated
end note

cnZ -> cnZ: updateSystemMetadata(pid)
cnZ --> cnZ: statusResponse

mnB -> mnA: getReplica(mnBSession, pid)
deactivate mnB
activate mnA #D74F57
mnA -> cnZ: isNodeAuthorized(mnASession, mnBSubject, pid)
cnZ --> mnA: authorizationResponse
mnA --> mnB: replicaBytes
deactivate mnA
activate mnB #D74F57

mnB -> cnZ: setReplicationStatus(session, pid,\n    nodeRef, ReplicationStatus.COMPLETE)
deactivate mnB
cnZ -> mnA: mnA.getChecksum(pid)
activate mnA #D74F57
mnA --> cnZ : checksum

note right
Object's system metadata get's updated
end note

deactivate mnA
cnZ -> cnZ: updateSystemMetadata(pid)
cnZ --> cnZ: statusResponse
deactivate cnZ


deactivate cnZ
deactivate cnZ

@endumlr‹��ÖÅr›��}rfi��(h"U�h#jÿ��ubaubj¿��)Årfl��}r‡��(h"X���.. image:: images/09_seq.png

h#h3h$h%h&j√��h(}r·��(UuriX!���design/UseCases/images/09_seq.pngr‚��h*]h+]h,]h-]j∆��}r„��U*j‚��sh.]uh0K¯h1hh]ubjµ��)År‰��}rÂ��(h"Xe�� @startuml images/09_seq_audit_1.png
 skinparam notebordercolor #AAAAAA
 skinparam notefontcolor #222222
 title Audit replicas on Member Nodes.\n\n
 participant "ReplicaAuditQuartzJob" as cnQuartz <<CN-1>>
 participant "ReplicaAuditService" as cnAudit <<CN-1>>
 participant "ReplicaAuditDao" as auditDao <<CN-1>>
 participant "DistributedExecutorService" as cnZ <<CN-Z>>

== Replication Audit ==

  note left of cnQuartz
   Quartz scheduled execution
   of replica audit processing.
  end note

    cnQuartz -> cnAudit : auditReplicas()
  activate cnAudit #D74F57

    cnAudit -> cnAudit : aquireReplicaAuditingLock();

  note over auditDao
    Query the Metacat replica system metadata replica status
    table for pids of replica records which have not been audited
    for the audit period length of time.  May be a paged result.
  end note
  cnAudit -> auditDao : getReplicasByDate()
  cnAudit <-- auditDao : List<Identifier> pidsToAudit

  loop for each Identifier pid in pidsToAudit
    note over cnAudit
      Create ReplicaAuditTasks if not already being handled.
      Tasks can be configured to batch several Identifiers
      into tasks or to create a task for each Identifier.
    end note
      alt if pid NOT in hzProcessingAuditIdentifiers
        cnAudit -> cnAudit : replicaAuditTasks.add(new ReplicaAuditTask(pid));
      end
      alt if replicaAuditTasks.size => replicaBatchSize
        note over cnAudit
            accumulatedTaskFuture List holds futures generated on this iteration.
            futuresToHandle holds futures generated on last iteration.
            Assumption is futures provided to distributed execution service on
            previous iteration should have executed asynch already.
        end note
        cnAudit -> cnAudit : futuresToHandle = accumulatedTaskFutures;  // futures from last batch
        cnAudit -> cnAudit : accumulatedTaskFutures.clear();
        loop for each ReplicaAuditTask auditTask in replicaAuditTasks
          note over cnZ
            Hazelcast distributed executor service used to
            distribute audit tasks among CN nodes.
          end note
          cnAudit -> cnZ : submit(auditTask);
          cnAudit -> cnAudit : hzProcessingAuditIdentfiers.removeAll(auditTask.pid);
          cnZ --> cnAudit : Future replicaTaskFuture;
          cnAudit -> cnAudit : accumulatedTaskFutures.add(replicaTaskFuture);
        end loop
        cnAudit -> cnAudit : replicaAuditTasks.clear(); // prepare for next batch tasks.
        loop for each Future replicaTaskFuture in futuresToHandle
          cnAudit -> cnAudit : handleResult(replicaTaskFuture.get());
        end loop
      end
  end loop
  note over cnAudit
      Handle futures from last batch of audit tasks
  end note
  loop for each Future replicaTaskFuture in accumulatedTaskFutures
      cnAudit->cnAudit: handleResult(replicaTaskFuture);
  end loop
  deactivate cnAudit

 @endumlh#h3h$h%h&j∏��h(}rÊ��(j∫��jª��h*]h+]h,]h-]h.]uh0MCh1hh]rÁ��hEXe�� @startuml images/09_seq_audit_1.png
 skinparam notebordercolor #AAAAAA
 skinparam notefontcolor #222222
 title Audit replicas on Member Nodes.\n\n
 participant "ReplicaAuditQuartzJob" as cnQuartz <<CN-1>>
 participant "ReplicaAuditService" as cnAudit <<CN-1>>
 participant "ReplicaAuditDao" as auditDao <<CN-1>>
 participant "DistributedExecutorService" as cnZ <<CN-Z>>

== Replication Audit ==

  note left of cnQuartz
   Quartz scheduled execution
   of replica audit processing.
  end note

    cnQuartz -> cnAudit : auditReplicas()
  activate cnAudit #D74F57

    cnAudit -> cnAudit : aquireReplicaAuditingLock();

  note over auditDao
    Query the Metacat replica system metadata replica status
    table for pids of replica records which have not been audited
    for the audit period length of time.  May be a paged result.
  end note
  cnAudit -> auditDao : getReplicasByDate()
  cnAudit <-- auditDao : List<Identifier> pidsToAudit

  loop for each Identifier pid in pidsToAudit
    note over cnAudit
      Create ReplicaAuditTasks if not already being handled.
      Tasks can be configured to batch several Identifiers
      into tasks or to create a task for each Identifier.
    end note
      alt if pid NOT in hzProcessingAuditIdentifiers
        cnAudit -> cnAudit : replicaAuditTasks.add(new ReplicaAuditTask(pid));
      end
      alt if replicaAuditTasks.size => replicaBatchSize
        note over cnAudit
            accumulatedTaskFuture List holds futures generated on this iteration.
            futuresToHandle holds futures generated on last iteration.
            Assumption is futures provided to distributed execution service on
            previous iteration should have executed asynch already.
        end note
        cnAudit -> cnAudit : futuresToHandle = accumulatedTaskFutures;  // futures from last batch
        cnAudit -> cnAudit : accumulatedTaskFutures.clear();
        loop for each ReplicaAuditTask auditTask in replicaAuditTasks
          note over cnZ
            Hazelcast distributed executor service used to
            distribute audit tasks among CN nodes.
          end note
          cnAudit -> cnZ : submit(auditTask);
          cnAudit -> cnAudit : hzProcessingAuditIdentfiers.removeAll(auditTask.pid);
          cnZ --> cnAudit : Future replicaTaskFuture;
          cnAudit -> cnAudit : accumulatedTaskFutures.add(replicaTaskFuture);
        end loop
        cnAudit -> cnAudit : replicaAuditTasks.clear(); // prepare for next batch tasks.
        loop for each Future replicaTaskFuture in futuresToHandle
          cnAudit -> cnAudit : handleResult(replicaTaskFuture.get());
        end loop
      end
  end loop
  note over cnAudit
      Handle futures from last batch of audit tasks
  end note
  loop for each Future replicaTaskFuture in accumulatedTaskFutures
      cnAudit->cnAudit: handleResult(replicaTaskFuture);
  end loop
  deactivate cnAudit

 @endumlrË��ÖÅrÈ��}rÍ��(h"U�h#j‰��ubaubhw)ÅrÎ��}rÏ��(h"Xˆ��*Figure 2.* Interactions for use case 09. The diagram describes transfer of a
single object from MN_A to MN_B as directed by a CN. It is assumed that the
object does not exist on MN_A and the object has been identified as requiring
replication by the CN checking its status in the system metadata. The end
state of a replicate operation is that content is available on the MN, the
MN has notified the CN of such, and the CN will schedule a synchronize
operation that will verify the copy as legitimate.h#h3h$h%h&hzh(}rÌ��(h,]h-]h+]h*]h.]uh0MDh1hh]rÓ��(jÃ��)ÅrÔ��}r��(h"X���*Figure 2.*h(}rÒ��(h,]h-]h+]h*]h.]uh#jÎ��h]rÚ��hEX	���Figure 2.rÛ��ÖÅrÙ��}rı��(h"U�h#jÔ��ubah&j‘��ubhEXÎ�� Interactions for use case 09. The diagram describes transfer of a
single object from MN_A to MN_B as directed by a CN. It is assumed that the
object does not exist on MN_A and the object has been identified as requiring
replication by the CN checking its status in the system metadata. The end
state of a replicate operation is that content is available on the MN, the
MN has notified the CN of such, and the CN will schedule a synchronize
operation that will verify the copy as legitimate.rˆ��ÖÅr˜��}r¯��(h"XÎ�� Interactions for use case 09. The diagram describes transfer of a
single object from MN_A to MN_B as directed by a CN. It is assumed that the
object does not exist on MN_A and the object has been identified as requiring
replication by the CN checking its status in the system metadata. The end
state of a replicate operation is that content is available on the MN, the
MN has notified the CN of such, and the CN will schedule a synchronize
operation that will verify the copy as legitimate.h#jÎ��ubeubh2)År˘��}r˙��(h"U�h#h3h$h%h&h7h(}r˚��(h,]h-]h+]h*]r¸��hah.]r˝��hauh0MMh1hh]r˛��(h>)Årˇ��}r���(h"X���Implementation Detailsr��h#j˘��h$h%h&hBh(}r��(h,]h-]h+]h*]h.]uh0MMh1hh]r��hEX���Implementation Detailsr��ÖÅr��}r��(h"j��h#jˇ��ubaubhw)År��}r��(h"X^��Replication of objects between Member Nodes (MN) within the DataONE system is
managed by the Coordinating Nodes (CN). CNs are aware of the replication
policies of each object (through system metadata) and the capabilities of each
MN (through node capabilities), and populate a distributed queue of replication
tasks to be processed by all of the CNs.r	��h#j˘��h$h%h&hzh(}r
��(h,]h-]h+]h*]h.]uh0MOh1hh]r��hEX^��Replication of objects between Member Nodes (MN) within the DataONE system is
managed by the Coordinating Nodes (CN). CNs are aware of the replication
policies of each object (through system metadata) and the capabilities of each
MN (through node capabilities), and populate a distributed queue of replication
tasks to be processed by all of the CNs.r��ÖÅr
��}r��(h"j	��h#j��ubaubhw)År��}r��(h"X+���Replication can be initiated in three ways:r��h#j˘��h$h%h&hzh(}r��(h,]h-]h+]h*]h.]uh0MUh1hh]r��hEX+���Replication can be initiated in three ways:r��ÖÅr��}r��(h"j��h#j��ubaubcdocutils.nodes
block_quote
r��)År��}r��(h"U�h#j˘��h$Nh&Ublock_quoter��h(}r��(h,]h-]h+]h*]h.]uh0Nh1hh]r��cdocutils.nodes
enumerated_list
r��)År��}r��(h"U�h(}r ��(Usuffixr!��U)h*]h+]h,]Uprefixr"��U�h-]h.]Uenumtyper#��Uarabicr$��uh#j��h]r%��(j��)År&��}r'��(h"X=���CN synchronization: harvesting of system and science metadatar(��h(}r)��(h,]h-]h+]h*]h.]uh#j��h]r*��hw)År+��}r,��(h"j(��h#j&��h$h%h&hzh(}r-��(h,]h-]h+]h*]h.]uh0MWh]r.��hEX=���CN synchronization: harvesting of system and science metadatar/��ÖÅr0��}r1��(h"j(��h#j+��ubaubah&j��ubj��)År2��}r3��(h"X:���CN timed replication: periodic sweep of all system objectsr4��h(}r5��(h,]h-]h+]h*]h.]uh#j��h]r6��hw)År7��}r8��(h"j4��h#j2��h$h%h&hzh(}r9��(h,]h-]h+]h*]h.]uh0MXh]r:��hEX:���CN timed replication: periodic sweep of all system objectsr;��ÖÅr<��}r=��(h"j4��h#j7��ubaubah&j��ubj��)År>��}r?��(h"XS���MN event-based replication: MN sends replication request to a
CN (not implemented)
h(}r@��(h,]h-]h+]h*]h.]uh#j��h]rA��hw)ÅrB��}rC��(h"XR���MN event-based replication: MN sends replication request to a
CN (not implemented)rD��h#j>��h$h%h&hzh(}rE��(h,]h-]h+]h*]h.]uh0MYh]rF��hEXR���MN event-based replication: MN sends replication request to a
CN (not implemented)rG��ÖÅrH��}rI��(h"jD��h#jB��ubaubah&j��ubeh&Uenumerated_listrJ��ubaubeubh2)ÅrK��}rL��(h"U�h#h3h$h%h&h7h(}rM��(h,]h-]h+]h*]rN��hah.]rO��hauh0M]h1hh]rP��(h>)ÅrQ��}rR��(h"X���Replication EventsrS��h#jK��h$h%h&hBh(}rT��(h,]h-]h+]h*]h.]uh0M]h1hh]rU��hEX���Replication EventsrV��ÖÅrW��}rX��(h"jS��h#jQ��ubaubhw)ÅrY��}rZ��(h"XG��The CN's maintain a synchronized, distributed Hazelcast Map of system
metadata (hzSystemMetadata). This map reflects the current state of the
DataONE system's object store. This in-memory map is also bound to the backing
Metacat object store via the Hazelcast MapStore and MapLoader interfaces. The
hzSystemMetadata map serves as an object-level locking mechanism across CNs, and
any service that will make changes to an object's system metadata will need to
gain a lock on the given object identifier in the map. The hzSystemMetadata map
is set to be persisted (backed-up) on 3 CNs.r[��h#jK��h$h%h&hzh(}r\��(h,]h-]h+]h*]h.]uh0M_h1hh]r]��hEXG��The CN's maintain a synchronized, distributed Hazelcast Map of system
metadata (hzSystemMetadata). This map reflects the current state of the
DataONE system's object store. This in-memory map is also bound to the backing
Metacat object store via the Hazelcast MapStore and MapLoader interfaces. The
hzSystemMetadata map serves as an object-level locking mechanism across CNs, and
any service that will make changes to an object's system metadata will need to
gain a lock on the given object identifier in the map. The hzSystemMetadata map
is set to be persisted (backed-up) on 3 CNs.r^��ÖÅr_��}r`��(h"j[��h#jY��ubaubhw)Åra��}rb��(h"X™��As the CN Synchronization Service becomes aware of create, update, and delete
events for MN objects through harvesting, it updates the hzSystemMetadata map.
The Replication service monitors this map for entry changes, and builds a list
of ReplicationTask objects for each changed identifier in the map. This is done by
calling ReplicationService.createReplicationTaskList(pid). The Replication
Service evaluates the ReplicationPolicy of the given object's system metadata,
evaluates the capabilities and availability of the potential target MNs, and
creates a ReplicationTask for each MN replication target up to the
numberOfReplicas in the object's ReplicationPolicy. Each ReplicationTask is
listed based on priority. The Replication Service then iterates through the
returned task list and populates the hzReplicationTasks queue with the ordered
tasks. Each item offered to the queue consists of a task identifier and a
ReplicationTask.rc��h#jK��h$h%h&hzh(}rd��(h,]h-]h+]h*]h.]uh0Mhh1hh]re��hEX™��As the CN Synchronization Service becomes aware of create, update, and delete
events for MN objects through harvesting, it updates the hzSystemMetadata map.
The Replication service monitors this map for entry changes, and builds a list
of ReplicationTask objects for each changed identifier in the map. This is done by
calling ReplicationService.createReplicationTaskList(pid). The Replication
Service evaluates the ReplicationPolicy of the given object's system metadata,
evaluates the capabilities and availability of the potential target MNs, and
creates a ReplicationTask for each MN replication target up to the
numberOfReplicas in the object's ReplicationPolicy. Each ReplicationTask is
listed based on priority. The Replication Service then iterates through the
returned task list and populates the hzReplicationTasks queue with the ordered
tasks. Each item offered to the queue consists of a task identifier and a
ReplicationTask.rf��ÖÅrg��}rh��(h"jc��h#ja��ubaubcdocutils.nodes
note
ri��)Årj��}rk��(h"XÇ���TODO: Describe the CN time-based population of the replication task queue
that periodically does a full sweep of the object store.h#jK��h$h%h&Unoterl��h(}rm��(h,]h-]h+]h*]h.]uh0Nh1hh]rn��hw)Åro��}rp��(h"XÇ���TODO: Describe the CN time-based population of the replication task queue
that periodically does a full sweep of the object store.rq��h#jj��h$h%h&hzh(}rr��(h,]h-]h+]h*]h.]uh0Mwh]rs��hEX���TODO: Describe the CN time-based population of the replication task queue
that periodically does a full sweep of the object store.rt��ÖÅru��}rv��(h"jq��h#jo��ubaubaubji��)Årw��}rx��(h"XY���TODO: Describe the MN-based replication via a CNReplication API request
(not implemented)h#jK��h$h%h&jl��h(}ry��(h,]h-]h+]h*]h.]uh0Nh1hh]rz��hw)År{��}r|��(h"XY���TODO: Describe the MN-based replication via a CNReplication API request
(not implemented)r}��h#jw��h$h%h&hzh(}r~��(h,]h-]h+]h*]h.]uh0M{h]r��hEXY���TODO: Describe the MN-based replication via a CNReplication API request
(not implemented)rÄ��ÖÅrÅ��}rÇ��(h"j}��h#j{��ubaubaubeubh2)ÅrÉ��}rÑ��(h"U�h#h3h$h%h&h7h(}rÖ��(h,]h-]h+]h*]rÜ��hah.]rá��hauh0MÄh1hh]rà��(h>)Årâ��}rä��(h"X���Processing Replication Tasksrã��h#jÉ��h$h%h&hBh(}rå��(h,]h-]h+]h*]h.]uh0MÄh1hh]rç��hEX���Processing Replication Tasksré��ÖÅrè��}rê��(h"jã��h#jâ��ubaubhw)Årë��}rí��(h"XÂ��As the hzReplicationTasks queue is populated, each CN's Replication Service
receives entry added events and polls the queue with a short timeout to submit
new tasks to process. A CN Replication Service instance's entryAdded() method is
fired, and it in turn polls the task queue and submits the ReplicationTask
to the cluster-wide Executor Service.  One of the CN's will execute the task by
calling the ReplicationTask.call() method.  This call initiates MN replication.
The CN calls replicate() on the target MN (mnB), passing in the cnZ token
(cnZToken), the originating node reference (mnA), and the identifier of the
object to be replicated (pid). This call triggers the MN (mnB) to call
getReplica() on the originating MN (mnA), passing in mnB token
(mnBToken) and the identifier of the object to be replicated (pid). In turn,
the CN updates the system metadata for the object, setting the ReplicationStatus
to REQUESTED after gaining the lock on the object. The lock is immediately
released.rì��h#jÉ��h$h%h&hzh(}rî��(h,]h-]h+]h*]h.]uh0MÇh1hh]rï��hEXÂ��As the hzReplicationTasks queue is populated, each CN's Replication Service
receives entry added events and polls the queue with a short timeout to submit
new tasks to process. A CN Replication Service instance's entryAdded() method is
fired, and it in turn polls the task queue and submits the ReplicationTask
to the cluster-wide Executor Service.  One of the CN's will execute the task by
calling the ReplicationTask.call() method.  This call initiates MN replication.
The CN calls replicate() on the target MN (mnB), passing in the cnZ token
(cnZToken), the originating node reference (mnA), and the identifier of the
object to be replicated (pid). This call triggers the MN (mnB) to call
getReplica() on the originating MN (mnA), passing in mnB token
(mnBToken) and the identifier of the object to be replicated (pid). In turn,
the CN updates the system metadata for the object, setting the ReplicationStatus
to REQUESTED after gaining the lock on the object. The lock is immediately
released.rñ��ÖÅró��}rò��(h"jì��h#jë��ubaubhw)Årô��}rö��(h"Xâ��Before responding to getReplica(), mnA checks for replication authorization by
calling isNodeAuthorized() on the CN, passing in the mnA token
(mnAToken), the Subject listed in the mnBToken (mnBSubject), the object
identifier (pid), and the desired replication permission
(replicationPermission). The Replication Service looks up Subject in the
LDAP replication group, and returns the response.rõ��h#jÉ��h$h%h&hzh(}rú��(h,]h-]h+]h*]h.]uh0Mëh1hh]rù��hEXâ��Before responding to getReplica(), mnA checks for replication authorization by
calling isNodeAuthorized() on the CN, passing in the mnA token
(mnAToken), the Subject listed in the mnBToken (mnBSubject), the object
identifier (pid), and the desired replication permission
(replicationPermission). The Replication Service looks up Subject in the
LDAP replication group, and returns the response.rû��ÖÅrü��}r†��(h"jõ��h#jô��ubaubhw)År°��}r¢��(h"XÄ��Upon successful authorization, mnA replicates the object (replicaBytes) to the
target MN (mnB). mnB in turn sends a successful replication response to the CN
(replicateResponse). The CN Replication Service once again updates the system
metadata for the object after gaining a lock in the hzSystemMetadataMap. The
lock is immediately released, and the statusResponse is sent to the CN.r£��h#jÉ��h$h%h&hzh(}r§��(h,]h-]h+]h*]h.]uh0Mòh1hh]r•��hEXÄ��Upon successful authorization, mnA replicates the object (replicaBytes) to the
target MN (mnB). mnB in turn sends a successful replication response to the CN
(replicateResponse). The CN Replication Service once again updates the system
metadata for the object after gaining a lock in the hzSystemMetadataMap. The
lock is immediately released, and the statusResponse is sent to the CN.r¶��ÖÅrß��}r®��(h"j£��h#j°��ubaubhw)År©��}r™��(h"X8��Note (2011.01.07 CWB): This simple authentication scheme will not work on
member nodes that have their own access control rules. In this scheme, each
member node will need to have knowledge of the administrative (or replication)
credentials for each of the other member nodes. The CN needs to handle the
login actions for both of the MNs involved and send an authenticated token
from MN_A to MN_B so that it can use that credential to successfully get the
document. This is only the case if the document on MN_A is read protected. If
it is public, not token is needed.r´��h#jÉ��h$h%h&hzh(}r¨��(h,]h-]h+]h*]h.]uh0Mûh1hh]r≠��hEX8��Note (2011.01.07 CWB): This simple authentication scheme will not work on
member nodes that have their own access control rules. In this scheme, each
member node will need to have knowledge of the administrative (or replication)
credentials for each of the other member nodes. The CN needs to handle the
login actions for both of the MNs involved and send an authenticated token
from MN_A to MN_B so that it can use that credential to successfully get the
document. This is only the case if the document on MN_A is read protected. If
it is public, not token is needed.rÆ��ÖÅrØ��}r∞��(h"j´��h#j©��ubaubhw)År±��}r≤��(h"Xß���Note that the call setReplicationStatus with a value of *COMPLETE* is
functionally equivalent to the *notify(objectCreated, identifier)* call
indicated in use case 06.h#jÉ��h$h%h&hzh(}r≥��(h,]h-]h+]h*]h.]uh0Mßh1hh]r¥��(hEX8���Note that the call setReplicationStatus with a value of rµ��ÖÅr∂��}r∑��(h"X8���Note that the call setReplicationStatus with a value of h#j±��ubjÃ��)År∏��}rπ��(h"X
���*COMPLETE*h(}r∫��(h,]h-]h+]h*]h.]uh#j±��h]rª��hEX���COMPLETErº��ÖÅrΩ��}ræ��(h"U�h#j∏��ubah&j‘��ubhEX#��� is
functionally equivalent to the rø��ÖÅr¿��}r¡��(h"X#��� is
functionally equivalent to the h#j±��ubjÃ��)År¬��}r√��(h"X#���*notify(objectCreated, identifier)*h(}rƒ��(h,]h-]h+]h*]h.]uh#j±��h]r≈��hEX!���notify(objectCreated, identifier)r∆��ÖÅr«��}r»��(h"U�h#j¬��ubah&j‘��ubhEX��� call
indicated in use case 06.r…��ÖÅr ��}rÀ��(h"X��� call
indicated in use case 06.h#j±��ubeubeubh2)ÅrÃ��}rÕ��(h"U�h#h3h$h%h&h7h(}rŒ��(h,]h-]h+]h*]rœ��hah.]r–��h	auh0M≠h1hh]r—��(h>)År“��}r”��(h"X���Replication Auditingr‘��h#jÃ��h$h%h&hBh(}r’��(h,]h-]h+]h*]h.]uh0M≠h1hh]r÷��hEX���Replication Auditingr◊��ÖÅrÿ��}rŸ��(h"j‘��h#j“��ubaubj¿��)År⁄��}r€��(h"X%���.. image:: images/09_seq_audit_1.png
h#jÃ��h$h%h&j√��h(}r‹��(UuriX)���design/UseCases/images/09_seq_audit_1.pngr›��h*]h+]h,]h-]j∆��}rfi��U*j›��sh.]uh0M≤h1hh]ubjµ��)Årfl��}r‡��(h"X§�� @startuml images/09_seq_audit_2.png
   skinparam notebordercolor #AAAAAA
   skinparam notefontcolor #222222
   title Replica Audit Task Procesing.\n\n
 participant "ReplicaAuditService" as cnAudit <<CN-1>>
   participant "DistributedExecutorService" as cnZ <<CN-Z>>
   participant "ReplicaAuditTask" as auditTask <<CN-Z>>
   participant "d1Client.CNode : CNodeClient" as cNodeClient <<CN-Z>>
 participant "d1Client.MNode : MNodeClient" as mnA <<MN-A>>
 participant "ReplicationManager" as repManager <<CN-Z>>

== Process replication audit. ==
 cnAudit -> cnZ : submit(replicaAuditTask);
   cnZ -> cnZ: execute(replicaAuditTask);
   cnZ -> auditTask : call()
   activate auditTask #D74F57

 loop for each Identifier pid in auditTask.pids
     auditTask -> cNodeClient : getSystemMetadata(pid);
     cNodeClient --> auditTask : sysMetadata;
     auditTask -> auditTask : verifiedReplicaCount = 0;
     loop for each Replica replica in sysMetadata.getReplicaList()
       auditTask -> auditTask : mnA = getMNodeClient(replica.getReplicaMemberNode());
       auditTask -> mnA : replicaChecksum = getChecksum(pid, sysMeta.getChecksum());
       alt if replicaChecksum == sysMetadata.getChecksum()
         auditTask -> auditTask : verfiedReplicaCount++;
         auditTask -> auditTask : replica.updateVerifiedDate(today);
         auditTask -> cNodeClient : updateReplicationMetadata(pid, replica);
       else else
         auditTask -> auditTask : replica.setReplicationStatus(INVALID);
         auditTask -> cNodeClient : updateReplicationMetadata(pid, replica);
         auditTask -> repManager : createAndQueueTasks(pid);
       end
     end loop
     alt if sysMetadata.getReplicationPolicy().getNumberReplicas !== verifiedReplicaCount
       auditTask -> repManager : createAndQueueTasks(pid);
     end
   end loop

 auditTask --> cnZ : String audit result
 deactivate auditTask

 cnZ --> cnAudit : Future - audit results including exceptions

 @endumlh#jÃ��h$h%h&j∏��h(}r·��(j∫��jª��h*]h+]h,]h-]h.]uh0M‡h1hh]r‚��hEX§�� @startuml images/09_seq_audit_2.png
   skinparam notebordercolor #AAAAAA
   skinparam notefontcolor #222222
   title Replica Audit Task Procesing.\n\n
 participant "ReplicaAuditService" as cnAudit <<CN-1>>
   participant "DistributedExecutorService" as cnZ <<CN-Z>>
   participant "ReplicaAuditTask" as auditTask <<CN-Z>>
   participant "d1Client.CNode : CNodeClient" as cNodeClient <<CN-Z>>
 participant "d1Client.MNode : MNodeClient" as mnA <<MN-A>>
 participant "ReplicationManager" as repManager <<CN-Z>>

== Process replication audit. ==
 cnAudit -> cnZ : submit(replicaAuditTask);
   cnZ -> cnZ: execute(replicaAuditTask);
   cnZ -> auditTask : call()
   activate auditTask #D74F57

 loop for each Identifier pid in auditTask.pids
     auditTask -> cNodeClient : getSystemMetadata(pid);
     cNodeClient --> auditTask : sysMetadata;
     auditTask -> auditTask : verifiedReplicaCount = 0;
     loop for each Replica replica in sysMetadata.getReplicaList()
       auditTask -> auditTask : mnA = getMNodeClient(replica.getReplicaMemberNode());
       auditTask -> mnA : replicaChecksum = getChecksum(pid, sysMeta.getChecksum());
       alt if replicaChecksum == sysMetadata.getChecksum()
         auditTask -> auditTask : verfiedReplicaCount++;
         auditTask -> auditTask : replica.updateVerifiedDate(today);
         auditTask -> cNodeClient : updateReplicationMetadata(pid, replica);
       else else
         auditTask -> auditTask : replica.setReplicationStatus(INVALID);
         auditTask -> cNodeClient : updateReplicationMetadata(pid, replica);
         auditTask -> repManager : createAndQueueTasks(pid);
       end
     end loop
     alt if sysMetadata.getReplicationPolicy().getNumberReplicas !== verifiedReplicaCount
       auditTask -> repManager : createAndQueueTasks(pid);
     end
   end loop

 auditTask --> cnZ : String audit result
 deactivate auditTask

 cnZ --> cnAudit : Future - audit results including exceptions

 @endumlr„��ÖÅr‰��}rÂ��(h"U�h#jfl��ubaubj¿��)ÅrÊ��}rÁ��(h"X'���.. image:: images/09_seq_audit_2.png


h#jÃ��h$h%h&j√��h(}rË��(UuriX)���design/UseCases/images/09_seq_audit_2.pngrÈ��h*]h+]h,]h-]j∆��}rÍ��U*jÈ��sh.]uh0M‰h1hh]ubjµ��)ÅrÎ��}rÏ��(h"X´�� @startuml images/09_uc_audit_components.png

title CN Replication Auditing Components

node "CN Audit Process(D1 Processing)" {
  frame "CN Replication Auditor" {
    frame "CN Common" {
      [ReplicationDao]
      }
      frame "CN Replication" {
        [Replication Service]
    }
      [CNAuditLogClient] --> [cn-audit-index] : add/remove log entries
    }
}

database "psql" {
  frame "metacat" {
    [smreplicationstatus] --> [ReplicationDao] : select audit candidates
  }
}

node "CN Service" {
  [REST Service] <-- [Replication Service] : update replica status/verified date
}

cloud "hazelcast" {
  frame "d1-processing" {
    [Replication Event Queue] <-- [Replication Service] : submit pids to replication
  }
}

cloud "CN Audit Log Cloud" as auditCloud {

  node "Zookeeper" {
    [index config] --> [cn-audit-index] : aquire cloud config
    [leader election] --> [cn-audit-index] : coordinate leader
    [replication] --> [cn-audit-index] : coordinate cloud
  }
  node "jetty" {
    node "Solr 4" {
      frame "cn-audit-index"{
      }
    }
  }
}



note "Each CN will be running its own instance of the zookeeper and jetty/solr.\n This forms the cloud cluster." as N1

@endumlh#jÃ��h$h%h&j∏��h(}rÌ��(j∫��jª��h*]h+]h,]h-]h.]uh0Mh1hh]rÓ��hEX´�� @startuml images/09_uc_audit_components.png

title CN Replication Auditing Components

node "CN Audit Process(D1 Processing)" {
  frame "CN Replication Auditor" {
    frame "CN Common" {
      [ReplicationDao]
      }
      frame "CN Replication" {
        [Replication Service]
    }
      [CNAuditLogClient] --> [cn-audit-index] : add/remove log entries
    }
}

database "psql" {
  frame "metacat" {
    [smreplicationstatus] --> [ReplicationDao] : select audit candidates
  }
}

node "CN Service" {
  [REST Service] <-- [Replication Service] : update replica status/verified date
}

cloud "hazelcast" {
  frame "d1-processing" {
    [Replication Event Queue] <-- [Replication Service] : submit pids to replication
  }
}

cloud "CN Audit Log Cloud" as auditCloud {

  node "Zookeeper" {
    [index config] --> [cn-audit-index] : aquire cloud config
    [leader election] --> [cn-audit-index] : coordinate leader
    [replication] --> [cn-audit-index] : coordinate cloud
  }
  node "jetty" {
    node "Solr 4" {
      frame "cn-audit-index"{
      }
    }
  }
}



note "Each CN will be running its own instance of the zookeeper and jetty/solr.\n This forms the cloud cluster." as N1

@endumlrÔ��ÖÅr��}rÒ��(h"U�h#jÎ��ubaubj¿��)ÅrÚ��}rÛ��(h"X.���.. image:: images/09_uc_audit_components.png

h#jÃ��h$h%h&j√��h(}rÙ��(UuriX1���design/UseCases/images/09_uc_audit_components.pngrı��h*]h+]h,]h-]j∆��}rˆ��U*jı��sh.]uh0Mh1hh]ubh)År˜��}r¯��(h"X°���.. _history: https://redmine.dataone.org/projects/d1/repository/changes/documents/Projects/cicore/architecture/api-documentation/source/design/UseCases/09_uc.txtU
referencedr˘��Kh#jÃ��h$h%h&h'h(}r˙��(háhàh*]r˚��hah+]h,]h-]h.]r¸��hauh0M h1hh]ubeubeubeh"U�Utransformerr˝��NU
footnote_refsr˛��}rˇ��Urefnamesr���}r��hÜ]r��hÅasUsymbol_footnotesr��]r��Uautofootnote_refsr��]r��Usymbol_footnote_refsr��]r��U	citationsr	��]r
��h1hUcurrent_liner��NUtransform_messagesr��]r
��(cdocutils.nodes
system_message
r��)År��}r��(h"U�h(}r��(h,]UlevelKh*]h+]Usourceh%h-]h.]UlineKUtypeUINFOr��uh]r��hw)År��}r��(h"U�h(}r��(h,]h-]h+]h*]h.]uh#j��h]r��hEX*���Hyperlink target "uc09" is not referenced.r��ÖÅr��}r��(h"U�h#j��ubah&hzubah&Usystem_messager��ubj��)År��}r��(h"U�h(}r��(h,]UlevelKh*]h+]Usourceh%h-]h.]UlineKUtypej��uh]r��hw)År ��}r!��(h"U�h(}r"��(h,]h-]h+]h*]h.]uh#j��h]r#��hEX-���Hyperlink target "index-0" is not referenced.r$��ÖÅr%��}r&��(h"U�h#j ��ubah&hzubah&j��ubeUreporterr'��NUid_startr(��KU
autofootnotesr)��]r*��U
citation_refsr+��}r,��Uindirect_targetsr-��]r.��Usettingsr/��(cdocutils.frontend
Values
r0��or1��}r2��(Ufootnote_backlinksr3��KUrecord_dependenciesr4��NUrfc_base_urlr5��Uhttps://tools.ietf.org/html/r6��U	tracebackr7��àUpep_referencesr8��NUstrip_commentsr9��NU
toc_backlinksr:��Uentryr;��U
language_coder<��Uenr=��U	datestampr>��NUreport_levelr?��KU_destinationr@��NU
halt_levelrA��KU
strip_classesrB��NhBNUerror_encoding_error_handlerrC��UbackslashreplacerD��UdebugrE��NUembed_stylesheetrF��âUoutput_encoding_error_handlerrG��UstrictrH��U
sectnum_xformrI��KUdump_transformsrJ��NU
docinfo_xformrK��KUwarning_streamrL��NUpep_file_url_templaterM��Upep-%04drN��Uexit_status_levelrO��KUconfigrP��NUstrict_visitorrQ��NUcloak_email_addressesrR��àUtrim_footnote_reference_spacerS��âUenvrT��NUdump_pseudo_xmlrU��NUexpose_internalsrV��NUsectsubtitle_xformrW��âUsource_linkrX��NUrfc_referencesrY��NUoutput_encodingrZ��Uutf-8r[��U
source_urlr\��NUinput_encodingr]��U	utf-8-sigr^��U_disable_configr_��NU	id_prefixr`��U�U	tab_widthra��KUerror_encodingrb��UUTF-8rc��U_sourcerd��h%Ugettext_compactre��àU	generatorrf��NUdump_internalsrg��NUsmart_quotesrh��âUpep_base_urlri��U https://www.python.org/dev/peps/rj��Usyntax_highlightrk��Ulongrl��Uinput_encoding_error_handlerrm��jH��Uauto_id_prefixrn��Uidro��Udoctitle_xformrp��âUstrip_elements_with_classesrq��NU
_config_filesrr��]Ufile_insertion_enabledrs��àUraw_enabledrt��KU
dump_settingsru��NubUsymbol_footnote_startrv��K�Uidsrw��}rx��(hjÃ��hj˘��hh3hh3hjK��hQh[hjÉ��hj˜��uUsubstitution_namesry��}rz��h&h1h(}r{��(h,]h*]h+]Usourceh%h-]h.]uU	footnotesr|��]r}��Urefidsr~��}r��(h]rÄ��h ahQ]rÅ��hWauub.