Skip to content
Snippets Groups Projects
SliceServiceServicerImpl.py 8.64 KiB
Newer Older
  • Learn to ignore specific revisions
  • # Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
    #
    # 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.
    
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    import grpc, logging #, deepdiff
    
    from common.proto.context_pb2 import (
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
        Empty, Service, ServiceId, ServiceStatusEnum, ServiceTypeEnum, Slice, SliceId, SliceStatusEnum)
    
    from common.proto.slice_pb2_grpc import SliceServiceServicer
    
    from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
    from common.tools.grpc.ConfigRules import copy_config_rules
    from common.tools.grpc.Constraints import copy_constraints
    from common.tools.grpc.EndPointIds import copy_endpoint_ids
    from common.tools.grpc.ServiceIds import update_service_ids
    from common.tools.grpc.Tools import grpc_message_to_json
    
    from context.client.ContextClient import ContextClient
    from interdomain.client.InterdomainClient import InterdomainClient
    from service.client.ServiceClient import ServiceClient
    
    LOGGER = logging.getLogger(__name__)
    
    SERVICE_NAME = 'Slice'
    METHOD_NAMES = ['CreateSlice', 'UpdateSlice', 'DeleteSlice']
    METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES)
    
    class SliceServiceServicerImpl(SliceServiceServicer):
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
        def __init__(self):
    
            LOGGER.debug('Creating Servicer...')
            LOGGER.debug('Servicer Created')
    
        def create_update(self, request : Slice) -> SliceId:
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
            context_client = ContextClient()
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
            try:
                _slice = context_client.GetSlice(request.slice_id)
                json_current_slice = grpc_message_to_json(_slice)
            except:
                json_current_slice = {}
                slice_request = Slice()
                slice_request.slice_id.CopyFrom(request.slice_id)
                slice_request.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_PLANNED
                context_client.SetSlice(slice_request)
                _slice = context_client.GetSlice(request.slice_id)
            slice_request = Slice()
            slice_request.CopyFrom(_slice)
    
            #LOGGER.info('json_current_slice = {:s}'.format(str(json_current_slice)))
            #json_updated_slice = grpc_message_to_json(request)
            #LOGGER.info('json_updated_slice = {:s}'.format(str(json_updated_slice)))
            #changes = deepdiff.DeepDiff(json_current_slice, json_updated_slice)
            #LOGGER.info('changes = {:s}'.format(str(changes)))
    
    
            domains = set()
            for slice_endpoint_id in request.slice_endpoint_ids:
                device_uuid = slice_endpoint_id.device_id.device_uuid.uuid
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
                device_parts = device_uuid.split('@')
                domain_uuid = '' if len(device_parts) == 1 else device_parts[1]
                domains.add(domain_uuid)
            LOGGER.info('domains = {:s}'.format(str(domains)))
            is_multi_domain = len(domains) > 1
            LOGGER.info('is_multi_domain = {:s}'.format(str(is_multi_domain)))
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
                interdomain_client = InterdomainClient()
                slice_id = interdomain_client.RequestSlice(request)
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
                service_id = ServiceId()
                context_uuid = service_id.context_id.context_uuid.uuid = request.slice_id.context_id.context_uuid.uuid
                slice_uuid = service_uuid = service_id.service_uuid.uuid = request.slice_id.slice_uuid.uuid
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
                service_client = ServiceClient()
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
                try:
                    _service = context_client.GetService(service_id)
                except:
                    service_request = Service()
                    service_request.service_id.CopyFrom(service_id)
                    service_request.service_type = ServiceTypeEnum.SERVICETYPE_L2NM
                    service_request.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED
                    service_reply = service_client.CreateService(service_request)
                    if service_reply != service_request.service_id: # pylint: disable=no-member
                        raise Exception('Service creation failed. Wrong Service Id was returned')
                    _service = context_client.GetService(service_id)
                service_request = Service()
                service_request.CopyFrom(_service)
    
                copy_endpoint_ids(request.slice_endpoint_ids, service_request.service_endpoint_ids)
                copy_constraints(request.slice_constraints, service_request.service_constraints)
                copy_config_rules(request.slice_config.config_rules, service_request.service_config.config_rules)
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
                service_reply = service_client.UpdateService(service_request)
    
                if service_reply != service_request.service_id: # pylint: disable=no-member
                    raise Exception('Service update failed. Wrong Service Id was returned')
    
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
                copy_endpoint_ids(request.slice_endpoint_ids, slice_request.slice_endpoint_ids)
                copy_constraints(request.slice_constraints, slice_request.slice_constraints)
                copy_config_rules(request.slice_config.config_rules, slice_request.slice_config.config_rules)
    
                update_service_ids(slice_request.slice_service_ids, context_uuid, service_uuid)
                context_client.SetSlice(slice_request)
                slice_id = slice_request.slice_id
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
            slice_ = context_client.GetSlice(slice_id)
    
            slice_active = Slice()
            slice_active.CopyFrom(slice_)
            slice_active.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_ACTIVE
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
            context_client.SetSlice(slice_active)
    
            return slice_id
    
        @safe_and_metered_rpc_method(METRICS, LOGGER)
        def CreateSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId:
            #try:
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
            #    slice_ = context_client.GetSlice(request.slice_id)
    
            #    slice_id = slice_.slice_id
            #except grpc.RpcError:
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
            #    slice_id = context_client.SetSlice(request)
    
            #return slice_id
            return self.create_update(request)
    
        @safe_and_metered_rpc_method(METRICS, LOGGER)
        def UpdateSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId:
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
            #slice_id = context_client.SetSlice(request)
    
            #if len(request.slice_endpoint_ids) != 2: return slice_id
            #
            #domains = set()
            #for slice_endpoint_id in request.slice_endpoint_ids:
            #    device_uuid = slice_endpoint_id.device_id.device_uuid.uuid
            #    domains.add(device_uuid.split('@')[0])
            #
            #is_multi_domain = len(domains) == 2
            #if is_multi_domain:
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
            #    interdomain_client = InterdomainClient()
            #    return interdomain_client.LookUpSlice(request)
    
            #else:
            #    raise NotImplementedError('Slice should create local services for single domain slice')
            return self.create_update(request)
    
        @safe_and_metered_rpc_method(METRICS, LOGGER)
        def DeleteSlice(self, request : SliceId, context : grpc.ServicerContext) -> Empty:
    
    Lluis Gifre Renom's avatar
    Lluis Gifre Renom committed
            context_client = ContextClient()
            try:
                _slice = context_client.GetSlice(request)
            except:
                return Empty()
    
            domains = set()
            for slice_endpoint_id in _slice.slice_endpoint_ids:
                device_uuid = slice_endpoint_id.device_id.device_uuid.uuid
                device_parts = device_uuid.split('@')
                domain_uuid = '' if len(device_parts) == 1 else device_parts[1]
                domains.add(domain_uuid)
            LOGGER.info('domains = {:s}'.format(str(domains)))
            is_multi_domain = len(domains) > 1
            LOGGER.info('is_multi_domain = {:s}'.format(str(is_multi_domain)))
    
            if is_multi_domain:
                interdomain_client = InterdomainClient()
                #slice_id = interdomain_client.DeleteSlice(request)
                raise NotImplementedError('Delete inter-domain slice')
            else:
                current_slice = Slice()
                current_slice.CopyFrom(_slice)
                current_slice.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_DEINIT
                context_client.SetSlice(current_slice)
    
                service_client = ServiceClient()
                for service_id in _slice.slice_service_ids:
                    current_slice = Slice()
                    current_slice.slice_id.CopyFrom(_slice.slice_id)
                    slice_service_id = current_slice.slice_service_ids.add()
                    slice_service_id.CopyFrom(service_id)
                    context_client.UnsetSlice(current_slice)
    
                    service_client.DeleteService(service_id)
    
            context_client.RemoveSlice(request)