Added A1 policy handler, healthcheck handler, sdl handler and alarm 69/5369/10
authorRahulBanerji <rahulbanerji96@gmail.com>
Mon, 7 Dec 2020 08:12:19 +0000 (13:42 +0530)
committerRahulBanerji <r.banerji@samsung.com>
Thu, 24 Dec 2020 09:14:51 +0000 (14:44 +0530)
Issue-Id: [ RICAPP-157 | RICAPP-158 | RICAPP-159 | RICAPP-160 ]
Change-Id: Icd0363fa6b6cc2d96252fb971d02db73e2c6b612
Signed-off-by: Rahul Banerji <r.banerji@samsung.com>
22 files changed:
Dockerfile
README.md
init/config-file.json [new file with mode: 0644]
init/init_script.py [new file with mode: 0644]
init/test_route.rt [new file with mode: 0644]
resources/pod.yaml
resources/test_route.rt [deleted file]
setup.py
src/__init__.py
src/handler/A1PolicyHandler.py [new file with mode: 0644]
src/handler/HealthCheckHandler.py [new file with mode: 0644]
src/handler/_BaseHandler.py [new file with mode: 0644]
src/handler/__init__.py [new file with mode: 0644]
src/hwxapp.py [new file with mode: 0644]
src/main.py
src/manager/A1PolicyManager.py [new file with mode: 0644]
src/manager/SdlAlarmManager.py [new file with mode: 0644]
src/manager/SdlManager.py [new file with mode: 0644]
src/manager/_BaseManager.py [new file with mode: 0644]
src/manager/__init__.py [new file with mode: 0644]
src/utils/__init__.py [new file with mode: 0644]
src/utils/constants.py [new file with mode: 0644]

index 34578ff..5f7a66e 100644 (file)
@@ -19,7 +19,7 @@ FROM python:3.8-alpine
 COPY --from=nexus3.o-ran-sc.org:10002/o-ran-sc/bldr-alpine3-rmr:4.0.5 /usr/local/lib64/librmr* /usr/local/lib64/
 # RMR setup
 RUN mkdir -p /opt/route/
-COPY resources/test_route.rt /opt/route/test_route.rt
+COPY init/test_route.rt /opt/route/test_route.rt
 ENV LD_LIBRARY_PATH /usr/local/lib/:/usr/local/lib64
 ENV RMR_SEED_RT /opt/route/test_route.rt
 
@@ -28,10 +28,19 @@ RUN apk update && apk add gcc musl-dev bash
 
 # Install
 COPY setup.py /tmp
+COPY README.md /tmp
 COPY LICENSE.txt /tmp/
 COPY src/ /tmp/src
+COPY init/ /tmp/init
 RUN pip install /tmp
 
-# Run
+# Env - TODO- Configmap
 ENV PYTHONUNBUFFERED 1
+ENV CONFIG_FILE=/tmp/init/config-file.json
+
+# For Default DB connection, modify for resp kubernetes env
+ENV DBAAS_SERVICE_PORT=6379
+ENV DBAAS_SERVICE_HOST=service-ricplt-dbaas-tcp.ricplt.svc.cluster.local
+
+#Run
 CMD run-hw-python.py
index e38d2af..eb323ec 100644 (file)
--- a/README.md
+++ b/README.md
@@ -42,7 +42,7 @@ This covers all three methods.
 3. Kubernetes 
 
 
-
+:
 Software Installation and Deployment
 ------------------------------------
 The build process assumes a Linux environment with python >= 3.8  and  has been tested on Ubuntu. For building docker images,
