)]}'
{"doc/images/available_protectables.svg":[{"author":{"_account_id":13070,"name":"Eran Gampel","email":"eran@gampel.net","username":"Gampel"},"change_message_id":"0258988d0ece8cebae91d4275476e2c87fb055e2","unresolved":false,"context_lines":[{"line_number":1,"context_line":"\u003c?xml version\u003d\"1.0\" encoding\u003d\"UTF-8\" standalone\u003d\"yes\"?\u003e"},{"line_number":2,"context_line":"    \u003csvg xmlns\u003d\"http://www.w3.org/2000/svg\" xmlns:xlink\u003d\"http://www.w3.org/1999/xlink\" height\u003d\"370px\" style\u003d\"width:717px;height:370px;\" version\u003d\"1.1\" viewBox\u003d\"0 0 717 370\" width\u003d\"717px\"\u003e"},{"line_number":3,"context_line":"        \u003cdefs\u003e"},{"line_number":4,"context_line":"            \u003cfilter height\u003d\"300%\" id\u003d\"f1\" width\u003d\"300%\" x\u003d\"-1\" y\u003d\"-1\"\u003e"}],"source_content_type":"application/xml","patch_set":6,"id":"da6ed579_9aee14b3","line":1,"updated":"2016-01-13 02:21:11.000000000","message":"please update the svg to not includ OS::Neutron::SecurityGrou","commit_id":"c4a908a057e3ffcf242434de7637105d41501a6a"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"479daad120c0699e0c29b193df197c1036ff4f91","unresolved":false,"context_lines":[{"line_number":1,"context_line":"\u003c?xml version\u003d\"1.0\" encoding\u003d\"UTF-8\" standalone\u003d\"yes\"?\u003e"},{"line_number":2,"context_line":"    \u003csvg xmlns\u003d\"http://www.w3.org/2000/svg\" xmlns:xlink\u003d\"http://www.w3.org/1999/xlink\" height\u003d\"370px\" style\u003d\"width:612px;height:370px;\" version\u003d\"1.1\" viewBox\u003d\"0 0 612 370\" width\u003d\"612px\"\u003e"},{"line_number":3,"context_line":"        \u003cdefs\u003e"},{"line_number":4,"context_line":"            \u003cfilter height\u003d\"300%\" id\u003d\"f1\" width\u003d\"300%\" x\u003d\"-1\" y\u003d\"-1\"\u003e"}],"source_content_type":"application/xml","patch_set":8,"id":"9a68dd71_e81674f0","line":1,"updated":"2016-01-27 06:45:19.000000000","message":"Is it possible to commit the .pu file of available protectables as well? the svg file is hard to comment.\nBTW, why the relationship here between project to others is inheritance? Shouldn\u0027t it be composition? same as the relationship between VM and volume/image.","commit_id":"976ea6237eaabcea162f04ba4f2ae4da50169f27"}],"doc/source/api/pluggable_protection_provider.pu":[{"author":{"_account_id":15069,"name":"zhonghuali","email":"lizhonghua.li@huawei.com","username":"sloblee"},"change_message_id":"5accad6dbc069a8c4b1006c3e171f074ab62e0ec","unresolved":false,"context_lines":[{"line_number":13,"context_line":""},{"line_number":14,"context_line":"class ResourceGraphNode {"},{"line_number":15,"context_line":"    resource: Resource"},{"line_number":16,"context_line":"    dependent_resources: []Resource"},{"line_number":17,"context_line":"}"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"class ResourceGraphWalker {"}],"source_content_type":"application/octet-stream","patch_set":2,"id":"fa69d971_57f64c90","line":16,"range":{"start_line":16,"start_character":4,"end_line":16,"end_character":23},"updated":"2015-12-31 07:14:10.000000000","message":"i\u0027m not sure i understood all the diagrams.\ni wonder if it is a mistake here,i think the ResourceGrapNode\u0027s dependences should be other ResourceGraphNodes, not refer to Resource directly. so that, ResourceGraphWalker can go over all the nodes in a graph through the root Node.\nplease check if i am right.","commit_id":"21c24fd9bfce5e55e9f6f1ede466c46dd2a63d06"},{"author":{"_account_id":13070,"name":"Eran Gampel","email":"eran@gampel.net","username":"Gampel"},"change_message_id":"8fe0e5647290457ddbd9e33af310c34b41f77593","unresolved":false,"context_lines":[{"line_number":13,"context_line":""},{"line_number":14,"context_line":"class ResourceGraphNode {"},{"line_number":15,"context_line":"    resource: Resource"},{"line_number":16,"context_line":"    dependent_resources: []Resource"},{"line_number":17,"context_line":"}"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"class ResourceGraphWalker {"}],"source_content_type":"application/octet-stream","patch_set":2,"id":"fa69d971_a3b666da","line":16,"range":{"start_line":16,"start_character":4,"end_line":16,"end_character":23},"in_reply_to":"fa69d971_57f64c90","updated":"2015-12-31 10:06:46.000000000","message":"You are correct i will fix that","commit_id":"21c24fd9bfce5e55e9f6f1ede466c46dd2a63d06"},{"author":{"_account_id":15069,"name":"zhonghuali","email":"lizhonghua.li@huawei.com","username":"sloblee"},"change_message_id":"5accad6dbc069a8c4b1006c3e171f074ab62e0ec","unresolved":false,"context_lines":[{"line_number":72,"context_line":"Context -- Operation"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"interface ProtectionPlugin {"},{"line_number":75,"context_line":"    +get_pre_task(context: Context): TaskFlow::Atom?"},{"line_number":76,"context_line":"    +get_post_task(context: Context): TaskFlow::Atom?"},{"line_number":77,"context_line":"}"},{"line_number":78,"context_line":""}],"source_content_type":"application/octet-stream","patch_set":2,"id":"fa69d971_57872cb5","line":75,"range":{"start_line":75,"start_character":5,"end_line":75,"end_character":17},"updated":"2015-12-31 07:14:10.000000000","message":"if i understand correctly, one protection Plugin instance will protect one resource for corresponding resource type, e.g.it will build one VolumeProtectionPlugin instance to protect one volume. so, i\u0027m confused why need so many tasks?","commit_id":"21c24fd9bfce5e55e9f6f1ede466c46dd2a63d06"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"9b3bbea6714a2be92a06cf7b1d02a142829aee20","unresolved":false,"context_lines":[{"line_number":72,"context_line":"Context -- Operation"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"interface ProtectionPlugin {"},{"line_number":75,"context_line":"    +get_pre_task(context: Context): TaskFlow::Atom?"},{"line_number":76,"context_line":"    +get_post_task(context: Context): TaskFlow::Atom?"},{"line_number":77,"context_line":"}"},{"line_number":78,"context_line":""}],"source_content_type":"application/octet-stream","patch_set":2,"id":"fa69d971_a802936d","line":75,"range":{"start_line":75,"start_character":5,"end_line":75,"end_character":17},"in_reply_to":"fa69d971_5514e042","updated":"2016-01-04 15:06:35.000000000","message":"This system allows the flows you describe without enforcing it. Also note that the return type is an Atom. It could be a complex task flow. We don\u0027t have to set any dependencies. We could even have all nodes return no-op and just return one task at the end by I assume we will have at least one task per VM if not more.","commit_id":"21c24fd9bfce5e55e9f6f1ede466c46dd2a63d06"},{"author":{"_account_id":13070,"name":"Eran Gampel","email":"eran@gampel.net","username":"Gampel"},"change_message_id":"8fe0e5647290457ddbd9e33af310c34b41f77593","unresolved":false,"context_lines":[{"line_number":72,"context_line":"Context -- Operation"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"interface ProtectionPlugin {"},{"line_number":75,"context_line":"    +get_pre_task(context: Context): TaskFlow::Atom?"},{"line_number":76,"context_line":"    +get_post_task(context: Context): TaskFlow::Atom?"},{"line_number":77,"context_line":"}"},{"line_number":78,"context_line":""}],"source_content_type":"application/octet-stream","patch_set":2,"id":"fa69d971_8387a20e","line":75,"range":{"start_line":75,"start_character":5,"end_line":75,"end_character":17},"in_reply_to":"fa69d971_57872cb5","updated":"2015-12-31 10:06:46.000000000","message":"I agree that most of the time Plugin will provide only one task and NOOP in the other call.\nThe idea here is to provide the plugin the flexibility to run his task before his dependencies or after them.\nIf a VM protection plugin wants to run single task after its volumes he will provide a NOOP in the get_pre and provide his task in the post this will define the order of execution of the tasks\nVOL 1 task in parallel to VOL2 TASK and then VM_TASK\nIn addition it allow one plugin to register for more then one resource and decide when to run the task. the plugin can save the context of all the calls","commit_id":"21c24fd9bfce5e55e9f6f1ede466c46dd2a63d06"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"491757788967d25c761e4c455bd77d6ea78ae71d","unresolved":false,"context_lines":[{"line_number":72,"context_line":"Context -- Operation"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"interface ProtectionPlugin {"},{"line_number":75,"context_line":"    +get_pre_task(context: Context): TaskFlow::Atom?"},{"line_number":76,"context_line":"    +get_post_task(context: Context): TaskFlow::Atom?"},{"line_number":77,"context_line":"}"},{"line_number":78,"context_line":""}],"source_content_type":"application/octet-stream","patch_set":2,"id":"fa69d971_5514e042","line":75,"range":{"start_line":75,"start_character":5,"end_line":75,"end_character":17},"in_reply_to":"fa69d971_8387a20e","updated":"2016-01-04 02:05:56.000000000","message":"IMHO, for protection, if we don\u0027t consider consistency, all resources protection task could be executed on the parallel.\n\nHowever, for composite resource, like VM,  if it has FS level consistency requirement, it will first freeze IO of VM, flush buffer of devices then build backup/snapshot of volumes. In this case, it seems that the composite VM plugin should build all of these logic into one task, which could be executed and rolled back atomically. It seems no need to build several separate tasks, since they will be rolled back one by one on failure, where volumes\u0026VMs are in inconsistent status.\n\nFor restore, yes, there are dependencies in tasks, like restore volumes and VMs first, then do attach work.","commit_id":"21c24fd9bfce5e55e9f6f1ede466c46dd2a63d06"}],"doc/source/api/pluggable_protection_provider.rst":[{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"428193647f2e532bb0516b85fbaef072da30efdb","unresolved":false,"context_lines":[{"line_number":7,"context_line":"from scratch."},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The protection provider will contain internally a map between any registered"},{"line_number":10,"context_line":"*Protectable* and a corrosponding *Protection Plugin*. When the pluggable"},{"line_number":11,"context_line":"protection provider is asked to perform an action, it will walk over the"},{"line_number":12,"context_line":"graph and pass a context object to the appropriate plugin whenever a node is"},{"line_number":13,"context_line":"encountered."}],"source_content_type":"text/x-rst","patch_set":2,"id":"fa69d971_77827002","line":10,"updated":"2015-12-31 06:49:51.000000000","message":"the map between protectable and plugin will be a one:one map or a one:multiple map? \nA map is not a fully connected graph, but several trees, how comes walk over the graph?","commit_id":"21c24fd9bfce5e55e9f6f1ede466c46dd2a63d06"},{"author":{"_account_id":13070,"name":"Eran Gampel","email":"eran@gampel.net","username":"Gampel"},"change_message_id":"8fe0e5647290457ddbd9e33af310c34b41f77593","unresolved":false,"context_lines":[{"line_number":7,"context_line":"from scratch."},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The protection provider will contain internally a map between any registered"},{"line_number":10,"context_line":"*Protectable* and a corrosponding *Protection Plugin*. When the pluggable"},{"line_number":11,"context_line":"protection provider is asked to perform an action, it will walk over the"},{"line_number":12,"context_line":"graph and pass a context object to the appropriate plugin whenever a node is"},{"line_number":13,"context_line":"encountered."}],"source_content_type":"text/x-rst","patch_set":2,"id":"fa69d971_23d27601","line":10,"in_reply_to":"fa69d971_77827002","updated":"2015-12-31 10:06:46.000000000","message":"I am not sure i understand, please see my response to zhonghua, it is up to the plugin one plugin can be registered as the protection plugin for two resources type","commit_id":"21c24fd9bfce5e55e9f6f1ede466c46dd2a63d06"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"428193647f2e532bb0516b85fbaef072da30efdb","unresolved":false,"context_lines":[{"line_number":12,"context_line":"graph and pass a context object to the appropriate plugin whenever a node is"},{"line_number":13,"context_line":"encountered."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"The resource graph is traversed in with DFS. When a node is first encountered"},{"line_number":16,"context_line":"the protection manager gets the plugin for the appropriate resource type, builds"},{"line_number":17,"context_line":"a context and passes it to the plugins `get_pre_task()` method. The plugin can"},{"line_number":18,"context_line":"return any tasks that it wants added to the task list. When all of a node"}],"source_content_type":"text/x-rst","patch_set":2,"id":"fa69d971_f7c42041","line":15,"updated":"2015-12-31 06:49:51.000000000","message":"How to build the resource graph? Or it\u0027s just the list of resources?","commit_id":"21c24fd9bfce5e55e9f6f1ede466c46dd2a63d06"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"65f24e023fff113556307eb3e9f2a85a323fec29","unresolved":false,"context_lines":[{"line_number":12,"context_line":"graph and pass a context object to the appropriate plugin whenever a node is"},{"line_number":13,"context_line":"encountered."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"The resource graph is traversed in with DFS. When a node is first encountered"},{"line_number":16,"context_line":"the protection manager gets the plugin for the appropriate resource type, builds"},{"line_number":17,"context_line":"a context and passes it to the plugins `get_pre_task()` method. The plugin can"},{"line_number":18,"context_line":"return any tasks that it wants added to the task list. When all of a node"}],"source_content_type":"text/x-rst","patch_set":2,"id":"fa69d971_d5a1b0aa","line":15,"in_reply_to":"fa69d971_039172f0","updated":"2016-01-04 02:41:08.000000000","message":"Yes, it answered my question.\nAnother question is will there be overlap in the built resource tree?  Follow your example, for one un-attached volume, user used to choose to protect it as well(may be only once). So this volume will be a sibling of the VM node. When user choose to attach this volume to one VM, if the VM is protected, the volume should be moved to be child of the VM node.\nIt seems that we need expose more operations of the resource tree.\n\nFollow this example, if the volume protection policy is different with its attached VM (volume used to be once as it un-attached) but VM is every week, what policy should the two follow?\nIt seems that we need policy conflict check and mechanism to solve it before move/add node to the resource tree.  It seems to me that we could take this check as a similar mechanism of \u0027automatic_discovery\u0027, where the policy on volume is none.","commit_id":"21c24fd9bfce5e55e9f6f1ede466c46dd2a63d06"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"9b3bbea6714a2be92a06cf7b1d02a142829aee20","unresolved":false,"context_lines":[{"line_number":12,"context_line":"graph and pass a context object to the appropriate plugin whenever a node is"},{"line_number":13,"context_line":"encountered."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"The resource graph is traversed in with DFS. When a node is first encountered"},{"line_number":16,"context_line":"the protection manager gets the plugin for the appropriate resource type, builds"},{"line_number":17,"context_line":"a context and passes it to the plugins `get_pre_task()` method. The plugin can"},{"line_number":18,"context_line":"return any tasks that it wants added to the task list. When all of a node"}],"source_content_type":"text/x-rst","patch_set":2,"id":"fa69d971_e9040ac1","line":15,"in_reply_to":"fa69d971_d5a1b0aa","updated":"2016-01-04 15:06:35.000000000","message":"You are mixing two different topics here. Triggering and options. Since Smaug looks at a point in time for an entire \"solution\" the user will need to define a different policy for every group that requires a different point it time.\n\nAs for different options for different use cases.\nOptions can be passes as \"\u003ctype\u003e\" and \"\u003ctype\u003e@\u003cinstance id\u003e\" the former being how you declare defaults and the latter how you define specific options for a resource to override the defaults. There is no way to specify defaults for children of. This is done to keep the model simple.","commit_id":"21c24fd9bfce5e55e9f6f1ede466c46dd2a63d06"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"99c0037c6c7228410a379f731686e196e28dd879","unresolved":false,"context_lines":[{"line_number":12,"context_line":"graph and pass a context object to the appropriate plugin whenever a node is"},{"line_number":13,"context_line":"encountered."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"The resource graph is traversed in with DFS. When a node is first encountered"},{"line_number":16,"context_line":"the protection manager gets the plugin for the appropriate resource type, builds"},{"line_number":17,"context_line":"a context and passes it to the plugins `get_pre_task()` method. The plugin can"},{"line_number":18,"context_line":"return any tasks that it wants added to the task list. When all of a node"}],"source_content_type":"text/x-rst","patch_set":2,"id":"fa69d971_0f72a57b","line":15,"in_reply_to":"fa69d971_e9040ac1","updated":"2016-01-05 01:16:57.000000000","message":"I\u0027m not sure if I get your points. Let\u0027s talk about it in IRC: how to construct/update the resource tree; how to check policy conflict between resource parent node and child node.","commit_id":"21c24fd9bfce5e55e9f6f1ede466c46dd2a63d06"},{"author":{"_account_id":13070,"name":"Eran Gampel","email":"eran@gampel.net","username":"Gampel"},"change_message_id":"8fe0e5647290457ddbd9e33af310c34b41f77593","unresolved":false,"context_lines":[{"line_number":12,"context_line":"graph and pass a context object to the appropriate plugin whenever a node is"},{"line_number":13,"context_line":"encountered."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"The resource graph is traversed in with DFS. When a node is first encountered"},{"line_number":16,"context_line":"the protection manager gets the plugin for the appropriate resource type, builds"},{"line_number":17,"context_line":"a context and passes it to the plugins `get_pre_task()` method. The plugin can"},{"line_number":18,"context_line":"return any tasks that it wants added to the task list. When all of a node"}],"source_content_type":"text/x-rst","patch_set":2,"id":"fa69d971_039172f0","line":15,"in_reply_to":"fa69d971_f7c42041","updated":"2015-12-31 10:06:46.000000000","message":"We build it using the Protectable API they will provide us the current updated resource Tree given a tree root.\nThis way we itinerantly supporting automatic object discovery\n\nFor example A user selected to protect a VM and its attached VOL and defined a Automatic operation to protect this resources every Week.\nLets say the user added a new VOL to that VM it will automatically be backup as well because we will build the tree do backup in the time of the operation.\n\nWe are introducing two built in parameters to a resource \ndisable_automatic_discovery that by default be false\nskip_resource that by default be false\n\nPlease let me know if I answered your question","commit_id":"21c24fd9bfce5e55e9f6f1ede466c46dd2a63d06"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"428193647f2e532bb0516b85fbaef072da30efdb","unresolved":false,"context_lines":[{"line_number":19,"context_line":"childrens have been visited the `get_pre_task()` is called. The task returned"},{"line_number":20,"context_line":"from this method will also be added to the task list but is also guranteed to"},{"line_number":21,"context_line":"execute after all the child node\u0027s tasks have finished. Any of the methods can"},{"line_number":22,"context_line":"return `None` if they don\u0027t want any action performed."},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"After the entire grap has been traversed the Protection Provider will return"},{"line_number":25,"context_line":"the task lists which will be queued and than executed according to the"}],"source_content_type":"text/x-rst","patch_set":2,"id":"fa69d971_f7f2e099","line":22,"updated":"2015-12-31 06:49:51.000000000","message":"So the intention here is to build a linear graph of tasks? \nIMHO, most resources are independent. Independent tasks should run on parallel for efficiency, while composite resource will build its own linear task flow.  How about building a graph flow?","commit_id":"21c24fd9bfce5e55e9f6f1ede466c46dd2a63d06"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"65f24e023fff113556307eb3e9f2a85a323fec29","unresolved":false,"context_lines":[{"line_number":19,"context_line":"childrens have been visited the `get_pre_task()` is called. The task returned"},{"line_number":20,"context_line":"from this method will also be added to the task list but is also guranteed to"},{"line_number":21,"context_line":"execute after all the child node\u0027s tasks have finished. Any of the methods can"},{"line_number":22,"context_line":"return `None` if they don\u0027t want any action performed."},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"After the entire grap has been traversed the Protection Provider will return"},{"line_number":25,"context_line":"the task lists which will be queued and than executed according to the"}],"source_content_type":"text/x-rst","patch_set":2,"id":"fa69d971_35c04c2a","line":22,"in_reply_to":"fa69d971_ee03e5b6","updated":"2016-01-04 02:41:08.000000000","message":"OK. Got it.","commit_id":"21c24fd9bfce5e55e9f6f1ede466c46dd2a63d06"},{"author":{"_account_id":13070,"name":"Eran Gampel","email":"eran@gampel.net","username":"Gampel"},"change_message_id":"8fe0e5647290457ddbd9e33af310c34b41f77593","unresolved":false,"context_lines":[{"line_number":19,"context_line":"childrens have been visited the `get_pre_task()` is called. The task returned"},{"line_number":20,"context_line":"from this method will also be added to the task list but is also guranteed to"},{"line_number":21,"context_line":"execute after all the child node\u0027s tasks have finished. Any of the methods can"},{"line_number":22,"context_line":"return `None` if they don\u0027t want any action performed."},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"After the entire grap has been traversed the Protection Provider will return"},{"line_number":25,"context_line":"the task lists which will be queued and than executed according to the"}],"source_content_type":"text/x-rst","patch_set":2,"id":"fa69d971_ee03e5b6","line":22,"in_reply_to":"fa69d971_f7f2e099","updated":"2015-12-31 10:06:46.000000000","message":"No it is not a linear graph of tasks.\n\nBasically if a Plugin return the task in the pre that task could be run in parallel to all of his dependencies .\n\nIf a plugin return a post task it will be run after his dependencies tasks.\n\nThe plugin can return NOOP task in the pre or post","commit_id":"21c24fd9bfce5e55e9f6f1ede466c46dd2a63d06"}],"doc/source/specs/available_protectables.pu":[{"author":{"_account_id":13070,"name":"Eran Gampel","email":"eran@gampel.net","username":"Gampel"},"change_message_id":"6aea04306ce8813b924228a320d272a3ec4906a9","unresolved":false,"context_lines":[{"line_number":23,"context_line":""},{"line_number":24,"context_line":"class OS::Manila::Share extends OS::Keystone::Project"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"class OS::Neutron::SecurityGroup extends OS::Nova::Server"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"@enduml"}],"source_content_type":"application/octet-stream","patch_set":5,"id":"da6ed579_b25ee674","line":26,"range":{"start_line":26,"start_character":19,"end_line":26,"end_character":32},"updated":"2016-01-11 23:42:51.000000000","message":"I am not sure we need :SecurityGroup to be separated from the  Neutron:Topology because then you logically need to split neutron into its elements Port Network Router and they are all dependent one on each other.\n\nSecurityGroup is dependents on a Port, \n\nwe might need to Support\n OS::Nova::Network/Topology but this can be supported in V2","commit_id":"ba411f11a22eb79f9b4c0e0c3bbcd3ba9bc6f2bb"}],"doc/source/specs/pluggable_protection_provider.pu":[{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"4c97302d3c42eb4f549ca283546b57bb5bbad1d4","unresolved":false,"context_lines":[{"line_number":63,"context_line":"}"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"class Context {"},{"line_number":66,"context_line":"    +plan: ProtectionPlan"},{"line_number":67,"context_line":"    +operation: Operation"},{"line_number":68,"context_line":"    +parameters: dict"},{"line_number":69,"context_line":"    +resource: ResourceGraphNode"}],"source_content_type":"application/octet-stream","patch_set":3,"id":"fa69d971_d1ce682d","line":66,"range":{"start_line":66,"start_character":11,"end_line":66,"end_character":25},"updated":"2016-01-05 09:24:00.000000000","message":"I don\u0027t think we need entire ProtectionPlan here.\nJust including the member needed would be enough.","commit_id":"b86cf3562c021788954bbc2c5755edbd7a8f957f"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"4c97302d3c42eb4f549ca283546b57bb5bbad1d4","unresolved":false,"context_lines":[{"line_number":66,"context_line":"    +plan: ProtectionPlan"},{"line_number":67,"context_line":"    +operation: Operation"},{"line_number":68,"context_line":"    +parameters: dict"},{"line_number":69,"context_line":"    +resource: ResourceGraphNode"},{"line_number":70,"context_line":"    +account: MetadataStore"},{"line_number":71,"context_line":"    +is_first_visit: boolean"},{"line_number":72,"context_line":"}"}],"source_content_type":"application/octet-stream","patch_set":3,"id":"fa69d971_71421c6a","line":69,"range":{"start_line":69,"start_character":15,"end_line":69,"end_character":32},"updated":"2016-01-05 09:24:00.000000000","message":"Why the type is ResourceGraphNode, instead of Resource?","commit_id":"b86cf3562c021788954bbc2c5755edbd7a8f957f"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"0592c0cba68ef1b08792fc1511ae937610a4312d","unresolved":false,"context_lines":[{"line_number":28,"context_line":""},{"line_number":29,"context_line":"interface ResourceGraphWalkerListener {"},{"line_number":30,"context_line":"    on_node_enter(node: ResourceGraphNode, is_first_visit: boolean)"},{"line_number":31,"context_line":"    on_node_exit(node: ResourceGraphNode, is_first_visit: boolean)"},{"line_number":32,"context_line":"}"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"ResourceGraphNode *- Resource"}],"source_content_type":"application/octet-stream","patch_set":4,"id":"fa69d971_6e41d962","line":31,"updated":"2016-01-11 02:26:52.000000000","message":"Is this pair of functions going to be called during ResourceGraphWalker.walk()?  It would be better if there\u0027s a sequence graph provided in rst to show how the resource graph will be walked and what output we get through the walking.","commit_id":"2d8f9b1b26f0f22de36940d5bb34cbc8db6a642f"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"0592c0cba68ef1b08792fc1511ae937610a4312d","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    + {static} list_resources(resource_type: ResourceType): [] Resource"},{"line_number":40,"context_line":"}"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"ProtectableRegistry -- Resource: \u003c\u003ccreates\u003e\u003e"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"ProtectableRegistry \"1\" *- \"*\" Protectable"},{"line_number":45,"context_line":""}],"source_content_type":"application/octet-stream","patch_set":4,"id":"fa69d971_d188a873","line":42,"updated":"2016-01-11 02:26:52.000000000","message":"who creates who?\n\nI think we need a sequence graph to show how the resource graph is built among classes ProtectableRegistry, Protectable, Resource, ResourceGraphNode.\nOtherwise, it\u0027s hard to guess the cooperation of those classes.","commit_id":"2d8f9b1b26f0f22de36940d5bb34cbc8db6a642f"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"0592c0cba68ef1b08792fc1511ae937610a4312d","unresolved":false,"context_lines":[{"line_number":44,"context_line":"ProtectableRegistry \"1\" *- \"*\" Protectable"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"interface Protectable {"},{"line_number":47,"context_line":"    + possible_parent_types(resource_type: ResourceType): []ResourceType"},{"line_number":48,"context_line":"    + fetch_child_resources(resource: Resource): []Resource"},{"line_number":49,"context_line":"    + list_resources(resource_type: ResourceType): []Resource"},{"line_number":50,"context_line":"}"}],"source_content_type":"application/octet-stream","patch_set":4,"id":"fa69d971_5167d8e8","line":47,"updated":"2016-01-11 02:26:52.000000000","message":"what\u0027s the usage of this interface? or what\u0027s the possible_parent_types?  It looks to me that the parent of each resource is definite.","commit_id":"2d8f9b1b26f0f22de36940d5bb34cbc8db6a642f"},{"author":{"_account_id":13070,"name":"Eran Gampel","email":"eran@gampel.net","username":"Gampel"},"change_message_id":"f7b3f45495cab61faf7170d1f80a42466ebc0173","unresolved":false,"context_lines":[{"line_number":57,"context_line":""},{"line_number":58,"context_line":"enum Operation {"},{"line_number":59,"context_line":"    protect"},{"line_number":60,"context_line":"    enable"},{"line_number":61,"context_line":"    disable"},{"line_number":62,"context_line":"    restore"},{"line_number":63,"context_line":"}"}],"source_content_type":"application/octet-stream","patch_set":4,"id":"fa69d971_f03458fc","line":60,"range":{"start_line":60,"start_character":4,"end_line":60,"end_character":10},"updated":"2016-01-07 11:09:55.000000000","message":"In the API we called that the Suspend and Start I think that we should use the same terminology","commit_id":"2d8f9b1b26f0f22de36940d5bb34cbc8db6a642f"},{"author":{"_account_id":13070,"name":"Eran Gampel","email":"eran@gampel.net","username":"Gampel"},"change_message_id":"f7b3f45495cab61faf7170d1f80a42466ebc0173","unresolved":false,"context_lines":[{"line_number":58,"context_line":"enum Operation {"},{"line_number":59,"context_line":"    protect"},{"line_number":60,"context_line":"    enable"},{"line_number":61,"context_line":"    disable"},{"line_number":62,"context_line":"    restore"},{"line_number":63,"context_line":"}"},{"line_number":64,"context_line":""}],"source_content_type":"application/octet-stream","patch_set":4,"id":"fa69d971_53676eea","line":61,"range":{"start_line":61,"start_character":4,"end_line":61,"end_character":11},"updated":"2016-01-07 11:09:55.000000000","message":"same","commit_id":"2d8f9b1b26f0f22de36940d5bb34cbc8db6a642f"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"0592c0cba68ef1b08792fc1511ae937610a4312d","unresolved":false,"context_lines":[{"line_number":74,"context_line":"Context -- Operation"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"interface ProtectionPlugin {"},{"line_number":77,"context_line":"    +get_pre_task(context: Context): TaskFlow::Atom?"},{"line_number":78,"context_line":"    +get_post_task(context: Context): TaskFlow::Atom?"},{"line_number":79,"context_line":"}"},{"line_number":80,"context_line":""}],"source_content_type":"application/octet-stream","patch_set":4,"id":"fa69d971_0e013d06","line":77,"updated":"2016-01-11 02:26:52.000000000","message":"If we use pre/post task, it\u0027s only capable to compose two levels of dependency.  I suggest we just give an interface get_sub_flow(context:Context):taskflow.flow.Flow, which will return the whole sub flow of this plugin.  It could compose its own dependency of tasks, which the provider doesn\u0027t care but retrieve them back.","commit_id":"2d8f9b1b26f0f22de36940d5bb34cbc8db6a642f"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"851a7795c17527d85c2f0f54c129fc868ecc72f3","unresolved":false,"context_lines":[{"line_number":75,"context_line":""},{"line_number":76,"context_line":"interface ProtectionPlugin {"},{"line_number":77,"context_line":"    +get_pre_task(context: Context): TaskFlow::Atom?"},{"line_number":78,"context_line":"    +get_post_task(context: Context): TaskFlow::Atom?"},{"line_number":79,"context_line":"}"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"ProtectionPlugin -- Context"}],"source_content_type":"application/octet-stream","patch_set":4,"id":"fa69d971_221ce968","line":78,"updated":"2016-01-07 08:47:48.000000000","message":"I think here should add two more interfaces:\nrun_task(task: TaskFlow) for running the task\nget_task_status(task: TaskFlow) for querying the task running status","commit_id":"2d8f9b1b26f0f22de36940d5bb34cbc8db6a642f"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"0592c0cba68ef1b08792fc1511ae937610a4312d","unresolved":false,"context_lines":[{"line_number":75,"context_line":""},{"line_number":76,"context_line":"interface ProtectionPlugin {"},{"line_number":77,"context_line":"    +get_pre_task(context: Context): TaskFlow::Atom?"},{"line_number":78,"context_line":"    +get_post_task(context: Context): TaskFlow::Atom?"},{"line_number":79,"context_line":"}"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"ProtectionPlugin -- Context"}],"source_content_type":"application/octet-stream","patch_set":4,"id":"fa69d971_2e2761cb","line":78,"in_reply_to":"fa69d971_221ce968","updated":"2016-01-11 02:26:52.000000000","message":"It\u0027s not the responsibility of this component to compose the whole task flow or execute the task. This component will only walk through the whole resource graph and generate sub task flow of each resources.  \nProtectionServiceManager will compose the whole task flow and run the engine.  \nTask/flow status will get reported by using Listeners or callbacks of flow/task status.","commit_id":"2d8f9b1b26f0f22de36940d5bb34cbc8db6a642f"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"2b4634d51f1275fdc4a75ccbe9645d0503068d7c","unresolved":false,"context_lines":[{"line_number":75,"context_line":""},{"line_number":76,"context_line":"interface ProtectionPlugin {"},{"line_number":77,"context_line":"    +get_pre_task(context: Context): TaskFlow::Atom?"},{"line_number":78,"context_line":"    +get_post_task(context: Context): TaskFlow::Atom?"},{"line_number":79,"context_line":"}"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"ProtectionPlugin -- Context"}],"source_content_type":"application/octet-stream","patch_set":4,"id":"fa69d971_627ae1be","line":78,"in_reply_to":"fa69d971_221ce968","updated":"2016-01-07 09:07:51.000000000","message":"Task class having a common public interface for execution is a good idea, as yinwei\u0027s design, execute() in Task.\nSo ignore this comment.","commit_id":"2d8f9b1b26f0f22de36940d5bb34cbc8db6a642f"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"0592c0cba68ef1b08792fc1511ae937610a4312d","unresolved":false,"context_lines":[{"line_number":75,"context_line":""},{"line_number":76,"context_line":"interface ProtectionPlugin {"},{"line_number":77,"context_line":"    +get_pre_task(context: Context): TaskFlow::Atom?"},{"line_number":78,"context_line":"    +get_post_task(context: Context): TaskFlow::Atom?"},{"line_number":79,"context_line":"}"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"ProtectionPlugin -- Context"}],"source_content_type":"application/octet-stream","patch_set":4,"id":"fa69d971_6e0f9939","line":78,"in_reply_to":"fa69d971_627ae1be","updated":"2016-01-11 02:26:52.000000000","message":"Actually, all concrete classes inherited from atom have to implement execute() and revert() functions. So it\u0027s not my design :)","commit_id":"2d8f9b1b26f0f22de36940d5bb34cbc8db6a642f"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"851a7795c17527d85c2f0f54c129fc868ecc72f3","unresolved":false,"context_lines":[{"line_number":81,"context_line":"ProtectionPlugin -- Context"},{"line_number":82,"context_line":"ProtectionPlugin -- TaskFlow::Atom"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"interface ProtectionProvider {"},{"line_number":85,"context_line":"    create_checkpoint(root_resource: ResourceGraphNode): Checkpoint"},{"line_number":86,"context_line":"    delete_checkpoint(checkpoint_id: UUID)"},{"line_number":87,"context_line":"}"}],"source_content_type":"application/octet-stream","patch_set":4,"id":"fa69d971_c76e3fff","line":84,"updated":"2016-01-07 08:47:48.000000000","message":"If protection provider\u0027s purpose is to be fully pluggable and extendable, I think just these two interface here aren\u0027t enough.\nHere should also be:\nlist_checkpoint()\nget_checkpoint(checkpoint_id: UUID)\nbuild_task_list(root_resource: ResourceGraphNode, \n                context: Context)","commit_id":"2d8f9b1b26f0f22de36940d5bb34cbc8db6a642f"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"749b27821da5e3c23acf6f2b648bf78c1253740e","unresolved":false,"context_lines":[{"line_number":21,"context_line":"class ResourceGraphWalker {"},{"line_number":22,"context_line":"    +constructor(root: ResourceGraphNode)"},{"line_number":23,"context_line":"    +add_listener(listener: ResourceGraphWalkerListener)"},{"line_number":24,"context_line":"    +walk()"},{"line_number":25,"context_line":"}"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"ResourceGraphWalker -- ResourceGraphWalkerListener"}],"source_content_type":"application/octet-stream","patch_set":6,"id":"da6ed579_56aeec81","line":24,"updated":"2016-01-14 07:44:36.000000000","message":"Need a context param to bring back the result?","commit_id":"c4a908a057e3ffcf242434de7637105d41501a6a"},{"author":{"_account_id":13070,"name":"Eran Gampel","email":"eran@gampel.net","username":"Gampel"},"change_message_id":"0258988d0ece8cebae91d4275476e2c87fb055e2","unresolved":false,"context_lines":[{"line_number":76,"context_line":""},{"line_number":77,"context_line":"interface ProtectionPlugin {"},{"line_number":78,"context_line":"    +get_pre_task(context: Context): TaskFlow::Atom?"},{"line_number":79,"context_line":"    +get_post_task(context: Context): TaskFlow::Atom?"},{"line_number":80,"context_line":"}"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"ProtectionPlugin -- Context"}],"source_content_type":"application/octet-stream","patch_set":6,"id":"da6ed579_1ad544b8","line":79,"range":{"start_line":79,"start_character":5,"end_line":79,"end_character":18},"updated":"2016-01-13 02:21:11.000000000","message":"we are missing the get option schema  and get ext-info schema","commit_id":"c4a908a057e3ffcf242434de7637105d41501a6a"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"749b27821da5e3c23acf6f2b648bf78c1253740e","unresolved":false,"context_lines":[{"line_number":87,"context_line":""},{"line_number":88,"context_line":"class PluggableProtectionProvider extends ProtectionProvider {"},{"line_number":89,"context_line":"    -plugins: [ResourceType]ProtectionPlugin"},{"line_number":90,"context_line":"}"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"PluggableProtectionProvider *-- \"1..*\" ProtectionPlugin: Uses for functionality"},{"line_number":93,"context_line":"PluggableProtectionProvider -\u003e ResourceGraphWalker: uses it to iterate over graph"}],"source_content_type":"application/octet-stream","patch_set":6,"id":"da6ed579_96bc64dd","line":90,"updated":"2016-01-14 07:44:36.000000000","message":"Need an interface like build_graph_flow to trigger graph walking and flow building?","commit_id":"c4a908a057e3ffcf242434de7637105d41501a6a"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"749b27821da5e3c23acf6f2b648bf78c1253740e","unresolved":false,"context_lines":[{"line_number":88,"context_line":"class PluggableProtectionProvider extends ProtectionProvider {"},{"line_number":89,"context_line":"    -plugins: [ResourceType]ProtectionPlugin"},{"line_number":90,"context_line":"}"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":"PluggableProtectionProvider *-- \"1..*\" ProtectionPlugin: Uses for functionality"},{"line_number":93,"context_line":"PluggableProtectionProvider -\u003e ResourceGraphWalker: uses it to iterate over graph"},{"line_number":94,"context_line":"ResourceGraphWalker - ResourceGraphNode"}],"source_content_type":"application/octet-stream","patch_set":6,"id":"da6ed579_d6741c37","line":91,"updated":"2016-01-14 07:44:36.000000000","message":"Need another interface to get the graph flow built from walking resource graph?","commit_id":"c4a908a057e3ffcf242434de7637105d41501a6a"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"7c31e01233e468d92250f5e6c480afcd4c992227","unresolved":false,"context_lines":[{"line_number":27,"context_line":"ResourceGraphWalker -- ResourceGraphWalkerListener"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"interface ResourceGraphWalkerListener {"},{"line_number":30,"context_line":"    on_node_enter(node: ResourceGraphNode, is_first_visit: boolean)"},{"line_number":31,"context_line":"    on_node_exit(node: ResourceGraphNode, is_first_visit: boolean)"},{"line_number":32,"context_line":"}"},{"line_number":33,"context_line":""}],"source_content_type":"application/octet-stream","patch_set":7,"id":"ba63e191_21112fad","line":30,"updated":"2016-01-19 02:46:58.000000000","message":"I think context should be passed as a parameter, cause the plugin\u0027s get_(pre/post)_task would be called by this, is that right?","commit_id":"7b3b2ee191b2b31f74c227999d38448883d2c115"},{"author":{"_account_id":13070,"name":"Eran Gampel","email":"eran@gampel.net","username":"Gampel"},"change_message_id":"486bb8ce2f8196f83579c6857ecbc1fafde0d930","unresolved":false,"context_lines":[{"line_number":68,"context_line":"    +operation: Operation"},{"line_number":69,"context_line":"    +parameters: dict"},{"line_number":70,"context_line":"    +resource: ResourceGraphNode"},{"line_number":71,"context_line":"    +account: MetadataStore"},{"line_number":72,"context_line":"    +is_first_visit: boolean"},{"line_number":73,"context_line":"}"},{"line_number":74,"context_line":""}],"source_content_type":"application/octet-stream","patch_set":7,"id":"da6ed579_de28739c","line":71,"range":{"start_line":71,"start_character":14,"end_line":71,"end_character":27},"updated":"2016-01-15 06:39:13.000000000","message":"If I understand correctly this is account info to log into the bank.\n\nI think that we should provide higher level abstraction and provide an object that provide read and write (bank )\nIn protect the plugin will be able to read and write and we automatically chroot  it into the plugin namespace under the checkpoint.\n\nIn Restore he will be able to only  read \nSo in \nProtect: Read \u0026 Write \nRestore: Read only \nStart:   Read \nSuspend: read","commit_id":"7b3b2ee191b2b31f74c227999d38448883d2c115"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"7c31e01233e468d92250f5e6c480afcd4c992227","unresolved":false,"context_lines":[{"line_number":68,"context_line":"    +operation: Operation"},{"line_number":69,"context_line":"    +parameters: dict"},{"line_number":70,"context_line":"    +resource: ResourceGraphNode"},{"line_number":71,"context_line":"    +account: MetadataStore"},{"line_number":72,"context_line":"    +is_first_visit: boolean"},{"line_number":73,"context_line":"}"},{"line_number":74,"context_line":""}],"source_content_type":"application/octet-stream","patch_set":7,"id":"ba63e191_e1923757","line":71,"range":{"start_line":71,"start_character":14,"end_line":71,"end_character":27},"in_reply_to":"ba63e191_d4b33209","updated":"2016-01-19 02:46:58.000000000","message":"I don\u0027t think this\u0027s what Eran meant.\nWhat he said should be that protect operation would R/W bank, and other operations only need to read bank.\nBut I don\u0027t understand how we could automatically chroot, unless the plugin explicitly tell changing to where under the checkpoint.","commit_id":"7b3b2ee191b2b31f74c227999d38448883d2c115"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"31d36ec6a28c0606e5717b3d279293429f173a38","unresolved":false,"context_lines":[{"line_number":68,"context_line":"    +operation: Operation"},{"line_number":69,"context_line":"    +parameters: dict"},{"line_number":70,"context_line":"    +resource: ResourceGraphNode"},{"line_number":71,"context_line":"    +account: MetadataStore"},{"line_number":72,"context_line":"    +is_first_visit: boolean"},{"line_number":73,"context_line":"}"},{"line_number":74,"context_line":""}],"source_content_type":"application/octet-stream","patch_set":7,"id":"ba63e191_9a770e02","line":71,"range":{"start_line":71,"start_character":14,"end_line":71,"end_character":27},"in_reply_to":"ba63e191_e1923757","updated":"2016-01-19 11:27:41.000000000","message":"Let\u0027s take swift as an example, AFAK in swift you can configure the access control of one object to different users. Back to Smaug, where bankplugin is actually the client of the swift, what else way do you think we can switch access control to swift?","commit_id":"7b3b2ee191b2b31f74c227999d38448883d2c115"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"bd7aa82be8989fd105c650bec0845fd29b048e38","unresolved":false,"context_lines":[{"line_number":68,"context_line":"    +operation: Operation"},{"line_number":69,"context_line":"    +parameters: dict"},{"line_number":70,"context_line":"    +resource: ResourceGraphNode"},{"line_number":71,"context_line":"    +account: MetadataStore"},{"line_number":72,"context_line":"    +is_first_visit: boolean"},{"line_number":73,"context_line":"}"},{"line_number":74,"context_line":""}],"source_content_type":"application/octet-stream","patch_set":7,"id":"ba63e191_d4b33209","line":71,"range":{"start_line":71,"start_character":14,"end_line":71,"end_character":27},"in_reply_to":"da6ed579_de28739c","updated":"2016-01-19 01:30:38.000000000","message":"do you mean in Smaug we have several accounts in one bank plugin?  say, one account with owner access and the other with read only access?","commit_id":"7b3b2ee191b2b31f74c227999d38448883d2c115"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"7c31e01233e468d92250f5e6c480afcd4c992227","unresolved":false,"context_lines":[{"line_number":82,"context_line":"    +get_options_schema(resource_type: ResourceType)"},{"line_number":83,"context_line":"    +get_extendend_info_schema(resource_type: ResourceType)"},{"line_number":84,"context_line":"    +get_restore_schema(resource_type: ResourceType)"},{"line_number":85,"context_line":"    +get_extended_info(resource: Resource)"},{"line_number":86,"context_line":"}"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"ProtectionPlugin -- Context"}],"source_content_type":"application/octet-stream","patch_set":7,"id":"ba63e191_21f84fe5","line":85,"range":{"start_line":85,"start_character":5,"end_line":85,"end_character":22},"updated":"2016-01-19 02:46:58.000000000","message":"I don\u0027t see why we need this get_extended_info.","commit_id":"7b3b2ee191b2b31f74c227999d38448883d2c115"},{"author":{"_account_id":13070,"name":"Eran Gampel","email":"eran@gampel.net","username":"Gampel"},"change_message_id":"d52414cfd5096f20a39a8e53c5fd20ac1abc0e01","unresolved":false,"context_lines":[{"line_number":64,"context_line":"    +operation: Operation"},{"line_number":65,"context_line":"    +parameters: dict"},{"line_number":66,"context_line":"    +resource: ResourceGraphNode"},{"line_number":67,"context_line":"    +account: MetadataStore"},{"line_number":68,"context_line":"    +is_first_visit: boolean"},{"line_number":69,"context_line":"    +task_builder: TaskBuilder"},{"line_number":70,"context_line":"}"}],"source_content_type":"application/octet-stream","patch_set":9,"id":"7a5de9d1_71026a0d","line":67,"range":{"start_line":67,"start_character":5,"end_line":67,"end_character":27},"updated":"2016-01-28 12:10:58.000000000","message":"I am not sure this is the best name for this object Maybe BankObject or Bank  \n\nwe need a Interface dentition\n\nWrite(key,value)\nRead (key)\n\n..","commit_id":"8e35a5b6117c101cceb03bf2dc8c3f612567d65e"},{"author":{"_account_id":13070,"name":"Eran Gampel","email":"eran@gampel.net","username":"Gampel"},"change_message_id":"d52414cfd5096f20a39a8e53c5fd20ac1abc0e01","unresolved":false,"context_lines":[{"line_number":88,"context_line":""},{"line_number":89,"context_line":"Context -- Operation"},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"interface ProtectionPlugin {"},{"line_number":92,"context_line":"    ..graph walk functions.."},{"line_number":93,"context_line":"    +on_resource_start(context: Context)"},{"line_number":94,"context_line":"    +on_resource_end(context: Context)"}],"source_content_type":"application/octet-stream","patch_set":9,"id":"7a5de9d1_7416d8f2","line":91,"range":{"start_line":91,"start_character":10,"end_line":91,"end_character":26},"updated":"2016-01-28 12:10:58.000000000","message":"are we missing an interface to get which resource this plugin protect","commit_id":"8e35a5b6117c101cceb03bf2dc8c3f612567d65e"},{"author":{"_account_id":13070,"name":"Eran Gampel","email":"eran@gampel.net","username":"Gampel"},"change_message_id":"d52414cfd5096f20a39a8e53c5fd20ac1abc0e01","unresolved":false,"context_lines":[{"line_number":94,"context_line":"    +on_resource_end(context: Context)"},{"line_number":95,"context_line":"    ..schema functions.."},{"line_number":96,"context_line":"    +get_options_schema(resource_type: ResourceType)"},{"line_number":97,"context_line":"    +get_extendend_info_schema(resource_type: ResourceType)"},{"line_number":98,"context_line":"    +get_restore_schema(resource_type: ResourceType)"},{"line_number":99,"context_line":"    +get_extended_info(resource: Resource)"},{"line_number":100,"context_line":"}"}],"source_content_type":"application/octet-stream","patch_set":9,"id":"7a5de9d1_d4ca2ca1","line":97,"range":{"start_line":97,"start_character":5,"end_line":97,"end_character":31},"updated":"2016-01-28 12:10:58.000000000","message":"I think get result schema will be clearer","commit_id":"8e35a5b6117c101cceb03bf2dc8c3f612567d65e"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"82dd412ac4fb3d59365590891431af35ea49ceb3","unresolved":false,"context_lines":[{"line_number":96,"context_line":"    +get_options_schema(resource_type: ResourceType)"},{"line_number":97,"context_line":"    +get_extendend_info_schema(resource_type: ResourceType)"},{"line_number":98,"context_line":"    +get_restore_schema(resource_type: ResourceType)"},{"line_number":99,"context_line":"    +get_extended_info(resource: Resource)"},{"line_number":100,"context_line":"}"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"ProtectionPlugin -- Context"}],"source_content_type":"application/octet-stream","patch_set":9,"id":"7a5de9d1_1aec628e","line":99,"range":{"start_line":99,"start_character":0,"end_line":99,"end_character":42},"updated":"2016-01-28 15:35:22.000000000","message":"Should get context","commit_id":"8e35a5b6117c101cceb03bf2dc8c3f612567d65e"},{"author":{"_account_id":13070,"name":"Eran Gampel","email":"eran@gampel.net","username":"Gampel"},"change_message_id":"d52414cfd5096f20a39a8e53c5fd20ac1abc0e01","unresolved":false,"context_lines":[{"line_number":96,"context_line":"    +get_options_schema(resource_type: ResourceType)"},{"line_number":97,"context_line":"    +get_extendend_info_schema(resource_type: ResourceType)"},{"line_number":98,"context_line":"    +get_restore_schema(resource_type: ResourceType)"},{"line_number":99,"context_line":"    +get_extended_info(resource: Resource)"},{"line_number":100,"context_line":"}"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"ProtectionPlugin -- Context"}],"source_content_type":"application/octet-stream","patch_set":9,"id":"7a5de9d1_54563cd3","line":99,"range":{"start_line":99,"start_character":5,"end_line":99,"end_character":22},"updated":"2016-01-28 12:10:58.000000000","message":"What do we get in get_extended_info ? I am not I understand the difference from  get_extendend_info_schema","commit_id":"8e35a5b6117c101cceb03bf2dc8c3f612567d65e"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"52283bbc5808d064f9b4e60b96ec148fc123eae7","unresolved":false,"context_lines":[{"line_number":28,"context_line":""},{"line_number":29,"context_line":"interface ResourceGraphWalkerListener {"},{"line_number":30,"context_line":"    on_node_enter(node: ResourceGraphNode, is_first_visit: boolean)"},{"line_number":31,"context_line":"    on_node_exit(node: ResourceGraphNode, is_first_visit: boolean)"},{"line_number":32,"context_line":"}"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"ResourceGraphNode *- Resource"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"7a5de9d1_c341b064","line":31,"updated":"2016-01-30 02:41:04.000000000","message":"If I get it correctly, it\u0027s ResourceGraphWalkerListener who will call ProtectionPlugin. Shouldn\u0027t context be passed into on_node_enter, on_node_exit?","commit_id":"2d73fd4cd79ec292fcc685dbaf1b89cee86ffec8"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"e07bd158a294e0ea8515ffe3d9cc58cf35421fbe","unresolved":false,"context_lines":[{"line_number":28,"context_line":""},{"line_number":29,"context_line":"interface ResourceGraphWalkerListener {"},{"line_number":30,"context_line":"    on_node_enter(node: ResourceGraphNode, is_first_visit: boolean)"},{"line_number":31,"context_line":"    on_node_exit(node: ResourceGraphNode, is_first_visit: boolean)"},{"line_number":32,"context_line":"}"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"ResourceGraphNode *- Resource"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"7a5de9d1_627b048d","line":31,"in_reply_to":"7a5de9d1_c341b064","updated":"2016-01-31 16:33:57.000000000","message":"It will call the provider which will prepare the context and pass it to the plugin.\n\nThe walker is generic.","commit_id":"2d73fd4cd79ec292fcc685dbaf1b89cee86ffec8"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"524f3ee8b05434d21376e52355d6e009564aa437","unresolved":false,"context_lines":[{"line_number":64,"context_line":"    +operation: Operation"},{"line_number":65,"context_line":"    +parameters: dict"},{"line_number":66,"context_line":"    +resource: ResourceGraphNode"},{"line_number":67,"context_line":"    +account: MetadataStore"},{"line_number":68,"context_line":"    +is_first_visit: boolean"},{"line_number":69,"context_line":"    +task_builder: TaskBuilder"},{"line_number":70,"context_line":"}"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"7a5de9d1_2fd7454c","line":67,"range":{"start_line":67,"start_character":5,"end_line":67,"end_character":12},"updated":"2016-01-30 08:18:34.000000000","message":"Suggest changing a more proper and explicit name.","commit_id":"2d73fd4cd79ec292fcc685dbaf1b89cee86ffec8"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"e07bd158a294e0ea8515ffe3d9cc58cf35421fbe","unresolved":false,"context_lines":[{"line_number":64,"context_line":"    +operation: Operation"},{"line_number":65,"context_line":"    +parameters: dict"},{"line_number":66,"context_line":"    +resource: ResourceGraphNode"},{"line_number":67,"context_line":"    +account: MetadataStore"},{"line_number":68,"context_line":"    +is_first_visit: boolean"},{"line_number":69,"context_line":"    +task_builder: TaskBuilder"},{"line_number":70,"context_line":"}"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"7a5de9d1_e295b486","line":67,"range":{"start_line":67,"start_character":5,"end_line":67,"end_character":12},"in_reply_to":"7a5de9d1_2fd7454c","updated":"2016-01-31 16:33:57.000000000","message":"Done","commit_id":"2d73fd4cd79ec292fcc685dbaf1b89cee86ffec8"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"f58c29a08cfe917f788f05df1a356d98cb590173","unresolved":false,"context_lines":[{"line_number":67,"context_line":"    +account: MetadataStore"},{"line_number":68,"context_line":"    +is_first_visit: boolean"},{"line_number":69,"context_line":"    +task_builder: TaskBuilder"},{"line_number":70,"context_line":"}"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"interface MetadataStore {"},{"line_number":73,"context_line":"    write_object(key: string, value: dict)"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"7a5de9d1_be516210","line":70,"updated":"2016-01-29 02:25:47.000000000","message":"we once discussed there should be a context to contains the result returned from children node traversing, say the task flows built from children plugins. \nmissing one field to contain this information?","commit_id":"2d73fd4cd79ec292fcc685dbaf1b89cee86ffec8"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"e07bd158a294e0ea8515ffe3d9cc58cf35421fbe","unresolved":false,"context_lines":[{"line_number":67,"context_line":"    +account: MetadataStore"},{"line_number":68,"context_line":"    +is_first_visit: boolean"},{"line_number":69,"context_line":"    +task_builder: TaskBuilder"},{"line_number":70,"context_line":"}"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"interface MetadataStore {"},{"line_number":73,"context_line":"    write_object(key: string, value: dict)"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"7a5de9d1_82b72039","line":70,"in_reply_to":"7a5de9d1_be516210","updated":"2016-01-31 16:33:57.000000000","message":"That task builder will contain the result.","commit_id":"2d73fd4cd79ec292fcc685dbaf1b89cee86ffec8"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"f58c29a08cfe917f788f05df1a356d98cb590173","unresolved":false,"context_lines":[{"line_number":69,"context_line":"    +task_builder: TaskBuilder"},{"line_number":70,"context_line":"}"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"interface MetadataStore {"},{"line_number":73,"context_line":"    write_object(key: string, value: dict)"},{"line_number":74,"context_line":"    read_object(key): dict"},{"line_number":75,"context_line":"    is_writeable(): bool"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"7a5de9d1_03e29d9f","line":72,"updated":"2016-01-29 02:25:47.000000000","message":"this interface is overlapped with BankPluginInterface()?","commit_id":"2d73fd4cd79ec292fcc685dbaf1b89cee86ffec8"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"e07bd158a294e0ea8515ffe3d9cc58cf35421fbe","unresolved":false,"context_lines":[{"line_number":69,"context_line":"    +task_builder: TaskBuilder"},{"line_number":70,"context_line":"}"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"interface MetadataStore {"},{"line_number":73,"context_line":"    write_object(key: string, value: dict)"},{"line_number":74,"context_line":"    read_object(key): dict"},{"line_number":75,"context_line":"    is_writeable(): bool"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"7a5de9d1_22a8acda","line":72,"in_reply_to":"7a5de9d1_03e29d9f","updated":"2016-01-31 16:33:57.000000000","message":"I will change so it extends that interface","commit_id":"2d73fd4cd79ec292fcc685dbaf1b89cee86ffec8"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"524f3ee8b05434d21376e52355d6e009564aa437","unresolved":false,"context_lines":[{"line_number":110,"context_line":"}"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"ProtectionPlugin -- Context"},{"line_number":113,"context_line":"ProtectionPlugin -- TaskFlow::Atom"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"interface ProtectionProvider {"},{"line_number":116,"context_line":"}"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"7a5de9d1_0f07e9ca","line":113,"updated":"2016-01-30 08:18:34.000000000","message":"plugin still associated to TaskFlow?","commit_id":"2d73fd4cd79ec292fcc685dbaf1b89cee86ffec8"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"e07bd158a294e0ea8515ffe3d9cc58cf35421fbe","unresolved":false,"context_lines":[{"line_number":110,"context_line":"}"},{"line_number":111,"context_line":""},{"line_number":112,"context_line":"ProtectionPlugin -- Context"},{"line_number":113,"context_line":"ProtectionPlugin -- TaskFlow::Atom"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"interface ProtectionProvider {"},{"line_number":116,"context_line":"}"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"7a5de9d1_22718ca8","line":113,"in_reply_to":"7a5de9d1_0f07e9ca","updated":"2016-01-31 16:33:57.000000000","message":"It\u0027s a mistake, I will remove the association.","commit_id":"2d73fd4cd79ec292fcc685dbaf1b89cee86ffec8"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"52283bbc5808d064f9b4e60b96ec148fc123eae7","unresolved":false,"context_lines":[{"line_number":112,"context_line":"ProtectionPlugin -- Context"},{"line_number":113,"context_line":"ProtectionPlugin -- TaskFlow::Atom"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"interface ProtectionProvider {"},{"line_number":116,"context_line":"}"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"class PluggableProtectionProvider extends ProtectionProvider {"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"7a5de9d1_e36f0cfa","line":115,"updated":"2016-01-30 02:41:04.000000000","message":"need an interface like build_work_flow(context):flow","commit_id":"2d73fd4cd79ec292fcc685dbaf1b89cee86ffec8"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"e07bd158a294e0ea8515ffe3d9cc58cf35421fbe","unresolved":false,"context_lines":[{"line_number":112,"context_line":"ProtectionPlugin -- Context"},{"line_number":113,"context_line":"ProtectionPlugin -- TaskFlow::Atom"},{"line_number":114,"context_line":""},{"line_number":115,"context_line":"interface ProtectionProvider {"},{"line_number":116,"context_line":"}"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":"class PluggableProtectionProvider extends ProtectionProvider {"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"7a5de9d1_c26af8b2","line":115,"in_reply_to":"7a5de9d1_e36f0cfa","updated":"2016-01-31 16:33:57.000000000","message":"I left it empty purposefully. It is defined in the in the protection service design (which you maintain).","commit_id":"2d73fd4cd79ec292fcc685dbaf1b89cee86ffec8"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"524f3ee8b05434d21376e52355d6e009564aa437","unresolved":false,"context_lines":[{"line_number":123,"context_line":"PluggableProtectionProvider -\u003e ResourceGraphWalker: uses it to iterate over graph"},{"line_number":124,"context_line":"ResourceGraphWalker - ResourceGraphNode"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"interface ProtectionProvider {"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"}"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"@enduml"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"7a5de9d1_2f898575","line":128,"range":{"start_line":126,"start_character":0,"end_line":128,"end_character":1},"updated":"2016-01-30 08:18:34.000000000","message":"Duplicated ProtectionProvider definition.","commit_id":"2d73fd4cd79ec292fcc685dbaf1b89cee86ffec8"},{"author":{"_account_id":2023,"name":"Saggi Mizrahi","email":"ficoos+osreview@gmail.com","username":"ficoos"},"change_message_id":"e07bd158a294e0ea8515ffe3d9cc58cf35421fbe","unresolved":false,"context_lines":[{"line_number":123,"context_line":"PluggableProtectionProvider -\u003e ResourceGraphWalker: uses it to iterate over graph"},{"line_number":124,"context_line":"ResourceGraphWalker - ResourceGraphNode"},{"line_number":125,"context_line":""},{"line_number":126,"context_line":"interface ProtectionProvider {"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"}"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"@enduml"}],"source_content_type":"application/octet-stream","patch_set":10,"id":"7a5de9d1_a25d7c16","line":128,"range":{"start_line":126,"start_character":0,"end_line":128,"end_character":1},"in_reply_to":"7a5de9d1_2f898575","updated":"2016-01-31 16:33:57.000000000","message":"removed","commit_id":"2d73fd4cd79ec292fcc685dbaf1b89cee86ffec8"},{"author":{"_account_id":13070,"name":"Eran Gampel","email":"eran@gampel.net","username":"Gampel"},"change_message_id":"1574e14bec99d3ff7d7942c47060c68e6f0c4e9c","unresolved":false,"context_lines":[{"line_number":64,"context_line":"    +operation: Operation"},{"line_number":65,"context_line":"    +parameters: dict"},{"line_number":66,"context_line":"    +resource: ResourceGraphNode"},{"line_number":67,"context_line":"    +metadata_store: MetadataStore"},{"line_number":68,"context_line":"    +is_first_visit: boolean"},{"line_number":69,"context_line":"    +task_builder: TaskBuilder"},{"line_number":70,"context_line":"}"}],"source_content_type":"application/octet-stream","patch_set":12,"id":"7a5de9d1_8f5d0817","line":67,"range":{"start_line":67,"start_character":5,"end_line":67,"end_character":19},"updated":"2016-01-31 20:36:26.000000000","message":"I am not sure this is the best name, some plugin will save their data using this object (network , project ...)\nI would just use bank but this is not a patch breaker","commit_id":"47263b539ff609e49201ac3d359d5f068361d793"},{"author":{"_account_id":19720,"name":"wangliuan","email":"wangliuan2016@163.com","username":"wangliuan"},"change_message_id":"e0da6992b7142da39db6c991823ace0c0f0cf872","unresolved":false,"context_lines":[{"line_number":107,"context_line":"    +get_options_schema(resource_type: ResourceType)"},{"line_number":108,"context_line":"    +get_saved_info_schema(resource_type: ResourceType)"},{"line_number":109,"context_line":"    +get_restore_schema(resource_type: ResourceType)"},{"line_number":110,"context_line":"    +get_savedgi_info(metadata_store: MetadataStore, resource: Resource)"},{"line_number":111,"context_line":"}"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"ProtectionPlugin -- Context"}],"source_content_type":"application/octet-stream","patch_set":13,"id":"7a5de9d1_9b109f5b","line":110,"range":{"start_line":110,"start_character":0,"end_line":110,"end_character":72},"updated":"2016-02-02 11:11:04.000000000","message":"what\u0027s the special meaning of \u0027savedgi\u0027","commit_id":"4f4ac100809f606f5f886d0850c3d3878dbea095"},{"author":{"_account_id":13070,"name":"Eran Gampel","email":"eran@gampel.net","username":"Gampel"},"change_message_id":"2357f5d85795fa4a35d6efb2297e99bc34357f49","unresolved":false,"context_lines":[{"line_number":107,"context_line":"    +get_options_schema(resource_type: ResourceType)"},{"line_number":108,"context_line":"    +get_saved_info_schema(resource_type: ResourceType)"},{"line_number":109,"context_line":"    +get_restore_schema(resource_type: ResourceType)"},{"line_number":110,"context_line":"    +get_savedgi_info(metadata_store: MetadataStore, resource: Resource)"},{"line_number":111,"context_line":"}"},{"line_number":112,"context_line":""},{"line_number":113,"context_line":"ProtectionPlugin -- Context"}],"source_content_type":"application/octet-stream","patch_set":13,"id":"7a5de9d1_8fc0442c","line":110,"range":{"start_line":110,"start_character":0,"end_line":110,"end_character":72},"in_reply_to":"7a5de9d1_9b109f5b","updated":"2016-02-02 16:34:04.000000000","message":"I think it should be get_saved_info(\nGood catch","commit_id":"4f4ac100809f606f5f886d0850c3d3878dbea095"}],"doc/source/specs/pluggable_protection_provider.rst":[{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"a9849cc993d8e03278c2784fa0d36b13da93e555","unresolved":false,"context_lines":[{"line_number":2,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":3,"context_line":""},{"line_number":4,"context_line":"The *Pluggable Protection Provider* will be the reference implementation"},{"line_number":5,"context_line":"protection provider. It\u0027s purpose is to be fully pluggable and extandable so"},{"line_number":6,"context_line":"that only extream use cases will need to implement their own Protection Provider"},{"line_number":7,"context_line":"from scratch."},{"line_number":8,"context_line":""}],"source_content_type":"text/x-rst","patch_set":3,"id":"fa69d971_170cfb3f","line":5,"range":{"start_line":5,"start_character":21,"end_line":5,"end_character":25},"updated":"2016-01-05 03:38:12.000000000","message":"Its","commit_id":"b86cf3562c021788954bbc2c5755edbd7a8f957f"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"a9849cc993d8e03278c2784fa0d36b13da93e555","unresolved":false,"context_lines":[{"line_number":2,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":3,"context_line":""},{"line_number":4,"context_line":"The *Pluggable Protection Provider* will be the reference implementation"},{"line_number":5,"context_line":"protection provider. It\u0027s purpose is to be fully pluggable and extandable so"},{"line_number":6,"context_line":"that only extream use cases will need to implement their own Protection Provider"},{"line_number":7,"context_line":"from scratch."},{"line_number":8,"context_line":""}],"source_content_type":"text/x-rst","patch_set":3,"id":"fa69d971_37a9ff90","line":5,"range":{"start_line":5,"start_character":63,"end_line":5,"end_character":73},"updated":"2016-01-05 03:38:12.000000000","message":"extendable","commit_id":"b86cf3562c021788954bbc2c5755edbd7a8f957f"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"a9849cc993d8e03278c2784fa0d36b13da93e555","unresolved":false,"context_lines":[{"line_number":3,"context_line":""},{"line_number":4,"context_line":"The *Pluggable Protection Provider* will be the reference implementation"},{"line_number":5,"context_line":"protection provider. It\u0027s purpose is to be fully pluggable and extandable so"},{"line_number":6,"context_line":"that only extream use cases will need to implement their own Protection Provider"},{"line_number":7,"context_line":"from scratch."},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The protection provider will contain internally a map between any registered"}],"source_content_type":"text/x-rst","patch_set":3,"id":"fa69d971_37801ff7","line":6,"range":{"start_line":6,"start_character":10,"end_line":6,"end_character":17},"updated":"2016-01-05 03:38:12.000000000","message":"extreme","commit_id":"b86cf3562c021788954bbc2c5755edbd7a8f957f"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"a9849cc993d8e03278c2784fa0d36b13da93e555","unresolved":false,"context_lines":[{"line_number":7,"context_line":"from scratch."},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The protection provider will contain internally a map between any registered"},{"line_number":10,"context_line":"*Protectable* and a corrosponding *Protection Plugin*. When the pluggable"},{"line_number":11,"context_line":"protection provider is asked to perform an action, it will walk over the"},{"line_number":12,"context_line":"graph and pass a context object to the appropriate plugin whenever a node is"},{"line_number":13,"context_line":"encountered."}],"source_content_type":"text/x-rst","patch_set":3,"id":"fa69d971_d7718345","line":10,"range":{"start_line":10,"start_character":20,"end_line":10,"end_character":33},"updated":"2016-01-05 03:38:12.000000000","message":"corresponding","commit_id":"b86cf3562c021788954bbc2c5755edbd7a8f957f"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"a9849cc993d8e03278c2784fa0d36b13da93e555","unresolved":false,"context_lines":[{"line_number":14,"context_line":""},{"line_number":15,"context_line":"The resource graph is traversed in with DFS. When a node is first encountered"},{"line_number":16,"context_line":"the protection manager gets the plugin for the appropriate resource type, builds"},{"line_number":17,"context_line":"a context and passes it to the plugins `get_pre_task()` method. The plugin can"},{"line_number":18,"context_line":"return any tasks that it wants added to the task list. When all of a node"},{"line_number":19,"context_line":"childrens have been visited the `get_pre_task()` is called. The task returned"},{"line_number":20,"context_line":"from this method will also be added to the task list but is also guranteed to"}],"source_content_type":"text/x-rst","patch_set":3,"id":"fa69d971_7765371c","line":17,"range":{"start_line":17,"start_character":31,"end_line":17,"end_character":38},"updated":"2016-01-05 03:38:12.000000000","message":"plugin\u0027s","commit_id":"b86cf3562c021788954bbc2c5755edbd7a8f957f"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"a9849cc993d8e03278c2784fa0d36b13da93e555","unresolved":false,"context_lines":[{"line_number":16,"context_line":"the protection manager gets the plugin for the appropriate resource type, builds"},{"line_number":17,"context_line":"a context and passes it to the plugins `get_pre_task()` method. The plugin can"},{"line_number":18,"context_line":"return any tasks that it wants added to the task list. When all of a node"},{"line_number":19,"context_line":"childrens have been visited the `get_pre_task()` is called. The task returned"},{"line_number":20,"context_line":"from this method will also be added to the task list but is also guranteed to"},{"line_number":21,"context_line":"execute after all the child node\u0027s tasks have finished. Any of the methods can"},{"line_number":22,"context_line":"return `None` if they don\u0027t want any action performed."}],"source_content_type":"text/x-rst","patch_set":3,"id":"fa69d971_d71bc3c8","line":19,"range":{"start_line":19,"start_character":33,"end_line":19,"end_character":45},"updated":"2016-01-05 03:38:12.000000000","message":"Should be get_post_task?","commit_id":"b86cf3562c021788954bbc2c5755edbd7a8f957f"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"a9849cc993d8e03278c2784fa0d36b13da93e555","unresolved":false,"context_lines":[{"line_number":15,"context_line":"The resource graph is traversed in with DFS. When a node is first encountered"},{"line_number":16,"context_line":"the protection manager gets the plugin for the appropriate resource type, builds"},{"line_number":17,"context_line":"a context and passes it to the plugins `get_pre_task()` method. The plugin can"},{"line_number":18,"context_line":"return any tasks that it wants added to the task list. When all of a node"},{"line_number":19,"context_line":"childrens have been visited the `get_pre_task()` is called. The task returned"},{"line_number":20,"context_line":"from this method will also be added to the task list but is also guranteed to"},{"line_number":21,"context_line":"execute after all the child node\u0027s tasks have finished. Any of the methods can"},{"line_number":22,"context_line":"return `None` if they don\u0027t want any action performed."}],"source_content_type":"text/x-rst","patch_set":3,"id":"fa69d971_57b91378","line":19,"range":{"start_line":18,"start_character":60,"end_line":19,"end_character":9},"updated":"2016-01-05 03:38:12.000000000","message":"all children of a node","commit_id":"b86cf3562c021788954bbc2c5755edbd7a8f957f"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"a9849cc993d8e03278c2784fa0d36b13da93e555","unresolved":false,"context_lines":[{"line_number":17,"context_line":"a context and passes it to the plugins `get_pre_task()` method. The plugin can"},{"line_number":18,"context_line":"return any tasks that it wants added to the task list. When all of a node"},{"line_number":19,"context_line":"childrens have been visited the `get_pre_task()` is called. The task returned"},{"line_number":20,"context_line":"from this method will also be added to the task list but is also guranteed to"},{"line_number":21,"context_line":"execute after all the child node\u0027s tasks have finished. Any of the methods can"},{"line_number":22,"context_line":"return `None` if they don\u0027t want any action performed."},{"line_number":23,"context_line":""}],"source_content_type":"text/x-rst","patch_set":3,"id":"fa69d971_b7564f28","line":20,"range":{"start_line":20,"start_character":65,"end_line":20,"end_character":74},"updated":"2016-01-05 03:38:12.000000000","message":"guaranteed","commit_id":"b86cf3562c021788954bbc2c5755edbd7a8f957f"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"a9849cc993d8e03278c2784fa0d36b13da93e555","unresolved":false,"context_lines":[{"line_number":21,"context_line":"execute after all the child node\u0027s tasks have finished. Any of the methods can"},{"line_number":22,"context_line":"return `None` if they don\u0027t want any action performed."},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"After the entire grap has been traversed the Protection Provider will return"},{"line_number":25,"context_line":"the task lists which will be queued and than executed according to the"},{"line_number":26,"context_line":"executor\u0027s policy. When all the tasks are done the operation is considered"},{"line_number":27,"context_line":"complete."}],"source_content_type":"text/x-rst","patch_set":3,"id":"fa69d971_f756075b","line":24,"range":{"start_line":24,"start_character":17,"end_line":24,"end_character":21},"updated":"2016-01-05 03:38:12.000000000","message":"graph","commit_id":"b86cf3562c021788954bbc2c5755edbd7a8f957f"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"a9849cc993d8e03278c2784fa0d36b13da93e555","unresolved":false,"context_lines":[{"line_number":22,"context_line":"return `None` if they don\u0027t want any action performed."},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"After the entire grap has been traversed the Protection Provider will return"},{"line_number":25,"context_line":"the task lists which will be queued and than executed according to the"},{"line_number":26,"context_line":"executor\u0027s policy. When all the tasks are done the operation is considered"},{"line_number":27,"context_line":"complete."},{"line_number":28,"context_line":""}],"source_content_type":"text/x-rst","patch_set":3,"id":"fa69d971_971f8b6b","line":25,"range":{"start_line":25,"start_character":9,"end_line":25,"end_character":14},"updated":"2016-01-05 03:38:12.000000000","message":"list","commit_id":"b86cf3562c021788954bbc2c5755edbd7a8f957f"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"a9849cc993d8e03278c2784fa0d36b13da93e555","unresolved":false,"context_lines":[{"line_number":22,"context_line":"return `None` if they don\u0027t want any action performed."},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"After the entire grap has been traversed the Protection Provider will return"},{"line_number":25,"context_line":"the task lists which will be queued and than executed according to the"},{"line_number":26,"context_line":"executor\u0027s policy. When all the tasks are done the operation is considered"},{"line_number":27,"context_line":"complete."},{"line_number":28,"context_line":""}],"source_content_type":"text/x-rst","patch_set":3,"id":"fa69d971_57159346","line":25,"range":{"start_line":25,"start_character":40,"end_line":25,"end_character":44},"updated":"2016-01-05 03:38:12.000000000","message":"then","commit_id":"b86cf3562c021788954bbc2c5755edbd7a8f957f"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"a9849cc993d8e03278c2784fa0d36b13da93e555","unresolved":false,"context_lines":[{"line_number":28,"context_line":""},{"line_number":29,"context_line":"This scheme decouples the tree structure form the task execution. A plugin that"},{"line_number":30,"context_line":"handles multiple resources or that aggregates mutiple resources to one task can"},{"line_number":31,"context_line":"use this mechanism to only return tasks when appropriate for it\u0027s scheme."}],"source_content_type":"text/x-rst","patch_set":3,"id":"fa69d971_979c6b10","line":31,"range":{"start_line":31,"start_character":61,"end_line":31,"end_character":65},"updated":"2016-01-05 03:38:12.000000000","message":"its","commit_id":"b86cf3562c021788954bbc2c5755edbd7a8f957f"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"4c321fc1684822b6b256f61e5a47c5c0034f40d8","unresolved":false,"context_lines":[{"line_number":38,"context_line":"the protection manager gets the plugin for the appropriate resource type, builds"},{"line_number":39,"context_line":"a context and passes it to the plugins `get_pre_task()` method. The plugin can"},{"line_number":40,"context_line":"return any tasks that it wants added to the task list. When all of a node"},{"line_number":41,"context_line":"childrens have been visited the `get_pre_task()` is called. The task returned"},{"line_number":42,"context_line":"from this method will also be added to the task list but is also guranteed to"},{"line_number":43,"context_line":"execute after all the child node\u0027s tasks have finished. Any of the methods can"},{"line_number":44,"context_line":"return `None` if they don\u0027t want any action performed."}],"source_content_type":"text/x-rst","patch_set":4,"id":"fa69d971_cecd6532","line":41,"updated":"2016-01-11 01:34:44.000000000","message":"should be get_post_task() here?","commit_id":"2d8f9b1b26f0f22de36940d5bb34cbc8db6a642f"},{"author":{"_account_id":19346,"name":"yinwei","email":"yinweiishere@icloud.com","username":"yinwei"},"change_message_id":"4c321fc1684822b6b256f61e5a47c5c0034f40d8","unresolved":false,"context_lines":[{"line_number":41,"context_line":"childrens have been visited the `get_pre_task()` is called. The task returned"},{"line_number":42,"context_line":"from this method will also be added to the task list but is also guranteed to"},{"line_number":43,"context_line":"execute after all the child node\u0027s tasks have finished. Any of the methods can"},{"line_number":44,"context_line":"return `None` if they don\u0027t want any action performed."},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"After the entire grap has been traversed the Protection Provider will return"},{"line_number":47,"context_line":"the task lists which will be queued and than executed according to the"}],"source_content_type":"text/x-rst","patch_set":4,"id":"fa69d971_8eea0d73","line":44,"updated":"2016-01-11 01:34:44.000000000","message":"The pre and post tasks seems a bit redundant to me. Why not just have plugin to return the flow (as base class atom) it wants to execute? and the plugin could specify the dependency of the tasks in side the flow, where the flow could be linear or graph.  Then provider doesn\u0027t need care the pre or post, but only compose a graph flow by all of flows returned from those plugins and run them on parallel?","commit_id":"2d8f9b1b26f0f22de36940d5bb34cbc8db6a642f"},{"author":{"_account_id":16203,"name":"zengyingzhe","email":"zengyingzhe@huawei.com","username":"zengyingzhe"},"change_message_id":"7c31e01233e468d92250f5e6c480afcd4c992227","unresolved":false,"context_lines":[{"line_number":38,"context_line":"the protection manager gets the plugin for the appropriate resource type, builds"},{"line_number":39,"context_line":"a context and passes it to the plugins `get_pre_task()` method. The plugin can"},{"line_number":40,"context_line":"return any tasks that it wants added to the task list. When all of a node"},{"line_number":41,"context_line":"childrens have been visited the `get_pre_task()` is called. The task returned"},{"line_number":42,"context_line":"from this method will also be added to the task list but is also guranteed to"},{"line_number":43,"context_line":"execute after all the child node\u0027s tasks have finished. Any of the methods can"},{"line_number":44,"context_line":"return `None` if they don\u0027t want any action performed."}],"source_content_type":"text/x-rst","patch_set":7,"id":"ba63e191_419b03ca","line":41,"range":{"start_line":41,"start_character":33,"end_line":41,"end_character":45},"updated":"2016-01-19 02:46:58.000000000","message":"Should be get_post_task.","commit_id":"7b3b2ee191b2b31f74c227999d38448883d2c115"}]}
