Skip to content
Snippets Groups Projects
ContextServiceServicerImpl.py 13.1 KiB
Newer Older
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
import grpc, logging, operator
from typing import Iterator
from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID
#from common.exceptions.ServiceException import ServiceException
from common.metrics.Metrics import create_metrics, safe_and_metered_rpc_method
from common.orm.Database import Database
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
from common.orm.backend.Tools import key_to_str
from context.proto.context_pb2 import \
    Context,  ContextEvent,  ContextId,  ContextIdList,  ContextList, \
    Device,   DeviceEvent,   DeviceId,   DeviceIdList,   DeviceList,  \
    Empty,                                                            \
    Link,     LinkEvent,     LinkId,     LinkIdList,     LinkList,    \
    Service,  ServiceEvent,  ServiceId,  ServiceIdList,  ServiceList, \
    Topology, TopologyEvent, TopologyId, TopologyIdList, TopologyList
from context.proto.context_pb2_grpc import ContextServiceServicer
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
from context.service.database.Models import ContextModel, TopologyModel
#from .Tools import check_link_id_request, check_link_request

LOGGER = logging.getLogger(__name__)

SERVICE_NAME = 'Context'
METHOD_NAMES = [
    'ListContextIds',  'ListContexts',   'GetContext',  'SetContext',  'RemoveContext',  'GetContextEvents',
    'ListTopologyIds', 'ListTopologies', 'GetTopology', 'SetTopology', 'RemoveTopology', 'GetTopologyEvents',
    'ListDeviceIds',   'ListDevices',    'GetDevice',   'SetDevice',   'RemoveDevice',   'GetDeviceEvents',
    'ListLinkIds',     'ListLinks',      'GetLink',     'SetLink',     'RemoveLink',     'GetLinkEvents',
    'ListServiceIds',  'ListServices',   'GetService',  'SetService',  'RemoveService',  'GetServiceEvents',
]
METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES)
class ContextServiceServicerImpl(ContextServiceServicer):
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
    def __init__(self, database : Database):
        LOGGER.debug('Creating Servicer...')
        self.database = database
        LOGGER.debug('Servicer Created')

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def ListContextIds(self, request: Empty, context : grpc.ServicerContext) -> ContextIdList:
        db_context_pks = sorted(list(ContextModel.get_primary_keys(self.database)))
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
        return ContextIdList(context_ids=[ContextModel(self.database, pk).dump_id() for pk in db_context_pks])

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def ListContexts(self, request: Empty, context : grpc.ServicerContext) -> ContextList:
        db_context_pks = sorted(list(ContextModel.get_primary_keys(self.database)))
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
        return ContextList(contexts=[ContextModel(self.database, pk).dump() for pk in db_context_pks])

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def GetContext(self, request: ContextId, context : grpc.ServicerContext) -> Context:
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
        str_key = key_to_str(request.context_uuid.uuid)
        db_context = ContextModel(self.database, str_key, auto_load=False)
        found = db_context.load()
        if not found: return Context()
        return Context(**db_context.dump(include_services=True, include_topologies=True))

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def SetContext(self, request: Context, context : grpc.ServicerContext) -> ContextId:
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
        str_key = key_to_str(request.context_id.context_uuid.uuid)
        db_context = ContextModel(self.database, str_key)
        db_context.save()
        # TODO: add topologies and services
        return ContextId(**db_context.dump_id())

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def RemoveContext(self, request: ContextId, context : grpc.ServicerContext) -> Empty:
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
        str_key = key_to_str(request.context_uuid.uuid)
        db_context = ContextModel(self.database, str_key)
        db_context.delete()
        return Empty()

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def GetContextEvents(self, request: Empty, context : grpc.ServicerContext) -> Iterator[ContextEvent]:
        pass

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def ListTopologyIds(self, request: ContextId, context : grpc.ServicerContext) -> TopologyIdList:
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
        db_context = ContextModel(self.database, request.context_uuid.uuid)
        db_topology_pks = db_context.references(TopologyModel)
        db_topology_pks = sorted(map(operator.itemgetter(0), db_topology_pks))
        topology_ids = [TopologyModel(self.database, pk).dump_id() for pk in db_topology_pks]
        return TopologyIdList(topology_ids=topology_ids)

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def ListTopologies(self, request: ContextId, context : grpc.ServicerContext) -> TopologyList:
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
        db_context = ContextModel(self.database, request.context_uuid.uuid)
        db_topology_pks = db_context.references(TopologyModel)
        db_topology_pks = sorted(map(operator.itemgetter(0), db_topology_pks))
        print('db_topology_pks', db_topology_pks)
        topologies = [TopologyModel(self.database, pk).dump() for pk in db_topology_pks]
        return TopologyList(topologies=topologies)

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def GetTopology(self, request: TopologyId, context : grpc.ServicerContext) -> Topology:
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
        str_key = key_to_str([request.context_id.context_uuid.uuid, request.topology_uuid.uuid])
        db_topology = TopologyModel(self.database, str_key, auto_load=False)
        found = db_topology.load()
        if not found: return Topology()
        return Topology(**db_topology.dump(include_devices=True, include_links=True))

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def SetTopology(self, request: Topology, context : grpc.ServicerContext) -> TopologyId:
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
        str_context_key = key_to_str([request.topology_id.context_id.context_uuid.uuid])
        str_topology_key = key_to_str([str_context_key, request.topology_id.topology_uuid.uuid])
        db_context = ContextModel(self.database, str_context_key)
        db_topology = TopologyModel(self.database, str_topology_key)
        db_topology.context_fk = db_context
        db_topology.save()
        # TODO: add devices and links
        return TopologyId(**db_topology.dump_id())

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def RemoveTopology(self, request: TopologyId, context : grpc.ServicerContext) -> Empty:
Lluis Gifre Renom's avatar
Lluis Gifre Renom committed
        str_key = key_to_str([request.context_id.context_uuid.uuid, request.topology_uuid.uuid])
        db_topology = TopologyModel(self.database, str_key)
        db_topology.delete()
        return Empty()

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def GetTopologyEvents(self, request: Empty, context : grpc.ServicerContext) -> Iterator[TopologyEvent]:
        pass

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def ListDeviceIds(self, request: Empty, context : grpc.ServicerContext) -> DeviceIdList:
        pass

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def ListDevices(self, request: Empty, context : grpc.ServicerContext) -> DeviceList:
        pass

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def GetDevice(self, request: DeviceId, context : grpc.ServicerContext) -> Device:
        pass

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def SetDevice(self, request: Device, context : grpc.ServicerContext) -> DeviceId:
        pass

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def RemoveDevice(self, request: DeviceId, context : grpc.ServicerContext) -> Empty:
        pass

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def GetDeviceEvents(self, request: Empty, context : grpc.ServicerContext) -> Iterator[DeviceEvent]:
        pass

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def ListLinkIds(self, request: Empty, context : grpc.ServicerContext) -> LinkIdList:
        pass

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def ListLinks(self, request: Empty, context : grpc.ServicerContext) -> LinkList:
        pass

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def GetLink(self, request: LinkId, context : grpc.ServicerContext) -> Link:
        pass

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def SetLink(self, request: Link, context : grpc.ServicerContext) -> LinkId:
        pass

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def RemoveLink(self, request: LinkId, context : grpc.ServicerContext) -> Empty:
        pass

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def GetLinkEvents(self, request: Empty, context : grpc.ServicerContext) -> Iterator[LinkEvent]:
        pass

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def ListServiceIds(self, request: ContextId, context : grpc.ServicerContext) -> ServiceIdList:
        pass

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def ListServices(self, request: ContextId, context : grpc.ServicerContext) -> ServiceList:
        pass

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def GetService(self, request: ServiceId, context : grpc.ServicerContext) -> Service:
        pass

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def SetService(self, request: Service, context : grpc.ServicerContext) -> ServiceId:
        pass

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def RemoveService(self, request: ServiceId, context : grpc.ServicerContext) -> Empty:
        pass

    @safe_and_metered_rpc_method(METRICS, LOGGER)
    def GetServiceEvents(self, request: Empty, context : grpc.ServicerContext) -> Iterator[ServiceEvent]:
        pass





