Commit ba48f69f authored by Mohammad Ismaeel's avatar Mohammad Ismaeel
Browse files

Openroadm related

parent 4451b5e9
Loading
Loading
Loading
Loading
+80 −41
Original line number Diff line number Diff line
@@ -19,8 +19,8 @@ from sqlalchemy.engine import Engine
from sqlalchemy.orm import Session, sessionmaker
from sqlalchemy_cockroachdb import run_transaction
from common.proto.context_pb2 import OpticalConfig, OpticalConfigId , Empty , EventTypeEnum
from .models.OpticalConfigModel import OpticalConfigModel , OpticalChannelModel
from context.service.database.uuids.OpticalConfig import channel_get_uuid , opticalconfig_get_uuid
from .models.OpticalConfigModel import OpticalConfigModel , TransponderTypeModel ,OpticalChannelModel
from context.service.database.uuids.OpticalConfig import channel_get_uuid , opticalconfig_get_uuid ,transponder_get_uuid
from .Events import notify_event_opticalconfig

LOGGER = logging.getLogger(__name__)
@@ -36,7 +36,7 @@ def get_opticalconfig(db_engine : Engine):
            optical_config = OpticalConfig()
            optical_config.config = json.dumps(obj.dump())
            ids_obj = obj.dump_id()
            LOGGER.info(f"ids {ids_obj}")
         
            optical_config.opticalconfig_id.opticalconfig_uuid = ids_obj["opticalconfig_uuid"]
            optical_config.device_id.device_uuid.uuid=ids_obj["device_uuid"]
            optical_configs.append(optical_config)
@@ -49,22 +49,35 @@ def set_opticalconfig(db_engine : Engine, request : OpticalConfig):
    opticalconfig_id = OpticalConfigId()
    device_id = request.device_id
    device_uuid =  request.device_id.device_uuid.uuid
    channels = []
    transponder=[]
  
    OpticalConfig_data = []
    config_type=None
    opticalconfig_uuid =opticalconfig_get_uuid(device_id) 
    LOGGER.info(f"cofigy_type {request.config}")        
    if request.config:
        channels = []
        transceivers = []
        config = json.loads(request.config)
        opticalconfig_uuid =opticalconfig_get_uuid(device_id)         
        if 'transceivers' in config and len(config['transceivers']['transceiver']) > 0:
            transceivers = [transceiver for transceiver in config['transceivers']['transceiver']]
        if "type" in config:
           
            config_type= config["type"]
            if config_type == "optical-transponder":
                
        if 'channels' in config and len(config['channels']) > 0:
                transceivers = []
            
               
                
                if 'transceivers' in config['transponder'] and len(config['transponder']['transceivers']['transceiver']) > 0:
                    transceivers = [transceiver for transceiver in config['transponder'] ['transceivers']['transceiver']]
                    
                if 'channels' in config['transponder'] and len(config['transponder']['channels']) > 0:
                    #channels = [channel['name']['index'] for channel in config['channels']]
            
            for channel_params in config['channels']:
                    for channel_params in config['transponder']['channels']:
                        channels.append(
                                        {
                                    "opticalconfig_uuid":opticalconfig_uuid,
                                            # "opticalconfig_uuid":opticalconfig_uuid,
                                            "transponder_uuid":transponder_get_uuid(device_id),
                                            "channel_uuid":channel_get_uuid(channel_params['name']['index']),
                                            "channel_name"          : channel_params['name']['index'],
                                            "frequency"         : int(channel_params["frequency"]) if "frequency" in channel_params  else 0,
@@ -74,14 +87,26 @@ def set_opticalconfig(db_engine : Engine, request : OpticalConfig):
                                        } 
                                     )
     
                transponder.append({
                    "transponder_uuid":transponder_get_uuid(device_id),
                    "transcievers":transceivers,
                    "interfaces":None,
                    "opticalconfig_uuid":opticalconfig_uuid,
                    

                })
                
                   
        OpticalConfig_data.append(
           {
                                    "opticalconfig_uuid":opticalconfig_uuid,
                                    "transcievers"      : transceivers,
                                    "interfaces"        :"",
                                    # "transcievers"      : transceivers,
                                    # "interfaces"        :"",
                                    "channel_namespace" : config.get("channel_namespace",None),
                                    "endpoints"         : [json.dumps(endpoint) for endpoint in config.get("endpoints",[])],
                                     "device_uuid": device_uuid}
                                     "device_uuid": device_uuid,
                                     "type":config_type
                                     }
        )
            
       
