Issue ID: RIC-791 63/6163/1
authorSangeetha KR <sangeetha-kr@hcl.com>
Sun, 30 May 2021 19:22:03 +0000 (00:52 +0530)
committerSangeetha KR <sangeetha-kr@hcl.com>
Sun, 30 May 2021 19:22:03 +0000 (00:52 +0530)
     Push Dockerfile to staging repo
     Updated tag for container-release-it-test-nanobot.yaml
     Updated Dockerfile
     Updated Container-tag.yaml
     Fixed KubernetesEntity
     Added SDLWrappper

Signed-off-by: Sangeetha KR <sangeetha-kr@hcl.com>
Change-Id: I420300879aaecfd380ec2a415222c44b2ae38820

releases/container-release-it-test-nanobot.yaml
ric_robot_suite/docker/nanobot/Dockerfile
ric_robot_suite/docker/nanobot/container-tag.yaml
ric_robot_suite/ric-python-utils/ricutils/KubernetesEntity.py
ric_robot_suite/ric-python-utils/ricutils/SDLWrapper.py [new file with mode: 0644]

index 7ea03bc..aa32d54 100644 (file)
@@ -7,4 +7,4 @@ project: it/test
 ref: e3a2b6fed94e2caab5f9f2424beace6e4cea0013
 containers:
     - name: it-test-nanobot
-      version: 0.0.3
+      version: 0.0.4
index 3d57ad5..e4d04cc 100644 (file)
@@ -1,17 +1,3 @@
-   #   Copyright (c)  2019 AT&T Intellectual Property.
-   #   Copyright (c)  2020 HCL Technologies.
-   #   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 python:3.8-alpine AS nanobot-build
 
    RUN apk update && apk add --no-cache git build-base libffi-dev libxml2 libxslt libxml2-dev libxslt-dev openssl-dev
@@ -47,8 +33,8 @@
         cd build && \
         cmake -DPACK_EXTERNALS=1 -DDEV_PKG=1 .. && \
         make install
-   RUN  mkdir -p /opt/e2
-   RUN  cp /rmr/build/src/support/rmr_probe /opt/e2/
+   #RUN  mkdir -p /opt/e2
+   #RUN  cp /rmr/build/src/support/rmr_probe /opt/e2/
 
 
 
    COPY --from=nanobot-build /usr/local/bin/robot /usr/local/bin
 
    RUN apk add wget
-   RUN  mkdir -p /robot/lib/python
-   WORKDIR ric-python-utils/ricutils
-   RUN wget -o SDLWrapper.py "https://gerrit.o-ran-sc.org/r/gitweb?p=ric-plt/xapp-frame-py.git;a=blob_plain;f=ricxappframe/xapp_sdl.py"
+   RUN mkdir -p /robot/lib/python
+   RUN mkdir -p /opt/e2
+   #WORKDIR ric-python-utils/ricutils
+   #RUN wget -o SDLWrapper.py "https://gerrit.o-ran-sc.org/r/gitweb?p=ric-plt/xapp-frame-py.git;a=blob_plain;f=ricxappframe/xapp_sdl.py"
    # ONAP eteutils
    # we only need a few things from this so we won't install the whole thing.
