mistral/mistral/engine/action_handler.py

107 lines
3.3 KiB
Python

# Copyright 2015 - Mirantis, Inc.
# Copyright 2016 - Brocade Communications Systems, Inc.
# Copyright 2020 Nokia Software.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_log import log as logging
from osprofiler import profiler
import traceback as tb
from mistral.db.v2.sqlalchemy import models
from mistral.engine import actions
from mistral.engine import task_handler
from mistral import exceptions as exc
LOG = logging.getLogger(__name__)
@profiler.trace('action-handler-on-action-complete', hide_args=True)
def on_action_complete(action_ex, result):
task_ex = action_ex.task_execution
action = _build_action(action_ex)
try:
action.complete(result)
except exc.MistralException as e:
msg = (
"Failed to complete action [error=%s, action=%s, task=%s]:\n%s"
% (e, action_ex.name, task_ex.name, tb.format_exc())
)
LOG.error(msg)
action.fail(msg)
if task_ex:
task_handler.force_fail_task(task_ex, msg)
return
if task_ex:
task_handler.schedule_on_action_complete(action_ex)
@profiler.trace('action-handler-on-action-update', hide_args=True)
def on_action_update(action_ex, state):
task_ex = action_ex.task_execution
action = _build_action(action_ex)
try:
action.update(state)
except exc.MistralException as e:
# If the update of the action execution fails, do not fail
# the action execution. Log the exception and re-raise the
# exception.
msg = (
"Failed to update action [error=%s, action=%s, task=%s]:\n%s"
% (e, action_ex.name, task_ex.name, tb.format_exc())
)
LOG.error(msg)
raise
if task_ex:
task_handler.schedule_on_action_update(action_ex)
@profiler.trace('action-handler-build-action', hide_args=True)
def _build_action(action_ex):
if isinstance(action_ex, models.WorkflowExecution):
return actions.WorkflowAction(wf_name=action_ex.name,
action_ex=action_ex)
adhoc_action_name = action_ex.runtime_context.get('adhoc_action_name')
if adhoc_action_name:
action_def = actions.resolve_action_definition(
adhoc_action_name,
namespace=action_ex.workflow_namespace
)
return actions.AdHocAction(action_def, action_ex=action_ex)
action_def = actions.resolve_action_definition(action_ex.name)
return actions.PythonAction(action_def, action_ex=action_ex)
def build_action_by_name(action_name, namespace=''):
action_def = actions.resolve_action_definition(action_name,
namespace=namespace)
action_cls = (actions.PythonAction if not action_def.spec
else actions.AdHocAction)
return action_cls(action_def)