Newer
Older
from typing import Any, List, Tuple

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 .driver_api._Driver import _Driver
from .driver_api.DriverInstanceCache import DriverInstanceCache
from .driver_api.FilterFields import FilterFieldEnum
#from .Tools import check_device_id_request, check_device_request

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')
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
@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
config_name = 'running'
self.data_cache.sync_device_from_context(device_uuid)
db_device,_ = self.data_cache.set_device(request)
# Compute list of changes between device_config in context, and device_config in request
set_changes : List[Tuple[str, Any]] = []
delete_changes : List[Tuple[str, Any]] = []
subscriptions : List[Tuple[str, Any]] = []
unsubscriptions : List[Tuple[str, Any]] = []
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()
result = driver.SetConfig(set_changes)
# check result
result = driver.DeleteConfig(delete_changes)
# check result
result = driver.SubscribeState(subscriptions)
# check result
result = driver.UnsubscribeState(unsubscriptions)
# 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)
driver.Disconnect()
self.data_cache.delete_device_from_context(device_uuid)
db_device.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(device_config={'config_rules': db_device.dump_initial_config()})