OSMENG-1155 Implementation of Constants and Dataclasses

Add stubs for common elements, workflows and activities

Change-Id: If7a2aa8a6e6627df5293154bf48da742dea57e1c
Signed-off-by: Dario Faccin <dario.faccin@canonical.com>
diff --git a/osm_common/temporal/activities/base.py b/osm_common/temporal/activities/base.py
new file mode 100644
index 0000000..d207fe3
--- /dev/null
+++ b/osm_common/temporal/activities/base.py
@@ -0,0 +1,23 @@
+#######################################################################################
+# Copyright ETSI Contributors and Others.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#######################################################################################
+
+import logging
+
+
+class BaseActivity:
+    def __init__(self):
+        self.logger = logging.getLogger(f"lcm.act.{self.__class__.__name__}")
diff --git a/osm_common/temporal/activities/lcm.py b/osm_common/temporal/activities/lcm.py
new file mode 100644
index 0000000..9298bd1
--- /dev/null
+++ b/osm_common/temporal/activities/lcm.py
@@ -0,0 +1,113 @@
+#######################################################################################
+# Copyright ETSI Contributors and Others.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#######################################################################################
+
+from dataclasses import dataclass
+
+from osm_common.dbbase import DbBase
+from osm_common.temporal.activities.base import BaseActivity
+from osm_common.temporal.states import LcmOperationState
+
+
+class NsLcmNoOp(BaseActivity):
+    """
+    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.
+    """
+
+    @dataclass
+    class Input:
+        """
+        Input dataclass for workflows that run as LCM operations.
+
+        Attributes:
+        -----------
+
+        nslcmop: dict
+            A dictionary representing the nslcmop record from the
+            database.
+        """
+
+        nslcmop: dict
+
+    async def __call__(self, activity_input: Input) -> None:
+        raise NotImplementedError()
+
+
+class UpdateNsLcmOperationState(BaseActivity):
+    """
+    Changes the state of a LCM operation task.  Should be done to
+    indicate progress, or completion of the task itself.
+
+    Collaborators:
+        DB Write:           nslcmops
+
+    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
+    """
+
+    @dataclass
+    class Input:
+        """
+        Input dataclass for updating LCM Operations in the Mongo nslcmops
+        collection.  The following attributes will be updated automatically
+          - statusEnteredTime
+          - _admin.modified
+
+        Attributes:
+        -----------
+        op_id: str
+            The operation (task) id for this activity.  This is the key
+            to the record in nslcmops collection that will be updated.
+
+        op_state : LcmOperationState
+            A representation of the state of the specified operation id,
+            such as PROCESSING, COMPLETED, or FAILED.
+
+        stage: str
+            Human readable checkpoint message, intended only to give the
+            user feedback.
+
+        error_message: str
+            Human readable error message if any failure occurred.
+
+        detailed_status : str
+            Human readable message providing additional details to the
+            operation state, such as the error message explaining why
+            the operation failed.
+        """
+
+        op_id: str
+        op_state: LcmOperationState
+        stage: str
+        error_message: str
+        detailed_status: str
+
+    def __init__(self, db: DbBase):
+        super().__init__()
+        self.db: DbBase = db
+
+    async def __call__(self, activity_input: Input) -> None:
+        raise NotImplementedError()
diff --git a/osm_common/temporal/activities/ns.py b/osm_common/temporal/activities/ns.py
new file mode 100644
index 0000000..4f1f4fe
--- /dev/null
+++ b/osm_common/temporal/activities/ns.py
@@ -0,0 +1,180 @@
+#######################################################################################
+# Copyright ETSI Contributors and Others.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#######################################################################################
+
+from dataclasses import dataclass
+from typing import List
+
+
+from osm_common.dbbase import DbBase
+from osm_common.temporal.activities.base import BaseActivity
+from osm_common.temporal.states import NsState
+
+
+class GetVnfDetails(BaseActivity):
+    """
+    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.
+    """
+
+    @dataclass
+    class Input:
+        """
+        Attributes:
+        -----------
+        ns_uuid : str
+            The UUID of the NS from which to retrieve the VNF records.
+        """
+
+        ns_uuid: str
+
+    @dataclass
+    class Output:
+        """
+        Attributes:
+        -----------
+        vnf_details: list[(vnfr_ids: str, vnf_member_index_ref: str), .. ]
+            List of tuples including VNF details associated with the NS.
+            Tuple(VNF record IDs, vnf_member_index_ref)
+        """
+
+        vnf_details: List[tuple]
+
+    def __init__(self, db: DbBase):
+        super().__init__()
+        self.db: DbBase = db
+
+    async def __call__(self, activity_input: Input) -> Output:
+        raise NotImplementedError()
+
+
+class GetNsRecord(BaseActivity):
+    """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.
+
+    """
+
+    @dataclass
+    class Input:
+        """
+        Input dataclass for getting NS record activity.
+
+        Attributes:
+        -----------
+        nsr_uuid :
+            The UUID of the NS record which is stored in the OSM nsrs
+            collection in Mongo.
+
+        """
+
+        nsr_uuid: str
+
+    @dataclass
+    class Output:
+        """
+        Output dataclass for getting NS record activity.
+
+        Attributes:
+        -----------
+        nsr : dict
+            NS record retrieved from Database..
+
+        """
+
+        nsr: dict
+
+    def __init__(self, db: DbBase):
+        super().__init__()
+        self.db: DbBase = db
+
+    async def __call__(self, activity_input: Input) -> Output:
+        raise NotImplementedError()
+
+
+class UpdateNsState(BaseActivity):
+    """
+    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
+    """
+
+    @dataclass
+    class Input:
+        """
+        Input dataclass for updating NS state in the DB
+
+        Attributes:
+        -----------
+        ns_uuid : str
+            The UUID of the NS as stored in the OSM ns
+            collection in Mongo
+
+        operational_state : NsState
+            A representation of the operational state (ENABLED or ERROR)
+            of the NS.
+
+        message : str
+            Human readable message providing additional details to the
+            operational state, such as the error message associated
+            with the ERROR operational_state.
+        """
+
+        ns_uuid: str
+        state: NsState
+        message: str
+
+    def __init__(self, db: DbBase):
+        super().__init__()
+        self.db: DbBase = db
+
+    async def __call__(self, activity_input: Input) -> None:
+        raise NotImplementedError()
diff --git a/osm_common/temporal/activities/paas.py b/osm_common/temporal/activities/paas.py
new file mode 100644
index 0000000..a037282
--- /dev/null
+++ b/osm_common/temporal/activities/paas.py
@@ -0,0 +1,231 @@
+#######################################################################################
+# Copyright ETSI Contributors and Others.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#######################################################################################
+
+from dataclasses import dataclass
+
+from osm_common.dbbase import DbBase
+from osm_common.temporal.activities.base import BaseActivity
+from osm_common.temporal.dataclasses_common import CharmInfo, VduComputeConstraints
+
+
+class TestVimConnectivity(BaseActivity):
+    """Validates the credentials by attempting to connect to the given Juju Controller.
+
+    Collaborators:
+        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.
+
+        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.
+    """
+
+    @dataclass
+    class Input:
+        """
+        Input dataclass for the Test Vim Connectivity Ativity
+
+        Attributes:
+        -----------
+        vim_uuid : str
+            The UUID of the VIM account as stored in the OSM vim
+            collection in Mongo
+        """
+
+        vim_uuid: str
+
+    def __init__(self, juju_controller):
+        super().__init__()
+        self.juju_controller = juju_controller
+
+    async def __call__(self, activity_input: Input) -> None:
+        raise NotImplementedError()
+
+
+class CreateModel(BaseActivity):
+    """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.
+    """
+
+    @dataclass
+    class Input:
+        """
+        Contains the information related to a model.
+
+        Attributes:
+        -----------
+        vim_uuid : str
+            The UUID of the VIM as stored in the OSM vim_accounts
+            collection in Mongo.
+
+        model_name : str
+            Name of the Juju model used to deploy charms.
+        """
+
+        vim_uuid: str
+        model_name: str
+
+    def __init__(self, db: DbBase, juju_controller):
+        super().__init__()
+        self.db: DbBase = db
+        self.juju_controller = juju_controller
+
+    async def __call__(self, activity_input: Input) -> None:
+        raise NotImplementedError()
+
+
+class DeployCharm(BaseActivity):
+    """Deploys a charm.
+
+    Collaborators:
+        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.
+
+        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.
+    """
+
+    @dataclass
+    class Input:
+        """
+        Input dataclass for workflow that instantiates a VDU.
+
+        vim_uuid: str
+
+        model_name: str
+
+        charm_info : CharmInfo
+
+        constraints: VduComputeConstraints
+
+        cloud: VIM cloud type
+
+        config: Config details of application
+        """
+
+        vim_uuid: str
+        model_name: str
+        charm_info: CharmInfo
+        constraints: VduComputeConstraints
+        cloud: str
+        config: dict
+
+    def __init__(self, juju_controller):
+        super().__init__()
+        self.juju_controller = juju_controller
+
+    async def __call__(self, activity_input: Input) -> None:
+        raise NotImplementedError()
+
+
+class CheckCharmStatus(BaseActivity):
+    """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:
+        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 time out.
+
+        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.
+    """
+
+    @dataclass
+    class Input:
+        """
+        Input dataclass for checking on a specific charm's deployment
+        status
+
+        Attributes:
+        -----------
+        vim_uuid : str
+            The UUID of the VIM as stored in the OSM vim_accounts
+            collection in Mongo.
+
+        model_name : str
+            Name of the model to create in Juju.
+
+        application_name : str
+            Name of the application that the state is going to be
+            awaited.
+
+        poll_interval : int (optional)
+            Time, in seconds, to wait between status checks.
+        """
+
+        vim_uuid: str
+        model_name: str
+        application_name: str
+        poll_interval: int = 1
+
+    def __init__(self, juju_controller):
+        super().__init__()
+        self.juju_controller = juju_controller
+
+    async def __call__(self, activity_input: Input) -> None:
+        raise NotImplementedError()
diff --git a/osm_common/temporal/activities/vim.py b/osm_common/temporal/activities/vim.py
new file mode 100644
index 0000000..e52b6a1
--- /dev/null
+++ b/osm_common/temporal/activities/vim.py
@@ -0,0 +1,174 @@
+#######################################################################################
+# Copyright ETSI Contributors and Others.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#######################################################################################
+
+from dataclasses import dataclass
+
+from osm_common.dbbase import DbBase
+from osm_common.temporal.activities.base import BaseActivity
+from osm_common.temporal.states import VimOperationState, VimState
+
+
+class UpdateVimState(BaseActivity):
+    """
+    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
+    """
+
+    @dataclass
+    class Input:
+        """
+        Input dataclass for updating VIM state in the DB
+
+        Attributes:
+        -----------
+        vim_uuid : str
+            The UUID of the VIM account as stored in the OSM vim
+            collection in Mongo
+
+        operational_state : VimState
+            A representation of the operational state (ENABLED or ERROR)
+            of the VIM.
+
+        message : str
+            Human readable message providing additional details to the
+            operational state, such as the error message associated
+            with the ERROR operational_state.
+        """
+
+        vim_uuid: str
+        operational_state: VimState
+        message: str
+
+    def __init__(self, db: DbBase):
+        super().__init__()
+        self.db: DbBase = db
+
+    async def __call__(self, activity_input: Input) -> None:
+        raise NotImplementedError()
+
+
+class UpdateVimOperationState(BaseActivity):
+    """
+    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
+    """
+
+    @dataclass
+    class Input:
+        """
+        Input dataclass for updating VIM Operations in the Mongo VIM
+        collection.
+
+        Attributes:
+        -----------
+        vim_uuid : str
+            The UUID of the VIM account as stored in the OSM vim
+            collection in Mongo
+
+        op_id: str
+            The operation (task) id for this workflow.  This is used
+            to update the status of the operation in Mongo vim collection.
+
+        op_state : VimOperationState
+            A representation of the state of the specified operation id,
+            such as COMPLETED, or FAILED.
+
+        message : str
+            Human readable message providing additional details to the
+            operation state, such as the error message explaining why
+            the operation failed.
+        """
+
+        vim_uuid: str
+        op_id: str
+        op_state: VimOperationState
+        message: str
+
+    def __init__(self, db: DbBase):
+        super().__init__()
+        self.db: DbBase = db
+
+    async def __call__(self, activity_input: Input) -> None:
+        raise NotImplementedError()
+
+
+class DeleteVimRecord(BaseActivity):
+    """
+    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
+    """
+
+    @dataclass
+    class Input:
+        """
+        Input dataclass for deleting vim record from the database
+
+        Attributes:
+        -----------
+        vim_uuid : str
+            The UUID of the VIM account as stored in the OSM vim
+            collection in Mongo
+
+        """
+
+        vim_uuid: str
+
+    def __init__(self, db: DbBase):
+        super().__init__()
+        self.db: DbBase = db
+
+    async def __call__(self, activity_input: Input) -> None:
+        raise NotImplementedError()
diff --git a/osm_common/temporal/activities/vnf.py b/osm_common/temporal/activities/vnf.py
new file mode 100644
index 0000000..81f2982
--- /dev/null
+++ b/osm_common/temporal/activities/vnf.py
@@ -0,0 +1,420 @@
+#######################################################################################
+# Copyright ETSI Contributors and Others.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#######################################################################################
+
+from dataclasses import dataclass
+
+from osm_common.dbbase import DbBase
+from osm_common.temporal.activities.base import BaseActivity
+from osm_common.temporal.states import VnfInstantiationState, VnfState
+
+
+class ChangeVnfState(BaseActivity):
+    """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.
+
+    """
+
+    @dataclass
+    class Input:
+        """
+        Input dataclass for changing VNF State.
+
+        Attributes:
+        -----------
+        vnfr_uuid : str
+            The UUID of the VNF which is stored in the OSM vnfrs
+            collection in Mongo.
+
+        state : VnfState
+            A representation of the VNF state (STOPPED or STARTED).
+        """
+
+        vnfr_uuid: str
+        state: VnfState
+
+    def __init__(self, db: DbBase):
+        super().__init__()
+        self.db: DbBase = db
+
+    async def __call__(self, activity_input: Input) -> None:
+        raise NotImplementedError()
+
+
+class ChangeVnfInstantiationState(BaseActivity):
+    """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.
+
+    """
+
+    @dataclass
+    class Input:
+        """
+        Input dataclass for changing VNF Instantiation State.
+
+        Attributes:
+        -----------
+        vnfr_uuid : str
+            The UUID of the VNF which is stored in the OSM vnfrs
+            collection in Mongo.
+
+        state : VnfInstantiationState
+            A representation of the VNF instantiation state (NOT_INSTANTIATED or INSTANTIATED).
+
+        """
+
+        vnfr_uuid: str
+        state: VnfInstantiationState
+
+    def __init__(self, db: DbBase):
+        super().__init__()
+        self.db: DbBase = db
+
+    async def __call__(self, activity_input: Input) -> None:
+        raise NotImplementedError()
+
+
+class GetVnfRecord(BaseActivity):
+    """Gets the VNF record and VNF descriptor from Database.
+
+    Collaborators:
+        DB read:           vnfrs, 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).
+
+        This activity will not report a heartbeat due to its
+        short-running nature.
+
+        This is an idempotent activity.
+
+    """
+
+    @dataclass
+    class Input:
+        """
+        Input dataclass for get vnf details activity.
+
+        Attributes:
+        -----------
+        vnfr_uuid : str
+            The UUID of the VNF which is stored in the OSM vnfrs
+            collection in Mongo.
+        """
+
+        vnfr_uuid: str
+
+    @dataclass
+    class Output:
+        """
+        Output dataclass for get vnf details activity.
+
+        Attributes:
+        -----------
+        vnf_details: list[(vnfr_ids: str, vnf_member_index_ref: str), .. ]
+            List of tuples including VNF details associated with the NS.
+            Tuple(VNF record IDs, vnf_member_index_ref)
+        """
+
+        vnfr: dict
+
+    def __init__(self, db: DbBase):
+        super().__init__()
+        self.db: DbBase = db
+
+    async def __call__(self, activity_input: Input) -> Output:
+        raise NotImplementedError()
+
+
+class GetVnfDescriptor(BaseActivity):
+    """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.
+
+    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.
+
+    """
+
+    @dataclass
+    class Input:
+        """
+        Input dataclass for get vnf descriptor activity.
+
+        Attributes:
+        -----------
+        vnfd_uuid : str
+            The UUID of the VNF descriptor which is stored in the OSM vnfds
+            collection in Mongo.
+        """
+
+        vnfd_uuid: str
+
+    @dataclass
+    class Output:
+        """
+        Output dataclass for get vnf details activity.
+
+        Attributes:
+        -----------
+        vnfd : dict
+            VNF descriptor retrieved from Database.
+        """
+
+        vnfd: dict
+
+    def __init__(self, db: DbBase):
+        super().__init__()
+        self.db: DbBase = db
+
+    async def __call__(self, activity_input: Input) -> Output:
+        raise NotImplementedError()
+
+
+class SendNotificationForVnf(BaseActivity):
+    """Perform Notification operations."""
+
+    @dataclass
+    class Input:
+        """
+        Input dataclass for sending notifications for change in VNF Instantiation State.
+
+        Attributes:
+        -----------
+        vnfr_uuid : str
+            The UUID of the VNF which is stored in the OSM vnfrs
+            collection in Mongo.
+
+        state : VnfInstantiationState
+            A representation of the VNF instantiation state (NOT_INSTANTIATED or INSTANTIATED).
+
+        """
+
+        vnfr_uuid: str
+        state: VnfState
+
+    async def __call__(self, activity_input: Input):
+        raise NotImplementedError()
+
+
+class GetTaskQueue(BaseActivity):
+    """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.
+
+    """
+
+    @dataclass
+    class Input:
+        """
+        Input dataclass for get task queue activity.
+
+        Attributes:
+        -----------
+        vnfr_uuid : str
+            The UUID of the VNF which is stored in the OSM vnfrs
+            collection in Mongo.
+
+        """
+
+        vnfr_uuid: str
+
+    @dataclass
+    class Output:
+        """
+        Output dataclass for get task queue activity.
+
+        Attributes:
+        -----------
+        task_queue : str
+            Name of the queue which is used to Deploy VNF.
+        """
+
+        task_queue: str
+
+    def __init__(self, db: DbBase):
+        super().__init__()
+        self.db: DbBase = db
+
+    async def __call__(self, activity_input: Input) -> Output:
+        raise NotImplementedError()
+
+
+class GetVimCloud(BaseActivity):
+    """Finds the cloud by checking the VIM account of VNF.
+
+    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.
+
+    """
+
+    @dataclass
+    class Input:
+        """
+        Input dataclass for get vim cloud activity.
+
+        Attributes:
+        -----------
+        vnfr_uuid : str
+            The UUID of the VNF which is stored in the OSM vnfrs
+            collection in Mongo.
+
+        """
+
+        vnfr_uuid: str
+
+    @dataclass
+    class Output:
+        """
+        Output dataclass for get vim cloud activity.
+
+        Attributes:
+        -----------
+        cloud : str
+            Type of the cloud which is used to Deploy VNF.
+        """
+
+        cloud: str
+
+    def __init__(self, db: DbBase):
+        super().__init__()
+        self.db: DbBase = db
+
+    async def __call__(self, activity_input: Input) -> Output:
+        raise NotImplementedError()
+
+
+class SetVnfModel(BaseActivity):
+    """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.
+
+    """
+
+    @dataclass
+    class Input:
+        """
+        Input dataclass for workflow that instantiates a VNF.
+
+        Attributes:
+        -----------
+        vnfr_uuid : str
+            The UUID of the VNF which is stored in the OSM vnfrs
+            collection in Mongo.
+
+        model_name: str
+
+        """
+
+        vnfr_uuid: str
+        model_name: str
+
+    def __init__(self, db: DbBase):
+        super().__init__()
+        self.db: DbBase = db
+
+    async def __call__(self, activity_input: Input) -> None:
+        raise NotImplementedError()