From: Bin Yang Date: Wed, 24 Nov 2021 00:22:09 +0000 (+0800) Subject: Update o2dms lcm api X-Git-Tag: 1.0.0~17 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=7fb3d02a3744ecb368b0531f16175034b987d42f;p=pti%2Fo2.git Update o2dms lcm api Signed-off-by: Bin Yang Change-Id: I86445cd818441826e17da9b946b480c29f94a401 --- diff --git a/o2app/adapter/unit_of_work.py b/o2app/adapter/unit_of_work.py index 2a8663d..e488542 100644 --- a/o2app/adapter/unit_of_work.py +++ b/o2app/adapter/unit_of_work.py @@ -52,6 +52,10 @@ class SqlAlchemyUnitOfWork(AbstractUnitOfWork): .DeploymentManagerSqlAlchemyRepository(self.session) self.nfdeployment_descs = dms_repository\ .NfDeploymentDescSqlAlchemyRepository(self.session) + self.nfdeployments = dms_repository\ + .NfDeploymentSqlAlchemyRepository(self.session) + self.ocloudvresources = dms_repository\ + .NfOCloudVResourceSqlAlchemyRepository(self.session) return super().__enter__() def __exit__(self, *args): @@ -83,3 +87,9 @@ class SqlAlchemyUnitOfWork(AbstractUnitOfWork): for entry in self.nfdeployment_descs.seen: while entry.events: yield entry.events.pop(0) + for entry in self.nfdeployments.seen: + while entry.events: + yield entry.events.pop(0) + for entry in self.ocloudvresources.seen: + while entry.events: + yield entry.events.pop(0) diff --git a/o2dms/adapter/dms_repository.py b/o2dms/adapter/dms_repository.py index 5dd2bb1..2c7c3ca 100644 --- a/o2dms/adapter/dms_repository.py +++ b/o2dms/adapter/dms_repository.py @@ -41,3 +41,57 @@ class NfDeploymentDescSqlAlchemyRepository(dms_repo self.session.query(dms.NfDeploymentDesc).filter_by( id=nfdeployment_desc_id ).delete() + + +class NfDeploymentSqlAlchemyRepository( + dms_repo.NfDeploymentRepository): + + def __init__(self, session): + super().__init__() + self.session = session + + def _add(self, nfdeployment: dms.NfDeployment): + self.session.add(nfdeployment) + + def _get(self, nfdeployment_id) -> dms.NfDeployment: + return self.session.query(dms.NfDeployment).filter_by( + id=nfdeployment_id).first() + + def _list(self) -> List[dms.NfDeployment]: + return self.session.query() + + def _update(self, nfdeployment_id, **kwargs): + self.session.query(dms.NfDeployment).filter_by( + id=nfdeployment_id).update(**kwargs) + + def _delete(self, nfdeployment_id): + self.session.query(dms.NfDeployment).filter_by( + id=nfdeployment_id + ).delete() + + +class NfOCloudVResourceSqlAlchemyRepository( + dms_repo.NfOCloudVResourceRepository): + + def __init__(self, session): + super().__init__() + self.session = session + + def _add(self, nfocloudvres: dms.NfOCloudVResource): + self.session.add(nfocloudvres) + + def _get(self, nfocloudvres_id) -> dms.NfOCloudVResource: + return self.session.query(dms.NfOCloudVResource).filter_by( + id=nfocloudvres_id).first() + + def _list(self) -> List[dms.NfOCloudVResource]: + return self.session.query() + + def _update(self, nfocloudvres, **kwargs): + self.session.query(dms.NfOCloudVResource).filter_by( + id=nfocloudvres).update(**kwargs) + + def _delete(self, nfocloudvres): + self.session.query(dms.NfOCloudVResource).filter_by( + id=nfocloudvres + ).delete() diff --git a/o2dms/adapter/orm.py b/o2dms/adapter/orm.py index 05821dc..1c2c93a 100644 --- a/o2dms/adapter/orm.py +++ b/o2dms/adapter/orm.py @@ -50,11 +50,49 @@ nfDeploymentDesc = Table( # Column("extensions", String(1024)) ) +nfDeployment = Table( + "nfDeployment", + metadata, + Column("updatetime", DateTime), + Column("createtime", DateTime), + Column("hash", String(255)), + Column("version_number", Integer), + + Column("id", String(255), primary_key=True), + Column("deploymentManagerId", String(255)), + Column("name", String(255)), + Column("description", String(255)), + Column("descriptorId", String(255)), + Column("parentDeploymentId", String(255)), + Column("status", Integer) +) + +nfOCloudVResource = Table( + "nfOcloudVRes", + metadata, + Column("updatetime", DateTime), + Column("createtime", DateTime), + Column("hash", String(255)), + Column("version_number", Integer), + + Column("id", String(255), primary_key=True), + Column("deploymentManagerId", String(255)), + Column("name", String(255)), + Column("description", String(255)), + Column("descriptorId", String(255)), + Column("vresourceType", String(255)), + Column("status", Integer), + Column("metadata", String(2048)), + Column("nfDeploymentId", String(255)) +) + def start_o2dms_mappers(engine=None): logger.info("Starting O2 DMS mappers") mapper(dmsModel.NfDeploymentDesc, nfDeploymentDesc) + mapper(dmsModel.NfDeployment, nfDeployment) + mapper(dmsModel.NfOCloudVResource, nfOCloudVResource) if engine is not None: metadata.create_all(engine) diff --git a/o2dms/domain/dms.py b/o2dms/domain/dms.py index 31932ee..28faf3c 100644 --- a/o2dms/domain/dms.py +++ b/o2dms/domain/dms.py @@ -29,3 +29,34 @@ class NfDeploymentDesc(AgRoot): self.inputParams = inputParams self.outputParams = outputParams # self.extensions = [] + + +class NfDeployment(AgRoot): + def __init__(self, id: str, name: str, dmsId: str, description: str = '', + descriptorId: str = '', parentId: str = '',) -> None: + super().__init__() + self.id = id + self.version_number = 0 + self.deploymentManagerId = dmsId + self.name = name + self.description = description + self.descriptorId = descriptorId + self.parentDeploymentId = parentId + self.status = 0 + + +class NfOCloudVResource(AgRoot): + def __init__(self, id: str, name: str, dmsId: str, description: str = '', + descriptorId: str = '', nfDeploymentId: str = '', + vresourceType: int = 0,) -> None: + super().__init__() + self.id = id + self.version_number = 0 + self.deploymentManagerId = dmsId + self.name = name + self.description = description + self.descriptorId = descriptorId + self.nfDeploymentId = nfDeploymentId + self.vresourceType = vresourceType + self.status = 0 + self.metadata = [] diff --git a/o2dms/domain/dms_repo.py b/o2dms/domain/dms_repo.py index 2564a81..c53d90f 100644 --- a/o2dms/domain/dms_repo.py +++ b/o2dms/domain/dms_repo.py @@ -17,6 +17,46 @@ from typing import List, Set from o2dms.domain import dms +class NfDeploymentRepository(abc.ABC): + def __init__(self): + self.seen = set() # type: Set[dms.NfDeployment] + + def add(self, nfdeployment: dms.NfDeployment): + self._add(nfdeployment) + self.seen.add(nfdeployment) + + def get(self, nfdeployment_id) -> dms.NfDeployment: + nfdeployment = self._get(nfdeployment_id) + if nfdeployment: + self.seen.add(nfdeployment) + return nfdeployment + + def list(self) -> List[dms.NfDeployment]: + return self._list() + + def update(self, id, **kwargs): + self._update(id, **kwargs) + + def delete(self, nfdeployment_id): + self._delete(nfdeployment_id) + + @abc.abstractmethod + def _add(self, nfdeployment: dms.NfDeployment): + raise NotImplementedError + + @abc.abstractmethod + def _get(self, nfdeployment_id) -> dms.NfDeployment: + raise NotImplementedError + + @abc.abstractmethod + def _update(self, id, **kwargs): + raise NotImplementedError + + @abc.abstractmethod + def _delete(self, nfdeployment_id): + raise NotImplementedError + + class NfDeploymentDescRepository(abc.ABC): def __init__(self): self.seen = set() # type: Set[dms.NfDeploymentDesc] @@ -49,9 +89,49 @@ class NfDeploymentDescRepository(abc.ABC): raise NotImplementedError @abc.abstractmethod - def _update(self, nfdeployment_descriptor: dms.NfDeploymentDesc): + def _update(self, id, **kwargs): raise NotImplementedError @abc.abstractmethod def _delete(self, nfdeployment_descriptor_id): raise NotImplementedError + + +class NfOCloudVResourceRepository(abc.ABC): + def __init__(self): + self.seen = set() # type: Set[dms.NfOCloudVResource] + + def add(self, nfocloudvres: dms.NfOCloudVResource): + self._add(nfocloudvres) + self.seen.add(nfocloudvres) + + def get(self, nfocloudvres_id) -> dms.NfOCloudVResource: + nfocloudvres = self._get(nfocloudvres_id) + if nfocloudvres: + self.seen.add(nfocloudvres) + return nfocloudvres + + def list(self) -> List[dms.NfOCloudVResource]: + return self._list() + + def update(self, nfocloudvres_id, **kwargs): + self._update(nfocloudvres_id, **kwargs) + + def delete(self, nfocloudvres_id): + self._delete(nfocloudvres_id) + + @abc.abstractmethod + def _add(self, nfocloudvres: dms.NfOCloudVResource): + raise NotImplementedError + + @abc.abstractmethod + def _get(self, nfocloudvres_id) -> dms.NfOCloudVResource: + raise NotImplementedError + + @abc.abstractmethod + def _update(self, nfocloudvres_id, **kwargs): + raise NotImplementedError + + @abc.abstractmethod + def _delete(self, nfocloudvres_id): + raise NotImplementedError diff --git a/o2dms/views/dms_dto.py b/o2dms/views/dms_dto.py index 4acc9a3..e52bc3e 100644 --- a/o2dms/views/dms_dto.py +++ b/o2dms/views/dms_dto.py @@ -33,7 +33,7 @@ class DmsDTO: class DmsLcmNfDeploymentDescriptorDTO: - dmslcm_NfDeploymentDescriptor_get = api_dms_lcm_v1.model( + NfDeploymentDescriptor_get = api_dms_lcm_v1.model( "NfDeploymentDescriptorGetDto", { 'id': fields.String( @@ -65,7 +65,7 @@ class DmsLcmNfDeploymentDescriptorDTO: ) NfDeploymentDescriptor_update = api_dms_lcm_v1.model( - "NfDeploymentDescriptorCreateDto", + "NfDeploymentDescriptorUpdateDto", { 'name': fields.String, 'description': fields.String, @@ -73,3 +73,64 @@ class DmsLcmNfDeploymentDescriptorDTO: 'outputParams': fields.String } ) + + +class DmsLcmNfDeploymentDTO: + NfDeployment_get = api_dms_lcm_v1.model( + "NfDeploymentGetDto", + { + 'id': fields.String( + required=True, + description='NfDeployment ID'), + 'name': fields.String, + 'description': fields.String, + 'descriptorId': fields.String, + 'parentDeploymentId': fields.String, + 'status': fields.Integer + } + ) + + NfDeployment_create = api_dms_lcm_v1.model( + "NfDeploymentCreateDto", + { + 'name': fields.String, + 'description': fields.String, + 'descriptorId': fields.String, + 'parentDeploymentId': fields.String + } + ) + + NfDeployment_create_post_resp = api_dms_lcm_v1.model( + "NfDeploymentCreateRespDto", + { + 'id': fields.String( + required=True, description='NfDeployment ID'), + } + ) + + NfDeployment_update = api_dms_lcm_v1.model( + "NfDeploymentUpdateDto", + { + 'name': fields.String, + 'description': fields.String, + 'descriptorId': fields.String, + 'parentDeploymentId': fields.String + } + ) + + +class DmsLcmNfOCloudVResourceDTO: + NfOCloudVResource_get = api_dms_lcm_v1.model( + "NfOCloudVResourceGetDto", + { + 'id': fields.String( + required=True, + description='NfOCloudVResource ID'), + 'name': fields.String, + 'description': fields.String, + 'descriptorId': fields.String, + 'vresourceType': fields.String, + 'status': fields.Integer, + 'metadata': fields.String + } + ) diff --git a/o2dms/views/dms_lcm_view.py b/o2dms/views/dms_lcm_view.py index ab84fba..186c9c3 100644 --- a/o2dms/views/dms_lcm_view.py +++ b/o2dms/views/dms_lcm_view.py @@ -16,9 +16,10 @@ from sqlalchemy import select import uuid from o2common.service import unit_of_work from o2ims.adapter.orm import deploymentmanager -from o2dms.adapter.orm import nfDeploymentDesc +from o2dms.adapter.orm import nfDeploymentDesc, nfDeployment, nfOCloudVResource from o2dms.views.dms_dto import DmsLcmNfDeploymentDescriptorDTO -from o2dms.domain.dms import NfDeploymentDesc +from o2dms.views.dms_dto import DmsLcmNfDeploymentDTO +from o2dms.domain.dms import NfDeploymentDesc, NfDeployment def deployment_managers(uow: unit_of_work.AbstractUnitOfWork): @@ -91,3 +92,77 @@ def lcm_nfdeploymentdesc_delete( uow.nfdeployment_descs.delete(nfdeploymentdescriptorid) uow.commit() return True + + +def lcm_nfdeployment_list( + deploymentManagerID: str, uow: unit_of_work.AbstractUnitOfWork): + with uow: + res = uow.session.execute(select(nfDeployment).where( + nfDeployment.c.deploymentManagerId == deploymentManagerID)) + return [dict(r) for r in res] + + +def lcm_nfdeployment_one( + nfdeploymentid: str, uow: unit_of_work.AbstractUnitOfWork): + with uow: + res = uow.session.execute(select(nfDeployment).where( + nfDeployment.c.id == nfdeploymentid)) + first = res.first() + return None if first is None else dict(first) + + +def lcm_nfdeployment_create( + deploymentManagerId: str, + input: DmsLcmNfDeploymentDTO. + NfDeployment_create, + uow: unit_of_work.AbstractUnitOfWork): + + id = str(uuid.uuid4()) + entity = NfDeployment( + id, input['name'], deploymentManagerId, input['description'], + input['descriptorId'], input['parentDeploymentId']) + with uow: + uow.nfdeployments.add(entity) + uow.commit() + return id + + +def lcm_nfdeployment_update( + nfdeploymentdescriptorid: str, + input: DmsLcmNfDeploymentDTO.NfDeployment_update, + uow: unit_of_work.AbstractUnitOfWork): + + with uow: + entity = uow.nfdeployments.get(nfdeploymentdescriptorid) + entity.name = input['name'] + entity.description = input['description'] + entity.inputParams = input['descriptorId'] + entity.outputParams = input['parentDeploymentId'] + uow.commit() + return True + + +def lcm_nfdeployment_delete( + nfdeploymentdescriptorid: str, uow: unit_of_work.AbstractUnitOfWork): + + with uow: + uow.nfdeployments.delete(nfdeploymentdescriptorid) + uow.commit() + return True + + +def lcm_nfocloudvresource_list( + nfDeploymentId: str, uow: unit_of_work.AbstractUnitOfWork): + with uow: + res = uow.session.execute(select(nfOCloudVResource).where( + nfOCloudVResource.c.nfDeploymentId == nfDeploymentId)) + return [dict(r) for r in res] + + +def lcm_nfocloudvresource_one( + ocloudvresourceId: str, uow: unit_of_work.AbstractUnitOfWork): + with uow: + res = uow.session.execute(select(nfOCloudVResource).where( + nfOCloudVResource.c.id == ocloudvresourceId)) + first = res.first() + return None if first is None else dict(first) diff --git a/o2dms/views/dms_route.py b/o2dms/views/dms_route.py index e9fd2e2..0fc6e69 100644 --- a/o2dms/views/dms_route.py +++ b/o2dms/views/dms_route.py @@ -17,6 +17,8 @@ from flask_restx import Resource from o2common.config import config from o2dms.views.dms_dto import DmsDTO, DmsLcmNfDeploymentDescriptorDTO +from o2dms.views.dms_dto import DmsLcmNfDeploymentDTO +from o2dms.views.dms_dto import DmsLcmNfOCloudVResourceDTO from o2dms.views import dms_lcm_view, api_dms_lcm_v1 apibase = config.get_o2dms_api_base() @@ -50,7 +52,7 @@ class DmsGetRouter(Resource): @api_dms_lcm_v1.response(404, 'DMS LCM not found') class DmsLcmNfDeploymentDescListRouter(Resource): - model = DmsLcmNfDeploymentDescriptorDTO.dmslcm_NfDeploymentDescriptor_get + model = DmsLcmNfDeploymentDescriptorDTO.NfDeploymentDescriptor_get createdto = DmsLcmNfDeploymentDescriptorDTO.NfDeploymentDescriptor_create post_resp = DmsLcmNfDeploymentDescriptorDTO.\ @@ -82,7 +84,7 @@ class DmsLcmNfDeploymentDescListRouter(Resource): @api_dms_lcm_v1.response(404, 'DMS LCM not found') class DmsLcmNfDeploymentDescGetRouter(Resource): - model = DmsLcmNfDeploymentDescriptorDTO.dmslcm_NfDeploymentDescriptor_get + model = DmsLcmNfDeploymentDescriptorDTO.NfDeploymentDescriptor_get updatedto = DmsLcmNfDeploymentDescriptorDTO.\ NfDeploymentDescriptor_update @@ -114,6 +116,127 @@ class DmsLcmNfDeploymentDescGetRouter(Resource): return '', 204 +# LCM services # +@api_dms_lcm_v1\ + .route("//O2dms_DeploymentLifecycle/" + "NfDeployment") +@api_dms_lcm_v1\ + .param('deploymentManagerID', 'ID of the deployment manager') +@api_dms_lcm_v1.response(404, 'DMS LCM not found') +class DmsLcmNfDeploymentListRouter(Resource): + + model = DmsLcmNfDeploymentDTO.NfDeployment_get + + createdto = DmsLcmNfDeploymentDTO.NfDeployment_create + post_resp = DmsLcmNfDeploymentDTO.\ + NfDeployment_create_post_resp + + @api_dms_lcm_v1.doc('Get a list of NfDeployment') + @api_dms_lcm_v1.marshal_list_with(model) + def get(self, deploymentManagerID): + return dms_lcm_view.lcm_nfdeployment_list( + deploymentManagerID, bus.uow) + + @api_dms_lcm_v1.doc('Create a NfDeployment') + @api_dms_lcm_v1.expect(createdto) + @api_dms_lcm_v1.marshal_with(post_resp, code=201) + def post(self, deploymentManagerID): + data = api_dms_lcm_v1.payload + id = dms_lcm_view.lcm_nfdeployment_create( + deploymentManagerID, data, bus.uow) + return {"id": id}, 201 + + +@api_dms_lcm_v1\ + .route("//O2dms_DeploymentLifecycle/" + "NfDeployment/") +@api_dms_lcm_v1\ + .param('deploymentManagerID', 'ID of the deployment manager') +@api_dms_lcm_v1.param('nfDeploymentId', + 'ID of the NfDeployment') +@api_dms_lcm_v1.response(404, 'DMS LCM not found') +class DmsLcmNfDeploymentGetRouter(Resource): + + model = DmsLcmNfDeploymentDTO.NfDeployment_get + updatedto = DmsLcmNfDeploymentDTO.\ + NfDeployment_update + + @api_dms_lcm_v1.doc('Get a NfDeploymentDescriptor') + @api_dms_lcm_v1.marshal_with(model) + def get(self, nfDeploymentId, deploymentManagerID): + result = dms_lcm_view\ + .lcm_nfdeployment_one(nfDeploymentId, bus.uow) + if result is not None: + return result + api_dms_lcm_v1.abort( + 404, "NfDeploymentDescriptor {} doesn't exist".format( + nfDeploymentId)) + + @api_dms_lcm_v1.doc('Update a NfDeployment') + @api_dms_lcm_v1.expect(updatedto) + def put(self, nfDeploymentId, deploymentManagerID): + data = api_dms_lcm_v1.payload + dms_lcm_view.lcm_nfdeployment_update( + nfDeploymentId, data, bus.uow) + return {}, 201 + + @api_dms_lcm_v1.doc('Delete NfDeployment by ID') + @api_dms_lcm_v1.response(204, 'NfDeployment deleted') + def delete(self, nfDeploymentId, deploymentManagerID): + with bus.uow: + bus.uow.nfdeployments.delete(nfDeploymentId) + bus.uow.commit() + return '', 204 + + +# LCM services # +@api_dms_lcm_v1\ + .route("//O2dms_DeploymentLifecycle/" + "NfDeployment//NfOCloudVirtualResource") +@api_dms_lcm_v1\ + .param('deploymentManagerID', 'ID of the Deployment Manager') +@api_dms_lcm_v1.param('nfDeploymentId', + 'ID of the NfDeployment') +@api_dms_lcm_v1.response(404, 'DMS LCM not found') +class DmsLcmNfOCloudVResListRouter(Resource): + + model = DmsLcmNfOCloudVResourceDTO.NfOCloudVResource_get + + @api_dms_lcm_v1.doc('Get a list of NfOCloudVirtualResource') + @api_dms_lcm_v1.marshal_list_with(model) + def get(self, nfDeploymentId, deploymentManagerID): + return dms_lcm_view.lcm_nfocloudvresource_list( + nfDeploymentId, bus.uow) + + +@api_dms_lcm_v1\ + .route("//O2dms_DeploymentLifecycle/" + "NfDeployment/" + "NfOCloudVirtualResource/") +@api_dms_lcm_v1\ + .param('deploymentManagerID', 'ID of the deployment manager') +@api_dms_lcm_v1.param('nfDeploymentId', + 'ID of the NfDeployment') +@api_dms_lcm_v1.param('nfOCloudVirtualResourceId', + 'ID of the NfOCloudVirtualResource') +@api_dms_lcm_v1.response(404, 'DMS LCM not found') +class DmsLcmNfOCloudVResGetRouter(Resource): + + model = DmsLcmNfOCloudVResourceDTO.NfOCloudVResource_get + + @api_dms_lcm_v1.doc('Get a NfOCloudVirtualResource') + @api_dms_lcm_v1.marshal_with(model) + def get(self, nfOCloudVirtualResourceId, + nfDeploymentId, deploymentManagerID): + result = dms_lcm_view\ + .lcm_nfocloudvresource_one(nfOCloudVirtualResourceId, bus.uow) + if result is not None: + return result + api_dms_lcm_v1.abort( + 404, "NfOCloudVirtualResource {} doesn't exist".format( + nfOCloudVirtualResourceId)) + + def configure_namespace(app, bus_new): app.add_namespace(api_dms_lcm_v1, path=apibase)