Commit 6230f618 authored by Mohammad Ismaeel's avatar Mohammad Ismaeel
Browse files

GetChildTopologyDetails route

parent 92bcac51
Loading
Loading
Loading
Loading
+39 −9
Original line number Diff line number Diff line
@@ -96,10 +96,10 @@ service ContextService {

  rpc ListChildTopologies     (ContextId          ) returns (ChildTopologyList    ) {}
  rpc GetChildTopology        (TopologyId         ) returns (ChildTopology        ) {}
  rpc GetChildTopologyDetails (TopologyId    ) returns (       TopologyDetails ) {}
  rpc SetChildTopology        (ChildTopology      ) returns (       TopologyId      ) {}
  rpc RemoveChildTopology     (TopologyId    ) returns (       Empty           ) {}

  rpc GetChildDevice          (DeviceId           ) returns (ChildDevice          ) {}
  rpc SetChildTopology        (ChildTopology      ) returns (ChildTopologyId      ) {}
  rpc RemoveChildTopology     (ChildTopologyId    ) returns (Empty                ) {}
  rpc GetTopologyByDeviceId   (DeviceId           ) returns (ChildTopology        ) {}
 
  rpc DeleteServiceConfigRule(ServiceConfigRule) returns (Empty                  ) {}
}
@@ -769,18 +769,48 @@ message OpticalBandList {
}


/////////////////////////// TAPI Experimental ////////////////////////////

message ChildTopology {

  string host = 1; 
  int32 port = 2;
  Topology topology = 3 ;
  repeated ChildDevice devices = 3 ;
  repeated ChildOpticallink optical_links =4 ;
  ChildTopologyId topology_id = 5 ;

}

message ChildTopologyList {
  repeated ChildTopology topology_list = 1 ;
}
message ChildTopologyId {
  Uuid topology_uuid =1 ;

}

message ChildDevice {
  DeviceId device_id = 1 ; 
  string device_name =2 ; 
  ChildTopologyId topology_id =3 ; 
  repeated ChildEndpoint endpoints = 4 ;

}
message ChildEndpointId {
  Uuid endpoint_uuid =1 ;
}
message ChildEndpoint {
  ChildEndpointId endpoint_id =1 ; 
  DeviceId device_id =2 ; 
  string endpoint_name = 3 ;
  ChildTopologyId topology_id = 4 ;
}
message ChildOpticallink {
  LinkId link_id =1 ; 
  string optical_link_name =2 ; 
  ChildTopologyId topology_id = 3;

}


////////////////// Config Rule Delete ////////////
+13 −5
Original line number Diff line number Diff line
@@ -28,7 +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  , ChildTopologyList , ChildTopology  
    OpticalBandList  , ChildTopologyList , ChildTopology  , ChildDevice
)
from common.proto.context_pb2_grpc import ContextServiceStub
from common.proto.context_policy_pb2_grpc import ContextPolicyServiceStub
@@ -598,8 +598,16 @@ class ContextClient:


    @RETRY_DECORATOR
    def GetChildTopologyDetails(self, request: TopologyId) -> TopologyDetails:
        LOGGER.debug('GetChildTopologyDetails request: {:s}'.format(grpc_message_to_json_string(request)))
        response = self.stub.GetChildTopologyDetails(request)
        LOGGER.debug('GetChildTopologyDetails result: {:s}'.format(grpc_message_to_json_string(response)))
    def GetChildDevice(self, request: DeviceId) -> ChildDevice:
        LOGGER.debug('GetChildDevice request: {:s}'.format(grpc_message_to_json_string(request)))
        response = self.stub.GetChildDevice(request)
        LOGGER.debug('GetChildDevice result: {:s}'.format(grpc_message_to_json_string(response)))
        return response
    
    @RETRY_DECORATOR
    def GetTopologyByDeviceId(self, request: DeviceId) -> ChildTopology:
        LOGGER.debug('GetTopologyByDeviceId request: {:s}'.format(grpc_message_to_json_string(request)))
        response = self.stub.GetTopologyByDeviceId(request)
        LOGGER.debug('GetTopologyByDeviceId result: {:s}'.format(grpc_message_to_json_string(response)))
        return response