#    @safe_and_metered_rpc_method(METRICS, LOGGER)
#    def GetTopology(self, request : Empty, grpc_context : grpc.ServicerContext) -> Topology:
#        # ----- Validate request data and pre-conditions -----------------------------------------------------------
#        db_context = self.database.context(DEFAULT_CONTEXT_UUID).create()
#        db_topology = db_context.topology(DEFAULT_TOPOLOGY_UUID).create()
#
#        # ----- Retrieve data from the database --------------------------------------------------------------------
#        json_topology = db_topology.dump()
#
#        # ----- Compose reply --------------------------------------------------------------------------------------
#        return Topology(**json_topology)
#
#    def CreaAddLink(self, request : Link, grpc_context : grpc.ServicerContext) -> LinkId:
#        ADDLINK_COUNTER_STARTED.inc()
#        try:
#            LOGGER.debug('AddLink request: {}'.format(str(request)))
#
#            # ----- Validate request data and pre-conditions -----------------------------------------------------------
#            link_id, db_endpoints = check_link_request('AddLink', request, self.database, LOGGER)
#
#            # ----- Implement changes in the database ------------------------------------------------------------------
#            db_context = self.database.context(DEFAULT_CONTEXT_UUID).create()
#            db_topology = db_context.topology(DEFAULT_TOPOLOGY_UUID).create()
#            db_link = db_topology.link(link_id).create()
#            for db_endpoint in db_endpoints:
#                link_endpoint_id = '{}/{}'.format(
#                    db_endpoint.device_uuid, db_endpoint.endpoint_uuid)
#                db_link.endpoint(link_endpoint_id).create(db_endpoint)
#
#            # ----- Compose reply --------------------------------------------------------------------------------------
#            reply = LinkId(**db_link.dump_id())
#            LOGGER.debug('AddLink reply: {}'.format(str(reply)))
#            ADDLINK_COUNTER_COMPLETED.inc()
#            return reply
#        except ServiceException as e:
#            LOGGER.exception('AddLink exception')
#            ADDLINK_COUNTER_FAILED.inc()
#            grpc_context.abort(e.code, e.details)
#        except Exception as e:                                      # pragma: no cover
#            LOGGER.exception('AddLink exception')
#            ADDLINK_COUNTER_FAILED.inc()
#            grpc_context.abort(grpc.StatusCode.INTERNAL, str(e))
#
#    @DELETELINK_HISTOGRAM_DURATION.time()
#    def DeleteLink(self, request : LinkId, grpc_context : grpc.ServicerContext) -> Empty:
#        DELETELINK_COUNTER_STARTED.inc()
#        try:
#            LOGGER.debug('DeleteLink request: {}'.format(str(request)))
#
#            # ----- Validate request data and pre-conditions -----------------------------------------------------------
#            link_id = check_link_id_request('DeleteLink', request, self.database, LOGGER)
#
#            # ----- Implement changes in the database ------------------------------------------------------------------
#            db_context = self.database.context(DEFAULT_CONTEXT_UUID).create()
#            db_topology = db_context.topology(DEFAULT_TOPOLOGY_UUID).create()
#            db_topology.link(link_id).delete()
#
#            # ----- Compose reply --------------------------------------------------------------------------------------
#            reply = Empty()
#            LOGGER.debug('DeleteLink reply: {}'.format(str(reply)))
#            DELETELINK_COUNTER_COMPLETED.inc()
#            return reply
#        except ServiceException as e:
#            LOGGER.exception('DeleteLink exception')
#            DELETELINK_COUNTER_FAILED.inc()
#            grpc_context.abort(e.code, e.details)
#        except Exception as e:                                      # pragma: no cover
#            LOGGER.exception('DeleteLink exception')
#            DELETELINK_COUNTER_FAILED.inc()
#            grpc_context.abort(grpc.StatusCode.INTERNAL, str(e))