# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/) # # 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, logging, os, time from typing import Dict from prometheus_client import Histogram from common.Constants import ServiceNameEnum from common.Settings import ENVVAR_SUFIX_SERVICE_HOST, get_env_var_name from common.method_wrappers.Decorator import MetricTypeEnum, MetricsPool, safe_and_metered_rpc_method from common.method_wrappers.ServiceExceptions import NotFoundException, OperationFailedException from common.proto.context_pb2 import ( Device, DeviceConfig, DeviceDriverEnum, DeviceId, DeviceOperationalStatusEnum, Empty, Link, MyConfig, MyConfigId, MyConfig, MyConfigList ) from common.proto.device_pb2 import MonitoringSettings from common.proto.device_pb2_grpc import DeviceServiceServicer from common.tools.context_queries.Device import get_device from common.tools.mutex_queues.MutexQueues import MutexQueues from context.client.ContextClient import ContextClient from .driver_api._Driver import _Driver from .driver_api.DriverInstanceCache import DriverInstanceCache, get_driver from .monitoring.MonitoringLoops import MonitoringLoops from .drivers.oc_driver.OCDriver import OCDriver from .ErrorMessages import ERROR_MISSING_DRIVER, ERROR_MISSING_KPI from .Tools import extract_resources from .Tools import ( check_connect_rules, check_no_endpoints, compute_rules_to_add_delete, configure_rules, deconfigure_rules, get_device_controller_uuid, populate_config_rules, populate_endpoint_monitoring_resources, populate_endpoints, populate_initial_config_rules, subscribe_kpi, unsubscribe_kpi, update_endpoints) LOGGER = logging.getLogger(__name__) METRICS_POOL = MetricsPool('Device', 'RPC') METRICS_POOL_DETAILS = MetricsPool('Device', 'execution', labels={ 'driver': '', 'operation': '', 'step': '', }) class OpenConfigServicer(DeviceServiceServicer): def __init__(self, driver_instance_cache : DriverInstanceCache, monitoring_loops : MonitoringLoops) -> None: LOGGER.debug('Creating Servicer...') self.driver_instance_cache = driver_instance_cache self.monitoring_loops = monitoring_loops self.mutex_queues = MutexQueues() LOGGER.debug('Servicer Created') @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def AddOpenConfigDevice(self, request : MyConfig, context : grpc.ServicerContext) -> DeviceId: device_uuid = request.device_id.device_uuid.uuid device_type=request.device_type ocdriver=OCDriver() connection_config_rules = check_connect_rules(request.device_config) check_no_endpoints(request.device_endpoints) context_client = ContextClient() device = get_device(context_client, device_uuid, rw_copy=True) if device is None: # not in context, create blank one to get UUID, and populate it below device = Device() device.device_id.CopyFrom(request.device_id) # pylint: disable=no-member device.name = request.name device.device_type = request.device_type device.device_operational_status = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_UNDEFINED device.device_drivers.extend(request.device_drivers) # pylint: disable=no-member device.device_config.CopyFrom(request.device_config) # pylint: disable=no-member device_id = context_client.SetDevice(device) device = get_device(context_client, device_id.device_uuid.uuid, rw_copy=True) # update device_uuid to honor UUID provided by Context device_uuid = device.device_id.device_uuid.uuid LOGGER.debug('device type %s',device) t2 = time.time() self.mutex_queues.wait_my_turn(device_uuid) t3 = time.time() #temp fix to solve the error #todo check what to pass here resources_to_get = [] try: #driver : _Driver = get_driver(self.driver_instance_cache, device) results_getconfig=ocdriver.GetConfig(resource_keys=resources_to_get,device_uuid=device_uuid) #results_getconfig = driver.GetConfig(resources_to_get,device_uuid) except Exception as error : LOGGER.debug("error %s",error) @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def ConfigureOpticalDevice (self, request : MyConfig, context:grpc.ServicerContext) -> Empty: LOGGER.info('Setting from ConfigureOpticalDevice with Flows %s',request) #device_id = request.myconfig_id #device_uuid = device_id.myconfig_uuid device_uuid = request.myconfig_id.myconfig_uuid LOGGER.info("device uuid {}".format(device_uuid)) resources=[] result=None config = eval(request.config) filter_fields= ["frequency", "target-output-power", "interface", "operational-mode"] try: context_client = ContextClient() device = get_device( context_client, device_uuid, rw_copy=True, include_endpoints=True, include_components=False, include_config_rules=False) if device is None: LOGGER.info("device is none") raise NotFoundException('Device', device_uuid, extra_details='loading in ConfigureDevice') resources,conditions=extract_resources(config=config,device=device) driver : _Driver = get_driver(self.driver_instance_cache, device) LOGGER.info("resource %s conditions %s",resources,conditions) result = driver.SetConfig(resources=resources,conditions=conditions) #todo #add a control with the NETCONF get #driver.GetConfig(resource_keys=filter_fields) except Exception as e: LOGGER.info("error in configuring %s",e) LOGGER.info("result %s",result) return Empty()