Skip to content
Snippets Groups Projects
ContextServiceServicerImpl.py 7.45 KiB
Newer Older
  • Learn to ignore specific revisions
  • import grpc, logging
    from prometheus_client import Counter, Histogram
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    from common.database.api.context.Constants import DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    from common.database.api.Database import Database
    from common.exceptions.ServiceException import ServiceException
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    from context.proto.context_pb2 import Empty, Link, LinkId, Topology
    
    from context.proto.context_pb2_grpc import ContextServiceServicer
    
    from context.service.Tools import check_link_id_request, check_link_request
    
    
    LOGGER = logging.getLogger(__name__)
    
    GETTOPOLOGY_COUNTER_STARTED    = Counter  ('context_gettopology_counter_started',
                                              'Context:GetTopology counter of requests started'  )
    GETTOPOLOGY_COUNTER_COMPLETED  = Counter  ('context_gettopology_counter_completed',
                                              'Context:GetTopology counter of requests completed')
    GETTOPOLOGY_COUNTER_FAILED     = Counter  ('context_gettopology_counter_failed',
                                              'Context:GetTopology counter of requests failed'   )
    GETTOPOLOGY_HISTOGRAM_DURATION = Histogram('context_gettopology_histogram_duration',
                                              'Context:GetTopology histogram of request duration')
    
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    ADDLINK_COUNTER_STARTED    = Counter  ('context_addlink_counter_started',
                                           'Context:AddLink counter of requests started'  )
    ADDLINK_COUNTER_COMPLETED  = Counter  ('context_addlink_counter_completed',
                                           'Context:AddLink counter of requests completed')
    ADDLINK_COUNTER_FAILED     = Counter  ('context_addlink_counter_failed',
                                           'Context:AddLink counter of requests failed'   )
    ADDLINK_HISTOGRAM_DURATION = Histogram('context_addlink_histogram_duration',
                                           'Context:AddLink histogram of request duration')
    
    DELETELINK_COUNTER_STARTED    = Counter  ('context_deletelink_counter_started',
                                              'Context:DeleteLink counter of requests started'  )
    DELETELINK_COUNTER_COMPLETED  = Counter  ('context_deletelink_counter_completed',
                                              'Context:DeleteLink counter of requests completed')
    DELETELINK_COUNTER_FAILED     = Counter  ('context_deletelink_counter_failed',
                                              'Context:DeleteLink counter of requests failed'   )
    DELETELINK_HISTOGRAM_DURATION = Histogram('context_deletelink_histogram_duration',
                                              'Context:DeleteLink histogram of request duration')
    
    
    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')
    
        @GETTOPOLOGY_HISTOGRAM_DURATION.time()
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
        def GetTopology(self, request : Empty, grpc_context : grpc.ServicerContext) -> Topology:
    
            GETTOPOLOGY_COUNTER_STARTED.inc()
            try:
                LOGGER.debug('GetTopology request: {}'.format(str(request)))
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    
                # ----- Validate request data and pre-conditions -----------------------------------------------------------
                db_context = self.database.context(DEFAULT_CONTEXT_ID).create()
                db_topology = db_context.topology(DEFAULT_TOPOLOGY_ID).create()
    
                # ----- Retrieve data from the database --------------------------------------------------------------------
                json_topology = db_topology.dump()
    
                # ----- Compose reply --------------------------------------------------------------------------------------
                reply = Topology(**json_topology)
    
                LOGGER.debug('GetTopology reply: {}'.format(str(reply)))
                GETTOPOLOGY_COUNTER_COMPLETED.inc()
                return reply
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
            except ServiceException as e:                               # pragma: no cover (ServiceException not thrown)
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
                LOGGER.exception('GetTopology exception')
                GETTOPOLOGY_COUNTER_FAILED.inc()
                grpc_context.abort(e.code, e.details)
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
            except Exception as e:                                      # pragma: no cover
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
                LOGGER.exception('GetTopology exception')
                GETTOPOLOGY_COUNTER_FAILED.inc()
                grpc_context.abort(grpc.StatusCode.INTERNAL, str(e))
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    
        @ADDLINK_HISTOGRAM_DURATION.time()
        def AddLink(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 ------------------------------------------------------------------
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
                db_context = self.database.context(DEFAULT_CONTEXT_ID).create()
                db_topology = db_context.topology(DEFAULT_TOPOLOGY_ID).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)
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
                    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:
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
                LOGGER.exception('AddLink exception')
                ADDLINK_COUNTER_FAILED.inc()
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
                grpc_context.abort(e.code, e.details)
            except Exception as e:                                      # pragma: no cover
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
                LOGGER.exception('AddLink exception')
                ADDLINK_COUNTER_FAILED.inc()
                grpc_context.abort(grpc.StatusCode.INTERNAL, str(e))
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    
        @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 ------------------------------------------------------------------
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
                db_context = self.database.context(DEFAULT_CONTEXT_ID).create()
                db_topology = db_context.topology(DEFAULT_TOPOLOGY_ID).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:
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
                LOGGER.exception('DeleteLink exception')
                DELETELINK_COUNTER_FAILED.inc()
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
                grpc_context.abort(e.code, e.details)
            except Exception as e:                                      # pragma: no cover
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
                LOGGER.exception('DeleteLink exception')
                DELETELINK_COUNTER_FAILED.inc()
                grpc_context.abort(grpc.StatusCode.INTERNAL, str(e))