Commit 579a1df2 authored by Lluis Gifre Renom's avatar Lluis Gifre Renom
Browse files

Merge branch 'develop' of ssh://gifrerenom_labs.etsi.org/tfs/controller into...

Merge branch 'develop' of ssh://gifrerenom_labs.etsi.org/tfs/controller into feat/294-cttc-correct-ci-cd-descriptors
parents c536664b 35450a68
Loading
Loading
Loading
Loading
+40 −0
Original line number Diff line number Diff line
@@ -99,6 +99,11 @@ service ContextService {
  rpc GetOpticalBand         (Empty            ) returns (OpticalBandList)  {}
  rpc SelectOpticalBand      (OpticalBandId    ) returns (OpticalBand)  {}

  rpc SetOpticalSpectrumReservation     (OpticalSpectrumReservation  ) returns (OpticalSpectrumReservationId  ) {}
  rpc GetOpticalSpectrumReservation     (OpticalSpectrumReservationId) returns (OpticalSpectrumReservation    ) {}
  rpc ListOpticalSpectrumReservations   (ContextId                   ) returns (OpticalSpectrumReservationList) {}
  rpc ConsumeOpticalSpectrumReservation (OpticalSpectrumReservation  ) returns (OpticalSpectrumReservationId  ) {}
  rpc ReleaseOpticalSpectrumReservation (OpticalSpectrumReservationId) returns (Empty                         ) {}

  rpc DeleteServiceConfigRule(ServiceConfigRule) returns (Empty            ) {}
}
@@ -813,6 +818,41 @@ message OpticalBandList {

}

enum OpticalSpectrumReservationStatusEnum {
  OPTICALSPECTRUMRESERVATIONSTATUS_UNDEFINED = 0;
  OPTICALSPECTRUMRESERVATIONSTATUS_RESERVED = 1;
  OPTICALSPECTRUMRESERVATIONSTATUS_CONSUMED = 2;
  OPTICALSPECTRUMRESERVATIONSTATUS_RELEASED = 3;
  OPTICALSPECTRUMRESERVATIONSTATUS_EXPIRED = 4;
}

message OpticalSpectrumReservationId {
  ContextId context_id = 1;
  Uuid reservation_uuid = 2;
}

message OpticalSpectrumReservation {
  OpticalSpectrumReservationId reservation_id = 1;
  TopologyId topology_id = 2;
  repeated LinkId optical_link_ids = 3;
  string band = 4;
  uint32 n_start = 5;
  uint32 n_end = 6;
  uint32 required_slots = 7;
  ServiceId service_id = 8;
  ConnectionId connection_id = 9;
  string owner_id = 10;
  string correlation_id = 11;
  OpticalSpectrumReservationStatusEnum status = 12;
  Timestamp created_at = 13;
  Timestamp updated_at = 14;
  Timestamp expires_at = 15;
}

message OpticalSpectrumReservationList {
  repeated OpticalSpectrumReservation reservations = 1;
}


////////////////// Config Rule Delete ////////////

+124 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ from common.proto.context_pb2 import (
    Empty, EventTypeEnum,
    Link, LinkEvent, LinkId, LinkIdList, LinkList,
    OpticalLink, OpticalLinkList,
    OpticalSpectrumReservation, OpticalSpectrumReservationId, OpticalSpectrumReservationList,
    OpticalSpectrumReservationStatusEnum,
    Service, ServiceEvent, ServiceFilter, ServiceId, ServiceIdList, ServiceList,
    Slice, SliceEvent, SliceFilter, SliceId, SliceIdList, SliceList,
    Topology, TopologyDetails, TopologyEvent, TopologyId, TopologyIdList, TopologyList
@@ -765,3 +767,125 @@ class MockServicerImpl_Context(ContextServiceServicer):

        LOGGER.debug('[DeleteOpticalLink] reply={:s}'.format(grpc_message_to_json_string(reply)))
        return reply

    # ----- Optical Spectrum Reservation ------------------------------------------------------------------------------

    def _optical_spectrum_reservation_is_active(self, reservation : OpticalSpectrumReservation) -> bool:
        return reservation.status in {
            OpticalSpectrumReservationStatusEnum.OPTICALSPECTRUMRESERVATIONSTATUS_RESERVED,
            OpticalSpectrumReservationStatusEnum.OPTICALSPECTRUMRESERVATIONSTATUS_CONSUMED,
        }

    def _optical_spectrum_reservation_ranges_overlap(
        self, a_start : int, a_end : int, b_start : int, b_end : int
    ) -> bool:
        return a_start <= b_end and b_start <= a_end

    def _validate_optical_spectrum_reservation(
        self, request : OpticalSpectrumReservation, container_name : str, context : grpc.ServicerContext
    ) -> None:
        reservation_uuid = request.reservation_id.reservation_uuid.uuid
        topology_uuid = request.topology_id.topology_uuid.uuid
        band = str(request.band)
        n_start = int(request.n_start)
        n_end = int(request.n_end)
        requested_link_uuids = {link_id.link_uuid.uuid for link_id in request.optical_link_ids}

        for link_uuid in requested_link_uuids:
            optical_link = self.obj_db.get_entry('optical_link', link_uuid, context)
            slots = getattr(optical_link.optical_details, band)
            for slot_index in range(n_start, n_end + 1):
                if int(slots.get(str(slot_index), 1)) != 1:
                    context.abort(
                        grpc.StatusCode.ALREADY_EXISTS,
                        'slot {:s}:{:d} is not available on optical link({:s})'.format(
                            band, slot_index, link_uuid
                        )
                    )

        for reservation in self.obj_db.get_entries(container_name):
            if reservation.reservation_id.reservation_uuid.uuid == reservation_uuid:
                continue
            if reservation.topology_id.topology_uuid.uuid != topology_uuid:
                continue
            if reservation.band != band:
                continue
            if not self._optical_spectrum_reservation_is_active(reservation):
                continue
            existing_link_uuids = {link_id.link_uuid.uuid for link_id in reservation.optical_link_ids}
            if len(requested_link_uuids.intersection(existing_link_uuids)) == 0:
                continue
            if self._optical_spectrum_reservation_ranges_overlap(
                n_start, n_end, int(reservation.n_start), int(reservation.n_end)
            ):
                context.abort(
                    grpc.StatusCode.ALREADY_EXISTS,
                    'OpticalSpectrumReservation({:s}) already exists; overlapping spectrum reservation'.format(
                        reservation.reservation_id.reservation_uuid.uuid
                    )
                )

    def ListOpticalSpectrumReservations(
        self, request : ContextId, context : grpc.ServicerContext
    ) -> OpticalSpectrumReservationList:
        LOGGER.debug('[ListOpticalSpectrumReservations] request={:s}'.format(grpc_message_to_json_string(request)))
        reservations = self.obj_db.get_entries('optical_spectrum_reservation[{:s}]'.format(
            str(request.context_uuid.uuid)
        ))
        reply = OpticalSpectrumReservationList(reservations=reservations)
        LOGGER.debug('[ListOpticalSpectrumReservations] reply={:s}'.format(grpc_message_to_json_string(reply)))
        return reply

    def GetOpticalSpectrumReservation(
        self, request : OpticalSpectrumReservationId, context : grpc.ServicerContext
    ) -> OpticalSpectrumReservation:
        LOGGER.debug('[GetOpticalSpectrumReservation] request={:s}'.format(grpc_message_to_json_string(request)))
        container_name = 'optical_spectrum_reservation[{:s}]'.format(str(request.context_id.context_uuid.uuid))
        reply = self.obj_db.get_entry(container_name, request.reservation_uuid.uuid, context)
        LOGGER.debug('[GetOpticalSpectrumReservation] reply={:s}'.format(grpc_message_to_json_string(reply)))
        return reply

    def SetOpticalSpectrumReservation(
        self, request : OpticalSpectrumReservation, context : grpc.ServicerContext
    ) -> OpticalSpectrumReservationId:
        LOGGER.debug('[SetOpticalSpectrumReservation] request={:s}'.format(grpc_message_to_json_string(request)))
        if request.status == OpticalSpectrumReservationStatusEnum.OPTICALSPECTRUMRESERVATIONSTATUS_UNDEFINED:
            request.status = OpticalSpectrumReservationStatusEnum.OPTICALSPECTRUMRESERVATIONSTATUS_RESERVED
        container_name = 'optical_spectrum_reservation[{:s}]'.format(
            str(request.reservation_id.context_id.context_uuid.uuid)
        )
        self._validate_optical_spectrum_reservation(request, container_name, context)
        reply, _ = self._set(
            request, container_name, request.reservation_id.reservation_uuid.uuid, 'reservation_id', TOPIC_CONTEXT
        )
        LOGGER.debug('[SetOpticalSpectrumReservation] reply={:s}'.format(grpc_message_to_json_string(reply)))
        return reply

    def ConsumeOpticalSpectrumReservation(
        self, request : OpticalSpectrumReservation, context : grpc.ServicerContext
    ) -> OpticalSpectrumReservationId:
        LOGGER.debug('[ConsumeOpticalSpectrumReservation] request={:s}'.format(grpc_message_to_json_string(request)))
        container_name = 'optical_spectrum_reservation[{:s}]'.format(
            str(request.reservation_id.context_id.context_uuid.uuid)
        )
        reservation = self.obj_db.get_entry(container_name, request.reservation_id.reservation_uuid.uuid, context)
        reservation.status = OpticalSpectrumReservationStatusEnum.OPTICALSPECTRUMRESERVATIONSTATUS_CONSUMED
        if request.HasField('service_id'):
            reservation.service_id.CopyFrom(request.service_id)
        if request.HasField('connection_id'):
            reservation.connection_id.CopyFrom(request.connection_id)
        LOGGER.debug('[ConsumeOpticalSpectrumReservation] reply={:s}'.format(
            grpc_message_to_json_string(reservation.reservation_id)
        ))
        return reservation.reservation_id

    def ReleaseOpticalSpectrumReservation(
        self, request : OpticalSpectrumReservationId, context : grpc.ServicerContext
    ) -> Empty:
        LOGGER.debug('[ReleaseOpticalSpectrumReservation] request={:s}'.format(grpc_message_to_json_string(request)))
        container_name = 'optical_spectrum_reservation[{:s}]'.format(str(request.context_id.context_uuid.uuid))
        reservation = self.obj_db.get_entry(container_name, request.reservation_uuid.uuid, context)
        reservation.status = OpticalSpectrumReservationStatusEnum.OPTICALSPECTRUMRESERVATIONSTATUS_RELEASED
        reply = Empty()
        LOGGER.debug('[ReleaseOpticalSpectrumReservation] reply={:s}'.format(grpc_message_to_json_string(reply)))
        return reply
+37 −1
Original line number Diff line number Diff line
@@ -28,7 +28,8 @@ from common.proto.context_pb2 import (
    Service, ServiceConfigRule, ServiceEvent, ServiceFilter, ServiceId, ServiceIdList, ServiceList,
    Slice, SliceEvent, SliceFilter, SliceId, SliceIdList, SliceList,
    Topology, TopologyDetails, TopologyEvent, TopologyId, TopologyIdList, TopologyList,
    OpticalBand, OpticalBandId, OpticalBandList
    OpticalBand, OpticalBandId, OpticalBandList,
    OpticalSpectrumReservation, OpticalSpectrumReservationId, OpticalSpectrumReservationList
)
from common.proto.context_pb2_grpc import ContextServiceStub
from common.proto.context_policy_pb2_grpc import ContextPolicyServiceStub
@@ -514,6 +515,41 @@ class ContextClient:
        LOGGER.debug('SetOpticalBand result: {:s}'.format(grpc_message_to_json_string(response)))
        return response

    @RETRY_DECORATOR
    def SetOpticalSpectrumReservation(self, request : OpticalSpectrumReservation) -> OpticalSpectrumReservationId:
        LOGGER.debug('SetOpticalSpectrumReservation request: {:s}'.format(grpc_message_to_json_string(request)))
        response = self.stub.SetOpticalSpectrumReservation(request)
        LOGGER.debug('SetOpticalSpectrumReservation result: {:s}'.format(grpc_message_to_json_string(response)))
        return response

    @RETRY_DECORATOR
    def GetOpticalSpectrumReservation(self, request : OpticalSpectrumReservationId) -> OpticalSpectrumReservation:
        LOGGER.debug('GetOpticalSpectrumReservation request: {:s}'.format(grpc_message_to_json_string(request)))
        response = self.stub.GetOpticalSpectrumReservation(request)
        LOGGER.debug('GetOpticalSpectrumReservation result: {:s}'.format(grpc_message_to_json_string(response)))
        return response

    @RETRY_DECORATOR
    def ListOpticalSpectrumReservations(self, request : ContextId) -> OpticalSpectrumReservationList:
        LOGGER.debug('ListOpticalSpectrumReservations request: {:s}'.format(grpc_message_to_json_string(request)))
        response = self.stub.ListOpticalSpectrumReservations(request)
        LOGGER.debug('ListOpticalSpectrumReservations result: {:s}'.format(grpc_message_to_json_string(response)))
        return response

    @RETRY_DECORATOR
    def ConsumeOpticalSpectrumReservation(self, request : OpticalSpectrumReservation) -> OpticalSpectrumReservationId:
        LOGGER.debug('ConsumeOpticalSpectrumReservation request: {:s}'.format(grpc_message_to_json_string(request)))
        response = self.stub.ConsumeOpticalSpectrumReservation(request)
        LOGGER.debug('ConsumeOpticalSpectrumReservation result: {:s}'.format(grpc_message_to_json_string(response)))
        return response

    @RETRY_DECORATOR
    def ReleaseOpticalSpectrumReservation(self, request : OpticalSpectrumReservationId) -> Empty:
        LOGGER.debug('ReleaseOpticalSpectrumReservation request: {:s}'.format(grpc_message_to_json_string(request)))
        response = self.stub.ReleaseOpticalSpectrumReservation(request)
        LOGGER.debug('ReleaseOpticalSpectrumReservation result: {:s}'.format(grpc_message_to_json_string(response)))
        return response
    
    #--------------------------- Optical Link ------------------------
    def GetOpticalLinkList(self, request: Empty) -> OpticalLinkList:
        LOGGER.debug('ListOpticalLinks request: {:s}'.format(grpc_message_to_json_string(request)))
+37 −1
Original line number Diff line number Diff line
@@ -25,7 +25,8 @@ from common.proto.context_pb2 import (
    Slice, SliceEvent, SliceFilter, SliceId, SliceIdList, SliceList,
    Topology, TopologyDetails, TopologyEvent, TopologyId, TopologyIdList, TopologyList,
    OpticalConfigList, OpticalConfigId, OpticalConfig, OpticalLink, OpticalLinkList,
    OpticalBand, OpticalBandId, OpticalBandList
    OpticalBand, OpticalBandId, OpticalBandList,
    OpticalSpectrumReservation, OpticalSpectrumReservationId, OpticalSpectrumReservationList
)
from common.proto.policy_pb2 import PolicyRuleIdList, PolicyRuleId, PolicyRuleList, PolicyRule
from common.proto.context_pb2_grpc import ContextServiceServicer
@@ -72,6 +73,11 @@ from .database.OpticalConfig import (
from .database.OpticalLink import (
    optical_link_delete, optical_link_get, optical_link_list_objs, optical_link_set
)
from .database.OpticalSpectrumReservation import (
    optical_spectrum_reservation_consume, optical_spectrum_reservation_get,
    optical_spectrum_reservation_list, optical_spectrum_reservation_release,
    optical_spectrum_reservation_set
)


LOGGER = logging.getLogger(__name__)
@@ -381,6 +387,36 @@ class ContextServiceServicerImpl(ContextServiceServicer, ContextPolicyServiceSer
        result = set_optical_band(self.db_engine, request)
        return Empty()

    @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
    def SetOpticalSpectrumReservation(
        self, request : OpticalSpectrumReservation, context : grpc.ServicerContext
    ) -> OpticalSpectrumReservationId:
        return optical_spectrum_reservation_set(self.db_engine, request)

    @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
    def GetOpticalSpectrumReservation(
        self, request : OpticalSpectrumReservationId, context : grpc.ServicerContext
    ) -> OpticalSpectrumReservation:
        return optical_spectrum_reservation_get(self.db_engine, request)

    @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
    def ListOpticalSpectrumReservations(
        self, request : ContextId, context : grpc.ServicerContext
    ) -> OpticalSpectrumReservationList:
        return optical_spectrum_reservation_list(self.db_engine, request)

    @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
    def ConsumeOpticalSpectrumReservation(
        self, request : OpticalSpectrumReservation, context : grpc.ServicerContext
    ) -> OpticalSpectrumReservationId:
        return optical_spectrum_reservation_consume(self.db_engine, request)

    @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
    def ReleaseOpticalSpectrumReservation(
        self, request : OpticalSpectrumReservationId, context : grpc.ServicerContext
    ) -> Empty:
        return optical_spectrum_reservation_release(self.db_engine, request)


    #--------------------- Experimental Optical Link -------------------

+337 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading