Integrate nfdeployment api with event handler 54/7254/1
authorBin Yang <bin.yang@windriver.com>
Tue, 7 Dec 2021 03:32:07 +0000 (11:32 +0800)
committerBin Yang <bin.yang@windriver.com>
Tue, 7 Dec 2021 08:07:59 +0000 (16:07 +0800)
Fix O2DMS api load issue

Issue-ID: INF-239

Signed-off-by: Bin Yang <bin.yang@windriver.com>
Change-Id: Idc5a41eb25fab5f23ac23fc5632f6589776e8f7c

22 files changed:
o2app/entrypoints/flask_application.py
o2app/entrypoints/redis_eventconsumer.py
o2app/service/handlers.py
o2dms/adapter/dms_repository.py
o2dms/adapter/orm.py
o2dms/api/__init__.py [new file with mode: 0644]
o2dms/api/dms_api_ns.py [new file with mode: 0644]
o2dms/api/dms_dto.py [moved from o2dms/views/dms_dto.py with 93% similarity]
o2dms/api/dms_lcm_nfdeployment.py [new file with mode: 0644]
o2dms/api/dms_lcm_nfdeployment_vres.py [new file with mode: 0644]
o2dms/api/dms_lcm_nfdeploymentdesc.py [new file with mode: 0644]
o2dms/api/dms_lcm_view.py [new file with mode: 0644]
o2dms/api/dms_route.py [moved from o2dms/views/dms_route.py with 81% similarity]
o2dms/api/nfdeployment_desc_route.py [moved from o2dms/views/nfdeployment_desc_route.py with 80% similarity]
o2dms/api/nfdeployment_route.py [moved from o2dms/views/nfdeployment_route.py with 69% similarity]
o2dms/api/ocloud_vresource_route.py [moved from o2dms/views/ocloud_vresource_route.py with 90% similarity]
o2dms/domain/commands.py [new file with mode: 0644]
o2dms/domain/dms.py
o2dms/domain/dms_repo.py
o2dms/domain/events.py [moved from o2dms/views/__init__.py with 66% similarity]
o2dms/service/nfdeployment_handler.py [new file with mode: 0644]
o2dms/views/dms_lcm_view.py [deleted file]

index ab8c261..f9d5f85 100644 (file)
@@ -17,7 +17,7 @@ from flask_restx import Api
 \r
 from o2app import bootstrap\r
 from o2ims.views import ocloud_route as ims_route\r
-from o2dms.views import configure_namespace as dms_route_configure_namespace\r
+from o2dms.api import configure_namespace as dms_route_configure_namespace\r
 \r
 \r
 # apibase = config.get_o2ims_api_base()\r
index 188eb87..1d38f04 100644 (file)
 #  limitations under the License.
 
 # import json
+from logging import log
 import redis
-
+import json
 from o2app import bootstrap
 from o2common.config import config
 # from o2common.domain import commands
+from o2dms.domain import commands
+from o2dms.domain import events
 
 from o2common.helper import o2logging
 logger = o2logging.get_logger(__name__)
@@ -29,14 +32,27 @@ def main():
     logger.info("Redis pubsub starting")
     bus = bootstrap.bootstrap()
     pubsub = r.pubsub(ignore_subscribe_messages=True)
-    pubsub.subscribe("dms_changed")
+    pubsub.subscribe("NfDeploymentCreated")
 
     for m in pubsub.listen():
-        handle_dms_changed(m, bus)
+        try:
+            handle_dms_changed(m, bus)
+        except Exception as ex:
+            logger.warning("{}".format(str(ex)))
+            continue
 
 
 def handle_dms_changed(m, bus):
     logger.info("handling %s", m)
+    channel = m['channel'].decode("UTF-8")
+    if channel == "NfDeploymentCreated":
+        datastr = m['data']
+        data = json.loads(datastr)
+        logger.info('InstallNfDeployment with cmd:{}'.format(data))
+        cmd = commands.InstallNfDeployment(NfDeploymentId = data['NfDeploymentId'])
+        bus.handle(cmd)
+    else:
+        logger.info("unhandled:{}".format(channel))
     # data = json.loads(m["data"])
     # cmd = commands.UpdateDms(ref=data["dmsid"])
     # bus.handle(cmd)
index f3b3d6d..b551ca6 100644 (file)
@@ -18,9 +18,14 @@ from __future__ import annotations
 from typing import List, Dict, Callable, Type
 # TYPE_CHECKING
 from o2ims.domain import commands, events
+
+from o2dms.domain import commands as o2dms_cmmands
+from o2dms.domain import events as o2dms_events
 from o2ims.service.auditor import ocloud_handler, dms_handler, \
     resourcepool_handler, pserver_handler, pserver_cpu_handler, \
     pserver_mem_handler, pserver_port_handler, pserver_if_handler
+from o2dms.service.nfdeployment_handler import publish_nfdeployment_created
+from o2dms.service.nfdeployment_handler import install_nfdeployment
 
 # if TYPE_CHECKING:
 #     from . import unit_of_work
