summaryrefslogtreecommitdiffstats
path: root/components/pm-subscription-handler/pmsh_service
diff options
context:
space:
mode:
authorefiacor <fiachra.corcoran@est.tech>2020-05-20 15:18:41 +0100
committerefiacor <fiachra.corcoran@est.tech>2020-05-25 08:50:24 +0100
commit5ed9b7d3cad56c6438bca305b6d2931bd320352b (patch)
treeb05cbb4e7215e9b6b9aead2a1ae45d63330c0761 /components/pm-subscription-handler/pmsh_service
parent9a57e9a2e2357f267c6a7c804488011ac97beab5 (diff)
[PMSH] Adding 'subscriptions' api endpoint
Signed-off-by: efiacor <fiachra.corcoran@est.tech> Change-Id: I837045b3b618a98d4aabe190359d0ad47f27ca9f Issue-ID: DCAEGEN2-2154
Diffstat (limited to 'components/pm-subscription-handler/pmsh_service')
-rw-r--r--components/pm-subscription-handler/pmsh_service/mod/__init__.py2
-rw-r--r--components/pm-subscription-handler/pmsh_service/mod/api/__init__.py0
-rwxr-xr-xcomponents/pm-subscription-handler/pmsh_service/mod/api/controller.py (renamed from components/pm-subscription-handler/pmsh_service/mod/healthcheck.py)12
-rwxr-xr-xcomponents/pm-subscription-handler/pmsh_service/mod/api/db_models.py (renamed from components/pm-subscription-handler/pmsh_service/mod/db_models.py)24
-rw-r--r--components/pm-subscription-handler/pmsh_service/mod/api/pmsh_swagger.yml89
-rwxr-xr-xcomponents/pm-subscription-handler/pmsh_service/mod/network_function.py5
-rw-r--r--components/pm-subscription-handler/pmsh_service/mod/pmsh_swagger.yml34
-rwxr-xr-xcomponents/pm-subscription-handler/pmsh_service/mod/subscription.py116
8 files changed, 187 insertions, 95 deletions
diff --git a/components/pm-subscription-handler/pmsh_service/mod/__init__.py b/components/pm-subscription-handler/pmsh_service/mod/__init__.py
index e09ec285..5c0a5144 100644
--- a/components/pm-subscription-handler/pmsh_service/mod/__init__.py
+++ b/components/pm-subscription-handler/pmsh_service/mod/__init__.py
@@ -37,7 +37,7 @@ def _get_app():
def launch_api_server(app_config):
connex_app = _get_app()
- connex_app.add_api('pmsh_swagger.yml')
+ connex_app.add_api('api/pmsh_swagger.yml')
connex_app.run(port=os.environ.get('PMSH_API_PORT', '8443'),
ssl_context=(app_config.cert_path, app_config.key_path))
diff --git a/components/pm-subscription-handler/pmsh_service/mod/api/__init__.py b/components/pm-subscription-handler/pmsh_service/mod/api/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/components/pm-subscription-handler/pmsh_service/mod/api/__init__.py
diff --git a/components/pm-subscription-handler/pmsh_service/mod/healthcheck.py b/components/pm-subscription-handler/pmsh_service/mod/api/controller.py
index af82fc4e..21d29caf 100755
--- a/components/pm-subscription-handler/pmsh_service/mod/healthcheck.py
+++ b/components/pm-subscription-handler/pmsh_service/mod/api/controller.py
@@ -16,6 +16,8 @@
# SPDX-License-Identifier: Apache-2.0
# ============LICENSE_END=====================================================
+from mod.subscription import Subscription
+
def status():
"""
@@ -28,3 +30,13 @@ def status():
NA
"""
return {'status': 'healthy'}
+
+
+def get_all_sub_to_nf_relations():
+ """ Retrieves all subscription to nf relations
+
+ Returns:
+ list: of Subscriptions and it's related Network Functions, else empty
+ """
+ subs_dict = [s.serialize() for s in Subscription.get_all()]
+ return subs_dict
diff --git a/components/pm-subscription-handler/pmsh_service/mod/db_models.py b/components/pm-subscription-handler/pmsh_service/mod/api/db_models.py
index d1836760..1d6f72b3 100755
--- a/components/pm-subscription-handler/pmsh_service/mod/db_models.py
+++ b/components/pm-subscription-handler/pmsh_service/mod/api/db_models.py
@@ -38,13 +38,19 @@ class SubscriptionModel(db.Model):
self.status = status
def __repr__(self):
- return f'Subscription: {self.subscription_name} {self.status}'
+ return f'subscription_name: {self.subscription_name}, status: {self.status}'
def __eq__(self, other):
if isinstance(self, other.__class__):
return self.subscription_name == other.subscription_name
return False
+ def serialize(self):
+ sub_nfs = NfSubRelationalModel.query.filter(
+ NfSubRelationalModel.subscription_name == self.subscription_name).all()
+ return {'subscription_name': self.subscription_name, 'subscription_status': self.status,
+ 'network_functions': [sub_nf.serialize_nf() for sub_nf in sub_nfs]}
+
class NetworkFunctionModel(db.Model):
__tablename__ = 'network_functions'
@@ -62,7 +68,7 @@ class NetworkFunctionModel(db.Model):
self.orchestration_status = orchestration_status
def __repr__(self):
- return f'NetworkFunctionModel: {self.nf_name}, {self.orchestration_status}'
+ return f'nf_name: {self.nf_name}, orchestration_status: {self.orchestration_status}'
class NfSubRelationalModel(db.Model):
@@ -87,5 +93,15 @@ class NfSubRelationalModel(db.Model):
self.nf_sub_status = nf_sub_status
def __repr__(self):
- return f'NetworkFunctionSubscriptions: {self.subscription_name}, ' \
- f'{self.nf_name}, {self.nf_sub_status}'
+ return f'subscription_name: {self.subscription_name}, ' \
+ f'nf_name: {self.nf_name}, nf_sub_status: {self.nf_sub_status}'
+
+ def serialize(self):
+ return {'subscription_name': self.subscription_name, 'nf_name': self.nf_name,
+ 'nf_sub_status': self.nf_sub_status}
+
+ def serialize_nf(self):
+ nf_orch_status = NetworkFunctionModel.query.filter(
+ NetworkFunctionModel.nf_name == self.nf_name).one_or_none().orchestration_status
+ return {'nf_name': self.nf_name, 'orchestration_status': nf_orch_status,
+ 'nf_sub_status': self.nf_sub_status}
diff --git a/components/pm-subscription-handler/pmsh_service/mod/api/pmsh_swagger.yml b/components/pm-subscription-handler/pmsh_service/mod/api/pmsh_swagger.yml
new file mode 100644
index 00000000..58e6a788
--- /dev/null
+++ b/components/pm-subscription-handler/pmsh_service/mod/api/pmsh_swagger.yml
@@ -0,0 +1,89 @@
+# ============LICENSE_START=======================================================
+# Copyright (C) 2020 Nordix Foundation.
+# ================================================================================
+# 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.
+#
+# SPDX-License-Identifier: Apache-2.0
+# ============LICENSE_END=========================================================
+
+swagger: "2.0"
+info:
+ title: PM Subscription Handler Service
+ version: "1.1.0"
+ description: PM subscription handler enables control of performance management jobs on network functions in ONAP
+produces:
+ - "application/json"
+basePath: "/"
+schemes:
+ - https
+# Paths supported by the server application
+paths:
+ /subscriptions:
+ get:
+ description: >-
+ Get all defined Subscriptions and their related Network Functions from ONAP.
+ operationId: mod.api.controller.get_all_sub_to_nf_relations
+ responses:
+ 200:
+ description: OK; Array of subscriptions are returned as an object
+ schema:
+ type: array
+ items:
+ type: object
+ properties:
+ subscription_name:
+ type: string
+ description: Name of the Subscription
+ subscription_status:
+ type: string
+ description: Status of the Subscription
+ network_functions:
+ type: array
+ items:
+ type: object
+ properties:
+ nf_name:
+ type: string
+ description: Name of the Network Function
+ nf_sub_status:
+ type: string
+ description: Status of the Subscription on the Network Function
+ orchestration_status:
+ type: string
+ description: Orchestration status of the Network Function
+ 401:
+ description: Unauthorized
+ 403:
+ description: Forbidden
+ 404:
+ description: there are no subscriptions defined
+
+ /healthcheck:
+ get:
+ operationId: mod.api.controller.status
+ tags:
+ - "HealthCheck"
+ description: >-
+ This is the health check endpoint. If this returns a 200, the server is alive.
+ responses:
+ 200:
+ description: Successful response
+ schema:
+ type: object
+ properties:
+ status:
+ type: string
+ description: Overall health of PMSH
+ enum: [healthy, unhealthy]
+ 503:
+ description: the pmsh service is unavailable
diff --git a/components/pm-subscription-handler/pmsh_service/mod/network_function.py b/components/pm-subscription-handler/pmsh_service/mod/network_function.py
index bf223184..0663be08 100755
--- a/components/pm-subscription-handler/pmsh_service/mod/network_function.py
+++ b/components/pm-subscription-handler/pmsh_service/mod/network_function.py
@@ -20,7 +20,7 @@ import re
from enum import Enum
from mod import pmsh_logging as logger, db
-from mod.db_models import NetworkFunctionModel
+from mod.api.db_models import NetworkFunctionModel
class NetworkFunction:
@@ -53,10 +53,9 @@ class NetworkFunction:
orchestration_status=self.orchestration_status)
db.session.add(new_nf)
db.session.commit()
-
return new_nf
else:
- logger.debug(f'Network function {existing_nf} already exists,'
+ logger.debug(f'Network function {existing_nf.nf_name} already exists,'
f' returning this network function..')
return existing_nf
diff --git a/components/pm-subscription-handler/pmsh_service/mod/pmsh_swagger.yml b/components/pm-subscription-handler/pmsh_service/mod/pmsh_swagger.yml
deleted file mode 100644
index 7bfecd81..00000000
--- a/components/pm-subscription-handler/pmsh_service/mod/pmsh_swagger.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-swagger: "2.0"
-info:
- title: PM Subscription Handler Service
- version: "1.0.0"
- description: This is the swagger file that outlines the PM subscription handler api
-consumes:
- - "application/json"
-produces:
- - "application/json"
-
-schemes:
- - https
-
-# Paths supported by the server application
-paths:
- /healthcheck:
- get:
- operationId: "mod.healthcheck.status"
- tags:
- - "HealthCheck"
- description: >-
- This is the health check endpoint. If this returns a 200, the server is alive.
- responses:
- 200:
- description: Successful response
- schema:
- type: object
- properties:
- status:
- type: string
- description: Overall health of PMSH
- enum: [healthy, unhealthy]
- 503:
- description: the pmsh service is unavailable
diff --git a/components/pm-subscription-handler/pmsh_service/mod/subscription.py b/components/pm-subscription-handler/pmsh_service/mod/subscription.py
index 3add7200..7517ba9c 100755
--- a/components/pm-subscription-handler/pmsh_service/mod/subscription.py
+++ b/components/pm-subscription-handler/pmsh_service/mod/subscription.py
@@ -15,14 +15,13 @@
#
# SPDX-License-Identifier: Apache-2.0
# ============LICENSE_END=====================================================
-
from enum import Enum
from tenacity import retry, retry_if_exception_type, wait_exponential, stop_after_attempt
import mod.pmsh_logging as logger
from mod import db
-from mod.db_models import SubscriptionModel, NfSubRelationalModel, NetworkFunctionModel
+from mod.api.db_models import SubscriptionModel, NfSubRelationalModel, NetworkFunctionModel
from mod.network_function import NetworkFunction
@@ -84,35 +83,33 @@ class Subscription:
Returns:
Subscription object
"""
- existing_subscription = (SubscriptionModel.query.filter(
- SubscriptionModel.subscription_name == self.subscriptionName).one_or_none())
-
- if existing_subscription is None:
- new_subscription = SubscriptionModel(subscription_name=self.subscriptionName,
- status=self.administrativeState)
-
- db.session.add(new_subscription)
- db.session.commit()
-
- return new_subscription
-
- else:
- logger.debug(f'Subscription {self.subscriptionName} already exists,'
- f' returning this subscription..')
- return existing_subscription
-
- def add_network_functions_to_subscription(self, nf_list):
- """ Associates network functions to a Subscription
+ try:
+ existing_subscription = (SubscriptionModel.query.filter(
+ SubscriptionModel.subscription_name == self.subscriptionName).one_or_none())
+ if existing_subscription is None:
+ new_subscription = SubscriptionModel(subscription_name=self.subscriptionName,
+ status=self.administrativeState)
+ db.session.add(new_subscription)
+ db.session.commit()
+ return new_subscription
+ else:
+ logger.debug(f'Subscription {self.subscriptionName} already exists,'
+ f' returning this subscription..')
+ return existing_subscription
+ except Exception as e:
+ logger.debug(f'Failed to create subscription {self.subscriptionName} in the DB: {e}')
+
+ def add_network_function_to_subscription(self, nf):
+ """ Associates a network function to a Subscription
Args:
- nf_list : A list of NetworkFunction objects.
+ nf : A NetworkFunction object.
"""
current_sub = self.create()
- logger.debug(f'Adding network functions to subscription {current_sub.subscription_name}')
-
- for nf in nf_list:
+ try:
current_nf = nf.create()
-
+ logger.debug(f'Adding network function {nf.nf_name} to Subscription '
+ f'{current_sub.subscription_name}')
existing_entry = NfSubRelationalModel.query.filter(
NfSubRelationalModel.subscription_name == current_sub.subscription_name,
NfSubRelationalModel.nf_name == current_nf.nf_name).one_or_none()
@@ -120,11 +117,14 @@ class Subscription:
new_nf_sub = NfSubRelationalModel(current_sub.subscription_name,
nf.nf_name, SubNfState.PENDING_CREATE.value)
new_nf_sub.nf = current_nf
- logger.debug(current_nf)
current_sub.nfs.append(new_nf_sub)
-
- db.session.add(current_sub)
- db.session.commit()
+ logger.debug(f'Network function {current_nf.nf_name} added to Subscription '
+ f'{current_sub.subscription_name}')
+ db.session.add(current_sub)
+ db.session.commit()
+ except Exception as e:
+ logger.debug(f'Failed to add nf {nf.nf_name} to subscription '
+ f'{current_sub.subscription_name}: {e}')
@staticmethod
def get(subscription_name):
@@ -150,27 +150,34 @@ class Subscription:
def update_subscription_status(self):
""" Updates the status of subscription in subscription table """
- SubscriptionModel.query.filter(
- SubscriptionModel.subscription_name == self.subscriptionName). \
- update({SubscriptionModel.status: self.administrativeState},
- synchronize_session='evaluate')
+ try:
+ SubscriptionModel.query.filter(
+ SubscriptionModel.subscription_name == self.subscriptionName)\
+ .update({SubscriptionModel.status: self.administrativeState},
+ synchronize_session='evaluate')
- db.session.commit()
+ db.session.commit()
+ except Exception as e:
+ logger.debug(f'Failed to update status of subscription: {self.subscriptionName}: {e}')
def delete_subscription(self):
""" Deletes a subscription and all its association from the database. A network function
that is only associated with the subscription being removed will also be deleted."""
- subscription = SubscriptionModel.query.filter(
- SubscriptionModel.subscription_name == self.subscriptionName).one_or_none()
- if subscription:
- for nf_relationship in subscription.nfs:
- other_nf_relationship = NfSubRelationalModel.query.filter(
- NfSubRelationalModel.subscription_name != self.subscriptionName,
- NfSubRelationalModel.nf_name == nf_relationship.nf_name).one_or_none()
- if not other_nf_relationship:
- db.session.delete(nf_relationship.nf)
- db.session.delete(subscription)
- db.session.commit()
+ try:
+ subscription = SubscriptionModel.query.filter(
+ SubscriptionModel.subscription_name == self.subscriptionName).one_or_none()
+ if subscription:
+ for nf_relationship in subscription.nfs:
+ other_nf_relationship = NfSubRelationalModel.query.filter(
+ NfSubRelationalModel.subscription_name != self.subscriptionName,
+ NfSubRelationalModel.nf_name == nf_relationship.nf_name).one_or_none()
+ if not other_nf_relationship:
+ db.session.delete(nf_relationship.nf)
+ db.session.delete(subscription)
+ db.session.commit()
+ except Exception as e:
+ logger.debug(f'Failed to delete subscription: {self.subscriptionName} '
+ f'and it\'s relations from the DB: {e}')
@retry(wait=wait_exponential(multiplier=1, min=30, max=120), stop=stop_after_attempt(3),
retry=retry_if_exception_type(Exception))
@@ -188,7 +195,7 @@ class Subscription:
mr_pub.publish_subscription_event_data(self, nf.nf_name, app_conf)
logger.debug(f'Publishing Event to {action} '
f'Sub: {self.subscriptionName} for the nf: {nf.nf_name}')
- self.add_network_functions_to_subscription(nfs)
+ self.add_network_function_to_subscription(nf)
self.update_sub_nf_status(self.subscriptionName, sub_nf_state, nf.nf_name)
except Exception as err:
raise Exception(f'Error publishing activation event to MR: {err}')
@@ -213,12 +220,15 @@ class Subscription:
nf_name (str): The network function name
status (str): Status of the subscription
"""
- NfSubRelationalModel.query.filter(
- NfSubRelationalModel.subscription_name == subscription_name,
- NfSubRelationalModel.nf_name == nf_name). \
- update({NfSubRelationalModel.nf_sub_status: status}, synchronize_session='evaluate')
-
- db.session.commit()
+ try:
+ NfSubRelationalModel.query.filter(
+ NfSubRelationalModel.subscription_name == subscription_name,
+ NfSubRelationalModel.nf_name == nf_name). \
+ update({NfSubRelationalModel.nf_sub_status: status}, synchronize_session='evaluate')
+ db.session.commit()
+ except Exception as e:
+ logger.debug(f'Failed to update status of nf: {nf_name} for subscription: '
+ f'{subscription_name}: {e}')
def _get_nf_models(self):
nf_sub_relationships = NfSubRelationalModel.query.filter(