diff --git a/init/config-file.json b/init/config-file.json
new file mode 100644 (file)
index 0000000..5478079
--- /dev/null
@@ -0,0 +1,48 @@
+ {
+        "xapp_name": "hwxapp",
+        "version": "1.0.0",
+        "containers": [
+            {
+                "name": "hwxapp",
+                "image": {
+                    "registry": "nexus3.o-ran-sc.org:10002",
+                    "name": "o-ran-sc/ric-app-hw",
+                    "tag": "1.0.6"
+                       }
+            }
+        ],
+        "messaging": {
+            "ports": [
+                {
+                    "name": "rmr-data",
+                    "container": "hwxapp",
+                    "port": 4560,
+                    "rxMessages": [
+                                               "A1_POLICY_REQ", "RIC_HEALTH_CHECK_REQ" 
+                    ],
+                    "txMessages": [ "A1_POLICY_RESP", "A1_POLICY_QUERY", "RIC_HEALTH_CHECK_RESP" ],
+                    "policies": [1],
+                    "description": "rmr receive data port for HWxapp"
+                },
+                {
+                    "name": "rmr-route",
+                    "container": "hwxapp",
+                    "port": 4561,
+                    "description": "rmr route port for hwxapp"
+                }
+            ]
+        },
+        "rmr": {
+            "protPort": "tcp:4560",
+            "maxSize": 2072,
+            "numWorkers": 1,
+            "txMessages": [
+                "RIC_SUB_REQ", "A1_POLICY_RESP", "A1_POLICY_QUERY", "RIC_HEALTH_CHECK_RESP"
+            ],
+            "rxMessages": [
+                "RIC_SUB_RESP", 
+                               "A1_POLICY_REQ", "RIC_HEALTH_CHECK_REQ"              
+            ],
+           "policies": [1]
+        }
+  }
diff --git a/init/init_script.py b/init/init_script.py
new file mode 100644 (file)
index 0000000..f8c9167
--- /dev/null
@@ -0,0 +1,125 @@
+# ==================================================================================
+#
+#       Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
+#
+#   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.
+#
+# ==================================================================================
+
+
+# This initialization script reads in a json from the specified config map path
+# to set up the initializations (route config map, variables etc) for the main
+# xapp process
+
+import json
+import sys
+import os
+import signal
+import time
+
+default_routing_file = "/opt/route/test_route.rt"
+lport = 0
+
+
+def signal_handler(signum, frame):
+    print("Received signal {0}\n".format(signum))
+    if xapp_subprocess is None or xapp_pid is None:
+        print("No xapp running. Quiting without sending signal to xapp\n", flush=True)
+    else:
+        print("Sending signal {0} to xapp ...".format(signum), flush=True)
+        xapp_subprocess.send_signal(signum)
+
+
+def parseConfigJson(config):
+    for k1 in config.keys():
+        if k1 in ParseSection:
+            result = ParseSection[k1](config)
+            if not result:
+                return False
+
+
+def getMessagingInfo(config):
+    global lport
+    if 'messaging' in config.keys() and 'ports' in config['messaging'].keys():
+        port_list = config['messaging']['ports']
+        for portdesc in port_list:
+            if 'port' in portdesc.keys() and 'name' in portdesc.keys() and portdesc['name'] == 'rmr-data':
+                lport = portdesc['port']
+                # Set the environment variable
+                os.environ["HW_PORT"] = str(lport)
+                return True
+    if lport == 0:
+        print("Error! No valid listening port", flush=True)
+        return False
+
+
+def getXappName(config):
+    myKey = "xapp_name"
+    if myKey not in config.keys():
+        print(("Error ! No information found for {0} in config\n".format(myKey)), flush=True)
+        return False
+
+    xapp_name = config[myKey]
+    print("Xapp Name is: " + xapp_name)
+    os.environ["XAPP_NAME"] = xapp_name
+
+
+ParseSection = dict()
+ParseSection["xapp_name"] = getXappName
+ParseSection["messaging"] = getMessagingInfo
+
+# ================================================================
+if __name__ == "__main__":
+
+    import subprocess
+
+    cmd = ["/usr/local/bin/run-hw-python.py"]
+    config_file = os.getenv("CONFIG_FILE", None)
+
+    if config_file is None:
+        print("Error! No configuration file specified\n", flush=True)
+        sys.exit(1)
+
+    with open(config_file, 'r') as f:
+        try:
+            config = json.load(f)
+        except Exception as e:
+            print(("Error loading json file from {0}. Reason = {1}\n".format(config_file, e)), flush=True)
+            sys.exit(1)
+
+    result = parseConfigJson(config)
+    if not result:
+        print("Error parsing config json. Not executing xAPP", flush=True)
+        sys.exit(1)
+
+    else:
+
+        print("Config read successfully", flush=True)
+
+        # Register signal handlers
+        signal.signal(signal.SIGINT, signal_handler)
+        signal.signal(signal.SIGTERM, signal_handler)
+
+        # Start the xAPP
+        print("Executing xAPP ....", flush=True)
+        xapp_subprocess = subprocess.Popen(cmd, shell=False, stdin=None, stdout=None, stderr=None)
+        xapp_pid = xapp_subprocess.pid
+
+        # Periodically poll the process every 5 seconds to check if still alive
+        while 1:
+            xapp_status = xapp_subprocess.poll()
+            if xapp_status is None:
+                time.sleep(5)
+            else:
+                print("XaPP terminated via signal {0}\n".format(-1 * xapp_status), flush=True)
+                break
diff --git a/init/test_route.rt b/init/test_route.rt
new file mode 100644 (file)
index 0000000..8e82103
--- /dev/null
@@ -0,0 +1,5 @@
+newrt|start
+rte|13111|127.0.0.1:4560
+rte|20011|service-ricplt-a1mediator-rmr.ricplt:4562
+rte|20012|service-ricplt-a1mediator-rmr.ricplt:4562
+newrt|end
index 30f55b9..5e6cd44 100644 (file)
@@ -1,3 +1,21 @@
+# ==================================================================================
+#
+#       Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
+#
+#   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.
+#
+# ==================================================================================
+
 apiVersion: v1
 kind: Pod
 metadata:
