OSMENG-994 Determine the content for Activity errors
Change-Id: Id86f1fa5a5adadac333842d81d9ba4f2dff69d8f
Signed-off-by: Gulsum Atici <gulsum.atici@canonical.com>
diff --git a/osm_lcm/temporal/lcm_workflows.py b/osm_lcm/temporal/lcm_workflows.py
index 9ab8e5d..9ee94d8 100644
--- a/osm_lcm/temporal/lcm_workflows.py
+++ b/osm_lcm/temporal/lcm_workflows.py
@@ -18,6 +18,9 @@
import traceback
from abc import ABC, abstractmethod
from datetime import timedelta
+from temporalio import workflow
+from temporalio.common import RetryPolicy
+from temporalio.exceptions import ActivityError, ChildWorkflowError
from osm_common.dataclasses.temporal_dataclasses import (
LcmOperationState,
@@ -29,9 +32,6 @@
ACTIVITY_UPDATE_LCM_OPERATION_STATE,
WORKFLOW_NSLCM_NO_OP,
)
-from temporalio import workflow
-from temporalio.common import RetryPolicy
-from temporalio.exceptions import ActivityError
class LcmOperationWorkflow(ABC):
@@ -73,23 +73,37 @@
await self.update_operation_state(LcmOperationState.PROCESSING)
try:
await self.workflow(input=input)
+
except ActivityError as e:
- # TODO: Deteremine the best content for Activity Errors OSM-994
- self.logger.exception(e)
+ err_details = str(e.cause.with_traceback(e.__traceback__))
+ self.logger.error(err_details)
await self.update_operation_state(
LcmOperationState.FAILED,
error_message=str(e.cause.message),
- detailed_status=str(e.cause.with_traceback(e.__traceback__)),
+ detailed_status=err_details,
)
raise e
+
+ except ChildWorkflowError as e:
+ err_details = str(e.cause.cause.cause.with_traceback(e.cause.__traceback__))
+ self.logger.error(err_details)
+ await self.update_operation_state(
+ LcmOperationState.FAILED,
+ error_message=str(e.cause.cause.message),
+ detailed_status=err_details,
+ )
+ raise e
+
except Exception as e:
- self.logger.exception(e)
- self.update_operation_state(
+ err_details = str(traceback.format_exc())
+ self.logger.error(err_details)
+ await self.update_operation_state(
LcmOperationState.FAILED,
error_message=str(e),
- detailed_status=traceback.format_exc(),
+ detailed_status=err_details,
)
raise e
+
await self.update_operation_state(LcmOperationState.COMPLETED)
async def update_operation_state(
diff --git a/osm_lcm/temporal/ns_workflows.py b/osm_lcm/temporal/ns_workflows.py
index 9a4e0ee..343a9c9 100644
--- a/osm_lcm/temporal/ns_workflows.py
+++ b/osm_lcm/temporal/ns_workflows.py
@@ -15,6 +15,10 @@
# limitations under the License.
import asyncio
+from temporalio import workflow
+from temporalio.converter import value_to_type
+from temporalio.exceptions import ActivityError, ChildWorkflowError
+import traceback
from osm_common.dataclasses.temporal_dataclasses import (
GetVnfRecordIdsInput,
@@ -32,10 +36,6 @@
WORKFLOW_NS_INSTANTIATE,
WORKFLOW_VNF_INSTANTIATE,
)
-from temporalio import workflow
-from temporalio.converter import value_to_type
-from temporalio.exceptions import ActivityError
-
from osm_lcm.temporal.lcm_workflows import LcmOperationWorkflow
@@ -88,16 +88,23 @@
)
except ActivityError as e:
- await self.update_ns_state(ns_uuid, NsState.INSTANTIATED, e.cause.message)
- self.logger.error(
- f"{WORKFLOW_NS_INSTANTIATE} failed with {str(e.cause.message)}"
- )
+ err_details = str(e.cause.with_traceback(e.__traceback__))
+ await self.update_ns_state(ns_uuid, NsState.INSTANTIATED, err_details)
+ self.logger.error(f"{WORKFLOW_NS_INSTANTIATE} failed with {err_details}")
+ raise e
+
+ except ChildWorkflowError as e:
+ err_details = str(e.cause.cause.cause.with_traceback(e.cause.__traceback__))
+ await self.update_ns_state(ns_uuid, NsState.INSTANTIATED, err_details)
+ self.logger.error(f"{WORKFLOW_NS_INSTANTIATE} failed with {err_details}")
raise e
except Exception as e:
- await self.update_ns_state(ns_uuid, NsState.INSTANTIATED, str(e))
- self.logger.error(f"{WORKFLOW_NS_INSTANTIATE} failed with {str(e)}")
+ err_details = str(traceback.format_exc())
+ await self.update_ns_state(ns_uuid, NsState.INSTANTIATED, err_details)
+ self.logger.error(f"{WORKFLOW_NS_INSTANTIATE} failed with {err_details}")
raise e
+
await self.update_ns_state(ns_uuid, NsState.INSTANTIATED, "Done")
@staticmethod
diff --git a/osm_lcm/temporal/vdu_workflows.py b/osm_lcm/temporal/vdu_workflows.py
index edb1235..0c91e99 100644
--- a/osm_lcm/temporal/vdu_workflows.py
+++ b/osm_lcm/temporal/vdu_workflows.py
@@ -18,6 +18,8 @@
import logging
from temporalio import workflow
from temporalio.common import RetryPolicy
+from temporalio.exceptions import ActivityError
+import traceback
from osm_common.dataclasses.temporal_dataclasses import (
VduInstantiateInput,
@@ -75,6 +77,12 @@
self.logger.info(f"VDU `{input.charm_info.app_name}` is ready")
+ except ActivityError as e:
+ err_details = str(e.cause.with_traceback(e.__traceback__))
+ self.logger.error(f"{WORKFLOW_VDU_INSTANTIATE} failed with {err_details}")
+ raise e
+
except Exception as e:
- self.logger.error(f"{WORKFLOW_VDU_INSTANTIATE} failed with {str(e)}")
+ err_details = str(traceback.format_exc())
+ self.logger.error(f"{WORKFLOW_VDU_INSTANTIATE} failed with {err_details}")
raise e
diff --git a/osm_lcm/temporal/vim_workflows.py b/osm_lcm/temporal/vim_workflows.py
index 33ab565..b549072 100644
--- a/osm_lcm/temporal/vim_workflows.py
+++ b/osm_lcm/temporal/vim_workflows.py
@@ -19,6 +19,7 @@
from temporalio import workflow
from temporalio.common import RetryPolicy
from temporalio.exceptions import ActivityError
+import traceback
from osm_common.dataclasses.temporal_dataclasses import (
DeleteVimInput,
@@ -44,13 +45,14 @@
retry_policy = RetryPolicy(maximum_attempts=3)
default_schedule_to_close_timeout = timedelta(minutes=10)
-workflow.logger = logging.getLogger("lcm.temporal.vim_workflows")
-
@workflow.defn(name=WORKFLOW_VIM_CREATE, sandboxed=_SANDBOXED)
class VimCreateWorkflow:
"""Updates VIM account state by validating the VIM connectivity."""
+ def __init__(self):
+ self.logger = logging.getLogger(f"lcm.wfl.{self.__class__.__name__}")
+
@workflow.run
async def run(self, input: VimOperationInput) -> None:
vim_state = UpdateVimStateInput(input.vim_uuid, VimState.ENABLED, "Done")
@@ -68,45 +70,55 @@
)
except ActivityError as e:
+ error_details = str(e.cause.with_traceback(e.__traceback__))
vim_state = UpdateVimStateInput(
- input.vim_uuid, VimState.ERROR, e.cause.message
+ input.vim_uuid, VimState.ERROR, str(e.cause.message)
)
op_state = UpdateVimOperationStateInput(
- input.vim_uuid, input.op_id, VimOperationState.FAILED, e.cause.message
+ input.vim_uuid,
+ input.op_id,
+ VimOperationState.FAILED,
+ error_details,
)
-
- workflow.logger.error(
- f"{WORKFLOW_VIM_CREATE} failed with {str(e.cause.message)}"
- )
+ await self.update_states(op_state, vim_state)
+ self.logger.error(f"{WORKFLOW_VIM_CREATE} failed with {error_details}")
raise e
except Exception as e:
+ error_details = str(traceback.format_exc())
vim_state = UpdateVimStateInput(input.vim_uuid, VimState.ERROR, str(e))
op_state = UpdateVimOperationStateInput(
- input.vim_uuid, input.op_id, VimOperationState.FAILED, str(e)
+ input.vim_uuid,
+ input.op_id,
+ VimOperationState.FAILED,
+ error_details,
)
-
- workflow.logger.error(f"{WORKFLOW_VIM_CREATE} failed with {str(e)}")
+ await self.update_states(op_state, vim_state)
+ self.logger.error(f"{WORKFLOW_VIM_CREATE} failed with {error_details}")
raise e
- finally:
- await workflow.execute_activity(
- activity=ACTIVITY_UPDATE_VIM_STATE,
- arg=vim_state,
- activity_id=f"{ACTIVITY_UPDATE_VIM_STATE}-{input.vim_uuid}",
- task_queue=LCM_TASK_QUEUE,
- schedule_to_close_timeout=default_schedule_to_close_timeout,
- retry_policy=retry_policy,
- )
+ async def update_states(
+ self,
+ op_state: UpdateVimOperationStateInput,
+ vim_state: UpdateVimStateInput,
+ ):
+ await workflow.execute_activity(
+ activity=ACTIVITY_UPDATE_VIM_STATE,
+ arg=vim_state,
+ activity_id=f"{ACTIVITY_UPDATE_VIM_STATE}-{vim_state.vim_uuid}",
+ task_queue=LCM_TASK_QUEUE,
+ schedule_to_close_timeout=default_schedule_to_close_timeout,
+ retry_policy=retry_policy,
+ )
- await workflow.execute_activity(
- activity=ACTIVITY_UPDATE_VIM_OPERATION_STATE,
- arg=op_state,
- activity_id=f"{ACTIVITY_UPDATE_VIM_OPERATION_STATE}-{input.vim_uuid}",
- task_queue=LCM_TASK_QUEUE,
- schedule_to_close_timeout=default_schedule_to_close_timeout,
- retry_policy=retry_policy,
- )
+ await workflow.execute_activity(
+ activity=ACTIVITY_UPDATE_VIM_OPERATION_STATE,
+ arg=op_state,
+ activity_id=f"{ACTIVITY_UPDATE_VIM_OPERATION_STATE}-{op_state.vim_uuid}",
+ task_queue=LCM_TASK_QUEUE,
+ schedule_to_close_timeout=default_schedule_to_close_timeout,
+ retry_policy=retry_policy,
+ )
@workflow.defn(name=WORKFLOW_VIM_UPDATE, sandboxed=_SANDBOXED)
diff --git a/osm_lcm/temporal/vnf_activities.py b/osm_lcm/temporal/vnf_activities.py
index 98fc86c..85de719 100644
--- a/osm_lcm/temporal/vnf_activities.py
+++ b/osm_lcm/temporal/vnf_activities.py
@@ -134,10 +134,10 @@
activity, the operation is idempotent.
"""
- update_vnf_state = {"vnfState": vnf_state_input.state}
+ update_vnf_state = {"vnfState": vnf_state_input.state.name}
self.db.set_one("vnfrs", {"_id": vnf_state_input.vnfr_uuid}, update_vnf_state)
self.logger.debug(
- f"VNF {vnf_state_input.vnfr_uuid} state is updated to {vnf_state_input.state}."
+ f"VNF {vnf_state_input.vnfr_uuid} state is updated to {vnf_state_input.state.name}."
)
@activity.defn(name=ACTIVITY_CHANGE_VNF_INSTANTIATION_STATE)
@@ -165,7 +165,7 @@
"""
update_vnf_instantiation_state = {
- "instantiationState": vnf_instantiation_state_input.state
+ "instantiationState": vnf_instantiation_state_input.state.name
}
self.db.set_one(
"vnfrs",
@@ -173,7 +173,7 @@
update_vnf_instantiation_state,
)
self.logger.debug(
- f"VNF {vnf_instantiation_state_input.vnfr_uuid} state is updated to {vnf_instantiation_state_input.state}."
+ f"VNF {vnf_instantiation_state_input.vnfr_uuid} state is updated to {vnf_instantiation_state_input.state.name}."
)
@activity.defn(name=ACTIVITY_SET_VNF_MODEL)
diff --git a/osm_lcm/temporal/vnf_workflows.py b/osm_lcm/temporal/vnf_workflows.py
index d2d6d71..ffdd403 100644
--- a/osm_lcm/temporal/vnf_workflows.py
+++ b/osm_lcm/temporal/vnf_workflows.py
@@ -19,18 +19,21 @@
from temporalio import workflow
from temporalio.converter import value_to_type
from temporalio.common import RetryPolicy
+from temporalio.exceptions import ActivityError, ChildWorkflowError
+import traceback
from osm_common.dataclasses.temporal_dataclasses import (
- VnfInstantiationState,
- VnfState,
- VnfInstantiateInput,
- VduInstantiateInput,
ChangeVnfInstantiationStateInput,
ChangeVnfStateInput,
GetTaskQueueInput,
GetTaskQueueOutput,
GetVnfDetailsInput,
GetVnfDetailsOutput,
+ VduComputeConstraints,
+ VduInstantiateInput,
+ VnfInstantiateInput,
+ VnfInstantiationState,
+ VnfState,
)
from osm_common.temporal_constants import (
@@ -123,12 +126,31 @@
),
)
- except Exception as e:
- workflow.logger.error(f"{WORKFLOW_VNF_INSTANTIATE} failed with {str(e)}")
+ except ActivityError as e:
+ err_details = str(e.cause.with_traceback(e.__traceback__))
await self.update_states(
vnf_instantiation_state=vnf_instantiation_state,
vnf_state=vnf_state,
)
+ self.logger.error(f"{WORKFLOW_VNF_INSTANTIATE} failed with {err_details}")
+ raise e
+
+ except ChildWorkflowError as e:
+ err_details = str(e.cause.cause.with_traceback(e.cause.__traceback__))
+ await self.update_states(
+ vnf_instantiation_state=vnf_instantiation_state,
+ vnf_state=vnf_state,
+ )
+ self.logger.error(f"{WORKFLOW_VNF_INSTANTIATE} failed with {err_details}")
+ raise e
+
+ except Exception as e:
+ err_details = str(traceback.format_exc())
+ await self.update_states(
+ vnf_instantiation_state=vnf_instantiation_state,
+ vnf_state=vnf_state,
+ )
+ self.logger.error(f"{WORKFLOW_VNF_INSTANTIATE} failed with {err_details}")
raise e
@staticmethod
@@ -186,7 +208,10 @@
vim_id = vnfr.get("vim-account-id")
sw_image_descs = vnfd.get("sw-image-desc")
vdu_info = CharmInfoUtils.get_charm_info(vdu, sw_image_descs)
- vdu_instantiate_input = VduInstantiateInput(vim_id, model_name, vdu_info, None)
+ compute_constraints = VduComputeConstraints(cores=0, mem=0)
+ vdu_instantiate_input = VduInstantiateInput(
+ vim_id, model_name, vdu_info, compute_constraints, "cloud"
+ )
vdu_instantiate_workflow_id = (
vdu_instantiate_input.model_name
+ "-"
@@ -227,6 +252,12 @@
schedule_to_close_timeout=default_schedule_to_close_timeout,
retry_policy=retry_policy,
)
+ except ActivityError as e:
+ err_details = str(e.cause.with_traceback(e.__traceback__))
+ self.logger.error(f"{WORKFLOW_VNF_PREPARE} failed with {err_details}")
+ raise e
+
except Exception as e:
- self.logger.error(f"{WORKFLOW_VNF_PREPARE} failed with {str(e)}")
+ err_details = str(traceback.format_exc())
+ self.logger.error(f"{WORKFLOW_VNF_PREPARE} failed with {err_details}")
raise e
diff --git a/osm_lcm/tests/test_juju_paas_activities.py b/osm_lcm/tests/test_juju_paas_activities.py
index 1aee12b..d104d07 100644
--- a/osm_lcm/tests/test_juju_paas_activities.py
+++ b/osm_lcm/tests/test_juju_paas_activities.py
@@ -257,9 +257,9 @@
channel = "latest"
entity_url = "ch:my-charm"
charm_info = CharmInfo(app_name, channel, entity_url)
- constraints = VduComputeConstraints(1, 2, "")
+ constraints = VduComputeConstraints(1, 2)
vdu_instantiate_input = VduInstantiateInput(
- vim_content["_id"], namespace, charm_info, constraints
+ vim_content["_id"], namespace, charm_info, constraints, cloud=""
)
async def test_deploy_charm_nominal_case(self):
diff --git a/osm_lcm/tests/test_vdu_workflow.py b/osm_lcm/tests/test_vdu_workflow.py
index c5b2adc..15b30f6 100644
--- a/osm_lcm/tests/test_vdu_workflow.py
+++ b/osm_lcm/tests/test_vdu_workflow.py
@@ -63,10 +63,10 @@
channel = "latest"
entity_url = "ch:my-charm"
cloud = "microk8s"
- constraints = VduComputeConstraints(mem=1, cores=1, cloud=cloud)
+ constraints = VduComputeConstraints(mem=1, cores=1)
charm_info = CharmInfo(app_name, channel, entity_url)
vdu_instantiate_input = VduInstantiateInput(
- vim_id, namespace, charm_info, constraints
+ vim_id, namespace, charm_info, constraints, cloud
)
worflow_id = namespace + "-" + app_name
diff --git a/osm_lcm/tests/test_vnf_workflows.py b/osm_lcm/tests/test_vnf_workflows.py
index 912f5d0..6fd97d8 100644
--- a/osm_lcm/tests/test_vnf_workflows.py
+++ b/osm_lcm/tests/test_vnf_workflows.py
@@ -483,7 +483,8 @@
charm_info=CharmInfo(
app_name="my-app", channel="latest", entity_url="my-url"
),
- constraints=VduComputeConstraints(cores=1, mem=1, cloud=cloud),
+ constraints=VduComputeConstraints(cores=1, mem=1),
+ cloud=cloud,
),
"vdu_instantiate_workflow_id",
)
diff --git a/tox.ini b/tox.ini
index 1cb2253..0b5b8f7 100644
--- a/tox.ini
+++ b/tox.ini
@@ -67,7 +67,7 @@
-r{toxinidir}/requirements-test.txt
pylint
commands =
- pylint -E osm_lcm --extension-pkg-whitelist=pydantic # issue with pydantic (https://github.com/pydantic/pydantic/issues/1961)
+ pylint -E osm_lcm --extension-pkg-whitelist=pydantic --disable=E1101 # issue with pydantic (https://github.com/pydantic/pydantic/issues/1961)
#######################################################################################