@@ -31,7 +36,8 @@ class InvalidResourceType(Exception):
 
 
 EVENT_HANDLERS = {
-}  # type: Dict[Type[events.Event], List[Callable]]
+    o2dms_events.NfDeploymentCreated: [publish_nfdeployment_created]
+}
 
 
 COMMAND_HANDLERS = {
@@ -43,4 +49,6 @@ COMMAND_HANDLERS = {
     commands.UpdatePserverMem: pserver_mem_handler.update_pserver_mem,
     commands.UpdatePserverIf: pserver_if_handler.update_pserver_if,
     commands.UpdatePserverPort: pserver_port_handler.update_pserver_port,
+    o2dms_cmmands.InstallNfDeployment: install_nfdeployment
+
 }  # type: Dict[Type[commands.Command], Callable]
index 2c7c3ca..d0116d0 100644 (file)
@@ -42,6 +42,10 @@ class NfDeploymentDescSqlAlchemyRepository(dms_repo
             id=nfdeployment_desc_id
         ).delete()
 
+    def _count(self, **kwargs):
+        return self.session.query(
+            dms.NfDeploymentDesc).filter_by(**kwargs).count()
+
 
 class NfDeploymentSqlAlchemyRepository(
         dms_repo.NfDeploymentRepository):
@@ -69,6 +73,10 @@ class NfDeploymentSqlAlchemyRepository(
             id=nfdeployment_id
         ).delete()
 
+    def _count(self, **kwargs):
+        return self.session.query(
+            dms.NfDeployment).filter_by(**kwargs).count()
+
 
 class NfOCloudVResourceSqlAlchemyRepository(
         dms_repo.NfOCloudVResourceRepository):
index 1c2c93a..4226d26 100644 (file)
@@ -47,6 +47,7 @@ nfDeploymentDesc = Table(
     Column("description", String(255)),\r
     Column("inputParams", String(255)),\r
     Column("outputParams", String(255)),\r
+    Column("artifactUrl", String(255)),\r
     # Column("extensions", String(1024))\r
 )\r
 \r
diff --git a/o2dms/api/__init__.py b/o2dms/api/__init__.py
new file mode 100644 (file)
index 0000000..10d5562
--- /dev/null
@@ -0,0 +1,33 @@
+# Copyright (C) 2021 Wind River Systems, Inc.\r
+#\r
+#  Licensed under the Apache License, Version 2.0 (the "License");\r
+#  you may not use this file except in compliance with the License.\r
+#  You may obtain a copy of the License at\r
+#\r
+#      http://www.apache.org/licenses/LICENSE-2.0\r
+#\r
+#  Unless required by applicable law or agreed to in writing, software\r
+#  distributed under the License is distributed on an "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+#  See the License for the specific language governing permissions and\r
+#  limitations under the License.\r
+\r
+from o2dms.api.dms_api_ns import api_dms_lcm_v1\r
+from . import dms_route\r
+from . import nfdeployment_desc_route\r
+from . import nfdeployment_route\r
+from o2common.config import config\r
+\r
+from o2common.helper import o2logging\r
+logger = o2logging.get_logger(__name__)\r
+\r
+\r
+def configure_namespace(app):\r
+    apibase = config.get_o2dms_api_base()\r
+    logger.info(\r
+        "Expose O2DMS API:{}".format(apibase))\r
+\r
+    dms_route.configure_api_route()\r
+    nfdeployment_desc_route.configure_api_route()\r
+    nfdeployment_route.configure_api_route()\r
+    app.add_namespace(api_dms_lcm_v1, path=apibase)\r
diff --git a/o2dms/api/dms_api_ns.py b/o2dms/api/dms_api_ns.py
new file mode 100644 (file)
index 0000000..4c8235f
--- /dev/null
@@ -0,0 +1,5 @@
+from flask_restx import Namespace\r
+\r
+\r
+api_dms_lcm_v1 = Namespace(\r
+    "O2DMS_LCM", description='DMS LCM related operations.')\r
similarity index 93%
rename from o2dms/views/dms_dto.py
rename to o2dms/api/dms_dto.py
index e52bc3e..06d4f3c 100644 (file)
@@ -13,7 +13,9 @@
 #  limitations under the License.
 
 from flask_restx import fields
-from o2dms.views import api_dms_lcm_v1
+from o2dms.api.dms_api_ns import api_dms_lcm_v1
+from o2common.helper import o2logging
+logger = o2logging.get_logger(__name__)
 
 
 class DmsDTO:
@@ -42,7 +44,8 @@ class DmsLcmNfDeploymentDescriptorDTO:
             'name': fields.String,
             'description': fields.String,
             'inputParams': fields.String,
-            'outputParams': fields.String
+            'outputParams': fields.String,
+            'artifactUrl': fields.String
         }
     )
 
@@ -51,6 +54,7 @@ class DmsLcmNfDeploymentDescriptorDTO:
         {
             'name': fields.String,
             'description': fields.String,
+            'artifactUrl': fields.String,
             'inputParams': fields.String,
             'outputParams': fields.String
         }
@@ -69,6 +73,7 @@ class DmsLcmNfDeploymentDescriptorDTO:
         {
             'name': fields.String,
             'description': fields.String,
+            'artifactUrl': fields.String,
             'inputParams': fields.String,
             'outputParams': fields.String
         }
@@ -113,7 +118,6 @@ class DmsLcmNfDeploymentDTO:
         {
             'name': fields.String,
             'description': fields.String,
-            'descriptorId': fields.String,
             'parentDeploymentId': fields.String
         }
     )