+18 −10
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,
    ServiceConfigRule,OpticalBand,OpticalBandId,OpticalBandList , ChildTopologyList , ChildTopology  
    ServiceConfigRule,OpticalBand,OpticalBandId,OpticalBandList , ChildTopologyList , ChildTopology ,
    ChildTopologyId , ChildDevice , ChildEndpoint , ChildOpticallink 
)
from common.proto.policy_pb2 import PolicyRuleIdList, PolicyRuleId, PolicyRuleList, PolicyRule
from common.proto.context_pb2_grpc import ContextServiceServicer
@@ -74,8 +75,9 @@ from .database.OpticalBand import (
                                   get_optical_band,set_optical_band , select_optical_band
                                   )

from .database.Tapi import ( child_topology_get , child_topology_get_details
                            , child_topology_list_objs , child_topology_delete , child_topology_set)
from .database.Tapi import ( child_topology_get , child_get_device
                            , child_topology_list_objs , child_topology_delete 
                            , child_topology_set , get_topology_by_device_id)

LOGGER = logging.getLogger(__name__)

@@ -411,17 +413,23 @@ class ContextServiceServicerImpl(ContextServiceServicer, ContextPolicyServiceSer
        return child_topology_list_objs(self.db_engine, request)

    @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
    def GetChildTopology(self, request : TopologyId, context : grpc.ServicerContext) -> ChildTopology:
    def GetChildTopology(self, request : ChildTopologyId, context : grpc.ServicerContext) -> ChildTopology:
        return child_topology_get(self.db_engine, request)

    @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
    def GetChildTopologyDetails(self, request : TopologyId, context : grpc.ServicerContext) -> TopologyDetails:
        return child_topology_get_details(self.db_engine, request)

    @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
    def SetChildTopology(self, request : ChildTopology, context : grpc.ServicerContext) -> TopologyId:
    def SetChildTopology(self, request : ChildTopology, context : grpc.ServicerContext) -> ChildTopologyId:
        return child_topology_set(self.db_engine, self.messagebroker, request)

    @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
    def RemoveChildTopology(self, request : TopologyId, context : grpc.ServicerContext) -> Empty:
    def RemoveChildTopology(self, request : ChildTopologyId, context : grpc.ServicerContext) -> Empty:
        return child_topology_delete(self.db_engine, self.messagebroker, request)
    
    @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
    def GetChildDevice(self, request : DeviceId, context : grpc.ServicerContext) -> ChildDevice:
        return child_get_device(self.db_engine, self.messagebroker, request)
    
    @safe_and_metered_rpc_method(METRICS_POOL, LOGGER)
    def GetTopologyByDeviceId(self, request : DeviceId, context : grpc.ServicerContext) -> ChildTopology:
        return get_topology_by_device_id(self.db_engine, self.messagebroker, request)
    
    
 No newline at end of file
+109 −46
Original line number Diff line number Diff line
@@ -19,21 +19,25 @@ from sqlalchemy.orm import Session, selectinload, sessionmaker
from sqlalchemy_cockroachdb import run_transaction
from typing import Dict, List, Optional, Set
from common.proto.context_pb2 import (
    ContextId, Empty, EventTypeEnum, ChildTopology, TopologyDetails, TopologyId, ChildTopologyList , Topology)
    ContextId, Empty, EventTypeEnum, ChildTopology, TopologyDetails
    , ChildTopologyId, ChildTopologyList  , DeviceId , ChildDevice)
from common.message_broker.MessageBroker import MessageBroker
from common.method_wrappers.ServiceExceptions import NotFoundException
from common.tools.object_factory.Context import json_context_id
from common.tools.object_factory.Topology import json_topology_id
from context.Config import ALLOW_EXPLICIT_ADD_DEVICE_TO_TOPOLOGY, ALLOW_EXPLICIT_ADD_LINK_TO_TOPOLOGY
from .models.enums.KpiSampleType import grpc_to_enum__kpi_sample_type
from .models.DeviceModel import DeviceModel

