)]}'
{"doc/notification_samples/action_plan-create.json":[{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"eb1fd6355d436351939463ca0feb09033cd33a51","unresolved":false,"context_lines":[{"line_number":3,"context_line":"  \"payload\": {"},{"line_number":4,"context_line":"    \"watcher_object.version\": \"1.0\","},{"line_number":5,"context_line":"    \"watcher_object.data\": {"},{"line_number":6,"context_line":"      \"strategy\": {"},{"line_number":7,"context_line":"        \"watcher_object.version\": \"1.0\","},{"line_number":8,"context_line":"        \"watcher_object.data\": {"},{"line_number":9,"context_line":"          \"uuid\": \"cb3d0b58-4415-4d90-b75b-1e96878730e3\","}],"source_content_type":"application/json","patch_set":7,"id":"1a430d35_24f3dfd7","line":6,"range":{"start_line":6,"start_character":7,"end_line":6,"end_character":15},"updated":"2017-02-06 18:00:41.000000000","message":"This file shouldn\u0027t be changed","commit_id":"5979b62a1a3cf2318db583f83c8c8724c0fcfa48"},{"author":{"_account_id":19055,"name":"Alexander Chadin","email":"joker946@gmail.com","username":"joker946"},"change_message_id":"9869c80e6bdb31343d276319a22179ef5ed2c72f","unresolved":false,"context_lines":[{"line_number":3,"context_line":"  \"payload\": {"},{"line_number":4,"context_line":"    \"watcher_object.version\": \"1.0\","},{"line_number":5,"context_line":"    \"watcher_object.data\": {"},{"line_number":6,"context_line":"      \"strategy\": {"},{"line_number":7,"context_line":"        \"watcher_object.version\": \"1.0\","},{"line_number":8,"context_line":"        \"watcher_object.data\": {"},{"line_number":9,"context_line":"          \"uuid\": \"cb3d0b58-4415-4d90-b75b-1e96878730e3\","}],"source_content_type":"application/json","patch_set":7,"id":"1a430d35_bcfa7fbb","line":6,"range":{"start_line":6,"start_character":7,"end_line":6,"end_character":15},"in_reply_to":"1a430d35_24f3dfd7","updated":"2017-02-07 11:52:58.000000000","message":"Done","commit_id":"5979b62a1a3cf2318db583f83c8c8724c0fcfa48"}],"doc/notification_samples/action_plan-delete.json":[{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"eb1fd6355d436351939463ca0feb09033cd33a51","unresolved":false,"context_lines":[{"line_number":6,"context_line":"      \"uuid\": \"76be87bd-3422-43f9-93a0-e85a577e3061\","},{"line_number":7,"context_line":"      \"created_at\": \"2016-10-18T09:52:05Z\","},{"line_number":8,"context_line":"      \"audit\": {"},{"line_number":9,"context_line":"        \"watcher_object.data\": {"},{"line_number":10,"context_line":"          \"uuid\": \"10a47dd1-4874-4298-91cf-eff046dbdb8d\","},{"line_number":11,"context_line":"          \"goal_uuid\": \"bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a\","},{"line_number":12,"context_line":"          \"strategy_uuid\": \"75234dfe-87e3-4f11-a0e0-3c3305d86a39\","}],"source_content_type":"application/json","patch_set":7,"id":"1a430d35_64bb27e6","line":9,"updated":"2017-02-06 18:00:41.000000000","message":"ditto, the uuid fields should have stayed","commit_id":"5979b62a1a3cf2318db583f83c8c8724c0fcfa48"},{"author":{"_account_id":19055,"name":"Alexander Chadin","email":"joker946@gmail.com","username":"joker946"},"change_message_id":"9869c80e6bdb31343d276319a22179ef5ed2c72f","unresolved":false,"context_lines":[{"line_number":6,"context_line":"      \"uuid\": \"76be87bd-3422-43f9-93a0-e85a577e3061\","},{"line_number":7,"context_line":"      \"created_at\": \"2016-10-18T09:52:05Z\","},{"line_number":8,"context_line":"      \"audit\": {"},{"line_number":9,"context_line":"        \"watcher_object.data\": {"},{"line_number":10,"context_line":"          \"uuid\": \"10a47dd1-4874-4298-91cf-eff046dbdb8d\","},{"line_number":11,"context_line":"          \"goal_uuid\": \"bc830f84-8ae3-4fc6-8bc6-e3dd15e8b49a\","},{"line_number":12,"context_line":"          \"strategy_uuid\": \"75234dfe-87e3-4f11-a0e0-3c3305d86a39\","}],"source_content_type":"application/json","patch_set":7,"id":"1a430d35_dcf58bcb","line":9,"in_reply_to":"1a430d35_64bb27e6","updated":"2017-02-07 11:52:58.000000000","message":"Done","commit_id":"5979b62a1a3cf2318db583f83c8c8724c0fcfa48"}],"doc/notification_samples/action_plan-execution-end.json":[{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"eb1fd6355d436351939463ca0feb09033cd33a51","unresolved":false,"context_lines":[{"line_number":8,"context_line":"      \"created_at\": \"2016-10-18T09:52:05Z\","},{"line_number":9,"context_line":"      \"deleted_at\": null,"},{"line_number":10,"context_line":"      \"audit\": {"},{"line_number":11,"context_line":"        \"watcher_object.namespace\": \"watcher\","},{"line_number":12,"context_line":"        \"watcher_object.name\": \"TerseAuditPayload\","},{"line_number":13,"context_line":"        \"watcher_object.version\": \"1.0\","},{"line_number":14,"context_line":"        \"watcher_object.data\": {"}],"source_content_type":"application/json","patch_set":7,"id":"1a430d35_84be53d2","line":11,"updated":"2017-02-06 18:00:41.000000000","message":"ditto","commit_id":"5979b62a1a3cf2318db583f83c8c8724c0fcfa48"},{"author":{"_account_id":19055,"name":"Alexander Chadin","email":"joker946@gmail.com","username":"joker946"},"change_message_id":"9869c80e6bdb31343d276319a22179ef5ed2c72f","unresolved":false,"context_lines":[{"line_number":8,"context_line":"      \"created_at\": \"2016-10-18T09:52:05Z\","},{"line_number":9,"context_line":"      \"deleted_at\": null,"},{"line_number":10,"context_line":"      \"audit\": {"},{"line_number":11,"context_line":"        \"watcher_object.namespace\": \"watcher\","},{"line_number":12,"context_line":"        \"watcher_object.name\": \"TerseAuditPayload\","},{"line_number":13,"context_line":"        \"watcher_object.version\": \"1.0\","},{"line_number":14,"context_line":"        \"watcher_object.data\": {"}],"source_content_type":"application/json","patch_set":7,"id":"1a430d35_fc1b2719","line":11,"in_reply_to":"1a430d35_84be53d2","updated":"2017-02-07 11:52:58.000000000","message":"Done","commit_id":"5979b62a1a3cf2318db583f83c8c8724c0fcfa48"}],"doc/notification_samples/action_plan-execution-error.json":[{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"eb1fd6355d436351939463ca0feb09033cd33a51","unresolved":false,"context_lines":[{"line_number":21,"context_line":"      },"},{"line_number":22,"context_line":"      \"uuid\": \"76be87bd-3422-43f9-93a0-e85a577e3061\","},{"line_number":23,"context_line":"      \"created_at\": \"2016-10-18T09:52:05Z\","},{"line_number":24,"context_line":"      \"strategy\": {"},{"line_number":25,"context_line":"        \"watcher_object.version\": \"1.0\","},{"line_number":26,"context_line":"        \"watcher_object.namespace\": \"watcher\","},{"line_number":27,"context_line":"        \"watcher_object.name\": \"StrategyPayload\","}],"source_content_type":"application/json","patch_set":7,"id":"1a430d35_04cb4373","line":24,"range":{"start_line":24,"start_character":7,"end_line":24,"end_character":15},"updated":"2017-02-06 18:00:41.000000000","message":"ditto","commit_id":"5979b62a1a3cf2318db583f83c8c8724c0fcfa48"},{"author":{"_account_id":19055,"name":"Alexander Chadin","email":"joker946@gmail.com","username":"joker946"},"change_message_id":"9869c80e6bdb31343d276319a22179ef5ed2c72f","unresolved":false,"context_lines":[{"line_number":21,"context_line":"      },"},{"line_number":22,"context_line":"      \"uuid\": \"76be87bd-3422-43f9-93a0-e85a577e3061\","},{"line_number":23,"context_line":"      \"created_at\": \"2016-10-18T09:52:05Z\","},{"line_number":24,"context_line":"      \"strategy\": {"},{"line_number":25,"context_line":"        \"watcher_object.version\": \"1.0\","},{"line_number":26,"context_line":"        \"watcher_object.namespace\": \"watcher\","},{"line_number":27,"context_line":"        \"watcher_object.name\": \"StrategyPayload\","}],"source_content_type":"application/json","patch_set":7,"id":"1a430d35_dce3cb03","line":24,"range":{"start_line":24,"start_character":7,"end_line":24,"end_character":15},"in_reply_to":"1a430d35_04cb4373","updated":"2017-02-07 11:52:58.000000000","message":"Done","commit_id":"5979b62a1a3cf2318db583f83c8c8724c0fcfa48"}],"doc/notification_samples/action_plan-execution-start.json":[{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"eb1fd6355d436351939463ca0feb09033cd33a51","unresolved":false,"context_lines":[{"line_number":7,"context_line":"    \"watcher_object.data\": {"},{"line_number":8,"context_line":"      \"created_at\": \"2016-10-18T09:52:05Z\","},{"line_number":9,"context_line":"      \"deleted_at\": null,"},{"line_number":10,"context_line":"      \"audit\": {"},{"line_number":11,"context_line":"        \"watcher_object.namespace\": \"watcher\","},{"line_number":12,"context_line":"        \"watcher_object.name\": \"TerseAuditPayload\","},{"line_number":13,"context_line":"        \"watcher_object.version\": \"1.0\","}],"source_content_type":"application/json","patch_set":7,"id":"1a430d35_44c54b59","line":10,"range":{"start_line":10,"start_character":7,"end_line":10,"end_character":12},"updated":"2017-02-06 18:00:41.000000000","message":"ditto","commit_id":"5979b62a1a3cf2318db583f83c8c8724c0fcfa48"},{"author":{"_account_id":19055,"name":"Alexander Chadin","email":"joker946@gmail.com","username":"joker946"},"change_message_id":"9869c80e6bdb31343d276319a22179ef5ed2c72f","unresolved":false,"context_lines":[{"line_number":7,"context_line":"    \"watcher_object.data\": {"},{"line_number":8,"context_line":"      \"created_at\": \"2016-10-18T09:52:05Z\","},{"line_number":9,"context_line":"      \"deleted_at\": null,"},{"line_number":10,"context_line":"      \"audit\": {"},{"line_number":11,"context_line":"        \"watcher_object.namespace\": \"watcher\","},{"line_number":12,"context_line":"        \"watcher_object.name\": \"TerseAuditPayload\","},{"line_number":13,"context_line":"        \"watcher_object.version\": \"1.0\","}],"source_content_type":"application/json","patch_set":7,"id":"1a430d35_3cbbefe6","line":10,"range":{"start_line":10,"start_character":7,"end_line":10,"end_character":12},"in_reply_to":"1a430d35_44c54b59","updated":"2017-02-07 11:52:58.000000000","message":"Done","commit_id":"5979b62a1a3cf2318db583f83c8c8724c0fcfa48"}],"doc/notification_samples/action_plan-update.json":[{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"eb1fd6355d436351939463ca0feb09033cd33a51","unresolved":false,"context_lines":[{"line_number":2,"context_line":"  \"payload\": {"},{"line_number":3,"context_line":"    \"watcher_object.version\": \"1.0\","},{"line_number":4,"context_line":"    \"watcher_object.data\": {"},{"line_number":5,"context_line":"      \"audit\": {"},{"line_number":6,"context_line":"        \"watcher_object.version\": \"1.0\","},{"line_number":7,"context_line":"        \"watcher_object.data\": {"},{"line_number":8,"context_line":"          \"audit_type\": \"ONESHOT\","}],"source_content_type":"application/json","patch_set":7,"id":"1a430d35_84a573b6","line":5,"range":{"start_line":5,"start_character":7,"end_line":5,"end_character":12},"updated":"2017-02-06 18:00:41.000000000","message":"ditto","commit_id":"5979b62a1a3cf2318db583f83c8c8724c0fcfa48"},{"author":{"_account_id":19055,"name":"Alexander Chadin","email":"joker946@gmail.com","username":"joker946"},"change_message_id":"9869c80e6bdb31343d276319a22179ef5ed2c72f","unresolved":false,"context_lines":[{"line_number":2,"context_line":"  \"payload\": {"},{"line_number":3,"context_line":"    \"watcher_object.version\": \"1.0\","},{"line_number":4,"context_line":"    \"watcher_object.data\": {"},{"line_number":5,"context_line":"      \"audit\": {"},{"line_number":6,"context_line":"        \"watcher_object.version\": \"1.0\","},{"line_number":7,"context_line":"        \"watcher_object.data\": {"},{"line_number":8,"context_line":"          \"audit_type\": \"ONESHOT\","}],"source_content_type":"application/json","patch_set":7,"id":"1a430d35_7cb577ec","line":5,"range":{"start_line":5,"start_character":7,"end_line":5,"end_character":12},"in_reply_to":"1a430d35_84a573b6","updated":"2017-02-07 11:52:58.000000000","message":"Done","commit_id":"5979b62a1a3cf2318db583f83c8c8724c0fcfa48"}],"watcher/api/controllers/v1/action.py":[{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"0cdb8abd5f6157fb84bf945ca96ebe7fc17161b9","unresolved":false,"context_lines":[{"line_number":226,"context_line":"        marker_obj \u003d None"},{"line_number":227,"context_line":"        if marker:"},{"line_number":228,"context_line":"            marker_obj \u003d objects.Action.get_by_uuid(pecan.request.context,"},{"line_number":229,"context_line":"                                                    marker, eager\u003dTrue)"},{"line_number":230,"context_line":""},{"line_number":231,"context_line":"        filters \u003d {}"},{"line_number":232,"context_line":"        if action_plan_uuid:"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a461143_041d4a66","line":229,"range":{"start_line":229,"start_character":60,"end_line":229,"end_character":70},"updated":"2017-02-02 09:32:14.000000000","message":"I don\u0027t think this one has to be eagerly loaded","commit_id":"4a9fb49df6b7b9585b8606554ae8d139472717e6"},{"author":{"_account_id":19055,"name":"Alexander Chadin","email":"joker946@gmail.com","username":"joker946"},"change_message_id":"90c26dba114f334aab562cb605d60a3183f6aa2e","unresolved":false,"context_lines":[{"line_number":226,"context_line":"        marker_obj \u003d None"},{"line_number":227,"context_line":"        if marker:"},{"line_number":228,"context_line":"            marker_obj \u003d objects.Action.get_by_uuid(pecan.request.context,"},{"line_number":229,"context_line":"                                                    marker, eager\u003dTrue)"},{"line_number":230,"context_line":""},{"line_number":231,"context_line":"        filters \u003d {}"},{"line_number":232,"context_line":"        if action_plan_uuid:"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a461143_e50f582c","line":229,"range":{"start_line":229,"start_character":60,"end_line":229,"end_character":70},"in_reply_to":"3a461143_041d4a66","updated":"2017-02-02 12:06:35.000000000","message":"Done","commit_id":"4a9fb49df6b7b9585b8606554ae8d139472717e6"}],"watcher/applier/workflow_engine/base.py":[{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"377df35aa130be7ae4e72ec2f4c3c2e57b98718b","unresolved":false,"context_lines":[{"line_number":90,"context_line":"        raise NotImplementedError()"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"class BaseTaskFlowActionContainer(flow_task.Task):"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    def __init__(self, name, db_action, engine, **kwargs):"},{"line_number":96,"context_line":"        super(BaseTaskFlowActionContainer, self).__init__(name\u003dname)"}],"source_content_type":"text/x-python","patch_set":8,"id":"1a430d35_89761ad5","line":93,"range":{"start_line":93,"start_character":6,"end_line":93,"end_character":50},"updated":"2017-02-08 10:55:37.000000000","message":"hmm, this is actually a taskflow class, so it\u0027s not abstracted away from taskflow. IMHO, we should do something like:\n\nclass ActionContainer(object):\n\n    def pre_execute()  # abstract\n    def do_execute()  # abstract\n    def post_execute()  # abstract\n    def execute():\n       try:\n           self.pre_execute()\n           # action.execution.start notif\n           self.do_execute()\n           self.post_execute()\n           # action.execution.end notif\n       except:\n           # action.execution.error notif\n\n\nclass TaskflowActionContainer(ActionContainer, flow_task.Task):\n    # contains all the logic you defined below\n    # also implements pre_execute()\n    # do_execute() and post_execute()\n\nSo it\u0027s a multi-inheritance that looks like a mixin class, but only because taskflow requires its tasks to inherit from their own class too.","commit_id":"54e53fea93645d2bd98e627b6a1dd70944a2a566"},{"author":{"_account_id":19055,"name":"Alexander Chadin","email":"joker946@gmail.com","username":"joker946"},"change_message_id":"350fbef3d063c5d7751975fbe85a54e74bdfcb6c","unresolved":false,"context_lines":[{"line_number":90,"context_line":"        raise NotImplementedError()"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"class BaseTaskFlowActionContainer(flow_task.Task):"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    def __init__(self, name, db_action, engine, **kwargs):"},{"line_number":96,"context_line":"        super(BaseTaskFlowActionContainer, self).__init__(name\u003dname)"}],"source_content_type":"text/x-python","patch_set":8,"id":"fa31d9ce_8d4b2f59","line":93,"range":{"start_line":93,"start_character":6,"end_line":93,"end_character":50},"in_reply_to":"1a430d35_89761ad5","updated":"2017-02-10 08:45:55.000000000","message":"I have described our conclusion in the NOTE section","commit_id":"54e53fea93645d2bd98e627b6a1dd70944a2a566"}],"watcher/applier/workflow_engine/default.py":[{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"eb1fd6355d436351939463ca0feb09033cd33a51","unresolved":false,"context_lines":[{"line_number":118,"context_line":"    def engine(self):"},{"line_number":119,"context_line":"        return self._engine"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    def pre_execute(self):"},{"line_number":122,"context_line":"        try:"},{"line_number":123,"context_line":"            self.engine.notify("},{"line_number":124,"context_line":"                self._db_action, objects.action.State.ONGOING,"},{"line_number":125,"context_line":"                fields.NotificationPhase.START,"},{"line_number":126,"context_line":"                fields.NotificationAction.EXECUTION"},{"line_number":127,"context_line":"            )"},{"line_number":128,"context_line":"            LOG.debug(\"Pre-condition action: %s\", self.name)"},{"line_number":129,"context_line":"            self.action.pre_condition()"},{"line_number":130,"context_line":"        except Exception as e:"},{"line_number":131,"context_line":"            LOG.exception(e)"},{"line_number":132,"context_line":"            self.engine.notify("},{"line_number":133,"context_line":"                self._db_action, objects.action.State.FAILED,"},{"line_number":134,"context_line":"                fields.NotificationPhase.ERROR,"},{"line_number":135,"context_line":"                fields.NotificationAction.EXECUTION)"},{"line_number":136,"context_line":"            raise"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"    def execute(self, *args, **kwargs):"},{"line_number":139,"context_line":"        try:"},{"line_number":140,"context_line":"            LOG.debug(\"Running action: %s\", self.name)"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"            self.action.execute()"},{"line_number":143,"context_line":"            self.engine.notify("},{"line_number":144,"context_line":"                self._db_action, objects.action.State.SUCCEEDED,"},{"line_number":145,"context_line":"                fields.NotificationPhase.END,"},{"line_number":146,"context_line":"                fields.NotificationAction.EXECUTION)"},{"line_number":147,"context_line":"        except Exception as e:"},{"line_number":148,"context_line":"            LOG.exception(e)"},{"line_number":149,"context_line":"            LOG.error(_LE(\u0027The workflow engine has failed \u0027"},{"line_number":150,"context_line":"                          \u0027to execute the action: %s\u0027), self.name)"},{"line_number":151,"context_line":""},{"line_number":152,"context_line":"            self.engine.notify("},{"line_number":153,"context_line":"                self._db_action, objects.action.State.FAILED,"},{"line_number":154,"context_line":"                fields.NotificationPhase.ERROR,"},{"line_number":155,"context_line":"                fields.NotificationAction.EXECUTION"},{"line_number":156,"context_line":"            )"},{"line_number":157,"context_line":"            raise"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"    def post_execute(self):"},{"line_number":160,"context_line":"        try:"},{"line_number":161,"context_line":"            LOG.debug(\"Post-condition action: %s\", self.name)"},{"line_number":162,"context_line":"            self.action.post_condition()"},{"line_number":163,"context_line":"        except Exception as e:"},{"line_number":164,"context_line":"            LOG.exception(e)"},{"line_number":165,"context_line":"            self.engine.notify("},{"line_number":166,"context_line":"                self._db_action, objects.action.State.FAILED,"},{"line_number":167,"context_line":"                fields.NotificationPhase.ERROR,"},{"line_number":168,"context_line":"                fields.NotificationAction.EXECUTION"},{"line_number":169,"context_line":"            )"},{"line_number":170,"context_line":"            raise"},{"line_number":171,"context_line":""},{"line_number":172,"context_line":"    def revert(self, *args, **kwargs):"},{"line_number":173,"context_line":"        LOG.warning(_LW(\"Revert action: %s\"), self.name)"}],"source_content_type":"text/x-python","patch_set":7,"id":"1a430d35_3fb6863d","line":170,"range":{"start_line":121,"start_character":0,"end_line":170,"end_character":17},"updated":"2017-02-06 18:00:41.000000000","message":"IMHO, this logic should be made outside of the plugin\u0027s logic so plugin developer can benefit from notification straight out of the box. To do so, I reckon we should change the BaseWorkflow interface to use the pre_execute() do_execute() post_execute() pattern that we also use here https://github.com/openstack/watcher/blob/master/watcher/decision_engine/audit/base.py#L36-L53 and here https://github.com/openstack/watcher/blob/master/watcher/decision_engine/strategy/strategies/base.py#L128-L164\n\nthe BaseWorkflowEngine.execute() method would then be implemented in the base as followed:\n\n\n    def execute(self):\n        try:\n            self.engine.notify(\n                self._db_action, objects.action.State.ONGOING,\n                fields.NotificationPhase.START,\n                fields.NotificationAction.EXECUTION)\n            \n            self.pre_execute()\n            self.do_execute()\n            self.post_execute()\n\n            self.engine.notify(\n                self._db_action, objects.action.State.SUCCEEDED,\n                fields.NotificationPhase.END,\n                fields.NotificationAction.EXECUTION)\n        except Exception as exc:\n            LOG.exception(exc)\n            self.engine.notify(\n                self._db_action, objects.action.State.FAILED,\n                fields.NotificationPhase.ERROR,\n                fields.NotificationAction.EXECUTION\n            )\n            raise","commit_id":"5979b62a1a3cf2318db583f83c8c8724c0fcfa48"},{"author":{"_account_id":19055,"name":"Alexander Chadin","email":"joker946@gmail.com","username":"joker946"},"change_message_id":"9869c80e6bdb31343d276319a22179ef5ed2c72f","unresolved":false,"context_lines":[{"line_number":118,"context_line":"    def engine(self):"},{"line_number":119,"context_line":"        return self._engine"},{"line_number":120,"context_line":""},{"line_number":121,"context_line":"    def pre_execute(self):"},{"line_number":122,"context_line":"        try:"},{"line_number":123,"context_line":"            self.engine.notify("},{"line_number":124,"context_line":"                self._db_action, objects.action.State.ONGOING,"},{"line_number":125,"context_line":"                fields.NotificationPhase.START,"},{"line_number":126,"context_line":"                fields.NotificationAction.EXECUTION"},{"line_number":127,"context_line":"            )"},{"line_number":128,"context_line":"            LOG.debug(\"Pre-condition action: %s\", self.name)"},{"line_number":129,"context_line":"            self.action.pre_condition()"},{"line_number":130,"context_line":"        except Exception as e:"},{"line_number":131,"context_line":"            LOG.exception(e)"},{"line_number":132,"context_line":"            self.engine.notify("},{"line_number":133,"context_line":"                self._db_action, objects.action.State.FAILED,"},{"line_number":134,"context_line":"                fields.NotificationPhase.ERROR,"},{"line_number":135,"context_line":"                fields.NotificationAction.EXECUTION)"},{"line_number":136,"context_line":"            raise"},{"line_number":137,"context_line":""},{"line_number":138,"context_line":"    def execute(self, *args, **kwargs):"},{"line_number":139,"context_line":"        try:"},{"line_number":140,"context_line":"            LOG.debug(\"Running action: %s\", self.name)"},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"            self.action.execute()"},{"line_number":143,"context_line":"            self.engine.notify("},{"line_number":144,"context_line":"                self._db_action, objects.action.State.SUCCEEDED,"},{"line_number":145,"context_line":"                fields.NotificationPhase.END,"},{"line_number":146,"context_line":"                fields.NotificationAction.EXECUTION)"},{"line_number":147,"context_line":"        except Exception as e:"},{"line_number":148,"context_line":"            LOG.exception(e)"},{"line_number":149,"context_line":"            LOG.error(_LE(\u0027The workflow engine has failed \u0027"},{"line_number":150,"context_line":"                          \u0027to execute the action: %s\u0027), self.name)"},{"line_number":151,"context_line":""},{"line_number":152,"context_line":"            self.engine.notify("},{"line_number":153,"context_line":"                self._db_action, objects.action.State.FAILED,"},{"line_number":154,"context_line":"                fields.NotificationPhase.ERROR,"},{"line_number":155,"context_line":"                fields.NotificationAction.EXECUTION"},{"line_number":156,"context_line":"            )"},{"line_number":157,"context_line":"            raise"},{"line_number":158,"context_line":""},{"line_number":159,"context_line":"    def post_execute(self):"},{"line_number":160,"context_line":"        try:"},{"line_number":161,"context_line":"            LOG.debug(\"Post-condition action: %s\", self.name)"},{"line_number":162,"context_line":"            self.action.post_condition()"},{"line_number":163,"context_line":"        except Exception as e:"},{"line_number":164,"context_line":"            LOG.exception(e)"},{"line_number":165,"context_line":"            self.engine.notify("},{"line_number":166,"context_line":"                self._db_action, objects.action.State.FAILED,"},{"line_number":167,"context_line":"                fields.NotificationPhase.ERROR,"},{"line_number":168,"context_line":"                fields.NotificationAction.EXECUTION"},{"line_number":169,"context_line":"            )"},{"line_number":170,"context_line":"            raise"},{"line_number":171,"context_line":""},{"line_number":172,"context_line":"    def revert(self, *args, **kwargs):"},{"line_number":173,"context_line":"        LOG.warning(_LW(\"Revert action: %s\"), self.name)"}],"source_content_type":"text/x-python","patch_set":7,"id":"1a430d35_6e8042c1","line":170,"range":{"start_line":121,"start_character":0,"end_line":170,"end_character":17},"in_reply_to":"1a430d35_3fb6863d","updated":"2017-02-07 11:52:58.000000000","message":"Since task_flow calls pre_execute, execute and post_execute methods itself, I\u0027ve made them wrappers that wrap do_* methods.","commit_id":"5979b62a1a3cf2318db583f83c8c8724c0fcfa48"}],"watcher/notifications/action.py":[{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"0cdb8abd5f6157fb84bf945ca96ebe7fc17161b9","unresolved":false,"context_lines":[{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    fields \u003d {"},{"line_number":50,"context_line":"        \u0027uuid\u0027: wfields.UUIDField(),"},{"line_number":51,"context_line":"        \u0027action_type\u0027: wfields.StringField(nullable\u003dTrue),"},{"line_number":52,"context_line":"        \u0027input_parameters\u0027: wfields.DictField(nullable\u003dTrue),"},{"line_number":53,"context_line":"        \u0027state\u0027: wfields.StringField(nullable\u003dTrue),"},{"line_number":54,"context_line":"        \u0027parents\u0027: wfields.ListOfStringsField(nullable\u003dTrue),"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a461143_df478b1b","line":51,"range":{"start_line":51,"start_character":43,"end_line":51,"end_character":56},"updated":"2017-02-02 09:32:14.000000000","message":"IMHO, this shouldn\u0027t be nullable","commit_id":"4a9fb49df6b7b9585b8606554ae8d139472717e6"},{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"0cdb8abd5f6157fb84bf945ca96ebe7fc17161b9","unresolved":false,"context_lines":[{"line_number":49,"context_line":"    fields \u003d {"},{"line_number":50,"context_line":"        \u0027uuid\u0027: wfields.UUIDField(),"},{"line_number":51,"context_line":"        \u0027action_type\u0027: wfields.StringField(nullable\u003dTrue),"},{"line_number":52,"context_line":"        \u0027input_parameters\u0027: wfields.DictField(nullable\u003dTrue),"},{"line_number":53,"context_line":"        \u0027state\u0027: wfields.StringField(nullable\u003dTrue),"},{"line_number":54,"context_line":"        \u0027parents\u0027: wfields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":55,"context_line":"        \u0027action_plan_uuid\u0027: wfields.UUIDField(),"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a461143_7f5777ca","line":52,"range":{"start_line":52,"start_character":46,"end_line":52,"end_character":59},"updated":"2017-02-02 09:32:14.000000000","message":"ditto. Instead, maybe it should have a default value","commit_id":"4a9fb49df6b7b9585b8606554ae8d139472717e6"},{"author":{"_account_id":19055,"name":"Alexander Chadin","email":"joker946@gmail.com","username":"joker946"},"change_message_id":"90c26dba114f334aab562cb605d60a3183f6aa2e","unresolved":false,"context_lines":[{"line_number":49,"context_line":"    fields \u003d {"},{"line_number":50,"context_line":"        \u0027uuid\u0027: wfields.UUIDField(),"},{"line_number":51,"context_line":"        \u0027action_type\u0027: wfields.StringField(nullable\u003dTrue),"},{"line_number":52,"context_line":"        \u0027input_parameters\u0027: wfields.DictField(nullable\u003dTrue),"},{"line_number":53,"context_line":"        \u0027state\u0027: wfields.StringField(nullable\u003dTrue),"},{"line_number":54,"context_line":"        \u0027parents\u0027: wfields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":55,"context_line":"        \u0027action_plan_uuid\u0027: wfields.UUIDField(),"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a461143_ad21b6b6","line":52,"range":{"start_line":52,"start_character":46,"end_line":52,"end_character":59},"in_reply_to":"3a461143_7f5777ca","updated":"2017-02-02 12:06:35.000000000","message":"Done","commit_id":"4a9fb49df6b7b9585b8606554ae8d139472717e6"},{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"0cdb8abd5f6157fb84bf945ca96ebe7fc17161b9","unresolved":false,"context_lines":[{"line_number":50,"context_line":"        \u0027uuid\u0027: wfields.UUIDField(),"},{"line_number":51,"context_line":"        \u0027action_type\u0027: wfields.StringField(nullable\u003dTrue),"},{"line_number":52,"context_line":"        \u0027input_parameters\u0027: wfields.DictField(nullable\u003dTrue),"},{"line_number":53,"context_line":"        \u0027state\u0027: wfields.StringField(nullable\u003dTrue),"},{"line_number":54,"context_line":"        \u0027parents\u0027: wfields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":55,"context_line":"        \u0027action_plan_uuid\u0027: wfields.UUIDField(),"},{"line_number":56,"context_line":"        \u0027action_plan\u0027: wfields.ObjectField(\u0027ActionPlanPayload\u0027),"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a461143_7f405708","line":53,"range":{"start_line":53,"start_character":37,"end_line":53,"end_character":50},"updated":"2017-02-02 09:32:14.000000000","message":"ditto","commit_id":"4a9fb49df6b7b9585b8606554ae8d139472717e6"},{"author":{"_account_id":19055,"name":"Alexander Chadin","email":"joker946@gmail.com","username":"joker946"},"change_message_id":"90c26dba114f334aab562cb605d60a3183f6aa2e","unresolved":false,"context_lines":[{"line_number":50,"context_line":"        \u0027uuid\u0027: wfields.UUIDField(),"},{"line_number":51,"context_line":"        \u0027action_type\u0027: wfields.StringField(nullable\u003dTrue),"},{"line_number":52,"context_line":"        \u0027input_parameters\u0027: wfields.DictField(nullable\u003dTrue),"},{"line_number":53,"context_line":"        \u0027state\u0027: wfields.StringField(nullable\u003dTrue),"},{"line_number":54,"context_line":"        \u0027parents\u0027: wfields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":55,"context_line":"        \u0027action_plan_uuid\u0027: wfields.UUIDField(),"},{"line_number":56,"context_line":"        \u0027action_plan\u0027: wfields.ObjectField(\u0027ActionPlanPayload\u0027),"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a461143_6d3fced6","line":53,"range":{"start_line":53,"start_character":37,"end_line":53,"end_character":50},"in_reply_to":"3a461143_7f405708","updated":"2017-02-02 12:06:35.000000000","message":"Done","commit_id":"4a9fb49df6b7b9585b8606554ae8d139472717e6"},{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"0cdb8abd5f6157fb84bf945ca96ebe7fc17161b9","unresolved":false,"context_lines":[{"line_number":51,"context_line":"        \u0027action_type\u0027: wfields.StringField(nullable\u003dTrue),"},{"line_number":52,"context_line":"        \u0027input_parameters\u0027: wfields.DictField(nullable\u003dTrue),"},{"line_number":53,"context_line":"        \u0027state\u0027: wfields.StringField(nullable\u003dTrue),"},{"line_number":54,"context_line":"        \u0027parents\u0027: wfields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":55,"context_line":"        \u0027action_plan_uuid\u0027: wfields.UUIDField(),"},{"line_number":56,"context_line":"        \u0027action_plan\u0027: wfields.ObjectField(\u0027ActionPlanPayload\u0027),"},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"3a461143_449af2c6","line":54,"range":{"start_line":54,"start_character":27,"end_line":54,"end_character":45},"updated":"2017-02-02 09:32:14.000000000","message":"To be more precise here, I would declare a new type like this:\n\n# In watcher/objects/fields.py\nclass ListOfUuidsField(AutoTypedField):\n    AUTO_TYPE \u003d List(UUID())","commit_id":"4a9fb49df6b7b9585b8606554ae8d139472717e6"},{"author":{"_account_id":19055,"name":"Alexander Chadin","email":"joker946@gmail.com","username":"joker946"},"change_message_id":"90c26dba114f334aab562cb605d60a3183f6aa2e","unresolved":false,"context_lines":[{"line_number":51,"context_line":"        \u0027action_type\u0027: wfields.StringField(nullable\u003dTrue),"},{"line_number":52,"context_line":"        \u0027input_parameters\u0027: wfields.DictField(nullable\u003dTrue),"},{"line_number":53,"context_line":"        \u0027state\u0027: wfields.StringField(nullable\u003dTrue),"},{"line_number":54,"context_line":"        \u0027parents\u0027: wfields.ListOfStringsField(nullable\u003dTrue),"},{"line_number":55,"context_line":"        \u0027action_plan_uuid\u0027: wfields.UUIDField(),"},{"line_number":56,"context_line":"        \u0027action_plan\u0027: wfields.ObjectField(\u0027ActionPlanPayload\u0027),"},{"line_number":57,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"3a461143_8d24fac6","line":54,"range":{"start_line":54,"start_character":27,"end_line":54,"end_character":45},"in_reply_to":"3a461143_449af2c6","updated":"2017-02-02 12:06:35.000000000","message":"Done","commit_id":"4a9fb49df6b7b9585b8606554ae8d139472717e6"}],"watcher/objects/fields.py":[{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"0cdb8abd5f6157fb84bf945ca96ebe7fc17161b9","unresolved":false,"context_lines":[{"line_number":126,"context_line":"    EXCEPTION \u003d \u0027exception\u0027"},{"line_number":127,"context_line":"    DELETE \u003d \u0027delete\u0027"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"    APPLIER \u003d \u0027applier\u0027"},{"line_number":130,"context_line":"    STRATEGY \u003d \u0027strategy\u0027"},{"line_number":131,"context_line":"    PLANNER \u003d \u0027planner\u0027"},{"line_number":132,"context_line":"    EXECUTION \u003d \u0027execution\u0027"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a461143_5f9f1bb4","line":129,"range":{"start_line":129,"start_character":4,"end_line":129,"end_character":23},"updated":"2017-02-02 09:32:14.000000000","message":"Why do you need this new action?\n\nIMHO, you should use the same naming as in the action plan notification with:\n\n- action.execution.start\n- action.execution.end\n- action.execution.error","commit_id":"4a9fb49df6b7b9585b8606554ae8d139472717e6"},{"author":{"_account_id":19055,"name":"Alexander Chadin","email":"joker946@gmail.com","username":"joker946"},"change_message_id":"90c26dba114f334aab562cb605d60a3183f6aa2e","unresolved":false,"context_lines":[{"line_number":126,"context_line":"    EXCEPTION \u003d \u0027exception\u0027"},{"line_number":127,"context_line":"    DELETE \u003d \u0027delete\u0027"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"    APPLIER \u003d \u0027applier\u0027"},{"line_number":130,"context_line":"    STRATEGY \u003d \u0027strategy\u0027"},{"line_number":131,"context_line":"    PLANNER \u003d \u0027planner\u0027"},{"line_number":132,"context_line":"    EXECUTION \u003d \u0027execution\u0027"}],"source_content_type":"text/x-python","patch_set":1,"id":"3a461143_b03bc937","line":129,"range":{"start_line":129,"start_character":4,"end_line":129,"end_character":23},"in_reply_to":"3a461143_5f9f1bb4","updated":"2017-02-02 12:06:35.000000000","message":"Done","commit_id":"4a9fb49df6b7b9585b8606554ae8d139472717e6"}],"watcher/tests/applier/workflow_engine/test_default_workflow_engine.py":[{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"eb1fd6355d436351939463ca0feb09033cd33a51","unresolved":false,"context_lines":[{"line_number":79,"context_line":"            \u0027action_type\u0027: action_type,"},{"line_number":80,"context_line":"            \u0027input_parameters\u0027: parameters,"},{"line_number":81,"context_line":"            \u0027state\u0027: objects.action.State.PENDING,"},{"line_number":82,"context_line":"            \u0027parents\u0027: parents,"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"        }"},{"line_number":85,"context_line":"        new_action \u003d objects.Action(self.context, **action)"}],"source_content_type":"text/x-python","patch_set":7,"id":"1a430d35_244bdfca","line":82,"range":{"start_line":82,"start_character":23,"end_line":82,"end_character":30},"updated":"2017-02-06 18:00:41.000000000","message":"instead of having all create_action() calls with and empty list [] for parents, why not making it the default value here like:\n\n        action \u003d {\n            \u0027uuid\u0027: uuid or utils.generate_uuid(),\n            \u0027action_plan_id\u0027: 0,\n            \u0027action_type\u0027: action_type,\n            \u0027input_parameters\u0027: parameters,\n            \u0027state\u0027: objects.action.State.PENDING,\n            \u0027parents\u0027: parents or [],  # \u003c--\n        }\n\nAnd then you can rewrite the calls like this:\n\n    self.create_action(\"nop\", {\u0027message\u0027: \u0027test\u0027})\n\ninstead of:\n\n    self.create_action(\"nop\", {\u0027message\u0027: \u0027test\u0027}, [])","commit_id":"5979b62a1a3cf2318db583f83c8c8724c0fcfa48"},{"author":{"_account_id":19055,"name":"Alexander Chadin","email":"joker946@gmail.com","username":"joker946"},"change_message_id":"9869c80e6bdb31343d276319a22179ef5ed2c72f","unresolved":false,"context_lines":[{"line_number":79,"context_line":"            \u0027action_type\u0027: action_type,"},{"line_number":80,"context_line":"            \u0027input_parameters\u0027: parameters,"},{"line_number":81,"context_line":"            \u0027state\u0027: objects.action.State.PENDING,"},{"line_number":82,"context_line":"            \u0027parents\u0027: parents,"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"        }"},{"line_number":85,"context_line":"        new_action \u003d objects.Action(self.context, **action)"}],"source_content_type":"text/x-python","patch_set":7,"id":"1a430d35_6933dcab","line":82,"range":{"start_line":82,"start_character":23,"end_line":82,"end_character":30},"in_reply_to":"1a430d35_244bdfca","updated":"2017-02-07 11:52:58.000000000","message":"Done","commit_id":"5979b62a1a3cf2318db583f83c8c8724c0fcfa48"}],"watcher/tests/notifications/test_action_plan_notification.py":[{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"eb1fd6355d436351939463ca0feb09033cd33a51","unresolved":false,"context_lines":[{"line_number":64,"context_line":"        # The 1st notification is because we created the object."},{"line_number":65,"context_line":"        # The 2nd notification is because we created the action plan object."},{"line_number":66,"context_line":"        self.assertEqual(3, self.m_notifier.info.call_count)"},{"line_number":67,"context_line":"        notification \u003d self.m_notifier.info.call_args[1]"},{"line_number":68,"context_line":"        payload \u003d notification[\u0027payload\u0027]"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"        self.assertEqual(\"infra-optim:node0\", self.m_notifier.publisher_id)"}],"source_content_type":"text/x-python","patch_set":7,"id":"1a430d35_64616739","line":67,"updated":"2017-02-06 18:00:41.000000000","message":"ditto the uuid fields should remain","commit_id":"5979b62a1a3cf2318db583f83c8c8724c0fcfa48"},{"author":{"_account_id":19055,"name":"Alexander Chadin","email":"joker946@gmail.com","username":"joker946"},"change_message_id":"9869c80e6bdb31343d276319a22179ef5ed2c72f","unresolved":false,"context_lines":[{"line_number":64,"context_line":"        # The 1st notification is because we created the object."},{"line_number":65,"context_line":"        # The 2nd notification is because we created the action plan object."},{"line_number":66,"context_line":"        self.assertEqual(3, self.m_notifier.info.call_count)"},{"line_number":67,"context_line":"        notification \u003d self.m_notifier.info.call_args[1]"},{"line_number":68,"context_line":"        payload \u003d notification[\u0027payload\u0027]"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"        self.assertEqual(\"infra-optim:node0\", self.m_notifier.publisher_id)"}],"source_content_type":"text/x-python","patch_set":7,"id":"1a430d35_1c73934e","line":67,"in_reply_to":"1a430d35_64616739","updated":"2017-02-07 11:52:58.000000000","message":"Done","commit_id":"5979b62a1a3cf2318db583f83c8c8724c0fcfa48"}]}
