From: Dario Faccin Date: Mon, 19 Jun 2023 10:35:33 +0000 (+0200) Subject: OSMENG-1155: Implementation of Constants and Dataclasses X-Git-Url: https://osm.etsi.org/gitweb/?a=commitdiff_plain;h=f5d65b535addea8d48a4519643eeb609a991321a;p=osm%2FLCM.git OSMENG-1155: Implementation of Constants and Dataclasses Add implementation for workflows and activities Change-Id: I58226765c41d18821724ac5763a3fe390c371ca6 Signed-off-by: Dario Faccin Signed-off-by: Mark Beierl --- diff --git a/osm_lcm/nglcm.py b/osm_lcm/nglcm.py index bad37f7..7feb866 100644 --- a/osm_lcm/nglcm.py +++ b/osm_lcm/nglcm.py @@ -26,28 +26,51 @@ from os import path import yaml from osm_common.dbbase import DbException -from osm_common.temporal_constants import LCM_TASK_QUEUE +from osm_common.temporal_task_queues.task_queues_mappings import LCM_TASK_QUEUE from osm_lcm.data_utils.database.database import Database from osm_lcm.data_utils.lcm_config import LcmCfg from osm_lcm.lcm_utils import LcmException -from osm_lcm.temporal.juju_paas_activities import JujuPaasConnector -from osm_lcm.temporal.lcm_activities import NsLcmActivity -from osm_lcm.temporal.lcm_workflows import NsNoOpWorkflow -from osm_lcm.temporal.ns_activities import NsDbActivity, NsOperations -from osm_lcm.temporal.ns_workflows import NsInstantiateWorkflow -from osm_lcm.temporal.vdu_workflows import VduInstantiateWorkflow -from osm_lcm.temporal.vim_activities import VimDbActivity +from osm_lcm.temporal.juju_paas_activities import ( + JujuPaasConnector, + CreateModelImpl, + CheckCharmStatusImpl, + DeployCharmImpl, + TestVimConnectivityImpl, +) + +from osm_lcm.temporal.lcm_activities import NsLcmNoOpImpl, UpdateNsLcmOperationStateImpl +from osm_lcm.temporal.lcm_workflows import NsNoOpWorkflowImpl +from osm_lcm.temporal.ns_activities import ( + GetVnfDetailsImpl, + GetNsRecordImpl, + UpdateNsStateImpl, +) +from osm_lcm.temporal.ns_workflows import NsInstantiateWorkflowImpl +from osm_lcm.temporal.vdu_workflows import VduInstantiateWorkflowImpl +from osm_lcm.temporal.vim_activities import ( + UpdateVimStateImpl, + UpdateVimOperationStateImpl, + DeleteVimRecordImpl, +) from osm_lcm.temporal.vim_workflows import ( - VimCreateWorkflow, - VimDeleteWorkflow, - VimUpdateWorkflow, + VimCreateWorkflowImpl, + VimDeleteWorkflowImpl, + VimUpdateWorkflowImpl, ) from osm_lcm.temporal.vnf_activities import ( - VnfDbActivity, - VnfOperations, - VnfSendNotifications, + GetTaskQueueImpl, + GetVnfDescriptorImpl, + GetVnfRecordImpl, + GetVimCloudImpl, + ChangeVnfStateImpl, + SetVnfModelImpl, + ChangeVnfInstantiationStateImpl, + SendNotificationForVnfImpl, +) +from osm_lcm.temporal.vnf_workflows import ( + VnfInstantiateWorkflowImpl, + VnfPrepareWorkflowImpl, ) -from osm_lcm.temporal.vnf_workflows import VnfInstantiateWorkflow, VnfPrepareWorkflow from temporalio.client import Client from temporalio.worker import Worker @@ -139,46 +162,39 @@ class NGLcm: ) client = await Client.connect(temporal_api) - ns_operation_instance = NsOperations(self.db) - ns_data_activity_instance = NsDbActivity(self.db) - nslcm_activity_instance = NsLcmActivity(self.db) paas_connector_instance = JujuPaasConnector(self.db) - vim_data_activity_instance = VimDbActivity(self.db) - vnf_data_activity_instance = VnfDbActivity(self.db) - vnf_operation_instance = VnfOperations(self.db) - vnf_send_notifications_instance = VnfSendNotifications() workflows = [ - NsInstantiateWorkflow, - NsNoOpWorkflow, - VimCreateWorkflow, - VimDeleteWorkflow, - VimUpdateWorkflow, - VduInstantiateWorkflow, - VnfInstantiateWorkflow, - VnfPrepareWorkflow, + NsInstantiateWorkflowImpl, + NsNoOpWorkflowImpl, + VimCreateWorkflowImpl, + VimDeleteWorkflowImpl, + VimUpdateWorkflowImpl, + VduInstantiateWorkflowImpl, + VnfInstantiateWorkflowImpl, + VnfPrepareWorkflowImpl, ] activities = [ - ns_data_activity_instance.update_ns_state, - ns_operation_instance.get_vnf_details, - ns_operation_instance.get_ns_record, - nslcm_activity_instance.update_ns_lcm_operation_state, - nslcm_activity_instance.no_op, - paas_connector_instance.create_model, - paas_connector_instance.deploy_charm, - paas_connector_instance.check_charm_status, - paas_connector_instance.test_vim_connectivity, - vim_data_activity_instance.update_vim_operation_state, - vim_data_activity_instance.update_vim_state, - vim_data_activity_instance.delete_vim_record, - vnf_data_activity_instance.change_vnf_state, - vnf_data_activity_instance.change_vnf_instantiation_state, - vnf_operation_instance.get_task_queue, - vnf_operation_instance.get_vim_cloud, - vnf_operation_instance.get_vnf_descriptor, - vnf_operation_instance.get_vnf_record, - vnf_send_notifications_instance.send_notification_for_vnf, - vnf_data_activity_instance.set_vnf_model, + UpdateNsStateImpl(self.db).__call__, + GetVnfDetailsImpl(self.db).__call__, + GetNsRecordImpl(self.db).__call__, + UpdateNsLcmOperationStateImpl(self.db).__call__, + NsLcmNoOpImpl().__call__, + CreateModelImpl(self.db, paas_connector_instance).__call__, + DeployCharmImpl(paas_connector_instance).__call__, + CheckCharmStatusImpl(paas_connector_instance).__call__, + TestVimConnectivityImpl(paas_connector_instance).__call__, + UpdateVimOperationStateImpl(self.db).__call__, + UpdateVimStateImpl(self.db).__call__, + DeleteVimRecordImpl(self.db).__call__, + ChangeVnfStateImpl(self.db).__call__, + ChangeVnfInstantiationStateImpl(self.db).__call__, + GetTaskQueueImpl(self.db).__call__, + GetVimCloudImpl(self.db).__call__, + GetVnfDescriptorImpl(self.db).__call__, + GetVnfRecordImpl(self.db).__call__, + SendNotificationForVnfImpl().__call__, + SetVnfModelImpl(self.db).__call__, ] # Check if we are running under a debugger diff --git a/osm_lcm/temporal/juju_paas_activities.py b/osm_lcm/temporal/juju_paas_activities.py index 5082254..2915ee9 100644 --- a/osm_lcm/temporal/juju_paas_activities.py +++ b/osm_lcm/temporal/juju_paas_activities.py @@ -21,19 +21,15 @@ from dataclasses import dataclass from juju.application import Application from juju.controller import Controller from n2vc.config import EnvironConfig -from osm_common.dataclasses.temporal_dataclasses import ( +from osm_common.temporal.activities.paas import ( + TestVimConnectivity, + CheckCharmStatus, + CreateModel, + DeployCharm, +) +from osm_common.temporal.dataclasses_common import ( CharmInfo, - CheckCharmStatusInput, - ModelInfo, - TestVimConnectivityInput, VduComputeConstraints, - VduInstantiateInput, -) -from osm_common.temporal_constants import ( - ACTIVITY_TEST_VIM_CONNECTIVITY, - ACTIVITY_CHECK_CHARM_STATUS, - ACTIVITY_CREATE_MODEL, - ACTIVITY_DEPLOY_CHARM, ) from osm_lcm.data_utils.database.database import Database from temporalio import activity @@ -123,121 +119,71 @@ class JujuPaasConnector: application_constraints["cores"] = constraints.cores return application_constraints - @activity.defn(name=ACTIVITY_TEST_VIM_CONNECTIVITY) - async def test_vim_connectivity( - self, test_connectivity_input: TestVimConnectivityInput - ) -> None: - """Validates the credentials by attempting to connect to the given Juju Controller. - - Collaborators: - DB Read: vim_accounts - Juju Controller: Connect only - - Raises (Retryable): - ApplicationError If any of password, cacert, cloud_credentials is invalid - or Juju controller is not reachable - - Activity Lifecycle: - This activity should complete relatively quickly (in a few seconds). - However, it would be reasonable to wait more than 72 seconds (network timeout) - incase there are network issues. + def _check_units_ready( + self, application: Application, last_unit_status: dict + ) -> bool: + for unit in application.units: + unit_workload_status = unit.workload_status + if unit_workload_status != last_unit_status.get(unit, None): + last_unit_status[unit] = unit_workload_status + self.logger.debug( + f"Application `{application.name}` Unit `{unit}` is {unit_workload_status}" + ) + if unit_workload_status not in ["active", "blocked"]: + return False + return True - This activity will not report a heartbeat due to its - short-running nature. - It is recommended, although not necessary to implement a - back-off strategy for this activity, as it will naturally block - and wait on each connection attempt. - """ - vim_id = test_connectivity_input.vim_uuid - await self._get_controller(vim_id) +class TestVimConnectivityImpl(TestVimConnectivity): + @activity.defn(name=TestVimConnectivity.__name__) + async def __call__(self, activity_input: TestVimConnectivity.Input) -> None: + vim_id = activity_input.vim_uuid + await self.juju_controller._get_controller(vim_id) message = f"Connection to juju controller succeeded for {vim_id}" self.logger.info(message) - @activity.defn(name=ACTIVITY_CREATE_MODEL) - async def create_model(self, create_model_input: ModelInfo) -> None: - """Connects to Juju Controller. Creates a new model. - - Collaborators: - DB Read: vim_accounts - Juju Controller: Connect and create model. - - Raises (Retryable): - ApplicationError If Juju controller is not reachable. - If the model already exists. - - Activity Lifecycle: - This activity should complete relatively quickly (in a few seconds). - However, it would be reasonable to wait more than 72 seconds (network timeout) - incase there are network issues. - - This activity will not report a heartbeat due to its - short-running nature. - It is recommended, although not necessary to implement a - back-off strategy for this activity, as it will naturally block - and wait on each connection attempt. - """ - controller = await self._get_controller(create_model_input.vim_uuid) - if create_model_input.model_name in await controller.list_models(): - self.logger.debug(f"Model {create_model_input.model_name} already created") +class CreateModelImpl(CreateModel): + @activity.defn(name=CreateModel.__name__) + async def __call__(self, activity_input: CreateModel.Input) -> None: + controller = await self.juju_controller._get_controller(activity_input.vim_uuid) + if activity_input.model_name in await controller.list_models(): + self.logger.debug(f"Model {activity_input.model_name} already created") return - vim_content = self.db.get_one( - "vim_accounts", {"_id": create_model_input.vim_uuid} - ) + vim_content = self.db.get_one("vim_accounts", {"_id": activity_input.vim_uuid}) vim_config = vim_content["config"] config = { "endpoints": ",".join(await controller.api_endpoints), "user": vim_content["vim_user"], - "secret": self._decrypt_password(vim_content), + "secret": self.juju_controller._decrypt_password(vim_content), "cacert": base64.b64encode( vim_config["ca_cert_content"].encode("utf-8") ).decode("utf-8"), "authorized-keys": vim_config["authorized_keys"], } - self.logger.debug(f"Creating model {create_model_input.model_name}") + self.logger.debug(f"Creating model {activity_input.model_name}") await controller.add_model( - create_model_input.model_name, + activity_input.model_name, config=config, cloud_name=vim_config["cloud"], credential_name=vim_config["cloud_credentials"], ) - self.logger.debug(f"Model {create_model_input.model_name} created") - - @activity.defn(name=ACTIVITY_DEPLOY_CHARM) - async def deploy_charm(self, deploy_charm_input: VduInstantiateInput) -> None: - """Deploys a charm. - - Collaborators: - DB Read: vim_accounts - Juju Controller: Connect and deploy charm - - Raises (Retryable): - ApplicationError If Juju controller is not reachable - If application already exists - - Activity Lifecycle: - This activity should complete relatively quickly (in a few seconds). - However, it would be reasonable to wait more than 72 seconds (network timeout) - incase there are network issues. + self.logger.debug(f"Model {activity_input.model_name} created") - This activity will not report a heartbeat due to its - short-running nature. - It is recommended, although not necessary to implement a - back-off strategy for this activity, as it will naturally block - and wait on each connection attempt. - """ - model_name = deploy_charm_input.model_name - charm_info = deploy_charm_input.charm_info +class DeployCharmImpl(DeployCharm): + @activity.defn(name=DeployCharm.__name__) + async def __call__(self, activity_input: DeployCharm.Input) -> None: + model_name = activity_input.model_name + charm_info = activity_input.charm_info application_name = charm_info.app_name - constraints = JujuPaasConnector._get_application_constraints( - deploy_charm_input.constraints, deploy_charm_input.cloud + constraints = self.juju_controller._get_application_constraints( + activity_input.constraints, activity_input.cloud ) - controller = await self._get_controller(deploy_charm_input.vim_uuid) + controller = await self.juju_controller._get_controller(activity_input.vim_uuid) model = await controller.get_model(model_name) if application_name in model.applications: raise Exception("Application {} already exists".format(application_name)) @@ -246,37 +192,16 @@ class JujuPaasConnector: application_name=application_name, channel=charm_info.channel, constraints=constraints if constraints else None, - config=deploy_charm_input.config, + config=activity_input.config, ) - @activity.defn(name=ACTIVITY_CHECK_CHARM_STATUS) - async def check_charm_status( - self, check_charm_status: CheckCharmStatusInput - ) -> None: - """Checks the ready status of the charm. This activity will block until the status of - the application is either "active" or "blocked". Additionally, it also blocks until - the workload status of each of its units is also either "active" or "blocked". - - Collaborators: - DB Read: vim_accounts - Juju Controller: Connect to controller and check charm status. - - Raises (Retryable): - ApplicationError If any of password, cacert, cloud_credentials is invalid - or Juju controller is not reachable - - Activity Lifecycle: - This activity will continue indefinitely until the specified charm deployment - has reached a ready state. Heartbeats are performed to ensure this activity - does not timeout. - - A start-to-close of something reasonable (such as 5 minutes) should be implemented - at the workflow level and such a timeout shall trigger workflow failure logic. - """ - controller = await self._get_controller(check_charm_status.vim_uuid) - model = await controller.get_model(check_charm_status.model_name) - application = model.applications[check_charm_status.application_name] +class CheckCharmStatusImpl(CheckCharmStatus): + @activity.defn(name=CheckCharmStatus.__name__) + async def __call__(self, activity_input: CheckCharmStatus.Input) -> None: + controller = await self.juju_controller._get_controller(activity_input.vim_uuid) + model = await controller.get_model(activity_input.model_name) + application = model.applications[activity_input.application_name] ready = False last_status = None @@ -285,18 +210,18 @@ class JujuPaasConnector: while not ready: activity.heartbeat() - await asyncio.sleep(check_charm_status.poll_interval) + await asyncio.sleep(activity_input.poll_interval) # Perform the fetch of the status only once and keep it locally application_status = application.status if application_status != last_status: last_status = application_status self.logger.debug( - f"Application `{check_charm_status.application_name}` is {application_status}" + f"Application `{activity_input.application_name}` is {application_status}" ) if application_status in ["active", "blocked"]: # Check each unit to see if they are also ready - if not self._check_units_ready( + if not self.juju_controller._check_units_ready( application=application, last_unit_status=last_unit_status ): continue @@ -304,20 +229,6 @@ class JujuPaasConnector: continue ready = True - def _check_units_ready( - self, application: Application, last_unit_status: dict - ) -> bool: - for unit in application.units: - unit_workload_status = unit.workload_status - if unit_workload_status != last_unit_status.get(unit, None): - last_unit_status[unit] = unit_workload_status - self.logger.debug( - f"Application `{application.name}` Unit `{unit}` is {unit_workload_status}" - ) - if unit_workload_status not in ["active", "blocked"]: - return False - return True - class CharmInfoUtils: @staticmethod diff --git a/osm_lcm/temporal/lcm_activities.py b/osm_lcm/temporal/lcm_activities.py index 6ddb0f3..3400e94 100644 --- a/osm_lcm/temporal/lcm_activities.py +++ b/osm_lcm/temporal/lcm_activities.py @@ -13,83 +13,45 @@ # implied. # See the License for the specific language governing permissions and # limitations under the License. -import logging -import time -from osm_common.dataclasses.temporal_dataclasses import ( - NsLcmOperationInput, - UpdateLcmOperationStateInput, -) -from osm_common.temporal_constants import ( - ACTIVITY_UPDATE_LCM_OPERATION_STATE, - ACTIVITY_NSLCM_NO_OP, -) -from osm_lcm.data_utils.database.database import Database from temporalio import activity +import time +from osm_common.temporal.activities.lcm import ( + NsLcmNoOp, + UpdateNsLcmOperationState, +) -class NsLcmActivity: - """ - Handles NS Lifecycle Managment operations. - Args: - db (Database): Data Access Object - """ - - def __init__(self, db: Database): - self.db: Database = db - self.logger = logging.getLogger(f"lcm.act.{self.__class__.__name__}") - - @activity.defn(name=ACTIVITY_NSLCM_NO_OP) - async def no_op(self, input: NsLcmOperationInput) -> None: - """ - This is a simple No Operation Activity that simply logs the data - with which it was called. It can be used as a placeholder when - developing workflows, or can be enhanced with logic to throw - exceptions on specific conditions to test exception handling in - a workflow. - """ - self.logger.debug(f"Called with: {input.nslcmop}") - - @activity.defn(name=ACTIVITY_UPDATE_LCM_OPERATION_STATE) - async def update_ns_lcm_operation_state( - self, data: UpdateLcmOperationStateInput - ) -> None: - """ - Changes the state of a LCM operation task. Should be done to - indicate progress, or completion of the task itself. - Collaborators: - DB Write: nslcmops +class NsLcmNoOpImpl(NsLcmNoOp): + @activity.defn(name=NsLcmNoOp.__name__) + async def __call__(self, activity_input: NsLcmNoOp.Input) -> None: + self.logger.debug(f"Called with: {activity_input.nslcmop}") - Raises (Retryable): - DbException If the target DB record does not exist or DB is not reachable. - Activity Lifecycle: - This activity will not report a heartbeat due to its - short-running nature. - As this is a direct DB update, it is not recommended to have - any specific retry policy - """ +class UpdateNsLcmOperationStateImpl(UpdateNsLcmOperationState): + @activity.defn(name=UpdateNsLcmOperationState.__name__) + async def __call__(self, activity_input: UpdateNsLcmOperationState.Input): now = time.time() update_lcm_operation = { "_admin.modified": now, } - if data.op_state is not None: - update_lcm_operation["operationState"] = data.op_state.name + if activity_input.op_state is not None: + update_lcm_operation["operationState"] = activity_input.op_state.name update_lcm_operation["statusEnteredTime"] = now - if data.stage is not None: - update_lcm_operation["stage"] = data.stage + if activity_input.stage is not None: + update_lcm_operation["stage"] = activity_input.stage - if data.error_message is not None: - update_lcm_operation["errorMessage"] = data.error_message + if activity_input.error_message is not None: + update_lcm_operation["errorMessage"] = activity_input.error_message - if data.detailed_status is not None: - update_lcm_operation["detailedStatus"] = data.detailed_status + if activity_input.detailed_status is not None: + update_lcm_operation["detailedStatus"] = activity_input.detailed_status - self.db.set_one("nslcmops", {"_id": data.op_id}, update_lcm_operation) + self.db.set_one("nslcmops", {"_id": activity_input.op_id}, update_lcm_operation) self.logger.debug( - f"Updated LCM Operation {data.op_id} to {update_lcm_operation}" + f"Updated LCM Operation {activity_input.op_id} to {update_lcm_operation}" ) diff --git a/osm_lcm/temporal/lcm_workflows.py b/osm_lcm/temporal/lcm_workflows.py index 6c8c28f..aaa9870 100644 --- a/osm_lcm/temporal/lcm_workflows.py +++ b/osm_lcm/temporal/lcm_workflows.py @@ -14,139 +14,30 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging -from abc import ABC, abstractmethod -from datetime import timedelta - -from osm_common.dataclasses.temporal_dataclasses import ( - LcmOperationState, - NsLcmOperationInput, - UpdateLcmOperationStateInput, -) -from osm_common.temporal_constants import ( - ACTIVITY_NSLCM_NO_OP, - ACTIVITY_UPDATE_LCM_OPERATION_STATE, - WORKFLOW_NSLCM_NO_OP, -) from temporalio import workflow -from temporalio.common import RetryPolicy -from temporalio.exceptions import ActivityError, ChildWorkflowError - - -class LcmOperationWorkflow(ABC): - """ - An abstract base class representing a Lifecycle Management Operation. Any - workflows that need LCM OP control should extend this class and implement - the workflow method. - - Methods - ------- - - @abstractmethod workflow(input: NsLcmOperationInput) - Method for subclasses to implement the actual workflow that is being - wrapped in this operation. - - @workflow.run wrap_nslcmop(input: NsLcmOperationInput) - Must be implemented in every subclass exactly as follows: - @workflow.run - async def wrap_nslcmop(self, input: NsLcmOperationInput) -> None: - await super().wrap_nslcmop(input=input) - """ - - _SANDBOXED = False - retry_policy = RetryPolicy(maximum_attempts=3) - no_retry_policy = RetryPolicy(maximum_attempts=1) - default_schedule_to_close_timeout = timedelta(minutes=10) - - def __init__(self): - self.logger = logging.getLogger(f"lcm.wfl.{self.__class__.__name__}") - self.op_id = None - self.stage = "" - @abstractmethod - async def workflow(self, input: NsLcmOperationInput): - pass - - async def wrap_nslcmop(self, input: NsLcmOperationInput): - self.op_id = input.nslcmop["_id"] - await self.update_operation_state(LcmOperationState.PROCESSING) - try: - await self.workflow(input=input) - - except ActivityError as 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=err_details, - ) - raise e - - except ChildWorkflowError as e: - err_details = str(e.cause.with_traceback(e.cause.__traceback__)) - self.logger.error(err_details) - await self.update_operation_state( - LcmOperationState.FAILED, - error_message=str(e.cause.message), - detailed_status=err_details, - ) - raise e - - except Exception as e: - self.logger.exception(e) - await self.update_operation_state( - LcmOperationState.FAILED, - error_message=str(e), - detailed_status=str(e), - ) - raise e - - await self.update_operation_state(LcmOperationState.COMPLETED) - - async def update_operation_state( - self, - op_state: LcmOperationState, - stage: str = None, - error_message: str = "", - detailed_status: str = "", - ) -> None: - if stage is not None: - self.stage = stage - input = UpdateLcmOperationStateInput( - op_id=self.op_id, - op_state=op_state, - stage=self.stage, - error_message=error_message, - detailed_status=detailed_status, - ) - await workflow.execute_activity( - activity=ACTIVITY_UPDATE_LCM_OPERATION_STATE, - arg=input, - activity_id=f"{ACTIVITY_UPDATE_LCM_OPERATION_STATE}-{self.op_id}", - schedule_to_close_timeout=LcmOperationWorkflow.default_schedule_to_close_timeout, - retry_policy=LcmOperationWorkflow.retry_policy, - ) +from osm_common.temporal.workflows.lcm import NsNoOpWorkflow +from osm_common.temporal.activities.lcm import NsLcmNoOp -@workflow.defn(name=WORKFLOW_NSLCM_NO_OP, sandboxed=LcmOperationWorkflow._SANDBOXED) -class NsNoOpWorkflow(LcmOperationWorkflow): +@workflow.defn(name=NsNoOpWorkflow.__name__, sandboxed=False) +class NsNoOpWorkflowImpl(NsNoOpWorkflow): """ This is a simple No Operation workflow that simply calls a No Operation activity. It can be used as a placeholder when developing workflows. """ @workflow.run - async def wrap_nslcmop(self, input: NsLcmOperationInput) -> None: - await super().wrap_nslcmop(input=input) + async def wrap_nslcmop(self, workflow_input: NsNoOpWorkflow.Input) -> None: + await super().wrap_nslcmop(workflow_input=workflow_input) - async def workflow(self, input: NsLcmOperationInput) -> None: - self.logger.debug(f"Called with: {input.nslcmop}") + async def run(self, workflow_input: NsNoOpWorkflow.Input) -> None: + self.logger.debug(f"Called with: {workflow_input.nslcmop}") await workflow.execute_activity( - activity=ACTIVITY_NSLCM_NO_OP, - arg=input, - activity_id=f"{ACTIVITY_NSLCM_NO_OP}-{self.op_id}", - schedule_to_close_timeout=LcmOperationWorkflow.default_schedule_to_close_timeout, - retry_policy=LcmOperationWorkflow.retry_policy, + activity=NsLcmNoOp.__name__, + arg=workflow_input, + activity_id=f"{NsLcmNoOp.__name__}-{self.op_id}", + schedule_to_close_timeout=NsNoOpWorkflow.default_schedule_to_close_timeout, + retry_policy=NsNoOpWorkflow.retry_policy, ) diff --git a/osm_lcm/temporal/ns_activities.py b/osm_lcm/temporal/ns_activities.py index 8c7c182..f25f78a 100644 --- a/osm_lcm/temporal/ns_activities.py +++ b/osm_lcm/temporal/ns_activities.py @@ -14,117 +14,46 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging +from temporalio import activity from time import time -from osm_common.dataclasses.temporal_dataclasses import ( - GetNsRecordInput, - GetNsRecordOutput, - GetVnfDetailsInput, - GetVnfDetailsOutput, - UpdateNsStateInput, -) -from osm_common.temporal_constants import ( - ACTIVITY_GET_NS_RECORD, - ACTIVITY_GET_VNF_DETAILS, - ACTIVITY_UPDATE_NS_STATE, +from osm_common.temporal.activities.ns import ( + GetNsRecord, + GetVnfDetails, + UpdateNsState, ) -from osm_lcm.data_utils.database.database import Database -from temporalio import activity - - -class NsOperations: - def __init__(self, db: Database): - self.db: Database = db - self.logger = logging.getLogger(f"lcm.act.{self.__class__.__name__}") - - @activity.defn(name=ACTIVITY_GET_VNF_DETAILS) - async def get_vnf_details( - self, get_vnf_details_input: GetVnfDetailsInput - ) -> GetVnfDetailsOutput: - """ - Gets the list of VNF record IDs, VNF member-index-refs for a given NS record ID. - Collaborators: - DB Read: vnfrs - Raises (Retryable): - DbException If the target DB record does not exist or DB is not reachable. - - Activity Lifecycle: - This activity will not report a heartbeat due to its short-running nature. - - Since this activity only reads from the DB, it is safe to retry, although - you may wish to have some back-off policy. - """ - vnfrs = self.db.get_list("vnfrs", {"nsr-id-ref": get_vnf_details_input.ns_uuid}) - return GetVnfDetailsOutput( +class GetVnfDetailsImpl(GetVnfDetails): + @activity.defn(name=GetVnfDetails.__name__) + async def __call__( + self, activity_input: GetVnfDetails.Input + ) -> GetVnfDetails.Output: + vnfrs = self.db.get_list("vnfrs", {"nsr-id-ref": activity_input.ns_uuid}) + return GetVnfDetails.Output( vnf_details=[(vnfr["id"], vnfr["member-vnf-index-ref"]) for vnfr in vnfrs] ) - @activity.defn(name=ACTIVITY_GET_NS_RECORD) - async def get_ns_record( - self, get_ns_record_input: GetNsRecordInput - ) -> GetNsRecordOutput: - """Gets the NS record from Database. - - Collaborators: - DB Read: nsrs - - Raises (retryable): - DbException: If DB read operations fail, the collection or DB record ID does not exist. - - Activity Lifecycle: - This activity should complete relatively quickly (less than 10 - second). - This activity will not report a heartbeat due to its - short-running nature. - - This is an idempotent activity. - - """ - nsr = self.db.get_one("nsrs", {"_id": get_ns_record_input.nsr_uuid}) +class GetNsRecordImpl(GetNsRecord): + @activity.defn(name=GetNsRecord.__name__) + async def __call__(self, activity_input: GetNsRecord.Input) -> GetNsRecord.Output: + nsr = self.db.get_one("nsrs", {"_id": activity_input.nsr_uuid}) self.logger.debug("Got the nsr from Database for VNF operations.") - return GetNsRecordOutput(nsr=nsr) - - -class NsDbActivity: - - """Perform Database operations for NS accounts. - - Args: - db (database): Data Access Object - """ + return GetNsRecord.Output(nsr=nsr) - def __init__(self, db: Database): - self.db: Database = db - self.logger = logging.getLogger(f"lcm.act.{self.__class__.__name__}") - @activity.defn(name=ACTIVITY_UPDATE_NS_STATE) - async def update_ns_state(self, data: UpdateNsStateInput) -> None: - """ - Changes the state of the NS itself. - - Collaborators: - DB Write: nsrs - - Raises (Retryable): - DbException If the target DB record does not exist or DB is not reachable. - - Activity Lifecycle: - This activity will not report a heartbeat due to its - short-running nature. - - As this is a direct DB update, it is not recommended to have - any specific retry policy - """ +class UpdateNsStateImpl(UpdateNsState): + @activity.defn(name=UpdateNsState.__name__) + async def __call__(self, activity_input: UpdateNsState.Input) -> None: update_ns_state = { - "nsState": data.state.name, + "nsState": activity_input.state.name, # "errorDescription" : data.message, - "_admin.nsState": data.state.name, - "_admin.detailed-status": data.message, + "_admin.nsState": activity_input.state.name, + "_admin.detailed-status": activity_input.message, "_admin.modified": time(), } - self.db.set_one("nsrs", {"_id": data.ns_uuid}, update_ns_state) - self.logger.debug(f"Updated NS {data.ns_uuid} to {data.state.name}") + self.db.set_one("nsrs", {"_id": activity_input.ns_uuid}, update_ns_state) + self.logger.debug( + f"Updated NS {activity_input.ns_uuid} to {activity_input.state.name}" + ) diff --git a/osm_lcm/temporal/ns_workflows.py b/osm_lcm/temporal/ns_workflows.py index 6281ee6..58bb40e 100644 --- a/osm_lcm/temporal/ns_workflows.py +++ b/osm_lcm/temporal/ns_workflows.py @@ -17,86 +17,74 @@ import asyncio import traceback -from osm_common.dataclasses.temporal_dataclasses import ( - GetNsRecordInput, - GetNsRecordOutput, - GetVnfDetailsInput, - GetVnfDetailsOutput, - ModelInfo, - NsLcmOperationInput, - NsState, - UpdateNsStateInput, - VnfInstantiateInput, +from osm_common.temporal.activities.paas import CreateModel +from osm_common.temporal.activities.ns import ( + GetVnfDetails, + GetNsRecord, + UpdateNsState, ) -from osm_common.temporal_constants import ( - ACTIVITY_CREATE_MODEL, - ACTIVITY_GET_NS_RECORD, - ACTIVITY_GET_VNF_DETAILS, - ACTIVITY_UPDATE_NS_STATE, - WORKFLOW_NS_INSTANTIATE, - WORKFLOW_VNF_INSTANTIATE, -) -from osm_lcm.temporal.lcm_workflows import LcmOperationWorkflow +from osm_common.temporal.workflows.lcm import LcmOperationWorkflow +from osm_common.temporal.workflows.ns import NsInstantiateWorkflow +from osm_common.temporal.workflows.vnf import VnfInstantiateWorkflow +from osm_common.temporal.states import NsState from temporalio import workflow from temporalio.converter import value_to_type from temporalio.exceptions import ActivityError, ChildWorkflowError -@workflow.defn(name=WORKFLOW_NS_INSTANTIATE, sandboxed=LcmOperationWorkflow._SANDBOXED) -class NsInstantiateWorkflow(LcmOperationWorkflow): - """Instantiate a NS""" - +@workflow.defn(name=NsInstantiateWorkflow.__name__, sandboxed=False) +class NsInstantiateWorkflowImpl(LcmOperationWorkflow): @workflow.run - async def wrap_nslcmop(self, input: NsLcmOperationInput) -> None: - await super().wrap_nslcmop(input=input) + async def wrap_nslcmop(self, workflow_input: NsInstantiateWorkflow.Input) -> None: + await super().wrap_nslcmop(workflow_input=workflow_input) - async def workflow(self, input: NsLcmOperationInput) -> None: - self.logger.info(f"Executing {WORKFLOW_NS_INSTANTIATE} with {input}") + async def run(self, workflow_input: NsInstantiateWorkflow.Input) -> None: + self.logger.info(f"Executing {NsInstantiateWorkflow.__name__} with {input}") # TODO: Can we clean up the input? Perhaps this workflow could receive NsInstantiateInput directly. - ns_uuid = input.nslcmop["nsInstanceId"] - vim_uuid = input.nslcmop["operationParams"]["vimAccountId"] + ns_uuid = workflow_input.nslcmop["nsInstanceId"] + vim_uuid = workflow_input.nslcmop["operationParams"]["vimAccountId"] model_name = self._get_namespace(ns_uuid, vim_uuid) try: await workflow.execute_activity( - activity=ACTIVITY_CREATE_MODEL, - arg=ModelInfo(vim_uuid=vim_uuid, model_name=model_name), - activity_id=f"{ACTIVITY_CREATE_MODEL}-{ns_uuid}", - schedule_to_close_timeout=LcmOperationWorkflow.default_schedule_to_close_timeout, - retry_policy=LcmOperationWorkflow.no_retry_policy, + activity=CreateModel.__name__, + arg=CreateModel.Input(vim_uuid=vim_uuid, model_name=model_name), + activity_id=f"{CreateModel.__name__}-{ns_uuid}", + schedule_to_close_timeout=NsInstantiateWorkflow.default_schedule_to_close_timeout, + retry_policy=NsInstantiateWorkflow.no_retry_policy, ) activities_results = await asyncio.gather( workflow.execute_activity( - activity=ACTIVITY_GET_VNF_DETAILS, - arg=GetVnfDetailsInput(ns_uuid=ns_uuid), - activity_id=f"{ACTIVITY_GET_VNF_DETAILS}-{ns_uuid}", - schedule_to_close_timeout=LcmOperationWorkflow.default_schedule_to_close_timeout, - retry_policy=LcmOperationWorkflow.no_retry_policy, + activity=GetVnfDetails.__name__, + arg=GetVnfDetails.Input(ns_uuid=ns_uuid), + activity_id=f"{GetVnfDetails.__name__}-{ns_uuid}", + schedule_to_close_timeout=NsInstantiateWorkflow.default_schedule_to_close_timeout, + retry_policy=NsInstantiateWorkflow.no_retry_policy, ), workflow.execute_activity( - activity=ACTIVITY_GET_NS_RECORD, - arg=GetNsRecordInput(nsr_uuid=ns_uuid), - activity_id=f"{ACTIVITY_GET_NS_RECORD}-{ns_uuid}", - schedule_to_close_timeout=LcmOperationWorkflow.default_schedule_to_close_timeout, - retry_policy=LcmOperationWorkflow.no_retry_policy, + activity=GetNsRecord.__name__, + arg=GetNsRecord.Input(nsr_uuid=ns_uuid), + activity_id=f"{GetNsRecord.__name__}-{ns_uuid}", + schedule_to_close_timeout=NsInstantiateWorkflow.default_schedule_to_close_timeout, + retry_policy=NsInstantiateWorkflow.no_retry_policy, ), ) get_vnf_details, get_ns_record = value_to_type( - GetVnfDetailsOutput, activities_results[0] - ), value_to_type(GetNsRecordOutput, activities_results[1]) + GetVnfDetails.Output, activities_results[0] + ), value_to_type(GetNsRecord.Output, activities_results[1]) await asyncio.gather( *( workflow.execute_child_workflow( - workflow=WORKFLOW_VNF_INSTANTIATE, - arg=VnfInstantiateInput( + workflow=VnfInstantiateWorkflow.__name__, + arg=VnfInstantiateWorkflow.Input( vnfr_uuid=vnfr_uuid, model_name=model_name, - instantiation_config=NsInstantiateWorkflow.get_vnf_config( + instantiation_config=NsInstantiateWorkflowImpl.get_vnf_config( vnf_member_index_ref, get_ns_record.nsr ), ), - id=f"{WORKFLOW_VNF_INSTANTIATE}-{vnfr_uuid}", + id=f"{VnfInstantiateWorkflow.__name__}-{vnfr_uuid}", ) for vnfr_uuid, vnf_member_index_ref in get_vnf_details.vnf_details ) @@ -105,19 +93,25 @@ class NsInstantiateWorkflow(LcmOperationWorkflow): except ActivityError as e: 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}") + self.logger.error( + f"{NsInstantiateWorkflow.__name__} failed with {err_details}" + ) raise e except ChildWorkflowError as e: err_details = str(e.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}") + self.logger.error( + f"{NsInstantiateWorkflow.__name__} failed with {err_details}" + ) raise e except Exception as 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}") + self.logger.error( + f"{NsInstantiateWorkflow.__name__} failed with {err_details}" + ) raise e await self.update_ns_state(ns_uuid, NsState.INSTANTIATED, "Done") @@ -128,13 +122,13 @@ class NsInstantiateWorkflow(LcmOperationWorkflow): state: NsState, message: str, ) -> None: - input = UpdateNsStateInput(ns_uuid, state, message) + activity_input = UpdateNsState.Input(ns_uuid, state, message) await workflow.execute_activity( - activity=ACTIVITY_UPDATE_NS_STATE, - arg=input, - activity_id=f"{ACTIVITY_UPDATE_NS_STATE}-{ns_uuid}", - schedule_to_close_timeout=LcmOperationWorkflow.default_schedule_to_close_timeout, - retry_policy=LcmOperationWorkflow.retry_policy, + activity=UpdateNsState.__name__, + arg=activity_input, + activity_id=f"{UpdateNsState.__name__}-{ns_uuid}", + schedule_to_close_timeout=NsInstantiateWorkflow.default_schedule_to_close_timeout, + retry_policy=NsInstantiateWorkflow.retry_policy, ) def _get_namespace(self, ns_id: str, vim_id: str) -> str: diff --git a/osm_lcm/temporal/vdu_workflows.py b/osm_lcm/temporal/vdu_workflows.py index 7349535..8dc5ba9 100644 --- a/osm_lcm/temporal/vdu_workflows.py +++ b/osm_lcm/temporal/vdu_workflows.py @@ -15,20 +15,15 @@ # limitations under the License. from datetime import timedelta -import logging import traceback -from osm_common.dataclasses.temporal_dataclasses import ( - VduInstantiateInput, - CheckCharmStatusInput, +from osm_common.temporal.activities.paas import ( + DeployCharm, + CheckCharmStatus, ) +from osm_common.temporal.workflows.vdu import VduInstantiateWorkflow +from osm_common.temporal_task_queues.task_queues_mappings import LCM_TASK_QUEUE -from osm_common.temporal_constants import ( - ACTIVITY_DEPLOY_CHARM, - ACTIVITY_CHECK_CHARM_STATUS, - LCM_TASK_QUEUE, - WORKFLOW_VDU_INSTANTIATE, -) from temporalio import workflow from temporalio.common import RetryPolicy from temporalio.exceptions import ActivityError @@ -38,51 +33,58 @@ retry_policy = RetryPolicy(maximum_attempts=3) default_schedule_to_close_timeout = timedelta(minutes=10) -@workflow.defn(name=WORKFLOW_VDU_INSTANTIATE, sandboxed=_SANDBOXED) -class VduInstantiateWorkflow: - """Instantiate a VDU""" - - def __init__(self): - self.logger = logging.getLogger(f"lcm.wfl.{self.__class__.__name__}") - +@workflow.defn(name=VduInstantiateWorkflow.__name__, sandboxed=False) +class VduInstantiateWorkflowImpl(VduInstantiateWorkflow): @workflow.run - async def run(self, input: VduInstantiateInput) -> None: + async def run(self, workflow_input: VduInstantiateWorkflow.Input) -> None: + deploy_charm_input = DeployCharm.Input( + vim_uuid=workflow_input.vim_uuid, + model_name=workflow_input.model_name, + charm_info=workflow_input.charm_info, + constraints=workflow_input.constraints, + cloud=workflow_input.cloud, + config=workflow_input.config, + ) try: - self.logger.info(f"Deploying VDU `{input.charm_info.app_name}`") + self.logger.info(f"Deploying VDU `{workflow_input.charm_info.app_name}`") await workflow.execute_activity( - activity=ACTIVITY_DEPLOY_CHARM, - arg=input, - activity_id=f"{ACTIVITY_DEPLOY_CHARM}-{input.vim_uuid}", + activity=DeployCharm.__name__, + arg=deploy_charm_input, + activity_id=f"{DeployCharm.__name__}-{workflow_input.vim_uuid}", task_queue=LCM_TASK_QUEUE, schedule_to_close_timeout=default_schedule_to_close_timeout, retry_policy=retry_policy, ) self.logger.info( - f"Waiting for VDU `{input.charm_info.app_name}` to become ready" + f"Waiting for VDU `{workflow_input.charm_info.app_name}` to become ready" ) await workflow.execute_activity( - activity=ACTIVITY_CHECK_CHARM_STATUS, - arg=CheckCharmStatusInput( - vim_uuid=input.vim_uuid, - model_name=input.model_name, - application_name=input.charm_info.app_name, + activity=CheckCharmStatus.__name__, + arg=CheckCharmStatus.Input( + vim_uuid=workflow_input.vim_uuid, + model_name=workflow_input.model_name, + application_name=workflow_input.charm_info.app_name, ), - activity_id=f"{ACTIVITY_CHECK_CHARM_STATUS}-{input.vim_uuid}", + activity_id=f"{CheckCharmStatus.__name__}-{workflow_input.vim_uuid}", task_queue=LCM_TASK_QUEUE, start_to_close_timeout=timedelta(minutes=5), heartbeat_timeout=timedelta(seconds=30), retry_policy=retry_policy, ) - self.logger.info(f"VDU `{input.charm_info.app_name}` is ready") + self.logger.info(f"VDU `{workflow_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}") + self.logger.error( + f"{VduInstantiateWorkflow.__name__} failed with {err_details}" + ) raise e except Exception as e: err_details = str(traceback.format_exc()) - self.logger.error(f"{WORKFLOW_VDU_INSTANTIATE} failed with {err_details}") + self.logger.error( + f"{VduInstantiateWorkflow.__name__} failed with {err_details}" + ) raise e diff --git a/osm_lcm/temporal/vim_activities.py b/osm_lcm/temporal/vim_activities.py index e9db668..708c423 100644 --- a/osm_lcm/temporal/vim_activities.py +++ b/osm_lcm/temporal/vim_activities.py @@ -14,115 +14,51 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging +from temporalio import activity from time import time - -from osm_common.temporal_constants import ( - ACTIVITY_DELETE_VIM, - ACTIVITY_UPDATE_VIM_OPERATION_STATE, - ACTIVITY_UPDATE_VIM_STATE, -) -from osm_common.dataclasses.temporal_dataclasses import ( - DeleteVimInput, - UpdateVimOperationStateInput, - UpdateVimStateInput, +from osm_common.temporal.activities.vim import ( + UpdateVimState, + UpdateVimOperationState, + DeleteVimRecord, ) -from osm_lcm.data_utils.database.database import Database -from temporalio import activity - - -class VimDbActivity: - """Perform Database operations for VIM accounts. - - Args: - db (Database): Data Access Object - """ - - def __init__(self, db: Database): - self.db: Database = db - self.logger = logging.getLogger(f"lcm.act.{self.__class__.__name__}") - - @activity.defn(name=ACTIVITY_UPDATE_VIM_STATE) - async def update_vim_state(self, data: UpdateVimStateInput) -> None: - """ - Changes the state of the VIM itself. Should be either - ENABLED or ERROR, however this activity does not validate - the state as no validation was done in OSM previously. - - Collaborators: - DB Write: vim_accounts - Raises (Retryable): - DbException If the target DB record does not exist or DB is not reachable. - Activity Lifecycle: - This activity will not report a heartbeat due to its - short-running nature. - - As this is a direct DB update, it is not recommended to have - any specific retry policy - """ +class UpdateVimStateImpl(UpdateVimState): + @activity.defn(name=UpdateVimState.__name__) + async def __call__(self, activity_input: UpdateVimState.Input) -> None: update_vim_state = { - "_admin.operationalState": data.operational_state.name, - "_admin.detailed-status": data.message, + "_admin.operationalState": activity_input.operational_state.name, + "_admin.detailed-status": activity_input.message, "_admin.modified": time(), } - self.db.set_one("vim_accounts", {"_id": data.vim_uuid}, update_vim_state) + self.db.set_one( + "vim_accounts", {"_id": activity_input.vim_uuid}, update_vim_state + ) self.logger.debug( - f"Updated VIM {data.vim_uuid} to {data.operational_state.name}" + f"Updated VIM {activity_input.vim_uuid} to {activity_input.operational_state.name}" ) - @activity.defn(name=ACTIVITY_UPDATE_VIM_OPERATION_STATE) - async def update_vim_operation_state( - self, data: UpdateVimOperationStateInput - ) -> None: - """ - Changes the state of a VIM operation task. Should be done to - indicate progress, or completion of the task itself. - - Collaborators: - DB Write: vim_accounts - - Raises (Retryable): - DbException If the target DB record does not exist or DB is not reachable. - - Activity Lifecycle: - This activity will not report a heartbeat due to its - short-running nature. - As this is a direct DB update, it is not recommended to have - any specific retry policy - """ +class UpdateVimOperationStateImpl(UpdateVimOperationState): + @activity.defn(name=UpdateVimOperationState.__name__) + async def __call__(self, activity_input: UpdateVimOperationState.Input) -> None: update_operation_state = { - f"_admin.operations.{format(data.op_id)}.operationState": data.op_state.name, - f"_admin.operations.{format(data.op_id)}.detailed-status": data.message, + f"_admin.operations.{format(activity_input.op_id)}.operationState": activity_input.op_state.name, + f"_admin.operations.{format(activity_input.op_id)}.detailed-status": activity_input.message, "_admin.current_operation": None, } - self.db.set_one("vim_accounts", {"_id": data.vim_uuid}, update_operation_state) + self.db.set_one( + "vim_accounts", {"_id": activity_input.vim_uuid}, update_operation_state + ) self.logger.debug( - f"Updated VIM {data.vim_uuid} OP ID {data.op_id} to {data.op_state.name}" + f"Updated VIM {activity_input.vim_uuid} OP ID {activity_input.op_id} to {activity_input.op_state.name}" ) - @activity.defn(name=ACTIVITY_DELETE_VIM) - async def delete_vim_record(self, data: DeleteVimInput) -> None: - """ - Deletes the VIM record from the database. - - Collaborators: - DB Delete: vim_accounts - - Raises (Retryable): - DbException If the target DB record does not exist or DB is not reachable. - - Activity Lifecycle: - This activity will not report a heartbeat due to its - short-running nature. - - As this is a direct DB update, it is not recommended to have - any specific retry policy - """ - self.db.del_one("vim_accounts", {"_id": data.vim_uuid}) - self.logger.debug(f"Removed VIM {data.vim_uuid}") +class DeleteVimRecordImpl(DeleteVimRecord): + @activity.defn(name=DeleteVimRecord.__name__) + async def __call__(self, activity_input: DeleteVimRecord.Input) -> None: + self.db.del_one("vim_accounts", {"_id": activity_input.vim_uuid}) + self.logger.debug(f"Removed VIM {activity_input.vim_uuid}") diff --git a/osm_lcm/temporal/vim_workflows.py b/osm_lcm/temporal/vim_workflows.py index 5d6b08c..5123132 100644 --- a/osm_lcm/temporal/vim_workflows.py +++ b/osm_lcm/temporal/vim_workflows.py @@ -15,28 +15,21 @@ # limitations under the License. from datetime import timedelta -import logging import traceback -from osm_common.dataclasses.temporal_dataclasses import ( - DeleteVimInput, - TestVimConnectivityInput, - UpdateVimOperationStateInput, - UpdateVimStateInput, - VimOperationInput, - VimState, - VimOperationState, +from osm_common.temporal_task_queues.task_queues_mappings import LCM_TASK_QUEUE +from osm_common.temporal.states import VimState, VimOperationState +from osm_common.temporal.workflows.vim import ( + VimCreateWorkflow, + VimUpdateWorkflow, + VimDeleteWorkflow, ) -from osm_common.temporal_constants import ( - ACTIVITY_TEST_VIM_CONNECTIVITY, - ACTIVITY_UPDATE_VIM_OPERATION_STATE, - ACTIVITY_UPDATE_VIM_STATE, - ACTIVITY_DELETE_VIM, - LCM_TASK_QUEUE, - WORKFLOW_VIM_CREATE, - WORKFLOW_VIM_UPDATE, - WORKFLOW_VIM_DELETE, +from osm_common.temporal.activities.vim import ( + DeleteVimRecord, + UpdateVimState, + UpdateVimOperationState, ) +from osm_common.temporal.activities.paas import TestVimConnectivity from temporalio import workflow from temporalio.common import RetryPolicy from temporalio.exceptions import ActivityError @@ -46,24 +39,24 @@ retry_policy = RetryPolicy(maximum_attempts=3) default_schedule_to_close_timeout = timedelta(minutes=10) -@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.defn(name=VimCreateWorkflow.__name__, sandboxed=False) +class VimCreateWorkflowImpl(VimCreateWorkflow): @workflow.run - async def run(self, input: VimOperationInput) -> None: - vim_state = UpdateVimStateInput(input.vim_uuid, VimState.ENABLED, "Done") - op_state = UpdateVimOperationStateInput( - input.vim_uuid, input.op_id, VimOperationState.COMPLETED, "Done" + async def run(self, workflow_input: VimCreateWorkflow.Input) -> None: + vim_state = UpdateVimState.Input( + workflow_input.vim_uuid, VimState.ENABLED, "Done" + ) + op_state = UpdateVimOperationState.Input( + workflow_input.vim_uuid, + workflow_input.op_id, + VimOperationState.COMPLETED, + "Done", ) try: await workflow.execute_activity( - activity=ACTIVITY_TEST_VIM_CONNECTIVITY, - arg=TestVimConnectivityInput(input.vim_uuid), - activity_id=f"{ACTIVITY_TEST_VIM_CONNECTIVITY}-{input.vim_uuid}", + activity=TestVimConnectivity.__name__, + arg=TestVimConnectivity.Input(workflow_input.vim_uuid), + activity_id=f"{TestVimConnectivity.__name__}-{workflow_input.vim_uuid}", task_queue=LCM_TASK_QUEUE, schedule_to_close_timeout=default_schedule_to_close_timeout, retry_policy=retry_policy, @@ -71,64 +64,72 @@ class VimCreateWorkflow: except ActivityError as e: error_details = str(e.cause.with_traceback(e.__traceback__)) - vim_state = UpdateVimStateInput( - input.vim_uuid, VimState.ERROR, str(e.cause.message) + vim_state = UpdateVimState.Input( + workflow_input.vim_uuid, VimState.ERROR, str(e.cause.message) ) - op_state = UpdateVimOperationStateInput( - input.vim_uuid, - input.op_id, + op_state = UpdateVimOperationState.Input( + workflow_input.vim_uuid, + workflow_input.op_id, VimOperationState.FAILED, error_details, ) await self.update_states(op_state, vim_state) - self.logger.error(f"{WORKFLOW_VIM_CREATE} failed with {error_details}") + self.logger.error( + f"{VimCreateWorkflow.__name__} 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, + vim_state = UpdateVimState.Input( + workflow_input.vim_uuid, VimState.ERROR, str(e) + ) + op_state = UpdateVimOperationState.Input( + workflow_input.vim_uuid, + workflow_input.op_id, VimOperationState.FAILED, error_details, ) await self.update_states(op_state, vim_state) - self.logger.error(f"{WORKFLOW_VIM_CREATE} failed with {error_details}") + self.logger.error( + f"{VimCreateWorkflow.__name__} failed with {error_details}" + ) raise e await self.update_states(op_state, vim_state) async def update_states( self, - op_state: UpdateVimOperationStateInput, - vim_state: UpdateVimStateInput, + op_state: UpdateVimOperationState.Input, + vim_state: UpdateVimState.Input, ): raised_exceptions = [] try: await workflow.execute_activity( - activity=ACTIVITY_UPDATE_VIM_STATE, + activity=UpdateVimState.__name__, arg=vim_state, - activity_id=f"{ACTIVITY_UPDATE_VIM_STATE}-{vim_state.vim_uuid}", + activity_id=f"{UpdateVimState.__name__}-{vim_state.vim_uuid}", task_queue=LCM_TASK_QUEUE, schedule_to_close_timeout=default_schedule_to_close_timeout, retry_policy=retry_policy, ) except ActivityError as e: raised_exceptions.append(e) - self.logger.error(f"{WORKFLOW_VIM_CREATE} failed to update VIM state.") + self.logger.error( + f"{VimCreateWorkflow.__name__} failed to update VIM state." + ) try: await workflow.execute_activity( - activity=ACTIVITY_UPDATE_VIM_OPERATION_STATE, + activity=UpdateVimOperationState.__name__, arg=op_state, - activity_id=f"{ACTIVITY_UPDATE_VIM_OPERATION_STATE}-{op_state.vim_uuid}", + activity_id=f"{UpdateVimOperationState.__name__}-{op_state.vim_uuid}", task_queue=LCM_TASK_QUEUE, schedule_to_close_timeout=default_schedule_to_close_timeout, retry_policy=retry_policy, ) except ActivityError as e: self.logger.error( - f"{WORKFLOW_VIM_CREATE} failed to update VIM operation state." + f"{VimCreateWorkflow.__name__} failed to update VIM operation state." ) raised_exceptions.append(e) @@ -138,25 +139,21 @@ class VimCreateWorkflow: raise raised_exceptions[0] -@workflow.defn(name=WORKFLOW_VIM_UPDATE, sandboxed=_SANDBOXED) -class VimUpdateWorkflow(VimCreateWorkflow): - """Updates VIM account state by validating the VIM connectivity.""" - +@workflow.defn(name=VimUpdateWorkflow.__name__, sandboxed=False) +class VimUpdateWorkflowImpl(VimCreateWorkflowImpl): @workflow.run - async def run(self, input: VimOperationInput) -> None: - await super().run(input) - + async def run(self, workflow_input: VimUpdateWorkflow.Input) -> None: + await super().run(workflow_input) -@workflow.defn(name=WORKFLOW_VIM_DELETE, sandboxed=_SANDBOXED) -class VimDeleteWorkflow: - """Deletes VIM accounts.""" +@workflow.defn(name=VimDeleteWorkflow.__name__, sandboxed=False) +class VimDeleteWorkflowImpl(VimDeleteWorkflow): @workflow.run - async def run(self, input: VimOperationInput) -> None: + async def run(self, workflow_input: VimDeleteWorkflow.Input) -> None: await workflow.execute_activity( - activity=ACTIVITY_DELETE_VIM, - arg=DeleteVimInput(input.vim_uuid), - activity_id=f"{ACTIVITY_UPDATE_VIM_STATE}-{input.vim_uuid}", + activity=DeleteVimRecord.__name__, + arg=DeleteVimRecord.Input(workflow_input.vim_uuid), + activity_id=f"{DeleteVimRecord.__name__}-{workflow_input.vim_uuid}", task_queue=LCM_TASK_QUEUE, schedule_to_close_timeout=default_schedule_to_close_timeout, retry_policy=retry_policy, diff --git a/osm_lcm/temporal/vnf_activities.py b/osm_lcm/temporal/vnf_activities.py index 9581db0..156bc59 100644 --- a/osm_lcm/temporal/vnf_activities.py +++ b/osm_lcm/temporal/vnf_activities.py @@ -13,158 +13,65 @@ # See the License for the specific language governing permissions and # limitations under the License. -import logging +from temporalio import activity from typing import List, Any -from osm_common.temporal_constants import ( - ACTIVITY_CHANGE_VNF_STATE, - ACTIVITY_CHANGE_VNF_INSTANTIATION_STATE, - ACTIVITY_GET_TASK_QUEUE, - ACTIVITY_GET_VIM_CLOUD, - ACTIVITY_GET_VNF_DESCRIPTOR, - ACTIVITY_GET_VNF_RECORD, - ACTIVITY_SEND_NOTIFICATION_FOR_VNF, - ACTIVITY_SET_VNF_MODEL, - VIM_TYPE_TASK_QUEUE_MAPPINGS, +from osm_common.temporal.activities.vnf import ( + GetTaskQueue, + GetVimCloud, + GetVnfDescriptor, + GetVnfRecord, + ChangeVnfState, + ChangeVnfInstantiationState, + SetVnfModel, + SendNotificationForVnf, ) -from osm_common.dataclasses.temporal_dataclasses import ( - ChangeVnfInstantiationStateInput, - ChangeVnfStateInput, - GetTaskQueueInput, - GetTaskQueueOutput, - GetVimCloudInput, - GetVimCloudOutput, - GetVnfDescriptorInput, - GetVnfDescriptorOutput, - GetVnfRecordInput, - GetVnfRecordOutput, - SetVnfModelInput, - VduComputeConstraints, +from osm_common.temporal.dataclasses_common import VduComputeConstraints +from osm_common.temporal_task_queues.task_queues_mappings import ( + VIM_TYPE_TASK_QUEUE_MAPPINGS, ) -from osm_lcm.data_utils.database.database import Database -from temporalio import activity - CONFIG_IDENTIFIER = "config::" -class VnfOperations: - def __init__(self, db: Database): - self.db: Database = db - self.logger = logging.getLogger(f"lcm.act.{self.__class__.__name__}") - - @activity.defn(name=ACTIVITY_GET_TASK_QUEUE) - async def get_task_queue( - self, get_task_queue_input: GetTaskQueueInput - ) -> GetTaskQueueOutput: - """Finds the appropriate task queue according to VIM type of VNF. - - Collaborators: - DB read: vim_accounts, vnfrs - - Raises (retryable): - DbException: If DB read operations fail, the collection or DB record ID does not exist. - - Activity Lifecycle: - This activity should complete relatively quickly (less than a - second). However, it would be reasonable to wait up to 10 - seconds. - - This activity will not report a heartbeat due to its - short-running nature. - - It is not necessary to implement a back-off strategy for this - activity, the operation is idempotent. - - """ - vnfr = self.db.get_one("vnfrs", {"_id": get_task_queue_input.vnfr_uuid}) +class GetTaskQueueImpl(GetTaskQueue): + @activity.defn(name=GetTaskQueue.__name__) + async def __call__(self, activity_input: GetTaskQueue.Input) -> GetTaskQueue.Output: + vnfr = self.db.get_one("vnfrs", {"_id": activity_input.vnfr_uuid}) vim_record = self.db.get_one("vim_accounts", {"_id": vnfr["vim-account-id"]}) task_queue = VIM_TYPE_TASK_QUEUE_MAPPINGS[vim_record["vim_type"]] self.logger.debug(f"Got the task queue {task_queue} for VNF operations.") - return GetTaskQueueOutput(task_queue) - - @activity.defn(name=ACTIVITY_GET_VIM_CLOUD) - async def get_vim_cloud( - self, get_vim_cloud_input: GetVimCloudInput - ) -> GetVimCloudOutput: - """Finds the cloud by checking the VIM account of VNF. + return GetTaskQueue.Output(task_queue) - Collaborators: - DB Read: vnfrs, vim_accounts - Raises (retryable): - DbException: If DB read operations fail, the collection or DB record ID does not exist. - - Activity Lifecycle: - This activity should complete relatively quickly (less than a - second). However, it would be reasonable to wait up to 10 - seconds. - - This activity will not report a heartbeat due to its - short-running nature. - - It is not necessary to implement a back-off strategy for this - activity, the operation is idempotent. - - """ - vnfr = self.db.get_one("vnfrs", {"_id": get_vim_cloud_input.vnfr_uuid}) +class GetVimCloudImpl(GetVimCloud): + @activity.defn(name=GetVimCloud.__name__) + async def __call__(self, activity_input: GetVimCloud.Input) -> GetVimCloud.Output: + vnfr = self.db.get_one("vnfrs", {"_id": activity_input.vnfr_uuid}) vim_record = self.db.get_one("vim_accounts", {"_id": vnfr["vim-account-id"]}) cloud = vim_record["config"].get("cloud", "") self.logger.debug(f"Got the cloud type {cloud} for VNF operations.") - return GetVimCloudOutput(cloud=cloud) - - @activity.defn(name=ACTIVITY_GET_VNF_RECORD) - async def get_vnf_record( - self, get_vnf_record_input: GetVnfRecordInput - ) -> GetVnfRecordOutput: - """Gets the VNF record and VNF descriptor from Database. - - Collaborators: - DB read: vnfrs - - Raises (retryable): - DbException: If DB read operations fail, the collection or DB record ID does not exist. + return GetVimCloud.Output(cloud=cloud) - Activity Lifecycle: - This activity should complete relatively quickly (less than 10 - second). - This activity will not report a heartbeat due to its - short-running nature. - - This is an idempotent activity. - - """ - vnfr = self.db.get_one("vnfrs", {"_id": get_vnf_record_input.vnfr_uuid}) +class GetVnfRecordImpl(GetVnfRecord): + @activity.defn(name=GetVnfRecord.__name__) + async def __call__(self, activity_input: GetVnfRecord.Input) -> GetVnfRecord.Output: + vnfr = self.db.get_one("vnfrs", {"_id": activity_input.vnfr_uuid}) self.logger.debug("Got the vnfr from Database for VNF operations.") - return GetVnfRecordOutput(vnfr=vnfr) - - @activity.defn(name=ACTIVITY_GET_VNF_DESCRIPTOR) - async def get_vnf_descriptor( - self, get_vnf_descriptor_input: GetVnfDescriptorInput - ) -> GetVnfDescriptorOutput: - """Gets the VNF record and VNF descriptor from Database. - - Collaborators: - DB read: vnfds - - Raises (retryable): - DbException: If DB read operations fail, the collection or DB record ID does not exist. - - Activity Lifecycle: - This activity should complete relatively quickly (less than 10 - second). + return GetVnfRecord.Output(vnfr=vnfr) - This activity will not report a heartbeat due to its - short-running nature. - This is an idempotent activity. +class GetVnfDescriptorImpl(GetVnfDescriptor): + @activity.defn(name=GetVnfDescriptor.__name__) + async def __call__( + self, activity_input: GetVnfDescriptor.Input + ) -> GetVnfDescriptor.Output: + vnfd = self.db.get_one("vnfds", {"_id": activity_input.vnfd_uuid}) + return GetVnfDescriptor.Output(vnfd=vnfd) - """ - vnfd = self.db.get_one("vnfds", {"_id": get_vnf_descriptor_input.vnfd_uuid}) - self.logger.debug("Got the vnfr and vnfd from Database for VNF operations.") - return GetVnfDescriptorOutput(vnfd=vnfd) +class VnfSpecifications: @staticmethod def get_vdu_instantiation_params( vdu_id: str, vnf_instantiation_config: dict @@ -179,7 +86,7 @@ class VnfOperations: compute_desc_id = vdu.get("virtual-compute-desc") if not compute_desc_id: return VduComputeConstraints(cores=0, mem=0) - flavor_details = VnfOperations._get_flavor_details(compute_desc_id, vnfd) + flavor_details = VnfSpecifications._get_flavor_details(compute_desc_id, vnfd) if not flavor_details: return VduComputeConstraints(cores=0, mem=0) @@ -198,11 +105,11 @@ class VnfOperations: def get_application_config(vdu: dict, vdu_instantiation_config: dict) -> dict: configurable_properties = vdu.get("configurable-properties", []) - config_from_descriptor = VnfOperations._get_only_config_items( - VnfOperations._list_to_dict(configurable_properties) + config_from_descriptor = VnfSpecifications._get_only_config_items( + VnfSpecifications._list_to_dict(configurable_properties) ) - config_from_instantiation = VnfOperations._get_only_config_items( + config_from_instantiation = VnfSpecifications._get_only_config_items( vdu_instantiation_config ) return {**config_from_descriptor, **config_from_instantiation} @@ -224,125 +131,43 @@ class VnfOperations: } -class VnfDbActivity: - """Perform Database operations for VNF accounts. - - Args: - db (Database): Data Access Object - """ - - def __init__(self, db: Database): - self.db: Database = db - self.logger = logging.getLogger(f"lcm.act.{self.__class__.__name__}") - - @activity.defn(name=ACTIVITY_CHANGE_VNF_STATE) - async def change_vnf_state(self, vnf_state_input: ChangeVnfStateInput) -> None: - """Updates the VNF State in VNFR. - - Collaborators: - DB Write: vnfrs - - Raises (retryable): - DbException: If DB access/update fails, the collection or DB record ID does not exist. - - Activity Lifecycle: - This activity should complete relatively quickly (less than a - second). However, it would be reasonable to wait up to 10 - seconds. - - This activity will not report a heartbeat due to its - short-running nature. - - It is not necessary to implement a back-off strategy for this - activity, the operation is idempotent. - - """ - update_vnf_state = {"vnfState": vnf_state_input.state.name} - self.db.set_one("vnfrs", {"_id": vnf_state_input.vnfr_uuid}, update_vnf_state) +class ChangeVnfStateImpl(ChangeVnfState): + @activity.defn(name=ChangeVnfState.__name__) + async def __call__(self, activity_input: ChangeVnfState.Input) -> None: + update_vnf_state = {"vnfState": activity_input.state.name} + self.db.set_one("vnfrs", {"_id": activity_input.vnfr_uuid}, update_vnf_state) self.logger.debug( - f"VNF {vnf_state_input.vnfr_uuid} state is updated to {vnf_state_input.state.name}." + f"VNF {activity_input.vnfr_uuid} state is updated to {activity_input.state.name}." ) - @activity.defn(name=ACTIVITY_CHANGE_VNF_INSTANTIATION_STATE) - async def change_vnf_instantiation_state( - self, vnf_instantiation_state_input: ChangeVnfInstantiationStateInput - ) -> None: - """Updates the VNF Instantiation State in VNFR. - - Collaborators: - DB Write: vnfrs - - Raises (retryable): - DbException: If DB access or update fails, the collection or DB record ID does not exist. - - Activity Lifecycle: - This activity should complete relatively quickly (less than a - second). However, it would be reasonable to wait up to 10 - seconds. - - This activity will not report a heartbeat due to its - short-running nature. - It is not necessary to implement a back-off strategy for this - activity, the operation is idempotent. - - """ +class ChangeVnfInstantiationStateImpl(ChangeVnfInstantiationState): + @activity.defn(name=ChangeVnfInstantiationState.__name__) + async def __call__(self, activity_input: ChangeVnfInstantiationState.Input) -> None: update_vnf_instantiation_state = { - "instantiationState": vnf_instantiation_state_input.state.name + "instantiationState": activity_input.state.name } self.db.set_one( "vnfrs", - {"_id": vnf_instantiation_state_input.vnfr_uuid}, + {"_id": activity_input.vnfr_uuid}, update_vnf_instantiation_state, ) self.logger.debug( - f"VNF {vnf_instantiation_state_input.vnfr_uuid} state is updated to {vnf_instantiation_state_input.state.name}." + f"VNF {activity_input.vnfr_uuid} state is updated to {activity_input.state.name}." ) - @activity.defn(name=ACTIVITY_SET_VNF_MODEL) - async def set_vnf_model(self, set_vnf_model_input: SetVnfModelInput) -> None: - """Updates the model name of VNF in VNFR. - - Collaborators: - DB Write: vnfrs - - Raises (retryable): - DbException: If DB access or update fails, the collection or DB record ID does not exist. - - Activity Lifecycle: - This activity should complete relatively quickly (less than a - second). However, it would be reasonable to wait up to 10 - seconds. - - This activity will not report a heartbeat due to its - short-running nature. - - It is not necessary to implement a back-off strategy for this - activity, the operation is idempotent. - """ - update_namespace = {"namespace": set_vnf_model_input.model_name} - self.db.set_one( - "vnfrs", {"_id": set_vnf_model_input.vnfr_uuid}, update_namespace - ) +class SetVnfModelImpl(SetVnfModel): + @activity.defn(name=SetVnfModel.__name__) + async def __call__(self, activity_input: SetVnfModel.Input) -> None: + update_namespace = {"namespace": activity_input.model_name} + self.db.set_one("vnfrs", {"_id": activity_input.vnfr_uuid}, update_namespace) self.logger.debug( - f"VNF {set_vnf_model_input.vnfr_uuid} model name is updated to {set_vnf_model_input.model_name}." + f"VNF {activity_input.vnfr_uuid} model name is updated to {activity_input.model_name}." ) -class VnfSendNotifications: - """Perform Notification operations.""" - - def __init__(self): - self.logger = logging.getLogger(f"lcm.act.{self.__class__.__name__}") - - @activity.defn(name=ACTIVITY_SEND_NOTIFICATION_FOR_VNF) - async def send_notification_for_vnf( - self, input: ChangeVnfInstantiationStateInput - ) -> None: - """If VNF LCM operation state changes, send notification updates. - - This activity does nothing. - - """ +class SendNotificationForVnfImpl(SendNotificationForVnf): + @activity.defn(name=SendNotificationForVnf.__name__) + async def __call__(self, activity_input: SendNotificationForVnf.Input) -> None: self.logger.debug("Send notification for VNF not implemented.") diff --git a/osm_lcm/temporal/vnf_workflows.py b/osm_lcm/temporal/vnf_workflows.py index c121b05..940eeb9 100644 --- a/osm_lcm/temporal/vnf_workflows.py +++ b/osm_lcm/temporal/vnf_workflows.py @@ -13,49 +13,36 @@ # implied. # See the License for the specific language governing permissions and # limitations under the License. + import asyncio from datetime import timedelta -import logging import traceback from typing import Tuple -from osm_common.dataclasses.temporal_dataclasses import ( - ChangeVnfInstantiationStateInput, - ChangeVnfStateInput, - GetTaskQueueInput, - GetTaskQueueOutput, - GetVimCloudInput, - GetVimCloudOutput, - GetVnfDescriptorInput, - GetVnfDescriptorOutput, - GetVnfRecordInput, - GetVnfRecordOutput, - SetVnfModelInput, - VduInstantiateInput, - VnfInstantiateInput, - VnfInstantiationState, - VnfPrepareInput, - VnfState, +from osm_common.temporal.states import VnfInstantiationState, VnfState +from osm_common.temporal.activities.vnf import ( + ChangeVnfInstantiationState, + ChangeVnfState, + GetTaskQueue, + GetVimCloud, + SetVnfModel, + SendNotificationForVnf, + GetVnfDescriptor, + GetVnfRecord, ) -from osm_common.temporal_constants import ( - ACTIVITY_CHANGE_VNF_INSTANTIATION_STATE, - ACTIVITY_SEND_NOTIFICATION_FOR_VNF, - ACTIVITY_CHANGE_VNF_STATE, - ACTIVITY_GET_TASK_QUEUE, - ACTIVITY_GET_VIM_CLOUD, - ACTIVITY_GET_VNF_RECORD, - ACTIVITY_GET_VNF_DESCRIPTOR, - ACTIVITY_SET_VNF_MODEL, - LCM_TASK_QUEUE, - WORKFLOW_VDU_INSTANTIATE, - WORKFLOW_VNF_INSTANTIATE, - WORKFLOW_VNF_PREPARE, + +from osm_common.temporal.workflows.vnf import ( + VnfInstantiateWorkflow, + VnfPrepareWorkflow, ) +from osm_common.temporal.workflows.vdu import VduInstantiateWorkflow +from osm_common.temporal_task_queues.task_queues_mappings import LCM_TASK_QUEUE + from osm_lcm.temporal.juju_paas_activities import CharmInfoUtils -from osm_lcm.temporal.vnf_activities import VnfOperations +from osm_lcm.temporal.vnf_activities import VnfSpecifications from temporalio import workflow -from temporalio.converter import value_to_type from temporalio.common import RetryPolicy +from temporalio.converter import value_to_type from temporalio.exceptions import ActivityError, ChildWorkflowError _SANDBOXED = False @@ -63,40 +50,30 @@ retry_policy = RetryPolicy(maximum_attempts=3) default_schedule_to_close_timeout = timedelta(minutes=10) -@workflow.defn(name=WORKFLOW_VNF_INSTANTIATE, sandboxed=_SANDBOXED) -class VnfInstantiateWorkflow: - """Instantiate a VNF. - - Workflow Identifier: - It is recommended that the ID for the VNF is referred as a workflow - ID when invoking this workflow. - """ - - def __init__(self): - self.logger = logging.getLogger(f"lcm.wfl.{self.__class__.__name__}") - +@workflow.defn(name=VnfInstantiateWorkflow.__name__, sandboxed=False) +class VnfInstantiateWorkflowImpl(VnfInstantiateWorkflow): @workflow.run - async def run(self, input: VnfInstantiateInput) -> None: - self.logger.info(f"Deploying VNF {input.vnfr_uuid}") + async def run(self, workflow_input: VnfInstantiateWorkflow.Input) -> None: + self.logger.info(f"Deploying VNF {workflow_input.vnfr_uuid}") try: await self.update_vnf_instantiation_state( - ChangeVnfInstantiationStateInput( - vnfr_uuid=input.vnfr_uuid, + ChangeVnfInstantiationState.Input( + vnfr_uuid=workflow_input.vnfr_uuid, state=VnfInstantiationState.NOT_INSTANTIATED, ), ) await self.send_notification_for_vnf( - ChangeVnfInstantiationStateInput( - vnfr_uuid=input.vnfr_uuid, + ChangeVnfInstantiationState.Input( + vnfr_uuid=workflow_input.vnfr_uuid, state=VnfInstantiationState.NOT_INSTANTIATED, ), ) vnf_task_queue = value_to_type( - GetTaskQueueOutput, + GetTaskQueue.Output, await workflow.execute_activity( - activity=ACTIVITY_GET_TASK_QUEUE, - arg=GetTaskQueueInput(input.vnfr_uuid), - activity_id=f"{ACTIVITY_GET_TASK_QUEUE}-{input.vnfr_uuid}", + activity=GetTaskQueue.__name__, + arg=GetTaskQueue.Input(workflow_input.vnfr_uuid), + activity_id=f"{GetTaskQueue.__name__}-{workflow_input.vnfr_uuid}", task_queue=LCM_TASK_QUEUE, schedule_to_close_timeout=default_schedule_to_close_timeout, retry_policy=retry_policy, @@ -106,18 +83,18 @@ class VnfInstantiateWorkflow: self.logger.debug(f"Dependent task queue is {vnf_task_queue.task_queue}") await workflow.execute_child_workflow( - workflow=WORKFLOW_VNF_PREPARE, - arg=input, + workflow=VnfPrepareWorkflow.__name__, + arg=workflow_input, task_queue=vnf_task_queue.task_queue, - id=f"{WORKFLOW_VNF_PREPARE}-{input.vnfr_uuid}", + id=f"{VnfPrepareWorkflow.__name__}-{workflow_input.vnfr_uuid}", ) get_vnf_record = value_to_type( - GetVnfRecordOutput, + GetVnfRecord.Output, await workflow.execute_activity( - activity=ACTIVITY_GET_VNF_RECORD, - arg=GetVnfRecordInput(input.vnfr_uuid), - activity_id=f"{ACTIVITY_GET_VNF_RECORD}-{input.vnfr_uuid}", + activity=GetVnfRecord.__name__, + arg=GetVnfRecord.Input(workflow_input.vnfr_uuid), + activity_id=f"{GetVnfRecord.__name__}-{workflow_input.vnfr_uuid}", task_queue=vnf_task_queue.task_queue, schedule_to_close_timeout=default_schedule_to_close_timeout, retry_policy=retry_policy, @@ -125,118 +102,142 @@ class VnfInstantiateWorkflow: ) activities_results = await asyncio.gather( workflow.execute_activity( - activity=ACTIVITY_GET_VNF_DESCRIPTOR, - arg=GetVnfDescriptorInput(get_vnf_record.vnfr["vnfd-id"]), - activity_id=f"{ACTIVITY_GET_VNF_DESCRIPTOR}-{get_vnf_record.vnfr['vnfd-id']}", + activity=GetVnfDescriptor.__name__, + arg=GetVnfDescriptor.Input(get_vnf_record.vnfr["vnfd-id"]), + activity_id=f"{GetVnfDescriptor.__name__}-{get_vnf_record.vnfr['vnfd-id']}", task_queue=vnf_task_queue.task_queue, schedule_to_close_timeout=default_schedule_to_close_timeout, retry_policy=retry_policy, ), workflow.execute_activity( - activity=ACTIVITY_GET_VIM_CLOUD, - arg=GetVimCloudInput(input.vnfr_uuid), - activity_id=f"{ACTIVITY_GET_VIM_CLOUD}-{input.vnfr_uuid}", + activity=GetVimCloud.__name__, + arg=GetVimCloud.Input(workflow_input.vnfr_uuid), + activity_id=f"{GetVimCloud.__name__}-{workflow_input.vnfr_uuid}", task_queue=vnf_task_queue.task_queue, schedule_to_close_timeout=default_schedule_to_close_timeout, retry_policy=retry_policy, ), ) get_vnf_descriptor, get_cloud = value_to_type( - GetVnfDescriptorOutput, activities_results[0] - ), value_to_type(GetVimCloudOutput, activities_results[1]) + GetVnfDescriptor.Output, activities_results[0] + ), value_to_type(GetVimCloud.Output, activities_results[1]) await self.instantiate_vdus( vnfr=get_vnf_record.vnfr, vnfd=get_vnf_descriptor.vnfd, task_queue=vnf_task_queue.task_queue, cloud=get_cloud.cloud, - vnf_instantiation_config=input.instantiation_config, + vnf_instantiation_config=workflow_input.instantiation_config, ) await self.update_vnf_instantiation_state( - ChangeVnfInstantiationStateInput( - vnfr_uuid=input.vnfr_uuid, state=VnfInstantiationState.INSTANTIATED + ChangeVnfInstantiationState.Input( + vnfr_uuid=workflow_input.vnfr_uuid, + state=VnfInstantiationState.INSTANTIATED, ), ) await self.update_vnf_state( - ChangeVnfStateInput(vnfr_uuid=input.vnfr_uuid, state=VnfState.STARTED), + ChangeVnfState.Input( + vnfr_uuid=workflow_input.vnfr_uuid, state=VnfState.STARTED + ), ) await self.send_notification_for_vnf( - ChangeVnfInstantiationStateInput( - vnfr_uuid=input.vnfr_uuid, state=VnfInstantiationState.INSTANTIATED + ChangeVnfInstantiationState.Input( + vnfr_uuid=workflow_input.vnfr_uuid, + state=VnfInstantiationState.INSTANTIATED, ), ) except ActivityError as e: err_details = str(e.cause.with_traceback(e.__traceback__)) await self.update_vnf_instantiation_state( - ChangeVnfInstantiationStateInput( - vnfr_uuid=input.vnfr_uuid, state=VnfInstantiationState.INSTANTIATED + ChangeVnfInstantiationState.Input( + vnfr_uuid=workflow_input.vnfr_uuid, + state=VnfInstantiationState.INSTANTIATED, ), ) await self.update_vnf_state( - ChangeVnfStateInput(vnfr_uuid=input.vnfr_uuid, state=VnfState.STOPPED), + ChangeVnfState.Input( + vnfr_uuid=workflow_input.vnfr_uuid, state=VnfState.STOPPED + ), ) await self.send_notification_for_vnf( - ChangeVnfInstantiationStateInput( - vnfr_uuid=input.vnfr_uuid, state=VnfInstantiationState.INSTANTIATED + ChangeVnfInstantiationState.Input( + vnfr_uuid=workflow_input.vnfr_uuid, + state=VnfInstantiationState.INSTANTIATED, ), ) - self.logger.error(f"{WORKFLOW_VNF_INSTANTIATE} failed with {err_details}") + self.logger.error( + f"{VnfInstantiateWorkflow.__name__} failed with {err_details}" + ) raise e except ChildWorkflowError as e: err_details = str(e.cause.with_traceback(e.cause.__traceback__)) await self.update_vnf_instantiation_state( - ChangeVnfInstantiationStateInput( - vnfr_uuid=input.vnfr_uuid, state=VnfInstantiationState.INSTANTIATED + ChangeVnfInstantiationState.Input( + vnfr_uuid=workflow_input.vnfr_uuid, + state=VnfInstantiationState.INSTANTIATED, ), ) await self.update_vnf_state( - ChangeVnfStateInput(vnfr_uuid=input.vnfr_uuid, state=VnfState.STOPPED), + ChangeVnfState.Input( + vnfr_uuid=workflow_input.vnfr_uuid, state=VnfState.STOPPED + ), ) await self.send_notification_for_vnf( - ChangeVnfInstantiationStateInput( - vnfr_uuid=input.vnfr_uuid, state=VnfInstantiationState.INSTANTIATED + ChangeVnfInstantiationState.Input( + vnfr_uuid=workflow_input.vnfr_uuid, + state=VnfInstantiationState.INSTANTIATED, ), ) - self.logger.error(f"{WORKFLOW_VNF_INSTANTIATE} failed with {err_details}") + self.logger.error( + f"{VnfInstantiateWorkflow.__name__} failed with {err_details}" + ) raise e except Exception as e: err_details = str(traceback.format_exc()) await self.update_vnf_instantiation_state( - ChangeVnfInstantiationStateInput( - vnfr_uuid=input.vnfr_uuid, state=VnfInstantiationState.INSTANTIATED + ChangeVnfInstantiationState.Input( + vnfr_uuid=workflow_input.vnfr_uuid, + state=VnfInstantiationState.INSTANTIATED, ), ) await self.update_vnf_state( - ChangeVnfStateInput(vnfr_uuid=input.vnfr_uuid, state=VnfState.STOPPED), + ChangeVnfState.Input( + vnfr_uuid=workflow_input.vnfr_uuid, state=VnfState.STOPPED + ), ) await self.send_notification_for_vnf( - ChangeVnfInstantiationStateInput( - vnfr_uuid=input.vnfr_uuid, state=VnfInstantiationState.INSTANTIATED + ChangeVnfInstantiationState.Input( + vnfr_uuid=workflow_input.vnfr_uuid, + state=VnfInstantiationState.INSTANTIATED, ), ) - self.logger.error(f"{WORKFLOW_VNF_INSTANTIATE} failed with {err_details}") + self.logger.error( + f"{VnfInstantiateWorkflow.__name__} failed with {err_details}" + ) raise e @staticmethod - async def update_vnf_state(vnf_state): + async def update_vnf_state(vnf_state: ChangeVnfState.Input): await workflow.execute_activity( - activity=ACTIVITY_CHANGE_VNF_STATE, + activity=ChangeVnfState.__name__, arg=vnf_state, - activity_id=f"{ACTIVITY_CHANGE_VNF_STATE}-{vnf_state.vnfr_uuid}", + activity_id=f"{ChangeVnfState.__name__}-{vnf_state.vnfr_uuid}", task_queue=LCM_TASK_QUEUE, schedule_to_close_timeout=default_schedule_to_close_timeout, retry_policy=retry_policy, ) @staticmethod - async def update_vnf_instantiation_state(vnf_instantiation_state): + async def update_vnf_instantiation_state( + vnf_instantiation_state: ChangeVnfInstantiationState.Input, + ): await workflow.execute_activity( - activity=ACTIVITY_CHANGE_VNF_INSTANTIATION_STATE, + activity=ChangeVnfInstantiationState.__name__, arg=vnf_instantiation_state, - activity_id=f"{ACTIVITY_CHANGE_VNF_INSTANTIATION_STATE}-{vnf_instantiation_state.vnfr_uuid}", + activity_id=f"{ChangeVnfInstantiationState.__name__}-{vnf_instantiation_state.vnfr_uuid}", task_queue=LCM_TASK_QUEUE, schedule_to_close_timeout=default_schedule_to_close_timeout, retry_policy=retry_policy, @@ -244,12 +245,12 @@ class VnfInstantiateWorkflow: @staticmethod async def send_notification_for_vnf( - vnf_instantiation_state: ChangeVnfInstantiationStateInput, + vnf_instantiation_state: ChangeVnfInstantiationState.Input, ): await workflow.execute_activity( - activity=ACTIVITY_SEND_NOTIFICATION_FOR_VNF, + activity=SendNotificationForVnf.__name__, arg=vnf_instantiation_state, - activity_id=f"{ACTIVITY_SEND_NOTIFICATION_FOR_VNF}-{vnf_instantiation_state.vnfr_uuid}", + activity_id=f"{SendNotificationForVnf.__name__}-{vnf_instantiation_state.vnfr_uuid}", task_queue=LCM_TASK_QUEUE, schedule_to_close_timeout=default_schedule_to_close_timeout, retry_policy=retry_policy, @@ -267,7 +268,7 @@ class VnfInstantiateWorkflow: ( vdu_instantiate_input, vdu_instantiate_workflow_id, - ) = VnfInstantiateWorkflow._get_vdu_instantiate_info( + ) = VnfInstantiateWorkflowImpl._get_vdu_instantiate_input( vnfr=vnfr, vnfd=vnfd, vdu=vdu, @@ -275,27 +276,27 @@ class VnfInstantiateWorkflow: vnf_instantiation_config=vnf_instantiation_config, ) await workflow.execute_child_workflow( - workflow=WORKFLOW_VDU_INSTANTIATE, + workflow=VduInstantiateWorkflow.__name__, arg=vdu_instantiate_input, task_queue=task_queue, id=vdu_instantiate_workflow_id, ) @staticmethod - def _get_vdu_instantiate_info( + def _get_vdu_instantiate_input( vnfr, vnfd, vdu, cloud, vnf_instantiation_config - ) -> Tuple[VduInstantiateInput, str]: + ) -> Tuple[VduInstantiateWorkflow.Input, str]: """Calculates the VDU instantiate input data without reaching Database.""" model_name = vnfr.get("namespace") 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_instantiation_config = VnfOperations.get_vdu_instantiation_params( + vdu_instantiation_config = VnfSpecifications.get_vdu_instantiation_params( vdu["id"], vnf_instantiation_config ) - compute_constraints = VnfOperations.get_compute_constraints(vdu, vnfd) - config = VnfOperations.get_application_config(vdu, vdu_instantiation_config) - vdu_instantiate_input = VduInstantiateInput( + compute_constraints = VnfSpecifications.get_compute_constraints(vdu, vnfd) + config = VnfSpecifications.get_application_config(vdu, vdu_instantiation_config) + vdu_instantiate_input = VduInstantiateWorkflow.Input( vim_uuid=vim_id, model_name=model_name, charm_info=vdu_info, @@ -311,35 +312,31 @@ class VnfInstantiateWorkflow: return vdu_instantiate_input, vdu_instantiate_workflow_id -@workflow.defn(name=WORKFLOW_VNF_PREPARE, sandboxed=_SANDBOXED) -class VnfPrepareWorkflow: - """Prepare a VNF. - - Workflow Identifier: - It is recommended that the ID for the VNF is referred as a workflow - ID when invoking this workflow. - """ - - def __init__(self): - self.logger = logging.getLogger(f"lcm.wfl.{self.__class__.__name__}") - +@workflow.defn(name=VnfPrepareWorkflow.__name__, sandboxed=False) +class VnfPrepareWorkflowImpl(VnfPrepareWorkflow): @workflow.run - async def run(self, wf_input: VnfPrepareInput) -> None: + async def run(self, workflow_input: VnfPrepareWorkflow.Input) -> None: try: await workflow.execute_activity( - activity=ACTIVITY_SET_VNF_MODEL, - arg=SetVnfModelInput(wf_input.vnfr_uuid, wf_input.model_name), - activity_id=f"{ACTIVITY_SET_VNF_MODEL}-{wf_input.vnfr_uuid}", + activity=SetVnfModel.__name__, + arg=SetVnfModel.Input( + workflow_input.vnfr_uuid, workflow_input.model_name + ), + activity_id=f"{SetVnfModel.__name__}-{workflow_input.vnfr_uuid}", task_queue=LCM_TASK_QUEUE, 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}") + self.logger.error( + f"{VnfPrepareWorkflow.__name__} failed with {err_details}" + ) raise e except Exception as e: err_details = str(traceback.format_exc()) - self.logger.error(f"{WORKFLOW_VNF_PREPARE} failed with {err_details}") + self.logger.error( + f"{VnfPrepareWorkflow.__name__} failed with {err_details}" + ) raise e diff --git a/osm_lcm/tests/test_charm_info_utils.py b/osm_lcm/tests/test_charm_info_utils.py index 8aca9dc..1b57a19 100644 --- a/osm_lcm/tests/test_charm_info_utils.py +++ b/osm_lcm/tests/test_charm_info_utils.py @@ -14,7 +14,7 @@ from unittest import TestCase from osm_lcm.temporal.juju_paas_activities import CharmInfoUtils -from osm_common.dataclasses.temporal_dataclasses import CharmInfo +from osm_common.temporal.dataclasses_common import CharmInfo import yaml vdu_nominal = """ diff --git a/osm_lcm/tests/test_juju_paas_activities.py b/osm_lcm/tests/test_juju_paas_activities.py index 1aae706..bac5619 100644 --- a/osm_lcm/tests/test_juju_paas_activities.py +++ b/osm_lcm/tests/test_juju_paas_activities.py @@ -25,14 +25,14 @@ from juju.controller import Controller from juju.model import Model from juju.errors import JujuError from juju.unit import Unit -from osm_common.dataclasses.temporal_dataclasses import ( - CharmInfo, - CheckCharmStatusInput, - ModelInfo, - TestVimConnectivityInput, - VduComputeConstraints, - VduInstantiateInput, +from osm_lcm.temporal.juju_paas_activities import ( + TestVimConnectivityImpl, + DeployCharmImpl, + CreateModelImpl, + CheckCharmStatusImpl, ) +from osm_common.temporal.workflows.vdu import VduInstantiateWorkflow +from osm_common.temporal.dataclasses_common import CharmInfo, VduComputeConstraints from osm_common.dbbase import DbException from osm_lcm.temporal.juju_paas_activities import JujuPaasConnector from parameterized import parameterized @@ -122,12 +122,13 @@ class TestJujuPaasActivitiesBase(asynctest.TestCase): class TestCreateModel(TestJujuPaasActivitiesBase): - model_info = ModelInfo(vim_content["_id"], namespace) + model_info = CreateModelImpl.Input(vim_content["_id"], namespace) def setUp(self): super().setUp() self._api_endpoints = [] self.controller.api_endpoints = self.api_endpoints + self.create_model = CreateModelImpl(self.db, self.juju_paas) @property async def api_endpoints(self): @@ -137,7 +138,7 @@ class TestCreateModel(TestJujuPaasActivitiesBase): self.db.get_one.side_effect = [vim_content] self.juju_paas._decrypt_password = Mock() self.juju_paas._decrypt_password.side_effect = ["password"] - await self.env.run(self.juju_paas.create_model, self.model_info) + await self.env.run(self.create_model, self.model_info) self.controller.add_model.assert_called_once_with( self.model_info.model_name, config=ANY, @@ -147,7 +148,7 @@ class TestCreateModel(TestJujuPaasActivitiesBase): async def test_create_model_already_exists(self): self.controller.list_models.return_value = [self.model_info.model_name] - await self.env.run(self.juju_paas.create_model, self.model_info) + await self.env.run(self.create_model, self.model_info) self.controller.add_model.assert_not_called() @@ -158,6 +159,7 @@ class TestCheckCharmStatus(TestJujuPaasActivitiesBase): self.heartbeat_count = 0 self.heartbeat_maximum = 5 self.add_application("application") + self.check_charm_status = CheckCharmStatusImpl(self.juju_paas) def on_heartbeat(self, *args, **kwargs): self.heartbeat_count += 1 @@ -187,7 +189,7 @@ class TestCheckCharmStatus(TestJujuPaasActivitiesBase): async def test_check_charm_status_application_with_one_unit( self, _, app_events, unit_events, heartbeat_maximum ): - arg = CheckCharmStatusInput( + arg = CheckCharmStatusImpl.Input( application_name=self.application_name, model_name="model", vim_uuid="vim-uuid", @@ -202,10 +204,10 @@ class TestCheckCharmStatus(TestJujuPaasActivitiesBase): type(units[0]).workload_status = mock.PropertyMock(side_effect=unit_events) - await self.env.run(self.juju_paas.check_charm_status, arg) + await self.env.run(self.check_charm_status.__call__, arg) async def test_check_charm_status_cancel(self): - arg = CheckCharmStatusInput( + arg = CheckCharmStatusImpl.Input( application_name=self.application_name, model_name="model", vim_uuid="vim-uuid", @@ -223,10 +225,10 @@ class TestCheckCharmStatus(TestJujuPaasActivitiesBase): type(units[0]).workload_status = mock.PropertyMock(side_effect=[]) with self.assertRaises(asyncio.exceptions.CancelledError): - await self.env.run(self.juju_paas.check_charm_status, arg) + await self.env.run(self.check_charm_status.__call__, arg) async def test_check_charm_status_multiple_units(self): - arg = CheckCharmStatusInput( + arg = CheckCharmStatusImpl.Input( application_name=self.application_name, model_name="model", vim_uuid="vim-uuid", @@ -250,7 +252,7 @@ class TestCheckCharmStatus(TestJujuPaasActivitiesBase): side_effect=["maintenance", "active", "maintenance", "active"] ) - await self.env.run(self.juju_paas.check_charm_status, arg) + await self.env.run(self.check_charm_status.__call__, arg) class TestDeployCharm(TestJujuPaasActivitiesBase): @@ -261,23 +263,31 @@ class TestDeployCharm(TestJujuPaasActivitiesBase): cloud_other = "other" config = {"domain_name1": "osm.org", "domain_name2": "osm.com"} charm_info = CharmInfo(app_name, channel, entity_url) - vdu_instantiate_input_with_constraints_k8s_without_config = VduInstantiateInput( - vim_content["_id"], - namespace, - charm_info, - VduComputeConstraints(mem=1, cores=1), - cloud_k8s, - {}, + vdu_instantiate_input_with_constraints_k8s_without_config = ( + VduInstantiateWorkflow.Input( + vim_content["_id"], + namespace, + charm_info, + VduComputeConstraints(mem=1, cores=1), + cloud_k8s, + {}, + ) ) - vdu_instantiate_input_with_constraints_k8s_with_config = VduInstantiateInput( - vim_content["_id"], - namespace, - charm_info, - VduComputeConstraints(mem=1, cores=1), - cloud_k8s, - config, + vdu_instantiate_input_with_constraints_k8s_with_config = ( + VduInstantiateWorkflow.Input( + vim_content["_id"], + namespace, + charm_info, + VduComputeConstraints(mem=1, cores=1), + cloud_k8s, + config, + ) ) + def setUp(self) -> None: + super().setUp() + self.deploy_charm = DeployCharmImpl(self.juju_paas) + @parameterized.expand( [ ( @@ -294,7 +304,7 @@ class TestDeployCharm(TestJujuPaasActivitiesBase): ), ( "k8s_cloud_with_config_without_constraints", - VduInstantiateInput( + VduInstantiateWorkflow.Input( vim_content["_id"], namespace, charm_info, @@ -307,7 +317,7 @@ class TestDeployCharm(TestJujuPaasActivitiesBase): ), ( "other_cloud_without_config_with_constraints", - VduInstantiateInput( + VduInstantiateWorkflow.Input( vim_content["_id"], namespace, charm_info, @@ -320,7 +330,7 @@ class TestDeployCharm(TestJujuPaasActivitiesBase): ), ( "other_cloud_without_config_without_constraints", - VduInstantiateInput( + VduInstantiateWorkflow.Input( vim_content["_id"], namespace, charm_info, @@ -337,7 +347,7 @@ class TestDeployCharm(TestJujuPaasActivitiesBase): self, _, vdu_instantiate_input, expected_constraint, expected_config ): await self.env.run( - self.juju_paas.deploy_charm, + self.deploy_charm, vdu_instantiate_input, ) self.model.deploy.assert_called_once_with( @@ -352,7 +362,7 @@ class TestDeployCharm(TestJujuPaasActivitiesBase): self.add_application(self.app_name) with self.assertRaises(Exception) as err: await self.env.run( - self.juju_paas.deploy_charm, + self.deploy_charm, self.vdu_instantiate_input_with_constraints_k8s_without_config, ) self.model.deploy.assert_not_called() @@ -365,7 +375,7 @@ class TestDeployCharm(TestJujuPaasActivitiesBase): self.controller.get_model.side_effect = JujuError() with self.assertRaises(JujuError): await self.env.run( - self.juju_paas.deploy_charm, + self.deploy_charm, self.vdu_instantiate_input_with_constraints_k8s_without_config, ) self.model.deploy.assert_not_called() @@ -417,11 +427,16 @@ class TestGetApplicationConstraints(TestCase): class TestTestVimConnectivity(TestJujuPaasActivitiesBase): - test_vim_connectivity_input = TestVimConnectivityInput(vim_content["_id"]) + test_vim_connectivity_input = TestVimConnectivityImpl.Input(vim_content["_id"]) + + def setUp(self) -> None: + super().setUp() + self.test_vim_connectivity = TestVimConnectivityImpl(self.juju_paas) async def test_connectivity_nominal_case(self): await self.env.run( - self.juju_paas.test_vim_connectivity, self.test_vim_connectivity_input + self.test_vim_connectivity, + self.test_vim_connectivity_input, ) async def test_connectivity_raises_exception(self): @@ -429,5 +444,6 @@ class TestTestVimConnectivity(TestJujuPaasActivitiesBase): self.juju_paas._get_controller.side_effect = JujuError() with self.assertRaises(JujuError): await self.env.run( - self.juju_paas.test_vim_connectivity, self.test_vim_connectivity_input + self.test_vim_connectivity, + self.test_vim_connectivity_input, ) diff --git a/osm_lcm/tests/test_ns_activities.py b/osm_lcm/tests/test_ns_activities.py index c3176ee..833f440 100644 --- a/osm_lcm/tests/test_ns_activities.py +++ b/osm_lcm/tests/test_ns_activities.py @@ -16,17 +16,13 @@ import asynctest -from osm_common.dataclasses.temporal_dataclasses import ( - GetNsRecordInput, - GetVnfDetailsInput, -) +from osm_lcm.temporal.ns_activities import GetNsRecordImpl, GetVnfDetailsImpl from osm_common.dbbase import DbException from temporalio.testing import ActivityEnvironment -from osm_lcm.temporal.ns_activities import NsOperations from unittest.mock import Mock ns_uuid = "00000000-0000-0000-0000-000000000000" -get_vnf_details_input = GetVnfDetailsInput(ns_uuid=ns_uuid) +get_vnf_details_input = GetVnfDetailsImpl.Input(ns_uuid=ns_uuid) sample_vnf_details = [ { "id": "00000000-0000-0000-0000-000000000000", @@ -56,13 +52,11 @@ class TestGetVnfDetails(asynctest.TestCase): def setUp(self): self.db = Mock() self.env = ActivityEnvironment() - self.ns_operations_activity = NsOperations(self.db) + self.get_vnf_details_impl = GetVnfDetailsImpl(self.db) async def test_activity__succeded__get_expected_result(self): self.db.get_list.return_value = sample_vnf_details - result = await self.env.run( - self.ns_operations_activity.get_vnf_details, get_vnf_details_input - ) + result = await self.env.run(self.get_vnf_details_impl, get_vnf_details_input) self.assertEqual( result.vnf_details, @@ -75,22 +69,20 @@ class TestGetVnfDetails(asynctest.TestCase): async def test_activity__failed__raise_db_exception(self): self.db.get_list.side_effect = DbException("not found.") with self.assertRaises(DbException): - await self.env.run( - self.ns_operations_activity.get_vnf_details, get_vnf_details_input - ) + await self.env.run(self.get_vnf_details_impl, get_vnf_details_input) class TestGetNsRecord(asynctest.TestCase): async def setUp(self): self.db = Mock() self.env = ActivityEnvironment() - self.ns_operations_activity = NsOperations(self.db) + self.get_ns_record_impl = GetNsRecordImpl(self.db) async def test_activity__succeeded__get_expected_result(self): self.db.get_one.return_value = sample_nsr activity_result = await self.env.run( - self.ns_operations_activity.get_ns_record, - GetNsRecordInput(nsr_uuid=sample_nsr["_id"]), + self.get_ns_record_impl, + GetNsRecordImpl.Input(nsr_uuid=sample_nsr["_id"]), ) self.assertEqual(activity_result.nsr, sample_nsr) @@ -98,6 +90,6 @@ class TestGetNsRecord(asynctest.TestCase): self.db.get_one.side_effect = TestException("Can not connect to Database.") with self.assertRaises(TestException): await self.env.run( - self.ns_operations_activity.get_ns_record, - GetNsRecordInput(nsr_uuid=sample_nsr["_id"]), + self.get_ns_record_impl, + GetNsRecordImpl.Input(nsr_uuid=sample_nsr["_id"]), ) diff --git a/osm_lcm/tests/test_ns_workflows.py b/osm_lcm/tests/test_ns_workflows.py index e5f38ef..56852df 100644 --- a/osm_lcm/tests/test_ns_workflows.py +++ b/osm_lcm/tests/test_ns_workflows.py @@ -18,29 +18,25 @@ import copy from datetime import timedelta from unittest.mock import Mock, patch -from osm_common.dataclasses.temporal_dataclasses import ( - GetNsRecordInput, - GetNsRecordOutput, - GetVnfDetailsInput, - GetVnfDetailsOutput, - LcmOperationState, - ModelInfo, - NsLcmOperationInput, - NsState, - UpdateLcmOperationStateInput, - UpdateNsStateInput, - VnfInstantiateInput, +from osm_common.temporal_task_queues.task_queues_mappings import LCM_TASK_QUEUE +from osm_common.temporal.activities.lcm import ( + UpdateNsLcmOperationState, ) -from osm_common.temporal_constants import ( - ACTIVITY_CREATE_MODEL, - ACTIVITY_GET_NS_RECORD, - ACTIVITY_GET_VNF_DETAILS, - ACTIVITY_UPDATE_LCM_OPERATION_STATE, - ACTIVITY_UPDATE_NS_STATE, - LCM_TASK_QUEUE, - WORKFLOW_VNF_INSTANTIATE, +from osm_common.temporal.activities.ns import ( + GetNsRecord, + GetVnfDetails, + UpdateNsState, +) +from osm_common.temporal.activities.paas import ( + CreateModel, +) +from osm_common.temporal.workflows.vnf import VnfInstantiateWorkflow +from osm_common.temporal.workflows.lcm import LcmOperationWorkflow +from osm_common.temporal.states import LcmOperationState, NsState +from osm_lcm.temporal.ns_workflows import ( + NsInstantiateWorkflow, + NsInstantiateWorkflowImpl, ) -from osm_lcm.temporal.ns_workflows import NsInstantiateWorkflow from temporalio import activity, workflow from temporalio.client import WorkflowFailureError from temporalio.common import RetryPolicy @@ -110,61 +106,61 @@ class TestException(Exception): pass -@activity.defn(name=ACTIVITY_CREATE_MODEL) -async def mock_create_model(create_model_input: ModelInfo) -> None: +@activity.defn(name=CreateModel.__name__) +async def mock_create_model(create_model_input: CreateModel.Input) -> None: pass -@activity.defn(name=ACTIVITY_CREATE_MODEL) -async def mock_create_model_raises(create_model_input: ModelInfo) -> None: - raise TestException(f"{ACTIVITY_CREATE_MODEL} failed.") +@activity.defn(name=CreateModel.__name__) +async def mock_create_model_raises(create_model_input: CreateModel.Input) -> None: + raise TestException(f"{CreateModel.__name__} failed.") -@activity.defn(name=ACTIVITY_GET_VNF_DETAILS) +@activity.defn(name=GetVnfDetails.__name__) async def mock_get_vnf_details( - get_vnf_details_input: GetVnfDetailsInput, -) -> GetVnfDetailsOutput: - return GetVnfDetailsOutput(vnf_details=vnf_details) + get_vnf_details_input: GetVnfDetails.Input, +) -> GetVnfDetails.Output: + return GetVnfDetails.Output(vnf_details=vnf_details) -@activity.defn(name=ACTIVITY_GET_VNF_DETAILS) +@activity.defn(name=GetVnfDetails.__name__) async def mock_get_vnf_details_raises( - et_vnf_details_input: GetVnfDetailsInput, -) -> GetVnfDetailsOutput: - raise TestException(f"{ACTIVITY_GET_VNF_DETAILS} failed.") + et_vnf_details_input: GetVnfDetails.Input, +) -> GetVnfDetails.Output: + raise TestException(f"{GetVnfDetails.__name__} failed.") -@activity.defn(name=ACTIVITY_GET_NS_RECORD) +@activity.defn(name=GetNsRecord.__name__) async def mock_get_ns_record( - get_ns_record_input: GetNsRecordInput, -) -> GetNsRecordOutput: - return GetNsRecordOutput(nsr=sample_nsr) + get_ns_record_input: GetNsRecord.Input, +) -> GetNsRecord.Output: + return GetNsRecord.Output(nsr=sample_nsr) -@activity.defn(name=ACTIVITY_GET_NS_RECORD) +@activity.defn(name=GetNsRecord.__name__) async def mock_get_ns_record_raise_exception( - get_ns_record_input: GetNsRecordInput, -) -> GetNsRecordOutput: - raise TestException(f"{ACTIVITY_GET_NS_RECORD} failed.") + get_ns_record_input: GetNsRecord.Input, +) -> GetNsRecord.Output: + raise TestException(f"{GetNsRecord.__name__} failed.") -@workflow.defn(name=WORKFLOW_VNF_INSTANTIATE, sandboxed=SANDBOXED) +@workflow.defn(name=VnfInstantiateWorkflow.__name__, sandboxed=SANDBOXED) class MockVnfInstantiateWorkflow: @workflow.run - async def run(self, input: VnfInstantiateInput) -> None: + async def run(self, input: VnfInstantiateWorkflow.Input) -> None: pass -@workflow.defn(name=WORKFLOW_VNF_INSTANTIATE, sandboxed=SANDBOXED) +@workflow.defn(name=VnfInstantiateWorkflow.__name__, sandboxed=SANDBOXED) class MockVnfInstantiateWorkflowFailed: @workflow.run - async def run(self, input: VnfInstantiateInput) -> None: + async def run(self, input: VnfInstantiateWorkflow.Input) -> None: raise ChildWorkflowError( - message=f"{WORKFLOW_VNF_INSTANTIATE} child workflow failed.", + message=f"{VnfInstantiateWorkflow.__name__} child workflow failed.", namespace="default", workflow_id="123", run_id="1", - workflow_type=WORKFLOW_VNF_INSTANTIATE, + workflow_type=VnfInstantiateWorkflow.__name__, initiated_event_id=0, started_event_id=0, retry_state=RetryState.NON_RETRYABLE_FAILURE, @@ -172,11 +168,11 @@ class MockVnfInstantiateWorkflowFailed: @patch( - "osm_lcm.temporal.ns_workflows.NsInstantiateWorkflow._get_namespace", + "osm_lcm.temporal.ns_workflows.NsInstantiateWorkflowImpl._get_namespace", new=mock_get_namespace, ) class TestNsInstantiateWorkflow(asynctest.TestCase): - input = NsLcmOperationInput( + input = LcmOperationWorkflow.Input( nslcmop={ "_id": "1234", "nsInstanceId": ns_uuid, @@ -184,15 +180,15 @@ class TestNsInstantiateWorkflow(asynctest.TestCase): } ) - @activity.defn(name=ACTIVITY_UPDATE_LCM_OPERATION_STATE) + @activity.defn(name=UpdateNsLcmOperationState.__name__) async def mock_update_lcm_operation_state( self, - data: UpdateLcmOperationStateInput, + data: UpdateNsLcmOperationState.Input, ) -> None: self.mock_update_lcm_operation_state_tracker(data) - @activity.defn(name=ACTIVITY_UPDATE_NS_STATE) - async def mock_update_ns_state(self, data: UpdateNsStateInput) -> None: + @activity.defn(name=UpdateNsState.__name__) + async def mock_update_ns_state(self, data: UpdateNsState.Input) -> None: self.mock_update_ns_state_tracker(data) async def setUp(self): @@ -200,7 +196,7 @@ class TestNsInstantiateWorkflow(asynctest.TestCase): self.client = self.env.client self.mock_update_lcm_operation_state_tracker = Mock() self.mock_update_ns_state_tracker = Mock() - self.workflows = [NsInstantiateWorkflow, MockVnfInstantiateWorkflow] + self.workflows = [NsInstantiateWorkflowImpl, MockVnfInstantiateWorkflow] self.task_queue = LCM_TASK_QUEUE mock_get_namespace.return_value = model_name @@ -215,7 +211,7 @@ class TestNsInstantiateWorkflow(asynctest.TestCase): async def execute_workflow(self): return await self.client.execute_workflow( - NsInstantiateWorkflow, + NsInstantiateWorkflow.__name__, arg=self.input, id=self.input.nslcmop["nsInstanceId"], task_queue=self.task_queue, @@ -329,7 +325,7 @@ class TestNsInstantiateWorkflow(asynctest.TestCase): await self.execute_workflow() self.assert_ns_error_details( self.mock_update_ns_state_tracker.call_args_list, - ["TestException: create-model failed."], + [f"TestException: {CreateModel.__name__} failed."], ) async def test_instantiate_workflow__get_ns_record_activity_failed__error_details_expected( @@ -349,7 +345,7 @@ class TestNsInstantiateWorkflow(asynctest.TestCase): await self.execute_workflow() self.assert_ns_error_details( self.mock_update_ns_state_tracker.call_args_list, - ["TestException: get-ns-record failed."], + [f"TestException: {GetNsRecord.__name__} failed."], ) async def test_instantiate_workflow__get_ns_record_activity_failed__raise_activity_error( @@ -386,7 +382,7 @@ class TestNsInstantiateWorkflow(asynctest.TestCase): await self.execute_workflow() self.assert_ns_error_details( self.mock_update_ns_state_tracker.call_args_list, - ["TestException: get-vnf-details failed."], + [f"TestException: {GetVnfDetails.__name__} failed."], ) async def test_instantiate_workflow__get_vnf_details_activity_failed__raise_activity_error( @@ -406,7 +402,7 @@ class TestNsInstantiateWorkflow(asynctest.TestCase): await self.execute_workflow() self.assertTrue(isinstance(err.exception.cause, ActivityError)) - @patch("osm_lcm.temporal.ns_workflows.NsInstantiateWorkflow.get_vnf_config") + @patch("osm_lcm.temporal.ns_workflows.NsInstantiateWorkflowImpl.get_vnf_config") async def test_instantiate_workflow__get_vnf_config_failed__workflow_times_out( self, mock_get_vnf_config ): @@ -426,7 +422,7 @@ class TestNsInstantiateWorkflow(asynctest.TestCase): await self.execute_workflow() self.assertTrue(isinstance(err.exception.cause, TimeoutError)) - @patch("osm_lcm.temporal.ns_workflows.NsInstantiateWorkflow.get_vnf_config") + @patch("osm_lcm.temporal.ns_workflows.NsInstantiateWorkflowImpl.get_vnf_config") async def test_instantiate_workflow__get_vnf_config_failed__update_ns_state( self, mock_get_vnf_config ): @@ -448,7 +444,7 @@ class TestNsInstantiateWorkflow(asynctest.TestCase): self.mock_update_ns_state_tracker.call_args_list, [NsState.INSTANTIATED] ) - @patch("osm_lcm.temporal.ns_workflows.NsInstantiateWorkflow.get_vnf_config") + @patch("osm_lcm.temporal.ns_workflows.NsInstantiateWorkflowImpl.get_vnf_config") async def test_instantiate_workflow__get_vnf_config_failed__update_lcm_op_state( self, mock_get_vnf_config ): @@ -484,7 +480,7 @@ class TestNsInstantiateWorkflow(asynctest.TestCase): with self.assertRaises(WorkflowFailureError) as err: async with self.env, self.get_worker( self.task_queue, - [NsInstantiateWorkflow, MockVnfInstantiateWorkflowFailed], + [NsInstantiateWorkflowImpl, MockVnfInstantiateWorkflowFailed], activities, ): await self.execute_workflow() @@ -503,13 +499,13 @@ class TestNsInstantiateWorkflow(asynctest.TestCase): with self.assertRaises(WorkflowFailureError): async with self.env, self.get_worker( self.task_queue, - [NsInstantiateWorkflow, MockVnfInstantiateWorkflowFailed], + [NsInstantiateWorkflowImpl, MockVnfInstantiateWorkflowFailed], activities, ): await self.execute_workflow() self.assert_ns_error_details( self.mock_update_ns_state_tracker.call_args_list, - ["vnf-instantiate child workflow failed."], + [f"{VnfInstantiateWorkflow.__name__} child workflow failed."], ) async def test_instantiate_workflow__child_wf_failed__update_ns_state( @@ -525,7 +521,7 @@ class TestNsInstantiateWorkflow(asynctest.TestCase): with self.assertRaises(WorkflowFailureError): async with self.env, self.get_worker( self.task_queue, - [NsInstantiateWorkflow, MockVnfInstantiateWorkflowFailed], + [NsInstantiateWorkflowImpl, MockVnfInstantiateWorkflowFailed], activities, ): await self.execute_workflow() @@ -547,7 +543,7 @@ class TestNsInstantiateWorkflow(asynctest.TestCase): with self.assertRaises(WorkflowFailureError): async with self.env, self.get_worker( self.task_queue, - [NsInstantiateWorkflow, MockVnfInstantiateWorkflowFailed], + [NsInstantiateWorkflowImpl, MockVnfInstantiateWorkflowFailed], activities, ): await self.execute_workflow() @@ -588,7 +584,7 @@ class TestGetVnfConfig(asynctest.TestCase): } ], } - result = NsInstantiateWorkflow.get_vnf_config( + result = NsInstantiateWorkflowImpl.get_vnf_config( vnf_member_index_ref_1, sample_nsr ) self.assertEqual(result, expected_config) @@ -596,15 +592,15 @@ class TestGetVnfConfig(asynctest.TestCase): def test_vnf_config__nsr_does_not_have_config__expected_no_config(self): nsr = copy.deepcopy(sample_nsr) nsr["instantiate_params"] = {} - result = NsInstantiateWorkflow.get_vnf_config(vnf_member_index_ref_1, nsr) + result = NsInstantiateWorkflowImpl.get_vnf_config(vnf_member_index_ref_1, nsr) self.assertEqual(result, {}) def test_vnf_config__empty_vnf_member_index_ref__expected_no_config(self): - result = NsInstantiateWorkflow.get_vnf_config("", sample_nsr) + result = NsInstantiateWorkflowImpl.get_vnf_config("", sample_nsr) self.assertEqual(result, {}) def test_vnf_config__nsr_config_does_not_match_with_vnf__expected_no_config(self): - result = NsInstantiateWorkflow.get_vnf_config( + result = NsInstantiateWorkflowImpl.get_vnf_config( vnf_member_index_ref_2, sample_nsr ) self.assertEqual(result, {}) diff --git a/osm_lcm/tests/test_vdu_workflow.py b/osm_lcm/tests/test_vdu_workflow.py index 333f1de..988618f 100644 --- a/osm_lcm/tests/test_vdu_workflow.py +++ b/osm_lcm/tests/test_vdu_workflow.py @@ -17,17 +17,13 @@ import asynctest from datetime import timedelta -from osm_common.dataclasses.temporal_dataclasses import ( - CharmInfo, - VduInstantiateInput, - VduComputeConstraints, +from osm_common.temporal_task_queues.task_queues_mappings import LCM_TASK_QUEUE +from osm_common.temporal.activities.paas import ( + DeployCharm, + CheckCharmStatus, ) -from osm_common.temporal_constants import ( - ACTIVITY_DEPLOY_CHARM, - ACTIVITY_CHECK_CHARM_STATUS, - LCM_TASK_QUEUE, -) -from osm_lcm.temporal.vdu_workflows import CheckCharmStatusInput, VduInstantiateWorkflow +from osm_common.temporal.dataclasses_common import CharmInfo, VduComputeConstraints +from osm_lcm.temporal.vdu_workflows import VduInstantiateWorkflowImpl from temporalio import activity from temporalio.client import WorkflowFailureError from temporalio.exceptions import ( @@ -44,26 +40,26 @@ class TestException(Exception): pass -@activity.defn(name=ACTIVITY_DEPLOY_CHARM) -async def deploy_charm_mocked(deploy_charm_input: VduInstantiateInput) -> None: +@activity.defn(name=DeployCharm.__name__) +async def deploy_charm_mocked(deploy_charm_input: DeployCharm.Input) -> None: pass -@activity.defn(name=ACTIVITY_DEPLOY_CHARM) -async def deploy_charm_mocked_raises(deploy_charm_input: VduInstantiateInput) -> None: - raise TestException(f"{ACTIVITY_DEPLOY_CHARM} failed.") +@activity.defn(name=DeployCharm.__name__) +async def deploy_charm_mocked_raises(deploy_charm_input: DeployCharm.Input) -> None: + raise TestException(f"{DeployCharm.__name__} failed.") -@activity.defn(name=ACTIVITY_CHECK_CHARM_STATUS) -async def check_charm_status_mocked(check_charm_status: CheckCharmStatusInput) -> None: +@activity.defn(name=CheckCharmStatus.__name__) +async def check_charm_status_mocked(check_charm_status: CheckCharmStatus.Input) -> None: pass -@activity.defn(name=ACTIVITY_CHECK_CHARM_STATUS) +@activity.defn(name=CheckCharmStatus.__name__) async def check_charm_status_mocked_raises( - check_charm_status: CheckCharmStatusInput, + check_charm_status: CheckCharmStatus.Input, ) -> None: - raise TestException(f"{ACTIVITY_CHECK_CHARM_STATUS} failed.") + raise TestException(f"{CheckCharmStatus.__name__} failed.") class TestVduWorkflows(asynctest.TestCase): @@ -77,10 +73,10 @@ class TestVduWorkflows(asynctest.TestCase): config = {"domain_name1": "osm.org", "domain_name2": "osm.com"} constraints = VduComputeConstraints(mem=1, cores=1) charm_info = CharmInfo(app_name, channel, entity_url) - vdu_instantiate_input_without_config = VduInstantiateInput( + vdu_instantiate_input_without_config = VduInstantiateWorkflowImpl.Input( vim_id, namespace, charm_info, constraints, cloud, {} ) - vdu_instantiate_input_with_config = VduInstantiateInput( + vdu_instantiate_input_with_config = VduInstantiateWorkflowImpl.Input( vim_id, namespace, charm_info, constraints, cloud, config ) workflow_id = namespace + "-" + app_name @@ -93,7 +89,7 @@ class TestVduWorkflows(asynctest.TestCase): return Worker( self.client, task_queue=self.task_queue_name, - workflows=[VduInstantiateWorkflow], + workflows=[VduInstantiateWorkflowImpl], activities=activities, debug_mode=True, ) @@ -102,7 +98,7 @@ class TestVduWorkflows(asynctest.TestCase): activities = [deploy_charm_mocked, check_charm_status_mocked] async with self.env, self.get_worker(activities): await self.client.execute_workflow( - VduInstantiateWorkflow.run, + VduInstantiateWorkflowImpl.run, arg=self.vdu_instantiate_input_without_config, id=self.workflow_id, task_queue=self.task_queue_name, @@ -114,7 +110,7 @@ class TestVduWorkflows(asynctest.TestCase): activities = [deploy_charm_mocked, check_charm_status_mocked] async with self.env, self.get_worker(activities): await self.client.execute_workflow( - VduInstantiateWorkflow.run, + VduInstantiateWorkflowImpl.run, arg=self.vdu_instantiate_input_with_config, id=self.workflow_id, task_queue=self.task_queue_name, @@ -127,7 +123,7 @@ class TestVduWorkflows(asynctest.TestCase): async with self.env, self.get_worker(activities): with self.assertRaises(WorkflowFailureError) as err: await self.client.execute_workflow( - VduInstantiateWorkflow.run, + VduInstantiateWorkflowImpl.run, arg=self.vdu_instantiate_input_without_config, id=self.workflow_id, task_queue=self.task_queue_name, @@ -141,7 +137,7 @@ class TestVduWorkflows(asynctest.TestCase): async with self.env, self.get_worker(activities): with self.assertRaises(WorkflowFailureError) as err: await self.client.execute_workflow( - VduInstantiateWorkflow.run, + VduInstantiateWorkflowImpl.run, arg=self.vdu_instantiate_input_without_config, id=self.workflow_id, task_queue=self.task_queue_name, @@ -149,7 +145,8 @@ class TestVduWorkflows(asynctest.TestCase): execution_timeout=EXECUTION_TIMEOUT, ) self.assertEqual( - str(err.exception.cause.cause), "TestException: deploy-charm failed." + str(err.exception.cause.cause), + f"TestException: {DeployCharm.__name__} failed.", ) async def test_vdu_instantiate__check_status__raise_activity_error(self): @@ -157,7 +154,7 @@ class TestVduWorkflows(asynctest.TestCase): async with self.env, self.get_worker(activities): with self.assertRaises(WorkflowFailureError) as err: await self.client.execute_workflow( - VduInstantiateWorkflow.run, + VduInstantiateWorkflowImpl.run, arg=self.vdu_instantiate_input_without_config, id=self.workflow_id, task_queue=self.task_queue_name, @@ -171,7 +168,7 @@ class TestVduWorkflows(asynctest.TestCase): async with self.env, self.get_worker(activities): with self.assertRaises(WorkflowFailureError) as err: await self.client.execute_workflow( - VduInstantiateWorkflow.run, + VduInstantiateWorkflowImpl.run, arg=self.vdu_instantiate_input_without_config, id=self.workflow_id, task_queue=self.task_queue_name, @@ -180,5 +177,5 @@ class TestVduWorkflows(asynctest.TestCase): ) self.assertEqual( str(err.exception.cause.cause), - "TestException: check-charm-status failed.", + f"TestException: {CheckCharmStatus.__name__} failed.", ) diff --git a/osm_lcm/tests/test_vim_workflows.py b/osm_lcm/tests/test_vim_workflows.py index 9c43895..8be573e 100644 --- a/osm_lcm/tests/test_vim_workflows.py +++ b/osm_lcm/tests/test_vim_workflows.py @@ -18,29 +18,26 @@ import asynctest from datetime import timedelta from unittest.mock import Mock -from osm_common.dataclasses.temporal_dataclasses import ( - DeleteVimInput, - TestVimConnectivityInput, - UpdateVimOperationStateInput, - UpdateVimStateInput, - VimOperationInput, +from osm_common.temporal_task_queues.task_queues_mappings import LCM_TASK_QUEUE +from osm_common.temporal.activities.paas import ( + TestVimConnectivity, +) +from osm_common.temporal.activities.vim import ( + UpdateVimState, + UpdateVimOperationState, + DeleteVimRecord, +) +from osm_common.temporal.states import ( VimState, VimOperationState, ) -from osm_common.temporal_constants import ( - ACTIVITY_TEST_VIM_CONNECTIVITY, - ACTIVITY_UPDATE_VIM_OPERATION_STATE, - ACTIVITY_UPDATE_VIM_STATE, - ACTIVITY_DELETE_VIM, - LCM_TASK_QUEUE, - WORKFLOW_VIM_CREATE, - WORKFLOW_VIM_UPDATE, - WORKFLOW_VIM_DELETE, -) from osm_lcm.temporal.vim_workflows import ( VimCreateWorkflow, VimUpdateWorkflow, VimDeleteWorkflow, + VimCreateWorkflowImpl, + VimUpdateWorkflowImpl, + VimDeleteWorkflowImpl, ) from parameterized import parameterized_class from temporalio import activity @@ -56,22 +53,22 @@ class TestException(Exception): pass -@activity.defn(name=ACTIVITY_TEST_VIM_CONNECTIVITY) +@activity.defn(name=TestVimConnectivity.__name__) async def mock_test_vim_connectivity( - test_connectivity_input: TestVimConnectivityInput, + test_connectivity_input: TestVimConnectivity.Input, ) -> None: pass -@activity.defn(name=ACTIVITY_TEST_VIM_CONNECTIVITY) +@activity.defn(name=TestVimConnectivity.__name__) async def mock_test_vim_connectivity_raises( - test_connectivity_input: TestVimConnectivityInput, + test_connectivity_input: TestVimConnectivity.Input, ) -> None: raise TestException("Test exception") -@activity.defn(name=ACTIVITY_DELETE_VIM) -async def mock_delete_vim_record_raises(data: DeleteVimInput) -> None: +@activity.defn(name=DeleteVimRecord.__name__) +async def mock_delete_vim_record_raises(data: DeleteVimRecord.Input) -> None: raise TestException("Test exception") @@ -79,32 +76,32 @@ class TestVimWorkflowsBase(asynctest.TestCase): task_queue_name = LCM_TASK_QUEUE vim_id = "some-vim-uuid" worflow_id = vim_id - vim_operation_input = VimOperationInput(vim_id, "op_id") + vim_operation_input = VimCreateWorkflow.Input(vim_id, "op_id") - @activity.defn(name=ACTIVITY_UPDATE_VIM_STATE) - async def mock_update_vim_state(self, data: UpdateVimStateInput) -> None: + @activity.defn(name=UpdateVimState.__name__) + async def mock_update_vim_state(self, data: UpdateVimState.Input) -> None: self.mock_update_vim_state_tracker(data) - @activity.defn(name=ACTIVITY_UPDATE_VIM_STATE) - async def mock_update_vim_state_raises(self, data: UpdateVimStateInput) -> None: + @activity.defn(name=UpdateVimState.__name__) + async def mock_update_vim_state_raises(self, data: UpdateVimState.Input) -> None: self.mock_update_vim_state_tracker(data) raise TestException("Test exception") - @activity.defn(name=ACTIVITY_UPDATE_VIM_OPERATION_STATE) + @activity.defn(name=UpdateVimOperationState.__name__) async def mock_update_vim_operation_state( - self, data: UpdateVimOperationStateInput + self, data: UpdateVimOperationState.Input ) -> None: self.mock_update_vim_operation_state_tracker(data) - @activity.defn(name=ACTIVITY_UPDATE_VIM_OPERATION_STATE) + @activity.defn(name=UpdateVimOperationState.__name__) async def mock_update_vim_operation_state_raises( - self, data: UpdateVimOperationStateInput + self, data: UpdateVimOperationState.Input ) -> None: self.mock_update_vim_operation_state_tracker(data) raise TestException("Test exception") - @activity.defn(name=ACTIVITY_DELETE_VIM) - async def mock_delete_vim_record(self, data: DeleteVimInput) -> None: + @activity.defn(name=DeleteVimRecord.__name__) + async def mock_delete_vim_record(self, data: DeleteVimRecord.Input) -> None: self.mock_delete_vim_record_tracker(data) async def setUp(self): @@ -118,7 +115,11 @@ class TestVimWorkflowsBase(asynctest.TestCase): return Worker( self.client, task_queue=self.task_queue_name, - workflows=[VimCreateWorkflow, VimUpdateWorkflow, VimDeleteWorkflow], + workflows=[ + VimCreateWorkflowImpl, + VimUpdateWorkflowImpl, + VimDeleteWorkflowImpl, + ], activities=activities, debug_mode=True, ) @@ -146,8 +147,8 @@ class TestVimWorkflowsBase(asynctest.TestCase): @parameterized_class( [ - {"workflow_name": WORKFLOW_VIM_CREATE}, - {"workflow_name": WORKFLOW_VIM_UPDATE}, + {"workflow_name": VimCreateWorkflow.__name__}, + {"workflow_name": VimUpdateWorkflow.__name__}, ] ) class TestVimWorkflow(TestVimWorkflowsBase): @@ -304,7 +305,7 @@ class TestVimDeleteWorkflow(TestVimWorkflowsBase): activities = [self.mock_delete_vim_record] async with self.env, self.get_worker(activities): result = await self.client.execute_workflow( - WORKFLOW_VIM_DELETE, + VimDeleteWorkflow.__name__, arg=self.vim_operation_input, id=self.worflow_id, task_queue=self.task_queue_name, @@ -319,7 +320,7 @@ class TestVimDeleteWorkflow(TestVimWorkflowsBase): async with self.env, self.get_worker(activities): with self.assertRaises(WorkflowFailureError): result = await self.client.execute_workflow( - WORKFLOW_VIM_DELETE, + VimDeleteWorkflow.__name__, arg=self.vim_operation_input, id=self.worflow_id, task_queue=self.task_queue_name, diff --git a/osm_lcm/tests/test_vnf_activities.py b/osm_lcm/tests/test_vnf_activities.py index 0c346ee..1f34563 100644 --- a/osm_lcm/tests/test_vnf_activities.py +++ b/osm_lcm/tests/test_vnf_activities.py @@ -19,23 +19,20 @@ from copy import deepcopy from unittest import TestCase from unittest.mock import Mock, patch -from osm_common.dataclasses.temporal_dataclasses import ( - ChangeVnfInstantiationStateInput, - ChangeVnfStateInput, - GetTaskQueueInput, - GetVimCloudInput, - GetVnfDescriptorInput, - GetVnfRecordInput, - SetVnfModelInput, - VnfInstantiationState, - VnfState, - VduComputeConstraints, -) from osm_common.dbbase import DbException -from osm_common.temporal_constants import ( - LCM_TASK_QUEUE, +from osm_common.temporal_task_queues.task_queues_mappings import LCM_TASK_QUEUE +from osm_lcm.temporal.vnf_activities import ( + ChangeVnfInstantiationStateImpl, + ChangeVnfStateImpl, + GetTaskQueueImpl, + GetVimCloudImpl, + GetVnfDescriptorImpl, + GetVnfRecordImpl, + SetVnfModelImpl, + VnfSpecifications, ) -from osm_lcm.temporal.vnf_activities import VnfDbActivity, VnfOperations +from osm_common.temporal.dataclasses_common import VduComputeConstraints +from osm_common.temporal.states import VnfState, VnfInstantiationState from temporalio.testing import ActivityEnvironment @@ -43,7 +40,7 @@ vnfr_uuid = "9f472177-95c0-4335-b357-5cdc17a79965" vnfd_uuid = "97784f19-d254-4252-946c-cf92d85443ca" vim_uuid = "a64f7c6c-bc27-4ec8-b664-5500a3324eca" model_name = "my-model-name" -set_vnf_model_input = SetVnfModelInput(vnfr_uuid=vnfr_uuid, model_name=model_name) +set_vnf_model_input = SetVnfModelImpl.Input(vnfr_uuid=vnfr_uuid, model_name=model_name) cloud = "microk8s" nsr_uuid = "583726d4-957d-47f5-8df5-199456f7afd0" sample_vim_record = { @@ -133,35 +130,33 @@ class TestVnfDbActivity(asynctest.TestCase): def setUp(self): self.db = Mock() self.env = ActivityEnvironment() - self.vnf_db_activity = VnfDbActivity(self.db) + self.change_vnf_state = ChangeVnfStateImpl(self.db) + self.change_vnf_instantiation_state = ChangeVnfInstantiationStateImpl(self.db) + self.set_vnf_model = SetVnfModelImpl(self.db) async def test_change_vnf_state__successful__db_updated_as_expected(self): vnf_state = VnfState.STOPPED - change_vnf_state_input = ChangeVnfStateInput(vnfr_uuid, vnf_state) - await self.env.run( - self.vnf_db_activity.change_vnf_state, change_vnf_state_input - ) + change_vnf_state_input = ChangeVnfStateImpl.Input(vnfr_uuid, vnf_state) + await self.env.run(self.change_vnf_state, change_vnf_state_input) self.db.set_one.assert_called_with( "vnfrs", {"_id": vnfr_uuid}, {"vnfState": vnf_state.name} ) async def test_change_vnf_state__failed__raises_db_exception(self): - change_vnf_state_input = ChangeVnfStateInput(vnfr_uuid, VnfState.STARTED) + change_vnf_state_input = ChangeVnfStateImpl.Input(vnfr_uuid, VnfState.STARTED) self.db.set_one.side_effect = DbException("not found") with self.assertRaises(DbException): - await self.env.run( - self.vnf_db_activity.change_vnf_state, change_vnf_state_input - ) + await self.env.run(self.change_vnf_state, change_vnf_state_input) async def test_change_vnf_instantiation_state__successful__db_updated_as_expected( self, ): instantiation_state = VnfInstantiationState.NOT_INSTANTIATED - change_instantiation_input = ChangeVnfInstantiationStateInput( + change_instantiation_input = ChangeVnfInstantiationStateImpl.Input( vnfr_uuid, instantiation_state ) await self.env.run( - self.vnf_db_activity.change_vnf_instantiation_state, + self.change_vnf_instantiation_state, change_instantiation_input, ) self.db.set_one.assert_called_with( @@ -171,18 +166,18 @@ class TestVnfDbActivity(asynctest.TestCase): ) async def test_change_vnf_instantiation_state__failed__raises_db_exception(self): - change_instantiation_input = ChangeVnfInstantiationStateInput( + change_instantiation_input = ChangeVnfInstantiationStateImpl.Input( vnfr_uuid, VnfInstantiationState.INSTANTIATED ) self.db.set_one.side_effect = DbException("not found") with self.assertRaises(DbException): await self.env.run( - self.vnf_db_activity.change_vnf_instantiation_state, + self.change_vnf_instantiation_state, change_instantiation_input, ) async def test_set_vnf_model__successful__db_updated_as_expected(self): - await self.env.run(self.vnf_db_activity.set_vnf_model, set_vnf_model_input) + await self.env.run(self.set_vnf_model, set_vnf_model_input) self.db.set_one.assert_called_with( "vnfrs", {"_id": vnfr_uuid}, {"namespace": model_name} ) @@ -190,20 +185,20 @@ class TestVnfDbActivity(asynctest.TestCase): async def test_set_vnf_model__failed__raises_db_exception(self): self.db.set_one.side_effect = DbException("not found") with self.assertRaises(DbException): - await self.env.run(self.vnf_db_activity.set_vnf_model, set_vnf_model_input) + await self.env.run(self.set_vnf_model, set_vnf_model_input) class TestGetTaskQueue(asynctest.TestCase): async def setUp(self): self.db = Mock() - self.vnf_operations_instance = VnfOperations(self.db) + self.get_task_queue = GetTaskQueueImpl(self.db) self.env = ActivityEnvironment() - self.get_task_queue_input = GetTaskQueueInput(vnfr_uuid=sample_vnfr["id"]) + self.get_task_queue_input = GetTaskQueueImpl.Input(vnfr_uuid=sample_vnfr["id"]) async def test_activity__succeeded__get_expected_task_queue(self): self.db.get_one.side_effect = [sample_vnfr, sample_vim_record] activity_result = await self.env.run( - self.vnf_operations_instance.get_task_queue, + self.get_task_queue, self.get_task_queue_input, ) self.assertEqual(activity_result.task_queue, LCM_TASK_QUEUE) @@ -212,7 +207,7 @@ class TestGetTaskQueue(asynctest.TestCase): self.db.get_one.side_effect = DbException("not found") with self.assertRaises(DbException): await self.env.run( - self.vnf_operations_instance.get_task_queue, + self.get_task_queue, self.get_task_queue_input, ) @@ -222,7 +217,7 @@ class TestGetTaskQueue(asynctest.TestCase): self.db.get_one.side_effect = [sample_vnfr, vim_record] with self.assertRaises(KeyError): await self.env.run( - self.vnf_operations_instance.get_task_queue, + self.get_task_queue, self.get_task_queue_input, ) @@ -230,14 +225,14 @@ class TestGetTaskQueue(asynctest.TestCase): class TestGetVnfDescriptor(asynctest.TestCase): async def setUp(self): self.db = Mock() - self.vnf_operations_instance = VnfOperations(self.db) + self.get_vnf_descriptor = GetVnfDescriptorImpl(self.db) self.env = ActivityEnvironment() async def test_activity__succeeded__get_expected_vnfd(self): self.db.get_one.return_value = sample_vnfd activity_result = await self.env.run( - self.vnf_operations_instance.get_vnf_descriptor, - GetVnfDescriptorInput(vnfd_uuid=vnfd_uuid), + self.get_vnf_descriptor, + GetVnfDescriptorImpl.Input(vnfd_uuid=vnfd_uuid), ) self.assertEqual(activity_result.vnfd, sample_vnfd) @@ -245,22 +240,22 @@ class TestGetVnfDescriptor(asynctest.TestCase): self.db.get_one.side_effect = DbException("Can not connect to Database.") with self.assertRaises(DbException): await self.env.run( - self.vnf_operations_instance.get_vnf_descriptor, - GetVnfDescriptorInput(vnfd_uuid=vnfd_uuid), + self.get_vnf_descriptor, + GetVnfDescriptorImpl.Input(vnfd_uuid=vnfd_uuid), ) class TestGetVnfRecord(asynctest.TestCase): async def setUp(self): self.db = Mock() - self.vnf_operations_instance = VnfOperations(self.db) + self.get_vnf_record = GetVnfRecordImpl(self.db) self.env = ActivityEnvironment() async def test_activity__succeeded__get_expected_vnfr(self): self.db.get_one.return_value = sample_vnfr activity_result = await self.env.run( - self.vnf_operations_instance.get_vnf_record, - GetVnfRecordInput(vnfr_uuid=vnfr_uuid), + self.get_vnf_record, + GetVnfRecordImpl.Input(vnfr_uuid=vnfr_uuid), ) self.assertEqual(activity_result.vnfr, sample_vnfr) @@ -268,22 +263,22 @@ class TestGetVnfRecord(asynctest.TestCase): self.db.get_one.side_effect = DbException("Can not connect to Database.") with self.assertRaises(DbException): await self.env.run( - self.vnf_operations_instance.get_vnf_record, - GetVnfRecordInput(vnfr_uuid=vnfr_uuid), + self.get_vnf_record, + GetVnfRecordImpl.Input(vnfr_uuid=vnfr_uuid), ) class TestGetVimCloud(asynctest.TestCase): async def setUp(self): self.db = Mock() - self.vnf_operations_instance = VnfOperations(self.db) + self.get_vim_cloud = GetVimCloudImpl(self.db) self.env = ActivityEnvironment() async def test_activity__succeeded__get_vim_cloud(self): self.db.get_one.side_effect = [sample_vnfr, sample_vim_record] activity_result = await self.env.run( - self.vnf_operations_instance.get_vim_cloud, - GetVimCloudInput(vnfr_uuid=sample_vnfr["id"]), + self.get_vim_cloud, + GetVimCloudImpl.Input(vnfr_uuid=sample_vnfr["id"]), ) self.assertEqual(activity_result.cloud, cloud) @@ -292,8 +287,8 @@ class TestGetVimCloud(asynctest.TestCase): vim_record["config"].pop("cloud") self.db.get_one.side_effect = [sample_vnfr, vim_record] activity_result = await self.env.run( - self.vnf_operations_instance.get_vim_cloud, - GetVimCloudInput(vnfr_uuid=sample_vnfr["id"]), + self.get_vim_cloud, + GetVimCloudImpl.Input(vnfr_uuid=sample_vnfr["id"]), ) self.assertEqual(activity_result.cloud, "") @@ -301,8 +296,8 @@ class TestGetVimCloud(asynctest.TestCase): self.db.get_one.side_effect = DbException("Can not connect to Database.") with self.assertRaises(DbException): await self.env.run( - self.vnf_operations_instance.get_vim_cloud, - GetVimCloudInput(vnfr_uuid=sample_vnfr["id"]), + self.get_vim_cloud, + GetVimCloudImpl.Input(vnfr_uuid=sample_vnfr["id"]), ) async def test_activity__wrong_vim_record__raise_key_error(self): @@ -311,30 +306,30 @@ class TestGetVimCloud(asynctest.TestCase): self.db.get_one.side_effect = [sample_vnfr, vim_record] with self.assertRaises(KeyError): await self.env.run( - self.vnf_operations_instance.get_vim_cloud, - GetVimCloudInput(vnfr_uuid=sample_vnfr["id"]), + self.get_vim_cloud, + GetVimCloudImpl.Input(vnfr_uuid=sample_vnfr["id"]), ) class TestGetVduInstantiateInfoMethods(TestCase): def test_get_flavor_details__successful__get_flavor(self): compute_desc_id = "compute-id-1" - result = VnfOperations._get_flavor_details(compute_desc_id, sample_vnfd) + result = VnfSpecifications._get_flavor_details(compute_desc_id, sample_vnfd) self.assertEqual(result, flavor_1) def test_get_flavor_details__empty_compute_desc__flavor_is_none(self): compute_desc_id = "" - result = VnfOperations._get_flavor_details(compute_desc_id, sample_vnfd) + result = VnfSpecifications._get_flavor_details(compute_desc_id, sample_vnfd) self.assertEqual(result, None) def test_get_flavor_details__compute_desc_not_found__flavor_is_none(self): compute_desc_id = "compute-id-5" - result = VnfOperations._get_flavor_details(compute_desc_id, sample_vnfd) + result = VnfSpecifications._get_flavor_details(compute_desc_id, sample_vnfd) self.assertEqual(result, None) def test_get_flavor_details__empty_vnfd__flavor_is_none(self): compute_desc_id = "compute-id-5" - result = VnfOperations._get_flavor_details(compute_desc_id, {}) + result = VnfSpecifications._get_flavor_details(compute_desc_id, {}) self.assertEqual(result, None) def test_get_flavor_details__wrong_vnfd_format__flavor_is_none(self): @@ -348,47 +343,47 @@ class TestGetVduInstantiateInfoMethods(TestCase): } ], } - result = VnfOperations._get_flavor_details(compute_desc_id, sample_vnfd) + result = VnfSpecifications._get_flavor_details(compute_desc_id, sample_vnfd) self.assertEqual(result, None) - @patch("osm_lcm.temporal.vnf_activities.VnfOperations._get_flavor_details") + @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications._get_flavor_details") def test_get_compute_constraints__succeeded__get_constraints( self, mock_get_flavor_details ): mock_get_flavor_details.return_value = flavor_1 - result = VnfOperations.get_compute_constraints(vdu, sample_vnfd) + result = VnfSpecifications.get_compute_constraints(vdu, sample_vnfd) self.assertEqual(VduComputeConstraints(cores=2, mem=4), result) - @patch("osm_lcm.temporal.vnf_activities.VnfOperations._get_flavor_details") + @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications._get_flavor_details") def test_get_compute_constraints__empty_flavor_details__no_constraints( self, mock_get_flavor_details ): mock_get_flavor_details.return_value = {} - result = VnfOperations.get_compute_constraints(vdu, sample_vnfd) + result = VnfSpecifications.get_compute_constraints(vdu, sample_vnfd) self.assertEqual(VduComputeConstraints(cores=0, mem=0), result) - @patch("osm_lcm.temporal.vnf_activities.VnfOperations._get_flavor_details") + @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications._get_flavor_details") def test_get_compute_constraints__flavor_details_is_none__no_constraints( self, mock_get_flavor_details ): mock_get_flavor_details.return_value = None - result = VnfOperations.get_compute_constraints(vdu, sample_vnfd) + result = VnfSpecifications.get_compute_constraints(vdu, sample_vnfd) self.assertEqual(VduComputeConstraints(cores=0, mem=0), result) - @patch("osm_lcm.temporal.vnf_activities.VnfOperations._get_flavor_details") + @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications._get_flavor_details") def test_get_compute_constraints__flavor_has_only_cpu__get_cpu_constraint( self, mock_get_flavor_details ): mock_get_flavor_details.return_value = flavor_2 - result = VnfOperations.get_compute_constraints(vdu, sample_vnfd) + result = VnfSpecifications.get_compute_constraints(vdu, sample_vnfd) self.assertEqual(VduComputeConstraints(cores=2, mem=0), result) - @patch("osm_lcm.temporal.vnf_activities.VnfOperations._get_flavor_details") + @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications._get_flavor_details") def test_get_compute_constraints__flavor_has_only_memory__get_memory_constraint( self, mock_get_flavor_details ): mock_get_flavor_details.return_value = flavor_3 - result = VnfOperations.get_compute_constraints(vdu, sample_vnfd) + result = VnfSpecifications.get_compute_constraints(vdu, sample_vnfd) self.assertEqual(VduComputeConstraints(cores=0, mem=4), result) def test_list_to_dict__config_has_several_items__get_expected_dict(self): @@ -396,45 +391,45 @@ class TestGetVduInstantiateInfoMethods(TestCase): {"key": "config::domain_name1", "value": "osm.org"}, {"key": "domain_name2", "value": "osm.com"}, ] - result = VnfOperations._list_to_dict(config) + result = VnfSpecifications._list_to_dict(config) self.assertEqual( result, {"config::domain_name1": "osm.org", "domain_name2": "osm.com"} ) def test_list_to_dict__empty_input__get_empty_dict(self): config = [] - result = VnfOperations._list_to_dict(config) + result = VnfSpecifications._list_to_dict(config) self.assertEqual(result, {}) def test_get_only_config_items__with_identifier__get_expected_config(self): config = {"config::redirect-map": "https://osm.instantiation.params"} - result = VnfOperations._get_only_config_items(config) + result = VnfSpecifications._get_only_config_items(config) self.assertEqual(result, {"redirect-map": "https://osm.instantiation.params"}) def test_get_only_config_items__without_identifier__no_config(self): config = {"key": "domain_name1", "value": "osm.org"} - result = VnfOperations._get_only_config_items(config) + result = VnfSpecifications._get_only_config_items(config) self.assertEqual(result, {}) def test_get_only_config_items__empty_input__no_config(self): config = {} - result = VnfOperations._get_only_config_items(config) + result = VnfSpecifications._get_only_config_items(config) self.assertEqual(result, {}) def test_get_vdu_instantiation_params__empty_vnf_config__get_params(self): - result = VnfOperations.get_vdu_instantiation_params(vdu_id, vnf_config) + result = VnfSpecifications.get_vdu_instantiation_params(vdu_id, vnf_config) self.assertEqual( result, {"config::redirect-map": "https://osm.instantiation.params"} ) def test_get_vdu_instantiation_params__empty_vnf_config__no_params(self): - result = VnfOperations.get_vdu_instantiation_params(vdu_id, {}) + result = VnfSpecifications.get_vdu_instantiation_params(vdu_id, {}) self.assertEqual(result, {}) def test_get_vdu_instantiation_params__vdu_id_mismatch__no_params(self): config = deepcopy(vnf_config) config["vdu"][0]["id"] = "other-vdu-id" - result = VnfOperations.get_vdu_instantiation_params(vdu_id, config) + result = VnfSpecifications.get_vdu_instantiation_params(vdu_id, config) self.assertEqual(result, {}) def test_get_vdu_instantiation_params__empty_configurable_properties__no_params( @@ -442,11 +437,11 @@ class TestGetVduInstantiateInfoMethods(TestCase): ): config = deepcopy(vnf_config) config["vdu"][0]["configurable-properties"] = {} - result = VnfOperations.get_vdu_instantiation_params(vdu_id, config) + result = VnfSpecifications.get_vdu_instantiation_params(vdu_id, config) self.assertEqual(result, {}) - @patch("osm_lcm.temporal.vnf_activities.VnfOperations._get_only_config_items") - @patch("osm_lcm.temporal.vnf_activities.VnfOperations._list_to_dict") + @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications._get_only_config_items") + @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications._list_to_dict") def test_get_application_config__instantiate_config_overrides_vdu_config__get_expected_application_config( self, mock_list_to_dict, @@ -460,13 +455,13 @@ class TestGetVduInstantiateInfoMethods(TestCase): }, {"domain_name1": "osm.public"}, ] - result = VnfOperations.get_application_config(vdu, vdu_instantiate_config) + result = VnfSpecifications.get_application_config(vdu, vdu_instantiate_config) self.assertEqual( result, {"domain_name1": "osm.public", "domain_name2": "osm.com"} ) - @patch("osm_lcm.temporal.vnf_activities.VnfOperations._get_only_config_items") - @patch("osm_lcm.temporal.vnf_activities.VnfOperations._list_to_dict") + @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications._get_only_config_items") + @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications._list_to_dict") def test_get_application_config__empty_instantiate_config__get_descriptor_config( self, mock_list_to_dict, @@ -480,11 +475,11 @@ class TestGetVduInstantiateInfoMethods(TestCase): }, {}, ] - result = VnfOperations.get_application_config(vdu, vdu_instantiate_config) + result = VnfSpecifications.get_application_config(vdu, vdu_instantiate_config) self.assertEqual(result, app_config) - @patch("osm_lcm.temporal.vnf_activities.VnfOperations._get_only_config_items") - @patch("osm_lcm.temporal.vnf_activities.VnfOperations._list_to_dict") + @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications._get_only_config_items") + @patch("osm_lcm.temporal.vnf_activities.VnfSpecifications._list_to_dict") def test_get_application_config__no_config__empty_application_config( self, mock_list_to_dict, @@ -494,7 +489,9 @@ class TestGetVduInstantiateInfoMethods(TestCase): vdu_copy = deepcopy(vdu) vdu_copy["configurable-properties"] = [] mock_get_only_config_items.side_effect = [{}, {}] - result = VnfOperations.get_application_config(vdu_copy, vdu_instantiate_config) + result = VnfSpecifications.get_application_config( + vdu_copy, vdu_instantiate_config + ) self.assertEqual(result, {}) diff --git a/osm_lcm/tests/test_vnf_workflows.py b/osm_lcm/tests/test_vnf_workflows.py index 8601142..45e70c9 100644 --- a/osm_lcm/tests/test_vnf_workflows.py +++ b/osm_lcm/tests/test_vnf_workflows.py @@ -21,40 +21,25 @@ from datetime import timedelta from unittest.mock import Mock import uuid -from osm_common.dataclasses.temporal_dataclasses import ( - ChangeVnfInstantiationStateInput, - ChangeVnfStateInput, - CharmInfo, - GetTaskQueueInput, - GetTaskQueueOutput, - GetVimCloudInput, - GetVimCloudOutput, - GetVnfDescriptorInput, - GetVnfDescriptorOutput, - GetVnfRecordInput, - GetVnfRecordOutput, - SetVnfModelInput, - VduComputeConstraints, - VduInstantiateInput, - VnfInstantiateInput, - VnfInstantiationState, - VnfPrepareInput, - VnfState, +from osm_common.temporal_task_queues.task_queues_mappings import LCM_TASK_QUEUE +from osm_common.temporal.activities.vnf import ( + ChangeVnfState, + ChangeVnfInstantiationState, + GetTaskQueue, + GetVimCloud, + GetVnfDescriptor, + GetVnfRecord, + SendNotificationForVnf, + SetVnfModel, ) -from osm_common.temporal_constants import ( - ACTIVITY_CHANGE_VNF_STATE, - ACTIVITY_CHANGE_VNF_INSTANTIATION_STATE, - ACTIVITY_GET_TASK_QUEUE, - ACTIVITY_GET_VIM_CLOUD, - ACTIVITY_GET_VNF_DESCRIPTOR, - ACTIVITY_GET_VNF_RECORD, - ACTIVITY_SEND_NOTIFICATION_FOR_VNF, - ACTIVITY_SET_VNF_MODEL, - LCM_TASK_QUEUE, - WORKFLOW_VDU_INSTANTIATE, - WORKFLOW_VNF_PREPARE, +from osm_common.temporal.dataclasses_common import CharmInfo, VduComputeConstraints +from osm_common.temporal.workflows.vnf import VnfPrepareWorkflow +from osm_common.temporal.workflows.vdu import VduInstantiateWorkflow +from osm_common.temporal.states import VnfState, VnfInstantiationState +from osm_lcm.temporal.vnf_workflows import ( + VnfInstantiateWorkflowImpl, + VnfPrepareWorkflowImpl, ) -from osm_lcm.temporal.vnf_workflows import VnfInstantiateWorkflow, VnfPrepareWorkflow from temporalio import activity from temporalio import workflow from temporalio.client import WorkflowFailureError @@ -103,7 +88,7 @@ config = [ {"key": "track", "value": "latest"}, {"key": "channel", "value": "stable"}, ] -wf_input = VnfInstantiateInput( +wf_input = VnfInstantiateWorkflowImpl.Input( vnfr_uuid=vnfr_uuid, model_name=model_name, instantiation_config={}, @@ -145,7 +130,7 @@ sample_vnfd = { } sample_charm_info = CharmInfo(app_name="my-app", channel="latest", entity_url="my-url") sample_constraints = VduComputeConstraints(cores=1, mem=1) -sample_vdu_instantiate_input = VduInstantiateInput( +sample_vdu_instantiate_input = VduInstantiateWorkflow.Input( vim_uuid=vim_account_id, model_name=model_name, charm_info=sample_charm_info, @@ -154,7 +139,7 @@ sample_vdu_instantiate_input = VduInstantiateInput( config={}, ) sample_vdu_instantiate_wf_id_1 = "vdu-instantiate-workflow-id-1" -sample_vdu_instantiate_input_with_config = VduInstantiateInput( +sample_vdu_instantiate_input_with_config = VduInstantiateWorkflow.Input( vim_uuid=vim_account_id, model_name=model_name, charm_info=sample_charm_info, @@ -190,129 +175,129 @@ class GetComputeConstraintsException(Exception): # Mock Activities -@activity.defn(name=ACTIVITY_SET_VNF_MODEL) -async def mock_set_vnf_model(set_vnf_model_input: SetVnfModelInput) -> None: +@activity.defn(name=SetVnfModel.__name__) +async def mock_set_vnf_model(set_vnf_model_input: SetVnfModel.Input) -> None: pass -@activity.defn(name=ACTIVITY_SET_VNF_MODEL) +@activity.defn(name=SetVnfModel.__name__) async def mock_set_vnf_model_raise_exception( - set_vnf_model_input: SetVnfModelInput, + set_vnf_model_input: SetVnfModel.Input, ) -> None: - raise TestException(f"{ACTIVITY_SET_VNF_MODEL} failed.") + raise TestException(f"{SetVnfModel.__name__} failed.") -@activity.defn(name=ACTIVITY_GET_TASK_QUEUE) +@activity.defn(name=GetTaskQueue.__name__) async def mock_get_task_queue( - get_task_queue_input: GetTaskQueueInput, -) -> GetTaskQueueOutput: - return GetTaskQueueOutput(LCM_TASK_QUEUE) + get_task_queue_input: GetTaskQueue.Input, +) -> GetTaskQueue.Output: + return GetTaskQueue.Output(LCM_TASK_QUEUE) -@activity.defn(name=ACTIVITY_GET_TASK_QUEUE) +@activity.defn(name=GetTaskQueue.__name__) async def mock_get_different_task_queue( - get_task_queue_input: GetTaskQueueInput, -) -> GetTaskQueueOutput: - return GetTaskQueueOutput(juju_task_queue) + get_task_queue_input: GetTaskQueue.Input, +) -> GetTaskQueue.Output: + return GetTaskQueue.Output(juju_task_queue) -@activity.defn(name=ACTIVITY_GET_TASK_QUEUE) +@activity.defn(name=GetTaskQueue.__name__) async def mock_get_task_queue_raise_exception( - get_task_queue_input: GetTaskQueueInput, -) -> GetTaskQueueOutput: - raise TestException(f"{ACTIVITY_GET_TASK_QUEUE} failed.") + get_task_queue_input: GetTaskQueue.Input, +) -> GetTaskQueue.Output: + raise TestException(f"{GetTaskQueue.__name__} failed.") -@activity.defn(name=ACTIVITY_GET_VNF_DESCRIPTOR) +@activity.defn(name=GetVnfDescriptor.__name__) async def mock_get_vnf_descriptor( - get_vnf_descriptor_input: GetVnfDescriptorInput, -) -> GetVnfDescriptorOutput: - return GetVnfDescriptorOutput(vnfd=sample_vnfd) + get_vnf_descriptor_input: GetVnfDescriptor.Input, +) -> GetVnfDescriptor.Output: + return GetVnfDescriptor.Output(vnfd=sample_vnfd) -@activity.defn(name=ACTIVITY_GET_VNF_DESCRIPTOR) +@activity.defn(name=GetVnfDescriptor.__name__) async def mock_get_vnf_descriptor_empty_output( - get_vnf_descriptor_input: GetVnfDescriptorInput, -) -> GetVnfDescriptorOutput: - return GetVnfDescriptorOutput(vnfd={}) + get_vnf_descriptor_input: GetVnfDescriptor.Input, +) -> GetVnfDescriptor.Output: + return GetVnfDescriptor.Output(vnfd={}) -@activity.defn(name=ACTIVITY_GET_VNF_DESCRIPTOR) +@activity.defn(name=GetVnfDescriptor.__name__) async def mock_get_vnf_descriptor_raise_exception( - get_vnf_descriptor_input: GetVnfDescriptorInput, -) -> GetVnfDescriptorOutput: - raise TestException(f"{ACTIVITY_GET_VNF_DESCRIPTOR} failed.") + get_vnf_descriptor_input: GetVnfDescriptor.Input, +) -> GetVnfDescriptor.Output: + raise TestException(f"{GetVnfDescriptor.__name__} failed.") -@activity.defn(name=ACTIVITY_GET_VNF_RECORD) +@activity.defn(name=GetVnfRecord.__name__) async def mock_get_vnf_record( - get_vnf_record_input: GetVnfRecordInput, -) -> GetVnfRecordOutput: - return GetVnfRecordOutput(vnfr=sample_vnfr) + get_vnf_record_input: GetVnfRecord.Input, +) -> GetVnfRecord.Output: + return GetVnfRecord.Output(vnfr=sample_vnfr) -@activity.defn(name=ACTIVITY_GET_VNF_RECORD) +@activity.defn(name=GetVnfRecord.__name__) async def mock_get_vnf_record_raise_exception( - get_vnf_record_input: GetVnfRecordInput, -) -> GetVnfRecordOutput: - raise TestException(f"{ACTIVITY_GET_VNF_RECORD} failed.") + get_vnf_record_input: GetVnfRecord.Input, +) -> GetVnfRecord.Output: + raise TestException(f"{GetVnfRecord.__name__} failed.") -@activity.defn(name=ACTIVITY_GET_VIM_CLOUD) +@activity.defn(name=GetVimCloud.__name__) async def mock_get_vim_cloud( - get_vim_cloud_input: GetVimCloudInput, -) -> GetVimCloudOutput: - return GetVimCloudOutput(cloud=cloud) + get_vim_cloud_input: GetVimCloud.Input, +) -> GetVimCloud.Output: + return GetVimCloud.Output(cloud=cloud) -@activity.defn(name=ACTIVITY_GET_VIM_CLOUD) +@activity.defn(name=GetVimCloud.__name__) async def mock_get_vim_cloud_raise_exception( - get_vim_cloud_input: GetVimCloudInput, -) -> GetVimCloudOutput: - raise TestException(f"{ACTIVITY_GET_VIM_CLOUD} failed.") + get_vim_cloud_input: GetVimCloud.Input, +) -> GetVimCloud.Output: + raise TestException(f"{GetVimCloud.__name__} failed.") # Mock Workflows -@workflow.defn(name=WORKFLOW_VNF_PREPARE, sandboxed=SANDBOXED) +@workflow.defn(name=VnfPrepareWorkflow.__name__, sandboxed=SANDBOXED) class MockPrepareVnfWorkflow: @workflow.run - async def run(self, input: VnfPrepareInput) -> None: + async def run(self, input: VnfPrepareWorkflow.Input) -> None: pass -@workflow.defn(name=WORKFLOW_VNF_PREPARE, sandboxed=SANDBOXED) +@workflow.defn(name=VnfPrepareWorkflow.__name__, sandboxed=SANDBOXED) class MockPrepareVnfWorkflowFailed: @workflow.run - async def run(self, input: VnfPrepareInput) -> None: + async def run(self, workflow_input: VnfPrepareWorkflow.Input) -> None: raise ChildWorkflowError( - message=f"{WORKFLOW_VNF_PREPARE} child workflow failed.", + message=f"{VnfPrepareWorkflow.__name__} child workflow failed.", namespace="default", workflow_id="123", run_id="1", - workflow_type=WORKFLOW_VNF_PREPARE, + workflow_type=VnfPrepareWorkflow.__name__, initiated_event_id=0, started_event_id=0, retry_state=RetryState.NON_RETRYABLE_FAILURE, ) -@workflow.defn(name=WORKFLOW_VDU_INSTANTIATE, sandboxed=SANDBOXED) +@workflow.defn(name=VduInstantiateWorkflow.__name__, sandboxed=SANDBOXED) class MockVduInstantiateWorkflow: @workflow.run - async def run(self, input: VduInstantiateInput) -> None: + async def run(self, workflow_input: VduInstantiateWorkflow.Input) -> None: pass -@workflow.defn(name=WORKFLOW_VDU_INSTANTIATE, sandboxed=SANDBOXED) +@workflow.defn(name=VduInstantiateWorkflow.__name__, sandboxed=SANDBOXED) class MockVduInstantiateWorkflowFailed: @workflow.run - async def run(self, input: VduInstantiateInput) -> None: + async def run(self, workflow_input: VduInstantiateWorkflow.Input) -> None: raise ChildWorkflowError( - message=f"{WORKFLOW_VDU_INSTANTIATE} child workflow failed.", + message=f"{VduInstantiateWorkflow.__name__} child workflow failed.", namespace="default", workflow_id="123", run_id="1", - workflow_type=WORKFLOW_VDU_INSTANTIATE, + workflow_type=VduInstantiateWorkflow.__name__, initiated_event_id=0, started_event_id=0, retry_state=RetryState.NON_RETRYABLE_FAILURE, @@ -331,13 +316,13 @@ class TestVnfPrepareWorkflow(asynctest.TestCase): self.client, debug_mode=DEBUG_MODE, task_queue=self.task_queue, - workflows=[VnfPrepareWorkflow], + workflows=[VnfPrepareWorkflowImpl], activities=[mock_set_vnf_model], ): await self.client.execute_workflow( - VnfPrepareWorkflow.run, + VnfPrepareWorkflowImpl.run, arg=wf_input, - id=f"{WORKFLOW_VNF_PREPARE}-{wf_input.vnfr_uuid}", + id=f"{VnfPrepareWorkflow.__name__}-{wf_input.vnfr_uuid}", task_queue=self.task_queue, task_timeout=TASK_TIMEOUT, execution_timeout=EXECUTION_TIMEOUT, @@ -351,14 +336,14 @@ class TestVnfPrepareWorkflow(asynctest.TestCase): self.client, debug_mode=DEBUG_MODE, task_queue=self.task_queue, - workflows=[VnfPrepareWorkflow], + workflows=[VnfPrepareWorkflowImpl], activities=[mock_set_vnf_model_raise_exception], ): with self.assertRaises(WorkflowFailureError) as err: await self.client.execute_workflow( - VnfPrepareWorkflow.run, + VnfPrepareWorkflowImpl.run, arg=wf_input, - id=f"{WORKFLOW_VNF_PREPARE}-{wf_input.vnfr_uuid}", + id=f"{VnfPrepareWorkflow.__name__}-{wf_input.vnfr_uuid}", task_queue=self.task_queue, task_timeout=TASK_TIMEOUT, execution_timeout=EXECUTION_TIMEOUT, @@ -373,20 +358,21 @@ class TestVnfPrepareWorkflow(asynctest.TestCase): self.client, debug_mode=DEBUG_MODE, task_queue=self.task_queue, - workflows=[VnfPrepareWorkflow], + workflows=[VnfPrepareWorkflowImpl], activities=[mock_set_vnf_model_raise_exception], ): with self.assertRaises(WorkflowFailureError) as err: await self.client.execute_workflow( - VnfPrepareWorkflow.run, + VnfPrepareWorkflowImpl.run, arg=wf_input, - id=f"{WORKFLOW_VNF_PREPARE}-{wf_input.vnfr_uuid}", + id=f"{VnfPrepareWorkflow.__name__}-{wf_input.vnfr_uuid}", task_queue=self.task_queue, task_timeout=TASK_TIMEOUT, execution_timeout=EXECUTION_TIMEOUT, ) self.assertEqual( - str(err.exception.cause.cause), "TestException: set-vnf-model failed." + str(err.exception.cause.cause), + f"TestException: {SetVnfModel.__name__} failed.", ) @@ -398,7 +384,7 @@ class TestVnfInstantiateWorkflow(asynctest.TestCase): self.mock_change_vnf_state_tracker = Mock() self.mock_send_notification_for_vnf_tracker = Mock() self.workflows = [ - VnfInstantiateWorkflow, + VnfInstantiateWorkflowImpl, MockPrepareVnfWorkflow, MockVduInstantiateWorkflow, ] @@ -415,7 +401,7 @@ class TestVnfInstantiateWorkflow(asynctest.TestCase): async def execute_workflow(self, wf_input=wf_input): return await self.client.execute_workflow( - VnfInstantiateWorkflow.run, + VnfInstantiateWorkflowImpl.run, arg=wf_input, id=uuid.uuid4().hex, task_queue=self.task_queue, @@ -429,7 +415,7 @@ class TestVnfInstantiateWorkflow(asynctest.TestCase): ) self.assertEqual( call_mock_change_vnf_instantiation_state_tracker[1].args[0], - ChangeVnfInstantiationStateInput(vnfr_uuid=vnfr_uuid, state=state), + ChangeVnfInstantiationState.Input(vnfr_uuid=vnfr_uuid, state=state), ) def vnf_state_is_updated(self, state): @@ -438,47 +424,47 @@ class TestVnfInstantiateWorkflow(asynctest.TestCase): ) self.assertEqual( call_mock_change_vnf_state_tracker[0].args[0], - ChangeVnfStateInput(vnfr_uuid=vnfr_uuid, state=state), + ChangeVnfState.Input(vnfr_uuid=vnfr_uuid, state=state), ) - @activity.defn(name=ACTIVITY_CHANGE_VNF_STATE) - async def mock_change_vnf_state(self, nf_state_input: ChangeVnfStateInput) -> None: + @activity.defn(name=ChangeVnfState.__name__) + async def mock_change_vnf_state(self, nf_state_input: ChangeVnfState.Input) -> None: self.mock_change_vnf_state_tracker(nf_state_input) - @activity.defn(name=ACTIVITY_CHANGE_VNF_STATE) + @activity.defn(name=ChangeVnfState.__name__) async def mock_change_vnf_state_exception( - self, nf_state_input: ChangeVnfStateInput + self, nf_state_input: ChangeVnfState.Input ) -> None: self.mock_change_vnf_state_tracker(nf_state_input) - raise TestException(f"{ACTIVITY_CHANGE_VNF_STATE} failed.") + raise TestException(f"{ChangeVnfState.__name__} failed.") - @activity.defn(name=ACTIVITY_CHANGE_VNF_INSTANTIATION_STATE) + @activity.defn(name=ChangeVnfInstantiationState.__name__) async def mock_change_vnf_instantiation_state( self, - nf_instantiation_state_input: ChangeVnfInstantiationStateInput, + nf_instantiation_state_input: ChangeVnfInstantiationState.Input, ) -> None: self.mock_change_vnf_instantiation_state_tracker(nf_instantiation_state_input) - @activity.defn(name=ACTIVITY_CHANGE_VNF_INSTANTIATION_STATE) + @activity.defn(name=ChangeVnfInstantiationState.__name__) async def mock_change_vnf_instantiation_state_exception( self, - nf_instantiation_state_input: ChangeVnfInstantiationStateInput, + nf_instantiation_state_input: ChangeVnfInstantiationState.Input, ) -> None: self.mock_change_vnf_instantiation_state_tracker(nf_instantiation_state_input) - raise TestException(f"{ACTIVITY_CHANGE_VNF_INSTANTIATION_STATE} failed.") + raise TestException(f"{ChangeVnfInstantiationState.__name__} failed.") - @activity.defn(name=ACTIVITY_SEND_NOTIFICATION_FOR_VNF) + @activity.defn(name=SendNotificationForVnf.__name__) async def mock_send_notification_for_vnf(self, input) -> None: self.mock_send_notification_for_vnf_tracker() @patch( - "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflow._get_vdu_instantiate_info" + "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflowImpl._get_vdu_instantiate_input" ) async def test_vnf_instantiate_workflow__successful__updates_vnf_instantiation_state( - self, mock_get_vdu_instantiate_info + self, mock_get_vdu_instantiate_input ): workflows = [ - VnfInstantiateWorkflow, + VnfInstantiateWorkflowImpl, MockPrepareVnfWorkflow, MockVduInstantiateWorkflow, ] @@ -492,7 +478,7 @@ class TestVnfInstantiateWorkflow(asynctest.TestCase): mock_get_vnf_record, mock_get_vim_cloud, ] - mock_get_vdu_instantiate_info.return_value = ( + mock_get_vdu_instantiate_input.return_value = ( sample_vdu_instantiate_input_with_config, sample_vdu_instantiate_wf_id_1, ) @@ -503,13 +489,13 @@ class TestVnfInstantiateWorkflow(asynctest.TestCase): self.vnf_instantiation_state_is_updated(VnfInstantiationState.INSTANTIATED) @patch( - "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflow._get_vdu_instantiate_info" + "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflowImpl._get_vdu_instantiate_input" ) async def test_vnf_instantiate_workflow__successful__updates_vnf_state( - self, mock_get_vdu_instantiate_info + self, mock_get_vdu_instantiate_input ): workflows = [ - VnfInstantiateWorkflow, + VnfInstantiateWorkflowImpl, MockPrepareVnfWorkflow, MockVduInstantiateWorkflow, ] @@ -523,7 +509,7 @@ class TestVnfInstantiateWorkflow(asynctest.TestCase): mock_get_vnf_record, mock_get_vim_cloud, ] - mock_get_vdu_instantiate_info.return_value = ( + mock_get_vdu_instantiate_input.return_value = ( sample_vdu_instantiate_input_with_config, sample_vdu_instantiate_wf_id_1, ) @@ -629,7 +615,7 @@ class TestVnfInstantiateWorkflow(asynctest.TestCase): async with self.env, self.get_worker( self.task_queue, [ - VnfInstantiateWorkflow, + VnfInstantiateWorkflowImpl, MockPrepareVnfWorkflowFailed, MockVduInstantiateWorkflow, ], @@ -655,7 +641,7 @@ class TestVnfInstantiateWorkflow(asynctest.TestCase): async with self.env, self.get_worker( self.task_queue, [ - VnfInstantiateWorkflow, + VnfInstantiateWorkflowImpl, MockPrepareVnfWorkflow, MockVduInstantiateWorkflowFailed, ], @@ -725,11 +711,11 @@ class TestVnfInstantiateWorkflow(asynctest.TestCase): await self.execute_workflow() self.assertTrue(isinstance(err.exception.cause, ActivityError)) - @patch("osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflow.instantiate_vdus") + @patch("osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflowImpl.instantiate_vdus") async def test_vnf_instantiate_workflow__use_different_task_queue__use_juju_task_queue( self, mock_instantiate_vdus ): - workflows = [VnfInstantiateWorkflow, MockPrepareVnfWorkflow] + workflows = [VnfInstantiateWorkflowImpl, MockPrepareVnfWorkflow] activities = [ mock_get_different_task_queue, self.mock_change_vnf_instantiation_state, @@ -755,19 +741,19 @@ class TestVnfInstantiateWorkflow(asynctest.TestCase): class TestInstantiateVdus(asynctest.TestCase): @patch( - "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflow._get_vdu_instantiate_info" + "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflowImpl._get_vdu_instantiate_input" ) @patch("temporalio.workflow.execute_child_workflow") async def test_instantiate_vdus__empty_vnf_instantiation_config__child_wf_executed_with_expected_vdu_instantiate_input( self, mock_execute_child_workflow, - mock_get_vdu_instantiate_info, + mock_get_vdu_instantiate_input, ): - mock_get_vdu_instantiate_info.return_value = ( + mock_get_vdu_instantiate_input.return_value = ( sample_vdu_instantiate_input, sample_vdu_instantiate_wf_id_1, ) - await VnfInstantiateWorkflow.instantiate_vdus( + await VnfInstantiateWorkflowImpl.instantiate_vdus( sample_vnfr, sample_vnfd, LCM_TASK_QUEUE, cloud, {} ) call_mock_execute_child_workflow = mock_execute_child_workflow.call_args_list @@ -777,24 +763,24 @@ class TestInstantiateVdus(asynctest.TestCase): "arg": sample_vdu_instantiate_input, "id": sample_vdu_instantiate_wf_id_1, "task_queue": LCM_TASK_QUEUE, - "workflow": "vdu-instantiate", + "workflow": f"{VduInstantiateWorkflow.__name__}", }, ) @patch( - "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflow._get_vdu_instantiate_info" + "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflowImpl._get_vdu_instantiate_input" ) @patch("temporalio.workflow.execute_child_workflow") async def test_instantiate_vdus__vnf_instantiation_config_exists__child_wf_executed_with_expected_vdu_instantiate_input( self, mock_execute_child_workflow, - mock_get_vdu_instantiate_info, + mock_get_vdu_instantiate_input, ): - mock_get_vdu_instantiate_info.return_value = ( + mock_get_vdu_instantiate_input.return_value = ( sample_vdu_instantiate_input_with_config, sample_vdu_instantiate_wf_id_1, ) - await VnfInstantiateWorkflow.instantiate_vdus( + await VnfInstantiateWorkflowImpl.instantiate_vdus( sample_vnfr, sample_vnfd, LCM_TASK_QUEUE, cloud, vnf_config ) call_mock_execute_child_workflow = mock_execute_child_workflow.call_args_list @@ -804,40 +790,40 @@ class TestInstantiateVdus(asynctest.TestCase): "arg": sample_vdu_instantiate_input_with_config, "id": sample_vdu_instantiate_wf_id_1, "task_queue": LCM_TASK_QUEUE, - "workflow": "vdu-instantiate", + "workflow": f"{VduInstantiateWorkflow.__name__}", }, ) @patch( - "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflow._get_vdu_instantiate_info" + "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflowImpl._get_vdu_instantiate_input" ) @patch("temporalio.workflow.execute_child_workflow") async def test_instantiate_vdus__vnfd_without_vdu__child_wf_is_not_executed( self, mock_execute_child_workflow, - mock_get_vdu_instantiate_info, + mock_get_vdu_instantiate_input, ): vnfd = deepcopy(sample_vnfd) vnfd["vdu"] = [] - await VnfInstantiateWorkflow.instantiate_vdus( + await VnfInstantiateWorkflowImpl.instantiate_vdus( sample_vnfr, vnfd, LCM_TASK_QUEUE, cloud, {} ) mock_execute_child_workflow.assert_not_called() @patch( - "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflow._get_vdu_instantiate_info" + "osm_lcm.temporal.vnf_workflows.VnfInstantiateWorkflowImpl._get_vdu_instantiate_input" ) @patch("temporalio.workflow.execute_child_workflow") async def test_instantiate_vdus__use_juju_task_queue__child_wf_executed_with_juju_task_queue( self, mock_execute_child_workflow, - mock_get_vdu_instantiate_info, + mock_get_vdu_instantiate_input, ): - mock_get_vdu_instantiate_info.return_value = ( + mock_get_vdu_instantiate_input.return_value = ( sample_vdu_instantiate_input_with_config, sample_vdu_instantiate_wf_id_1, ) - await VnfInstantiateWorkflow.instantiate_vdus( + await VnfInstantiateWorkflowImpl.instantiate_vdus( sample_vnfr, sample_vnfd, juju_task_queue, cloud, vnf_config ) call_mock_execute_child_workflow = mock_execute_child_workflow.call_args_list @@ -847,25 +833,25 @@ class TestInstantiateVdus(asynctest.TestCase): "arg": sample_vdu_instantiate_input_with_config, "id": sample_vdu_instantiate_wf_id_1, "task_queue": juju_task_queue, - "workflow": "vdu-instantiate", + "workflow": f"{VduInstantiateWorkflow.__name__}", }, ) class TestGetVduInstantiateInfo(asynctest.TestCase): @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_application_config" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_vdu_instantiation_params" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params" ) @asynctest.mock.patch( "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_compute_constraints" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints" ) - async def test_get_vdu_instantiate_info__empty_vnf_instantiation_config__get_expected_vdu_inst_input_and_wf_id( + async def test_get_vdu_instantiate_input__empty_vnf_instantiation_config__get_expected_vdu_inst_input_and_wf_id( self, mock_get_compute_constraints, mock_get_charm_info, @@ -879,7 +865,7 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): ( vdu_instantiate_input, vdu_instantiate_workflow_id, - ) = VnfInstantiateWorkflow._get_vdu_instantiate_info( + ) = VnfInstantiateWorkflowImpl._get_vdu_instantiate_input( vnfr=sample_vnfr, vnfd=sample_vnfd, vdu=vdu, @@ -892,18 +878,18 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_application_config" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_vdu_instantiation_params" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params" ) @asynctest.mock.patch( "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_compute_constraints" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints" ) - async def test_get_vdu_instantiate_info__with_vnf_instantiation_config__get_expected_vdu_inst_input_and_wf_id( + async def test_get_vdu_instantiate_input__with_vnf_instantiation_config__get_expected_vdu_inst_input_and_wf_id( self, mock_get_compute_constraints, mock_get_charm_info, @@ -917,7 +903,7 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): ( vdu_instantiate_input, vdu_instantiate_workflow_id, - ) = VnfInstantiateWorkflow._get_vdu_instantiate_info( + ) = VnfInstantiateWorkflowImpl._get_vdu_instantiate_input( vnfr=sample_vnfr, vnfd=sample_vnfd, vdu=vdu, @@ -930,18 +916,18 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_application_config" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_vdu_instantiation_params" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params" ) @asynctest.mock.patch( "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_compute_constraints" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints" ) - async def test_get_vdu_instantiate_info__vnfr_without_namespace__raise_type_error( + async def test_get_vdu_instantiate_input__vnfr_without_namespace__raise_type_error( self, mock_get_compute_constraints, mock_get_charm_info, @@ -953,7 +939,7 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): mock_get_compute_constraints.return_value = sample_constraints mock_get_charm_info.return_value = sample_charm_info with self.assertRaises(TypeError): - VnfInstantiateWorkflow._get_vdu_instantiate_info( + VnfInstantiateWorkflowImpl._get_vdu_instantiate_input( vnfr=vnfr, vnfd=sample_vnfd, vdu=vdu, @@ -962,18 +948,18 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_application_config" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_vdu_instantiation_params" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params" ) @asynctest.mock.patch( "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_compute_constraints" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints" ) - async def test_get_vdu_instantiate_info__app_name_is_empty__expected_wf_id( + async def test_get_vdu_instantiate_input__app_name_is_empty__expected_wf_id( self, mock_get_compute_constraints, mock_get_charm_info, @@ -987,7 +973,7 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): ( _, vdu_instantiate_workflow_id, - ) = VnfInstantiateWorkflow._get_vdu_instantiate_info( + ) = VnfInstantiateWorkflowImpl._get_vdu_instantiate_input( vnfr=sample_vnfr, vnfd=sample_vnfd, vdu=vdu, @@ -997,18 +983,18 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): self.assertEqual(vdu_instantiate_workflow_id, "my-model-name-") @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_application_config" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_vdu_instantiation_params" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params" ) @asynctest.mock.patch( "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_compute_constraints" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints" ) - async def test_get_vdu_instantiate_info__get_compute_constraints_failed__no_vdu_inst_wf_input_and_vdu_wf_id( + async def test_get_vdu_instantiate_input__get_compute_constraints_failed__no_vdu_inst_wf_input_and_vdu_wf_id( self, mock_get_compute_constraints, mock_get_charm_info, @@ -1023,7 +1009,7 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): ( vdu_instantiate_input, vdu_instantiate_workflow_id, - ) = VnfInstantiateWorkflow._get_vdu_instantiate_info( + ) = VnfInstantiateWorkflowImpl._get_vdu_instantiate_input( vnfr=sample_vnfr, vnfd=sample_vnfd, vdu=vdu, @@ -1035,18 +1021,18 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_application_config" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_vdu_instantiation_params" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params" ) @asynctest.mock.patch( "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_compute_constraints" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints" ) - async def test_get_vdu_instantiate_info__get_compute_constraints_failed__raise_compute_constraints_exception( + async def test_get_vdu_instantiate_input__get_compute_constraints_failed__raise_compute_constraints_exception( self, mock_get_compute_constraints, mock_get_charm_info, @@ -1058,7 +1044,7 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): ) mock_get_charm_info.return_value = sample_charm_info with self.assertRaises(GetComputeConstraintsException): - VnfInstantiateWorkflow._get_vdu_instantiate_info( + VnfInstantiateWorkflowImpl._get_vdu_instantiate_input( vnfr=sample_vnfr, vnfd=sample_vnfd, vdu=vdu, @@ -1067,18 +1053,18 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_application_config" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_vdu_instantiation_params" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params" ) @asynctest.mock.patch( "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_compute_constraints" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints" ) - async def test_get_vdu_instantiate_info__get_charm_info_failed__raise_get_charm_info_exception( + async def test_get_vdu_instantiate_input__get_charm_info_failed__raise_get_charm_info_exception( self, mock_get_compute_constraints, mock_get_charm_info, @@ -1090,7 +1076,7 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): "get_compute_constraints failed" ) with self.assertRaises(GetCharmInfoException): - VnfInstantiateWorkflow._get_vdu_instantiate_info( + VnfInstantiateWorkflowImpl._get_vdu_instantiate_input( vnfr=sample_vnfr, vnfd=sample_vnfd, vdu=vdu, @@ -1099,18 +1085,18 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_application_config" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_vdu_instantiation_params" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params" ) @asynctest.mock.patch( "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_compute_constraints" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints" ) - async def test_get_vdu_instantiate_info__get_charm_info_failed__no_vdu_inst_wf_input_and_vdu_wf_id( + async def test_get_vdu_instantiate_input__get_charm_info_failed__no_vdu_inst_wf_input_and_vdu_wf_id( self, mock_get_compute_constraints, mock_get_charm_info, @@ -1125,7 +1111,7 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): ( vdu_instantiate_input, vdu_instantiate_workflow_id, - ) = VnfInstantiateWorkflow._get_vdu_instantiate_info( + ) = VnfInstantiateWorkflowImpl._get_vdu_instantiate_input( vnfr=sample_vnfr, vnfd=sample_vnfd, vdu=vdu, @@ -1137,18 +1123,18 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_application_config" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_vdu_instantiation_params" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params" ) @asynctest.mock.patch( "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_compute_constraints" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints" ) - async def test_get_vdu_instantiate_info__get_vdu_instantiation_params_failed__raise_get_vdu_instantiation_params_exception( + async def test_get_vdu_instantiate_input__get_vdu_instantiation_params_failed__raise_get_vdu_instantiation_params_exception( self, mock_get_compute_constraints, mock_get_charm_info, @@ -1162,7 +1148,7 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): ) mock_get_application_config.return_value = {} with self.assertRaises(GetVduInstantiationParamsException): - VnfInstantiateWorkflow._get_vdu_instantiate_info( + VnfInstantiateWorkflowImpl._get_vdu_instantiate_input( vnfr=sample_vnfr, vnfd=sample_vnfd, vdu=vdu, @@ -1171,18 +1157,18 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_application_config" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_vdu_instantiation_params" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params" ) @asynctest.mock.patch( "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_compute_constraints" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints" ) - async def test_get_vdu_instantiate_info__get_vdu_instantiation_params_failed__no_vdu_inst_wf_input_and_vdu_wf_id( + async def test_get_vdu_instantiate_input__get_vdu_instantiation_params_failed__no_vdu_inst_wf_input_and_vdu_wf_id( self, mock_get_compute_constraints, mock_get_charm_info, @@ -1199,7 +1185,7 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): ( vdu_instantiate_input, vdu_instantiate_workflow_id, - ) = VnfInstantiateWorkflow._get_vdu_instantiate_info( + ) = VnfInstantiateWorkflowImpl._get_vdu_instantiate_input( vnfr=sample_vnfr, vnfd=sample_vnfd, vdu=vdu, @@ -1212,18 +1198,18 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_application_config" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_vdu_instantiation_params" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params" ) @asynctest.mock.patch( "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_compute_constraints" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints" ) - async def test_get_vdu_instantiate_info__get_application_config_failed__raise_get_application_config_exception( + async def test_get_vdu_instantiate_input__get_application_config_failed__raise_get_application_config_exception( self, mock_get_compute_constraints, mock_get_charm_info, @@ -1237,7 +1223,7 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): "get_vdu_instantiation_params failed" ) with self.assertRaises(GetApplicationConfigException): - VnfInstantiateWorkflow._get_vdu_instantiate_info( + VnfInstantiateWorkflowImpl._get_vdu_instantiate_input( vnfr=sample_vnfr, vnfd=sample_vnfd, vdu=vdu, @@ -1246,18 +1232,18 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_application_config" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_application_config" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_vdu_instantiation_params" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_vdu_instantiation_params" ) @asynctest.mock.patch( "osm_lcm.temporal.juju_paas_activities.CharmInfoUtils.get_charm_info" ) @asynctest.mock.patch( - "osm_lcm.temporal.vnf_activities.VnfOperations.get_compute_constraints" + "osm_lcm.temporal.vnf_activities.VnfSpecifications.get_compute_constraints" ) - async def test_get_vdu_instantiate_info__get_application_config_failed__no_vdu_inst_wf_input_and_vdu_wf_id( + async def test_get_vdu_instantiate_input__get_application_config_failed__no_vdu_inst_wf_input_and_vdu_wf_id( self, mock_get_compute_constraints, mock_get_charm_info, @@ -1274,7 +1260,7 @@ class TestGetVduInstantiateInfo(asynctest.TestCase): ( vdu_instantiate_input, vdu_instantiate_workflow_id, - ) = VnfInstantiateWorkflow._get_vdu_instantiate_info( + ) = VnfInstantiateWorkflowImpl._get_vdu_instantiate_input( vnfr=sample_vnfr, vnfd=sample_vnfd, vdu=vdu,