diff --git a/resources/test_route.rt b/resources/test_route.rt
deleted file mode 100644 (file)
index 7f69614..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-newrt|start
-rte|13111|127.0.0.1:4560
-newrt|end
index 0da755d..e832e67 100644 (file)
--- a/setup.py
+++ b/setup.py
 # ==================================================================================
 
 from setuptools import setup, find_packages
+import os
+
+
+def read(fname):
+    return open(os.path.join(os.path.dirname(__file__), fname)).read()
+
 
 setup(
     name='hw_python',
@@ -23,8 +29,13 @@ setup(
     packages=find_packages(),
     url='https://gerrit.o-ran-sc.org/r/admin/repos/ric-app/hw-python',
     license='Apache 2.0',
+    description="Hello World Python XAPP for O-RAN RIC Platform",
+    long_description=read('README.md'),
+    author='Rahul Banerji',
+    author_email='r.banerji@samsung.com',
+    python_requires='>=3.8',
     install_requires=["ricxappframe>=1.1.1,<2.0.0"],
-    entry_points={"console_scripts": ["run-hw-python.py=src.main:start"]},  # adds a magical entrypoint for Docker
+    entry_points={"console_scripts": ["run-hw-python.py=src.main:launchXapp"]},  # adds a magical entrypoint for Docker
     data_files=[("", ["LICENSE.txt"])],
 )
 
index 4f7e5d5..f035acd 100644 (file)
@@ -13,4 +13,5 @@
 #   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.
+#
 # ==================================================================================
diff --git a/src/handler/A1PolicyHandler.py b/src/handler/A1PolicyHandler.py
new file mode 100644 (file)
index 0000000..b21a0ac
--- /dev/null
@@ -0,0 +1,60 @@
+# ==================================================================================
+#
+#       Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
+#
+#   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 ricxappframe.xapp_frame import RMRXapp, rmr
+from ..utils.constants import Constants
+from ._BaseHandler import _BaseHandler
+
+
+class A1PolicyHandler(_BaseHandler):
+
+    def __init__(self, rmr_xapp: RMRXapp, msgtype):
+        super().__init__(rmr_xapp, msgtype)
+
+    def request_handler(self, rmr_xapp, summary, sbuf):
+        self._rmr_xapp.rmr_free(sbuf)
+        try:
+            req = json.loads(summary[rmr.RMR_MS_PAYLOAD])  # input should be a json encoded as bytes
+            self.logger.debug("A1PolicyHandler.resp_handler:: Handler processing request")
+        except (json.decoder.JSONDecodeError, KeyError):
+            self.logger.error("A1PolicyManager.resp_handler:: Handler failed to parse request")
+            return
+
+        if self.verifyPolicy(req):
+            self.logger.info("A1PolicyHandler.resp_handler:: Handler processed request: {}".format(req))
+        else:
+            self.logger.error("A1PolicyHandler.resp_handler:: Request verification failed: {}".format(req))
+            return
+        self.logger.debug("A1PolicyHandler.resp_handler:: Request verification success: {}".format(req))
+
+        resp = self.buildPolicyResp(req)
+        self._rmr_xapp.rmr_send(json.dumps(resp).encode(), Constants.A1_POLICY_RESP)
+        self.logger.info("A1PolicyHandler.resp_handler:: Response sent: {}".format(resp))
+
+    def verifyPolicy(self, req: dict):
+        for i in ["policy_type_id", "operation", "policy_instance_id"]:
+            if i not in req:
+                return False
+        return True
+
+    def buildPolicyResp(self, req: dict):
+        req["handler_id"] = self._rmr_xapp.config["xapp_name"]
+        del req["operation"]
+        req["status"] = "OK"
+        return req
diff --git a/src/handler/HealthCheckHandler.py b/src/handler/HealthCheckHandler.py
new file mode 100644 (file)
index 0000000..25f7dc9
--- /dev/null
@@ -0,0 +1,38 @@
+#       Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
+#
+#   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 ricxappframe.xapp_frame import RMRXapp
+from ..utils.constants import Constants
+from ._BaseHandler import _BaseHandler
+# from ..manager import SdlAlarmManager
+
+
+class HealthCheckHandler(_BaseHandler):
+
+    def __init__(self, rmr_xapp: RMRXapp, msgtype):
+        super().__init__(rmr_xapp, msgtype)
+        # self.sdl_alarm_mgr = SdlAlarmManager()
+
+    def request_handler(self, rmr_xapp, summary, sbuf):
+        ok = self._rmr_xapp.healthcheck()
+        # self.sdl_alarm_mgr.checkSdl()
+        if ok:
+            payload = b"OK\n"
+        else:
+            payload = b"ERROR [RMR or SDL is unhealthy]\n"
+        self._rmr_xapp.rmr_rts(sbuf, new_payload=payload, new_mtype=Constants.RIC_HEALTH_CHECK_RESP)
+        self._rmr_xapp.rmr_free(sbuf)
diff --git a/src/handler/_BaseHandler.py b/src/handler/_BaseHandler.py
new file mode 100644 (file)
index 0000000..b99ed81
--- /dev/null
@@ -0,0 +1,41 @@
+# ==================================================================================
+#
+#       Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
+#
+#   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 ricxappframe.xapp_frame import RMRXapp
+from abc import ABC, abstractmethod
+
+
+class _BaseHandler(ABC):
+    """
+    Represents base Abstract Handler class
+    Here initialize variables which will be common to all xapp
+
+    Parameters:
+        rmr_xapp: Reference to original RMRxappframe object
+        msgtype: Integer specifying messagetype
+    """
+
+    def __init__(self, rmr_xapp: RMRXapp, msgtype):
+        self._rmr_xapp = rmr_xapp
+        self.logger = self._rmr_xapp.logger
+        self.msgtype = msgtype
+        self._rmr_xapp.register_callback(self.request_handler, msgtype)
+
+    @abstractmethod
+    def request_handler(self, rmr_xapp, summary, sbuf):
+        pass
diff --git a/src/handler/__init__.py b/src/handler/__init__.py
new file mode 100644 (file)
index 0000000..5c7b391
--- /dev/null
@@ -0,0 +1,20 @@
+# ==================================================================================
+#
+#       Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
+#
+#   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 .A1PolicyHandler import A1PolicyHandler
+from .HealthCheckHandler import HealthCheckHandler
diff --git a/src/hwxapp.py b/src/hwxapp.py
new file mode 100644 (file)
index 0000000..7d66d0c
--- /dev/null
@@ -0,0 +1,84 @@
+# ==================================================================================
+#
+#       Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
+#
+#   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 os import getenv
+from ricxappframe.xapp_frame import RMRXapp, rmr
+from .utils.constants import Constants
+from .manager import *
+from .handler import *
+from mdclogpy import Logger
+
+
+class HWXapp:
+
+    def __init__(self):
+        fake_sdl = getenv("USE_FAKE_SDL", False)
+        self._rmr_xapp = RMRXapp(self._default_handler,
+                                 config_handler=self._handle_config_change,
+                                 rmr_port=4560,
+                                 post_init=self._post_init,
+                                 use_fake_sdl=bool(fake_sdl))
+
+    def _post_init(self, rmr_xapp):
+        """
+        Function that runs when xapp initialization is complete
+        """
+        rmr_xapp.logger.info("HWXapp.post_init :: post_init called")
+        # self.sdl_alarm_mgr = SdlAlarmManager()
+        sdl_mgr = SdlManager(rmr_xapp)
+        sdl_mgr.sdlGetGnbList()
+        a1_mgr = A1PolicyManager(rmr_xapp)
+        a1_mgr.startup()
+
+    def _handle_config_change(self, rmr_xapp, config):
+        """
+        Function that runs at start and on every configuration file change.
+        """
+        rmr_xapp.logger.info("HWXapp.handle_config_change:: config: {}".format(config))
+        rmr_xapp.config = config  # No mutex required due to GIL
+
+    def _default_handler(self, rmr_xapp, summary, sbuf):
+        """
+        Function that processes messages for which no handler is defined
+        """
+        rmr_xapp.logger.info("HWXapp.default_handler called for msg type = " +
+                                   str(summary[rmr.RMR_MS_MSG_TYPE]))
+        rmr_xapp.rmr_free(sbuf)
+
+    def createHandlers(self):
+        """
+        Function that creates all the handlers for RMR Messages
+        """
+        HealthCheckHandler(self._rmr_xapp, Constants.RIC_HEALTH_CHECK_REQ)
+        A1PolicyHandler(self._rmr_xapp, Constants.A1_POLICY_REQ)
+
+    def start(self, thread=False):
+        """
+        This is a convenience function that allows this xapp to run in Docker
+        for "real" (no thread, real SDL), but also easily modified for unit testing
+        (e.g., use_fake_sdl). The defaults for this function are for the Dockerized xapp.
+        """
+        self.createHandlers()
+        self._rmr_xapp.run(thread)
+
+    def stop(self):
+        """
+        can only be called if thread=True when started
+        TODO: could we register a signal handler for Docker SIGTERM that calls this?
+        """
+        self._rmr_xapp.stop()
index 10ad0f8..34875b3 100644 (file)
 #   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 os import getenv
-from ricxappframe.xapp_frame import RMRXapp, rmr
-from ricxappframe.alarm import alarm
-
-
-# pylint: disable=invalid-name
-rmr_xapp = None
-
-
-def post_init(self):
-    """
-    Function that runs when xapp initialization is complete
-    """
-    self.logger.info("post_init called")
-
-def handle_config_change(self, config):
-    """
-    Function that runs at start and on every configuration file change.
-    """
-    self.logger.info("handle_config_change: config: {}".format(config))
-
-
-def default_handler(self, summary, sbuf):
-    """
-    Function that processes messages for which no handler is defined
-    """
-    self.logger.info("default_handler called")
-    self.rmr_free(sbuf)
-
+from .hwxapp import HWXapp
 
-def start(thread=False):
-    """
-    This is a convenience function that allows this xapp to run in Docker
-    for "real" (no thread, real SDL), but also easily modified for unit testing
-    (e.g., use_fake_sdl). The defaults for this function are for the Dockerized xapp.
-    """
-    global rmr_xapp
-    fake_sdl = getenv("USE_FAKE_SDL", True)
-    config_file = getenv("CONFIG_FILE", None)
-    rmr_xapp = RMRXapp(default_handler,
-                       config_handler=handle_config_change,
-                       rmr_port=4560,
-                       post_init=post_init,
-                       use_fake_sdl=bool(fake_sdl))
-    rmr_xapp.run(thread)
 
+def launchXapp():
+    hwxapp = HWXapp()
+    hwxapp.start()
 
-def stop():
-    """
-    can only be called if thread=True when started
-    TODO: could we register a signal handler for Docker SIGTERM that calls this?
-    """
-    rmr_xapp.stop()
 
 if __name__ == "__main__":
-    start()
+    launchXapp()
diff --git a/src/manager/A1PolicyManager.py b/src/manager/A1PolicyManager.py
new file mode 100644 (file)
index 0000000..57c6760
--- /dev/null
@@ -0,0 +1,34 @@
+# ==================================================================================
+#
+#       Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
+#
+#   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 ricxappframe.xapp_frame import RMRXapp, rmr
+from ..utils.constants import Constants
+from ._BaseManager import _BaseManager
+
+
+class A1PolicyManager(_BaseManager):
+
+    def __init__(self, rmr_xapp: RMRXapp):
+        super().__init__(rmr_xapp)
+
+    def startup(self):
+        policy_query = '{"policy_type_id":"' + str(Constants.HELLOWORLD_POLICY_ID) + '"}'
+        self._rmr_xapp.rmr_send(policy_query.encode(), Constants.A1_POLICY_QUERY)
+        self.logger.info("A1PolicyManager.startup:: Sent A1 policy query = " + policy_query)
+
diff --git a/src/manager/SdlAlarmManager.py b/src/manager/SdlAlarmManager.py
new file mode 100644 (file)
index 0000000..dc5bd7b
--- /dev/null
@@ -0,0 +1,48 @@
+# ==================================================================================
+#
+#       Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
+#
+#   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 ricxappframe.xapp_frame import RMRXapp
+from ricxappframe.alarm import alarm
+from ._BaseManager import _BaseManager
+
+
+# noinspection PyProtectedMember,PyProtectedMember
+class SdlAlarmManager(_BaseManager):
+
+    def __init__(self, rmr_xapp: RMRXapp):
+        super().__init__(rmr_xapp)
+        self.alarm_mgr = alarm.AlarmManager(self._rmr_xapp._mrc, "ric-xapp", "hw-python")
+        self.alarm_sdl = None
+
+    def checkSdl(self):
+        if self._rmr_xapp._sdl.healthcheck():
+            # healthy, so clear the alarm if it was raised
+            if self.alarm_sdl:
+                self.logger.info("SdlAlarmManager:: clearing alarm")
+                self.alarm_mgr.clear_alarm(self.alarm_sdl)
+                self.alarm_sdl = None
+        else:
+            # not healthy, so (re-)raise the alarm
+            self.logger.info("SdlAlarmManager:: connection to SDL is not healthy, raising alarm")
+            if self.alarm_sdl:
+                self.alarm_mgr.reraise_alarm(self.alarm_sdl)
+            else:
+                self.alarm_sdl = self.alarm_mgr.create_alarm(1, alarm.AlarmSeverity.CRITICAL,
+                                                             "SdlAlarmManager:: SDL failure")
+                self.alarm_mgr.raise_alarm(self.alarm_sdl)
+            self.logger.warning("SdlAlarmManager:: dropping request!")
diff --git a/src/manager/SdlManager.py b/src/manager/SdlManager.py
new file mode 100644 (file)
index 0000000..827e8f4
--- /dev/null
@@ -0,0 +1,41 @@
+# ==================================================================================
+#
+#       Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
+#
+#   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 ricxappframe.xapp_frame import RMRXapp
+import json
+from ._BaseManager import _BaseManager
+
+
+class SdlManager(_BaseManager):
+
+    __namespace = "e2Manager"
+
+    def __init__(self, rmr_xapp: RMRXapp):
+        super().__init__(rmr_xapp)
+
+    def sdlGetGnbList(self):
+        gnblist = self._rmr_xapp.sdl_find_and_get(self.__namespace, "GNB")
+        self.logger.info("SdlManager.sdlGetGnbList:: Processed request: {}".format(json.dumps(gnblist)))
+
+    def sdlGetEnbList(self):
+        enblist = self._rmr_xapp.sdl_find_and_get(self.__namespace, "ENB")
+        self.logger.info("SdlManager.sdlGetGnbList:: Handler processed request: {}".format(json.dumps(enblist)))
+
+
+
+
diff --git a/src/manager/_BaseManager.py b/src/manager/_BaseManager.py
new file mode 100644 (file)
index 0000000..be8df7c
--- /dev/null
@@ -0,0 +1,33 @@
+# ==================================================================================
+#
+#       Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
+#
+#   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 ricxappframe.xapp_frame import RMRXapp
+from abc import ABC
+
+
+class _BaseManager(ABC):
+    """
+    Represents base Manager Abstract class
+    Here initialize variables which will be common to all xapp
+
+    Parameters:
+        rmr_xapp: Reference to original RMRxappframe object
+    """
+    def __init__(self, rmr_xapp: RMRXapp):
+        self._rmr_xapp = rmr_xapp
+        self.logger = self._rmr_xapp.logger
diff --git a/src/manager/__init__.py b/src/manager/__init__.py
new file mode 100644 (file)
index 0000000..54b63c3
--- /dev/null
@@ -0,0 +1,21 @@
+# ==================================================================================
+#
+#       Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
+#
+#   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 .A1PolicyManager import A1PolicyManager
+from .SdlAlarmManager import SdlAlarmManager
+from .SdlManager import SdlManager
diff --git a/src/utils/__init__.py b/src/utils/__init__.py
new file mode 100644 (file)
index 0000000..f035acd
--- /dev/null
@@ -0,0 +1,17 @@
+# ==================================================================================
+#
+#       Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
+#
+#   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.
+#
+# ==================================================================================
diff --git a/src/utils/constants.py b/src/utils/constants.py
new file mode 100644 (file)
index 0000000..55c12e2
--- /dev/null
@@ -0,0 +1,26 @@
+# ==================================================================================
+#
+#       Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
+#
+#   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.
+#
+# ==================================================================================
+
+class Constants:
+    A1_POLICY_QUERY = 20012
+    HELLOWORLD_POLICY_ID = 2
+    RIC_HEALTH_CHECK_REQ = 100
+    RIC_HEALTH_CHECK_RESP = 101
+    A1_POLICY_REQ = 20010
+    A1_POLICY_RESP = 20011
+    RIC_ALARM_UPDATE = 110