from common.tools.grpc.Tools import grpc_message_to_json_string
from .models.OpticalLinkModel import OpticalLinkModel
from .models.TapiModel import ChildTopologyDeviceModel, ChildTopologyOpticalLinkModel, ChildTopologyModel
from .models.TapiModel import (ChildTopologyDeviceModel, ChildTopologyOpticalLinkModel
                               , ChildTopologyModel , ChildTopologyEndponitModel , ChildOpticalLinkEndponitModel)
from .uuids.Context import context_get_uuid
from .uuids.Device import device_get_uuid
from .uuids.Link import link_get_uuid
from .uuids.Topology import topology_get_uuid
from .Events import notify_event_context, notify_event_topology
from .uuids.EndPoint import endpoint_get_uuid


LOGGER = logging.getLogger(__name__)

@@ -49,8 +53,8 @@ def child_topology_list_objs(db_engine : Engine, request : ContextId) -> ChildTo
    topologies = run_transaction(sessionmaker(bind=db_engine), callback)
    return ChildTopologyList(topology_list=topologies)

def child_topology_get(db_engine : Engine, request : TopologyId) -> ChildTopology:
    _,topology_uuid = topology_get_uuid(request, allow_random=False)
def child_topology_get(db_engine : Engine, request : ChildTopologyId) -> ChildTopology:
    topology_uuid = request.topology_uuid.uuid
    def callback(session : Session) -> Optional[Dict]:
        obj : Optional[ChildTopologyModel] = session.query(ChildTopologyModel)\
            .options(selectinload(ChildTopologyModel.child_topology_devices))\
@@ -66,29 +70,10 @@ def child_topology_get(db_engine : Engine, request : TopologyId) -> ChildTopolog
            'context_uuid generated was: {:s}'.format(context_uuid),
            'topology_uuid generated was: {:s}'.format(topology_uuid),
        ])
    return ChildTopology(**obj)
    return obj.dump()

def child_topology_get_details(db_engine : Engine, request : TopologyId) -> TopologyDetails:
    _,topology_uuid = topology_get_uuid(request, allow_random=False)
    def callback(session : Session) -> Optional[Dict]:
        obj : Optional[ChildTopologyModel] = session.query(ChildTopologyModel)\
            .options(selectinload(ChildTopologyModel.child_topology_devices, ChildTopologyModel.device, DeviceModel.endpoints))\
            .options(selectinload(ChildTopologyModel.child_topology_optical_links
                                  , ChildTopologyOpticalLinkModel.optical_link, OpticalLinkModel.opticallink_endpoints))\
            .filter_by(child_topology_uuid=topology_uuid).one_or_none()
            #.options(selectinload(DeviceModel.components))\
        return None if obj is None else obj.dump_details()
    obj = run_transaction(sessionmaker(bind=db_engine), callback)
    if obj is None:
        context_uuid = context_get_uuid(request.topology.context_id, allow_random=False)
        raw_topology_uuid = '{:s}/{:s}'.format(request.context_id.context_uuid.uuid, request.topology_uuid.uuid)
        raise NotFoundException('Topology', raw_topology_uuid, extra_details=[
            'context_uuid generated was: {:s}'.format(context_uuid),
            'topology_uuid generated was: {:s}'.format(topology_uuid),
        ])
    return TopologyDetails(**obj)

def child_topology_set(db_engine : Engine, messagebroker : MessageBroker, request : ChildTopology) -> TopologyId:
def child_topology_set(db_engine : Engine, messagebroker : MessageBroker, request : ChildTopology) -> ChildTopologyId:
    topology_name = request.topology.name
    if len(topology_name) == 0: topology_name = request.topology.topology_id.topology_uuid.uuid
    context_uuid,topology_uuid = topology_get_uuid(request.topology.topology_id, topology_name=topology_name, allow_random=True)
