# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) # # 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 grpc from typing import Any, Dict, Tuple from common.method_wrappers.ServiceExceptions import InvalidArgumentException from common.orm.Database import Database from common.orm.HighLevel import get_or_create_object, update_or_create_object from common.orm.backend.Tools import key_to_str from common.proto.context_pb2 import Device, DeviceId from context.client.ContextClient import ContextClient from device.service.driver_api.FilterFields import FilterFieldEnum from .ConfigModel import delete_all_config_rules, grpc_config_rules_to_raw, update_config from .ContextModel import ContextModel from .DeviceModel import DeviceModel, DriverModel, grpc_to_enum__device_operational_status, set_drivers from .EndPointModel import EndPointModel, set_endpoint_monitors from .TopologyModel import TopologyModel def update_device_in_local_database(database : Database, device : Device) -> Tuple[DeviceModel, bool]: device_uuid = device.device_id.device_uuid.uuid for i,endpoint in enumerate(device.device_endpoints): endpoint_device_uuid = endpoint.endpoint_id.device_id.device_uuid.uuid if len(endpoint_device_uuid) == 0: endpoint_device_uuid = device_uuid if device_uuid != endpoint_device_uuid: raise InvalidArgumentException( 'request.device_endpoints[{:d}].device_id.device_uuid.uuid'.format(i), endpoint_device_uuid, ['should be == {:s}({:s})'.format('request.device_id.device_uuid.uuid', device_uuid)]) initial_config_result = update_config(database, device_uuid, 'initial', []) config_rules = grpc_config_rules_to_raw(device.device_config.config_rules) delete_all_config_rules(database, device_uuid, 'running') running_config_result = update_config(database, device_uuid, 'running', config_rules) result : Tuple[DeviceModel, bool] = update_or_create_object(database, DeviceModel, device_uuid, { 'device_uuid' : device_uuid, 'device_type' : device.device_type, 'device_operational_status': grpc_to_enum__device_operational_status(device.device_operational_status), 'device_initial_config_fk' : initial_config_result[0][0], 'device_running_config_fk' : running_config_result[0][0], }) db_device, updated = result set_drivers(database, db_device, device.device_drivers) for i,endpoint in enumerate(device.device_endpoints): endpoint_uuid = endpoint.endpoint_id.endpoint_uuid.uuid endpoint_device_uuid = endpoint.endpoint_id.device_id.device_uuid.uuid if len(endpoint_device_uuid) == 0: endpoint_device_uuid = device_uuid str_endpoint_key = key_to_str([device_uuid, endpoint_uuid]) endpoint_attributes = { 'device_fk' : db_device, 'endpoint_uuid': endpoint_uuid, 'endpoint_type': endpoint.endpoint_type, } endpoint_topology_context_uuid = endpoint.endpoint_id.topology_id.context_id.context_uuid.uuid endpoint_topology_uuid = endpoint.endpoint_id.topology_id.topology_uuid.uuid if len(endpoint_topology_context_uuid) > 0 and len(endpoint_topology_uuid) > 0: result : Tuple[ContextModel, bool] = get_or_create_object( database, ContextModel, endpoint_topology_context_uuid, defaults={ 'context_uuid': endpoint_topology_context_uuid, }) db_context, _ = result str_topology_key = key_to_str([endpoint_topology_context_uuid, endpoint_topology_uuid]) result : Tuple[TopologyModel, bool] = get_or_create_object( database, TopologyModel, str_topology_key, defaults={ 'context_fk': db_context, 'topology_uuid': endpoint_topology_uuid, }) db_topology, _ = result str_endpoint_key = key_to_str([str_endpoint_key, str_topology_key], separator=':') endpoint_attributes['topology_fk'] = db_topology result : Tuple[EndPointModel, bool] = update_or_create_object( database, EndPointModel, str_endpoint_key, endpoint_attributes) db_endpoint, db_endpoint_updated = result set_endpoint_monitors(database, db_endpoint, endpoint.kpi_sample_types) updated = updated or db_endpoint_updated return db_device, updated def sync_device_from_context( device_uuid : str, context_client : ContextClient, database : Database ) -> Tuple[DeviceModel, bool]: try: device : Device = context_client.GetDevice(DeviceId(device_uuid={'uuid': device_uuid})) except grpc.RpcError as e: if e.code() != grpc.StatusCode.NOT_FOUND: raise # pylint: disable=no-member return None return update_device_in_local_database(database, device) def sync_device_to_context(db_device : DeviceModel, context_client : ContextClient) -> None: if db_device is None: return context_client.SetDevice(Device(**db_device.dump( include_config_rules=True, include_drivers=True, include_endpoints=True))) def delete_device_from_context(db_device : DeviceModel, context_client : ContextClient) -> None: if db_device is None: return context_client.RemoveDevice(DeviceId(**db_device.dump_id())) def get_device_driver_filter_fields(db_device : DeviceModel) -> Dict[FilterFieldEnum, Any]: if db_device is None: return {} database = db_device.database db_driver_pks = db_device.references(DriverModel) db_driver_names = [DriverModel(database, pk).driver.value for pk,_ in db_driver_pks] return { FilterFieldEnum.DEVICE_TYPE: db_device.device_type, FilterFieldEnum.DRIVER : db_driver_names, }