Pluggable protection provider doc

Change-Id: I64dce168322cf607951bada5ac0eb19f80c4b09e
This commit is contained in:
Saggi Mizrahi 2015-12-29 18:27:32 +02:00
parent 7273d222cb
commit adda314ede
3 changed files with 321 additions and 0 deletions

View File

@ -0,0 +1,99 @@
@startuml
title Pluggable Protection Provider
class ResourceType extends String {
}
class Resource {
+type: ResourceType
+id: UUID
}
class ResourceGraphNode {
resource: Resource
dependent_resources: []Resource
}
class ResourceGraphWalker {
+constructor(root: ResourceGraphNode)
+add_listener(listener: ResourceGraphWalkerListener)
+walk()
}
ResourceGraphWalker -- ResourceGraphWalkerListener
interface ResourceGraphWalkerListener {
on_node_enter(node: ResourceGraphNode, is_first_visit: boolean)
on_node_exit(node: ResourceGraphNode, is_first_visit: boolean)
}
ResourceGraphNode *- Resource
class ProtectableRegistry {
+ {static} fetch_dependant_resources(resource: Resource): []Resource
+ {static} register(resource_type: ResourceType, protectable: Protectable)
+ {static} list_resources(resource_type: ResourceType): [] Resource
}
ProtectableRegistry -- Resource: <<creates>>
ProtectableRegistry "1" *- "*" Protectable
interface Protectable {
+ possible_parent_types: []ResourceType
+ fetch_child_resources(resource: Resource): []Resource
+ list_resources(resource_type: ResourceType): []Resource
}
Resource *- ResourceType
class TaskFlow::Atom {
}
enum Operation {
protect
enable
disable
restore
}
class Context {
+plan: ProtectionPlan
+operation: Operation
+parameters: dict
+resource: ResourceGraphNode
+account: MetadataStore
+is_first_visit: boolean
}
Context -- Operation
interface ProtectionPlugin {
+get_pre_task(context: Context): TaskFlow::Atom?
+get_post_task(context: Context): TaskFlow::Atom?
}
ProtectionPlugin -- Context
ProtectionPlugin -- TaskFlow::Atom
interface ProtectionProvider {
create_checkpoint(root_resource: ResourceGraphNode): Checkpoint
delete_checkpoint(checkpoint_id: UUID)
}
class PluggableProtectionProvider extends ProtectionProvider {
-plugins: [ResourceType]ProtectionPlugin
}
PluggableProtectionProvider *-- "1..*" ProtectionPlugin: Uses for functionality
PluggableProtectionProvider -> ResourceGraphWalker: uses it to iterate over graph
ResourceGraphWalker - ResourceGraphNode
interface ProtectionProvider {
}
@enduml

View File

@ -0,0 +1,31 @@
Pluggable Protection Provider
=============================
The *Pluggable Protection Provider* will be the reference implementation
protection provider. It's purpose is to be fully pluggable and extandable so
that only extream use cases will need to implement their own Protection Provider
from scratch.
The protection provider will contain internally a map between any registered
*Protectable* and a corrosponding *Protection Plugin*. When the pluggable
protection provider is asked to perform an action, it will walk over the
graph and pass a context object to the appropriate plugin whenever a node is
encountered.
The resource graph is traversed in with DFS. When a node is first encountered
the protection manager gets the plugin for the appropriate resource type, builds
a context and passes it to the plugins `get_pre_task()` method. The plugin can
return any tasks that it wants added to the task list. When all of a node
childrens have been visited the `get_pre_task()` is called. The task returned
from this method will also be added to the task list but is also guranteed to
execute after all the child node's tasks have finished. Any of the methods can
return `None` if they don't want any action performed.
After the entire grap has been traversed the Protection Provider will return
the task lists which will be queued and than executed according to the
executor's policy. When all the tasks are done the operation is considered
complete.
This scheme decouples the tree structure form the task execution. A plugin that
handles multiple resources or that aggregates mutiple resources to one task can
use this mechanism to only return tasks when appropriate for it's scheme.

View File