@@ -97,12 +122,26 @@ def set_opticalconfig(db_engine : Engine, request : OpticalConfig):
        )
        stmt = stmt.returning(OpticalConfigModel.opticalconfig_uuid)
        opticalconfig_id = session.execute(stmt).fetchone()
        if config_type == 'optical-transponder':
            if (len(transponder)>0):
                stmt = insert(TransponderTypeModel).values(transponder)
            
                stmt = stmt.on_conflict_do_update(
                        index_elements=[TransponderTypeModel.transponder_uuid],
                        set_=dict(
                            transcievers= stmt.excluded.transcievers ,
                        )
                        
                    )
                stmt = stmt.returning(TransponderTypeModel.transponder_uuid)
                transponder_id = session.execute(stmt).fetchone()
                
            if (len(channels)>0) :

                    stmt = insert(OpticalChannelModel).values(channels)
            
                    stmt = stmt.on_conflict_do_update(
                    index_elements=[OpticalChannelModel.channel_uuid , OpticalConfigModel.opticalconfig_uuid],
                        index_elements=[OpticalChannelModel.channel_uuid ],
                        set_=dict(
                            channel_name= stmt.excluded.channel_name ,
                            frequency = stmt.excluded.frequency,
+51 −18
Original line number Diff line number Diff line
@@ -21,13 +21,16 @@ from ._Base import _Base
class OpticalConfigModel(_Base):
    __tablename__ = 'optical_config'
    opticalconfig_uuid = Column(String, primary_key=True)
   
    transcievers       = Column(ARRAY(String), nullable=True)
    interfaces         = Column(String, nullable=True)
    channel_namespace  = Column(String, nullable=True)
    endpoints          = Column(ARRAY(String), nullable=True)
    type               = Column(String,nullable=False)
    
    channels           = relationship("OpticalChannelModel")
    # transcievers       = Column(ARRAY(String), nullable=True)
    # interfaces         = Column(String, nullable=True)
  
   
    #channels           = relationship("OpticalChannelModel")
    transponders=relationship("TransponderTypeModel")
    
    
    device_uuid = Column(ForeignKey("device.device_uuid",ondelete="CASCADE"),index=True ,nullable=False)
@@ -43,26 +46,56 @@ class OpticalConfigModel(_Base):

    def dump(self):
        return {
            "channels"          : [channel.dump() for channel in self.channels],
            "transceivers"      : {"transceiver": [transciever for transciever in self.transcievers]},
            "interfaces"        : {"interface":json.loads(self.interfaces) if self.interfaces else ''},
            # "channels"          : [channel.dump() for channel in self.channels],
            # "transceivers"      : {"transceiver": [transciever for transciever in self.transcievers]},
            # "interfaces"        : {"interface":json.loads(self.interfaces) if self.interfaces else ''},
            "channel_namespace" : self.channel_namespace,
            "endpoints"         : [json.loads(endpoint) for endpoint in self.endpoints if endpoint],
            "device_name": self.device.device_name
            "device_name"       : self.device.device_name,
            "transponder"       : [transponer.dump() for transponer in self.transponders if self.type =="optical-transponder" ],
            "type"              : self.type
        }
        

class TransponderTypeModel (_Base):
    
    __tablename__             = 'transponder_type'
    transponder_uuid          = Column(String, primary_key=True)
           
    transcievers              = Column(ARRAY(String), nullable=True)
    interfaces                = Column(String, nullable=True)
    channels                  = relationship("OpticalChannelModel")
    
    opticalconfig_uuid        = Column(ForeignKey('optical_config.opticalconfig_uuid',  ondelete='CASCADE' ),index=True ,nullable=False)
    opticalconfig             = relationship('OpticalConfigModel',     back_populates='transponders')
    
    def dump_id (self): 
        return {
            "transponder_uuid":self.transponder_uuid
        }
    
    def dump (self):
        return {
            #"channels"          : [channel.dump() for channel in self.channels],
            "transceivers"      : {"transceiver": [transciever for transciever in self.transcievers]},
            "interfaces"        : {"interface":json.loads(self.interfaces) if self.interfaces else ''},
            "trasponder_uuid"   : self.dump_id()
        }

class OpticalChannelModel(_Base):
    __tablename__         =      'optical_channel'
    channel_uuid          =       Column(String, primary_key=True)
    
    channel_name          =       Column (String,nullable=True)
    frequency             =       Column(Integer, nullable=True)
    operational_mode      =       Column(Integer, nullable=True)
    status                =       Column(String , nullable=True)
    target_output_power   =       Column(String, nullable=True)
    opticalconfig_uuid        = Column(ForeignKey('optical_config.opticalconfig_uuid',         ondelete='CASCADE' ), primary_key=True)
    opticalconfig             = relationship('OpticalConfigModel',     back_populates='channels')
    
    transponder_uuid      =       Column(ForeignKey('transponder_type.transponder_uuid', ondelete='CASCADE' ),nullable=False)
    transponder           =       relationship('TransponderTypeModel',back_populates='channels')
    # opticalconfig_uuid        = Column(ForeignKey('optical_config.opticalconfig_uuid',         ondelete='CASCADE' ), primary_key=True)
    # opticalconfig             = relationship('OpticalConfigModel',     back_populates='channels')
    def dump_id (self ):
        return {
            "channel_uuid":self.channel_uuid
+16 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
from common.method_wrappers.ServiceExceptions import InvalidArgumentsException
from ._Builder import get_uuid_from_string, get_uuid_random
from common.proto.context_pb2 import DeviceId

def channel_get_uuid(
    channel_name :str , allow_random : bool = False
) -> str:
@@ -16,6 +17,21 @@ def channel_get_uuid(
       
    ], extra_details=['Channel name is required to produce a channel UUID'])

def transponder_get_uuid(
    opticalconfig_id :str , allow_random : bool = False
) -> str:
    

    if opticalconfig_id is not None:
        return get_uuid_from_string(f"{opticalconfig_id}-transponder")
    if allow_random: return get_uuid_random()

    raise InvalidArgumentsException([
        ('transponder uuid', opticalconfig_id),
       
    ], extra_details=['Channel name is required to produce a channel UUID'])
    

def opticalconfig_get_uuid ( device_id: DeviceId, allow_random : bool = False) -> str : 
    device_uuid = device_id.device_uuid.uuid
    if (len(device_uuid)>0):
+16 −8
Original line number Diff line number Diff line
@@ -37,8 +37,8 @@ from .RetryDecorator import retry
from context.client.ContextClient import ContextClient
from common.proto.context_pb2 import (
    OpticalConfig)
from .templates.Tools import roadm_values_extractor, transponder_values_extractor

from .templates.descovery_tool.transponders import  transponder_values_extractor
from .templates.descovery_tool.roadms import roadm_values_extractor ,openroadm_values_extractor
DEBUG_MODE = False
logging.getLogger('ncclient.manager').setLevel(logging.DEBUG if DEBUG_MODE else logging.WARNING)
logging.getLogger('ncclient.transport.ssh').setLevel(logging.DEBUG if DEBUG_MODE else logging.WARNING)
@@ -271,17 +271,25 @@ class OCDriver(_Driver):
            transceivers={}
            oc_values={}
            ports_result=[]
            oc_values["type"]=self.__type
            try:    
                oc_values["transponder"]={}
                xml_data = self.__netconf_handler.get().data_xml
                
                logging.info(f"type {self.__type}")
                if (self.__type == "optical-transponder"):
                    extracted_values=transponder_values_extractor(data_xml=xml_data,resource_keys=transponder_filter_fields,dic=config)     
                    transceivers,optical_channels_params,channel_namespace,endpoints,ports_result=extracted_values
                    oc_values["channels"]=optical_channels_params
                    oc_values["transceivers"]=transceivers     
                    oc_values["channel_namespace"]=channel_namespace
                    oc_values["endpoints"]=endpoints
                    oc_values["ports"]=ports_result
                    oc_values["transponder"]["channels"]=optical_channels_params
                    oc_values["transponder"]["transceivers"]=transceivers     
                    oc_values["transponder"]["channel_namespace"]=channel_namespace
                    oc_values["transponder"]["endpoints"]=endpoints
                    oc_values["transponder"]["ports"]=ports_result
                elif (self.__type =='openroadm')    :
                   extracted_values=openroadm_values_extractor(data_xml=xml_data,resource_keys=[],dic=oc_values)
                   ports_result = extracted_values[1]

                    
                    
                else :
                    extracted_values=roadm_values_extractor(data_xml=xml_data,resource_keys=[],dic=config)
                    ports_result = extracted_values[0]
+97 −1
Original line number Diff line number Diff line
@@ -368,3 +368,99 @@ def roadm_values_extractor (data_xml:str,resource_keys:list,dic:dict):
        ports_result.append((resource_key, resource_value))
      
     return [ports_result]   
 
 
 
 #/////////////// OpenRoadm //////////////
 
 
def extract_roadm_circuits_pack (xml_data:str):
  
   
    xml_bytes = xml_data.encode("utf-8")
    root = ET.fromstring(xml_bytes)
    # with open('xml.log', 'w') as f:
    #      print(xml_bytes, file=f)
    
    
    namespace = {'oc': "http://org/openroadm/device"}
    
    circuits = root.findall('.//oc:circuit-packs',namespace)
  
    circuits_list =[]
    # print(f"component {components}")
    
    if (circuits is not None):
        circuit_info ={}
        for circuit  in circuits:
        
            circuit_name = circuit.find(".//oc:circuit-pack-name",namespace)
            circuit_type=circuit.find(".//oc:circuit-pack-type",namespace)
            circuit_adminstrative_status=circuit.find(".//oc:administrative-state",namespace)
            circuit_equipment_state=circuit.find("./oc:equipment-state",namespace)
            circuit_mode=circuit.find("./oc:circuit-pack-mode",namespace)
            slot= circuit.find("./oc:slot",namespace)
            shelf= circuit.find("./oc:shelf",namespace)
            ports = circuit.findall("./oc:ports",namespace)
           
            circuit_ports=[]
            if (ports is not None):
                
                for port in ports :
                    port_info={}
                    port_name=port.find('./oc:port-name',namespace)
                    port_qual= port.find("./oc:port-qual",namespace)
                   
                    if port_name is not None :
                        port_info["port_name"]=port_name.text
                    if port_qual is not None :
                        port_info["port_qual"]=port_qual.text
                    circuit_ports.append(port_info)            
            if (circuit_name is not None):
                circuit_info["circuit_name"]=circuit_name.text
            if (circuit_type is not None):
                circuit_info["circuit_type"]=circuit_type.text
            if (circuit_adminstrative_status is not None):
                circuit_info["circuit_adminstrative_status"]=circuit_adminstrative_status.text
            if (circuit_equipment_state is not None):
                circuit_info["circuit_equipment_state"]=circuit_equipment_state.text
            if (circuit_mode is not None):
                circuit_info["circuit_mode"]=circuit_mode.text
            if (slot is not None):
                circuit_info["slot"]=slot.text
            if (shelf is not None):
                circuit_info["shelf"]=shelf.text
            circuit_info["ports"]=circuit_ports 
                                   
            circuits_list.append(circuit_info)   
          
        
    return circuits_list                



def extract_openroadm_info(xml_data:str):
    roadm_info={"node-id":None,"node-number":None,"node-type":None,'clli':None}
    xml_bytes = xml_data.encode("utf-8")
    root = ET.fromstring(xml_bytes)
    namespace = {'oc': "http://org/openroadm/device"}
    info = root.findall('.//oc:info',namespace)
    if info is not None :
        for i in info :
            node_id= i.find('.//oc:node-id',namespace)
            node_number= i.find('.//oc:node-number',namespace)
            node_type=i.find('.//oc:node-type',namespace)
            clli=i.find('.//oc:clli',namespace)
            if (node_id is not None):
                roadm_info['node-id']=node_id.text
            if (node_number is not None):
                roadm_info['node-number']=node_number.text
            if (node_type is not None):
                roadm_info['node-type']=node_type.text
            if (clli is not None):
                roadm_info['clli']=clli.text
    return roadm_info                    


    
              
 No newline at end of file
Loading