From 5c501cb5e57a1ac3e0e7d38e22a3759e7958777a Mon Sep 17 00:00:00 2001 From: "Zhang Rong(Jon)" Date: Mon, 22 Nov 2021 00:16:17 +0800 Subject: [PATCH] Add Subscription get and list API; Provide swagger openAPI doc 1. Add API that get and list subscription 2. import flask-restx package to support swagger openAPI document Signed-off-by: Zhang Rong(Jon) Change-Id: I404c25809e80af6949543ab6fb307ef2124d4dd1 --- o2ims/adapter/ocloud_repository.py | 41 +++++- o2ims/adapter/orm.py | 1 + o2ims/adapter/unit_of_work.py | 2 + o2ims/domain/ocloud.py | 4 +- o2ims/domain/ocloud_repo.py | 66 +++++++++ o2ims/entrypoints/flask_application.py | 19 ++- o2ims/views/ocloud_dto.py | 134 ++++++++++++++++++ o2ims/views/ocloud_route.py | 206 +++++++++++++++++++++++++++- o2ims/views/ocloud_view.py | 19 ++- requirements.txt | 1 + tests/conftest.py | 16 ++- tests/integration/test_ocloud_repository.py | 22 +++ tests/integration/test_ocloud_view.py | 71 ++++++++++ tests/unit/test_ocloud.py | 125 ++++++++++++++++- 14 files changed, 705 insertions(+), 22 deletions(-) create mode 100644 o2ims/views/ocloud_dto.py diff --git a/o2ims/adapter/ocloud_repository.py b/o2ims/adapter/ocloud_repository.py index 5fa9b7e..4d4361c 100644 --- a/o2ims/adapter/ocloud_repository.py +++ b/o2ims/adapter/ocloud_repository.py @@ -16,7 +16,8 @@ from typing import List # from o2ims.adapter import orm from o2ims.domain import ocloud from o2ims.domain.ocloud_repo import OcloudRepository, ResourceTypeRepository,\ - ResourcePoolRepository, ResourceRepository + ResourcePoolRepository, ResourceRepository, DeploymentManagerRepository,\ + SubscriptionRepository class OcloudSqlAlchemyRepository(OcloudRepository): @@ -95,3 +96,41 @@ class ResourceSqlAlchemyRepository(ResourceRepository): def _update(self, resource: ocloud.Resource): self.session.add(resource) + + +class DeploymentManagerSqlAlchemyRepository(DeploymentManagerRepository): + def __init__(self, session): + super().__init__() + self.session = session + + def _add(self, deployment_manager: ocloud.DeploymentManager): + self.session.add(deployment_manager) + + def _get(self, deployment_manager_id) -> ocloud.DeploymentManager: + return self.session.query(ocloud.DeploymentManager).filter_by( + deploymentManagerId=deployment_manager_id).first() + + def _list(self) -> List[ocloud.DeploymentManager]: + return self.session.query() + + def _update(self, deployment_manager: ocloud.DeploymentManager): + self.session.add(deployment_manager) + + +class SubscriptionSqlAlchemyRepository(SubscriptionRepository): + def __init__(self, session): + super().__init__() + self.session = session + + def _add(self, subscription: ocloud.Subscription): + self.session.add(subscription) + + def _get(self, subscription_id) -> ocloud.Subscription: + return self.session.query(ocloud.Subscription).filter_by( + subscriptionId=subscription_id).first() + + def _list(self) -> List[ocloud.Subscription]: + return self.session.query() + + def _update(self, subscription: ocloud.Subscription): + self.session.add(subscription) diff --git a/o2ims/adapter/orm.py b/o2ims/adapter/orm.py index 9cbf41a..a9d2cea 100644 --- a/o2ims/adapter/orm.py +++ b/o2ims/adapter/orm.py @@ -76,6 +76,7 @@ resource = Table( Column("resourceId", String(255), primary_key=True), Column("resourceTypeId", ForeignKey("resourcetype.resourceTypeId")), Column("resourcePoolId", ForeignKey("resourcepool.resourcePoolId")), + # Column("globalAssetId", String(255)), # Column("oCloudId", ForeignKey("ocloud.oCloudId")), Column("parentId", String(255)), Column("description", String(255)), diff --git a/o2ims/adapter/unit_of_work.py b/o2ims/adapter/unit_of_work.py index 23c4cff..d966a87 100644 --- a/o2ims/adapter/unit_of_work.py +++ b/o2ims/adapter/unit_of_work.py @@ -46,6 +46,8 @@ class SqlAlchemyUnitOfWork(AbstractUnitOfWork): .ResourcePoolSqlAlchemyRepository(self.session) self.resources = ocloud_repository\ .ResourceSqlAlchemyRepository(self.session) + self.deployment_managers = ocloud_repository\ + .DeploymentManagerSqlAlchemyRepository(self.session) self.stxobjects = StxObjectSqlAlchemyRepository(self.session) return super().__enter__() diff --git a/o2ims/domain/ocloud.py b/o2ims/domain/ocloud.py index 7ed2c1e..49b2550 100644 --- a/o2ims/domain/ocloud.py +++ b/o2ims/domain/ocloud.py @@ -23,8 +23,8 @@ from .resource_type import ResourceTypeEnum class Subscription(AgRoot): - def __init__(self, id: str, callback: str, consumersubid: list = [], - filter: list = []) -> None: + def __init__(self, id: str, callback: str, consumersubid: str = '', + filter: str = '') -> None: self.subscriptionId = id self.callback = callback self.consumerSubscriptionId = consumersubid diff --git a/o2ims/domain/ocloud_repo.py b/o2ims/domain/ocloud_repo.py index f3b43d2..9d9fce7 100644 --- a/o2ims/domain/ocloud_repo.py +++ b/o2ims/domain/ocloud_repo.py @@ -154,3 +154,69 @@ class ResourceRepository(abc.ABC): @abc.abstractmethod def _update(self, resource: ocloud.Resource): raise NotImplementedError + + +class DeploymentManagerRepository(abc.ABC): + def __init__(self): + self.seen = set() # type: Set[ocloud.DeploymentManager] + + def add(self, deployment_manager: ocloud.DeploymentManager): + self._add(deployment_manager) + self.seen.add(deployment_manager) + + def get(self, deployment_manager_id) -> ocloud.DeploymentManager: + deployment_manager = self._get(deployment_manager_id) + if deployment_manager: + self.seen.add(deployment_manager) + return deployment_manager + + def list(self) -> List[ocloud.DeploymentManager]: + return self._list() + + def update(self, deployment_manager: ocloud.DeploymentManager): + self._update(deployment_manager) + + @abc.abstractmethod + def _add(self, deployment_manager: ocloud.DeploymentManager): + raise NotImplementedError + + @abc.abstractmethod + def _get(self, deployment_manager_id) -> ocloud.DeploymentManager: + raise NotImplementedError + + @abc.abstractmethod + def _update(self, deployment_manager: ocloud.DeploymentManager): + raise NotImplementedError + + +class SubscriptionRepository(abc.ABC): + def __init__(self): + self.seen = set() # type: Set[ocloud.Subscription] + + def add(self, subscription: ocloud.Subscription): + self._add(subscription) + self.seen.add(subscription) + + def get(self, subscription_id) -> ocloud.Subscription: + subscription = self._get(subscription_id) + if subscription: + self.seen.add(subscription) + return subscription + + def list(self) -> List[ocloud.Subscription]: + return self._list() + + def update(self, subscription: ocloud.Subscription): + self._update(subscription) + + @abc.abstractmethod + def _add(self, subscription: ocloud.Subscription): + raise NotImplementedError + + @abc.abstractmethod + def _get(self, subscription_id) -> ocloud.Subscription: + raise NotImplementedError + + @abc.abstractmethod + def _update(self, subscription: ocloud.Subscription): + raise NotImplementedError diff --git a/o2ims/entrypoints/flask_application.py b/o2ims/entrypoints/flask_application.py index 315b86c..1144c10 100644 --- a/o2ims/entrypoints/flask_application.py +++ b/o2ims/entrypoints/flask_application.py @@ -12,15 +12,22 @@ # See the License for the specific language governing permissions and # limitations under the License. -# from datetime import datetime from flask import Flask -# request -# from o2ims.domain import commands -# from o2ims.service.handlers import InvalidResourceType +from flask_restx import Api + from o2ims import bootstrap -from o2ims.views.ocloud_route import configure_routes +# from o2ims import config +# from o2ims.views.ocloud_route import configure_routes +from o2ims.views.ocloud_route import configure_namespace +# apibase = config.get_o2ims_api_base() app = Flask(__name__) +api = Api(app, version='1.0.0', + title='O-Cloud Infrastructure Management Services', + description='Swagger OpenAPI document for \ + O-Cloud Infrastructure Management Services', + ) bus = bootstrap.bootstrap() -configure_routes(app, bus) +# configure_routes(app, bus) +configure_namespace(api, bus) diff --git a/o2ims/views/ocloud_dto.py b/o2ims/views/ocloud_dto.py new file mode 100644 index 0000000..1573101 --- /dev/null +++ b/o2ims/views/ocloud_dto.py @@ -0,0 +1,134 @@ +# 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. + +from flask_restx import Namespace, fields + + +class OcloudDTO: + + api = Namespace("Ocloud", description='Ocloud related operations.') + + ocloud_list = api.model( + "List Ocloud object", + { + 'oCloudId': fields.String(required=True), + 'globalCloudId': fields.String, + 'name': fields.String, + 'description': fields.String, + 'infrastructureManagementServiceEndpoint': fields.String, + } + ) + + +class ResourceTypeDTO: + + api = Namespace( + "ResourceType", description='Resource type related operations.') + + resource_type_get = api.model( + "Get ResourceType object", + { + 'resourceTypeId': fields.String(required=True, + description='Resource type ID'), + 'name': fields.String, + 'vendor': fields.String, + 'version': fields.String, + 'description': fields.String, + } + ) + + +class ResourcePoolDTO: + + api = Namespace( + "ResourcePool", description='Resource pool related operations.') + + resource_pool_get = api.model( + "Get ResourcePool object", + { + 'resourcePoolId': fields.String(required=True, + description='Resource pool ID'), + 'name': fields.String, + 'globalLocationId': fields.String, + 'location': fields.String, + 'description': fields.String, + } + ) + + +class ResourceDTO: + + api = Namespace("Resource", description='Resource related operations.') + + resource_list = api.model( + "List Resource object", + { + 'resourceId': fields.String(required=True, + description='Resource ID'), + 'resourceTypeId': fields.String, + 'resourcePoolId': fields.String, + 'parentId': fields.String, + 'description': fields.String, + } + ) + + resource_get = api.model( + "Get Resource object", + { + 'resourceId': fields.String(required=True, + description='Resource ID'), + 'resourceTypeId': fields.String, + 'resourcePoolId': fields.String, + 'parentId': fields.String, + 'description': fields.String, + } + ) + + +class DeploymentManagerDTO: + + api = Namespace("DeploymentManager", + description='Deployment manager related operations.') + + deployment_manager_get = api.model( + "Get DeploymentManager object", + { + 'deploymentManagerId': fields.String( + required=True, + description='Deployment manager ID'), + 'name': fields.String, + 'description': fields.String, + 'deploymentManagementServiceEndpoint': fields.String, + 'supportedLocations': fields.String, + 'capabilities': fields.String, + 'capacity': fields.String, + } + ) + + +class SubscriptionDTO: + + api = Namespace( + "Subscription", description='Subscription related operations.') + + subscription_get = api.model( + "Get Subscription object", + { + 'subscriptionId': fields.String(required=True, + description='Subscription ID'), + 'callback': fields.String, + 'consumerSubscriptionId': fields.String, + 'filter': fields.String, + } + ) diff --git a/o2ims/views/ocloud_route.py b/o2ims/views/ocloud_route.py index 1341b21..4237ab4 100644 --- a/o2ims/views/ocloud_route.py +++ b/o2ims/views/ocloud_route.py @@ -13,12 +13,216 @@ # limitations under the License. from flask import jsonify +from flask_restx import Resource from o2ims import config from o2ims.views import ocloud_view - +from o2ims.views.ocloud_dto import OcloudDTO, ResourceTypeDTO,\ + ResourcePoolDTO, ResourceDTO, DeploymentManagerDTO, SubscriptionDTO apibase = config.get_o2ims_api_base() +# api = Namespace("O2IMS", description='IMS') + + +# ---------- OClouds ---------- # +api_ocloud = OcloudDTO.api + + +@api_ocloud.route("/") +class OcloudsListRouter(Resource): + """Ocloud get endpoint + O2 interface ocloud endpoint + """ + + ocloud_get = OcloudDTO.ocloud_list + + @api_ocloud.marshal_list_with(ocloud_get) + def get(self): + return ocloud_view.oclouds(uow) + + +# ---------- ResourceTypes ---------- # +api_rt = ResourceTypeDTO.api + + +@api_rt.route("/resourceTypes") +class ResourceTypesListRouter(Resource): + + model = ResourceTypeDTO.resource_type_get + + @api_rt.marshal_list_with(model) + def get(self): + return ocloud_view.resource_types(uow) + + # @api.doc(response={405: 'Method Not Allowed'}) + # def post(self): + # api.abort(405) + + # @api.doc(response={405: 'Method Not Allowed'}) + # def put(self): + # api.abort(405) + + # @api.doc(response={405: 'Method Not Allowed'}) + # def patch(self): + # api.abort(405) + + # @api.doc(response={405: 'Method Not Allowed'}) + # def delete(self): + # api.abort(405) + + +@api_rt.route("/resourceTypes/") +@api_rt.param('resourceTypeID', 'ID of the resource type') +@api_rt.response(404, 'Resource type not found') +class ResourceTypeGetRouter(Resource): + + model = ResourceTypeDTO.resource_type_get + + @api_rt.doc('Get resource type') + @api_rt.marshal_with(model) + def get(self, resourceTypeID): + result = ocloud_view.resource_type_one(resourceTypeID, uow) + if result is not None: + return result + api_rt.abort( + 404, "Resource type {} doesn't exist".format(resourceTypeID)) + + +# ---------- ResourcePools ---------- # +api_rp = ResourcePoolDTO.api + + +@api_rp.route("/resourcePools") +class ResourcePoolsListRouter(Resource): + + model = ResourcePoolDTO.resource_pool_get + + @api_rp.marshal_list_with(model) + def get(self): + return ocloud_view.resource_pools(uow) + + +@api_rp.route("/resourcePools/") +@api_rp.param('resourcePoolID', 'ID of the resource pool') +@api_rp.response(404, 'Resource pool not found') +class ResourcePoolGetRouter(Resource): + + model = ResourcePoolDTO.resource_pool_get + + @api_rp.doc('Get resource pool') + def get(self, resourcePoolID): + result = ocloud_view.resource_pool_one(resourcePoolID, uow) + if result is not None: + return result + api_rp.abort( + 404, "Resource pool {} doesn't exist".format(resourcePoolID)) + + +# ---------- Resources ---------- # +api_res = ResourceDTO.api + + +@api_res.route("/resourcePools//resources") +@api_res.param('resourcePoolID', 'ID of the resource pool') +class ResourcesListRouter(Resource): + + model = ResourceDTO.resource_list + + @api_res.marshal_list_with(model) + def get(self, resourcePoolID): + return ocloud_view.resources(resourcePoolID, uow) + + +@api_res.route("/resourcePools//resources/") +@api_res.param('resourcePoolID', 'ID of the resource pool') +@api_res.param('resourceID', 'ID of the resource') +@api_res.response(404, 'Resource not found') +class ResourceGetRouter(Resource): + + model = ResourceDTO.resource_get + + @api_res.doc('Get resource') + def get(self, resourcePoolID, resourceID): + result = ocloud_view.resource_one(resourceID, uow) + if result is not None: + return result + api_res.abort(404, "Resource {} doesn't exist".format(resourceID)) + + +# ---------- DeploymentManagers ---------- # +api_dm = DeploymentManagerDTO.api + + +@api_dm.route("/deploymentManagers") +class DeploymentManagersListRouter(Resource): + + model = DeploymentManagerDTO.deployment_manager_get + + @api_dm.marshal_list_with(model) + def get(self): + return ocloud_view.deployment_managers(uow) + + +@api_dm.route("/deploymentManagers/") +@api_dm.param('deploymentManagerID', 'ID of the deployment manager') +@api_dm.response(404, 'Deployment manager not found') +class DeploymentManagerGetRouter(Resource): + + model = DeploymentManagerDTO.deployment_manager_get + + @api_dm.doc('Get deployment manager') + def get(self, deploymentManagerID): + result = ocloud_view.deployment_manager_one( + deploymentManagerID, uow) + if result is not None: + return result + api_dm.abort(404, "Deployment manager {} doesn't exist".format( + deploymentManagerID)) + + +# ---------- Subscriptions ---------- # +api_sub = SubscriptionDTO.api + + +@api_sub.route("/subscriptions") +class SubscriptionsListRouter(Resource): + + model = SubscriptionDTO.subscription_get + + @api_sub.marshal_list_with(model) + def get(self): + return ocloud_view.subscriptions(uow) + + +@api_sub.route("/subscriptions/") +@api_sub.param('subscriptionID', 'ID of the subscription') +@api_sub.response(404, 'Subscription not found') +class SubscriptionGetRouter(Resource): + + model = DeploymentManagerDTO.deployment_manager_get + + @api_sub.doc('Get subscription by ID') + def get(self, subscriptionID): + result = ocloud_view.subscription_one( + subscriptionID, uow) + if result is not None: + return result + api_sub.abort(404, "Subscription {} doesn't exist".format( + subscriptionID)) + + +def configure_namespace(app, bus): + + app.add_namespace(api_ocloud, path=apibase) + app.add_namespace(api_rt, path=apibase) + app.add_namespace(api_rp, path=apibase) + app.add_namespace(api_res, path=apibase) + app.add_namespace(api_dm, path=apibase) + app.add_namespace(api_sub, path=apibase) + + # Set global uow + global uow + uow = bus.uow def configure_routes(app, bus): diff --git a/o2ims/views/ocloud_view.py b/o2ims/views/ocloud_view.py index b1b6e5d..513e9e0 100644 --- a/o2ims/views/ocloud_view.py +++ b/o2ims/views/ocloud_view.py @@ -14,8 +14,8 @@ from sqlalchemy import select -from o2ims.adapter.orm import ocloud, resource, \ - resourcetype, resourcepool, deploymentmanager +from o2ims.adapter.orm import ocloud, resource, resourcetype, \ + resourcepool, deploymentmanager, subscription from o2ims.adapter import unit_of_work # from o2ims.domain.ocloud import Ocloud @@ -167,3 +167,18 @@ def deployment_manager_one(deploymentManagerId: str, deploymentmanager.c.deploymentManagerId == deploymentManagerId)) first = res.first() return None if first is None else dict(first) + + +def subscriptions(uow: unit_of_work.SqlAlchemyUnitOfWork): + with uow: + res = uow.session.execute(select(subscription)) + return [dict(r) for r in res] + + +def subscription_one(subscriptionId: str, + uow: unit_of_work.SqlAlchemyUnitOfWork): + with uow: + res = uow.session.execute(select(subscription).where( + subscription.c.subscriptionId == subscriptionId)) + first = res.first() + return None if first is None else dict(first) diff --git a/requirements.txt b/requirements.txt index fae9d70..cfeda23 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ flask +flask-restx sqlalchemy redis psycopg2-binary diff --git a/tests/conftest.py b/tests/conftest.py index 1ab714d..e06fa1c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -8,6 +8,7 @@ import pytest import redis import requests from flask import Flask +from flask_restx import Api from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker, clear_mappers from tenacity import retry, stop_after_delay @@ -17,7 +18,8 @@ from o2ims import config from o2ims.adapter.orm import metadata, start_o2ims_mappers from o2ims.adapter.clients.orm_stx import start_o2ims_stx_mappers from o2ims.adapter import unit_of_work -from o2ims.views.ocloud_route import configure_routes +# from o2ims.views.ocloud_route import configure_routes +from o2ims.views.ocloud_route import configure_namespace from o2ims.bootstrap import bootstrap @@ -33,8 +35,10 @@ def mock_flask_uow(mock_uow): session, uow = mock_uow app = Flask(__name__) # app.config["TESTING"] = True + api = Api(app) bus = bootstrap(False, uow) - configure_routes(app, bus) + # configure_routes(app, bus) + configure_namespace(api, bus) client = app.test_client() return session, client @@ -70,8 +74,10 @@ def sqlite_uow(sqlite_session_factory): def sqlite_flask_uow(sqlite_uow): app = Flask(__name__) # app.config["TESTING"] = True + api = Api(app) bus = bootstrap(False, sqlite_uow) - configure_routes(app, bus) + # configure_routes(app, bus) + configure_namespace(api, bus) yield app.test_client() @@ -128,8 +134,10 @@ def postgres_uow(postgres_session_factory): @pytest.fixture def postgres_flask_uow(postgres_uow): app = Flask(__name__) + api = Api(app) bus = bootstrap(False, postgres_uow) - configure_routes(app, bus) + # configure_routes(app, bus) + configure_namespace(api, bus) yield app.test_client() diff --git a/tests/integration/test_ocloud_repository.py b/tests/integration/test_ocloud_repository.py index 9cf6109..1adef04 100644 --- a/tests/integration/test_ocloud_repository.py +++ b/tests/integration/test_ocloud_repository.py @@ -140,3 +140,25 @@ def test_add_resource(sqlite_session_factory): resource_id1, resource_type_id1, resource_pool_id1) repo.add(resource1) assert repo.get(resource_id1) == resource1 + + +def test_add_deployment_manager(sqlite_session_factory): + session = sqlite_session_factory() + repo = repository.DeploymentManagerSqlAlchemyRepository(session) + ocloud_id1 = str(uuid.uuid4()) + deployment_manager_id1 = str(uuid.uuid4()) + deployment_manager1 = ocloud.DeploymentManager( + deployment_manager_id1, "k8s1", ocloud_id1, + config.get_api_url()+"/k8s1") + repo.add(deployment_manager1) + assert repo.get(deployment_manager_id1) == deployment_manager1 + + +def test_add_subscription(sqlite_session_factory): + session = sqlite_session_factory() + repo = repository.SubscriptionSqlAlchemyRepository(session) + subscription_id1 = str(uuid.uuid4()) + subscription1 = ocloud.Subscription( + subscription_id1, "https://callback/uri/write/here") + repo.add(subscription1) + assert repo.get(subscription_id1) == subscription1 diff --git a/tests/integration/test_ocloud_view.py b/tests/integration/test_ocloud_view.py index 38d560d..75e2804 100644 --- a/tests/integration/test_ocloud_view.py +++ b/tests/integration/test_ocloud_view.py @@ -159,3 +159,74 @@ def test_view_resource_one(sqlite_uow): resource_res = ocloud_view.resource_one(resource_id1, uow) assert str(resource_res.get("resourceId")) == resource_id1 + + +def test_view_deployment_managers(sqlite_uow): + ocloud_id1 = str(uuid.uuid4()) + deployment_manager_id1 = str(uuid.uuid4()) + deployment_manager1 = ocloud.DeploymentManager( + deployment_manager_id1, "k8s1", ocloud_id1, + config.get_api_url()+"/k8s1") + with sqlite_uow as uow: + uow.oclouds.add(deployment_manager1) + uow.commit() + + deployment_manager_list = ocloud_view.deployment_managers(uow) + assert str(deployment_manager_list[0].get( + "deploymentManagerId")) == deployment_manager_id1 + + +def test_view_deployment_manager_one(sqlite_uow): + ocloud_id1 = str(uuid.uuid4()) + deployment_manager_id1 = str(uuid.uuid4()) + deployment_manager1 = ocloud.DeploymentManager( + deployment_manager_id1, "k8s1", ocloud_id1, + config.get_api_url()+"/k8s1") + + # Query return None + deployment_manager_res = ocloud_view.deployment_manager_one( + deployment_manager_id1, sqlite_uow) + assert deployment_manager_res is None + + with sqlite_uow as uow: + uow.oclouds.add(deployment_manager1) + uow.commit() + + deployment_manager_res = ocloud_view.deployment_manager_one( + deployment_manager_id1, sqlite_uow) + assert str(deployment_manager_res.get( + "deploymentManagerId")) == deployment_manager_id1 + + +def test_view_subscriptions(mock_uow): + session, uow = mock_uow + + subscription_id1 = str(uuid.uuid4()) + session.return_value.execute.return_value = [{ + "subscriptionId": subscription_id1, + }] + + deployment_manager_list = ocloud_view.subscriptions(uow) + assert str(deployment_manager_list[0].get( + "subscriptionId")) == subscription_id1 + + +def test_view_subscription_one(mock_uow): + session, uow = mock_uow + + subscription_id1 = str(uuid.uuid4()) + session.return_value.execute.return_value.first.return_value = None + + # Query return None + deployment_manager_res = ocloud_view.subscription_one( + subscription_id1, uow) + assert deployment_manager_res is None + + session.return_value.execute.return_value.first.return_value = { + "deploymentManagerId": subscription_id1, + } + + deployment_manager_res = ocloud_view.subscription_one( + subscription_id1, uow) + assert str(deployment_manager_res.get( + "deploymentManagerId")) == subscription_id1 diff --git a/tests/unit/test_ocloud.py b/tests/unit/test_ocloud.py index 89b008b..a98f0db 100644 --- a/tests/unit/test_ocloud.py +++ b/tests/unit/test_ocloud.py @@ -75,6 +75,24 @@ def test_new_resource(): assert resource_id1 is not None and resource1.resourceId == resource_id1 +def test_new_deployment_manager(): + ocloud_id1 = str(uuid.uuid4()) + deployment_manager_id1 = str(uuid.uuid4()) + deployment_manager1 = ocloud.DeploymentManager( + deployment_manager_id1, "k8s1", ocloud_id1, + config.get_api_url()+"/k8s1") + assert deployment_manager_id1 is not None and deployment_manager1.\ + deploymentManagerId == deployment_manager_id1 + + +def test_new_subscription(): + subscription_id1 = str(uuid.uuid4()) + subscription1 = ocloud.Subscription( + subscription_id1, "https://callback/uri/write/here") + assert subscription_id1 is not None and\ + subscription1.subscriptionId == subscription_id1 + + def test_view_olcouds(mock_uow): session, uow = mock_uow @@ -201,6 +219,74 @@ def test_view_resource_one(mock_uow): assert str(resource_res.get("resourceId")) == resource_id1 +def test_view_deployment_managers(mock_uow): + session, uow = mock_uow + + deployment_manager_id1 = str(uuid.uuid4()) + session.return_value.execute.return_value = [{ + "deploymentManagerId": deployment_manager_id1, + }] + + deployment_manager_list = ocloud_view.deployment_managers(uow) + assert str(deployment_manager_list[0].get( + "deploymentManagerId")) == deployment_manager_id1 + + +def test_view_deployment_manager_one(mock_uow): + session, uow = mock_uow + + deployment_manager_id1 = str(uuid.uuid4()) + session.return_value.execute.return_value.first.return_value = None + + # Query return None + deployment_manager_res = ocloud_view.deployment_manager_one( + deployment_manager_id1, uow) + assert deployment_manager_res is None + + session.return_value.execute.return_value.first.return_value = { + "deploymentManagerId": deployment_manager_id1, + } + + deployment_manager_res = ocloud_view.deployment_manager_one( + deployment_manager_id1, uow) + assert str(deployment_manager_res.get( + "deploymentManagerId")) == deployment_manager_id1 + + +def test_view_subscriptions(mock_uow): + session, uow = mock_uow + + subscription_id1 = str(uuid.uuid4()) + session.return_value.execute.return_value = [{ + "subscriptionId": subscription_id1, + }] + + deployment_manager_list = ocloud_view.subscriptions(uow) + assert str(deployment_manager_list[0].get( + "subscriptionId")) == subscription_id1 + + +def test_view_subscription_one(mock_uow): + session, uow = mock_uow + + subscription_id1 = str(uuid.uuid4()) + session.return_value.execute.return_value.first.return_value = None + + # Query return None + deployment_manager_res = ocloud_view.subscription_one( + subscription_id1, uow) + assert deployment_manager_res is None + + session.return_value.execute.return_value.first.return_value = { + "deploymentManagerId": subscription_id1, + } + + deployment_manager_res = ocloud_view.subscription_one( + subscription_id1, uow) + assert str(deployment_manager_res.get( + "deploymentManagerId")) == subscription_id1 + + def test_flask_get_list(mock_flask_uow): session, client = mock_flask_uow session.return_value.execute.return_value = [] @@ -208,7 +294,7 @@ def test_flask_get_list(mock_flask_uow): # Get list and return empty list ########################## - resp = client.get(apibase) + resp = client.get(apibase+"/") assert resp.get_data() == b'[]\n' resp = client.get(apibase+"/resourceTypes") @@ -230,24 +316,28 @@ def test_flask_get_one(mock_flask_uow): session.return_value.execute.return_value.first.return_value = None apibase = config.get_o2ims_api_base() - # Get one and return nothing + # Get one and return 404 ########################### resource_type_id1 = str(uuid.uuid4()) resp = client.get(apibase+"/resourceTypes/"+resource_type_id1) - assert resp.get_data() == b'' + assert resp.status_code == 404 resource_pool_id1 = str(uuid.uuid4()) resp = client.get(apibase+"/resourcePools/"+resource_pool_id1) - assert resp.get_data() == b'' + assert resp.status_code == 404 resource_id1 = str(uuid.uuid4()) resp = client.get(apibase+"/resourcePools/" + resource_pool_id1+"/resources/"+resource_id1) - assert resp.get_data() == b'' + assert resp.status_code == 404 deployment_manager_id1 = str(uuid.uuid4()) resp = client.get(apibase+"/deploymentManagers/"+deployment_manager_id1) - assert resp.get_data() == b'' + assert resp.status_code == 404 + + subscription_id1 = str(uuid.uuid4()) + resp = client.get(apibase+"/subscriptions/"+subscription_id1) + assert resp.status_code == 404 def test_flask_not_allowed(mock_flask_uow): @@ -346,3 +436,26 @@ def test_flask_not_allowed(mock_flask_uow): assert resp.status == '405 METHOD NOT ALLOWED' resp = client.delete(uri) assert resp.status == '405 METHOD NOT ALLOWED' + + # Testing subscriptions not support method + ########################## + uri = apibase + "/subscriptions" + resp = client.post(uri) + assert resp.status == '405 METHOD NOT ALLOWED' + resp = client.put(uri) + assert resp.status == '405 METHOD NOT ALLOWED' + resp = client.patch(uri) + assert resp.status == '405 METHOD NOT ALLOWED' + resp = client.delete(uri) + assert resp.status == '405 METHOD NOT ALLOWED' + + subscription_id1 = str(uuid.uuid4()) + uri = apibase + "/subscriptions/" + subscription_id1 + resp = client.post(uri) + assert resp.status == '405 METHOD NOT ALLOWED' + resp = client.put(uri) + assert resp.status == '405 METHOD NOT ALLOWED' + resp = client.patch(uri) + assert resp.status == '405 METHOD NOT ALLOWED' + resp = client.delete(uri) + assert resp.status == '405 METHOD NOT ALLOWED' -- 2.16.6