.ResourceSqlAlchemyRepository(self.session)\r
self.subscriptions = ocloud_repository\\r
.SubscriptionSqlAlchemyRepository(self.session)\r
+ self.registrations = ocloud_repository\\r
+ .RegistrationSqlAlchemyRepository(self.session)\r
self.deployment_managers = ocloud_repository\\r
.DeploymentManagerSqlAlchemyRepository(self.session)\r
self.nfdeployment_descs = dms_repository\\r
resourcepool_handler, pserver_handler, pserver_cpu_handler, \
pserver_mem_handler, pserver_port_handler, pserver_if_handler,\
pserver_eth_handler
-from o2ims.service.event import notify_handler, ocloud_event, \
+from o2ims.service.command import notify_handler
+from o2ims.service.event import ocloud_event, \
resource_event, resource_pool_event
# if TYPE_CHECKING:
from o2ims.domain import ocloud, subscription_obj
from o2ims.domain.ocloud_repo import OcloudRepository, ResourceTypeRepository,\
ResourcePoolRepository, ResourceRepository, DeploymentManagerRepository
-from o2ims.domain.subscription_repo import SubscriptionRepository
+from o2ims.domain.subscription_repo import SubscriptionRepository, \
+ RegistrationRepository
from o2common.helper import o2logging
logger = o2logging.get_logger(__name__)
def _delete(self, subscription_id):
self.session.query(subscription_obj.Subscription).filter_by(
subscriptionId=subscription_id).delete()
+
+
+class RegistrationSqlAlchemyRepository(RegistrationRepository):
+ def __init__(self, session):
+ super().__init__()
+ self.session = session
+
+ def _add(self, registration: subscription_obj.Registration):
+ self.session.add(registration)
+
+ def _get(self, registration_id) -> subscription_obj.Registration:
+ return self.session.query(subscription_obj.Registration).filter_by(
+ registrationId=registration_id).first()
+
+ def _list(self) -> List[subscription_obj.Registration]:
+ return self.session.query(subscription_obj.Registration)
+
+ def _update(self, registration: subscription_obj.Registration):
+ self.session.add(registration)
+
+ def _delete(self, registration_id):
+ self.session.query(subscription_obj.Registration).filter_by(
+ registrationId=registration_id).delete()
# Date,\r
DateTime,\r
ForeignKey,\r
+ Boolean,\r
# engine,\r
# event,\r
)\r
Column("filter", String(255)),\r
)\r
\r
+registration = Table(\r
+ "registration",\r
+ metadata,\r
+ Column("updatetime", DateTime),\r
+ Column("createtime", DateTime),\r
+\r
+ Column("registrationId", String(255), primary_key=True),\r
+ Column("callback", String(255)),\r
+ Column("notified", Boolean),\r
+)\r
+\r
\r
def start_o2ims_mappers(engine=None):\r
logger.info("Starting O2 IMS mappers")\r
}\r
)\r
mapper(subModel.Subscription, subscription)\r
+ mapper(subModel.Registration, registration)\r
\r
if engine is not None:\r
metadata.create_all(engine)\r
self.filter = filter
+class Registration(AgRoot, Serializer):
+ def __init__(self, id: str, url: str) -> None:
+ super().__init__()
+ self.registrationId = id
+ self.callback = url
+ self.notified = False
+
+
class NotificationEventEnum(str, Enum):
CREATE = 'CREATE'
MODIFY = 'MODIFY'
@abc.abstractmethod
def _delete(self, subscription_id):
raise NotImplementedError
+
+
+class RegistrationRepository(abc.ABC):
+ def __init__(self):
+ self.seen = set() # type: Set[subobj.Subscription]
+
+ def add(self, registration: subobj.Registration):
+ self._add(registration)
+ self.seen.add(registration)
+
+ def get(self, registration_id) -> subobj.Registration:
+ registration = self._get(registration_id)
+ if registration:
+ self.seen.add(registration)
+ return registration
+
+ def list(self) -> List[subobj.Registration]:
+ return self._list()
+
+ def update(self, registration: subobj.Registration):
+ self._update(registration)
+
+ def delete(self, registration_id):
+ self._delete(registration_id)
+
+ @abc.abstractmethod
+ def _add(self, registration: subobj.Registration):
+ raise NotImplementedError
+
+ @abc.abstractmethod
+ def _get(self, registration_id) -> subobj.Registration:
+ raise NotImplementedError
+
+ @abc.abstractmethod
+ def _update(self, registration: subobj.Registration):
+ raise NotImplementedError
+
+ @abc.abstractmethod
+ def _delete(self, registration_id):
+ raise NotImplementedError
--- /dev/null
+# 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
description='Subscription ID'),
}
)
+
+
+class RegistrationDTO:
+
+ registration_get = api_ims_inventory_v1.model(
+ "RegistrationGetDto",
+ {
+ 'registrationId': fields.String(required=True,
+ description='Registration ID'),
+ 'callback': fields.String,
+ 'notified': fields.Boolean,
+ }
+ )
+
+ registration = api_ims_inventory_v1.model(
+ "RegistrationCreateDto",
+ {
+ 'callback': fields.String(
+ required=True, description='Registration SMO callback address')
+ }
+ )
+
+ registration_post_resp = api_ims_inventory_v1.model(
+ "RegistrationCreatedRespDto",
+ {
+ 'registrationId': fields.String(required=True,
+ description='registration ID'),
+ }
+ )
from o2ims.views import ocloud_view, api_ims_inventory_v1
from o2common.config import config
from o2ims.views.ocloud_dto import OcloudDTO, ResourceTypeDTO,\
- ResourcePoolDTO, ResourceDTO, DeploymentManagerDTO, SubscriptionDTO
+ ResourcePoolDTO, ResourceDTO, DeploymentManagerDTO, SubscriptionDTO,\
+ RegistrationDTO
apibase = config.get_o2ims_api_base()
return result, 204
+# ---------- Registration ---------- #
+@api_ims_inventory_v1.route("/registrations")
+class RegistrationListRouter(Resource):
+
+ model = RegistrationDTO.registration_get
+ expect = RegistrationDTO.registration
+ post_resp = RegistrationDTO.registration_post_resp
+
+ @api_ims_inventory_v1.doc('List registrations')
+ @api_ims_inventory_v1.marshal_list_with(model)
+ def get(self):
+ return ocloud_view.registrations(bus.uow)
+
+ @api_ims_inventory_v1.doc('Create a registration')
+ @api_ims_inventory_v1.expect(expect)
+ @api_ims_inventory_v1.marshal_with(post_resp, code=201)
+ def post(self):
+ data = api_ims_inventory_v1.payload
+ result = ocloud_view.registration_create(data, bus.uow)
+ return result, 201
+
+
+@api_ims_inventory_v1.route("/registrations/<registrationID>")
+@api_ims_inventory_v1.param('registrationID', 'ID of the registration')
+@api_ims_inventory_v1.response(404, 'Registration not found')
+class RegistrationGetDelRouter(Resource):
+
+ model = RegistrationDTO.registration_get
+
+ @api_ims_inventory_v1.doc('Get registration by ID')
+ @api_ims_inventory_v1.marshal_with(model)
+ def get(self, registrationID):
+ result = ocloud_view.registration_one(
+ registrationID, bus.uow)
+ if result is not None:
+ return result
+ api_ims_inventory_v1.abort(404, "Registration {} doesn't exist".format(
+ registrationID))
+
+ @api_ims_inventory_v1.doc('Delete registration by ID')
+ @api_ims_inventory_v1.response(204, 'Registration deleted')
+ def delete(self, registrationID):
+ result = ocloud_view.registration_delete(registrationID, bus.uow)
+ return result, 204
+
+
def configure_namespace(app, bus_new):
# Set global bus for resource
import uuid\r
\r
from o2common.service import unit_of_work\r
-from o2ims.views.ocloud_dto import SubscriptionDTO\r
-from o2ims.domain.subscription_obj import Subscription\r
+from o2ims.views.ocloud_dto import RegistrationDTO, SubscriptionDTO\r
+from o2ims.domain.subscription_obj import Registration, Subscription\r
\r
\r
def oclouds(uow: unit_of_work.AbstractUnitOfWork):\r
uow.subscriptions.delete(subscriptionId)\r
uow.commit()\r
return True\r
+\r
+\r
+def registrations(uow: unit_of_work.AbstractUnitOfWork):\r
+ with uow:\r
+ li = uow.registrations.list()\r
+ return [r.serialize() for r in li]\r
+\r
+\r
+def registration_one(registrationId: str,\r
+ uow: unit_of_work.AbstractUnitOfWork):\r
+ with uow:\r
+ first = uow.registrations.get(registrationId)\r
+ return first.serialize() if first is not None else None\r
+\r
+\r
+def registration_create(registrationDto: RegistrationDTO.registration,\r
+ uow: unit_of_work.AbstractUnitOfWork):\r
+\r
+ reg_uuid = str(uuid.uuid4())\r
+ registration = Registration(\r
+ reg_uuid, registrationDto['callback'])\r
+ with uow:\r
+ uow.registrations.add(registration)\r
+ uow.commit()\r
+ return {"registrationId": reg_uuid}\r
+\r
+\r
+def registration_delete(registrationId: str,\r
+ uow: unit_of_work.AbstractUnitOfWork):\r
+ with uow:\r
+ uow.registrations.delete(registrationId)\r
+ uow.commit()\r
+ return True\r
subscription1.subscriptionId == subscription_id1
+def test_new_registration():
+ registration_id1 = str(uuid.uuid4())
+ registration1 = subscription_obj.Registration(
+ registration_id1, "https://callback/uri/write/here")
+ assert registration_id1 is not None and\
+ registration1.registrationId == registration_id1
+
+
def test_view_olcouds(mock_uow):
session, uow = mock_uow
"subscriptionId")) == subscription_id1
+def test_view_registrations(mock_uow):
+ session, uow = mock_uow
+
+ registration_id1 = str(uuid.uuid4())
+ reg1 = MagicMock()
+ reg1.serialize.return_value = {
+ "registrationId": registration_id1,
+ }
+ session.return_value.query.return_value = [reg1]
+
+ registration_list = ocloud_view.registrations(uow)
+ assert str(registration_list[0].get(
+ "registrationId")) == registration_id1
+
+
+def test_view_registration_one(mock_uow):
+ session, uow = mock_uow
+
+ registration_id1 = str(uuid.uuid4())
+ session.return_value.query.return_value.filter_by.return_value.first.\
+ return_value.serialize.return_value = None
+
+ # Query return None
+ registration_res = ocloud_view.registration_one(
+ registration_id1, uow)
+ assert registration_res is None
+
+ session.return_value.query.return_value.filter_by.return_value.first.\
+ return_value.serialize.return_value = {
+ "registrationId": registration_id1,
+ }
+
+ registration_res = ocloud_view.registration_one(
+ registration_id1, uow)
+ assert str(registration_res.get(
+ "registrationId")) == registration_id1
+
+
def test_flask_get_list(mock_flask_uow):
session, app = mock_flask_uow
session.query.return_value = []
resp = client.get(apibase+"/subscriptions")
assert resp.get_data() == b'[]\n'
+ resp = client.get(apibase+"/registrations")
+ assert resp.get_data() == b'[]\n'
+
def test_flask_get_one(mock_flask_uow):
session, app = mock_flask_uow
resp = client.get(apibase+"/subscriptions/"+subscription_id1)
assert resp.status_code == 404
+ registration_id1 = str(uuid.uuid4())
+ resp = client.get(apibase+"/registrations/"+registration_id1)
+ assert resp.status_code == 404
+
def test_flask_post(mock_flask_uow):
session, app = mock_flask_uow
assert resp.status_code == 201
assert 'subscriptionId' in resp.get_json()
+ reg_callback = 'http://registration/callback/url'
+ resp = client.post(apibase+'/registrations', json={
+ 'callback': reg_callback,
+ })
+ assert resp.status_code == 201
+ assert 'registrationId' in resp.get_json()
+
def test_flask_delete(mock_flask_uow):
session, app = mock_flask_uow
resp = client.delete(apibase+"/subscriptions/"+subscription_id1)
assert resp.status_code == 204
+ registration_id1 = str(uuid.uuid4())
+ resp = client.delete(apibase+"/registrations/"+registration_id1)
+ assert resp.status_code == 204
+
def test_flask_not_allowed(mock_flask_uow):
_, app = mock_flask_uow
assert resp.status == '405 METHOD NOT ALLOWED'
resp = client.patch(uri)
assert resp.status == '405 METHOD NOT ALLOWED'
+
+ # Testing registrations not support method
+ ##########################
+ uri = apibase + "/registrations"
+ 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 + "/registrations/" + 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'