3 # Copyright 2016 RIFT.IO Inc
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
23 gi
.require_version('RwNsdYang', '1.0')
24 gi
.require_version('RwVnfdYang', '1.0')
25 gi
.require_version('RwYang', '1.0')
26 from gi
.repository
import (
35 class UnknownExtensionError(Exception):
39 class SerializationError(Exception):
43 def decode(desc_data
):
44 if isinstance(desc_data
, bytes
):
45 desc_data
= desc_data
.decode()
50 class ProtoMessageSerializer(object):
51 """(De)Serializer/deserializer fo a specific protobuf message into various formats"""
54 def __init__(self
, yang_ns
, yang_pb_cls
):
55 """ Create a serializer for a specific protobuf message """
56 self
._yang
_ns
= yang_ns
57 self
._yang
_pb
_cls
= yang_pb_cls
60 def _deserialize_extension_method_map(cls
):
62 ".xml": cls
._from
_xml
_file
_hdl
,
63 ".yml": cls
._from
_yaml
_file
_hdl
,
64 ".yaml": cls
._from
_yaml
_file
_hdl
,
65 ".json": cls
._from
_json
_file
_hdl
,
69 def _serialize_extension_method_map(cls
):
71 ".xml": cls
.to_xml_string
,
72 ".yml": cls
.to_yaml_string
,
73 ".yaml": cls
.to_yaml_string
,
74 ".json": cls
.to_json_string
,
78 def is_supported_file(cls
, filename
):
79 """Returns whether a file has a supported file extension
82 filename - A descriptor file
85 True if file extension is supported, False otherwise
88 _
, extension
= os
.path
.splitext(filename
)
89 extension_lc
= extension
.lower()
91 return extension_lc
in cls
._deserialize
_extension
_method
_map
()
94 def yang_namespace(self
):
95 """ The Protobuf's GI namespace class (e.g. RwVnfdYang) """
100 """ The Protobuf's GI class (e.g. RwVnfdYang.YangData_Vnfd_VnfdCatalog_Vnfd) """
101 return self
._yang
_pb
_cls
107 # Cache the libncx model for the serializer class
108 if cls
.libncx_model
is None:
109 cls
.libncx_model
= RwYang
.model_create_libncx()
110 cls
.libncx_model
.load_schema_ypbc(self
.yang_namespace
.get_schema())
112 return cls
.libncx_model
114 def _from_xml_file_hdl(self
, file_hdl
):
115 xml
= file_hdl
.read()
117 return self
.yang_class
.from_xml_v2(self
.model
, decode(xml
), strict
=False)
119 def _from_json_file_hdl(self
, file_hdl
):
120 json
= file_hdl
.read()
122 return self
.yang_class
.from_json(self
.model
, decode(json
), strict
=False)
124 def _from_yaml_file_hdl(self
, file_hdl
):
125 yaml
= file_hdl
.read()
127 return self
.yang_class
.from_yaml(self
.model
, decode(yaml
), strict
=False)
129 def to_json_string(self
, pb_msg
):
130 """ Serialize a protobuf message into JSON
133 pb_msg - A GI-protobuf object of type provided into constructor
136 A JSON string representing the protobuf message
139 SerializationError - Message could not be serialized
140 TypeError - Incorrect protobuf type provided
142 if not isinstance(pb_msg
, self
._yang
_pb
_cls
):
143 raise TypeError("Invalid protobuf message type provided")
146 json_str
= pb_msg
.to_json(self
.model
)
148 except Exception as e
:
149 raise SerializationError(e
)
153 def to_yaml_string(self
, pb_msg
):
154 """ Serialize a protobuf message into YAML
157 pb_msg - A GI-protobuf object of type provided into constructor
160 A YAML string representing the protobuf message
163 SerializationError - Message could not be serialized
164 TypeError - Incorrect protobuf type provided
166 if not isinstance(pb_msg
, self
._yang
_pb
_cls
):
167 raise TypeError("Invalid protobuf message type provided")
170 yaml_str
= pb_msg
.to_yaml(self
.model
)
172 except Exception as e
:
173 raise SerializationError(e
)
177 def to_xml_string(self
, pb_msg
):
178 """ Serialize a protobuf message into XML
181 pb_msg - A GI-protobuf object of type provided into constructor
184 A XML string representing the protobuf message
187 SerializationError - Message could not be serialized
188 TypeError - Incorrect protobuf type provided
190 if not isinstance(pb_msg
, self
._yang
_pb
_cls
):
191 raise TypeError("Invalid protobuf message type provided")
194 xml_str
= pb_msg
.to_xml_v2(self
.model
)
196 except Exception as e
:
197 raise SerializationError(e
)
201 def from_file_hdl(self
, file_hdl
, extension
):
202 """ Returns the deserialized protobuf message from file contents
204 This function determines the serialization format based on file extension
207 file_hdl - The file hdl to deserialize (set at pos 0)
208 extension - Extension of the file format (second item of os.path.splitext())
211 A GI-Proto message of type that was provided into the constructor
214 UnknownExtensionError - File extension is not of a known serialization format
215 SerializationError - File failed to be deserialized into the protobuf message
218 extension_lc
= extension
.lower()
219 extension_map
= self
._deserialize
_extension
_method
_map
()
221 if extension_lc
not in extension_map
:
222 raise UnknownExtensionError("Cannot detect message format for %s extension" % extension_lc
)
225 msg
= extension_map
[extension_lc
](self
, file_hdl
)
226 except Exception as e
:
227 raise SerializationError(e
)
231 def to_string(self
, pb_msg
, extension
):
232 """ Returns the serialized protobuf message for a particular file extension
234 This function determines the serialization format based on file extension
237 pb_msg - A GI-protobuf object of type provided into constructor
238 extension - Extension of the file format (second item of os.path.splitext())
241 A GI-Proto message of type that was provided into the constructor
244 UnknownExtensionError - File extension is not of a known serialization format
245 SerializationError - File failed to be deserialized into the protobuf message
248 extension_lc
= extension
.lower()
249 extension_map
= self
._serialize
_extension
_method
_map
()
251 if extension_lc
not in extension_map
:
252 raise UnknownExtensionError("Cannot detect message format for %s extension" % extension_lc
)
255 msg
= extension_map
[extension_lc
](self
, pb_msg
)
256 except Exception as e
:
257 raise SerializationError(e
)
262 class VnfdSerializer(ProtoMessageSerializer
):
263 """ Creates a serializer for the VNFD descriptor"""
265 super().__init
__(VnfdYang
, VnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd
)
268 class NsdSerializer(ProtoMessageSerializer
):
269 """ Creates a serializer for the NSD descriptor"""
271 super().__init
__(NsdYang
, NsdYang
.YangData_Nsd_NsdCatalog_Nsd
)
274 class RwVnfdSerializer(ProtoMessageSerializer
):
275 """ Creates a serializer for the VNFD descriptor"""
277 super().__init
__(RwVnfdYang
, RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd
)
280 class RwNsdSerializer(ProtoMessageSerializer
):
281 """ Creates a serializer for the NSD descriptor"""
283 super().__init
__(RwNsdYang
, RwNsdYang
.YangData_Nsd_NsdCatalog_Nsd
)