summaryrefslogtreecommitdiffstats
path: root/components/pm-subscription-handler/pmsh_service/mod
diff options
context:
space:
mode:
Diffstat (limited to 'components/pm-subscription-handler/pmsh_service/mod')
-rwxr-xr-xcomponents/pm-subscription-handler/pmsh_service/mod/pmsh_utils.py36
-rw-r--r--components/pm-subscription-handler/pmsh_service/mod/sub_schema.json122
-rw-r--r--components/pm-subscription-handler/pmsh_service/mod/subscription_handler.py8
3 files changed, 164 insertions, 2 deletions
diff --git a/components/pm-subscription-handler/pmsh_service/mod/pmsh_utils.py b/components/pm-subscription-handler/pmsh_service/mod/pmsh_utils.py
index 18834134..7b91a307 100755
--- a/components/pm-subscription-handler/pmsh_service/mod/pmsh_utils.py
+++ b/components/pm-subscription-handler/pmsh_service/mod/pmsh_utils.py
@@ -15,7 +15,10 @@
#
# SPDX-License-Identifier: Apache-2.0
# ============LICENSE_END=====================================================
+import json
+import os
import uuid
+from json import JSONDecodeError
from os import getenv
from threading import Timer
@@ -24,8 +27,8 @@ from onap_dcae_cbs_docker_client.client import get_all
from onaplogging.mdcContext import MDC
from requests.auth import HTTPBasicAuth
from tenacity import wait_fixed, stop_after_attempt, retry, retry_if_exception_type
+from jsonschema import validate, ValidationError
-import mod.network_function
from mod import logger
from mod.subscription import Subscription
@@ -41,6 +44,7 @@ def mdc_handler(function):
kwargs['request_id'] = request_id
kwargs['invocation_id'] = invocation_id
return function(*args, **kwargs)
+
return decorator
@@ -58,6 +62,16 @@ class MySingleton(object):
return type(clz.__name__, (MySingleton,), dict(clz.__dict__))
+def _load_sub_schema_from_file():
+ try:
+ with open(os.path.join(os.path.dirname(__file__), 'sub_schema.json')) as sub:
+ return json.load(sub)
+ except OSError as err:
+ logger.error(f'Failed to read sub schema file: {err}', exc_info=True)
+ except JSONDecodeError as json_err:
+ logger.error(f'sub schema file is not a valid JSON file: {json_err}', exc_info=True)
+
+
class AppConfig:
INSTANCE = None
@@ -73,8 +87,9 @@ class AppConfig:
self.streams_publishes = conf['config'].get('streams_publishes')
self.operational_policy_name = conf['config'].get('operational_policy_name')
self.control_loop_name = conf['config'].get('control_loop_name')
+ self.sub_schema = _load_sub_schema_from_file()
self.subscription = Subscription(**conf['policy']['subscription'])
- self.nf_filter = mod.network_function.NetworkFunctionFilter(**self.subscription.nfFilter)
+ self.nf_filter = None
def __new__(cls, *args, **kwargs):
if AppConfig.INSTANCE is None:
@@ -103,6 +118,23 @@ class AppConfig:
logger.error(f'Failed to get config from CBS: {e}', exc_info=True)
raise ValueError(e)
+ def validate_sub_schema(self):
+ """
+ Validates schema of PMSH subscription
+
+ Raises:
+ ValidationError: If the PMSH subscription schema is invalid
+ """
+ sub_data = self.subscription.__dict__
+ validate(instance=sub_data, schema=self.sub_schema)
+ nf_filter = sub_data["nfFilter"]
+ for filter_name in nf_filter:
+ if len(nf_filter[filter_name]) > 0:
+ break
+ else:
+ raise ValidationError("At least one filter within nfFilter must not be empty")
+ logger.debug("Subscription schema is valid.")
+
def refresh_config(self):
"""
Update the relevant attributes of the AppConfig object.
diff --git a/components/pm-subscription-handler/pmsh_service/mod/sub_schema.json b/components/pm-subscription-handler/pmsh_service/mod/sub_schema.json
new file mode 100644
index 00000000..7a1da5bb
--- /dev/null
+++ b/components/pm-subscription-handler/pmsh_service/mod/sub_schema.json
@@ -0,0 +1,122 @@
+{
+ "type":"object",
+ "properties":{
+ "subscriptionName":{
+ "type":"string"
+ },
+ "administrativeState":{
+ "allOf":[
+ {
+ "type":"string"
+ },
+ {
+ "enum":[
+ "UNLOCKED",
+ "LOCKED"
+ ]
+ }
+ ]
+ },
+ "fileBasedGP":{
+ "type":"integer"
+ },
+ "fileLocation":{
+ "type":"string"
+ },
+ "nfFilter":{
+ "type":"object",
+ "properties":{
+ "nfNames":{
+ "type":"array",
+ "items":{
+ "type":"string"
+ }
+ },
+ "modelInvariantIDs":{
+ "type":"array",
+ "items":{
+ "type":"string"
+ }
+ },
+ "modelVersionIDs":{
+ "type":"array",
+ "items":{
+ "type":"string"
+ }
+ },
+ "modelNames":{
+ "type":"array",
+ "items":{
+ "type":"string"
+ }
+ }
+ },
+ "required":[
+ "nfNames",
+ "modelInvariantIDs",
+ "modelVersionIDs",
+ "modelNames"
+ ]
+ },
+ "measurementGroups":{
+ "type":"array",
+ "minItems": 1,
+ "items":{
+ "type":"object",
+ "properties":{
+ "measurementGroup":{
+ "type":"object",
+ "properties":{
+ "measurementTypes":{
+ "type":"array",
+ "minItems": 1,
+ "items":{
+ "type":"object",
+ "properties":{
+ "measurementType":{
+ "type":"string"
+ }
+ },
+ "required":[
+ "measurementType"
+ ]
+ }
+ },
+ "managedObjectDNsBasic":{
+ "type":"array",
+ "minItems": 1,
+ "items":{
+ "type":"object",
+ "properties":{
+ "DN":{
+ "type":"string"
+ }
+ },
+ "required":[
+ "DN"
+ ]
+ }
+ }
+ },
+ "required":[
+ "measurementTypes",
+ "managedObjectDNsBasic"
+ ]
+ }
+ },
+ "required":[
+ "measurementGroup"
+ ]
+ }
+ }
+ },
+ "required":[
+ "subscriptionName",
+ "administrativeState",
+ "fileBasedGP",
+ "fileLocation",
+ "nfFilter",
+ "measurementGroups"
+ ]
+
+} \ No newline at end of file
diff --git a/components/pm-subscription-handler/pmsh_service/mod/subscription_handler.py b/components/pm-subscription-handler/pmsh_service/mod/subscription_handler.py
index f50f5ab2..6238a298 100644
--- a/components/pm-subscription-handler/pmsh_service/mod/subscription_handler.py
+++ b/components/pm-subscription-handler/pmsh_service/mod/subscription_handler.py
@@ -15,9 +15,11 @@
#
# SPDX-License-Identifier: Apache-2.0
# ============LICENSE_END=====================================================
+from jsonschema import ValidationError
from mod import logger, aai_client
from mod.aai_event_handler import process_aai_events
+from mod.network_function import NetworkFunctionFilter
from mod.pmsh_utils import PeriodicTask
from mod.subscription import AdministrativeState
@@ -42,12 +44,16 @@ class SubscriptionHandler:
self._check_for_failed_nfs()
else:
self.app_conf.refresh_config()
+ self.app_conf.validate_sub_schema()
new_administrative_state = self.app_conf.subscription.administrativeState
if local_admin_state == new_administrative_state:
logger.info(f'Administrative State did not change in the app config: '
f'{new_administrative_state}')
else:
self._check_state_change(local_admin_state, new_administrative_state)
+ except (ValidationError, TypeError) as err:
+ logger.error(f'Error occurred during validation of subscription schema {err}',
+ exc_info=True)
except Exception as err:
logger.error(f'Error occurred during the activation/deactivation process {err}',
exc_info=True)
@@ -65,6 +71,8 @@ class SubscriptionHandler:
raise Exception(f'Invalid AdministrativeState: {new_administrative_state}')
def _activate(self, new_administrative_state):
+ if not self.app_conf.nf_filter:
+ self.app_conf.nf_filter = NetworkFunctionFilter(**self.app_conf.subscription.nfFilter)
self._start_aai_event_thread()
self.app_conf.subscription.update_sub_params(new_administrative_state,
self.app_conf.subscription.fileBasedGP,