@ -0,0 +1,191 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="784px" style="width:1833px;height:784px;" version="1.1" viewBox="0 0 1833 784" width="1833px">
<defs>
<filter height="300%" id="f1" width="300%" x="-1" y="-1">
<feGaussianBlur result="blurOut" stdDeviation="2.0" />
<feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0" />
<feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3" />
<feBlend in="SourceGraphic" in2="blurOut3" mode="normal" />
</filter>
</defs>
<g>
<text fill="#000000" font-family="sans-serif" font-size="18" lengthAdjust="spacingAndGlyphs" textLength="265" x="788.5" y="16.708">Pluggable Protection Provider</text>
<rect fill="#FEFECE" filter="url(#f1)" height="48" style="stroke: #A80036; stroke-width: 1.5;" width="120" x="1485.5" y="210.9531" />
<ellipse cx="1500.5" cy="226.9531" fill="#ADD1B2" rx="11" ry="11" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M1503.4688,232.5938 Q1502.8906,232.8906 1502.25,233.0391 Q1501.6094,233.1875 1500.9063,233.1875 Q1498.4063,233.1875 1497.0859,231.5391 Q1495.7656,229.8906 1495.7656,226.7656 Q1495.7656,223.6406 1497.0859,221.9844 Q1498.4063,220.3281 1500.9063,220.3281 Q1501.6094,220.3281 1502.2578,220.4844 Q1502.9063,220.6406 1503.4688,220.9375 L1503.4688,223.6563 Q1502.8438,223.0781 1502.25,222.8047 Q1501.6563,222.5313 1501.0313,222.5313 Q1499.6875,222.5313 1499,223.6016 Q1498.3125,224.6719 1498.3125,226.7656 Q1498.3125,228.8594 1499,229.9297 Q1499.6875,231 1501.0313,231 Q1501.6563,231 1502.25,230.7266 Q1502.8438,230.4531 1503.4688,229.875 L1503.4688,232.5938 Z "
/>
<text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="88" x="1514.5" y="231.1074">ResourceType</text>
<line style="stroke: #A80036; stroke-width: 1.5;" x1="1486.5" x2="1604.5" y1="242.9531" y2="242.9531" />
<line style="stroke: #A80036; stroke-width: 1.5;" x1="1486.5" x2="1604.5" y1="250.9531" y2="250.9531" />
<rect fill="#FEFECE" filter="url(#f1)" height="48" style="stroke: #A80036; stroke-width: 1.5;" width="69" x="1755" y="47.9531" />
<ellipse cx="1770" cy="63.9531" fill="#ADD1B2" rx="11" ry="11" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M1772.9688,69.5938 Q1772.3906,69.8906 1771.75,70.0391 Q1771.1094,70.1875 1770.4063,70.1875 Q1767.9063,70.1875 1766.5859,68.5391 Q1765.2656,66.8906 1765.2656,63.7656 Q1765.2656,60.6406 1766.5859,58.9844 Q1767.9063,57.3281 1770.4063,57.3281 Q1771.1094,57.3281 1771.7578,57.4844 Q1772.4063,57.6406 1772.9688,57.9375 L1772.9688,60.6563 Q1772.3438,60.0781 1771.75,59.8047 Q1771.1563,59.5313 1770.5313,59.5313 Q1769.1875,59.5313 1768.5,60.6016 Q1767.8125,61.6719 1767.8125,63.7656 Q1767.8125,65.8594 1768.5,66.9297 Q1769.1875,68 1770.5313,68 Q1771.1563,68 1771.75,67.7266 Q1772.3438,67.4531 1772.9688,66.875 L1772.9688,69.5938 Z "
/>
<text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="37" x="1784" y="68.1074">String</text>
<line style="stroke: #A80036; stroke-width: 1.5;" x1="1756" x2="1823" y1="79.9531" y2="79.9531" />
<line style="stroke: #A80036; stroke-width: 1.5;" x1="1756" x2="1823" y1="87.9531" y2="87.9531" />
<rect fill="#FEFECE" filter="url(#f1)" height="73.6094" style="stroke: #A80036; stroke-width: 1.5;" width="138" x="1216.5" y="197.9531" />
<ellipse cx="1252.65" cy="213.9531" fill="#ADD1B2" rx="11" ry="11" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M1255.6188,219.5938 Q1255.0406,219.8906 1254.4,220.0391 Q1253.7594,220.1875 1253.0563,220.1875 Q1250.5563,220.1875 1249.2359,218.5391 Q1247.9156,216.8906 1247.9156,213.7656 Q1247.9156,210.6406 1249.2359,208.9844 Q1250.5563,207.3281 1253.0563,207.3281 Q1253.7594,207.3281 1254.4078,207.4844 Q1255.0563,207.6406 1255.6188,207.9375 L1255.6188,210.6563 Q1254.9938,210.0781 1254.4,209.8047 Q1253.8063,209.5313 1253.1813,209.5313 Q1251.8375,209.5313 1251.15,210.6016 Q1250.4625,211.6719 1250.4625,213.7656 Q1250.4625,215.8594 1251.15,216.9297 Q1251.8375,218 1253.1813,218 Q1253.8063,218 1254.4,217.7266 Q1254.9938,217.4531 1255.6188,216.875 L1255.6188,219.5938 Z "
/>
<text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="59" x="1271.35" y="218.1074">Resource</text>
<line style="stroke: #A80036; stroke-width: 1.5;" x1="1217.5" x2="1353.5" y1="229.9531" y2="229.9531" />
<ellipse cx="1227.5" cy="241.8555" fill="none" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="112" x="1236.5" y="244.1636">type: ResourceType</text>
<ellipse cx="1227.5" cy="254.6602" fill="none" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="45" x="1236.5" y="256.9683">id: UUID</text>
<line style="stroke: #A80036; stroke-width: 1.5;" x1="1217.5" x2="1353.5" y1="263.5625" y2="263.5625" />
<rect fill="#FEFECE" filter="url(#f1)" height="73.6094" style="stroke: #A80036; stroke-width: 1.5;" width="205" x="942" y="197.9531" />
<ellipse cx="976.35" cy="213.9531" fill="#ADD1B2" rx="11" ry="11" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M979.3188,219.5938 Q978.7406,219.8906 978.1,220.0391 Q977.4594,220.1875 976.7563,220.1875 Q974.2563,220.1875 972.9359,218.5391 Q971.6156,216.8906 971.6156,213.7656 Q971.6156,210.6406 972.9359,208.9844 Q974.2563,207.3281 976.7563,207.3281 Q977.4594,207.3281 978.1078,207.4844 Q978.7563,207.6406 979.3188,207.9375 L979.3188,210.6563 Q978.6938,210.0781 978.1,209.8047 Q977.5063,209.5313 976.8813,209.5313 Q975.5375,209.5313 974.85,210.6016 Q974.1625,211.6719 974.1625,213.7656 Q974.1625,215.8594 974.85,216.9297 Q975.5375,218 976.8813,218 Q977.5063,218 978.1,217.7266 Q978.6938,217.4531 979.3188,216.875 L979.3188,219.5938 Z "
/>
<text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="130" x="994.65" y="218.1074">ResourceGraphNode</text>
<line style="stroke: #A80036; stroke-width: 1.5;" x1="943" x2="1146" y1="229.9531" y2="229.9531" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="112" x="948" y="244.1636">resource: Resource</text>
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="193" x="948" y="256.9683">dependent_resources: []Resource</text>
<line style="stroke: #A80036; stroke-width: 1.5;" x1="943" x2="1146" y1="263.5625" y2="263.5625" />
<rect fill="#FEFECE" filter="url(#f1)" height="86.4141" style="stroke: #A80036; stroke-width: 1.5;" width="326" x="546.5" y="191.9531" />
<ellipse cx="635.75" cy="207.9531" fill="#ADD1B2" rx="11" ry="11" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M638.7188,213.5938 Q638.1406,213.8906 637.5,214.0391 Q636.8594,214.1875 636.1563,214.1875 Q633.6563,214.1875 632.3359,212.5391 Q631.0156,210.8906 631.0156,207.7656 Q631.0156,204.6406 632.3359,202.9844 Q633.6563,201.3281 636.1563,201.3281 Q636.8594,201.3281 637.5078,201.4844 Q638.1563,201.6406 638.7188,201.9375 L638.7188,204.6563 Q638.0938,204.0781 637.5,203.8047 Q636.9063,203.5313 636.2813,203.5313 Q634.9375,203.5313 634.25,204.6016 Q633.5625,205.6719 633.5625,207.7656 Q633.5625,209.8594 634.25,210.9297 Q634.9375,212 636.2813,212 Q636.9063,212 637.5,211.7266 Q638.0938,211.4531 638.7188,210.875 L638.7188,213.5938 Z "
/>
<text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="139" x="656.25" y="212.1074">ResourceGraphWalker</text>
<line style="stroke: #A80036; stroke-width: 1.5;" x1="547.5" x2="871.5" y1="223.9531" y2="223.9531" />
<line style="stroke: #A80036; stroke-width: 1.5;" x1="547.5" x2="871.5" y1="231.9531" y2="231.9531" />
<ellipse cx="557.5" cy="243.8555" fill="#84BE84" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="221" x="566.5" y="246.1636">constructor(root: ResourceGraphNode)</text>
<ellipse cx="557.5" cy="256.6602" fill="#84BE84" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="300" x="566.5" y="258.9683">add_listener(listener: ResourceGraphWalkerListener)</text>
<ellipse cx="557.5" cy="269.4648" fill="#84BE84" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="33" x="566.5" y="271.7729">walk()</text>
<rect fill="#FEFECE" filter="url(#f1)" height="73.6094" style="stroke: #A80036; stroke-width: 1.5;" width="386" x="516.5" y="354.9531" />
<ellipse cx="610.75" cy="370.9531" fill="#B4A7E5" rx="11" ry="11" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M606.6719,366.7188 L606.6719,364.5625 L614.0625,364.5625 L614.0625,366.7188 L611.5938,366.7188 L611.5938,374.7969 L614.0625,374.7969 L614.0625,376.9531 L606.6719,376.9531 L606.6719,374.7969 L609.1406,374.7969 L609.1406,366.7188 L606.6719,366.7188 Z "
/>
<text fill="#000000" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacingAndGlyphs" textLength="189" x="631.25" y="375.1074">ResourceGraphWalkerListener</text>
<line style="stroke: #A80036; stroke-width: 1.5;" x1="517.5" x2="901.5" y1="386.9531" y2="386.9531" />
<line style="stroke: #A80036; stroke-width: 1.5;" x1="517.5" x2="901.5" y1="394.9531" y2="394.9531" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="374" x="522.5" y="409.1636">on_node_enter(node: ResourceGraphNode, is_first_visit: boolean)</text>
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="364" x="522.5" y="421.9683">on_node_exit(node: ResourceGraphNode, is_first_visit: boolean)</text>
<rect fill="#FEFECE" filter="url(#f1)" height="86.4141" style="stroke: #A80036; stroke-width: 1.5;" width="392" x="905.5" y="28.9531" />
<ellipse cx="1035.75" cy="44.9531" fill="#ADD1B2" rx="11" ry="11" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M1038.7188,50.5938 Q1038.1406,50.8906 1037.5,51.0391 Q1036.8594,51.1875 1036.1563,51.1875 Q1033.6563,51.1875 1032.3359,49.5391 Q1031.0156,47.8906 1031.0156,44.7656 Q1031.0156,41.6406 1032.3359,39.9844 Q1033.6563,38.3281 1036.1563,38.3281 Q1036.8594,38.3281 1037.5078,38.4844 Q1038.1563,38.6406 1038.7188,38.9375 L1038.7188,41.6563 Q1038.0938,41.0781 1037.5,40.8047 Q1036.9063,40.5313 1036.2813,40.5313 Q1034.9375,40.5313 1034.25,41.6016 Q1033.5625,42.6719 1033.5625,44.7656 Q1033.5625,46.8594 1034.25,47.9297 Q1034.9375,49 1036.2813,49 Q1036.9063,49 1037.5,48.7266 Q1038.0938,48.4531 1038.7188,47.875 L1038.7188,50.5938 Z "
/>
<text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="123" x="1056.25" y="49.1074">ProtectableRegistry</text>
<line style="stroke: #A80036; stroke-width: 1.5;" x1="906.5" x2="1296.5" y1="60.9531" y2="60.9531" />
<line style="stroke: #A80036; stroke-width: 1.5;" x1="906.5" x2="1296.5" y1="68.9531" y2="68.9531" />
<ellipse cx="916.5" cy="80.8555" fill="#84BE84" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" text-decoration="underline" textLength="347" x="925.5" y="83.1636">fetch_dependant_resources(resource: Resource): []Resource</text>
<line style="stroke: #000000; stroke-width: 1.0;" x1="925.5" x2="1272.5" y1="85.1636" y2="85.1636" />
<ellipse cx="916.5" cy="93.6602" fill="#84BE84" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" text-decoration="underline" textLength="366" x="925.5" y="95.9683">register(resource_type: ResourceType, protectable: Protectable)</text>
<line style="stroke: #000000; stroke-width: 1.0;" x1="925.5" x2="1291.5" y1="97.9683" y2="97.9683" />
<ellipse cx="916.5" cy="106.4648" fill="#84BE84" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" text-decoration="underline" textLength="331" x="925.5" y="108.7729">list_resources(resource_type: ResourceType): [] Resource</text>
<line style="stroke: #000000; stroke-width: 1.0;" x1="925.5" x2="1256.5" y1="110.7729" y2="110.7729" />
<rect fill="#FEFECE" filter="url(#f1)" height="86.4141" style="stroke: #A80036; stroke-width: 1.5;" width="353" x="1367" y="28.9531" />
<ellipse cx="1503.25" cy="44.9531" fill="#B4A7E5" rx="11" ry="11" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M1499.1719,40.7188 L1499.1719,38.5625 L1506.5625,38.5625 L1506.5625,40.7188 L1504.0938,40.7188 L1504.0938,48.7969 L1506.5625,48.7969 L1506.5625,50.9531 L1499.1719,50.9531 L1499.1719,48.7969 L1501.6406,48.7969 L1501.6406,40.7188 L1499.1719,40.7188 Z "
/>
<text fill="#000000" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacingAndGlyphs" textLength="72" x="1523.75" y="49.1074">Protectable</text>
<line style="stroke: #A80036; stroke-width: 1.5;" x1="1368" x2="1719" y1="60.9531" y2="60.9531" />
<ellipse cx="1378" cy="72.8555" fill="none" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="224" x="1387" y="75.1636">possible_parent_types: []ResourceType</text>
<line style="stroke: #A80036; stroke-width: 1.5;" x1="1368" x2="1719" y1="81.7578" y2="81.7578" />
<ellipse cx="1378" cy="93.6602" fill="#84BE84" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="313" x="1387" y="95.9683">fetch_child_resources(resource: Resource): []Resource</text>
<ellipse cx="1378" cy="106.4648" fill="#84BE84" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="327" x="1387" y="108.7729">list_resources(resource_type: ResourceType): []Resource</text>
<rect fill="#FEFECE" filter="url(#f1)" height="48" style="stroke: #A80036; stroke-width: 1.5;" width="128" x="120.5" y="528.4531" />
<ellipse cx="135.5" cy="544.4531" fill="#ADD1B2" rx="11" ry="11" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M138.4688,550.0938 Q137.8906,550.3906 137.25,550.5391 Q136.6094,550.6875 135.9063,550.6875 Q133.4063,550.6875 132.0859,549.0391 Q130.7656,547.3906 130.7656,544.2656 Q130.7656,541.1406 132.0859,539.4844 Q133.4063,537.8281 135.9063,537.8281 Q136.6094,537.8281 137.2578,537.9844 Q137.9063,538.1406 138.4688,538.4375 L138.4688,541.1563 Q137.8438,540.5781 137.25,540.3047 Q136.6563,540.0313 136.0313,540.0313 Q134.6875,540.0313 134,541.1016 Q133.3125,542.1719 133.3125,544.2656 Q133.3125,546.3594 134,547.4297 Q134.6875,548.5 136.0313,548.5 Q136.6563,548.5 137.25,548.2266 Q137.8438,547.9531 138.4688,547.375 L138.4688,550.0938 Z "
/>
<text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="96" x="149.5" y="548.6074">TaskFlow::Atom</text>
<line style="stroke: #A80036; stroke-width: 1.5;" x1="121.5" x2="247.5" y1="560.4531" y2="560.4531" />
<line style="stroke: #A80036; stroke-width: 1.5;" x1="121.5" x2="247.5" y1="568.4531" y2="568.4531" />
<rect fill="#FEFECE" filter="url(#f1)" height="99.2188" style="stroke: #A80036; stroke-width: 1.5;" width="94" x="337.5" y="675.9531" />
<ellipse cx="352.5" cy="691.9531" fill="#EB937F" rx="11" ry="11" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M356.6094,697.9531 L348.8906,697.9531 L348.8906,685.5625 L356.6094,685.5625 L356.6094,687.7188 L351.3438,687.7188 L351.3438,690.3906 L356.1094,690.3906 L356.1094,692.5469 L351.3438,692.5469 L351.3438,695.7969 L356.6094,695.7969 L356.6094,697.9531 Z "
/>
<text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="62" x="366.5" y="696.1074">Operation</text>
<line style="stroke: #A80036; stroke-width: 1.5;" x1="338.5" x2="430.5" y1="707.9531" y2="707.9531" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="40" x="343.5" y="722.1636">protect</text>
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="38" x="343.5" y="734.9683">enable</text>
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="41" x="343.5" y="747.7729">disable</text>
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="42" x="343.5" y="760.5776">restore</text>
<line style="stroke: #A80036; stroke-width: 1.5;" x1="338.5" x2="430.5" y1="767.1719" y2="767.1719" />
<rect fill="#FEFECE" filter="url(#f1)" height="124.8281" style="stroke: #A80036; stroke-width: 1.5;" width="202" x="283.5" y="489.9531" />
<ellipse cx="356.25" cy="505.9531" fill="#ADD1B2" rx="11" ry="11" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M359.2188,511.5938 Q358.6406,511.8906 358,512.0391 Q357.3594,512.1875 356.6563,512.1875 Q354.1563,512.1875 352.8359,510.5391 Q351.5156,508.8906 351.5156,505.7656 Q351.5156,502.6406 352.8359,500.9844 Q354.1563,499.3281 356.6563,499.3281 Q357.3594,499.3281 358.0078,499.4844 Q358.6563,499.6406 359.2188,499.9375 L359.2188,502.6563 Q358.5938,502.0781 358,501.8047 Q357.4063,501.5313 356.7813,501.5313 Q355.4375,501.5313 354.75,502.6016 Q354.0625,503.6719 354.0625,505.7656 Q354.0625,507.8594 354.75,508.9297 Q355.4375,510 356.7813,510 Q357.4063,510 358,509.7266 Q358.5938,509.4531 359.2188,508.875 L359.2188,511.5938 Z "
/>
<text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="48" x="376.75" y="510.1074">Context</text>
<line style="stroke: #A80036; stroke-width: 1.5;" x1="284.5" x2="484.5" y1="521.9531" y2="521.9531" />
<ellipse cx="294.5" cy="533.8555" fill="none" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="113" x="303.5" y="536.1636">plan: ProtectionPlan</text>
<ellipse cx="294.5" cy="546.6602" fill="none" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="118" x="303.5" y="548.9683">operation: Operation</text>
<ellipse cx="294.5" cy="559.4648" fill="none" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="95" x="303.5" y="561.7729">parameters: dict</text>
<ellipse cx="294.5" cy="572.2695" fill="none" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="176" x="303.5" y="574.5776">resource: ResourceGraphNode</text>
<ellipse cx="294.5" cy="585.0742" fill="none" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="135" x="303.5" y="587.3823">account: MetadataStore</text>
<ellipse cx="294.5" cy="597.8789" fill="none" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="121" x="303.5" y="600.187">is_first_visit: boolean</text>
<line style="stroke: #A80036; stroke-width: 1.5;" x1="284.5" x2="484.5" y1="606.7813" y2="606.7813" />
<rect fill="#FEFECE" filter="url(#f1)" height="73.6094" style="stroke: #A80036; stroke-width: 1.5;" width="308" x="50.5" y="354.9531" />
<ellipse cx="149.75" cy="370.9531" fill="#B4A7E5" rx="11" ry="11" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M145.6719,366.7188 L145.6719,364.5625 L153.0625,364.5625 L153.0625,366.7188 L150.5938,366.7188 L150.5938,374.7969 L153.0625,374.7969 L153.0625,376.9531 L145.6719,376.9531 L145.6719,374.7969 L148.1406,374.7969 L148.1406,366.7188 L145.6719,366.7188 Z "
/>
<text fill="#000000" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacingAndGlyphs" textLength="101" x="170.25" y="375.1074">ProtectionPlugin</text>
<line style="stroke: #A80036; stroke-width: 1.5;" x1="51.5" x2="357.5" y1="386.9531" y2="386.9531" />
<line style="stroke: #A80036; stroke-width: 1.5;" x1="51.5" x2="357.5" y1="394.9531" y2="394.9531" />
<ellipse cx="61.5" cy="406.8555" fill="#84BE84" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="276" x="70.5" y="409.1636">get_pre_task(context: Context): TaskFlow::Atom?</text>
<ellipse cx="61.5" cy="419.6602" fill="#84BE84" rx="3" ry="3" style="stroke: #038048; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="282" x="70.5" y="421.9683">get_post_task(context: Context): TaskFlow::Atom?</text>
<rect fill="#FEFECE" filter="url(#f1)" height="73.6094" style="stroke: #A80036; stroke-width: 1.5;" width="397" x="6" y="34.9531" />
<ellipse cx="143.25" cy="50.9531" fill="#B4A7E5" rx="11" ry="11" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M139.1719,46.7188 L139.1719,44.5625 L146.5625,44.5625 L146.5625,46.7188 L144.0938,46.7188 L144.0938,54.7969 L146.5625,54.7969 L146.5625,56.9531 L139.1719,56.9531 L139.1719,54.7969 L141.6406,54.7969 L141.6406,46.7188 L139.1719,46.7188 Z "
/>
<text fill="#000000" font-family="sans-serif" font-size="12" font-style="italic" lengthAdjust="spacingAndGlyphs" textLength="114" x="163.75" y="55.1074">ProtectionProvider</text>
<line style="stroke: #A80036; stroke-width: 1.5;" x1="7" x2="402" y1="66.9531" y2="66.9531" />
<line style="stroke: #A80036; stroke-width: 1.5;" x1="7" x2="402" y1="74.9531" y2="74.9531" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="385" x="12" y="89.1636">create_checkpoint(root_resource: ResourceGraphNode): Checkpoint</text>
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="220" x="12" y="101.9683">delete_checkpoint(checkpoint_id: UUID)</text>
<rect fill="#FEFECE" filter="url(#f1)" height="60.8047" style="stroke: #A80036; stroke-width: 1.5;" width="254" x="77.5" y="204.4531" />
<ellipse cx="112.3" cy="220.4531" fill="#ADD1B2" rx="11" ry="11" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M115.2688,226.0938 Q114.6906,226.3906 114.05,226.5391 Q113.4094,226.6875 112.7063,226.6875 Q110.2063,226.6875 108.8859,225.0391 Q107.5656,223.3906 107.5656,220.2656 Q107.5656,217.1406 108.8859,215.4844 Q110.2063,213.8281 112.7063,213.8281 Q113.4094,213.8281 114.0578,213.9844 Q114.7063,214.1406 115.2688,214.4375 L115.2688,217.1563 Q114.6438,216.5781 114.05,216.3047 Q113.4563,216.0313 112.8313,216.0313 Q111.4875,216.0313 110.8,217.1016 Q110.1125,218.1719 110.1125,220.2656 Q110.1125,222.3594 110.8,223.4297 Q111.4875,224.5 112.8313,224.5 Q113.4563,224.5 114.05,224.2266 Q114.6438,223.9531 115.2688,223.375 L115.2688,226.0938 Z "
/>
<text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacingAndGlyphs" textLength="178" x="130.7" y="224.6074">PluggableProtectionProvider</text>
<line style="stroke: #A80036; stroke-width: 1.5;" x1="78.5" x2="330.5" y1="236.4531" y2="236.4531" />
<rect fill="none" height="6" style="stroke: #C82930; stroke-width: 1.0;" width="6" x="85.5" y="245.3555" />
<text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacingAndGlyphs" textLength="228" x="97.5" y="250.6636">plugins: [ResourceType]ProtectionPlugin</text>
<line style="stroke: #A80036; stroke-width: 1.5;" x1="78.5" x2="330.5" y1="257.2578" y2="257.2578" />
<path d="M1746.09,108.6681 C1743.21,110.8321 1740.33,112.9451 1737.5,114.9531 C1686.97,150.8101 1625.67,187.7361 1586.15,210.7521 " fill="none" style="stroke: #A80036; stroke-width: 1.0;" />
<polygon fill="none" points="1742.14,102.8711,1762.2,96.0591,1750.76,113.8971,1742.14,102.8711" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M709.5,278.3071 C709.5,302.2401 709.5,331.8451 709.5,354.6981 " fill="none" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M1160.36,234.9531 C1179.01,234.9531 1197.66,234.9531 1216.31,234.9531 " fill="none" style="stroke: #A80036; stroke-width: 1.0;" />
<polygon fill="#A80036" points="1147.11,234.9531,1153.11,238.9531,1159.11,234.9531,1153.11,230.9531,1147.11,234.9531" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M1149.84,115.2541 C1179.23,140.9681 1216.36,173.4521 1244.34,197.9341 " fill="none" style="stroke: #A80036; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="92" x="1199.5" y="158.02">&lt;&lt;creates&gt;&gt;</text>
<path d="M1311.12,71.9531 C1329.74,71.9531 1348.35,71.9531 1366.97,71.9531 " fill="none" style="stroke: #A80036; stroke-width: 1.0;" />
<polygon fill="#A80036" points="1297.9,71.9531,1303.9,75.9531,1309.9,71.9531,1303.9,67.9531,1297.9,71.9531" style="stroke: #A80036; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="8" x="1305.7281" y="68.7216">1</text>
<text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="7" x="1351.8124" y="68.6738">*</text>
<path d="M1367.6,234.9531 C1406.89,234.9531 1446.17,234.9531 1485.46,234.9531 " fill="none" style="stroke: #A80036; stroke-width: 1.0;" />
<polygon fill="#A80036" points="1354.56,234.9531,1360.56,238.9531,1366.56,234.9531,1360.56,230.9531,1354.56,234.9531" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M384.5,615.1881 C384.5,635.1821 384.5,657.0601 384.5,675.9516 " fill="none" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M245.796,429.3161 C266.139,447.2301 291.234,469.3271 314.46,489.7791 " fill="none" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M199.912,429.3161 C196.083,459.6591 190.739,502.0061 187.455,528.0311 " fill="none" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M204.5,129.2711 C204.5,154.5851 204.5,183.4151 204.5,204.4011 " fill="none" style="stroke: #A80036; stroke-width: 1.0;" />
<polygon fill="none" points="197.5,129.0851,204.5,109.0851,211.5,129.0851,197.5,129.0851" style="stroke: #A80036; stroke-width: 1.0;" />
<path d="M204.5,278.7881 C204.5,302.6441 204.5,332.0191 204.5,354.7231 " fill="none" style="stroke: #A80036; stroke-width: 1.0;" />
<polygon fill="#A80036" points="204.5,265.4721,200.5,271.4721,204.5,277.4721,208.5,271.4721,204.5,265.4721" style="stroke: #A80036; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="134" x="205.5" y="321.02">Uses for functionality</text>
<text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="23" x="179.4516" y="343.8691">1..*</text>
<path d="M331.607,234.9531 C395.109,234.9531 472.792,234.9531 541.174,234.9531 " fill="none" style="stroke: #A80036; stroke-width: 1.0;" />
<polygon fill="#A80036" points="546.499,234.9531,537.499,230.9531,541.499,234.9531,537.499,238.9531,546.499,234.9531" style="stroke: #A80036; stroke-width: 1.0;" />
<text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="178" x="350" y="228.02">uses it to iterate over graph</text>
<path d="M872.747,234.9531 C895.782,234.9531 918.816,234.9531 941.851,234.9531 " fill="none" style="stroke: #A80036; stroke-width: 1.0;" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 30 KiB