diff --git a/o2dms/api/dms_lcm_nfdeployment.py b/o2dms/api/dms_lcm_nfdeployment.py
new file mode 100644 (file)
index 0000000..bdf5ea5
--- /dev/null
@@ -0,0 +1,112 @@
+# Copyright (C) 2021 Wind River Systems, Inc.\r
+#\r
+#  Licensed under the Apache License, Version 2.0 (the "License");\r
+#  you may not use this file except in compliance with the License.\r
+#  You may obtain a copy of the License at\r
+#\r
+#      http://www.apache.org/licenses/LICENSE-2.0\r
+#\r
+#  Unless required by applicable law or agreed to in writing, software\r
+#  distributed under the License is distributed on an "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+#  See the License for the specific language governing permissions and\r
+#  limitations under the License.\r
+\r
+from sqlalchemy import select\r
+import uuid\r
+from o2common.service import messagebus\r
+from o2dms.domain import events\r
+from o2common.service import unit_of_work\r
+from o2dms.adapter.orm import nfDeployment\r
+from o2dms.api.dms_dto import DmsLcmNfDeploymentDTO\r
+from o2dms.domain.dms import NfDeployment\r
+from o2common.helper import o2logging\r
+logger = o2logging.get_logger(__name__)\r
+\r
+\r
+def lcm_nfdeployment_list(\r
+        deploymentManagerID: str, uow: unit_of_work.AbstractUnitOfWork):\r
+    with uow:\r
+        res = uow.session.execute(select(nfDeployment).where(\r
+            nfDeployment.c.deploymentManagerId == deploymentManagerID))\r
+    return [dict(r) for r in res]\r
+\r
+\r
+def lcm_nfdeployment_one(\r
+        nfdeploymentid: str, uow: unit_of_work.AbstractUnitOfWork):\r
+    with uow:\r
+        res = uow.session.execute(select(nfDeployment).where(\r
+            nfDeployment.c.id == nfdeploymentid))\r
+        first = res.first()\r
+    return None if first is None else dict(first)\r
+\r
+\r
+def lcm_nfdeployment_create(\r
+        deploymentManagerId: str,\r
+        input: DmsLcmNfDeploymentDTO.\r
+        NfDeployment_create,\r
+        bus: messagebus.MessageBus):\r
+\r
+    uow = bus.uow\r
+    with uow:\r
+        _check_duplication(input, uow)\r
+        _check_dependencies(input, uow)\r
+        id = str(uuid.uuid4())\r
+        entity = NfDeployment(\r
+            id, input['name'], deploymentManagerId, input['description'],\r
+            input['descriptorId'], input['parentDeploymentId'])\r
+        uow.nfdeployments.add(entity)\r
+\r
+        # publish event\r
+        event = events.NfDeploymentCreated(NfDeploymentId=id)\r
+        uow.commit()\r
+    bus.handle(event)\r
+\r
+    return id\r
+\r
+\r
+def lcm_nfdeployment_update(\r
+        nfdeploymentid: str,\r
+        input: DmsLcmNfDeploymentDTO.NfDeployment_update,\r
+        uow: unit_of_work.AbstractUnitOfWork):\r
+\r
+    with uow:\r
+        entity = uow.nfdeployments.get(nfdeploymentid)\r
+        entity.name = input['name']\r
+        entity.description = input['description']\r
+        entity.outputParams = input['parentDeploymentId']\r
+        uow.commit()\r
+    return True\r
+\r
+\r
+def lcm_nfdeployment_delete(\r
+        nfdeploymentid: str, uow: unit_of_work.AbstractUnitOfWork):\r
+\r
+    with uow:\r
+        uow.nfdeployments.delete(nfdeploymentid)\r
+        uow.commit()\r
+    return True\r
+\r
+\r
+def _check_duplication(\r
+        input: DmsLcmNfDeploymentDTO,\r
+        uow: unit_of_work.AbstractUnitOfWork):\r
+    name = input['name']\r
+    descriptorId = input['descriptorId']\r
+    if uow.nfdeployments.count(name=name) > 0:\r
+        raise Exception(\r
+            "NfDeployment with name {} exists already".format(name))\r
+    if uow.nfdeployments.count(descriptorId=descriptorId) > 0:\r
+        raise Exception(\r
+            "NfDeployment with descriptorId {} exists already".format(\r
+                descriptorId))\r
+\r
+\r
+def _check_dependencies(\r
+        input: DmsLcmNfDeploymentDTO,\r
+        uow: unit_of_work.AbstractUnitOfWork):\r
+    descriptorId = input['descriptorId']\r
+    if uow.nfdeployment_descs.count(id=descriptorId) == 0:\r
+        raise Exception(\r
+            "NfDeploymentDescriptor with id {} does not exist".format(\r
+                descriptorId))\r
diff --git a/o2dms/api/dms_lcm_nfdeployment_vres.py b/o2dms/api/dms_lcm_nfdeployment_vres.py
new file mode 100644 (file)
index 0000000..edd989a
--- /dev/null
@@ -0,0 +1,36 @@
+# Copyright (C) 2021 Wind River Systems, Inc.\r
+#\r
+#  Licensed under the Apache License, Version 2.0 (the "License");\r
+#  you may not use this file except in compliance with the License.\r
+#  You may obtain a copy of the License at\r
+#\r
+#      http://www.apache.org/licenses/LICENSE-2.0\r
+#\r
+#  Unless required by applicable law or agreed to in writing, software\r
+#  distributed under the License is distributed on an "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+#  See the License for the specific language governing permissions and\r
+#  limitations under the License.\r
+\r
+from sqlalchemy import select\r
+from o2common.service import unit_of_work\r
+from o2dms.adapter.orm import nfOCloudVResource\r
+from o2common.helper import o2logging\r
+logger = o2logging.get_logger(__name__)\r
+\r
+\r
+def lcm_nfocloudvresource_list(\r
+        nfDeploymentId: str, uow: unit_of_work.AbstractUnitOfWork):\r
+    with uow:\r
+        res = uow.session.execute(select(nfOCloudVResource).where(\r
+            nfOCloudVResource.c.nfDeploymentId == nfDeploymentId))\r
+    return [dict(r) for r in res]\r
+\r
+\r
+def lcm_nfocloudvresource_one(\r
+        ocloudvresourceId: str, uow: unit_of_work.AbstractUnitOfWork):\r
+    with uow:\r
+        res = uow.session.execute(select(nfOCloudVResource).where(\r
+            nfOCloudVResource.c.id == ocloudvresourceId))\r
+        first = res.first()\r
+    return None if first is None else dict(first)\r
diff --git a/o2dms/api/dms_lcm_nfdeploymentdesc.py b/o2dms/api/dms_lcm_nfdeploymentdesc.py
new file mode 100644 (file)
index 0000000..5ed98b7
--- /dev/null
@@ -0,0 +1,99 @@
+# Copyright (C) 2021 Wind River Systems, Inc.\r
+#\r
+#  Licensed under the Apache License, Version 2.0 (the "License");\r
+#  you may not use this file except in compliance with the License.\r
+#  You may obtain a copy of the License at\r
+#\r
+#      http://www.apache.org/licenses/LICENSE-2.0\r
+#\r
+#  Unless required by applicable law or agreed to in writing, software\r
+#  distributed under the License is distributed on an "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+#  See the License for the specific language governing permissions and\r
+#  limitations under the License.\r
+\r
+from sqlalchemy import select\r
+import uuid\r
+from o2common.service import unit_of_work\r
+from o2dms.adapter.orm import nfDeploymentDesc\r
+from o2dms.api.dms_dto import DmsLcmNfDeploymentDescriptorDTO\r
+from o2dms.domain.dms import NfDeploymentDesc\r
+from o2common.helper import o2logging\r
+logger = o2logging.get_logger(__name__)\r
+\r
+\r
+def lcm_nfdeploymentdesc_list(deploymentManagerID: str,\r
+                              uow: unit_of_work.AbstractUnitOfWork):\r
+    with uow:\r
+        res = uow.session.execute(select(nfDeploymentDesc).where(\r
+            nfDeploymentDesc.c.deploymentManagerId == deploymentManagerID))\r
+    return [dict(r) for r in res]\r
+\r
+\r
+def lcm_nfdeploymentdesc_one(nfdeploymentdescriptorid: str,\r
+                             uow: unit_of_work.AbstractUnitOfWork):\r
+    with uow:\r
+        res = uow.session.execute(select(nfDeploymentDesc).where(\r
+            nfDeploymentDesc.c.id == nfdeploymentdescriptorid))\r
+        first = res.first()\r
+    return None if first is None else dict(first)\r
+\r
+\r
+def _check_duplication(name: str, uow: unit_of_work.AbstractUnitOfWork):\r
+    if uow.nfdeployment_descs.count(name=name) > 0:\r
+        raise Exception(\r
+            "NfDeploymentDescriptor with name {} exists already".format(name))\r
+\r
+\r
+def lcm_nfdeploymentdesc_create(\r
+        deploymentManagerId: str,\r
+        input: DmsLcmNfDeploymentDescriptorDTO.\r
+        NfDeploymentDescriptor_create,\r
+        uow: unit_of_work.AbstractUnitOfWork):\r
+\r
+    with uow:\r
+        _check_duplication(input['name'], uow)\r
+        id = str(uuid.uuid4())\r
+        entity = NfDeploymentDesc(\r
+            id, input['name'], deploymentManagerId, input['description'],\r
+            input['inputParams'], input['outputParams'], input['artifactUrl'])\r
+        uow.nfdeployment_descs.add(entity)\r
+        uow.commit()\r
+    return id\r
+\r
+\r
+def lcm_nfdeploymentdesc_update(\r
+        nfdeploymentdescriptorid: str,\r
+        input: DmsLcmNfDeploymentDescriptorDTO.NfDeploymentDescriptor_update,\r
+        uow: unit_of_work.AbstractUnitOfWork):\r
+\r
+    with uow:\r
+        entity = uow.nfdeployment_descs.get(nfdeploymentdescriptorid)\r
+        entity.name = input['name']\r
+        entity.description = input['description']\r
+        entity.inputParams = input['inputParams']\r
+        entity.outputParams = input['outputParams']\r
+        entity.artifactUrl = input['artifactUrl']\r
+        uow.commit()\r
+    return True\r
+\r
+\r
+def lcm_nfdeploymentdesc_delete(\r
+        nfdeploymentdescriptorid: str, uow: unit_of_work.AbstractUnitOfWork):\r
+\r
+    with uow:\r
+        # check dependency\r
+        _check_dependencies(nfdeploymentdescriptorid, uow)\r
+        uow.nfdeployment_descs.delete(nfdeploymentdescriptorid)\r
+        uow.commit()\r
+    return True\r
+\r
+\r
+def _check_dependencies(\r
+    descriptorId: str, uow: unit_of_work.AbstractUnitOfWork\r
+):\r
+    # check if nfdeployment depends on it\r
+    if uow.nfdeployments.count(descriptorId=descriptorId) > 0:\r
+        raise Exception(\r
+            "NfDeployment with descriptorId {} exists".format(\r
+                descriptorId))\r
diff --git a/o2dms/api/dms_lcm_view.py b/o2dms/api/dms_lcm_view.py
new file mode 100644 (file)
index 0000000..9995e8e
--- /dev/null
@@ -0,0 +1,34 @@
+# Copyright (C) 2021 Wind River Systems, Inc.\r
+#\r
+#  Licensed under the Apache License, Version 2.0 (the "License");\r
+#  you may not use this file except in compliance with the License.\r
+#  You may obtain a copy of the License at\r
+#\r
+#      http://www.apache.org/licenses/LICENSE-2.0\r
+#\r
+#  Unless required by applicable law or agreed to in writing, software\r
+#  distributed under the License is distributed on an "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+#  See the License for the specific language governing permissions and\r
+#  limitations under the License.\r
+\r
+from sqlalchemy import select\r
+from o2common.service import unit_of_work\r
+from o2ims.adapter.orm import deploymentmanager\r
+from o2common.helper import o2logging\r
+logger = o2logging.get_logger(__name__)\r
+\r
+\r
+def deployment_managers(uow: unit_of_work.AbstractUnitOfWork):\r
+    with uow:\r
+        res = uow.session.execute(select(deploymentmanager))\r
+    return [dict(r) for r in res]\r
+\r
+\r
+def deployment_manager_one(deploymentManagerId: str,\r
+                           uow: unit_of_work.AbstractUnitOfWork):\r
+    with uow:\r
+        res = uow.session.execute(select(deploymentmanager).where(\r
+            deploymentmanager.c.deploymentManagerId == deploymentManagerId))\r
+        first = res.first()\r
+    return None if first is None else dict(first)\r
similarity index 81%
rename from o2dms/views/dms_route.py
rename to o2dms/api/dms_route.py
index 4541258..480d965 100644 (file)
 # from flask import jsonify
 from flask_restx import Resource
 
