From a3f7e8f7466bb98300765a3931fb364a0e8401aa Mon Sep 17 00:00:00 2001 From: gifrerenom <lluis.gifre@cttc.es> Date: Fri, 13 Jan 2023 18:01:18 +0000 Subject: [PATCH] Context: - migrated events for Service and Slice entities - added missing not-nulls to database fields --- .../service/ContextServiceServicerImpl.py | 51 ++-- src/context/service/database/ConfigRule.py | 2 +- src/context/service/database/Connection.py | 2 +- src/context/service/database/Constraint.py | 25 +- src/context/service/database/Service.py | 55 +++-- src/context/service/database/Slice.py | 60 +++-- .../database/models/ConfigRuleModel.py | 4 +- .../database/models/ConstraintModel.py | 4 +- .../service/database/models/ContextModel.py | 4 +- .../service/database/models/DeviceModel.py | 4 +- .../service/database/models/EndPointModel.py | 4 +- .../service/database/models/LinkModel.py | 4 +- .../service/database/models/ServiceModel.py | 4 +- .../service/database/models/SliceModel.py | 4 +- .../service/database/models/TopologyModel.py | 4 +- src/context/tests/test_service.py | 126 +++++----- src/context/tests/test_slice.py | 227 ++++++++++-------- 17 files changed, 336 insertions(+), 248 deletions(-) diff --git a/src/context/service/ContextServiceServicerImpl.py b/src/context/service/ContextServiceServicerImpl.py index 5c9565859..34608d619 100644 --- a/src/context/service/ContextServiceServicerImpl.py +++ b/src/context/service/ContextServiceServicerImpl.py @@ -200,28 +200,29 @@ class ContextServiceServicerImpl(ContextServiceServicer, ContextPolicyServiceSer @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def ListServiceIds(self, request : ContextId, context : grpc.ServicerContext) -> ServiceIdList: - return service_list_ids(self.db_engine, request) + return ServiceIdList(service_ids=service_list_ids(self.db_engine, request)) @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def ListServices(self, request : ContextId, context : grpc.ServicerContext) -> ServiceList: - return service_list_objs(self.db_engine, request) + return ServiceList(services=service_list_objs(self.db_engine, request)) @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def GetService(self, request : ServiceId, context : grpc.ServicerContext) -> Service: - return service_get(self.db_engine, request) + return Service(**service_get(self.db_engine, request)) @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def SetService(self, request : Service, context : grpc.ServicerContext) -> ServiceId: - service_id,updated = service_set(self.db_engine, request) # pylint: disable=unused-variable - #event_type = EventTypeEnum.EVENTTYPE_UPDATE if updated else EventTypeEnum.EVENTTYPE_CREATE - #notify_event(self.messagebroker, TOPIC_SERVICE, event_type, {'service_id': service_id}) - return service_id + service_id,updated = service_set(self.db_engine, request) + event_type = EventTypeEnum.EVENTTYPE_UPDATE if updated else EventTypeEnum.EVENTTYPE_CREATE + notify_event(self.messagebroker, TOPIC_SERVICE, event_type, {'service_id': service_id}) + return ServiceId(**service_id) @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def RemoveService(self, request : ServiceId, context : grpc.ServicerContext) -> Empty: - deleted = service_delete(self.db_engine, request) # pylint: disable=unused-variable - #if deleted: - # notify_event(self.messagebroker, TOPIC_SERVICE, EventTypeEnum.EVENTTYPE_REMOVE, {'service_id': request}) + service_id,deleted = service_delete(self.db_engine, request) + if deleted: + event_type = EventTypeEnum.EVENTTYPE_REMOVE + notify_event(self.messagebroker, TOPIC_SERVICE, event_type, {'service_id': service_id}) return Empty() @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) @@ -234,35 +235,37 @@ class ContextServiceServicerImpl(ContextServiceServicer, ContextPolicyServiceSer @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def ListSliceIds(self, request : ContextId, context : grpc.ServicerContext) -> SliceIdList: - return slice_list_ids(self.db_engine, request) + return SliceIdList(slice_ids=slice_list_ids(self.db_engine, request)) @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def ListSlices(self, request : ContextId, context : grpc.ServicerContext) -> SliceList: - return slice_list_objs(self.db_engine, request) + return SliceList(slices=slice_list_objs(self.db_engine, request)) @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def GetSlice(self, request : SliceId, context : grpc.ServicerContext) -> Slice: - return slice_get(self.db_engine, request) + return Slice(**slice_get(self.db_engine, request)) @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def SetSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId: - slice_id,updated = slice_set(self.db_engine, request) # pylint: disable=unused-variable - #event_type = EventTypeEnum.EVENTTYPE_UPDATE if updated else EventTypeEnum.EVENTTYPE_CREATE - #notify_event(self.messagebroker, TOPIC_SLICE, event_type, {'slice_id': slice_id}) - return slice_id + slice_id,updated = slice_set(self.db_engine, request) + event_type = EventTypeEnum.EVENTTYPE_UPDATE if updated else EventTypeEnum.EVENTTYPE_CREATE + notify_event(self.messagebroker, TOPIC_SLICE, event_type, {'slice_id': slice_id}) + return SliceId(**slice_id) @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def UnsetSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId: - slice_id,updated = slice_unset(self.db_engine, request) # pylint: disable=unused-variable - #if updated: - # notify_event(self.messagebroker, TOPIC_SLICE, EventTypeEnum.EVENTTYPE_UPDATE, {'slice_id': slice_id}) - return slice_id + slice_id,updated = slice_unset(self.db_engine, request) + if updated: + event_type = EventTypeEnum.EVENTTYPE_UPDATE + notify_event(self.messagebroker, TOPIC_SLICE, event_type, {'slice_id': slice_id}) + return SliceId(**slice_id) @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) def RemoveSlice(self, request : SliceId, context : grpc.ServicerContext) -> Empty: - deleted = slice_delete(self.db_engine, request) # pylint: disable=unused-variable - #if deleted: - # notify_event(self.messagebroker, TOPIC_SLICE, EventTypeEnum.EVENTTYPE_REMOVE, {'slice_id': request}) + slice_id,deleted = slice_delete(self.db_engine, request) + if deleted: + event_type = EventTypeEnum.EVENTTYPE_REMOVE + notify_event(self.messagebroker, TOPIC_SLICE, event_type, {'slice_id': slice_id}) return Empty() @safe_and_metered_rpc_method(METRICS_POOL, LOGGER) diff --git a/src/context/service/database/ConfigRule.py b/src/context/service/database/ConfigRule.py index 5f701386f..5443e178c 100644 --- a/src/context/service/database/ConfigRule.py +++ b/src/context/service/database/ConfigRule.py @@ -51,7 +51,7 @@ def compose_config_rules_data( def upsert_config_rules( session : Session, config_rules : List[Dict], device_uuid : Optional[str] = None, service_uuid : Optional[str] = None, slice_uuid : Optional[str] = None, -) -> bool: +) -> List[bool]: # TODO: do not delete all rules; just add-remove as needed stmt = delete(ConfigRuleModel) if device_uuid is not None: stmt = stmt.where(ConfigRuleModel.device_uuid == device_uuid ) diff --git a/src/context/service/database/Connection.py b/src/context/service/database/Connection.py index 42fc86ebf..2f6fb8433 100644 --- a/src/context/service/database/Connection.py +++ b/src/context/service/database/Connection.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import re +import datetime, logging, re from sqlalchemy.dialects.postgresql import insert from sqlalchemy.engine import Engine from sqlalchemy.exc import IntegrityError diff --git a/src/context/service/database/Constraint.py b/src/context/service/database/Constraint.py index f79159a35..2880c05a8 100644 --- a/src/context/service/database/Constraint.py +++ b/src/context/service/database/Constraint.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import datetime, logging from sqlalchemy import delete from sqlalchemy.dialects.postgresql import insert from sqlalchemy.orm import Session @@ -21,8 +22,10 @@ from common.tools.grpc.Tools import grpc_message_to_json_string from .models.ConstraintModel import ConstraintKindEnum, ConstraintModel from .uuids._Builder import get_uuid_random +LOGGER = logging.getLogger(__name__) + def compose_constraints_data( - constraints : List[Constraint], + constraints : List[Constraint], now : datetime.datetime, service_uuid : Optional[str] = None, slice_uuid : Optional[str] = None ) -> List[Dict]: dict_constraints : List[Dict] = list() @@ -33,6 +36,8 @@ def compose_constraints_data( 'position' : position, 'kind' : ConstraintKindEnum._member_map_.get(str_kind.upper()), # pylint: disable=no-member 'data' : grpc_message_to_json_string(getattr(constraint, str_kind, {})), + 'created_at' : now, + 'updated_at' : now, } if service_uuid is not None: dict_constraint['service_uuid'] = service_uuid if slice_uuid is not None: dict_constraint['slice_uuid' ] = slice_uuid @@ -42,13 +47,27 @@ def compose_constraints_data( def upsert_constraints( session : Session, constraints : List[Dict], service_uuid : Optional[str] = None, slice_uuid : Optional[str] = None -) -> None: +) -> List[bool]: + # TODO: do not delete all constraints; just add-remove as needed stmt = delete(ConstraintModel) if service_uuid is not None: stmt = stmt.where(ConstraintModel.service_uuid == service_uuid) if slice_uuid is not None: stmt = stmt.where(ConstraintModel.slice_uuid == slice_uuid ) session.execute(stmt) + + constraint_updates = [] if len(constraints) > 0: - session.execute(insert(ConstraintModel).values(constraints)) + stmt = insert(ConstraintModel).values(constraints) + #stmt = stmt.on_conflict_do_update( + # index_elements=[ConstraintModel.configrule_uuid], + # set_=dict( + # updated_at = stmt.excluded.updated_at, + # ) + #) + stmt = stmt.returning(ConstraintModel.created_at, ConstraintModel.updated_at) + constraint_updates = session.execute(stmt).fetchall() + + return constraint_updates + # def set_constraint(self, db_constraints: ConstraintsModel, grpc_constraint: Constraint, position: int # ) -> Tuple[Union_ConstraintModel, bool]: diff --git a/src/context/service/database/Service.py b/src/context/service/database/Service.py index 247914d65..a8f9f40d6 100644 --- a/src/context/service/database/Service.py +++ b/src/context/service/database/Service.py @@ -12,12 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +import datetime, logging from sqlalchemy.dialects.postgresql import insert from sqlalchemy.engine import Engine from sqlalchemy.orm import Session, sessionmaker from sqlalchemy_cockroachdb import run_transaction from typing import Dict, List, Optional, Tuple -from common.proto.context_pb2 import ContextId, Service, ServiceId, ServiceIdList, ServiceList +from common.proto.context_pb2 import ContextId, Service, ServiceId from common.method_wrappers.ServiceExceptions import InvalidArgumentException, NotFoundException from common.tools.object_factory.Context import json_context_id from common.tools.object_factory.Service import json_service_id @@ -30,23 +31,23 @@ from .uuids.Context import context_get_uuid from .uuids.EndPoint import endpoint_get_uuid from .uuids.Service import service_get_uuid -def service_list_ids(db_engine : Engine, request : ContextId) -> ServiceIdList: +LOGGER = logging.getLogger(__name__) + +def service_list_ids(db_engine : Engine, request : ContextId) -> List[Dict]: context_uuid = context_get_uuid(request, allow_random=False) def callback(session : Session) -> List[Dict]: obj_list : List[ServiceModel] = session.query(ServiceModel).filter_by(context_uuid=context_uuid).all() - #.options(selectinload(ContextModel.service)).filter_by(context_uuid=context_uuid).one_or_none() return [obj.dump_id() for obj in obj_list] - return ServiceIdList(service_ids=run_transaction(sessionmaker(bind=db_engine), callback)) + return run_transaction(sessionmaker(bind=db_engine), callback) -def service_list_objs(db_engine : Engine, request : ContextId) -> ServiceList: +def service_list_objs(db_engine : Engine, request : ContextId) -> List[Dict]: context_uuid = context_get_uuid(request, allow_random=False) def callback(session : Session) -> List[Dict]: obj_list : List[ServiceModel] = session.query(ServiceModel).filter_by(context_uuid=context_uuid).all() - #.options(selectinload(ContextModel.service)).filter_by(context_uuid=context_uuid).one_or_none() return [obj.dump() for obj in obj_list] - return ServiceList(services=run_transaction(sessionmaker(bind=db_engine), callback)) + return run_transaction(sessionmaker(bind=db_engine), callback) -def service_get(db_engine : Engine, request : ServiceId) -> Service: +def service_get(db_engine : Engine, request : ServiceId) -> Dict: _,service_uuid = service_get_uuid(request, allow_random=False) def callback(session : Session) -> Optional[Dict]: obj : Optional[ServiceModel] = session.query(ServiceModel).filter_by(service_uuid=service_uuid).one_or_none() @@ -59,9 +60,9 @@ def service_get(db_engine : Engine, request : ServiceId) -> Service: 'context_uuid generated was: {:s}'.format(context_uuid), 'service_uuid generated was: {:s}'.format(service_uuid), ]) - return Service(**obj) + return obj -def service_set(db_engine : Engine, request : Service) -> Tuple[ServiceId, bool]: +def service_set(db_engine : Engine, request : Service) -> Tuple[Dict, bool]: raw_context_uuid = request.service_id.context_id.context_uuid.uuid raw_service_uuid = request.service_id.service_uuid.uuid raw_service_name = request.name @@ -71,6 +72,8 @@ def service_set(db_engine : Engine, request : Service) -> Tuple[ServiceId, bool] service_type = grpc_to_enum__service_type(request.service_type) service_status = grpc_to_enum__service_status(request.service_status.service_status) + now = datetime.datetime.utcnow() + service_endpoints_data : List[Dict] = list() for i,endpoint_id in enumerate(request.service_endpoint_ids): endpoint_context_uuid = endpoint_id.topology_id.context_id.context_uuid.uuid @@ -87,8 +90,8 @@ def service_set(db_engine : Engine, request : Service) -> Tuple[ServiceId, bool] 'endpoint_uuid': endpoint_uuid, }) - constraints = compose_constraints_data(request.service_constraints, service_uuid=service_uuid) - config_rules = compose_config_rules_data(request.service_config.config_rules, service_uuid=service_uuid) + constraints = compose_constraints_data(request.service_constraints, now, service_uuid=service_uuid) + config_rules = compose_config_rules_data(request.service_config.config_rules, now, service_uuid=service_uuid) service_data = [{ 'context_uuid' : context_uuid, @@ -96,9 +99,11 @@ def service_set(db_engine : Engine, request : Service) -> Tuple[ServiceId, bool] 'service_name' : service_name, 'service_type' : service_type, 'service_status': service_status, + 'created_at' : now, + 'updated_at' : now, }] - def callback(session : Session) -> None: + def callback(session : Session) -> bool: stmt = insert(ServiceModel).values(service_data) stmt = stmt.on_conflict_do_update( index_elements=[ServiceModel.service_uuid], @@ -108,7 +113,9 @@ def service_set(db_engine : Engine, request : Service) -> Tuple[ServiceId, bool] service_status = stmt.excluded.service_status, ) ) - session.execute(stmt) + stmt = stmt.returning(ServiceModel.created_at, ServiceModel.updated_at) + created_at,updated_at = session.execute(stmt).fetchone() + updated = updated_at > created_at stmt = insert(ServiceEndPointModel).values(service_endpoints_data) stmt = stmt.on_conflict_do_nothing( @@ -116,17 +123,21 @@ def service_set(db_engine : Engine, request : Service) -> Tuple[ServiceId, bool] ) session.execute(stmt) - upsert_constraints(session, constraints, service_uuid=service_uuid) - upsert_config_rules(session, config_rules, service_uuid=service_uuid) + constraint_updates = upsert_constraints(session, constraints, service_uuid=service_uuid) + updated = updated or any([(updated_at > created_at) for created_at,updated_at in constraint_updates]) - run_transaction(sessionmaker(bind=db_engine), callback) - updated = False # TODO: improve and check if created/updated - return ServiceId(**json_service_id(service_uuid, json_context_id(context_uuid))),updated + configrule_updates = upsert_config_rules(session, config_rules, service_uuid=service_uuid) + updated = updated or any([(updated_at > created_at) for created_at,updated_at in configrule_updates]) + return updated -def service_delete(db_engine : Engine, request : ServiceId) -> bool: - _,service_uuid = service_get_uuid(request, allow_random=False) + updated = run_transaction(sessionmaker(bind=db_engine), callback) + return json_service_id(service_uuid, json_context_id(context_uuid)),updated + +def service_delete(db_engine : Engine, request : ServiceId) -> Tuple[Dict, bool]: + context_uuid,service_uuid = service_get_uuid(request, allow_random=False) def callback(session : Session) -> bool: num_deleted = session.query(ServiceModel).filter_by(service_uuid=service_uuid).delete() return num_deleted > 0 - return run_transaction(sessionmaker(bind=db_engine), callback) + deleted = run_transaction(sessionmaker(bind=db_engine), callback) + return json_service_id(service_uuid, json_context_id(context_uuid)),deleted diff --git a/src/context/service/database/Slice.py b/src/context/service/database/Slice.py index e963fb772..f255968b2 100644 --- a/src/context/service/database/Slice.py +++ b/src/context/service/database/Slice.py @@ -12,13 +12,14 @@ # See the License for the specific language governing permissions and # limitations under the License. +import datetime, logging from sqlalchemy import and_ from sqlalchemy.dialects.postgresql import insert from sqlalchemy.engine import Engine from sqlalchemy.orm import Session, sessionmaker from sqlalchemy_cockroachdb import run_transaction from typing import Dict, List, Optional, Set, Tuple -from common.proto.context_pb2 import ContextId, Slice, SliceId, SliceIdList, SliceList +from common.proto.context_pb2 import ContextId, Slice, SliceId from common.method_wrappers.ServiceExceptions import InvalidArgumentException, NotFoundException from common.tools.object_factory.Context import json_context_id from common.tools.object_factory.Slice import json_slice_id @@ -31,23 +32,23 @@ from .uuids.EndPoint import endpoint_get_uuid from .uuids.Service import service_get_uuid from .uuids.Slice import slice_get_uuid -def slice_list_ids(db_engine : Engine, request : ContextId) -> SliceIdList: +LOGGER = logging.getLogger(__name__) + +def slice_list_ids(db_engine : Engine, request : ContextId) -> List[Dict]: context_uuid = context_get_uuid(request, allow_random=False) def callback(session : Session) -> List[Dict]: obj_list : List[SliceModel] = session.query(SliceModel).filter_by(context_uuid=context_uuid).all() - #.options(selectinload(ContextModel.slice)).filter_by(context_uuid=context_uuid).one_or_none() return [obj.dump_id() for obj in obj_list] - return SliceIdList(slice_ids=run_transaction(sessionmaker(bind=db_engine), callback)) + return run_transaction(sessionmaker(bind=db_engine), callback) -def slice_list_objs(db_engine : Engine, request : ContextId) -> SliceList: +def slice_list_objs(db_engine : Engine, request : ContextId) -> List[Dict]: context_uuid = context_get_uuid(request, allow_random=False) def callback(session : Session) -> List[Dict]: obj_list : List[SliceModel] = session.query(SliceModel).filter_by(context_uuid=context_uuid).all() - #.options(selectinload(ContextModel.slice)).filter_by(context_uuid=context_uuid).one_or_none() return [obj.dump() for obj in obj_list] - return SliceList(slices=run_transaction(sessionmaker(bind=db_engine), callback)) + return run_transaction(sessionmaker(bind=db_engine), callback) -def slice_get(db_engine : Engine, request : SliceId) -> Slice: +def slice_get(db_engine : Engine, request : SliceId) -> Dict: _,slice_uuid = slice_get_uuid(request, allow_random=False) def callback(session : Session) -> Optional[Dict]: obj : Optional[SliceModel] = session.query(SliceModel).filter_by(slice_uuid=slice_uuid).one_or_none() @@ -60,9 +61,9 @@ def slice_get(db_engine : Engine, request : SliceId) -> Slice: 'context_uuid generated was: {:s}'.format(context_uuid), 'slice_uuid generated was: {:s}'.format(slice_uuid), ]) - return Slice(**obj) + return obj -def slice_set(db_engine : Engine, request : Slice) -> Tuple[SliceId, bool]: +def slice_set(db_engine : Engine, request : Slice) -> Tuple[Dict, bool]: raw_context_uuid = request.slice_id.context_id.context_uuid.uuid raw_slice_uuid = request.slice_id.slice_uuid.uuid raw_slice_name = request.name @@ -71,6 +72,8 @@ def slice_set(db_engine : Engine, request : Slice) -> Tuple[SliceId, bool]: slice_status = grpc_to_enum__slice_status(request.slice_status.slice_status) + now = datetime.datetime.utcnow() + slice_endpoints_data : List[Dict] = list() for i,endpoint_id in enumerate(request.slice_endpoint_ids): endpoint_context_uuid = endpoint_id.topology_id.context_id.context_uuid.uuid @@ -103,8 +106,8 @@ def slice_set(db_engine : Engine, request : Slice) -> Tuple[SliceId, bool]: 'subslice_uuid': subslice_uuid, }) - constraints = compose_constraints_data(request.slice_constraints, slice_uuid=slice_uuid) - config_rules = compose_config_rules_data(request.slice_config.config_rules, slice_uuid=slice_uuid) + constraints = compose_constraints_data(request.slice_constraints, now, slice_uuid=slice_uuid) + config_rules = compose_config_rules_data(request.slice_config.config_rules, now, slice_uuid=slice_uuid) slice_data = [{ 'context_uuid' : context_uuid, @@ -113,9 +116,11 @@ def slice_set(db_engine : Engine, request : Slice) -> Tuple[SliceId, bool]: 'slice_status' : slice_status, 'slice_owner_uuid' : request.slice_owner.owner_uuid.uuid, 'slice_owner_string': request.slice_owner.owner_string, + 'created_at' : now, + 'updated_at' : now, }] - def callback(session : Session) -> None: + def callback(session : Session) -> bool: stmt = insert(SliceModel).values(slice_data) stmt = stmt.on_conflict_do_update( index_elements=[SliceModel.slice_uuid], @@ -126,7 +131,9 @@ def slice_set(db_engine : Engine, request : Slice) -> Tuple[SliceId, bool]: slice_owner_string = stmt.excluded.slice_owner_string, ) ) - session.execute(stmt) + stmt = stmt.returning(SliceModel.created_at, SliceModel.updated_at) + created_at,updated_at = session.execute(stmt).fetchone() + updated = updated_at > created_at if len(slice_endpoints_data) > 0: stmt = insert(SliceEndPointModel).values(slice_endpoints_data) @@ -149,14 +156,18 @@ def slice_set(db_engine : Engine, request : Slice) -> Tuple[SliceId, bool]: ) session.execute(stmt) - upsert_constraints(session, constraints, slice_uuid=slice_uuid) - upsert_config_rules(session, config_rules, slice_uuid=slice_uuid) + constraint_updates = upsert_constraints(session, constraints, slice_uuid=slice_uuid) + updated = updated or any([(updated_at > created_at) for created_at,updated_at in constraint_updates]) - run_transaction(sessionmaker(bind=db_engine), callback) - updated = False # TODO: improve and check if created/updated - return SliceId(**json_slice_id(slice_uuid, json_context_id(context_uuid))),updated + configrule_updates = upsert_config_rules(session, config_rules, slice_uuid=slice_uuid) + updated = updated or any([(updated_at > created_at) for created_at,updated_at in configrule_updates]) -def slice_unset(db_engine : Engine, request : Slice) -> Tuple[SliceId, bool]: + return updated + + updated = run_transaction(sessionmaker(bind=db_engine), callback) + return json_slice_id(slice_uuid, json_context_id(context_uuid)),updated + +def slice_unset(db_engine : Engine, request : Slice) -> Tuple[Dict, bool]: raw_context_uuid = request.slice_id.context_id.context_uuid.uuid raw_slice_uuid = request.slice_id.slice_uuid.uuid raw_slice_name = request.name @@ -208,11 +219,12 @@ def slice_unset(db_engine : Engine, request : Slice) -> Tuple[SliceId, bool]: return num_deletes > 0 updated = run_transaction(sessionmaker(bind=db_engine), callback) - return SliceId(**json_slice_id(slice_uuid, json_context_id(context_uuid))),updated + return json_slice_id(slice_uuid, json_context_id(context_uuid)),updated -def slice_delete(db_engine : Engine, request : SliceId) -> bool: - _,slice_uuid = slice_get_uuid(request, allow_random=False) +def slice_delete(db_engine : Engine, request : SliceId) -> Tuple[Dict, bool]: + context_uuid,slice_uuid = slice_get_uuid(request, allow_random=False) def callback(session : Session) -> bool: num_deleted = session.query(SliceModel).filter_by(slice_uuid=slice_uuid).delete() return num_deleted > 0 - return run_transaction(sessionmaker(bind=db_engine), callback) + deleted = run_transaction(sessionmaker(bind=db_engine), callback) + return json_slice_id(slice_uuid, json_context_id(context_uuid)),deleted diff --git a/src/context/service/database/models/ConfigRuleModel.py b/src/context/service/database/models/ConfigRuleModel.py index a697de556..c2305b001 100644 --- a/src/context/service/database/models/ConfigRuleModel.py +++ b/src/context/service/database/models/ConfigRuleModel.py @@ -35,8 +35,8 @@ class ConfigRuleModel(_Base): kind = Column(Enum(ConfigRuleKindEnum), nullable=False) action = Column(Enum(ORM_ConfigActionEnum), nullable=False) data = Column(String, nullable=False) - created_at = Column(DateTime) - updated_at = Column(DateTime) + created_at = Column(DateTime, nullable=False) + updated_at = Column(DateTime, nullable=False) __table_args__ = ( CheckConstraint(position >= 0, name='check_position_value'), diff --git a/src/context/service/database/models/ConstraintModel.py b/src/context/service/database/models/ConstraintModel.py index 30ade508e..51fc0b91d 100644 --- a/src/context/service/database/models/ConstraintModel.py +++ b/src/context/service/database/models/ConstraintModel.py @@ -13,7 +13,7 @@ # limitations under the License. import enum, json -from sqlalchemy import CheckConstraint, Column, Enum, ForeignKey, Integer, String +from sqlalchemy import CheckConstraint, Column, DateTime, Enum, ForeignKey, Integer, String from sqlalchemy.dialects.postgresql import UUID from typing import Dict from ._Base import _Base @@ -35,6 +35,8 @@ class ConstraintModel(_Base): position = Column(Integer, nullable=False) kind = Column(Enum(ConstraintKindEnum), nullable=False) data = Column(String, nullable=False) + created_at = Column(DateTime, nullable=False) + updated_at = Column(DateTime, nullable=False) __table_args__ = ( CheckConstraint(position >= 0, name='check_position_value'), diff --git a/src/context/service/database/models/ContextModel.py b/src/context/service/database/models/ContextModel.py index fee0f72a5..26ccd8c60 100644 --- a/src/context/service/database/models/ContextModel.py +++ b/src/context/service/database/models/ContextModel.py @@ -23,8 +23,8 @@ class ContextModel(_Base): context_uuid = Column(UUID(as_uuid=False), primary_key=True) context_name = Column(String, nullable=False) - created_at = Column(DateTime) - updated_at = Column(DateTime) + created_at = Column(DateTime, nullable=False) + updated_at = Column(DateTime, nullable=False) topologies = relationship('TopologyModel', back_populates='context') services = relationship('ServiceModel', back_populates='context') diff --git a/src/context/service/database/models/DeviceModel.py b/src/context/service/database/models/DeviceModel.py index ef56c7158..d73cec75d 100644 --- a/src/context/service/database/models/DeviceModel.py +++ b/src/context/service/database/models/DeviceModel.py @@ -29,8 +29,8 @@ class DeviceModel(_Base): device_type = Column(String, nullable=False) device_operational_status = Column(Enum(ORM_DeviceOperationalStatusEnum), nullable=False) device_drivers = Column(ARRAY(Enum(ORM_DeviceDriverEnum), dimensions=1)) - created_at = Column(DateTime) - updated_at = Column(DateTime) + created_at = Column(DateTime, nullable=False) + updated_at = Column(DateTime, nullable=False) #topology_devices = relationship('TopologyDeviceModel', back_populates='device') config_rules = relationship('ConfigRuleModel', passive_deletes=True) # lazy='joined', back_populates='device' diff --git a/src/context/service/database/models/EndPointModel.py b/src/context/service/database/models/EndPointModel.py index abc16c1af..07a5df2bf 100644 --- a/src/context/service/database/models/EndPointModel.py +++ b/src/context/service/database/models/EndPointModel.py @@ -28,8 +28,8 @@ class EndPointModel(_Base): name = Column(String, nullable=False) endpoint_type = Column(String, nullable=False) kpi_sample_types = Column(ARRAY(Enum(ORM_KpiSampleTypeEnum), dimensions=1)) - created_at = Column(DateTime) - updated_at = Column(DateTime) + created_at = Column(DateTime, nullable=False) + updated_at = Column(DateTime, nullable=False) device = relationship('DeviceModel', back_populates='endpoints') topology = relationship('TopologyModel') diff --git a/src/context/service/database/models/LinkModel.py b/src/context/service/database/models/LinkModel.py index a13f61bf3..abf37a28a 100644 --- a/src/context/service/database/models/LinkModel.py +++ b/src/context/service/database/models/LinkModel.py @@ -23,8 +23,8 @@ class LinkModel(_Base): link_uuid = Column(UUID(as_uuid=False), primary_key=True) link_name = Column(String, nullable=False) - created_at = Column(DateTime) - updated_at = Column(DateTime) + created_at = Column(DateTime, nullable=False) + updated_at = Column(DateTime, nullable=False) #topology_links = relationship('TopologyLinkModel', back_populates='link') link_endpoints = relationship('LinkEndPointModel') # lazy='joined', back_populates='link' diff --git a/src/context/service/database/models/ServiceModel.py b/src/context/service/database/models/ServiceModel.py index 7343b5ade..1a28dbce2 100644 --- a/src/context/service/database/models/ServiceModel.py +++ b/src/context/service/database/models/ServiceModel.py @@ -13,7 +13,7 @@ # limitations under the License. import operator -from sqlalchemy import Column, Enum, ForeignKey, String +from sqlalchemy import Column, DateTime, Enum, ForeignKey, String from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import relationship from typing import Dict @@ -29,6 +29,8 @@ class ServiceModel(_Base): service_name = Column(String, nullable=False) service_type = Column(Enum(ORM_ServiceTypeEnum), nullable=False) service_status = Column(Enum(ORM_ServiceStatusEnum), nullable=False) + created_at = Column(DateTime, nullable=False) + updated_at = Column(DateTime, nullable=False) context = relationship('ContextModel', back_populates='services') service_endpoints = relationship('ServiceEndPointModel') # lazy='joined', back_populates='service' diff --git a/src/context/service/database/models/SliceModel.py b/src/context/service/database/models/SliceModel.py index d3dff51e1..5c9ebafa4 100644 --- a/src/context/service/database/models/SliceModel.py +++ b/src/context/service/database/models/SliceModel.py @@ -13,7 +13,7 @@ # limitations under the License. import operator -from sqlalchemy import Column, Enum, ForeignKey, String, Table +from sqlalchemy import Column, DateTime, Enum, ForeignKey, String from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import relationship from typing import Dict @@ -29,6 +29,8 @@ class SliceModel(_Base): slice_status = Column(Enum(ORM_SliceStatusEnum), nullable=False) slice_owner_uuid = Column(String, nullable=True) slice_owner_string = Column(String, nullable=True) + created_at = Column(DateTime, nullable=False) + updated_at = Column(DateTime, nullable=False) context = relationship('ContextModel', back_populates='slices') slice_endpoints = relationship('SliceEndPointModel') # lazy='joined', back_populates='slice' diff --git a/src/context/service/database/models/TopologyModel.py b/src/context/service/database/models/TopologyModel.py index d4dbe173e..59659ecd3 100644 --- a/src/context/service/database/models/TopologyModel.py +++ b/src/context/service/database/models/TopologyModel.py @@ -24,8 +24,8 @@ class TopologyModel(_Base): topology_uuid = Column(UUID(as_uuid=False), primary_key=True) context_uuid = Column(ForeignKey('context.context_uuid'), nullable=False) topology_name = Column(String, nullable=False) - created_at = Column(DateTime) - updated_at = Column(DateTime) + created_at = Column(DateTime, nullable=False) + updated_at = Column(DateTime, nullable=False) context = relationship('ContextModel', back_populates='topologies') topology_devices = relationship('TopologyDeviceModel') # back_populates='topology' diff --git a/src/context/tests/test_service.py b/src/context/tests/test_service.py index ca81bbfa3..e80437dbb 100644 --- a/src/context/tests/test_service.py +++ b/src/context/tests/test_service.py @@ -12,12 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -import copy, grpc, pytest +import copy, grpc, pytest, time from common.proto.context_pb2 import ( - Context, ContextId, Device, DeviceId, Service, ServiceId, ServiceStatusEnum, ServiceTypeEnum, Topology, TopologyId) + Context, ContextEvent, ContextId, Device, DeviceEvent, DeviceId, EventTypeEnum, Service, ServiceEvent, ServiceId, + ServiceStatusEnum, ServiceTypeEnum, Topology, TopologyEvent, TopologyId) from context.client.ContextClient import ContextClient from context.service.database.uuids.Service import service_get_uuid -#from context.client.EventsCollector import EventsCollector +from context.client.EventsCollector import EventsCollector from .Objects import ( CONTEXT, CONTEXT_ID, CONTEXT_NAME, DEVICE_R1, DEVICE_R1_ID, SERVICE_R1_R2_NAME, DEVICE_R2, DEVICE_R2_ID, SERVICE_R1_R2, SERVICE_R1_R2_ID, TOPOLOGY, TOPOLOGY_ID) @@ -26,33 +27,42 @@ from .Objects import ( def test_service(context_client : ContextClient) -> None: # ----- Initialize the EventsCollector ----------------------------------------------------------------------------- - #events_collector = EventsCollector( - # context_client, log_events_received=True, - # activate_context_collector = False, activate_topology_collector = False, activate_device_collector = False, - # activate_link_collector = False, activate_service_collector = True, activate_slice_collector = False, - # activate_connection_collector = False) - #events_collector.start() + events_collector = EventsCollector( + context_client, log_events_received=True, + activate_context_collector = True, activate_topology_collector = True, activate_device_collector = True, + activate_link_collector = True, activate_service_collector = True, activate_slice_collector = False, + activate_connection_collector = False) + events_collector.start() + time.sleep(3) # ----- Prepare dependencies for the test and capture related events ----------------------------------------------- - context_client.SetContext(Context(**CONTEXT)) - context_client.SetTopology(Topology(**TOPOLOGY)) - context_client.SetDevice(Device(**DEVICE_R1)) - context_client.SetDevice(Device(**DEVICE_R2)) - - # events = events_collector.get_events(block=True, count=4) - # assert isinstance(events[0], ContextEvent) - # assert events[0].event.event_type == EventTypeEnum.EVENTTYPE_CREATE - # assert events[0].context_id.context_uuid.uuid == context_uuid - # assert isinstance(events[1], TopologyEvent) - # assert events[1].event.event_type == EventTypeEnum.EVENTTYPE_CREATE - # assert events[1].topology_id.context_id.context_uuid.uuid == context_uuid - # assert events[1].topology_id.topology_uuid.uuid == topology_uuid - # assert isinstance(events[2], DeviceEvent) - # assert events[2].event.event_type == EventTypeEnum.EVENTTYPE_CREATE - # assert events[2].device_id.device_uuid.uuid == device_r1_uuid - # assert isinstance(events[3], DeviceEvent) - # assert events[3].event.event_type == EventTypeEnum.EVENTTYPE_CREATE - # assert events[3].device_id.device_uuid.uuid == device_r2_uuid + response = context_client.SetContext(Context(**CONTEXT)) + context_uuid = response.context_uuid.uuid + + response = context_client.SetTopology(Topology(**TOPOLOGY)) + assert response.context_id.context_uuid.uuid == context_uuid + topology_uuid = response.topology_uuid.uuid + + response = context_client.SetDevice(Device(**DEVICE_R1)) + device_r1_uuid = response.device_uuid.uuid + + response = context_client.SetDevice(Device(**DEVICE_R2)) + device_r2_uuid = response.device_uuid.uuid + + events = events_collector.get_events(block=True, count=4, timeout=1.0) + assert isinstance(events[0], ContextEvent) + assert events[0].event.event_type == EventTypeEnum.EVENTTYPE_CREATE + assert events[0].context_id.context_uuid.uuid == context_uuid + assert isinstance(events[1], TopologyEvent) + assert events[1].event.event_type == EventTypeEnum.EVENTTYPE_CREATE + assert events[1].topology_id.context_id.context_uuid.uuid == context_uuid + assert events[1].topology_id.topology_uuid.uuid == topology_uuid + assert isinstance(events[2], DeviceEvent) + assert events[2].event.event_type == EventTypeEnum.EVENTTYPE_CREATE + assert events[2].device_id.device_uuid.uuid == device_r1_uuid + assert isinstance(events[3], DeviceEvent) + assert events[3].event.event_type == EventTypeEnum.EVENTTYPE_CREATE + assert events[3].device_id.device_uuid.uuid == device_r2_uuid # ----- Get when the object does not exist ------------------------------------------------------------------------- service_id = ServiceId(**SERVICE_R1_R2_ID) @@ -92,11 +102,11 @@ def test_service(context_client : ContextClient) -> None: assert response.service_uuid.uuid == service_uuid # ----- Check create event ----------------------------------------------------------------------------------------- - #event = events_collector.get_event(block=True) - #assert isinstance(event, ServiceEvent) - #assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE - #assert event.service_id.context_id.context_uuid.uuid == context_uuid - #assert event.service_id.service_uuid.uuid == service_uuid + event = events_collector.get_event(block=True, timeout=1.0) + assert isinstance(event, ServiceEvent) + assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE + assert event.service_id.context_id.context_uuid.uuid == context_uuid + assert event.service_id.service_uuid.uuid == service_uuid # ----- Get when the object exists --------------------------------------------------------------------------------- response = context_client.GetContext(ContextId(**CONTEXT_ID)) @@ -145,11 +155,11 @@ def test_service(context_client : ContextClient) -> None: assert response.service_uuid.uuid == service_uuid # ----- Check update event ----------------------------------------------------------------------------------------- - #event = events_collector.get_event(block=True) - #assert isinstance(event, ServiceEvent) - #assert event.event.event_type == EventTypeEnum.EVENTTYPE_UPDATE - #assert event.service_id.context_id.context_uuid.uuid == context_uuid - #assert event.service_id.service_uuid.uuid == service_uuid + event = events_collector.get_event(block=True, timeout=1.0) + assert isinstance(event, ServiceEvent) + assert event.event.event_type == EventTypeEnum.EVENTTYPE_UPDATE + assert event.service_id.context_id.context_uuid.uuid == context_uuid + assert event.service_id.service_uuid.uuid == service_uuid # ----- Get when the object is modified ---------------------------------------------------------------------------- response = context_client.GetService(ServiceId(**SERVICE_R1_R2_ID)) @@ -183,11 +193,11 @@ def test_service(context_client : ContextClient) -> None: context_client.RemoveService(ServiceId(**SERVICE_R1_R2_ID)) # ----- Check remove event ----------------------------------------------------------------------------------------- - #event = events_collector.get_event(block=True) - #assert isinstance(event, ServiceEvent) - #assert event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE - #assert event.service_id.context_id.context_uuid.uuid == context_uuid - #assert event.service_id.service_uuid.uuid == service_uuid + event = events_collector.get_event(block=True, timeout=1.0) + assert isinstance(event, ServiceEvent) + assert event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE + assert event.service_id.context_id.context_uuid.uuid == context_uuid + assert event.service_id.service_uuid.uuid == service_uuid # ----- List after deleting the object ----------------------------------------------------------------------------- response = context_client.GetContext(ContextId(**CONTEXT_ID)) @@ -207,20 +217,20 @@ def test_service(context_client : ContextClient) -> None: context_client.RemoveTopology(TopologyId(**TOPOLOGY_ID)) context_client.RemoveContext(ContextId(**CONTEXT_ID)) - #events = events_collector.get_events(block=True, count=4) - #assert isinstance(events[0], DeviceEvent) - #assert events[0].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE - #assert events[0].device_id.device_uuid.uuid == device_r1_uuid - #assert isinstance(events[1], DeviceEvent) - #assert events[1].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE - #assert events[1].device_id.device_uuid.uuid == device_r2_uuid - #assert isinstance(events[2], TopologyEvent) - #assert events[2].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE - #assert events[2].topology_id.context_id.context_uuid.uuid == context_uuid - #assert events[2].topology_id.topology_uuid.uuid == topology_uuid - #assert isinstance(events[3], ContextEvent) - #assert events[3].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE - #assert events[3].context_id.context_uuid.uuid == context_uuid + events = events_collector.get_events(block=True, count=4, timeout=1.0) + assert isinstance(events[0], DeviceEvent) + assert events[0].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE + assert events[0].device_id.device_uuid.uuid == device_r1_uuid + assert isinstance(events[1], DeviceEvent) + assert events[1].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE + assert events[1].device_id.device_uuid.uuid == device_r2_uuid + assert isinstance(events[2], TopologyEvent) + assert events[2].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE + assert events[2].topology_id.context_id.context_uuid.uuid == context_uuid + assert events[2].topology_id.topology_uuid.uuid == topology_uuid + assert isinstance(events[3], ContextEvent) + assert events[3].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE + assert events[3].context_id.context_uuid.uuid == context_uuid # ----- Stop the EventsCollector ----------------------------------------------------------------------------------- - #events_collector.stop() + events_collector.stop() diff --git a/src/context/tests/test_slice.py b/src/context/tests/test_slice.py index 9d27523b1..cb7eb7737 100644 --- a/src/context/tests/test_slice.py +++ b/src/context/tests/test_slice.py @@ -12,13 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -import copy, grpc, pytest +import copy, grpc, pytest, time from common.proto.context_pb2 import ( - Context, ContextId, Device, DeviceId, Link, LinkId, Service, ServiceId, Slice, SliceId, SliceStatusEnum, Topology, + Context, ContextEvent, ContextId, Device, DeviceEvent, DeviceId, EventTypeEnum, Link, LinkEvent, LinkId, Service, ServiceEvent, ServiceId, Slice, SliceEvent, SliceId, SliceStatusEnum, Topology, TopologyEvent, TopologyId) from context.client.ContextClient import ContextClient from context.service.database.uuids.Slice import slice_get_uuid -#from context.client.EventsCollector import EventsCollector +from context.client.EventsCollector import EventsCollector from .Objects import ( CONTEXT, CONTEXT_ID, CONTEXT_NAME, DEVICE_R1, DEVICE_R1_ID, DEVICE_R2, DEVICE_R2_ID, DEVICE_R3, DEVICE_R3_ID, LINK_R1_R2, LINK_R1_R2_ID, LINK_R1_R3, LINK_R1_R3_ID, LINK_R2_R3, LINK_R2_R3_ID, SERVICE_R1_R2, SERVICE_R1_R2_ID, @@ -28,57 +28,82 @@ from .Objects import ( def test_slice(context_client : ContextClient) -> None: # ----- Initialize the EventsCollector ----------------------------------------------------------------------------- - #events_collector = EventsCollector( - # context_client, log_events_received=True, - # activate_context_collector = False, activate_topology_collector = False, activate_device_collector = False, - # activate_link_collector = False, activate_service_collector = False, activate_slice_collector = True, - # activate_connection_collector = False) - #events_collector.start() + events_collector = EventsCollector( + context_client, log_events_received=True, + activate_context_collector = True, activate_topology_collector = True, activate_device_collector = True, + activate_link_collector = True, activate_service_collector = True, activate_slice_collector = True, + activate_connection_collector = False) + events_collector.start() + time.sleep(3) # ----- Prepare dependencies for the test and capture related events ----------------------------------------------- - context_client.SetContext(Context(**CONTEXT)) - context_client.SetTopology(Topology(**TOPOLOGY)) - context_client.SetDevice(Device(**DEVICE_R1)) - context_client.SetDevice(Device(**DEVICE_R2)) - context_client.SetDevice(Device(**DEVICE_R3)) - context_client.SetLink(Link(**LINK_R1_R2)) - context_client.SetLink(Link(**LINK_R1_R3)) - context_client.SetLink(Link(**LINK_R2_R3)) - context_client.SetService(Service(**SERVICE_R1_R2)) - context_client.SetService(Service(**SERVICE_R2_R3)) - - #events = events_collector.get_events(block=True, count=10) - #assert isinstance(events[0], ContextEvent) - #assert events[0].event.event_type == EventTypeEnum.EVENTTYPE_CREATE - #assert events[0].context_id.context_uuid.uuid == context_uuid - #assert isinstance(events[1], TopologyEvent) - #assert events[1].event.event_type == EventTypeEnum.EVENTTYPE_CREATE - #assert events[1].topology_id.context_id.context_uuid.uuid == context_uuid - #assert events[1].topology_id.topology_uuid.uuid == topology_uuid - #assert isinstance(events[2], DeviceEvent) - #assert events[2].event.event_type == EventTypeEnum.EVENTTYPE_CREATE - #assert events[2].device_id.device_uuid.uuid == device_r1_uuid - #assert isinstance(events[3], DeviceEvent) - #assert events[3].event.event_type == EventTypeEnum.EVENTTYPE_CREATE - #assert events[3].device_id.device_uuid.uuid == device_r2_uuid - #assert isinstance(events[4], DeviceEvent) - #assert events[4].event.event_type == EventTypeEnum.EVENTTYPE_CREATE - #assert events[4].device_id.device_uuid.uuid == device_r3_uuid - #assert isinstance(events[5], LinkEvent) - #assert events[5].event.event_type == EventTypeEnum.EVENTTYPE_CREATE - #assert events[5].link_id.link_uuid.uuid == link_r1_r2_uuid - #assert isinstance(events[6], LinkEvent) - #assert events[6].event.event_type == EventTypeEnum.EVENTTYPE_CREATE - #assert events[6].link_id.link_uuid.uuid == link_r1_r3_uuid - #assert isinstance(events[7], LinkEvent) - #assert events[7].event.event_type == EventTypeEnum.EVENTTYPE_CREATE - #assert events[7].link_id.link_uuid.uuid == link_r2_r3_uuid - #assert isinstance(events[8], ServiceEvent) - #assert events[8].event.event_type == EventTypeEnum.EVENTTYPE_CREATE - #assert events[8].service_id.service_uuid.uuid == service_r1_r2_uuid - #assert isinstance(events[9], ServiceEvent) - #assert events[9].event.event_type == EventTypeEnum.EVENTTYPE_CREATE - #assert events[9].service_id.service_uuid.uuid == service_r2_r3_uuid + response = context_client.SetContext(Context(**CONTEXT)) + context_uuid = response.context_uuid.uuid + + response = context_client.SetTopology(Topology(**TOPOLOGY)) + assert response.context_id.context_uuid.uuid == context_uuid + topology_uuid = response.topology_uuid.uuid + + response = context_client.SetDevice(Device(**DEVICE_R1)) + device_r1_uuid = response.device_uuid.uuid + + response = context_client.SetDevice(Device(**DEVICE_R2)) + device_r2_uuid = response.device_uuid.uuid + + response = context_client.SetDevice(Device(**DEVICE_R3)) + device_r3_uuid = response.device_uuid.uuid + + response = context_client.SetLink(Link(**LINK_R1_R2)) + link_r1_r2_uuid = response.link_uuid.uuid + + response = context_client.SetLink(Link(**LINK_R1_R3)) + link_r1_r3_uuid = response.link_uuid.uuid + + response = context_client.SetLink(Link(**LINK_R2_R3)) + link_r2_r3_uuid = response.link_uuid.uuid + + response = context_client.SetService(Service(**SERVICE_R1_R2)) + assert response.context_id.context_uuid.uuid == context_uuid + service_r1_r2_uuid = response.service_uuid.uuid + + response = context_client.SetService(Service(**SERVICE_R2_R3)) + assert response.context_id.context_uuid.uuid == context_uuid + service_r2_r3_uuid = response.service_uuid.uuid + + events = events_collector.get_events(block=True, count=10, timeout=1.0) + assert isinstance(events[0], ContextEvent) + assert events[0].event.event_type == EventTypeEnum.EVENTTYPE_CREATE + assert events[0].context_id.context_uuid.uuid == context_uuid + assert isinstance(events[1], TopologyEvent) + assert events[1].event.event_type == EventTypeEnum.EVENTTYPE_CREATE + assert events[1].topology_id.context_id.context_uuid.uuid == context_uuid + assert events[1].topology_id.topology_uuid.uuid == topology_uuid + assert isinstance(events[2], DeviceEvent) + assert events[2].event.event_type == EventTypeEnum.EVENTTYPE_CREATE + assert events[2].device_id.device_uuid.uuid == device_r1_uuid + assert isinstance(events[3], DeviceEvent) + assert events[3].event.event_type == EventTypeEnum.EVENTTYPE_CREATE + assert events[3].device_id.device_uuid.uuid == device_r2_uuid + assert isinstance(events[4], DeviceEvent) + assert events[4].event.event_type == EventTypeEnum.EVENTTYPE_CREATE + assert events[4].device_id.device_uuid.uuid == device_r3_uuid + assert isinstance(events[5], LinkEvent) + assert events[5].event.event_type == EventTypeEnum.EVENTTYPE_CREATE + assert events[5].link_id.link_uuid.uuid == link_r1_r2_uuid + assert isinstance(events[6], LinkEvent) + assert events[6].event.event_type == EventTypeEnum.EVENTTYPE_CREATE + assert events[6].link_id.link_uuid.uuid == link_r1_r3_uuid + assert isinstance(events[7], LinkEvent) + assert events[7].event.event_type == EventTypeEnum.EVENTTYPE_CREATE + assert events[7].link_id.link_uuid.uuid == link_r2_r3_uuid + assert isinstance(events[8], ServiceEvent) + assert events[8].event.event_type == EventTypeEnum.EVENTTYPE_CREATE + assert events[8].service_id.context_id.context_uuid.uuid == context_uuid + assert events[8].service_id.service_uuid.uuid == service_r1_r2_uuid + assert isinstance(events[9], ServiceEvent) + assert events[9].event.event_type == EventTypeEnum.EVENTTYPE_CREATE + assert events[9].service_id.context_id.context_uuid.uuid == context_uuid + assert events[9].service_id.service_uuid.uuid == service_r2_r3_uuid # ----- Get when the object does not exist ------------------------------------------------------------------------- slice_id = SliceId(**SLICE_R1_R3_ID) @@ -118,11 +143,11 @@ def test_slice(context_client : ContextClient) -> None: assert response.slice_uuid.uuid == slice_uuid # ----- Check create event ----------------------------------------------------------------------------------------- - #event = events_collector.get_event(block=True) - #assert isinstance(event, SliceEvent) - #assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE - #assert event.slice_id.context_id.context_uuid.uuid == context_uuid - #assert event.slice_id.slice_uuid.uuid == slice_uuid + event = events_collector.get_event(block=True, timeout=1.0) + assert isinstance(event, SliceEvent) + assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE + assert event.slice_id.context_id.context_uuid.uuid == context_uuid + assert event.slice_id.slice_uuid.uuid == slice_uuid # ----- Get when the object exists --------------------------------------------------------------------------------- response = context_client.GetContext(ContextId(**CONTEXT_ID)) @@ -169,11 +194,11 @@ def test_slice(context_client : ContextClient) -> None: assert response.slice_uuid.uuid == slice_uuid # ----- Check update event ----------------------------------------------------------------------------------------- - #event = events_collector.get_event(block=True) - #assert isinstance(event, SliceEvent) - #assert event.event.event_type == EventTypeEnum.EVENTTYPE_UPDATE - #assert event.slice_id.context_id.context_uuid.uuid == context_uuid - #assert event.slice_id.slice_uuid.uuid == slice_uuid + event = events_collector.get_event(block=True, timeout=1.0) + assert isinstance(event, SliceEvent) + assert event.event.event_type == EventTypeEnum.EVENTTYPE_UPDATE + assert event.slice_id.context_id.context_uuid.uuid == context_uuid + assert event.slice_id.slice_uuid.uuid == slice_uuid # ----- Get when the object is modified ---------------------------------------------------------------------------- response = context_client.GetSlice(SliceId(**SLICE_R1_R3_ID)) @@ -205,11 +230,11 @@ def test_slice(context_client : ContextClient) -> None: context_client.RemoveSlice(SliceId(**SLICE_R1_R3_ID)) # ----- Check remove event ----------------------------------------------------------------------------------------- - #event = events_collector.get_event(block=True) - #assert isinstance(event, SliceEvent) - #assert event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE - #assert event.slice_id.context_id.context_uuid.uuid == context_uuid - #assert event.slice_id.slice_uuid.uuid == slice_uuid + event = events_collector.get_event(block=True, timeout=1.0) + assert isinstance(event, SliceEvent) + assert event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE + assert event.slice_id.context_id.context_uuid.uuid == context_uuid + assert event.slice_id.slice_uuid.uuid == slice_uuid # ----- List after deleting the object ----------------------------------------------------------------------------- response = context_client.GetContext(ContextId(**CONTEXT_ID)) @@ -235,38 +260,40 @@ def test_slice(context_client : ContextClient) -> None: context_client.RemoveTopology(TopologyId(**TOPOLOGY_ID)) context_client.RemoveContext(ContextId(**CONTEXT_ID)) - #events = events_collector.get_events(block=True, count=10) - #assert isinstance(events[0], ServiceEvent) - #assert events[0].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE - #assert events[0].service_id.service_uuid.uuid == service_r1_r2_uuid - #assert isinstance(events[1], ServiceEvent) - #assert events[1].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE - #assert events[1].service_id.service_uuid.uuid == service_r2_r3_uuid - #assert isinstance(events[2], LinkEvent) - #assert events[2].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE - #assert events[2].link_id.link_uuid.uuid == link_r1_r2_uuid - #assert isinstance(events[3], LinkEvent) - #assert events[3].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE - #assert events[3].link_id.link_uuid.uuid == link_r1_r3_uuid - #assert isinstance(events[4], LinkEvent) - #assert events[4].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE - #assert events[4].link_id.link_uuid.uuid == link_r2_r3_uuid - #assert isinstance(events[5], DeviceEvent) - #assert events[5].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE - #assert events[5].device_id.device_uuid.uuid == device_r1_uuid - #assert isinstance(events[6], DeviceEvent) - #assert events[6].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE - #assert events[6].device_id.device_uuid.uuid == device_r2_uuid - #assert isinstance(events[7], DeviceEvent) - #assert events[7].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE - #assert events[7].device_id.device_uuid.uuid == device_r3_uuid - #assert isinstance(events[8], TopologyEvent) - #assert events[8].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE - #assert events[8].topology_id.context_id.context_uuid.uuid == context_uuid - #assert events[8].topology_id.topology_uuid.uuid == topology_uuid - #assert isinstance(events[9], ContextEvent) - #assert events[9].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE - #assert events[9].context_id.context_uuid.uuid == context_uuid + events = events_collector.get_events(block=True, count=10) + assert isinstance(events[0], ServiceEvent) + assert events[0].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE + assert events[0].service_id.context_id.context_uuid.uuid == context_uuid + assert events[0].service_id.service_uuid.uuid == service_r1_r2_uuid + assert isinstance(events[1], ServiceEvent) + assert events[1].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE + assert events[1].service_id.context_id.context_uuid.uuid == context_uuid + assert events[1].service_id.service_uuid.uuid == service_r2_r3_uuid + assert isinstance(events[2], LinkEvent) + assert events[2].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE + assert events[2].link_id.link_uuid.uuid == link_r1_r2_uuid + assert isinstance(events[3], LinkEvent) + assert events[3].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE + assert events[3].link_id.link_uuid.uuid == link_r1_r3_uuid + assert isinstance(events[4], LinkEvent) + assert events[4].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE + assert events[4].link_id.link_uuid.uuid == link_r2_r3_uuid + assert isinstance(events[5], DeviceEvent) + assert events[5].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE + assert events[5].device_id.device_uuid.uuid == device_r1_uuid + assert isinstance(events[6], DeviceEvent) + assert events[6].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE + assert events[6].device_id.device_uuid.uuid == device_r2_uuid + assert isinstance(events[7], DeviceEvent) + assert events[7].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE + assert events[7].device_id.device_uuid.uuid == device_r3_uuid + assert isinstance(events[8], TopologyEvent) + assert events[8].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE + assert events[8].topology_id.context_id.context_uuid.uuid == context_uuid + assert events[8].topology_id.topology_uuid.uuid == topology_uuid + assert isinstance(events[9], ContextEvent) + assert events[9].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE + assert events[9].context_id.context_uuid.uuid == context_uuid # ----- Stop the EventsCollector ----------------------------------------------------------------------------------- - #events_collector.stop() + events_collector.stop() -- GitLab