diff --git a/src/device/service/Tools.py b/src/device/service/Tools.py index 6a62a75e71f0e02adb7fb1b70e4568b382494980..8717254cb59ad1b83a6e65ca3c1ba68757663674 100644 --- a/src/device/service/Tools.py +++ b/src/device/service/Tools.py @@ -174,7 +174,6 @@ def populate_endpoints( elif resource_key.startswith('/endpoints/endpoint'): endpoint_uuid = resource_value['uuid'] _device_uuid = resource_value.get('device_uuid') - endpoint_name = resource_value.get('name') if _device_uuid is None: # add endpoint to current device @@ -185,11 +184,17 @@ def populate_endpoints( device_endpoint = new_sub_devices[_device_uuid].device_endpoints.add() device_endpoint.endpoint_id.device_id.device_uuid.uuid = _device_uuid - device_endpoint.endpoint_id.topology_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME - device_endpoint.endpoint_id.topology_id.topology_uuid.uuid = DEFAULT_TOPOLOGY_NAME - device_endpoint.endpoint_id.endpoint_uuid.uuid = endpoint_uuid + + endpoint_context_uuid = resource_value.get('context_uuid', DEFAULT_CONTEXT_NAME) + device_endpoint.endpoint_id.topology_id.context_id.context_uuid.uuid = endpoint_context_uuid + + endpoint_topology_uuid = resource_value.get('topology_uuid', DEFAULT_TOPOLOGY_NAME) + device_endpoint.endpoint_id.topology_id.topology_uuid.uuid = endpoint_topology_uuid + + endpoint_name = resource_value.get('name') if endpoint_name is not None: device_endpoint.name = endpoint_name + device_endpoint.endpoint_type = resource_value.get('type', '-') sample_types : Dict[int, str] = resource_value.get('sample_types', {}) diff --git a/src/device/service/drivers/emulated/Tools.py b/src/device/service/drivers/emulated/Tools.py index 4770cc6e6d2b2ccbf86d1e3764e62f03b48837e2..0ac92bf56d5538a5ed4d3e7c53bc480d5ecd40bd 100644 --- a/src/device/service/drivers/emulated/Tools.py +++ b/src/device/service/drivers/emulated/Tools.py @@ -13,34 +13,74 @@ # limitations under the License. import logging -from typing import Any, Dict, Tuple +from typing import Any, Dict, Optional, Tuple from common.proto.kpi_sample_types_pb2 import KpiSampleType +from common.type_checkers.Checkers import chk_attribute, chk_string, chk_type from device.service.driver_api._Driver import RESOURCE_ENDPOINTS from .Constants import SPECIAL_RESOURCE_MAPPINGS LOGGER = logging.getLogger(__name__) -def compose_resource_endpoint(endpoint_data : Dict[str, Any]) -> Tuple[str, Any]: - endpoint_uuid = endpoint_data.get('uuid') - if endpoint_uuid is None: return None - endpoint_resource_path = SPECIAL_RESOURCE_MAPPINGS.get(RESOURCE_ENDPOINTS) - endpoint_resource_key = '{:s}/endpoint[{:s}]'.format(endpoint_resource_path, endpoint_uuid) - - endpoint_type = endpoint_data.get('type') - if endpoint_type is None: return None - - endpoint_sample_types = endpoint_data.get('sample_types') - if endpoint_sample_types is None: return None - - sample_types = {} - for endpoint_sample_type in endpoint_sample_types: - try: - metric_name = KpiSampleType.Name(endpoint_sample_type).lower().replace('kpisampletype_', '') - except: # pylint: disable=bare-except - LOGGER.warning('Unsupported EndPointSampleType({:s})'.format(str(endpoint_sample_type))) - continue - monitoring_resource_key = '{:s}/state/{:s}'.format(endpoint_resource_key, metric_name) - sample_types[endpoint_sample_type] = monitoring_resource_key - - endpoint_resource_value = {'uuid': endpoint_uuid, 'type': endpoint_type, 'sample_types': sample_types} - return endpoint_resource_key, endpoint_resource_value +def process_optional_string_field( + endpoint_data : Dict[str, Any], field_name : str, endpoint_resource_value : Dict[str, Any] +) -> None: + field_value = chk_attribute(field_name, endpoint_data, 'endpoint_data', default=None) + if field_value is None: return + chk_string('endpoint_data.{:s}'.format(field_name), field_value) + if len(field_value) > 0: endpoint_resource_value[field_name] = field_value + +def compose_resource_endpoint(endpoint_data : Dict[str, Any]) -> Optional[Tuple[str, Dict]]: + try: + # Check type of endpoint_data + chk_type('endpoint_data', endpoint_data, dict) + + # Check endpoint UUID (mandatory) + endpoint_uuid = chk_attribute('uuid', endpoint_data, 'endpoint_data') + chk_string('endpoint_data.uuid', endpoint_uuid, min_length=1) + endpoint_resource_path = SPECIAL_RESOURCE_MAPPINGS.get(RESOURCE_ENDPOINTS) + endpoint_resource_key = '{:s}/endpoint[{:s}]'.format(endpoint_resource_path, endpoint_uuid) + endpoint_resource_value = {'uuid': endpoint_uuid} + + # Check endpoint optional string fields + process_optional_string_field(endpoint_data, 'name', endpoint_resource_value) + process_optional_string_field(endpoint_data, 'type', endpoint_resource_value) + process_optional_string_field(endpoint_data, 'context_uuid', endpoint_resource_value) + process_optional_string_field(endpoint_data, 'topology_uuid', endpoint_resource_value) + + # Check endpoint sample types (optional) + endpoint_sample_types = chk_attribute('sample_types', endpoint_data, 'endpoint_data', default=[]) + chk_type('endpoint_data.sample_types', endpoint_sample_types, list) + sample_types = {} + sample_type_errors = [] + for i,endpoint_sample_type in enumerate(endpoint_sample_types): + field_name = 'endpoint_data.sample_types[{:d}]'.format(i) + try: + chk_type(field_name, endpoint_sample_type, (int, str)) + if isinstance(endpoint_sample_type, int): + metric_name = KpiSampleType.Name(endpoint_sample_type) + metric_id = endpoint_sample_type + elif isinstance(endpoint_sample_type, str): + metric_id = KpiSampleType.Value(endpoint_sample_type) + metric_name = endpoint_sample_type + else: + str_type = str(type(endpoint_sample_type)) + raise Exception('Bad format: {:s}'.format(str_type)) # pylint: disable=broad-exception-raised + except Exception as e: # pylint: disable=broad-exception-caught + MSG = 'Unsupported {:s}({:s}) : {:s}' + sample_type_errors.append(MSG.format(field_name, str(endpoint_sample_type), str(e))) + + metric_name = metric_name.lower().replace('kpisampletype_', '') + monitoring_resource_key = '{:s}/state/{:s}'.format(endpoint_resource_key, metric_name) + sample_types[metric_id] = monitoring_resource_key + + if len(sample_type_errors) > 0: + # pylint: disable=broad-exception-raised + raise Exception('Malformed Sample Types:\n{:s}'.format('\n'.join(sample_type_errors))) + + if len(sample_types) > 0: + endpoint_resource_value['sample_types'] = sample_types + + return endpoint_resource_key, endpoint_resource_value + except: # pylint: disable=bare-except + LOGGER.exception('Problem composing endpoint({:s})'.format(str(endpoint_data))) + return None