-from o2dms.views.dms_dto import DmsDTO
-from o2dms.views import dms_lcm_view, api_dms_lcm_v1
+from o2dms.api.dms_dto import DmsDTO
+from o2dms.api import dms_lcm_view
+from o2dms.api.dms_api_ns import api_dms_lcm_v1
+
 from o2common.service.messagebus import MessageBus
+from o2common.helper import o2logging
+logger = o2logging.get_logger(__name__)
+
+
+def configure_api_route():
+    pass
 
 
 # ----------  DeploymentManagers ---------- #
@@ -31,6 +39,9 @@ class DmsGetRouter(Resource):
     @api_dms_lcm_v1.doc('Get deployment manager')
     @api_dms_lcm_v1.marshal_with(model)
     def get(self, deploymentManagerID):
+        logger.debug("get o2dms info:{}".format(
+            deploymentManagerID
+        ))
         bus = MessageBus.get_instance()
         result = dms_lcm_view.deployment_manager_one(
             deploymentManagerID, bus.uow)
similarity index 80%
rename from o2dms/views/nfdeployment_desc_route.py
rename to o2dms/api/nfdeployment_desc_route.py
index 7bcf3c3..8d6dc91 100644 (file)
 # from flask import jsonify
 from flask_restx import Resource
 
-from o2common.config import config
-from o2dms.views.dms_dto import DmsLcmNfDeploymentDescriptorDTO
-from o2dms.views import dms_lcm_view, api_dms_lcm_v1
+from o2dms.api.dms_dto import DmsLcmNfDeploymentDescriptorDTO
+from o2dms.api import dms_lcm_nfdeploymentdesc as dms_lcm_view
+from o2dms.api.dms_api_ns import api_dms_lcm_v1
+
 from o2common.service.messagebus import MessageBus
+from o2common.helper import o2logging
+logger = o2logging.get_logger(__name__)
+
 
-apibase = config.get_o2dms_api_base()
+def configure_api_route():
+    pass
 
 
 # LCM services #
@@ -49,11 +54,18 @@ class DmsLcmNfDeploymentDescListRouter(Resource):
     @api_dms_lcm_v1.expect(createdto)
     @api_dms_lcm_v1.marshal_with(post_resp, code=201)
     def post(self, deploymentManagerID):
-        bus = MessageBus.get_instance()
-        data = api_dms_lcm_v1.payload
-        id = dms_lcm_view.lcm_nfdeploymentdesc_create(
-            deploymentManagerID, data, bus.uow)
-        return {"id": id}, 201
+        try:
+            logger.debug("create deployment desc:{}".format(
+                api_dms_lcm_v1.payload
+            ))
+            bus = MessageBus.get_instance()
+            data = api_dms_lcm_v1.payload
+            id = dms_lcm_view.lcm_nfdeploymentdesc_create(
+                deploymentManagerID, data, bus.uow)
+            return {"id": id}, 201
+        except Exception as ex:
+            logger.warning("{}".format(str(ex)))
+            api_dms_lcm_v1.abort(400, str(ex))
 
 
 @api_dms_lcm_v1\
@@ -85,6 +97,9 @@ class DmsLcmNfDeploymentDescGetRouter(Resource):
     @api_dms_lcm_v1.doc('Update a NfDeploymentDescriptor')
     @api_dms_lcm_v1.expect(updatedto)
     def put(self, nfDeploymentDescriptorId, deploymentManagerID):
