diff --git a/src/context/service/ContextServiceServicerImpl.py b/src/context/service/ContextServiceServicerImpl.py index 5c956585997476d579cc0e14e0ad5eac3bb6c2b6..34608d61944bd19b349fae44b18a83d9f4220e84 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 5f701386fa2087934088894383348ce9d00f53ad..5443e178c0f726be5b55e7955a6dc7b575d9f53a 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 42fc86ebf514d9a858495f79dbc150925ec11968..2f6fb84337b085b29e3fd275e96d9bf4c4495e70 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 f79159a35a5ab3450f92c2539ca5fa65ebc70f98..2880c05a85dbde7c3af87d6766375862767611a7 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 247914d6518f6f3282c27ba3f77428f8c64140a5..a8f9f40d6d6351450e7fe1c6e400a0b36f9b3e8b 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 e963fb7729ff1edba382e71d2d1573674d060a59..f255968b28902d02182e29d4e16d4efb1302b632 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 a697de55652c82406f7496188641c33f99f9682a..c2305b001b4453436603e0e384fddcecfa839b00 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 30ade508e1793e0af3ef8a26b00020d3c540d037..51fc0b91df07a2c86c5e84692b3dd5edd21fb761 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 fee0f72a544d96d7fb9381e1ecd406cc3084b560..26ccd8c60f12c841aeb43c0dfc11754bb45843b0 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 ef56c715863607dc67c4f0be31202f03948353e0..d73cec75d70d3f12cf964258a84adfab79978082 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 abc16c1affdf542b64c2d0d6698645e1ba82b665..07a5df2bf69e154f8d969d716a2eb914145f9919 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 a13f61bf319d1298c34a64f6832399fe7ad350b8..abf37a28afe6db4a27e225de8e86b0d6d323b420 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 7343b5adea813687d7770d9e49e3fa776e31dc17..1a28dbce288860afd53f19640621e788674dbdff 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 d3dff51e193281a79041c62549931f3595136bfe..5c9ebafa48c302b959bb265a35a80706da0a3975 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 d4dbe173e510332f35f707221af9a27b84eb5f22..59659ecd3f8ad9f896bd7d8f07c1f65ba1d6f27d 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 ca81bbfa33d2a8e61b56201833acba0e7af29b8e..e80437dbb9d623bd6a021ad3d0c779a16326e36c 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 9d27523b12567cb949494e0954c691205cb06c96..cb7eb773776e5d38050c09485fd88b90c8d67601 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()