+   COPY ric-python-utils/ricutils/KubernetesEntity.py /robot/lib/python
+   COPY ric-python-utils/ricutils/SDLWrapper.py /robot/lib/python
+   COPY --from=nanobot-build /rmr/build/src/support/rmr_probe /opt/e2
    COPY --from=nanobot-build /tmp/python-testing-utils/eteutils/StringTemplater.py /robot/lib/python
    COPY --from=nanobot-build /tmp/python-testing-utils/eteutils/UUID.py /robot/lib/python
    COPY ric-python-utils/ricutils/*.py /robot/lib/python/
 
    WORKDIR /
    CMD ["sleep", "9125d"]
-
index 74bddb3..ad34f17 100644 (file)
@@ -53,7 +53,7 @@ class KubernetesEntity(object):
   # that the typical check here sfst.replicas == sfst.ready_replicas
   return self._k8sApp.read_namespaced_stateful_set(namespace = namespace or self._ns,
                                                    name=name)
+
  def Service(self, name, namespace=None):
   # as above, we'll rely on this to throw if the svc dne.
 
@@ -98,7 +98,7 @@ class KubernetesEntity(object):
   d = self.Deployment(name, namespace or self._ns)
   labels = d.spec.selector.match_labels
   pods = self._k8sCore.list_namespaced_pod(namespace or self._ns,
-                                           label_selector=",".join(map(lambda k: k + "=" + labels[k], 
+                                           label_selector=",".join(map(lambda k: k + "=" + labels[k],
                                                                        labels)))
   return list(map(lambda i: i.metadata.name, pods.items))
 
@@ -122,7 +122,7 @@ class KubernetesEntity(object):
    # after performance here.
    ctx=ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
    c = client.Configuration()
-   
+
    async def ExecCoroutine():
       # base64.channel.k8s.io is also a valid subprotocol, but i don't see any
       # reason to support it.
@@ -136,12 +136,12 @@ class KubernetesEntity(object):
              # i really don't want to be bothered with asyncio exception handling
              # for that vanishingly improbable case.
              output[channels[message[0]]].extend(message[1:-1].decode('utf-8').split('\n'))
-            
+
    ctx.load_verify_locations(c.ssl_ca_cert)
    if(c.cert_file and c.key_file):
      ctx.load_cert_chain(c.cert_file, c.key_file)
    uri = 'wss://%s%s' % (c.host.lstrip('https://'), path)
 
    asyncio.get_event_loop().run_until_complete(ExecCoroutine())
-  
+
    return(output)
diff --git a/ric_robot_suite/ric-python-utils/ricutils/SDLWrapper.py b/ric_robot_suite/ric-python-utils/ricutils/SDLWrapper.py
new file mode 100644 (file)
index 0000000..ece4a95
--- /dev/null
@@ -0,0 +1,174 @@
+# ==================================================================================
+#       Copyright (c) 2020 Nokia
+#       Copyright (c) 2020 AT&T Intellectual Property.
+#
+#   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.
+# ==================================================================================
+
+"""
+sdl functionality
+"""
+
+import msgpack
+from ricsdl.syncstorage import SyncStorage
+
+class SDLWrapper:
+    """
+    Provides convenient wrapper methods for using the SDL Python interface.
+    Optionally uses msgpack for binary (de)serialization:
+    see https://msgpack.org/index.html
+
+    Published as a standalone module (and kept separate from the Xapp
+    framework classes) so these features can be used outside Xapps.
+    """
+
+    def __init__(self, use_fake_sdl=False):
+        """
+        init
+
+        Parameters
+        ----------
+        use_fake_sdl: bool (optional, default False)
+            if this is True, then use SDL's in-memory backend,
+            which is very useful for testing since it allows use
+            of SDL without a running SDL or Redis instance.
+            This can be used while developing an xapp and also
+            for monkeypatching during unit testing; e.g., the xapp
+            framework unit tests do this.
+        """
+        if use_fake_sdl:
+            self._sdl = SyncStorage(fake_db_backend="dict")
+        else:
+            self._sdl = SyncStorage()
+
+
+    def set(self, ns, key, value, usemsgpack=True):
+        """
+        Stores a key-value pair,
+        optionally serializing the value to bytes using msgpack.
+
+        TODO: discuss whether usemsgpack should *default* to True or
+        False here. This seems like a usage statistic question (that we
+        don't have enough data for yet). Are more uses for an xapp to
+        write/read their own data, or will more xapps end up reading data
+        written by some other thing? I think it's too early to know.
+
+        Parameters
+        ----------
+        ns: string
+            SDL namespace
+        key: string
+            SDL key
+        value:
+            Object or byte array to store.  See the `usemsgpack` parameter.
+        usemsgpack: boolean (optional, default is True)
+            Determines whether the value is serialized using msgpack before storing.
+            If usemsgpack is True, the msgpack function `packb` is invoked
+            on the value to yield a byte array that is then sent to SDL.
+            Stated differently, if usemsgpack is True, the value can be anything
+            that is serializable by msgpack.
+            If usemsgpack is False, the value must be bytes.
+        """
+        if usemsgpack:
+            value = msgpack.packb(value, use_bin_type=True)
+        self._sdl.set(ns, {key: value})
+
+    def get(self, ns, key, usemsgpack=True):
+        """
+        Gets the value for the specified namespace and key,
+        optionally deserializing stored bytes using msgpack.
+
+        Parameters
+        ----------
+        ns: string
+            SDL namespace
+        key: string
+            SDL key
+        usemsgpack: boolean (optional, default is True)
+            If usemsgpack is True, the byte array stored by SDL is deserialized
+            using msgpack to yield the original object that was stored.
+            If usemsgpack is False, the byte array stored by SDL is returned
+            without further processing.
+
+        Returns
+        -------
+        Value
+            See the usemsgpack parameter for an explanation of the returned value type.
+            Answers None if the key is not found.
+        """
+        result = None
+        ret_dict = self._sdl.get(ns, {key})
+        if key in ret_dict:
+            result = ret_dict[key]
+            if usemsgpack:
+                result = msgpack.unpackb(result, raw=False)
+        return result
+
+    def find_and_get(self, ns, prefix, usemsgpack=True):
+        """
+        Gets all key-value pairs in the specified namespace
+        with keys that start with the specified prefix,
+        optionally deserializing stored bytes using msgpack.
+
+        Parameters
+        ----------
+        ns: string
+           SDL namespace
+        prefix: string
+            the key prefix
+        usemsgpack: boolean (optional, default is True)
+            If usemsgpack is True, every byte array stored by SDL is deserialized
+            using msgpack to yield the original value that was stored.
+            If usemsgpack is False, every byte array stored by SDL is returned
+            without further processing.
+
+        Returns
+        -------
+        Dictionary of key-value pairs
+            Each key has the specified prefix.
+            See the usemsgpack parameter for an explanation of the returned value types.
+            Answers an empty dictionary if no keys matched the prefix.
+        """
+
+        # note: SDL "*" usage is inconsistent with real python regex, where it would be ".*"
+        ret_dict = self._sdl.find_and_get(ns, "{0}*".format(prefix))
+        if usemsgpack:
+            ret_dict = {k: msgpack.unpackb(v, raw=False) for k, v in ret_dict.items()}
+        return ret_dict
+
+    def delete(self, ns, key):
+        """
+        Deletes the key-value pair with the specified key in the specified namespace.
+
+        Parameters
+        ----------
+        ns: string
+           SDL namespace
+        key: string
+            SDL key
+        """
+        self._sdl.remove(ns, {key})
+
+
+    def healthcheck(self):
+        """
+        Checks if the sdl connection is healthy.
+
+        Returns
+        -------
+        bool
+        """
+        return self._sdl.is_active()
+        #if self._sdl.is_active():
+         #   return True
+        #return False