RIFT OSM R1 Initial Submission
[osm/SO.git] / rwlaunchpad / plugins / rwlaunchpadtasklet / rift / package / convert.py
diff --git a/rwlaunchpad/plugins/rwlaunchpadtasklet/rift/package/convert.py b/rwlaunchpad/plugins/rwlaunchpadtasklet/rift/package/convert.py
new file mode 100644 (file)
index 0000000..7571c57
--- /dev/null
@@ -0,0 +1,283 @@
+
+# 
+#   Copyright 2016 RIFT.IO 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 os
+import tempfile
+
+import gi
+gi.require_version('RwNsdYang', '1.0')
+gi.require_version('RwVnfdYang', '1.0')
+gi.require_version('RwYang', '1.0')
+from gi.repository import (
+        RwNsdYang,
+        RwVnfdYang,
+        NsdYang,
+        VnfdYang,
+        RwYang,
+        )
+
+
+class UnknownExtensionError(Exception):
+    pass
+
+
+class SerializationError(Exception):
+    pass
+
+
+def decode(desc_data):
+    if isinstance(desc_data, bytes):
+        desc_data = desc_data.decode()
+
+    return desc_data
+
+
+class ProtoMessageSerializer(object):
+    """(De)Serializer/deserializer fo a specific protobuf message into various formats"""
+    libncx_model = None
+
+    def __init__(self, yang_ns, yang_pb_cls):
+        """ Create a serializer for a specific protobuf message """
+        self._yang_ns = yang_ns
+        self._yang_pb_cls = yang_pb_cls
+
+    @classmethod
+    def _deserialize_extension_method_map(cls):
+        return {
+                ".xml": cls._from_xml_file_hdl,
+                ".yml": cls._from_yaml_file_hdl,
+                ".yaml": cls._from_yaml_file_hdl,
+                ".json": cls._from_json_file_hdl,
+                }
+
+    @classmethod
+    def _serialize_extension_method_map(cls):
+        return {
+                ".xml": cls.to_xml_string,
+                ".yml": cls.to_yaml_string,
+                ".yaml": cls.to_yaml_string,
+                ".json": cls.to_json_string,
+                }
+
+    @classmethod
+    def is_supported_file(cls, filename):
+        """Returns whether a file has a supported file extension
+
+        Arguments:
+            filename - A descriptor file
+
+        Returns:
+            True if file extension is supported, False otherwise
+
+        """
+        _, extension = os.path.splitext(filename)
+        extension_lc = extension.lower()
+
+        return extension_lc in cls._deserialize_extension_method_map()
+
+    @property
+    def yang_namespace(self):
+        """ The Protobuf's GI namespace class (e.g. RwVnfdYang) """
+        return self._yang_ns
+
+    @property
+    def yang_class(self):
+        """ The Protobuf's GI class (e.g. RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd) """
+        return self._yang_pb_cls
+
+    @property
+    def model(self):
+        cls = self.__class__
+
+        # Cache the libncx model for the serializer class
+        if cls.libncx_model is None:
+            cls.libncx_model = RwYang.model_create_libncx()
+            cls.libncx_model.load_schema_ypbc(self.yang_namespace.get_schema())
+
+        return cls.libncx_model
+
+    def _from_xml_file_hdl(self, file_hdl):
+        xml = file_hdl.read()
+
+        return self.yang_class.from_xml_v2(self.model, decode(xml), strict=False)
+
+    def _from_json_file_hdl(self, file_hdl):
+        json = file_hdl.read()
+
+        return self.yang_class.from_json(self.model, decode(json), strict=False)
+
+    def _from_yaml_file_hdl(self, file_hdl):
+        yaml = file_hdl.read()
+
+        return self.yang_class.from_yaml(self.model, decode(yaml), strict=False)
+
+    def to_json_string(self, pb_msg):
+        """ Serialize a protobuf message into JSON
+
+        Arguments:
+            pb_msg - A GI-protobuf object of type provided into constructor
+
+        Returns:
+            A JSON string representing the protobuf message
+
+        Raises:
+            SerializationError - Message could not be serialized
+            TypeError - Incorrect protobuf type provided
+        """
+        if not isinstance(pb_msg, self._yang_pb_cls):
+            raise TypeError("Invalid protobuf message type provided")
+
+        try:
+            json_str = pb_msg.to_json(self.model)
+
+        except Exception as e:
+            raise SerializationError(e)
+
+        return json_str
+
+    def to_yaml_string(self, pb_msg):
+        """ Serialize a protobuf message into YAML
+
+        Arguments:
+            pb_msg - A GI-protobuf object of type provided into constructor
+
+        Returns:
+            A YAML string representing the protobuf message
+
+        Raises:
+            SerializationError - Message could not be serialized
+            TypeError - Incorrect protobuf type provided
+        """
+        if not isinstance(pb_msg, self._yang_pb_cls):
+            raise TypeError("Invalid protobuf message type provided")
+
+        try:
+            yaml_str = pb_msg.to_yaml(self.model)
+
+        except Exception as e:
+            raise SerializationError(e)
+
+        return yaml_str
+
+    def to_xml_string(self, pb_msg):
+        """ Serialize a protobuf message into XML
+
+        Arguments:
+            pb_msg - A GI-protobuf object of type provided into constructor
+
+        Returns:
+            A XML string representing the protobuf message
+
+        Raises:
+            SerializationError - Message could not be serialized
+            TypeError - Incorrect protobuf type provided
+        """
+        if not isinstance(pb_msg, self._yang_pb_cls):
+            raise TypeError("Invalid protobuf message type provided")
+
+        try:
+            xml_str = pb_msg.to_xml_v2(self.model)
+
+        except Exception as e:
+            raise SerializationError(e)
+
+        return xml_str
+
+    def from_file_hdl(self, file_hdl, extension):
+        """ Returns the deserialized protobuf message from file contents
+
+        This function determines the serialization format based on file extension
+
+        Arguments:
+            file_hdl - The file hdl to deserialize (set at pos 0)
+            extension - Extension of the file format (second item of os.path.splitext())
+
+        Returns:
+            A GI-Proto message of type that was provided into the constructor
+
+        Raises:
+            UnknownExtensionError - File extension is not of a known serialization format
+            SerializationError - File failed to be deserialized into the protobuf message
+        """
+
+        extension_lc = extension.lower()
+        extension_map = self._deserialize_extension_method_map()
+
+        if extension_lc not in extension_map:
+            raise UnknownExtensionError("Cannot detect message format for %s extension" % extension_lc)
+
+        try:
+            msg = extension_map[extension_lc](self, file_hdl)
+        except Exception as e:
+            raise SerializationError(e)
+
+        return msg
+
+    def to_string(self, pb_msg, extension):
+        """ Returns the serialized protobuf message for a particular file extension
+
+        This function determines the serialization format based on file extension
+
+        Arguments:
+            pb_msg - A GI-protobuf object of type provided into constructor
+            extension - Extension of the file format (second item of os.path.splitext())
+
+        Returns:
+            A GI-Proto message of type that was provided into the constructor
+
+        Raises:
+            UnknownExtensionError - File extension is not of a known serialization format
+            SerializationError - File failed to be deserialized into the protobuf message
+        """
+
+        extension_lc = extension.lower()
+        extension_map = self._serialize_extension_method_map()
+
+        if extension_lc not in extension_map:
+            raise UnknownExtensionError("Cannot detect message format for %s extension" % extension_lc)
+
+        try:
+            msg = extension_map[extension_lc](self, pb_msg)
+        except Exception as e:
+            raise SerializationError(e)
+
+        return msg
+
+
+class VnfdSerializer(ProtoMessageSerializer):
+    """ Creates a serializer for the VNFD descriptor"""
+    def __init__(self):
+        super().__init__(VnfdYang, VnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd)
+
+
+class NsdSerializer(ProtoMessageSerializer):
+    """ Creates a serializer for the NSD descriptor"""
+    def __init__(self):
+        super().__init__(NsdYang, NsdYang.YangData_Nsd_NsdCatalog_Nsd)
+
+
+class RwVnfdSerializer(ProtoMessageSerializer):
+    """ Creates a serializer for the VNFD descriptor"""
+    def __init__(self):
+        super().__init__(RwVnfdYang, RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd)
+
+
+class RwNsdSerializer(ProtoMessageSerializer):
+    """ Creates a serializer for the NSD descriptor"""
+    def __init__(self):
+        super().__init__(RwNsdYang, RwNsdYang.YangData_Nsd_NsdCatalog_Nsd)