@@ -101,19 +86,38 @@ def child_topology_set(db_engine : Engine, messagebroker : MessageBroker, reques
    # ALLOW_EXPLICIT_ADD_DEVICE_TO_TOPOLOGY and/or ALLOW_EXPLICIT_ADD_LINK_TO_TOPOLOGY.

    related_devices : List[Dict] = list()
    if ALLOW_EXPLICIT_ADD_DEVICE_TO_TOPOLOGY:
    
    device_uuids : Set[str] = set()
        for device_id in request.toplogy.device_ids:
            device_uuid = device_get_uuid(device_id)
            if device_uuid not in device_uuids: continue
            related_devices.append({'topology_uuid': topology_uuid, 'device_uuid': device_uuid})
            device_uuids.add(device_uuid)
    else:
        if len(request.topology.device_ids) > 0: # pragma: no cover
            MSG = 'ALLOW_EXPLICIT_ADD_DEVICE_TO_TOPOLOGY={:s}; '.format(str(ALLOW_EXPLICIT_ADD_DEVICE_TO_TOPOLOGY))
            MSG += 'Items in field "device_ids" ignored. This field is used for retrieval purposes only.'
            LOGGER.warning(MSG)
    related_topology_endpoints : List[Dict] = list()

    for device in request.toplogy.devices:
        device_uuid = device.device_id.device_uuid.uuid
        related_devices.append({'topology_uuid': topology_uuid, 'device_uuid': device_uuid,'device_name': device.name})
   
      
        for i, endpoint in enumerate(device.device_endpoints):
            endpoint_device_uuid = endpoint.endpoint_id.device_id.device_uuid.uuid
            raw_endpoint_uuid = endpoint.endpoint_id.endpoint_uuid.uuid
            raw_endpoint_name = endpoint.name
            related_topology_endpoints.append({
                'endpoint_uuid'    : raw_endpoint_uuid,
                'device_uuid'      : endpoint_device_uuid,
                'topology_uuid'    : topology_uuid,
                'endpoint_name'             : raw_endpoint_name,
                
            })    
            
    related_endpoint_opticallinks : List[Dict] = list()
    related_topology_opticallinks : List[Dict] = list()
    for opticallink in request.topology.optical_links:
        link_uuid = opticallink.link_id.link_uuid.uuid
        link_name = opticallink.name
        related_topology_opticallinks.append({'topology_uuid': topology_uuid, 'optical_link_uuid': 
            link_uuid,'optical_link_name': link_name})
        for endpoint in opticallink.link_endpoint_ids:
            
             related_endpoint_opticallinks.append({'optical_link_uuid': link_uuid,
                                                   'endpoint_uuid': opticallink.endpoint_uuid})
  
    now = datetime.datetime.now(datetime.timezone.utc)

@@ -150,23 +154,82 @@ def child_topology_set(db_engine : Engine, messagebroker : MessageBroker, reques
            topology_device_inserts = session.execute(stmt)
            updated_topology_device = int(topology_device_inserts.rowcount) > 0
        
        if len(related_topology_opticallinks) > 0:
            stmt = insert(ChildTopologyOpticalLinkModel).values(related_topology_opticallinks)
            stmt = stmt.on_conflict_do_nothing(
                index_elements=[ChildTopologyOpticalLinkModel.topology_uuid, ChildTopologyOpticalLinkModel.optical_link_uuid]
            )
            topology_links_inserts = session.execute(stmt)
            updated_topology_links = int(topology_links_inserts.rowcount) > 0
        
        if len(related_topology_endpoints) > 0:
            stmt = insert(ChildTopologyEndponitModel).values(related_topology_endpoints)
            stmt = stmt.on_conflict_do_nothing(
                index_elements=[ChildTopologyEndponitModel.topology_uuid, ChildTopologyEndponitModel.endpoint_uuid]
            )
            topology_endpoints_inserts = session.execute(stmt)
            updated_topology_endpoints = int(topology_endpoints_inserts.rowcount) > 0    
        
        if len(related_endpoint_opticallinks) > 0:
            stmt = insert(ChildOpticalLinkEndponitModel).values(related_endpoint_opticallinks)
            stmt = stmt.on_conflict_do_nothing(
                index_elements=[ChildOpticalLinkEndponitModel.optical_link_uuid, ChildOpticalLinkEndponitModel.endpoint_uuid]
            )
            links_endpoints_inserts = session.execute(stmt)
            updated_topology_endpoints_links = int(links_endpoints_inserts.rowcount) > 0        
    
        

        return updated or updated_topology_device 

    updated = run_transaction(sessionmaker(bind=db_engine), callback)
    context_id = json_context_id(context_uuid)
    topology_id = json_topology_id(topology_uuid, context_id=context_id)
    topology_id = {'topology_uuid':{'uuid': topology_uuid}}
   
    return TopologyId(**topology_id)
    return topology_id

def child_topology_delete(db_engine : Engine, messagebroker : MessageBroker, request : TopologyId) -> Empty:
    context_uuid,topology_uuid = topology_get_uuid(request, allow_random=False)
def child_topology_delete(db_engine : Engine, messagebroker : MessageBroker, request : ChildTopologyId) -> Empty:
    topology_uuid = request.topology_uuid.uuid
    def callback(session : Session) -> bool:
        num_deleted = session.query(ChildTopologyModel).filter_by(child_topology_uuid=topology_uuid).delete()
        return num_deleted > 0
    deleted = run_transaction(sessionmaker(bind=db_engine), callback)
    context_id = json_context_id(context_uuid)
    topology_id = json_topology_id(topology_uuid, context_id=context_id)
    if not deleted:
        
        raw_topology_uuid = '{:s}'.format( request.topology_uuid.uuid)
        raise NotFoundException('Topology', raw_topology_uuid, extra_details=[
            'topology_uuid Not Existed : {:s}'.format(topology_uuid),
        ])
   
    return Empty()

def child_get_device(db_engine : Engine, request : DeviceId) -> List[DeviceModel]:
    device_uuid = request.device_id.device_uuid.uuid
    def callback(session : Session) -> Optional[Dict]:
        obj : Optional[ChildTopologyDeviceModel] = session.query(ChildTopologyDeviceModel)\
            .filter_by(device_uuid=device_uuid).one_or_none()
        return None if obj is None else obj.dump()
    obj = run_transaction(sessionmaker(bind=db_engine), callback)
    if obj is None:
        raw_device_uuid = request.device_uuid.uuid
        raise NotFoundException('Device', raw_device_uuid, extra_details=[
            'device_uuid generated was: {:s}'.format(device_uuid)
        ])
    return obj


def get_topology_by_device_id(db_engine : Engine, request : DeviceId) -> List[DeviceModel]:
    device_uuid = request.device_id.device_uuid.uuid
    def callback(session: Session):
        obj= session.query(ChildTopologyModel)\
            .join(ChildTopologyModel.child_topology_devices)\
            .filter(ChildTopologyDeviceModel.device_uuid == device_uuid)\
            .first()
        return None if obj is None else obj.dump()
    obj = run_transaction(sessionmaker(bind=db_engine), callback)
    if obj is None:
        raw_device_uuid = request.device_id.device_uuid.uuid
        raise NotFoundException('Device', raw_device_uuid, extra_details=[
            'No Topology found for  device uuid : {:s}'.format(device_uuid)
        ])
    return obj
 No newline at end of file
+1 −1
Original line number Diff line number Diff line
@@ -40,7 +40,7 @@ class OpticalLinkModel(_Base):
    s_slots                   = Column (S_Slot,nullable=True)
    opticallink_endpoints     = relationship('OpticalLinkEndPointModel')
    topology_optical_links    = relationship('TopologyOpticalLinkModel', back_populates='optical_link')
    child_topology_optical_links    = relationship('ChildTopologyOpticalLinkModel', back_populates='optical_link')
    #child_topology_optical_links    = relationship('ChildTopologyOpticalLinkModel', back_populates='optical_link')

    def dump_id(self) -> Dict:
        return {'link_uuid': {'uuid': self.opticallink_uuid}}
Loading