COPY o2ims/ /src/o2ims/\r
COPY o2dms/ /src/o2dms/\r
COPY o2common/ /src/o2common/\r
+\r
+RUN mkdir -p /src/o2app/\r
+COPY o2app/ /src/o2app/\r
COPY setup.py /src/\r
\r
RUN pip install -e /src\r
COPY o2ims/ /src/o2ims/\r
COPY o2dms/ /src/o2dms/\r
COPY o2common/ /src/o2common/\r
+\r
+RUN mkdir -p /src/o2app/\r
+COPY o2app/ /src/o2app/\r
COPY setup.py /src/\r
\r
COPY configs/ /etc/o2/\r
### test api endpoint\r
\r
```sh\r
+curl -k http(s)://<Node IP>:30205\r
curl -k http(s)://<Node IP>:30205/o2ims_infrastructureInventory/v1\r
```\r
\r
\r
\d\r
\r
- select * from stxcache;\r
+ select * from ocloud;\r
\r
\q\r
\r
git clone "https://gerrit.o-ran-sc.org/r/pti/o2"
pip install -e /root/o2
-python /root/o2/o2ims/entrypoints/redis_eventconsumer.py
+python /root/o2/o2app/entrypoints/redis_eventconsumer.py
sleep infinity
git clone "https://gerrit.o-ran-sc.org/r/pti/o2"
pip install -e /root/o2
-python /root/o2/o2ims/entrypoints/resource_watcher.py
+python /root/o2/o2app/entrypoints/resource_watcher.py
sleep infinity
- name: DB_PASSWORD\r
value: o2ims123\r
- name: FLASK_APP\r
- value: /root/o2/o2ims/entrypoints/flask_application.py\r
+ value: /root/o2/o2app/entrypoints/flask_application.py\r
- name: FLASK_DEBUG\r
value: {{ .Values.o2ims.logginglevel }}\r
- name: LOGGING_CONFIG_LEVEL\r
- ./o2ims:/o2ims
- ./o2dms:/o2dms
- ./o2common:/o2common
+ - ./o2app:/o2app
- ./tests:/tests
entrypoint:
- /bin/sh
- - /tests/o2ims-redis-entry.sh
+ - /tests/o2app-redis-entry.sh
api:
image: o2imsdms
- API_HOST=api
- REDIS_HOST=redis
- PYTHONDONTWRITEBYTECODE=1
- - FLASK_APP=/o2ims/entrypoints/flask_application.py
+ - FLASK_APP=/o2app/entrypoints/flask_application.py
- FLASK_DEBUG=1
- PYTHONUNBUFFERED=1
- OS_AUTH_URL=${OS_AUTH_URL}
- ./o2ims:/o2ims
- ./o2dms:/o2dms
- ./o2common:/o2common
+ - ./o2app:/o2app
- ./tests:/tests
entrypoint:
- - flask
- - run
- - --host=0.0.0.0
- - --port=80
+ - /bin/sh
+ - /tests/o2app-api-entry.sh
ports:
- "5005:80"
- ./o2ims:/o2ims
- ./o2dms:/o2dms
- ./o2common:/o2common
+ - ./o2app:/o2app
- ./tests:/tests
entrypoint:
- /bin/sh
- - /tests/o2ims-watcher-entry.sh
+ - /tests/o2app-watcher-entry.sh
postgres:
image: postgres:9.6
--- /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
--- /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
--- /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
+\r
+# pylint: disable=attribute-defined-outside-init\r
+from __future__ import annotations\r
+from sqlalchemy import create_engine\r
+from sqlalchemy.orm import sessionmaker\r
+from sqlalchemy.orm.session import Session\r
+\r
+from o2common.config import config\r
+from o2common.service.unit_of_work import AbstractUnitOfWork\r
+\r
+from o2ims.adapter import ocloud_repository\r
+from o2dms.adapter import dms_repository\r
+\r
+DEFAULT_SESSION_FACTORY = sessionmaker(\r
+ bind=create_engine(\r
+ config.get_postgres_uri(),\r
+ isolation_level="REPEATABLE READ",\r
+ )\r
+)\r
+\r
+\r
+class SqlAlchemyUnitOfWork(AbstractUnitOfWork):\r
+ def __init__(self, session_factory=DEFAULT_SESSION_FACTORY):\r
+ self.session_factory = session_factory\r
+\r
+ def __enter__(self):\r
+ self.session = self.session_factory() # type: Session\r
+ self.oclouds = ocloud_repository\\r
+ .OcloudSqlAlchemyRepository(self.session)\r
+ self.resource_types = ocloud_repository\\r
+ .ResouceTypeSqlAlchemyRepository(self.session)\r
+ self.resource_pools = ocloud_repository\\r
+ .ResourcePoolSqlAlchemyRepository(self.session)\r
+ self.resources = ocloud_repository\\r
+ .ResourceSqlAlchemyRepository(self.session)\r
+ self.deployment_managers = ocloud_repository\\r
+ .DeploymentManagerSqlAlchemyRepository(self.session)\r
+ self.nfdeployment_descs = dms_repository\\r
+ .NfDeploymentDescSqlAlchemyRepository(self.session)\r
+ return super().__enter__()\r
+\r
+ def __exit__(self, *args):\r
+ super().__exit__(*args)\r
+ self.session.close()\r
+\r
+ def _commit(self):\r
+ self.session.commit()\r
+\r
+ def rollback(self):\r
+ self.session.rollback()\r
+\r
+ def _collect_new_events(self):\r
+ for entry in self.oclouds.seen:\r
+ while entry.events:\r
+ yield entry.events.pop(0)\r
+ for entry in self.resource_pools.seen:\r
+ while entry.events:\r
+ yield entry.events.pop(0)\r
+ for entry in self.resources.seen:\r
+ while entry.events:\r
+ yield entry.events.pop(0)\r
+ for entry in self.resource_types.seen:\r
+ while entry.events:\r
+ yield entry.events.pop(0)\r
+ for entry in self.deployment_managers.seen:\r
+ while entry.events:\r
+ yield entry.events.pop(0)\r
+ for entry in self.nfdeployment_descs.seen:\r
+ while entry.events:\r
+ yield entry.events.pop(0)\r
--- /dev/null
+# 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 retry import retry
+import inspect
+from typing import Callable
+
+from o2common.adapter.notifications import AbstractNotifications,\
+ SmoO2Notifications
+from o2common.adapter import redis_eventpublisher
+from o2common.service import unit_of_work
+
+from o2app.service import handlers, messagebus
+from o2app.adapter.unit_of_work import SqlAlchemyUnitOfWork
+
+from o2ims.adapter import orm as o2ims_orm
+from o2dms.adapter import orm as o2dms_orm
+
+from o2common.helper import o2logging
+logger = o2logging.get_logger(__name__)
+
+
+@retry(tries=100, delay=2, backoff=1)
+def wait_for_db_ready(engine):
+ # wait for db up
+ logger.info("Wait for DB ready ...")
+ engine.connect()
+ logger.info("DB is ready")
+
+
+def bootstrap(
+ start_orm: bool = True,
+ uow: unit_of_work.AbstractUnitOfWork = SqlAlchemyUnitOfWork(),
+ notifications: AbstractNotifications = None,
+ publish: Callable = redis_eventpublisher.publish,
+) -> messagebus.MessageBus:
+
+ if notifications is None:
+ notifications = SmoO2Notifications()
+
+ if start_orm:
+ with uow:
+ # get default engine if uow is by default
+ engine = uow.session.get_bind()
+ wait_for_db_ready(engine)
+ o2ims_orm.start_o2ims_mappers(engine)
+ o2dms_orm.start_o2dms_mappers(engine)
+
+ dependencies = {"uow": uow, "notifications": notifications,
+ "publish": publish}
+ injected_event_handlers = {
+ event_type: [
+ inject_dependencies(handler, dependencies)
+ for handler in event_handlers
+ ]
+ for event_type, event_handlers in handlers.EVENT_HANDLERS.items()
+ }
+ injected_command_handlers = {
+ command_type: inject_dependencies(handler, dependencies)
+ for command_type, handler in handlers.COMMAND_HANDLERS.items()
+ }
+
+ return messagebus.MessageBus(
+ uow=uow,
+ event_handlers=injected_event_handlers,
+ command_handlers=injected_command_handlers,
+ )
+
+
+def inject_dependencies(handler, dependencies):
+ params = inspect.signature(handler).parameters
+ deps = {
+ name: dependency
+ for name, dependency in dependencies.items()
+ if name in params
+ }
+ return lambda message: handler(message, **deps)
--- /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
--- /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
+\r
+from flask import Flask\r
+from flask_restx import Api\r
+\r
+from o2app import bootstrap\r
+# from o2ims import config\r
+# from o2ims.views.ocloud_route import configure_routes\r
+from o2ims.views import ocloud_route as ims_route\r
+from o2dms.views import dms_route\r
+\r
+\r
+# apibase = config.get_o2ims_api_base()\r
+app = Flask(__name__)\r
+api = Api(app, version='1.0.0',\r
+ title='O-Cloud O2 Services',\r
+ description='Swagger OpenAPI document for \\r
+ O-Cloud O2 Services',\r
+ )\r
+bus = bootstrap.bootstrap()\r
+\r
+ims_route.configure_namespace(api, bus)\r
+dms_route.configure_namespace(api, bus)\r
--- /dev/null
+# 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.
+
+# import json
+import redis
+
+from o2app import bootstrap
+from o2common.config import config
+# from o2common.domain import commands
+
+from o2common.helper import o2logging
+logger = o2logging.get_logger(__name__)
+
+r = redis.Redis(**config.get_redis_host_and_port())
+
+
+def main():
+ logger.info("Redis pubsub starting")
+ bus = bootstrap.bootstrap()
+ pubsub = r.pubsub(ignore_subscribe_messages=True)
+ pubsub.subscribe("dms_changed")
+
+ for m in pubsub.listen():
+ handle_dms_changed(m, bus)
+
+
+def handle_dms_changed(m, bus):
+ logger.info("handling %s", m)
+ # data = json.loads(m["data"])
+ # cmd = commands.UpdateDms(ref=data["dmsid"])
+ # bus.handle(cmd)
+
+
+if __name__ == "__main__":
+ main()
--- /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
+\r
+import cotyledon\r
+\r
+from o2app import bootstrap\r
+from o2common.service.watcher.base import WatcherTree\r
+\r
+from o2ims.service.watcher.worker import PollWorker\r
+from o2ims.service.watcher.ocloud_watcher import OcloudWatcher\r
+from o2ims.service.watcher.ocloud_watcher import DmsWatcher\r
+from o2ims.service.watcher.resourcepool_watcher import ResourcePoolWatcher\r
+from o2ims.adapter.clients.ocloud_sa_client import StxSaDmsClient\r
+from o2ims.adapter.clients.ocloud_sa_client import StxSaOcloudClient\r
+from o2ims.adapter.clients.ocloud_sa_client import StxSaResourcePoolClient\r
+\r
+from o2ims.service.watcher.pserver_watcher import PServerWatcher\r
+from o2ims.adapter.clients.ocloud_sa_client import StxPserverClient\r
+\r
+from o2ims.service.watcher.pserver_cpu_watcher import PServerCpuWatcher\r
+from o2ims.adapter.clients.ocloud_sa_client import StxCpuClient\r
+\r
+from o2common.helper import o2logging\r
+logger = o2logging.get_logger(__name__)\r
+\r
+# r = redis.Redis(**config.get_redis_host_and_port())\r
+\r
+\r
+class WatcherService(cotyledon.Service):\r
+ def __init__(self, worker_id, args=None) -> None:\r
+ super().__init__(worker_id)\r
+ self.args = args\r
+ self.bus = bootstrap.bootstrap()\r
+ self.worker = PollWorker()\r
+\r
+ def run(self):\r
+ try:\r
+ root = WatcherTree(OcloudWatcher(\r
+ StxSaOcloudClient(), self.bus))\r
+ root.addchild(\r
+ DmsWatcher(StxSaDmsClient(), self.bus))\r
+\r
+ child_respool = root.addchild(\r
+ ResourcePoolWatcher(StxSaResourcePoolClient(),\r
+ self.bus))\r
+ child_pserver = child_respool.addchild(\r
+ PServerWatcher(StxPserverClient(), self.bus))\r
+ child_pserver.addchild(\r
+ PServerCpuWatcher(StxCpuClient(), self.bus))\r
+\r
+ self.worker.add_watcher(root)\r
+\r
+ self.worker.start()\r
+ except Exception as ex:\r
+ logger.warning("WorkerService Exception:" + str(ex))\r
+ finally:\r
+ self.worker.stop()\r
+\r
+\r
+def start_watchers(sm: cotyledon.ServiceManager = None):\r
+ watchersm = sm if sm else cotyledon.ServiceManager()\r
+ watchersm.add(WatcherService, workers=1, args=())\r
+ watchersm.run()\r
+\r
+\r
+def main():\r
+ logger.info("Resource watcher starting")\r
+ start_watchers()\r
+\r
+\r
+if __name__ == "__main__":\r
+ main()\r
--- /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
--- /dev/null
+# 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 dataclasses import asdict
+from typing import List, Dict, Callable, Type
+from o2ims.service.auditor import dms_handler
+# TYPE_CHECKING
+from o2ims.domain import commands, events
+from o2ims.service.auditor import ocloud_handler
+
+# if TYPE_CHECKING:
+# from . import unit_of_work
+
+
+class InvalidResourceType(Exception):
+ pass
+
+
+EVENT_HANDLERS = {
+} # type: Dict[Type[events.Event], List[Callable]]
+
+
+COMMAND_HANDLERS = {
+ commands.UpdateOCloud: ocloud_handler.update_ocloud,
+ commands.UpdateDms: dms_handler.update_dms
+} # type: Dict[Type[commands.Command], Callable]
--- /dev/null
+# 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=broad-except, attribute-defined-outside-init
+from __future__ import annotations
+from typing import Callable, Dict, List, Union, Type, TYPE_CHECKING
+from o2ims.domain import commands, events
+
+if TYPE_CHECKING:
+ from . import unit_of_work
+
+from o2common.helper import o2logging
+logger = o2logging.get_logger(__name__)
+
+Message = Union[commands.Command, events.Event]
+
+
+class MessageBus:
+ def __init__(
+ self,
+ uow: unit_of_work.AbstractUnitOfWork,
+ event_handlers: Dict[Type[events.Event], List[Callable]],
+ command_handlers: Dict[Type[commands.Command], Callable],
+ ):
+ self.uow = uow
+ self.event_handlers = event_handlers
+ self.command_handlers = command_handlers
+
+ def handle(self, message: Message):
+ self.queue = [message]
+ while self.queue:
+ message = self.queue.pop(0)
+ if not message:
+ continue
+ elif isinstance(message, events.Event):
+ self.handle_event(message)
+ elif isinstance(message, commands.Command):
+ self.handle_command(message)
+ else:
+ raise Exception(f"{message} was not an Event or Command")
+
+ def handle_event(self, event: events.Event):
+ for handler in self.event_handlers[type(event)]:
+ try:
+ logger.debug("handling event %s with handler %s",
+ event, handler)
+ handler(event)
+ self.queue.extend(self.uow.collect_new_events())
+ except Exception:
+ logger.exception("Exception handling event %s", event)
+ continue
+
+ def handle_command(self, command: commands.Command):
+ logger.debug("handling command %s", command)
+ try:
+ handler = self.command_handlers[type(command)]
+ handler(command)
+ self.queue.extend(self.uow.collect_new_events())
+ except Exception as ex:
+ logger.exception("Exception handling command %s", command)
+ raise ex
--- /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
--- /dev/null
+# pylint: disable=too-few-public-methods
+import abc
+from o2ims import config
+
+
+SMO_O2_ENDPOINT = config.get_smo_o2endpoint()
+
+
+class AbstractNotifications(abc.ABC):
+ @abc.abstractmethod
+ def send(self, message):
+ raise NotImplementedError
+
+
+class SmoO2Notifications(AbstractNotifications):
+ def __init__(self, smoO2Endpoint=SMO_O2_ENDPOINT):
+ self.smoO2Endpoint = smoO2Endpoint
+
+ def send(self, message):
+ pass
--- /dev/null
+# 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.
+
+import json
+from dataclasses import asdict
+import redis
+
+from o2ims import config
+from o2ims.domain import events
+
+from o2common.helper import o2logging
+logger = o2logging.get_logger(__name__)
+
+
+r = redis.Redis(**config.get_redis_host_and_port())
+
+
+def publish(channel, event: events.Event):
+ logger.info("publishing: channel=%s, event=%s", channel, event)
+ r.publish(channel, json.dumps(asdict(event)))
--- /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
--- /dev/null
+# 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.
+
+import os
+import sys
+
+from o2common.helper import o2logging
+logger = o2logging.get_logger(__name__)
+
+
+def get_postgres_uri():
+ host = os.environ.get("DB_HOST", "localhost")
+ port = 54321 if host == "localhost" else 5432
+ password = os.environ.get("DB_PASSWORD", "o2ims123")
+ user, db_name = "o2ims", "o2ims"
+ return f"postgresql://{user}:{password}@{host}:{port}/{db_name}"
+
+
+def get_api_url():
+ host = os.environ.get("API_HOST", "localhost")
+ port = 5005 if host == "localhost" else 80
+ return f"http://{host}:{port}"
+
+
+def get_root_api_base():
+ return "/"
+
+
+def get_o2ims_api_base():
+ return get_root_api_base() + 'o2ims_infrastructureInventory/v1'
+
+
+def get_o2dms_api_base():
+ return get_root_api_base() + "o2dms/v1"
+
+
+def get_redis_host_and_port():
+ host = os.environ.get("REDIS_HOST", "localhost")
+ port = 63791 if host == "localhost" else 6379
+ return dict(host=host, port=port)
+
+
+def get_smo_o2endpoint():
+ smo_o2endpoint = os.environ.get(
+ "SMO_O2_ENDPOINT", "http://localhost/smo_sim")
+ return smo_o2endpoint
+
+
+def get_stx_access_info():
+ # authurl = os.environ.get("STX_AUTH_URL", "http://192.168.204.1:5000/v3")
+ # username = os.environ.get("STX_USERNAME", "admin")
+ # pswd = os.environ.get("STX_PASSWORD", "passwd1")
+ # stx_access_info = (authurl, username, pswd)
+ try:
+ client_args = dict(
+ auth_url=os.environ.get('OS_AUTH_URL',
+ "http://192.168.204.1:5000/v3"),
+ username=os.environ.get('OS_USERNAME', "admin"),
+ api_key=os.environ.get('OS_PASSWORD', "fakepasswd1"),
+ project_name=os.environ.get('OS_PROJECT_NAME', "admin"),
+ )
+ # dc_client_args = dict(
+ # auth_url=os.environ['OS_AUTH_URL'],
+ # username=os.environ['OS_USERNAME'],
+ # api_key=os.environ['OS_PASSWORD'],
+ # project_name=os.environ['OS_PROJECT_NAME'],
+ # user_domain_name=os.environ['OS_USER_DOMAIN_NAME'],
+ # project_domain_name=os.environ['OS_PROJECT_NAME'],
+ # project_domain_id=os.environ['OS_PROJECT_DOMAIN_ID']
+ # )
+ except KeyError:
+ logger.error('Please source your RC file before execution, '
+ 'e.g.: `source ~/downloads/admin-rc.sh`')
+ sys.exit(1)
+
+ os_client_args = {}
+ for key, val in client_args.items():
+ os_client_args['os_{key}'.format(key=key)] = val
+ os_client_args['os_password'] = os_client_args.pop('os_api_key')
+ os_client_args['os_region_name'] = 'RegionOne'
+ os_client_args['api_version'] = 1
+ return os_client_args
--- /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
--- /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
+\r
+from datetime import datetime\r
+from typing import List\r
+from .events import Event\r
+\r
+\r
+class AgRoot:\r
+ def __init__(self) -> None:\r
+ self.hash = ""\r
+ # self.id = ""\r
+ self.updatetime = datetime.now()\r
+ self.createtime = datetime.now()\r
+ self.events = [] # type: List[Event]\r
--- /dev/null
+# 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 o2ims.domain.stx_object import StxGenericModel
+
+
+class Command:
+ pass
+
+
+@dataclass
+class UpdateStxObject(Command):
+ data: StxGenericModel
+
+
+@dataclass
+class UpdateOCloud(UpdateStxObject):
+ pass
+
+
+@dataclass
+class UpdateDms(UpdateStxObject):
+ parentid: str
+
+
+@dataclass
+class UpdateResourcePool(UpdateStxObject):
+ parentid: str
+
+
+@dataclass
+class UpdateResource(UpdateStxObject):
+ parentid: str
+
+
+@dataclass
+class UpdatePserverCpu(UpdateResource):
+ pass
+
+
+@dataclass
+class UpdatePserver(UpdateResource):
+ pass
--- /dev/null
+# 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
+
+
+class Event:
+ pass
+
+
+@dataclass
+class OcloudUpdated(Event):
+ oCloudId: str
--- /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
--- /dev/null
+# 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=attribute-defined-outside-init
+from __future__ import annotations
+import abc
+
+from o2ims.domain.ocloud_repo import OcloudRepository,\
+ ResourcePoolRepository, ResourceRepository, ResourceTypeRepository,\
+ DeploymentManagerRepository
+from o2ims.domain.stx_repo import StxObjectRepository
+
+
+class AbstractUnitOfWork(abc.ABC):
+ oclouds: OcloudRepository
+ resource_types: ResourceTypeRepository
+ resource_pools: ResourcePoolRepository
+ resources: ResourceRepository
+ deployment_managers: DeploymentManagerRepository
+ stxobjects: StxObjectRepository
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, *args):
+ self.rollback()
+
+ def commit(self):
+ self._commit()
+
+ def collect_new_events(self):
+ return self._collect_new_events()
+
+ def _collect_new_events(self):
+ raise NotImplementedError
+
+ @abc.abstractmethod
+ def _commit(self):
+ raise NotImplementedError
+
+ @abc.abstractmethod
+ def rollback(self):
+ 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
--- /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
+\r
+# from logging import exception\r
+# from cgtsclient import exc\r
+from o2ims.service.client.base_client import BaseClient\r
+# from o2ims.domain.stx_object import StxGenericModel\r
+# from o2ims.service.unit_of_work import AbstractUnitOfWork\r
+from o2ims.domain import commands\r
+from o2ims.service.messagebus import MessageBus\r
+from o2common.helper import o2logging\r
+logger = o2logging.get_logger(__name__)\r
+\r
+\r
+class BaseWatcher(object):\r
+ def __init__(self, client: BaseClient,\r
+ bus: MessageBus) -> None:\r
+ super().__init__()\r
+ self._client = client\r
+ self._bus = bus\r
+ # self._uow = bus.uow\r
+\r
+ def targetname(self) -> str:\r
+ return self._targetname()\r
+\r
+ def probe(self, parent: commands.UpdateStxObject = None):\r
+ try:\r
+ cmds = self._probe(parent.data if parent else None)\r
+ for cmd in cmds:\r
+ self._bus.handle(cmd)\r
+\r
+ # return self._probe(parent)\r
+ return cmds\r
+ except Exception as ex:\r
+ logger.warning("Failed to probe resource due to: " + str(ex))\r
+ return []\r
+\r
+ def _probe(self, parent: object = None) -> commands.UpdateStxObject:\r
+ raise NotImplementedError\r
+\r
+ def _targetname(self):\r
+ raise NotImplementedError\r
+\r
+ # def _compare_and_update(self, newmodel: StxGenericModel) -> bool:\r
+ # with self._uow:\r
+ # # localmodel = self._uow.stxobjects.get(ocloudmodel.id)\r
+ # localmodel = self._uow.stxobjects.get(str(newmodel.id))\r
+ # if not localmodel:\r
+ # logger.info("add entry:" + newmodel.name)\r
+ # self._uow.stxobjects.add(newmodel)\r
+ # elif localmodel.is_outdated(newmodel):\r
+ # logger.info("update entry:" + newmodel.name)\r
+ # localmodel.update_by(newmodel)\r
+ # self._uow.stxobjects.update(localmodel)\r
+ # self._uow.commit()\r
+\r
+\r
+# node to organize watchers in tree hierachy\r
+class WatcherTree(object):\r
+ def __init__(self, watcher: BaseWatcher) -> None:\r
+ super().__init__()\r
+ self.watcher = watcher\r
+ self.children = {}\r
+\r
+ def addchild(self, watcher: BaseWatcher) -> object:\r
+ child = WatcherTree(watcher)\r
+ self.children[watcher.targetname()] = child\r
+ return child\r
+\r
+ def removechild(self, targetname: str) -> object:\r
+ return self.children.pop(targetname)\r
+\r
+ # probe all resources by parent, depth = 0 for indefinite recursive\r
+ def probe(self, parentresource=None, depth: int = 0):\r
+ logger.debug("probe resources with watcher: "\r
+ + self.watcher.targetname())\r
+ childdepth = depth - 1 if depth > 0 else 0\r
+ resources = self.watcher.probe(parentresource)\r
+ logger.debug("probe returns " + str(len(resources)) + " resources")\r
+\r
+ if depth == 1:\r
+ # stop recursive\r
+ return\r
+\r
+ for res in resources:\r
+ for targetname in self.children.keys():\r
+ self.children[targetname].probe(res, childdepth)\r
--- /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
--- /dev/null
+# 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 typing import List
+from o2dms.domain import dms, dms_repo
+
+
+class NfDeploymentDescSqlAlchemyRepository(dms_repo
+ .NfDeploymentDescRepository):
+
+ def __init__(self, session):
+ super().__init__()
+ self.session = session
+
+ def _add(self, nfdeployment_desc: dms.NfDeploymentDesc):
+ self.session.add(nfdeployment_desc)
+
+ def _get(self, nfdeployment_desc_id) -> dms.NfDeploymentDesc:
+ return self.session.query(dms.NfDeploymentDesc).filter_by(
+ nfDeploymentDescId=nfdeployment_desc_id).first()
+
+ def _list(self) -> List[dms.NfDeploymentDesc]:
+ return self.session.query()
+
+ def _update(self, nfdeployment_desc: dms.NfDeploymentDesc):
+ self.session.add(nfdeployment_desc)
--- /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
+\r
+from sqlalchemy import (\r
+ Table,\r
+ MetaData,\r
+ Column,\r
+ Integer,\r
+ String,\r
+ # Date,\r
+ DateTime,\r
+ # ForeignKey,\r
+ # engine,\r
+ # event,\r
+)\r
+\r
+from sqlalchemy.orm import mapper\r
+from o2dms.domain import dms as dmsModel\r
+\r
+from o2common.helper import o2logging\r
+logger = o2logging.get_logger(__name__)\r
+\r
+metadata = MetaData()\r
+\r
+nfDeploymentDesc = Table(\r
+ "nfDeploymentDesc",\r
+ metadata,\r
+ Column("updatetime", DateTime),\r
+ Column("createtime", DateTime),\r
+ Column("hash", String(255)),\r
+ Column("version_number", Integer),\r
+\r
+ Column("id", String(255), primary_key=True),\r
+ Column("deploymentManagerId", String(255)),\r
+ Column("name", String(255)),\r
+ Column("description", String(255)),\r
+ Column("supportedLocations", String(255)),\r
+ Column("capabilities", String(255)),\r
+ Column("capacity", String(255)),\r
+ # Column("extensions", String(1024))\r
+)\r
+\r
+\r
+def start_o2dms_mappers(engine=None):\r
+ logger.info("Starting O2 DMS mappers")\r
+\r
+ mapper(dmsModel.NfDeploymentDesc, nfDeploymentDesc)\r
+\r
+ if engine is not None:\r
+ metadata.create_all(engine)\r
--- /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
+\r
+from __future__ import annotations\r
+\r
+from o2ims.domain.base import AgRoot\r
+\r
+\r
+class NfDeploymentDesc(AgRoot):\r
+ def __init__(self, id: str, name: str, dmsId: str, description: str = '',\r
+ inputParams: str = '', outputParams: str = '',) -> None:\r
+ super().__init__()\r
+ self.id = id\r
+ self.version_number = 0\r
+ self.dmsId = dmsId\r
+ self.name = name\r
+ self.description = description\r
+ self.inputParams = inputParams\r
+ self.outputParams = outputParams\r
+ self.extensions = []\r
--- /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
+\r
+import abc\r
+from typing import List, Set\r
+from o2dms.domain import dms\r
+\r
+\r
+class NfDeploymentDescRepository(abc.ABC):\r
+ def __init__(self):\r
+ self.seen = set() # type: Set[dms.NfDeploymentDesc]\r
+\r
+ def add(self, nfdeployment_descriptor: dms.NfDeploymentDesc):\r
+ self._add(nfdeployment_descriptor)\r
+ self.seen.add(nfdeployment_descriptor)\r
+\r
+ def get(self, nfdeployment_descriptor_id) -> dms.NfDeploymentDesc:\r
+ nfdeployment_descriptor = self._get(nfdeployment_descriptor_id)\r
+ if nfdeployment_descriptor:\r
+ self.seen.add(nfdeployment_descriptor)\r
+ return nfdeployment_descriptor\r
+\r
+ def list(self) -> List[dms.NfDeploymentDesc]:\r
+ return self._list()\r
+\r
+ def update(self, nfdeployment_descriptor: dms.NfDeploymentDesc):\r
+ self._update(nfdeployment_descriptor)\r
+\r
+ @abc.abstractmethod\r
+ def _add(self, nfdeployment_descriptor: dms.NfDeploymentDesc):\r
+ raise NotImplementedError\r
+\r
+ @abc.abstractmethod\r
+ def _get(self, nfdeployment_descriptor_id) -> dms.NfDeploymentDesc:\r
+ raise NotImplementedError\r
+\r
+ @abc.abstractmethod\r
+ def _update(self, nfdeployment_descriptor: dms.NfDeploymentDesc):\r
+ raise NotImplementedError\r
--- /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
--- /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
--- /dev/null
+# 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 DmsDTO:
+
+ api = Namespace("O2DMS",
+ description='DMS related operations.')
+
+ dms_get = api.model(
+ "Get DMS information",
+ {
+ 'deploymentManagerId': fields.String(
+ required=True,
+ description='Deployment manager ID'),
+ 'name': fields.String,
+ 'description': fields.String,
+ 'supportedLocations': fields.String,
+ 'capabilities': fields.String,
+ 'capacity': fields.String,
+ }
+ )
+
+
+class DmsLcmNfDeploymentDescriptorDTO:
+
+ api = Namespace("O2DMS_LCM_NfDeploymentDescriptor",
+ description='DMS LCM NfDeploymentDescritpor operations.')
+
+ dmslcm_NfDeploymentDescriptor_get = api.model(
+ "Get NfDeploymentDescriptor information",
+ {
+ 'id': fields.String(
+ required=True,
+ description='NfDeploymentDescriptor ID'),
+ 'name': fields.String,
+ 'description': fields.String,
+ 'inputParams': fields.String,
+ 'outputParams': fields.String
+ }
+ )
--- /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
+\r
+from sqlalchemy import select\r
+\r
+from o2common.service import unit_of_work\r
+from o2ims.adapter.orm import deploymentmanager\r
+from o2dms.adapter.orm import nfDeploymentDesc\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
+ deploymentManagerID: str,\r
+ uow: unit_of_work.AbstractUnitOfWork):\r
+ with uow:\r
+ res = uow.session.execute(select(deploymentmanager).where(\r
+ nfDeploymentDesc.c.deploymentManagerId == deploymentManagerID,\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(nfdeploymentdescriptorid: str,\r
+# uow: unit_of_work.AbstractUnitOfWork):\r
+# with uow:\r
+# res = uow.session.execute(select(deploymentmanager).where(\r
+# deploymentmanager.c.id == nfdeploymentdescriptorid))\r
+# first = res.first()\r
+# return None if first is None else dict(first)\r
+\r
+\r
+# def lcm_nfdeploymentdesc_delete(nfdeploymentdescriptorid: str,\r
+# uow: unit_of_work.AbstractUnitOfWork):\r
+# with uow:\r
+# res = uow.session.execute(select(deploymentmanager).where(\r
+# deploymentmanager.c.id == nfdeploymentdescriptorid))\r
+# first = res.first()\r
+# return None if first is None else dict(first)\r
--- /dev/null
+# 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 import jsonify
+from flask_restx import Resource
+
+from o2common.config import config
+from o2dms.views.dms_dto import DmsDTO, DmsLcmNfDeploymentDescriptorDTO
+from o2dms.views import dms_lcm_view
+
+apibase = config.get_o2dms_api_base()
+
+
+# ---------- DeploymentManagers ---------- #
+api_dms = DmsDTO.api
+
+
+@api_dms.route("/<deploymentManagerID>")
+@api_dms.param('deploymentManagerID', 'ID of the deployment manager')
+@api_dms.response(404, 'Deployment manager not found')
+class DmsGetRouter(Resource):
+
+ model = DmsDTO.dms_get
+
+ @api_dms.doc('Get deployment manager')
+ @api_dms.marshal_with(model)
+ def get(self, deploymentManagerID):
+ result = dms_lcm_view.deployment_manager_one(
+ deploymentManagerID, uow)
+ if result is not None:
+ return result
+ api_dms.abort(404, "Deployment manager {} doesn't exist".format(
+ deploymentManagerID))
+
+
+# LCM services #
+api_lcm_nfdeploymentDesc = DmsLcmNfDeploymentDescriptorDTO.api
+
+
+@api_lcm_nfdeploymentDesc\
+ .route("/<deploymentManagerID>/O2dms_DeploymentLifecycle")
+@api_lcm_nfdeploymentDesc\
+ .param('deploymentManagerID', 'ID of the deployment manager')
+@api_lcm_nfdeploymentDesc.response(404, 'DMS LCM not found')
+class DmsLcmNfDeploymentDescListRouter(Resource):
+
+ model = DmsLcmNfDeploymentDescriptorDTO.dmslcm_NfDeploymentDescriptor_get
+
+ @api_lcm_nfdeploymentDesc.doc('Get a list of NfDeploymentDescriptor')
+ @api_lcm_nfdeploymentDesc.marshal_list_with(model)
+ def get(self, deploymentManagerID):
+ return dms_lcm_view.lcm_nfdeploymentdesc_list(deploymentManagerID, uow)
+
+
+@api_lcm_nfdeploymentDesc\
+ .route("/<deploymentManagerID>/O2dms_DeploymentLifecycle/"
+ "<nfDeploymentDescriptorId>")
+@api_lcm_nfdeploymentDesc\
+ .param('deploymentManagerID', 'ID of the deployment manager')
+@api_lcm_nfdeploymentDesc.param('nfDeploymentDescriptorId',
+ 'ID of the NfDeploymentDescriptor')
+@api_lcm_nfdeploymentDesc.response(404, 'DMS LCM not found')
+class DmsLcmNfDeploymentDescGetRouter(Resource):
+
+ model = DmsLcmNfDeploymentDescriptorDTO.dmslcm_NfDeploymentDescriptor_get
+
+ @api_lcm_nfdeploymentDesc.doc('Get a NfDeploymentDescriptor')
+ @api_lcm_nfdeploymentDesc.marshal_with(model)
+ def get(self, nfDeploymentDescriptorId, deploymentManagerID):
+ result = dms_lcm_view\
+ .lcm_nfdeploymentdesc_one(nfDeploymentDescriptorId,
+ deploymentManagerID, uow)
+ if result is not None:
+ return result
+ api_dms.abort(404, "NfDeploymentDescriptor {} doesn't exist".format(
+ nfDeploymentDescriptorId))
+
+
+def configure_namespace(app, bus):
+ app.add_namespace(api_dms, path=apibase)
+ app.add_namespace(api_lcm_nfdeploymentDesc, path=apibase)
+
+ # Set global uow
+ global uow
+ uow = bus.uow
--- /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
Column("updatetime", DateTime),\r
Column("createtime", DateTime),\r
Column("hash", String(255)),\r
+ Column("version_number", Integer),\r
\r
Column("deploymentManagerId", String(255), primary_key=True),\r
Column("oCloudId", ForeignKey("ocloud.oCloudId")),\r
return f"http://{host}:{port}"
+def get_root_api_base():
+ return "/"
+
+
def get_o2ims_api_base():
- return '/o2ims_infrastructureInventory/v1'
+ return get_root_api_base() + 'o2ims_infrastructureInventory/v1'
-def get_o2dms_api_base(dmsid: str):
- return "/" + dmsid + '/o2dms/v1'
+def get_o2dms_api_base():
+ return get_root_api_base() + "o2dms/v1"
def get_redis_host_and_port():
from o2ims import bootstrap\r
# from o2ims import config\r
from o2ims.views.ocloud_route import configure_namespace\r
+from o2dms.views import dms_route\r
\r
\r
# apibase = config.get_o2ims_api_base()\r
)\r
bus = bootstrap.bootstrap()\r
configure_namespace(api, bus)\r
+\r
+dms_route.configure_namespace(api, bus)\r
def create_by(stxobj: StxGenericModel, parentid: str) -> DeploymentManager:
- dmsendpoint = config.get_api_url() + config.get_o2dms_api_base(stxobj.id)
+ dmsendpoint = config.get_api_url() +\
+ config.get_o2dms_api_base() + "/" + stxobj.id
description = "A DMS"
ocloudid = parentid
supportedLocations = ''
--- /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
--- /dev/null
+#!/bin/sh
+
+# pip install -e /src
+# python /o2ims/entrypoints/resource_watcher.py
+
+mkdir -p /etc/o2
+cp -r /configs/* /etc/o2/
+mkdir -p /src/o2common
+cp -r /o2common/* /src/o2common
+mkdir -p /src/o2ims
+cp -r /o2ims/* /src/o2ims
+mkdir -p /src/o2dms
+cp -r /o2dms/* /src/o2dms
+mkdir -p /src/o2app
+cp -r /o2app/* /src/o2app
+pip install -e /src
+
+export FLASK_APP=/o2app/entrypoints/flask_application.py
+flask run --host=0.0.0.0 --port=80
# pip install -e /src
# python /o2ims/entrypoints/resource_watcher.py
+mkdir -p /etc/o2
cp -r /configs/* /etc/o2/
+mkdir -p /src/o2common
cp -r /o2common/* /src/o2common
+mkdir -p /src/o2ims
cp -r /o2ims/* /src/o2ims
+mkdir -p /src/o2dms
cp -r /o2dms/* /src/o2dms
+mkdir -p /src/o2app
+cp -r /o2app/* /src/o2app
pip install -e /src
-python /o2ims/entrypoints/resource_watcher.py
+python /o2app/entrypoints/redis_eventconsumer.py
# pip install -e /src
# python /o2ims/entrypoints/resource_watcher.py
+mkdir -p /etc/o2
cp -r /configs/* /etc/o2/
+mkdir -p /src/o2common
cp -r /o2common/* /src/o2common
+mkdir -p /src/o2ims
cp -r /o2ims/* /src/o2ims
+mkdir -p /src/o2dms
cp -r /o2dms/* /src/o2dms
+mkdir -p /src/o2app
+cp -r /o2app/* /src/o2app
pip install -e /src
-python /o2ims/entrypoints/redis_eventconsumer.py
+python /o2app/entrypoints/resource_watcher.py