def _get_target(self, input_dict): ctx_view = data_flow.ContextView( input_dict, self.ctx, data_flow.get_workflow_environment_dict(self.wf_ex), self.wf_ex.context, self.wf_ex.input) return expr.evaluate_recursively(self.task_spec.get_target(), ctx_view)
def _find_next_tasks(self, task_ex, ctx=None): t_state = task_ex.state t_name = task_ex.name ctx_view = data_flow.ContextView( data_flow.get_current_task_dict(task_ex), ctx or data_flow.evaluate_task_outbound_context(task_ex), data_flow.get_workflow_environment_dict(self.wf_ex), self.wf_ex.context, self.wf_ex.input) # [(task_name, params, 'on-success'|'on-error'|'on-complete'), ...] result = [] def process_clause(clause, event_name): task_tuples = self._find_next_tasks_for_clause(clause, ctx_view) for t in task_tuples: result.append((t[0], t[1], event_name)) if t_state == states.SUCCESS: process_clause(self.wf_spec.get_on_success_clause(t_name), 'on-success') elif t_state == states.ERROR: process_clause(self.wf_spec.get_on_error_clause(t_name), 'on-error') if states.is_completed(t_state) and not states.is_cancelled(t_state): process_clause(self.wf_spec.get_on_complete_clause(t_name), 'on-complete') return result
def _evaluate_expression(self, expression, ctx=None): ctx_view = data_flow.ContextView( data_flow.get_current_task_dict(self.task_ex), data_flow.get_workflow_environment_dict(self.wf_ex), ctx or self.ctx, self.wf_ex.context, self.wf_ex.input) return expr.evaluate_recursively(expression, ctx_view)
def _find_next_tasks(self, task_ex, ctx): t_n = task_ex.name t_s = task_ex.state ctx_view = data_flow.ContextView( data_flow.get_current_task_dict(task_ex), ctx, data_flow.get_workflow_environment_dict(self.wf_ex), self.wf_ex.context, self.wf_ex.input) # [(task_name, params, 'on-success'|'on-error'|'on-complete'), ...] result = [] if t_s == states.ERROR: for name, cond, params in self.wf_spec.get_on_error_clause(t_n): if not cond or expr.evaluate(cond, ctx_view): params = expr.evaluate_recursively(params, ctx_view) result.append((name, params, 'on-error')) if t_s == states.SUCCESS: for name, cond, params in self.wf_spec.get_on_success_clause(t_n): if not cond or expr.evaluate(cond, ctx_view): params = expr.evaluate_recursively(params, ctx_view) result.append((name, params, 'on-success')) if states.is_completed(t_s) and not states.is_cancelled(t_s): for name, cond, params in self.wf_spec.get_on_complete_clause(t_n): if not cond or expr.evaluate(cond, ctx_view): params = expr.evaluate_recursively(params, ctx_view) result.append((name, params, 'on-complete')) return result
def _prepare_input(self, input_dict): if self._prepared_input is not None: return self._prepared_input base_input_dict = input_dict for action_def in self.adhoc_action_defs: action_spec = spec_parser.get_action_spec(action_def.spec) for k, v in action_spec.get_input().items(): if (k not in base_input_dict or base_input_dict[k] is utils.NotDefined): base_input_dict[k] = v base_input_expr = action_spec.get_base_input() if base_input_expr: wf_ex = (self.task_ex.workflow_execution if self.task_ex else None) ctx_view = data_flow.ContextView( base_input_dict, self.task_ctx, data_flow.get_workflow_environment_dict(wf_ex), self.wf_ctx) base_input_dict = expr.evaluate_recursively( base_input_expr, ctx_view) else: base_input_dict = {} self._prepared_input = super(AdHocAction, self)._prepare_input(base_input_dict) return self._prepared_input
def _evaluate_expression(self, expression, ctx=None): ctx_view = data_flow.ContextView( data_flow.get_current_task_dict(self.task_ex), data_flow.get_workflow_environment_dict(self.wf_ex), ctx or self.ctx, self.wf_ex.context, self.wf_ex.input ) return expr.evaluate_recursively(expression, ctx_view)
def get_expression_context(self, ctx=None): assert self.task_ex return data_flow.ContextView( data_flow.get_current_task_dict(self.task_ex), data_flow.get_workflow_environment_dict(self.wf_ex), ctx or {}, self.task_ex.in_context, self.wf_ex.context, self.wf_ex.input, )
def schedule(self, input_dict, target, index=0, desc='', safe_rerun=False, timeout=None): assert not self.action_ex self.action_desc.check_parameters(input_dict) wf_ex = self.task_ex.workflow_execution if self.task_ex else None wf_ctx = data_flow.ContextView( self.task_ctx, data_flow.get_workflow_environment_dict(wf_ex), wf_ex.context if wf_ex else {}) try: action = self.action_desc.instantiate(input_dict, wf_ctx) except Exception: raise exc.InvalidActionException( 'Failed to instantiate an action' ' [action_desc=%s, input_dict=%s]' % (self.action_desc, input_dict)) # Assign the action execution ID here to minimize database calls. # Otherwise, the input property of the action execution DB object needs # to be updated with the action execution ID after the action execution # DB object is created. action_ex_id = utils.generate_unicode_uuid() self._create_action_execution(input_dict, self._prepare_runtime_context( index, safe_rerun), desc=desc, action_ex_id=action_ex_id, is_sync=action.is_sync()) def _run_action(): executor = exe.get_executor(cfg.CONF.executor.type) return executor.run_action( action, self.action_ex.id if self.action_ex is not None else None, safe_rerun, self._prepare_execution_context(), target=target, timeout=timeout) # Register an asynchronous command to run the action # on an executor outside of the main DB transaction. post_tx_queue.register_operation(_run_action)
def all_errors_handled(self): for t_ex in lookup_utils.find_error_task_executions(self.wf_ex.id): ctx_view = data_flow.ContextView( data_flow.evaluate_task_outbound_context(t_ex), data_flow.get_workflow_environment_dict(self.wf_ex), self.wf_ex.context, self.wf_ex.input) tasks_on_error = self._find_next_tasks_for_clause( self.wf_spec.get_on_error_clause(t_ex.name), ctx_view) if not tasks_on_error: return False return True
def after_task_complete(self, task_ex, task_spec): """Called right after task completes. :param task_ex: Completed task DB model. :param task_spec: Completed task specification. """ wf_ex = task_ex.workflow_execution ctx_view = data_flow.ContextView( task_ex.in_context, data_flow.get_workflow_environment_dict(wf_ex), wf_ex.context, wf_ex.input) data_flow.evaluate_object_fields(self, ctx_view) self._validate()
def before_task_start(self, task_ex, task_spec): """Called right before task start. :param task_ex: DB model for task that is about to start. :param task_spec: Task specification. """ wf_ex = task_ex.workflow_execution ctx_view = data_flow.ContextView( task_ex.in_context, data_flow.get_workflow_environment_dict(wf_ex), wf_ex.context, wf_ex.input) data_flow.evaluate_object_fields(self, ctx_view) self._validate()
def _get_target(self, input_dict): if not self.task_spec.get_target(): return None ctx_view = data_flow.ContextView( input_dict, self.ctx, data_flow.get_workflow_environment_dict(self.wf_ex), self.wf_ex.context, self.wf_ex.input ) return expr.evaluate_recursively( self.task_spec.get_target(), ctx_view )
def get_published_global(task_ex, wf_ex=None): if task_ex.state not in [states.SUCCESS, states.ERROR]: return if wf_ex is None: wf_ex = task_ex.workflow_execution expr_ctx = ContextView(get_current_task_dict(task_ex), task_ex.in_context, get_workflow_environment_dict(wf_ex), wf_ex.context, wf_ex.input) task_spec = spec_parser.get_task_spec(task_ex.spec) publish_spec = task_spec.get_publish(task_ex.state) if not publish_spec: return global_vars = publish_spec.get_global() return expr.evaluate_recursively(global_vars, expr_ctx)
def _prepare_input(self, input_dict): if self._prepared_input is not None: return self._prepared_input base_input_dict = input_dict for action_def in self.adhoc_action_defs: action_spec = spec_parser.get_action_spec(action_def.spec) for k, v in action_spec.get_input().items(): if (k not in base_input_dict or base_input_dict[k] is utils.NotDefined): base_input_dict[k] = v base_input_expr = action_spec.get_base_input() if base_input_expr: wf_ex = ( self.task_ex.workflow_execution if self.task_ex else None ) ctx_view = data_flow.ContextView( base_input_dict, self.task_ctx, data_flow.get_workflow_environment_dict(wf_ex), self.wf_ctx ) base_input_dict = expr.evaluate_recursively( base_input_expr, ctx_view ) else: base_input_dict = {} self._prepared_input = super(AdHocAction, self)._prepare_input( base_input_dict ) return self._prepared_input
def _find_next_tasks(self, task_ex, ctx=None): t_state = task_ex.state t_name = task_ex.name ctx_view = data_flow.ContextView( data_flow.get_current_task_dict(task_ex), ctx or data_flow.evaluate_task_outbound_context(task_ex), data_flow.get_workflow_environment_dict(self.wf_ex), self.wf_ex.context, self.wf_ex.input ) # [(task_name, params, 'on-success'|'on-error'|'on-complete'), ...] result = [] def process_clause(clause, event_name): task_tuples = self._find_next_tasks_for_clause(clause, ctx_view) for t in task_tuples: result.append((t[0], t[1], event_name)) if t_state == states.SUCCESS: process_clause( self.wf_spec.get_on_success_clause(t_name), 'on-success' ) elif t_state == states.ERROR: process_clause( self.wf_spec.get_on_error_clause(t_name), 'on-error' ) if states.is_completed(t_state) and not states.is_cancelled(t_state): process_clause( self.wf_spec.get_on_complete_clause(t_name), 'on-complete' ) return result