+        logger.debug("update deployment desc:{}".format(
+            api_dms_lcm_v1.payload
+        ))
         bus = MessageBus.get_instance()
         data = api_dms_lcm_v1.payload
         dms_lcm_view.lcm_nfdeploymentdesc_update(
similarity index 69%
rename from o2dms/views/nfdeployment_route.py
rename to o2dms/api/nfdeployment_route.py
index 962e6f4..bced33d 100644 (file)
 # from flask import jsonify
 from flask_restx import Resource
 
-from o2common.config import config
-from o2dms.views.dms_dto import DmsLcmNfDeploymentDTO
-from o2dms.views import dms_lcm_view, api_dms_lcm_v1
+from o2dms.api.dms_dto import DmsLcmNfDeploymentDTO
+from o2dms.api import dms_lcm_nfdeployment as dms_lcm_view
+from o2dms.api.dms_api_ns import api_dms_lcm_v1
+
 from o2common.service.messagebus import MessageBus
+from o2common.helper import o2logging
+logger = o2logging.get_logger(__name__)
+
 
-apibase = config.get_o2dms_api_base()
+def configure_api_route():
+    pass
 
 
 # LCM services #
@@ -49,11 +54,18 @@ class DmsLcmNfDeploymentListRouter(Resource):
     @api_dms_lcm_v1.expect(createdto)
     @api_dms_lcm_v1.marshal_with(post_resp, code=201)
     def post(self, deploymentManagerID):
-        bus = MessageBus.get_instance()
-        data = api_dms_lcm_v1.payload
-        id = dms_lcm_view.lcm_nfdeployment_create(
-            deploymentManagerID, data, bus.uow)
-        return {"id": id}, 201
+        try:
+            logger.debug("create deployment:{}".format(
+                api_dms_lcm_v1.payload
+            ))
+            bus = MessageBus.get_instance()
+            data = api_dms_lcm_v1.payload
+            id = dms_lcm_view.lcm_nfdeployment_create(
+                deploymentManagerID, data, bus)
+            return {"id": id}, 201
+        except Exception as ex:
+            logger.warning("{}".format(str(ex)))
+            api_dms_lcm_v1.abort(400, str(ex))
 
 
 @api_dms_lcm_v1\
@@ -70,7 +82,7 @@ class DmsLcmNfDeploymentGetRouter(Resource):
     updatedto = DmsLcmNfDeploymentDTO.\
         NfDeployment_update
 
-    @api_dms_lcm_v1.doc('Get a NfDeploymentDescriptor')
+    @api_dms_lcm_v1.doc('Get a NfDeployment')
     @api_dms_lcm_v1.marshal_with(model)
     def get(self, nfDeploymentId, deploymentManagerID):
         bus = MessageBus.get_instance()
@@ -79,17 +91,25 @@ class DmsLcmNfDeploymentGetRouter(Resource):
         if result is not None:
             return result
         api_dms_lcm_v1.abort(
-            404, "NfDeploymentDescriptor {} doesn't exist".format(
+            404, "NfDeployment {} doesn't exist".format(
                 nfDeploymentId))
 
     @api_dms_lcm_v1.doc('Update a NfDeployment')
     @api_dms_lcm_v1.expect(updatedto)
     def put(self, nfDeploymentId, deploymentManagerID):
-        bus = MessageBus.get_instance()
-        data = api_dms_lcm_v1.payload
-        dms_lcm_view.lcm_nfdeployment_update(
-            nfDeploymentId, data, bus.uow)
-        return {}, 201
+        try:
+            logger.debug("update deployment:{},{}".format(
+                nfDeploymentId,
+                api_dms_lcm_v1.payload
+            ))
+            bus = MessageBus.get_instance()
+            data = api_dms_lcm_v1.payload
+            dms_lcm_view.lcm_nfdeployment_update(
+                nfDeploymentId, data, bus.uow)
+            return {}, 201
+        except Exception as ex:
+            logger.warning("{}".format(str(ex)))
+            api_dms_lcm_v1.abort(400, str(ex))
 
     @api_dms_lcm_v1.doc('Delete NfDeployment by ID')
     @api_dms_lcm_v1.response(204, 'NfDeployment deleted')
similarity index 90%
rename from o2dms/views/ocloud_vresource_route.py
rename to o2dms/api/ocloud_vresource_route.py
index 4f0adfd..8d77650 100644 (file)
 # from flask import jsonify
 from flask_restx import Resource
 
-from o2common.config import config
-from o2dms.views.dms_dto import DmsLcmNfOCloudVResourceDTO
-from o2dms.views import dms_lcm_view, api_dms_lcm_v1
+from o2dms.api.dms_dto import DmsLcmNfOCloudVResourceDTO
+from o2dms.api import dms_lcm_nfdeployment_vres as dms_lcm_view
+from o2dms.api.dms_api_ns import api_dms_lcm_v1
+
 from o2common.service.messagebus import MessageBus
+from o2common.helper import o2logging
+logger = o2logging.get_logger(__name__)
+
 
-apibase = config.get_o2dms_api_base()
+def configure_api_route():
+    pass
 
 
 # LCM services #
diff --git a/o2dms/domain/commands.py b/o2dms/domain/commands.py
new file mode 100644 (file)
index 0000000..7c275a2
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright (C) 2021 Wind River Systems, Inc.
+#
+#  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.
+
+# pylint: disable=too-few-public-methods
+# from datetime import date
+# from typing import Optional
+from dataclasses import dataclass
+# from datetime import datetime
+# from o2ims.domain.resource_type import ResourceTypeEnum
+
+from o2common.domain.commands import Command
+
+
+@dataclass
+class InstallNfDeployment(Command):
+    NfDeploymentId: str
index 28faf3c..783231f 100644 (file)
@@ -19,7 +19,8 @@ from o2common.domain.base import AgRoot
 \r
 class NfDeploymentDesc(AgRoot):\r
     def __init__(self, id: str, name: str, dmsId: str, description: str = '',\r
-                 inputParams: str = '', outputParams: str = '',) -> None:\r
+                 inputParams: str = '', outputParams: str = '',\r
+                 artifacturl: str = '') -> None:\r
         super().__init__()\r
         self.id = id\r
         self.version_number = 0\r
@@ -28,6 +29,7 @@ class NfDeploymentDesc(AgRoot):
         self.description = description\r
         self.inputParams = inputParams\r
         self.outputParams = outputParams\r
+        self.artifactUrl = artifacturl\r
         # self.extensions = []\r
 \r
 \r
index c53d90f..4a63a85 100644 (file)
@@ -40,6 +40,9 @@ class NfDeploymentRepository(abc.ABC):
     def delete(self, nfdeployment_id):\r
         self._delete(nfdeployment_id)\r
 \r
+    def count(self, **kwargs):\r
+        return self._count(**kwargs)\r
+\r
     @abc.abstractmethod\r
     def _add(self, nfdeployment: dms.NfDeployment):\r
         raise NotImplementedError\r
@@ -56,6 +59,10 @@ class NfDeploymentRepository(abc.ABC):
     def _delete(self, nfdeployment_id):\r
         raise NotImplementedError\r
 \r
+    @abc.abstractmethod\r
+    def _count(self, **kwargs):\r
+        raise NotImplementedError\r
+\r
 \r
 class NfDeploymentDescRepository(abc.ABC):\r
     def __init__(self):\r
@@ -80,6 +87,9 @@ class NfDeploymentDescRepository(abc.ABC):
     def delete(self, nfdeployment_descriptor_id):\r
         self._delete(nfdeployment_descriptor_id)\r
 \r
+    def count(self, **kwargs):\r
+        return self._count(**kwargs)\r
+\r
     @abc.abstractmethod\r
     def _add(self, nfdeployment_descriptor: dms.NfDeploymentDesc):\r
         raise NotImplementedError\r
@@ -96,6 +106,10 @@ class NfDeploymentDescRepository(abc.ABC):
     def _delete(self, nfdeployment_descriptor_id):\r
         raise NotImplementedError\r
 \r
+    @abc.abstractmethod\r
+    def _count(self, **kwargs):\r
+        raise NotImplementedError\r
+\r
 \r
 class NfOCloudVResourceRepository(abc.ABC):\r
     def __init__(self):\r
similarity index 66%
rename from o2dms/views/__init__.py
rename to o2dms/domain/events.py
index 7a888a6..93af574 100644 (file)
@@ -1,25 +1,27 @@
-# Copyright (C) 2021 Wind River Systems, Inc.\r
-#\r
-#  Licensed under the Apache License, Version 2.0 (the "License");\r
-#  you may not use this file except in compliance with the License.\r
-#  You may obtain a copy of the License at\r
-#\r
-#      http://www.apache.org/licenses/LICENSE-2.0\r
-#\r
-#  Unless required by applicable law or agreed to in writing, software\r
-#  distributed under the License is distributed on an "AS IS" BASIS,\r
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-#  See the License for the specific language governing permissions and\r
-#  limitations under the License.\r
-\r
-from flask_restx import Namespace\r
-from o2common.config import config\r
-\r
-\r
-api_dms_lcm_v1 = Namespace(\r
-    "O2DMS_LCM", description='DMS LCM related operations.')\r
-apibase = config.get_o2dms_api_base()\r
-\r
-\r
-def configure_namespace(app):\r
-    app.add_namespace(api_dms_lcm_v1, path=apibase)\r
+# Copyright (C) 2021 Wind River Systems, Inc.
+#
+#  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.
+
+# pylint: disable=too-few-public-methods
+from dataclasses import dataclass
+from o2common.domain.events import Event
+
+
+@dataclass
+class NfDeploymentCreated(Event):
+    NfDeploymentId: str
+
+
+@dataclass
+class NfDeploymentDeleted(Event):
+    NfDeploymentId: str
diff --git a/o2dms/service/nfdeployment_handler.py b/o2dms/service/nfdeployment_handler.py
new file mode 100644 (file)
index 0000000..6143f18
--- /dev/null
@@ -0,0 +1,43 @@
+# Copyright (C) 2021 Wind River Systems, Inc.
+#
+#  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.
+
+# pylint: disable=unused-argument
+from __future__ import annotations
+from o2dms.domain.commands import InstallNfDeployment
+from typing import Callable
+
+from o2dms.domain import events
+from o2common.service.unit_of_work import AbstractUnitOfWork
+# if TYPE_CHECKING:
+#     from . import unit_of_work
+
+from o2common.helper import o2logging
+logger = o2logging.get_logger(__name__)
+
+
+def publish_nfdeployment_created(
+    event: events.NfDeploymentCreated,
+    publish: Callable,
+):
+    publish("NfDeploymentCreated", event)
+    logger.debug("published NfDeploymentCreated: {}".format(
+        event.NfDeploymentId))
+
+
+def install_nfdeployment(
+    cmd: InstallNfDeployment,
+    uow: AbstractUnitOfWork
+):
+    logger.info("install with NfDeploymentId: {}".format(
+        cmd.NfDeploymentId))
diff --git a/o2dms/views/dms_lcm_view.py b/o2dms/views/dms_lcm_view.py
deleted file mode 100644 (file)
index 186c9c3..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-# Copyright (C) 2021 Wind River Systems, Inc.\r
-#\r
-#  Licensed under the Apache License, Version 2.0 (the "License");\r
-#  you may not use this file except in compliance with the License.\r
-#  You may obtain a copy of the License at\r
-#\r
-#      http://www.apache.org/licenses/LICENSE-2.0\r
-#\r
-#  Unless required by applicable law or agreed to in writing, software\r
-#  distributed under the License is distributed on an "AS IS" BASIS,\r
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-#  See the License for the specific language governing permissions and\r
-#  limitations under the License.\r
-\r
-from sqlalchemy import select\r
-import uuid\r
-from o2common.service import unit_of_work\r
-from o2ims.adapter.orm import deploymentmanager\r
-from o2dms.adapter.orm import nfDeploymentDesc, nfDeployment, nfOCloudVResource\r
-from o2dms.views.dms_dto import DmsLcmNfDeploymentDescriptorDTO\r
-from o2dms.views.dms_dto import DmsLcmNfDeploymentDTO\r
-from o2dms.domain.dms import NfDeploymentDesc, NfDeployment\r
-\r
-\r
-def deployment_managers(uow: unit_of_work.AbstractUnitOfWork):\r
-    with uow:\r
-        res = uow.session.execute(select(deploymentmanager))\r
-    return [dict(r) for r in res]\r
-\r
-\r
-def deployment_manager_one(deploymentManagerId: str,\r
-                           uow: unit_of_work.AbstractUnitOfWork):\r
-    with uow:\r
-        res = uow.session.execute(select(deploymentmanager).where(\r
-            deploymentmanager.c.deploymentManagerId == deploymentManagerId))\r
-        first = res.first()\r
-    return None if first is None else dict(first)\r
-\r
-\r
-def lcm_nfdeploymentdesc_list(deploymentManagerID: str,\r
-                              uow: unit_of_work.AbstractUnitOfWork):\r
-    with uow:\r
-        res = uow.session.execute(select(nfDeploymentDesc).where(\r
-            nfDeploymentDesc.c.deploymentManagerId == deploymentManagerID))\r
-    return [dict(r) for r in res]\r
-\r
-\r
-def lcm_nfdeploymentdesc_one(nfdeploymentdescriptorid: str,\r
-                             uow: unit_of_work.AbstractUnitOfWork):\r
-    with uow:\r
-        res = uow.session.execute(select(nfDeploymentDesc).where(\r
-            nfDeploymentDesc.c.id == nfdeploymentdescriptorid))\r
-        first = res.first()\r
-    return None if first is None else dict(first)\r
-\r
-\r
-def lcm_nfdeploymentdesc_create(\r
-        deploymentManagerId: str,\r
-        input: DmsLcmNfDeploymentDescriptorDTO.\r
-        NfDeploymentDescriptor_create,\r
-        uow: unit_of_work.AbstractUnitOfWork):\r
-\r
-    id = str(uuid.uuid4())\r
-    entity = NfDeploymentDesc(\r
-        id, input['name'], deploymentManagerId, input['description'],\r
-        input['inputParams'], input['outputParams'])\r
-    with uow:\r
-        uow.nfdeployment_descs.add(entity)\r
-        uow.commit()\r
-    return id\r
-\r
-\r
-def lcm_nfdeploymentdesc_update(\r
-        nfdeploymentdescriptorid: str,\r
-        input: DmsLcmNfDeploymentDescriptorDTO.NfDeploymentDescriptor_update,\r
-        uow: unit_of_work.AbstractUnitOfWork):\r
-\r
-    with uow:\r
-        entity = uow.nfdeployment_descs.get(nfdeploymentdescriptorid)\r
-        entity.name = input['name']\r
-        entity.description = input['description']\r
-        entity.inputParams = input['inputParams']\r
-        entity.outputParams = input['outputParams']\r
-        uow.commit()\r
-    return True\r
-\r
-\r
-def lcm_nfdeploymentdesc_delete(\r
-        nfdeploymentdescriptorid: str, uow: unit_of_work.AbstractUnitOfWork):\r
-\r
-    with uow:\r
-        uow.nfdeployment_descs.delete(nfdeploymentdescriptorid)\r
-        uow.commit()\r
-    return True\r
-\r
-\r
-def lcm_nfdeployment_list(\r
-        deploymentManagerID: str, uow: unit_of_work.AbstractUnitOfWork):\r
-    with uow:\r
-        res = uow.session.execute(select(nfDeployment).where(\r
-            nfDeployment.c.deploymentManagerId == deploymentManagerID))\r
-    return [dict(r) for r in res]\r
-\r
-\r
-def lcm_nfdeployment_one(\r
-        nfdeploymentid: str, uow: unit_of_work.AbstractUnitOfWork):\r
-    with uow:\r
-        res = uow.session.execute(select(nfDeployment).where(\r
-            nfDeployment.c.id == nfdeploymentid))\r
-        first = res.first()\r
-    return None if first is None else dict(first)\r
-\r
-\r
-def lcm_nfdeployment_create(\r
-        deploymentManagerId: str,\r
-        input: DmsLcmNfDeploymentDTO.\r
-        NfDeployment_create,\r
-        uow: unit_of_work.AbstractUnitOfWork):\r
-\r
-    id = str(uuid.uuid4())\r
-    entity = NfDeployment(\r
-        id, input['name'], deploymentManagerId, input['description'],\r
-        input['descriptorId'], input['parentDeploymentId'])\r
-    with uow:\r
-        uow.nfdeployments.add(entity)\r
-        uow.commit()\r
-    return id\r
-\r
-\r
-def lcm_nfdeployment_update(\r
-        nfdeploymentdescriptorid: str,\r
-        input: DmsLcmNfDeploymentDTO.NfDeployment_update,\r
-        uow: unit_of_work.AbstractUnitOfWork):\r
-\r
-    with uow:\r
-        entity = uow.nfdeployments.get(nfdeploymentdescriptorid)\r
-        entity.name = input['name']\r
-        entity.description = input['description']\r
-        entity.inputParams = input['descriptorId']\r
-        entity.outputParams = input['parentDeploymentId']\r
-        uow.commit()\r
-    return True\r
-\r
-\r
-def lcm_nfdeployment_delete(\r
-        nfdeploymentdescriptorid: str, uow: unit_of_work.AbstractUnitOfWork):\r
-\r
-    with uow:\r
-        uow.nfdeployments.delete(nfdeploymentdescriptorid)\r
-        uow.commit()\r
-    return True\r
-\r
-\r
-def lcm_nfocloudvresource_list(\r
-        nfDeploymentId: str, uow: unit_of_work.AbstractUnitOfWork):\r
-    with uow:\r
-        res = uow.session.execute(select(nfOCloudVResource).where(\r
-            nfOCloudVResource.c.nfDeploymentId == nfDeploymentId))\r
-    return [dict(r) for r in res]\r
-\r
-\r
-def lcm_nfocloudvresource_one(\r
-        ocloudvresourceId: str, uow: unit_of_work.AbstractUnitOfWork):\r
-    with uow:\r
-        res = uow.session.execute(select(nfOCloudVResource).where(\r
-            nfOCloudVResource.c.id == ocloudvresourceId))\r
-        first = res.first()\r
-    return None if first is None else dict(first)\r