Loading proto/context.proto +39 −9 Original line number Diff line number Diff line Loading @@ -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 ) {} } Loading Loading @@ -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 //////////// Loading src/context/client/ContextClient.py +13 −5 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 src/context/service/ContextServiceServicerImpl.py +18 −10 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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__) Loading Loading @@ -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 src/context/service/database/Tapi.py +109 −46 Original line number Diff line number Diff line Loading @@ -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__) Loading @@ -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))\ Loading @@ -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) Loading @@ -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) Loading Loading @@ -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 src/context/service/database/models/OpticalLinkModel.py +1 −1 Original line number Diff line number Diff line Loading @@ -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 Loading
proto/context.proto +39 −9 Original line number Diff line number Diff line Loading @@ -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 ) {} } Loading Loading @@ -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 //////////// Loading
src/context/client/ContextClient.py +13 −5 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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
src/context/service/ContextServiceServicerImpl.py +18 −10 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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__) Loading Loading @@ -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
src/context/service/database/Tapi.py +109 −46 Original line number Diff line number Diff line Loading @@ -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__) Loading @@ -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))\ Loading @@ -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) Loading @@ -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) Loading Loading @@ -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
src/context/service/database/models/OpticalLinkModel.py +1 −1 Original line number Diff line number Diff line Loading @@ -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