Skip to content
Snippets Groups Projects
Commit e871a09e authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Common:

- updated generic descriptor loader tool
- updated scenario loader for automated tests
parent 5ae72c8e
No related branches found
No related tags found
2 merge requests!54Release 2.0.0,!27New Descriptor Loader Framework and OFC'22 code migrations
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import json, logging import logging
from common.tools.descriptor.Loader import DescriptorLoader, compose_notifications from common.tools.descriptor.Loader import DescriptorLoader, compose_notifications
from context.client.ContextClient import ContextClient from context.client.ContextClient import ContextClient
from device.client.DeviceClient import DeviceClient from device.client.DeviceClient import DeviceClient
...@@ -29,15 +29,15 @@ LOGGERS = { ...@@ -29,15 +29,15 @@ LOGGERS = {
def load_scenario_from_descriptor( def load_scenario_from_descriptor(
descriptor_file : str, context_client : ContextClient, device_client : DeviceClient, descriptor_file : str, context_client : ContextClient, device_client : DeviceClient,
service_client : ServiceClient, slice_client : SliceClient service_client : ServiceClient, slice_client : SliceClient
) -> None: ) -> DescriptorLoader:
with open(descriptor_file, 'r', encoding='UTF-8') as f: with open(descriptor_file, 'r', encoding='UTF-8') as f:
descriptors = json.loads(f.read()) descriptors = f.read()
descriptor_loader = DescriptorLoader( descriptor_loader = DescriptorLoader(
descriptors,
context_client=context_client, device_client=device_client, context_client=context_client, device_client=device_client,
service_client=service_client, slice_client=slice_client) service_client=service_client, slice_client=slice_client)
descriptor_loader.process_descriptors(descriptors) results = descriptor_loader.process()
results = descriptor_loader.get_results()
num_errors = 0 num_errors = 0
for message,level in compose_notifications(results): for message,level in compose_notifications(results):
...@@ -46,3 +46,5 @@ def load_scenario_from_descriptor( ...@@ -46,3 +46,5 @@ def load_scenario_from_descriptor(
if num_errors > 0: if num_errors > 0:
MSG = 'Failed to load descriptors in file {:s}' MSG = 'Failed to load descriptors in file {:s}'
raise Exception(MSG.format(str(descriptor_file))) raise Exception(MSG.format(str(descriptor_file)))
return descriptor_loader
\ No newline at end of file
...@@ -16,25 +16,23 @@ ...@@ -16,25 +16,23 @@
# Usage example (WebUI): # Usage example (WebUI):
# descriptors = json.loads(descriptors_data_from_client) # descriptors = json.loads(descriptors_data_from_client)
# # descriptor_loader = DescriptorLoader(descriptors)
# descriptor_loader = DescriptorLoader() # results = descriptor_loader.process()
# descriptor_loader.process_descriptors(descriptors)
# results = descriptor_loader.get_results()
# for message,level in compose_notifications(results): # for message,level in compose_notifications(results):
# flash(message, level) # flash(message, level)
# Usage example (pytest): # Usage example (pytest):
# with open('path/to/descriptor.json', 'r', encoding='UTF-8') as f: # with open('path/to/descriptor.json', 'r', encoding='UTF-8') as f:
# descriptors = json.loads(f.read()) # descriptors = json.loads(f.read())
# # descriptor_loader = DescriptorLoader(
# descriptor_loader = DescriptorLoader() # descriptors, context_client=..., device_client=..., service_client=..., slice_client=...)
# descriptor_loader.process_descriptors(descriptors) # results = descriptor_loader.process()
# results = descriptor_loader.get_results()
# loggers = {'success': LOGGER.info, 'danger': LOGGER.error, 'error': LOGGER.error} # loggers = {'success': LOGGER.info, 'danger': LOGGER.error, 'error': LOGGER.error}
# for message,level in compose_notifications(results): # for message,level in compose_notifications(results):
# loggers.get(level)(message) # loggers.get(level)(message)
from typing import Dict, List, Optional, Tuple import json
from typing import Dict, List, Optional, Tuple, Union
from common.proto.context_pb2 import Connection, Context, Device, Link, Service, Slice, Topology from common.proto.context_pb2 import Connection, Context, Device, Link, Service, Slice, Topology
from context.client.ContextClient import ContextClient from context.client.ContextClient import ContextClient
from device.client.DeviceClient import DeviceClient from device.client.DeviceClient import DeviceClient
...@@ -81,41 +79,107 @@ def compose_notifications(results : TypeResults) -> TypeNotificationList: ...@@ -81,41 +79,107 @@ def compose_notifications(results : TypeResults) -> TypeNotificationList:
class DescriptorLoader: class DescriptorLoader:
def __init__( def __init__(
self, context_client : Optional[ContextClient] = None, device_client : Optional[DeviceClient] = None, self, descriptors : Union[str, Dict],
context_client : Optional[ContextClient] = None, device_client : Optional[DeviceClient] = None,
service_client : Optional[ServiceClient] = None, slice_client : Optional[SliceClient] = None service_client : Optional[ServiceClient] = None, slice_client : Optional[SliceClient] = None
) -> None: ) -> None:
self.__descriptors = json.loads(descriptors) if isinstance(descriptors, str) else descriptors
self.__dummy_mode = self.__descriptors.get('dummy_mode' , False)
self.__contexts = self.__descriptors.get('contexts' , [])
self.__topologies = self.__descriptors.get('topologies' , [])
self.__devices = self.__descriptors.get('devices' , [])
self.__links = self.__descriptors.get('links' , [])
self.__services = self.__descriptors.get('services' , [])
self.__slices = self.__descriptors.get('slices' , [])
self.__connections = self.__descriptors.get('connections', [])
self.__contexts_add = None
self.__topologies_add = None
self.__devices_add = None
self.__devices_config = None
self.__services_add = None
self.__slices_add = None
self.__ctx_cli = ContextClient() if context_client is None else context_client self.__ctx_cli = ContextClient() if context_client is None else context_client
self.__dev_cli = DeviceClient() if device_client is None else device_client self.__dev_cli = DeviceClient() if device_client is None else device_client
self.__svc_cli = ServiceClient() if service_client is None else service_client self.__svc_cli = ServiceClient() if service_client is None else service_client
self.__slc_cli = SliceClient() if slice_client is None else slice_client self.__slc_cli = SliceClient() if slice_client is None else slice_client
self.__results : TypeResults = list()
self.__connections = None
self.__contexts = None
self.__contexts_add = None
self.__devices = None
self.__devices_add = None
self.__devices_config = None
self.__dummy_mode = None
self.__links = None
self.__services = None
self.__services_add = None
self.__slices = None
self.__slices_add = None
self.__topologies = None
self.__topologies_add = None
def get_results(self) -> TypeResults: return self.__results self.__results : TypeResults = list()
def process_descriptors(self, descriptors : Dict) -> None:
self.__dummy_mode = descriptors.get('dummy_mode' , False)
self.__contexts = descriptors.get('contexts' , [])
self.__topologies = descriptors.get('topologies' , [])
self.__devices = descriptors.get('devices' , [])
self.__links = descriptors.get('links' , [])
self.__services = descriptors.get('services' , [])
self.__slices = descriptors.get('slices' , [])
self.__connections = descriptors.get('connections', [])
@property
def contexts(self) -> List[Dict]: return self.__contexts
@property
def num_contexts(self) -> int: return len(self.__contexts)
@property
def topologies(self) -> Dict[str, List[Dict]]:
_topologies = {}
for topology in self.__topologies:
context_uuid = topology.topology_id.context_id.context_uuid.uuid
_topologies.setdefault(context_uuid, []).append(topology)
return _topologies
@property
def num_topologies(self) -> Dict[str, int]:
_num_topologies = {}
for topology in self.__topologies:
context_uuid = topology.topology_id.context_id.context_uuid.uuid
_num_topologies[context_uuid] = _num_topologies.get(context_uuid, 0) + 1
return _num_topologies
@property
def devices(self) -> List[Dict]: return self.__devices
@property
def num_devices(self) -> int: return len(self.__devices)
@property
def links(self) -> List[Dict]: return self.__links
@property
def num_links(self) -> int: return len(self.__links)
@property
def services(self) -> Dict[str, List[Dict]]:
_services = {}
for service in self.__services:
context_uuid = service.service_id.context_id.context_uuid.uuid
_services.setdefault(context_uuid, []).append(service)
return _services
@property
def num_services(self) -> Dict[str, int]:
_num_services = {}
for service in self.__services:
context_uuid = service.service_id.context_id.context_uuid.uuid
_num_services[context_uuid] = _num_services.get(context_uuid, 0) + 1
return _num_services
@property
def slices(self) -> Dict[str, List[Dict]]:
_slices = {}
for slice_ in self.__slices:
context_uuid = slice_.slice_id.context_id.context_uuid.uuid
_slices.setdefault(context_uuid, []).append(slice_)
return _slices
@property
def num_slices(self) -> Dict[str, int]:
_num_slices = {}
for slice_ in self.__slices:
context_uuid = slice_.slice_id.context_id.context_uuid.uuid
_num_slices[context_uuid] = _num_slices.get(context_uuid, 0) + 1
return _num_slices
@property
def connections(self) -> List[Dict]: return self.__connections
@property
def num_connections(self) -> int: return len(self.__connections)
def process(self) -> TypeResults:
# Format CustomConfigRules in Devices, Services and Slices provided in JSON format # Format CustomConfigRules in Devices, Services and Slices provided in JSON format
self.__devices = [format_device_custom_config_rules (device ) for device in self.__devices ] self.__devices = [format_device_custom_config_rules (device ) for device in self.__devices ]
self.__services = [format_service_custom_config_rules(service) for service in self.__services] self.__services = [format_service_custom_config_rules(service) for service in self.__services]
...@@ -130,6 +194,8 @@ class DescriptorLoader: ...@@ -130,6 +194,8 @@ class DescriptorLoader:
self._dummy_mode() self._dummy_mode()
else: else:
self._normal_mode() self._normal_mode()
return self.__results
def _dummy_mode(self) -> None: def _dummy_mode(self) -> None:
# Dummy Mode: used to pre-load databases (WebUI debugging purposes) with no smart or automated tasks. # Dummy Mode: used to pre-load databases (WebUI debugging purposes) with no smart or automated tasks.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment