Resolve "Optical bandwidth expansion"

Closes #281 (closed)

Edited by Lluis Gifre Renom

Merge request reports

Loading
+38 −0
Changes for proto/context.proto: 38 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -94,6 +94,10 @@ service ContextService {
  rpc DeleteOpticalLink      (LinkId           ) returns (Empty            ) {}
  rpc GetOpticalLinkList     (Empty            ) returns (OpticalLinkList  ) {}

  rpc GetOpticalBand         (Empty            ) returns (OpticalBandList)  {}
  rpc SelectOpticalBand      (OpticalBandId    ) returns (OpticalBand)  {}


  rpc DeleteServiceConfigRule(ServiceConfigRule) returns (Empty            ) {}
}

@@ -695,6 +699,8 @@ message AuthenticationResult {
  bool authenticated = 2;
}



// ---------------- Experimental ------------------------
message OpticalConfigId {
  string opticalconfig_uuid = 1;
@@ -715,6 +721,8 @@ message OpticalConfigEvent {
}




// ---- Optical Link ----

message OpticalEndPointId {
@@ -730,6 +738,7 @@ message OpticalLinkList {


message OpticalLinkDetails {

  float length = 1;
  string src_port = 2;
  string dst_port = 3;
@@ -739,6 +748,7 @@ message OpticalLinkDetails {
  map<string, int32> c_slots = 7;
  map<string, int32> l_slots = 8;
  map<string, int32> s_slots = 9;
  
}

message OpticalLink {
@@ -749,6 +759,34 @@ message OpticalLink {
}


message ChannelId {
  Uuid channel_uuid = 1;
}

message OpticalBandId {
  Uuid opticalband_uuid = 1;
}


message OpticalBand {
  
   OpticalBandId opticalband_id = 1 ; 
   ConnectionId connection_id =2 ; 
    ChannelId channel_id = 3;
    ServiceId service_id =4;
    oneof field {
      Service service =5 ;
      Connection connection =6 ;
      string channel = 7;
    }

}

message OpticalBandList {
   repeated OpticalBand opticalbands =1 ;

}


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

+34 −1
Changes for src/common/tools/context_queries/OpticalConfig.py: 34 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -14,9 +14,11 @@


from common.method_wrappers.ServiceExceptions import InvalidArgumentsException
from context.client.ContextClient import ContextClient
import logging
from typing import Optional, Union
from uuid import UUID, uuid4, uuid5

from common.proto.context_pb2 import OpticalBand, OpticalBandId, Empty
# Generate a UUIDv5-like from the SHA-1 of "TFS" and no namespace to be used as the NAMESPACE for all
# the context UUIDs generated. For efficiency purposes, the UUID is hardcoded; however, it is produced
# using the following code:
@@ -64,3 +66,34 @@ def opticalconfig_get_uuid(
    raise InvalidArgumentsException([
        ('name', device_name),
    ], extra_details=['At least one is required to produce a OpticalConfig UUID'])


def ob_get_uuid(
    ob_name:str , allow_random : bool = False
) -> str:
   
    if ( ob_name is not None):
        
        
      result = get_uuid_from_string(f'ob_{ob_name}')
 
      return result 
    if allow_random: return get_uuid_random()

    raise InvalidArgumentsException([
        ('ob_name ', ob_name),
    ], extra_details=['ob_name is required to produce a Optical band UUID'])



def find_optical_band (ob_index)->OpticalBand:

    op_uuid = ob_get_uuid(ob_index)
    op_id=OpticalBandId()
    op_id.opticalband_uuid.uuid =op_uuid
    try:
        ctxt = ContextClient()
        target_ob= ctxt.SelectOpticalBand(op_id)
        return target_ob
    except Exception as e : 
            logging.debug(f"error in finding optical band {e}")
+41 −0
Changes for src/common/tools/object_factory/OpticalLink.py: 41 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -38,3 +38,44 @@ def correct_slot(dic: dict) -> dict:
                _dict[key]=1
            #print(f"result {_dict}")
    return _dict


## To be deleted , needed now for development purpose ## 

def order_list (lst:list[tuple])->list:
    if (len(lst)<=1):
        return lst
    else :
        pivot,bit_val =lst[0]
        lst_smaller = []
        lst_greater = []
        for element in lst[1:]:
            key,val=element
            if (key <= pivot):
                lst_smaller.append(element)
            else :
                lst_greater.append(element)
        return order_list(lst_smaller) + [(pivot,bit_val)] + order_list(lst_greater)

def list_to_dict (lst:list[tuple[int,int]])->dict:
    dct = dict()
    for ele in lst :
        key,value = ele
        dct[str(key)]=value
    return dct

def order_dict (dct:dict)->dict:
    lst = list()
    for key,value in sorted(dct.items()):
        lst.append((int(key),value))
    ordered_lst= order_list(lst)
    if (len(ordered_lst)>0):
        return list_to_dict (ordered_lst)

def order_dict_v1 (dct:dict)->dict:
    lst = list()
    for key,value in dct.items():
        lst.append((int(key),value))
    ordered_lst= order_list(lst)
    if (len(ordered_lst)>0):
        return list_to_dict (ordered_lst)
+23 −0
Changes for src/context/client/ContextClient.py: 23 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ 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
)
from common.proto.context_pb2_grpc import ContextServiceStub
from common.proto.context_policy_pb2_grpc import ContextPolicyServiceStub
@@ -491,6 +492,28 @@ class ContextClient:
        LOGGER.debug('DeleteOpticalChannel result: {:s}'.format(grpc_message_to_json_string(response)))
        return response
    
    
    @RETRY_DECORATOR
    def GetOpticalBand(self, request : Empty) -> OpticalBandList:
        LOGGER.debug('GetOpticalBand request: {:s}'.format(grpc_message_to_json_string(request)))
        response = self.stub.GetOpticalBand(request)
        LOGGER.debug('GetOpticalBand result: {:s}'.format(grpc_message_to_json_string(response)))
        return response
    
    @RETRY_DECORATOR
    def SelectOpticalBand(self, request : OpticalBandId) -> OpticalBand:
        LOGGER.debug('SelectOpticalBand request: {:s}'.format(grpc_message_to_json_string(request)))
        response = self.stub.SelectOpticalBand(request)
        LOGGER.debug('SelectOpticalBand result: {:s}'.format(grpc_message_to_json_string(response)))
        return response

    @RETRY_DECORATOR
    def SetOpticalBand(self,request : OpticalBand) -> Empty:
        LOGGER.debug('SetOpticalBand request: {:s}'.format(grpc_message_to_json_string(request)))
        response = self.stub.SetOpticalBand(request)
        LOGGER.debug('SetOpticalBand 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)))
+48 −0
Changes for src/context/service/database/models/OpticalConfig/OpticalBandModel.py: 48 added lines, 0 removed lines.
Original line number Diff line number Diff line
# Copyright 2022-2024 ETSI SDG TeraFlowSDN (TFS) (https://tfs.etsi.org/)
#
# 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.

import json, logging, operator
from sqlalchemy import Column, DateTime, ForeignKey, Integer, CheckConstraint, String
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship
from typing import Dict
from context.service.database.models._Base import _Base

LOGGER = logging.getLogger(__name__)

class OpticalBandModel(_Base):
    __tablename__ = 'opticalband'

    ob_uuid = Column(UUID(as_uuid=False), primary_key=True)
    connection_uuid     = Column(ForeignKey('connection.connection_uuid', ondelete='CASCADE'), nullable=False)
    channel_uuid        = Column(ForeignKey('channel.channel_uuid', ondelete='CASCADE'), nullable=False)
    created_at          = Column(DateTime, nullable=False)
    ob_channel          = relationship('ChannelModel') # back_populates='connections'
    ob_connection       = relationship('ConnectionModel') # lazy='joined', back_populates='connection'
   
    def dump_id(self) -> Dict:
        return {'opticalband_uuid': {'uuid': self.ob_uuid}}

    def dump(self) -> Dict:
        return {
            'opticalband_id': self.dump_id(),
            'channel_id'    : self.ob_channel.dump_id(),
            'connection_id' : self.ob_connection.dump_id(),
            'service_id'    : self.ob_connection.connection_service.dump_id(),
            'channel'       : json.dumps(self.ob_channel.dump()),
            'connection'    : self.ob_connection.dump(),
            "service"       : self.ob_connection.connection_service.dump()
            
        }
Loading
Loading