def test_add_or_update_given_trace_context(self): trace_context = {'id_': str(self.trace_empty.id)} action_execution_id = 'action_execution_1' rule_id = 'rule_1' trigger_instance_id = 'trigger_instance_1' trace_service.add_or_update_given_trace_context( trace_context, action_executions=[action_execution_id], rules=[rule_id], trigger_instances=[trigger_instance_id]) retrieved_trace_db = Trace.get_by_id(self.trace_empty.id) self.assertEqual(len(retrieved_trace_db.action_executions), 1, 'Expected updated action_executions.') self.assertEqual(retrieved_trace_db.action_executions[0].object_id, action_execution_id, 'Expected updated action_executions.') self.assertEqual(len(retrieved_trace_db.rules), 1, 'Expected updated rules.') self.assertEqual(retrieved_trace_db.rules[0].object_id, rule_id, 'Expected updated rules.') self.assertEqual(len(retrieved_trace_db.trigger_instances), 1, 'Expected updated trigger_instances.') self.assertEqual(retrieved_trace_db.trigger_instances[0].object_id, trigger_instance_id, 'Expected updated trigger_instances.') Trace.delete(retrieved_trace_db) Trace.add_or_update(self.trace_empty)
def process(self, pre_ack_response): trigger_instance, message = self._decompose_pre_ack_process_response( pre_ack_response) if not trigger_instance: raise ValueError("No trigger_instance provided for processing.") get_driver().inc_counter("trigger.%s.processed" % (trigger_instance.trigger)) try: # Use trace_context from the message and if not found create a new context # and use the trigger_instance.id as trace_tag. trace_context = message.get(TRACE_CONTEXT, None) if not trace_context: trace_context = { TRACE_ID: "trigger_instance-%s" % str(trigger_instance.id) } # add a trace or update an existing trace with trigger_instance trace_service.add_or_update_given_trace_context( trace_context=trace_context, trigger_instances=[ trace_service.get_trace_component_for_trigger_instance( trigger_instance) ], ) container_utils.update_trigger_instance_status( trigger_instance, trigger_constants.TRIGGER_INSTANCE_PROCESSING) with CounterWithTimer(key="rule.processed"): with Timer(key="trigger.%s.processed" % (trigger_instance.trigger)): self.rules_engine.handle_trigger_instance(trigger_instance) container_utils.update_trigger_instance_status( trigger_instance, trigger_constants.TRIGGER_INSTANCE_PROCESSED) except: # TODO : Capture the reason for failure. container_utils.update_trigger_instance_status( trigger_instance, trigger_constants.TRIGGER_INSTANCE_PROCESSING_FAILED) # This could be a large message but at least in case of an exception # we get to see more context. # Beyond this point code cannot really handle the exception anyway so # eating up the exception. LOG.exception("Failed to handle trigger_instance %s.", trigger_instance) return
def test_triggered_execution(self): docs = { 'trigger_type': copy.deepcopy(fixture.ARTIFACTS['trigger_type']), 'trigger': copy.deepcopy(fixture.ARTIFACTS['trigger']), 'rule': copy.deepcopy(fixture.ARTIFACTS['rule']), 'trigger_instance': copy.deepcopy(fixture.ARTIFACTS['trigger_instance'])} # Trigger an action execution. trigger_type = TriggerType.add_or_update( TriggerTypeAPI.to_model(TriggerTypeAPI(**docs['trigger_type']))) trigger = Trigger.add_or_update(TriggerAPI.to_model(TriggerAPI(**docs['trigger']))) rule = RuleAPI.to_model(RuleAPI(**docs['rule'])) rule.trigger = reference.get_str_resource_ref_from_model(trigger) rule = Rule.add_or_update(rule) trigger_instance = TriggerInstance.add_or_update( TriggerInstanceAPI.to_model(TriggerInstanceAPI(**docs['trigger_instance']))) trace_service.add_or_update_given_trace_context( trace_context={'trace_tag': 'test_triggered_execution_trace'}, trigger_instances=[str(trigger_instance.id)]) enforcer = RuleEnforcer(trigger_instance, rule) enforcer.enforce() # Wait for the action execution to complete and then confirm outcome. liveaction = LiveAction.get(context__trigger_instance__id=str(trigger_instance.id)) self.assertIsNotNone(liveaction) liveaction = self._wait_on_status(liveaction, action_constants.LIVEACTION_STATUS_FAILED) execution = self._get_action_execution( liveaction__id=str(liveaction.id), raise_exception=True ) self.assertDictEqual(execution.trigger, vars(TriggerAPI.from_model(trigger))) self.assertDictEqual(execution.trigger_type, vars(TriggerTypeAPI.from_model(trigger_type))) self.assertDictEqual(execution.trigger_instance, vars(TriggerInstanceAPI.from_model(trigger_instance))) self.assertDictEqual(execution.rule, vars(RuleAPI.from_model(rule))) action = action_utils.get_action_by_ref(liveaction.action) self.assertDictEqual(execution.action, vars(ActionAPI.from_model(action))) runner = RunnerType.get_by_name(action.runner_type['name']) self.assertDictEqual(execution.runner, vars(RunnerTypeAPI.from_model(runner))) liveaction = LiveAction.get_by_id(str(liveaction.id)) self.assertEqual(execution.start_timestamp, liveaction.start_timestamp) self.assertEqual(execution.end_timestamp, liveaction.end_timestamp) self.assertEqual(execution.result, liveaction.result) self.assertEqual(execution.status, liveaction.status) self.assertEqual(execution.context, liveaction.context) self.assertEqual(execution.liveaction['callback'], liveaction.callback) self.assertEqual(execution.liveaction['action'], liveaction.action)
def test_add_or_update_given_trace_context_new(self): trace_context = {'trace_tag': 'awesome_test_trace'} action_execution_id = 'action_execution_1' rule_id = 'rule_1' trigger_instance_id = 'trigger_instance_1' pre_add_or_update_traces = len(Trace.get_all()) trace_db = trace_service.add_or_update_given_trace_context( trace_context, action_executions=[action_execution_id], rules=[rule_id], trigger_instances=[trigger_instance_id]) post_add_or_update_traces = len(Trace.get_all()) self.assertTrue(post_add_or_update_traces > pre_add_or_update_traces, 'Expected new Trace to be created.') retrieved_trace_db = Trace.get_by_id(trace_db.id) self.assertEqual(len(retrieved_trace_db.action_executions), 1, 'Expected updated action_executions.') self.assertEqual(retrieved_trace_db.action_executions[0].object_id, action_execution_id, 'Expected updated action_executions.') self.assertEqual(len(retrieved_trace_db.rules), 1, 'Expected updated rules.') self.assertEqual(retrieved_trace_db.rules[0].object_id, rule_id, 'Expected updated rules.') self.assertEqual(len(retrieved_trace_db.trigger_instances), 1, 'Expected updated trigger_instances.') self.assertEqual(retrieved_trace_db.trigger_instances[0].object_id, trigger_instance_id, 'Expected updated trigger_instances.') Trace.delete(retrieved_trace_db)
def test_add_or_update_given_trace_context_new_with_causals(self): trace_context = {'trace_tag': 'causal_test_trace'} action_execution_id = 'action_execution_1' rule_id = 'rule_1' trigger_instance_id = 'trigger_instance_1' pre_add_or_update_traces = len(Trace.get_all()) trace_db = trace_service.add_or_update_given_trace_context( trace_context, action_executions=[{ 'id': action_execution_id, 'caused_by': { 'id': '%s:%s' % (rule_id, trigger_instance_id), 'type': 'rule' } }], rules=[{ 'id': rule_id, 'caused_by': { 'id': trigger_instance_id, 'type': 'trigger-instance' } }], trigger_instances=[trigger_instance_id]) post_add_or_update_traces = len(Trace.get_all()) self.assertTrue(post_add_or_update_traces > pre_add_or_update_traces, 'Expected new Trace to be created.') retrieved_trace_db = Trace.get_by_id(trace_db.id) self.assertEqual(len(retrieved_trace_db.action_executions), 1, 'Expected updated action_executions.') self.assertEqual(retrieved_trace_db.action_executions[0].object_id, action_execution_id, 'Expected updated action_executions.') self.assertEqual(retrieved_trace_db.action_executions[0].caused_by, { 'id': '%s:%s' % (rule_id, trigger_instance_id), 'type': 'rule' }, 'Expected updated action_executions.') self.assertEqual(len(retrieved_trace_db.rules), 1, 'Expected updated rules.') self.assertEqual(retrieved_trace_db.rules[0].object_id, rule_id, 'Expected updated rules.') self.assertEqual(retrieved_trace_db.rules[0].caused_by, { 'id': trigger_instance_id, 'type': 'trigger-instance' }, 'Expected updated rules.') self.assertEqual(len(retrieved_trace_db.trigger_instances), 1, 'Expected updated trigger_instances.') self.assertEqual(retrieved_trace_db.trigger_instances[0].object_id, trigger_instance_id, 'Expected updated trigger_instances.') self.assertEqual(retrieved_trace_db.trigger_instances[0].caused_by, {}, 'Expected updated rules.') Trace.delete(retrieved_trace_db)
def process(self, instance): trigger = instance['trigger'] payload = instance['payload'] trigger_instance = None try: trigger_instance = container_utils.create_trigger_instance( trigger, payload or {}, date_utils.get_datetime_utc_now(), raise_on_no_trigger=True) except: # We got a trigger ref but we were unable to create a trigger instance. # This could be because a trigger object wasn't found in db for the ref. LOG.exception('Failed to create trigger_instance %s.', instance) return if trigger_instance: try: # Use trace_context from the instance and if not found create a new context # and use the trigger_instance.id as trace_tag. trace_context = instance.get(TRACE_CONTEXT, None) if not trace_context: trace_context = { TRACE_ID: 'trigger_instance-%s' % str(trigger_instance.id) } # add a trace or update an existing trace with trigger_instance trace_service.add_or_update_given_trace_context( trace_context=trace_context, trigger_instances=[ trace_service.get_trace_component_for_trigger_instance( trigger_instance) ]) self.rules_engine.handle_trigger_instance(trigger_instance) except: # This could be a large message but at least in case of an exception # we get to see more context. # Beyond this point code cannot really handle the exception anyway so # eating up the exception. LOG.exception('Failed to handle trigger_instance %s.', instance) return
def process(self, pre_ack_response): trigger_instance, message = self._decompose_pre_ack_process_response(pre_ack_response) if not trigger_instance: raise ValueError('No trigger_instance provided for processing.') get_driver().inc_counter('trigger.%s.processed' % (trigger_instance.trigger)) try: # Use trace_context from the message and if not found create a new context # and use the trigger_instance.id as trace_tag. trace_context = message.get(TRACE_CONTEXT, None) if not trace_context: trace_context = { TRACE_ID: 'trigger_instance-%s' % str(trigger_instance.id) } # add a trace or update an existing trace with trigger_instance trace_service.add_or_update_given_trace_context( trace_context=trace_context, trigger_instances=[ trace_service.get_trace_component_for_trigger_instance(trigger_instance) ] ) container_utils.update_trigger_instance_status( trigger_instance, trigger_constants.TRIGGER_INSTANCE_PROCESSING) with CounterWithTimer(key='rule.processed'): with Timer(key='trigger.%s.processed' % (trigger_instance.trigger)): self.rules_engine.handle_trigger_instance(trigger_instance) container_utils.update_trigger_instance_status( trigger_instance, trigger_constants.TRIGGER_INSTANCE_PROCESSED) except: # TODO : Capture the reason for failure. container_utils.update_trigger_instance_status( trigger_instance, trigger_constants.TRIGGER_INSTANCE_PROCESSING_FAILED) # This could be a large message but at least in case of an exception # we get to see more context. # Beyond this point code cannot really handle the exception anyway so # eating up the exception. LOG.exception('Failed to handle trigger_instance %s.', trigger_instance) return
def process(self, instance): trigger = instance['trigger'] payload = instance['payload'] trigger_instance = None try: trigger_instance = container_utils.create_trigger_instance( trigger, payload or {}, date_utils.get_datetime_utc_now(), raise_on_no_trigger=True) except: # We got a trigger ref but we were unable to create a trigger instance. # This could be because a trigger object wasn't found in db for the ref. LOG.exception('Failed to create trigger_instance %s.', instance) return if trigger_instance: try: # Use trace_context from the instance and if not found create a new context # and use the trigger_instance.id as trace_tag. trace_context = instance.get(TRACE_CONTEXT, None) if not trace_context: trace_context = { TRACE_ID: 'trigger_instance-%s' % str(trigger_instance.id) } # add a trace or update an existing trace with trigger_instance trace_service.add_or_update_given_trace_context( trace_context=trace_context, trigger_instances=[ trace_service.get_trace_component_for_trigger_instance(trigger_instance) ]) self.rules_engine.handle_trigger_instance(trigger_instance) except: # This could be a large message but at least in case of an exception # we get to see more context. # Beyond this point code cannot really handle the exception anyway so # eating up the exception. LOG.exception('Failed to handle trigger_instance %s.', instance) return
def test_add_or_update_given_trace_context_new(self): trace_context = {"trace_tag": "awesome_test_trace"} action_execution_id = "action_execution_1" rule_id = "rule_1" trigger_instance_id = "trigger_instance_1" pre_add_or_update_traces = len(Trace.get_all()) trace_db = trace_service.add_or_update_given_trace_context( trace_context, action_executions=[action_execution_id], rules=[rule_id], trigger_instances=[trigger_instance_id], ) post_add_or_update_traces = len(Trace.get_all()) self.assertTrue( post_add_or_update_traces > pre_add_or_update_traces, "Expected new Trace to be created.", ) retrieved_trace_db = Trace.get_by_id(trace_db.id) self.assertEqual( len(retrieved_trace_db.action_executions), 1, "Expected updated action_executions.", ) self.assertEqual( retrieved_trace_db.action_executions[0].object_id, action_execution_id, "Expected updated action_executions.", ) self.assertEqual(len(retrieved_trace_db.rules), 1, "Expected updated rules.") self.assertEqual(retrieved_trace_db.rules[0].object_id, rule_id, "Expected updated rules.") self.assertEqual( len(retrieved_trace_db.trigger_instances), 1, "Expected updated trigger_instances.", ) self.assertEqual( retrieved_trace_db.trigger_instances[0].object_id, trigger_instance_id, "Expected updated trigger_instances.", ) Trace.delete(retrieved_trace_db)
def test_add_or_update_given_trace_context_new_with_causals(self): trace_context = {'trace_tag': 'causal_test_trace'} action_execution_id = 'action_execution_1' rule_id = 'rule_1' trigger_instance_id = 'trigger_instance_1' pre_add_or_update_traces = len(Trace.get_all()) trace_db = trace_service.add_or_update_given_trace_context( trace_context, action_executions=[{'id': action_execution_id, 'caused_by': {'id': '%s:%s' % (rule_id, trigger_instance_id), 'type': 'rule'}}], rules=[{'id': rule_id, 'caused_by': {'id': trigger_instance_id, 'type': 'trigger-instance'}}], trigger_instances=[trigger_instance_id]) post_add_or_update_traces = len(Trace.get_all()) self.assertTrue(post_add_or_update_traces > pre_add_or_update_traces, 'Expected new Trace to be created.') retrieved_trace_db = Trace.get_by_id(trace_db.id) self.assertEqual(len(retrieved_trace_db.action_executions), 1, 'Expected updated action_executions.') self.assertEqual(retrieved_trace_db.action_executions[0].object_id, action_execution_id, 'Expected updated action_executions.') self.assertEqual(retrieved_trace_db.action_executions[0].caused_by, {'id': '%s:%s' % (rule_id, trigger_instance_id), 'type': 'rule'}, 'Expected updated action_executions.') self.assertEqual(len(retrieved_trace_db.rules), 1, 'Expected updated rules.') self.assertEqual(retrieved_trace_db.rules[0].object_id, rule_id, 'Expected updated rules.') self.assertEqual(retrieved_trace_db.rules[0].caused_by, {'id': trigger_instance_id, 'type': 'trigger-instance'}, 'Expected updated rules.') self.assertEqual(len(retrieved_trace_db.trigger_instances), 1, 'Expected updated trigger_instances.') self.assertEqual(retrieved_trace_db.trigger_instances[0].object_id, trigger_instance_id, 'Expected updated trigger_instances.') self.assertEqual(retrieved_trace_db.trigger_instances[0].caused_by, {}, 'Expected updated rules.') Trace.delete(retrieved_trace_db)
def test_triggered_execution(self): docs = { "trigger_type": copy.deepcopy(fixture.ARTIFACTS["trigger_type"]), "trigger": copy.deepcopy(fixture.ARTIFACTS["trigger"]), "rule": copy.deepcopy(fixture.ARTIFACTS["rule"]), "trigger_instance": copy.deepcopy(fixture.ARTIFACTS["trigger_instance"]), } # Trigger an action execution. trigger_type = TriggerType.add_or_update( TriggerTypeAPI.to_model(TriggerTypeAPI(**docs["trigger_type"]))) trigger = Trigger.add_or_update( TriggerAPI.to_model(TriggerAPI(**docs["trigger"]))) rule = RuleAPI.to_model(RuleAPI(**docs["rule"])) rule.trigger = reference.get_str_resource_ref_from_model(trigger) rule = Rule.add_or_update(rule) trigger_instance = TriggerInstance.add_or_update( TriggerInstanceAPI.to_model( TriggerInstanceAPI(**docs["trigger_instance"]))) trace_service.add_or_update_given_trace_context( trace_context={"trace_tag": "test_triggered_execution_trace"}, trigger_instances=[str(trigger_instance.id)], ) enforcer = RuleEnforcer(trigger_instance, rule) enforcer.enforce() # Wait for the action execution to complete and then confirm outcome. liveaction = LiveAction.get( context__trigger_instance__id=str(trigger_instance.id)) self.assertIsNotNone(liveaction) liveaction = self._wait_on_status( liveaction, action_constants.LIVEACTION_STATUS_FAILED) execution = self._get_action_execution(liveaction__id=str( liveaction.id), raise_exception=True) self.assertDictEqual(execution.trigger, vars(TriggerAPI.from_model(trigger))) self.assertDictEqual(execution.trigger_type, vars(TriggerTypeAPI.from_model(trigger_type))) self.assertDictEqual( execution.trigger_instance, vars(TriggerInstanceAPI.from_model(trigger_instance)), ) self.assertDictEqual(execution.rule, vars(RuleAPI.from_model(rule))) action = action_utils.get_action_by_ref(liveaction.action) self.assertDictEqual(execution.action, vars(ActionAPI.from_model(action))) runner = RunnerType.get_by_name(action.runner_type["name"]) self.assertDictEqual(execution.runner, vars(RunnerTypeAPI.from_model(runner))) liveaction = LiveAction.get_by_id(str(liveaction.id)) self.assertEqual(execution.start_timestamp, liveaction.start_timestamp) # NOTE: Timestamp of liveaction and execution may be a bit different, depending on how long # it takes to persist each object in the database self.assertEqual( execution.end_timestamp.replace(microsecond=0), liveaction.end_timestamp.replace(microsecond=0), ) self.assertEqual(execution.result, liveaction.result) self.assertEqual(execution.status, liveaction.status) self.assertEqual(execution.context, liveaction.context) self.assertEqual(execution.liveaction["callback"], liveaction.callback) self.assertEqual(execution.liveaction["action"], liveaction.action)
def test_add_or_update_given_trace_context_new_with_causals(self): trace_context = {"trace_tag": "causal_test_trace"} action_execution_id = "action_execution_1" rule_id = "rule_1" trigger_instance_id = "trigger_instance_1" pre_add_or_update_traces = len(Trace.get_all()) trace_db = trace_service.add_or_update_given_trace_context( trace_context, action_executions=[{ "id": action_execution_id, "caused_by": { "id": "%s:%s" % (rule_id, trigger_instance_id), "type": "rule", }, }], rules=[{ "id": rule_id, "caused_by": { "id": trigger_instance_id, "type": "trigger-instance", }, }], trigger_instances=[trigger_instance_id], ) post_add_or_update_traces = len(Trace.get_all()) self.assertTrue( post_add_or_update_traces > pre_add_or_update_traces, "Expected new Trace to be created.", ) retrieved_trace_db = Trace.get_by_id(trace_db.id) self.assertEqual( len(retrieved_trace_db.action_executions), 1, "Expected updated action_executions.", ) self.assertEqual( retrieved_trace_db.action_executions[0].object_id, action_execution_id, "Expected updated action_executions.", ) self.assertEqual( retrieved_trace_db.action_executions[0].caused_by, { "id": "%s:%s" % (rule_id, trigger_instance_id), "type": "rule" }, "Expected updated action_executions.", ) self.assertEqual(len(retrieved_trace_db.rules), 1, "Expected updated rules.") self.assertEqual(retrieved_trace_db.rules[0].object_id, rule_id, "Expected updated rules.") self.assertEqual( retrieved_trace_db.rules[0].caused_by, { "id": trigger_instance_id, "type": "trigger-instance" }, "Expected updated rules.", ) self.assertEqual( len(retrieved_trace_db.trigger_instances), 1, "Expected updated trigger_instances.", ) self.assertEqual( retrieved_trace_db.trigger_instances[0].object_id, trigger_instance_id, "Expected updated trigger_instances.", ) self.assertEqual( retrieved_trace_db.trigger_instances[0].caused_by, {}, "Expected updated rules.", ) Trace.delete(retrieved_trace_db)