Newer
Older

Lluis Gifre Renom
committed
import grpc, logging
from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method
from device.proto.context_pb2 import Device, DeviceConfig, DeviceId, Empty

Lluis Gifre Renom
committed
from device.proto.device_pb2_grpc import DeviceServiceServicer
from .data_cache.DataCache import DataCache
from .data_cache.database.DeviceModel import DriverModel
from .data_cache.database.EndPointModel import EndPointModel
from .driver_api._Driver import _Driver
from .driver_api.DriverInstanceCache import DriverInstanceCache

Lluis Gifre Renom
committed
LOGGER = logging.getLogger(__name__)
SERVICE_NAME = 'Device'
METHOD_NAMES = ['AddDevice', 'ConfigureDevice', 'DeleteDevice', 'GetInitialConfig']
METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES)

Lluis Gifre Renom
committed
class DeviceServiceServicerImpl(DeviceServiceServicer):
def __init__(self, data_cache : DataCache, driver_instance_cache : DriverInstanceCache):

Lluis Gifre Renom
committed
LOGGER.debug('Creating Servicer...')
self.data_cache = data_cache
self.driver_instance_cache = driver_instance_cache

Lluis Gifre Renom
committed
LOGGER.debug('Servicer Created')
@safe_and_metered_rpc_method(METRICS, LOGGER)
def AddDevice(self, request : Device, context : grpc.ServicerContext) -> DeviceId:
device_id = request.device_id
device_uuid = device_id.device_uuid.uuid
self.data_cache.sync_device_from_context(device_uuid)
db_device,_ = self.data_cache.set_device(request)
driver_filter_fields = self.data_cache.get_device_driver_filter_fields(device_uuid)
driver : _Driver = self.driver_instance_cache.get(device_uuid, driver_filter_fields)
driver.Connect()
running_config_rules = driver.GetConfig()
self.data_cache.update_device_config_in_local_database(device_uuid, 'running', running_config_rules)
initial_config_rules = driver.GetInitialConfig()
self.data_cache.update_device_config_in_local_database(device_uuid, 'initial', initial_config_rules)
self.data_cache.sync_device_to_context(device_uuid)
return DeviceId(**db_device.dump_id())
@safe_and_metered_rpc_method(METRICS, LOGGER)
def ConfigureDevice(self, request : Device, context : grpc.ServicerContext) -> DeviceId:
device_id = request.device_id
device_uuid = device_id.device_uuid.uuid
self.data_cache.sync_device_from_context(device_uuid)
db_device,_ = self.data_cache.set_device(request)
#resources_to_set = List[Tuple[str: resource_key, any: resource_value]]
#resources_to_delete = List[Tuple[str: resource_key]]
#resources_to_subscribe = List[str: resource_key, float: sampling_rate]
#resources_to_unsubscribe = List[Tuple[str: resource_key]]
# Compute "difference" between config field in request and config from Context
# Compute list of changes between device_config in context, and device_config in request
driver_filter_fields = self.data_cache.get_device_driver_filter_fields(device_uuid)
driver : _Driver = self.driver_instance_cache.get(device_uuid, driver_filter_fields)
#results_setconfig = driver.SetConfig(resources_to_set)
## check result
#results_deleteconfig = driver.DeleteConfig(resources_to_delete)
## check result
#results_subscribestate = driver.SubscribeState(resources_to_subscribe)
## check result
#results_unsubscribestate = driver.UnsubscribeState(resources_to_unsubscribe)
## check result
self.data_cache.sync_device_to_context(device_uuid)
return DeviceId(**db_device.dump_id())
@safe_and_metered_rpc_method(METRICS, LOGGER)
def DeleteDevice(self, request : DeviceId, context : grpc.ServicerContext) -> Empty:
device_uuid = request.device_uuid.uuid
self.data_cache.sync_device_from_context(device_uuid)
db_device = self.data_cache.get_device(device_uuid)
driver_filter_fields = self.data_cache.get_device_driver_filter_fields(device_uuid)
driver : _Driver = self.driver_instance_cache.get(device_uuid, driver_filter_fields)
self.data_cache.delete_device_from_context(device_uuid)
for db_endpoint_pk,_ in db_device.references(EndPointModel):
EndPointModel(db_device.database, db_endpoint_pk).delete()
for db_driver_pk,_ in db_device.references(DriverModel):
DriverModel(db_device.database, db_driver_pk).delete()
#db_config = ConfigModel(db_device.database, db_device.device_config_fk)
#for db_config_rule_pk,_ in db_config.references(ConfigRuleModel):
# ConfigRuleModel(db_device.database, db_config_rule_pk).delete()
return Empty()
@safe_and_metered_rpc_method(METRICS, LOGGER)
def GetInitialConfig(self, request : DeviceId, context : grpc.ServicerContext) -> DeviceConfig:
device_uuid = request.device_uuid.uuid
self.data_cache.sync_device_from_context(device_uuid)
db_device = self.data_cache.get_device(device_uuid)
return DeviceConfig(config_rules=db_device.dump_initial_config())