diff --git a/proto/context.proto b/proto/context.proto index ab8db45e14ffb127e7bc76167a8879bdfd38e632..fd7580e52fccbacfc66511ce1fe5b6d9af9a1bbb 100644 --- a/proto/context.proto +++ b/proto/context.proto @@ -64,8 +64,9 @@ message ContextId { message Context { ContextId context_id = 1; - repeated Topology topology = 2; - TeraFlowController controller = 3; + repeated TopologyId topology_ids = 2; + repeated ServiceId service_ids = 3; + TeraFlowController controller = 4; } message ContextIdList { diff --git a/run_local_tests.sh b/run_local_tests.sh index 2b2eb9e39d6a8ed8fbbc0a575eb995e8b43ac078..ef21ad852626c5bf74f60c6998618f8c21826b20 100755 --- a/run_local_tests.sh +++ b/run_local_tests.sh @@ -22,8 +22,7 @@ coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \ # centralizedcybersecurity/tests/test_unitary.py coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \ - context/tests/test_unitary_orm_context_inmemory.py \ -# context/tests/test_unitary.py + context/tests/test_unitary.py #coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \ # device/tests/test_unitary_driverapi.py \ diff --git a/src/common/orm/backend/inmemory/InMemoryBackend.py b/src/common/orm/backend/inmemory/InMemoryBackend.py index a6f7e863742121159f7be30d7125802aee2d03de..ddd25c1720cc2e581e7b205113b14167b03d85aa 100644 --- a/src/common/orm/backend/inmemory/InMemoryBackend.py +++ b/src/common/orm/backend/inmemory/InMemoryBackend.py @@ -70,7 +70,7 @@ class InMemoryBackend(_Backend): str_key = key_to_str(key) with self._lock: container = get_dict(self._keys, str_key) - if container is None: return None + if container is None: return {} if len(fields) == 0: fields = container.keys() return copy.deepcopy({ field_name : field_value for field_name,field_value in container.items() if field_name in fields @@ -97,7 +97,7 @@ class InMemoryBackend(_Backend): str_key = key_to_str(key) with self._lock: container = get_list(self._keys, str_key) - if container is None: return None + if container is None: return [] return copy.deepcopy(container) def list_push_last(self, key : List[str], item : str) -> None: @@ -129,7 +129,7 @@ class InMemoryBackend(_Backend): str_key = key_to_str(key) with self._lock: container = get_set(self._keys, str_key) - if container is None: return None + if container is None: return {} return copy.deepcopy(container) def set_remove(self, key : List[str], item : str) -> None: diff --git a/src/common/orm/model/Model.py b/src/common/orm/model/Model.py index 22e4e04d28d00c2442e06e4887db9660a41df532..19010277b49dcb921401d7958c973745326278ad 100644 --- a/src/common/orm/model/Model.py +++ b/src/common/orm/model/Model.py @@ -1,9 +1,10 @@ from __future__ import annotations import logging, re -from typing import Any, Dict, List, Mapping, Optional, Set, Tuple +from typing import Any, Dict, List, Mapping, Optional, Set, Tuple, Union from common.orm.Database import Database from common.orm.backend.Tools import key_to_str from common.orm.fields.ForeignKeyField import ForeignKeyField +from common.type_checkers.Checkers import chk_issubclass from ..Exceptions import ConstraintException, MutexException from ..fields.Field import Field from ..fields.PrimaryKeyField import PrimaryKeyField @@ -44,7 +45,43 @@ class MetaModel(type): setattr(cls_obj, '_field_names_set', set(field_names)) return cls_obj +KEYWORD_INSTANCES = 'instances' +KEYWORD_LOCK = 'lock' +KEYWORD_REFERENCES = 'references' +KEYWORD_STORED = '_stored' + class Model(metaclass=MetaModel): + @classmethod + def get_backend_key_instances(cls) -> str: + return key_to_str(['{:s}'.format(cls.__name__), KEYWORD_INSTANCES]) + + @classmethod + def get_backend_key_instance(cls, primary_key : str) -> str: + return '{:s}[{:s}]'.format(cls.__name__, primary_key) + + @classmethod + def get_backend_key_references(cls, primary_key : str) -> str: + match = re.match(r'^[a-zA-Z0-9\_]+\[([^\]]*)\]', primary_key) + if not match: primary_key = cls.get_backend_key_instance(primary_key) + return key_to_str([primary_key, KEYWORD_REFERENCES]) + + @staticmethod + def get_backend_key_lock(backend_key : str) -> str: + if backend_key.endswith(KEYWORD_LOCK): return backend_key + return key_to_str([backend_key, KEYWORD_LOCK]) + + @staticmethod + def get_backend_key_locks(backend_keys : List[str]) -> List[str]: + return [Model.get_backend_key_lock(backend_key) for backend_key in backend_keys] + + @classmethod + def backend_key__to__instance_key(cls, backend_key : str) -> str: + class_name = cls.__name__ + if backend_key.startswith(class_name): + match = re.match(r'^{:s}\[([^\]]*)\]'.format(class_name), backend_key) + if match: return match.group(1) + return backend_key + def __init__(self, database : Database, primary_key : str, auto_load : bool = True) -> None: if not isinstance(database, Database): str_class_path = '{}.{}'.format(Database.__module__, Database.__name__) @@ -54,31 +91,33 @@ class Model(metaclass=MetaModel): pk_field_name = self._pk_field_name # pylint: disable=no-member pk_field_instance : 'PrimaryKeyField' = getattr(self._model_class, pk_field_name) primary_key = pk_field_instance.validate(primary_key) - if primary_key.startswith(self._class_name): - match = re.match(r'^{:s}\[([^\]]*)\]'.format(self._class_name), primary_key) - if match: primary_key = match.group(1) + primary_key = self.backend_key__to__instance_key(primary_key) setattr(self, pk_field_name, primary_key) self._database = database self._backend = database.backend - self._instance_key : str = '{:s}[{:s}]'.format(self._class_name, primary_key) - self._references_key : str = key_to_str([self._instance_key, 'references']) + self._instance_key : str = self.get_backend_key_instance(primary_key) + self._instances_key : str = self.get_backend_key_instances() + self._references_key : str = self.get_backend_key_references(primary_key) self._owner_key : Optional[str] = None if auto_load: self.load() + @property + def database(self) -> Database: return self._database + @property def instance_key(self) -> str: return self._instance_key def lock(self, extra_keys : List[List[str]] = []): - lock_keys = [self._instance_key, self._references_key] + extra_keys - lock_keys = [key_to_str([lock_key, 'lock']) for lock_key in lock_keys] + lock_keys = Model.get_backend_key_locks( + [self._instance_key, self._instances_key, self._references_key] + extra_keys) acquired,self._owner_key = self._backend.lock(lock_keys, owner_key=self._owner_key) if acquired: return raise MutexException('Unable to lock keys {:s} using owner_key {:s}'.format( str(lock_keys), str(self._owner_key))) def unlock(self, extra_keys : List[List[str]] = []): - lock_keys = [self._instance_key, self._references_key] + extra_keys - lock_keys = [key_to_str([lock_key, 'lock']) for lock_key in lock_keys] + lock_keys = Model.get_backend_key_locks( + [self._instance_key, self._instances_key, self._references_key] + extra_keys) released = self._backend.unlock(lock_keys, self._owner_key) if released: return raise MutexException('Unable to unlock keys {:s} using owner_key {:s}'.format( @@ -99,7 +138,7 @@ class Model(metaclass=MetaModel): field_instance : 'Field' = getattr(self._model_class, field_name) field_value = field_instance.deserialize(raw_field_value) if isinstance(field_instance, ForeignKeyField): - setattr(self, field_name + '_stored', field_value) + setattr(self, field_name + KEYWORD_STORED, field_value) field_value = field_instance.foreign_model(self._database, field_value, auto_load=True) setattr(self, field_name, field_value) finally: @@ -117,10 +156,10 @@ class Model(metaclass=MetaModel): if (serialized_field_value is None) and (not field_instance.required): continue if isinstance(field_instance, ForeignKeyField): foreign_reference = '{:s}:{:s}'.format(self._instance_key, field_name) - field_value_stored = getattr(self, field_name + '_stored', None) + field_value_stored = getattr(self, field_name + KEYWORD_STORED, None) if field_value_stored is not None: - foreign_removals[key_to_str([field_value_stored, 'references'])] = foreign_reference - foreign_additions[key_to_str([serialized_field_value, 'references'])] = foreign_reference + foreign_removals[self.get_backend_key_references(field_value_stored)] = foreign_reference + foreign_additions[self.get_backend_key_references(serialized_field_value)] = foreign_reference required_keys.add(serialized_field_value) attributes[field_name] = serialized_field_value @@ -131,14 +170,16 @@ class Model(metaclass=MetaModel): try: self.lock(extra_keys=extra_keys) - not_exists = [] - for required_key in required_keys: - if self._backend.exists(required_key): continue - not_exists.append('{:s}'.format(str(required_key))) + not_exists = [ + str(required_key) + for required_key in required_keys + if not self._backend.exists(required_key)] if len(not_exists) > 0: raise ConstraintException('Required Keys ({:s}) does not exist'.format(', '.join(sorted(not_exists)))) self._backend.dict_update(self._instance_key, attributes) + self._backend.set_add(self._instances_key, self._instance_key) + for serialized_field_value,foreign_reference in foreign_removals.items(): self._backend.set_remove(serialized_field_value, foreign_reference) @@ -148,7 +189,7 @@ class Model(metaclass=MetaModel): self.unlock(extra_keys=extra_keys) for serialized_field_value,foreign_reference in foreign_additions.items(): - setattr(self, (foreign_reference.rsplit(':', 1)[-1]) + '_stored', field_value_stored) + setattr(self, (foreign_reference.rsplit(':', 1)[-1]) + KEYWORD_STORED, field_value_stored) def delete(self) -> None: foreign_removals : Dict[str, str] = {} @@ -156,9 +197,9 @@ class Model(metaclass=MetaModel): field_instance : 'Field' = getattr(self._model_class, field_name) if not isinstance(field_instance, ForeignKeyField): continue foreign_reference = '{:s}:{:s}'.format(self._instance_key, field_name) - field_value_stored = getattr(self, field_name + '_stored', None) + field_value_stored = getattr(self, field_name + KEYWORD_STORED, None) if field_value_stored is None: continue - foreign_removals[key_to_str([field_value_stored, 'references'])] = foreign_reference + foreign_removals[self.get_backend_key_references(field_value_stored)] = foreign_reference extra_keys = [] extra_keys.extend(list(foreign_removals.keys())) @@ -171,21 +212,55 @@ class Model(metaclass=MetaModel): raise ConstraintException('Instance is used by Keys ({:s})'.format(', '.join(sorted(references)))) self._backend.delete(self._instance_key) + self._backend.set_remove(self._instances_key, self._instance_key) + for serialized_field_value,foreign_reference in foreign_removals.items(): self._backend.set_remove(serialized_field_value, foreign_reference) finally: self.unlock(extra_keys=extra_keys) - def references(self) -> Set[Tuple[str, str]]: + def references( + self, filter_by_models : Optional[Union[type, List[type], Set[type]]] = None) -> Set[Tuple[str, str]]: try: self.lock() - if self._backend.exists(self._references_key): - references = self._backend.set_get_all(self._references_key) - return {tuple(reference.rsplit(':', 1)) for reference in references} - return {} + if not self._backend.exists(self._references_key): return {} + references = self._backend.set_get_all(self._references_key) + if filter_by_models is None: + pass + elif isinstance(filter_by_models, (list, set)): + filter_by_models = {type(chk_issubclass(model, Model)).__name__ for model in filter_by_models} + elif issubclass(filter_by_models, Model): + filter_by_models = {type(chk_issubclass(filter_by_models, Model)).__name__} + else: + msg = 'filter_by_models({:s}) unsupported. Expected a type or a list/set of types. Optionally, keep '\ + 'it as None to retrieve all the references pointing to this instance.' + raise AttributeError(msg.format(str(filter_by_models))) + if filter_by_models: + references = filter(lambda instance_key: instance_key.split('[', 1)[0] in filter_by_models, references) + return {tuple(reference.rsplit(':', 1)) for reference in references} finally: self.unlock() + @classmethod + def get_primary_keys(cls, database : Database): + backend = database.backend + key_model_instances = cls.get_backend_key_instances() + key_model_instances_lock = cls.get_backend_key_lock(key_model_instances) + + acquired,owner_key = backend.lock(key_model_instances_lock) + if not acquired: + raise MutexException('Unable to lock keys {:s}'.format( + str(key_model_instances_lock))) + + instance_keys = backend.set_get_all(key_model_instances) + + released = backend.unlock(key_model_instances_lock, owner_key) + if not released: + raise MutexException('Unable to unlock keys {:s} using owner_key {:s}'.format( + str(key_model_instances_lock), str(owner_key))) + + return instance_keys + def dump_id(self) -> Dict: raise NotImplementedError() diff --git a/src/common/orm/tests/test_unitary.py b/src/common/orm/tests/test_unitary.py index edac0ae5a49d84d1f25e9886fc0c100698dce722..387d4ffea35a6821e557d1e9a84b468e34001481 100644 --- a/src/common/orm/tests/test_unitary.py +++ b/src/common/orm/tests/test_unitary.py @@ -85,6 +85,18 @@ def test_model_with_primarykey(): active = BooleanField() gender = EnumeratedField(GenderEnum) + backend_key_instances = TestModel.get_backend_key_instances() + backend_key_instance = TestModel.get_backend_key_instance('pk') + backend_key_references = TestModel.get_backend_key_references('pk') + + assert backend_key_instances == 'TestModel/instances' + assert backend_key_instance == 'TestModel[pk]' + assert backend_key_references == 'TestModel[pk]/references' + + assert TestModel.get_backend_key_lock(backend_key_instances ) == 'TestModel/instances/lock' + assert TestModel.get_backend_key_lock(backend_key_instance ) == 'TestModel[pk]/lock' + assert TestModel.get_backend_key_lock(backend_key_references) == 'TestModel[pk]/references/lock' + with pytest.raises(ValueError) as e: TestModel(database, None) assert str(e.value) == 'pk(None) is required. It cannot be None.' @@ -248,8 +260,11 @@ def test_model_database_operations(): obj.save() db_entries = database.dump() - assert len(db_entries) == 1 + assert len(db_entries) == 2 assert db_entries[0] == ( + 'set', 'TestModel/instances', + "{'TestModel[valid-pk]'}") + assert db_entries[1] == ( 'dict', 'TestModel[valid-pk]', "{'active': 'True', 'age': '37', 'gender': 'MALE', 'name': 'John Smith', 'pk': 'valid-pk', "\ "'salary': '5023.52'}") @@ -270,7 +285,20 @@ def test_model_database_operations(): assert len(database.dump()) == 0 obj2.save() - assert len(database.dump()) == 1 + + db_entries = database.dump() + LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries))) + for db_entry in db_entries: + LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) + LOGGER.info('-----------------------------------------------------------') + assert len(db_entries) == 2 + assert db_entries[0] == ( + 'set', 'TestModel/instances', + "{'TestModel[valid-pk]'}") + assert db_entries[1] == ( + 'dict', 'TestModel[valid-pk]', + "{'active': 'True', 'age': '37', 'gender': 'MALE', 'name': 'John Smith', 'pk': 'valid-pk', "\ + "'salary': '5023.52'}") database.clear_all() assert len(database.dump()) == 0 @@ -462,29 +490,35 @@ def test_model_foreignkeys(): LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) LOGGER.info('-----------------------------------------------------------') - assert len(db_entries) == 10 - assert db_entries[0] == ('dict', "Member[brad]", - "{'gender': 'MALE', 'name': 'Brad', 'pk': 'brad', 'team': 'Team[admin]'}") - assert db_entries[1] == ('dict', "Member[jane]", - "{'gender': 'FEMALE', 'name': 'Jane', 'pk': 'jane', 'place': 'Workplace[mad]', "\ - "'team': 'Team[dev-ops]'}") - assert db_entries[2] == ('dict', "Member[john]", - "{'gender': 'MALE', 'name': 'John', 'pk': 'john', 'place': 'Workplace[mad]', "\ - "'team': 'Team[dev-ops]'}") - assert db_entries[3] == ('dict', "Team[admin]", - "{'name': 'Admin', 'pk': 'admin'}") - assert db_entries[4] == ('set' , "Team[admin]/references", - "{'Member[brad]:team'}") - assert db_entries[5] == ('dict', "Team[dev-ops]", - "{'name': 'Dev Ops', 'pk': 'dev-ops'}") - assert db_entries[6] == ('set' , "Team[dev-ops]/references", - "{'Member[jane]:team', 'Member[john]:team'}") - assert db_entries[7] == ('dict', "Workplace[bcn]", - "{'name': 'Barcelona', 'pk': 'bcn'}") - assert db_entries[8] == ('dict', "Workplace[mad]", - "{'name': 'Madrid', 'pk': 'mad'}") - assert db_entries[9] == ('set' , "Workplace[mad]/references", - "{'Member[jane]:place', 'Member[john]:place'}") + assert len(db_entries) == 13 + assert db_entries[ 0] == ('set', "Member/instances", + "{'Member[brad]', 'Member[jane]', 'Member[john]'}") + assert db_entries[ 1] == ('dict', "Member[brad]", + "{'gender': 'MALE', 'name': 'Brad', 'pk': 'brad', 'team': 'Team[admin]'}") + assert db_entries[ 2] == ('dict', "Member[jane]", + "{'gender': 'FEMALE', 'name': 'Jane', 'pk': 'jane', 'place': 'Workplace[mad]', "\ + "'team': 'Team[dev-ops]'}") + assert db_entries[ 3] == ('dict', "Member[john]", + "{'gender': 'MALE', 'name': 'John', 'pk': 'john', 'place': 'Workplace[mad]', "\ + "'team': 'Team[dev-ops]'}") + assert db_entries[ 4] == ('set', "Team/instances", + "{'Team[admin]', 'Team[dev-ops]'}") + assert db_entries[ 5] == ('dict', "Team[admin]", + "{'name': 'Admin', 'pk': 'admin'}") + assert db_entries[ 6] == ('set' , "Team[admin]/references", + "{'Member[brad]:team'}") + assert db_entries[ 7] == ('dict', "Team[dev-ops]", + "{'name': 'Dev Ops', 'pk': 'dev-ops'}") + assert db_entries[ 8] == ('set' , "Team[dev-ops]/references", + "{'Member[jane]:team', 'Member[john]:team'}") + assert db_entries[ 9] == ('set', "Workplace/instances", + "{'Workplace[bcn]', 'Workplace[mad]'}") + assert db_entries[10] == ('dict', "Workplace[bcn]", + "{'name': 'Barcelona', 'pk': 'bcn'}") + assert db_entries[11] == ('dict', "Workplace[mad]", + "{'name': 'Madrid', 'pk': 'mad'}") + assert db_entries[12] == ('set' , "Workplace[mad]/references", + "{'Member[jane]:place', 'Member[john]:place'}") Member(database, member_john.pk).delete() @@ -494,23 +528,29 @@ def test_model_foreignkeys(): LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) LOGGER.info('-----------------------------------------------------------') - assert len(db_entries) == 9 - assert db_entries[ 0] == ('dict', 'Member[brad]', + assert len(db_entries) == 12 + assert db_entries[ 0] == ('set', "Member/instances", + "{'Member[brad]', 'Member[jane]'}") + assert db_entries[ 1] == ('dict', 'Member[brad]', "{'gender': 'MALE', 'name': 'Brad', 'pk': 'brad', 'team': 'Team[admin]'}") - assert db_entries[ 1] == ('dict', 'Member[jane]', + assert db_entries[ 2] == ('dict', 'Member[jane]', "{'gender': 'FEMALE', 'name': 'Jane', 'pk': 'jane', 'place': 'Workplace[mad]', "\ "'team': 'Team[dev-ops]'}") - assert db_entries[ 2] == ('dict', 'Team[admin]', + assert db_entries[ 3] == ('set', "Team/instances", + "{'Team[admin]', 'Team[dev-ops]'}") + assert db_entries[ 4] == ('dict', 'Team[admin]', "{'name': 'Admin', 'pk': 'admin'}") - assert db_entries[ 3] == ('set', 'Team[admin]/references', + assert db_entries[ 5] == ('set', 'Team[admin]/references', "{'Member[brad]:team'}") - assert db_entries[ 4] == ('dict', 'Team[dev-ops]', + assert db_entries[ 6] == ('dict', 'Team[dev-ops]', "{'name': 'Dev Ops', 'pk': 'dev-ops'}") - assert db_entries[ 5] == ('set', 'Team[dev-ops]/references', + assert db_entries[ 7] == ('set', 'Team[dev-ops]/references', "{'Member[jane]:team'}") - assert db_entries[ 6] == ('dict', 'Workplace[bcn]', + assert db_entries[ 8] == ('set', "Workplace/instances", + "{'Workplace[bcn]', 'Workplace[mad]'}") + assert db_entries[ 9] == ('dict', 'Workplace[bcn]', "{'name': 'Barcelona', 'pk': 'bcn'}") - assert db_entries[ 7] == ('dict', 'Workplace[mad]', + assert db_entries[10] == ('dict', 'Workplace[mad]', "{'name': 'Madrid', 'pk': 'mad'}") - assert db_entries[ 8] == ('set', 'Workplace[mad]/references', + assert db_entries[11] == ('set', 'Workplace[mad]/references', "{'Member[jane]:place'}") diff --git a/src/context/client/ContextClient.py b/src/context/client/ContextClient.py index 32074eba3c8681029b567ca7bc4760d0879a593a..048a47edc3e51c7628ce5659eed05de78aed633e 100644 --- a/src/context/client/ContextClient.py +++ b/src/context/client/ContextClient.py @@ -1,6 +1,13 @@ +from typing import Iterator import grpc, logging from common.tools.client.RetryDecorator import retry, delay_exponential -from context.proto.context_pb2 import Link, LinkId, Empty, Topology +from context.proto.context_pb2 import \ + Context, ContextEvent, ContextId, ContextIdList, ContextList, \ + Device, DeviceEvent, DeviceId, DeviceIdList, DeviceList, \ + Empty, \ + Link, LinkEvent, LinkId, LinkIdList, LinkList, \ + Service, ServiceEvent, ServiceId, ServiceIdList, ServiceList, \ + Topology, TopologyEvent, TopologyId, TopologyIdList, TopologyList from context.proto.context_pb2_grpc import ContextServiceStub LOGGER = logging.getLogger(__name__) @@ -10,7 +17,7 @@ DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0) class ContextClient: def __init__(self, address, port): self.endpoint = '{}:{}'.format(address, port) - LOGGER.debug('Creating channel to {}...'.format(self.endpoint)) + LOGGER.debug('Creating channel to {:s}...'.format(self.endpoint)) self.channel = None self.stub = None self.connect() @@ -21,27 +28,216 @@ class ContextClient: self.stub = ContextServiceStub(self.channel) def close(self): - if(self.channel is not None): self.channel.close() + if self.channel is not None: self.channel.close() self.channel = None self.stub = None @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') - def GetTopology(self, request : Empty) -> Topology: - LOGGER.debug('GetTopology request: {}'.format(request)) + def ListContextIds(self, request: Empty) -> ContextIdList: + LOGGER.debug('ListContextIds request: {:s}'.format(str(request))) + response = self.stub.ListContextIds(request) + LOGGER.debug('ListContextIds result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def ListContexts(self, request: Empty) -> ContextList: + LOGGER.debug('ListContexts request: {:s}'.format(str(request))) + response = self.stub.ListContexts(request) + LOGGER.debug('ListContexts result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def GetContext(self, request: ContextId) -> Context: + LOGGER.debug('GetContext request: {:s}'.format(str(request))) + response = self.stub.GetContext(request) + LOGGER.debug('GetContext result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def SetContext(self, request: Context) -> ContextId: + LOGGER.debug('SetContext request: {:s}'.format(str(request))) + response = self.stub.SetContext(request) + LOGGER.debug('SetContext result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def RemoveContext(self, request: ContextId) -> Empty: + LOGGER.debug('RemoveContext request: {:s}'.format(str(request))) + response = self.stub.RemoveContext(request) + LOGGER.debug('RemoveContext result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def GetContextEvents(self, request: Empty) -> Iterator[ContextEvent]: + LOGGER.debug('GetContextEvents request: {:s}'.format(str(request))) + response = self.stub.GetContextEvents(request) + LOGGER.debug('GetContextEvents result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def ListTopologyIds(self, request: ContextId) -> TopologyIdList: + LOGGER.debug('ListTopologyIds request: {:s}'.format(str(request))) + response = self.stub.ListTopologyIds(request) + LOGGER.debug('ListTopologyIds result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def ListTopologies(self, request: ContextId) -> TopologyList: + LOGGER.debug('ListTopologies request: {:s}'.format(str(request))) + response = self.stub.ListTopologies(request) + LOGGER.debug('ListTopologies result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def GetTopology(self, request: TopologyId) -> Topology: + LOGGER.debug('GetTopology request: {:s}'.format(str(request))) response = self.stub.GetTopology(request) - LOGGER.debug('GetTopology result: {}'.format(response)) + LOGGER.debug('GetTopology result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def SetTopology(self, request: Topology) -> TopologyId: + LOGGER.debug('SetTopology request: {:s}'.format(str(request))) + response = self.stub.SetTopology(request) + LOGGER.debug('SetTopology result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def RemoveTopology(self, request: TopologyId) -> Empty: + LOGGER.debug('RemoveTopology request: {:s}'.format(str(request))) + response = self.stub.RemoveTopology(request) + LOGGER.debug('RemoveTopology result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def GetTopologyEvents(self, request: Empty) -> Iterator[TopologyEvent]: + LOGGER.debug('GetTopologyEvents request: {:s}'.format(str(request))) + response = self.stub.GetTopologyEvents(request) + LOGGER.debug('GetTopologyEvents result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def ListDeviceIds(self, request: Empty) -> DeviceIdList: + LOGGER.debug('ListDeviceIds request: {:s}'.format(str(request))) + response = self.stub.ListDeviceIds(request) + LOGGER.debug('ListDeviceIds result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def ListDevices(self, request: Empty) -> DeviceList: + LOGGER.debug('ListDevices request: {:s}'.format(str(request))) + response = self.stub.ListDevices(request) + LOGGER.debug('ListDevices result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def GetDevice(self, request: DeviceId) -> Device: + LOGGER.debug('GetDevice request: {:s}'.format(str(request))) + response = self.stub.GetDevice(request) + LOGGER.debug('GetDevice result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def SetDevice(self, request: Device) -> DeviceId: + LOGGER.debug('SetDevice request: {:s}'.format(str(request))) + response = self.stub.SetDevice(request) + LOGGER.debug('SetDevice result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def RemoveDevice(self, request: DeviceId) -> Empty: + LOGGER.debug('RemoveDevice request: {:s}'.format(str(request))) + response = self.stub.RemoveDevice(request) + LOGGER.debug('RemoveDevice result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def GetDeviceEvents(self, request: Empty) -> Iterator[DeviceEvent]: + LOGGER.debug('GetDeviceEvents request: {:s}'.format(str(request))) + response = self.stub.GetDeviceEvents(request) + LOGGER.debug('GetDeviceEvents result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def ListLinkIds(self, request: Empty) -> LinkIdList: + LOGGER.debug('ListLinkIds request: {:s}'.format(str(request))) + response = self.stub.ListLinkIds(request) + LOGGER.debug('ListLinkIds result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def ListLinks(self, request: Empty) -> LinkList: + LOGGER.debug('ListLinks request: {:s}'.format(str(request))) + response = self.stub.ListLinks(request) + LOGGER.debug('ListLinks result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def GetLink(self, request: LinkId) -> Link: + LOGGER.debug('GetLink request: {:s}'.format(str(request))) + response = self.stub.GetLink(request) + LOGGER.debug('GetLink result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def SetLink(self, request: Link) -> LinkId: + LOGGER.debug('SetLink request: {:s}'.format(str(request))) + response = self.stub.SetLink(request) + LOGGER.debug('SetLink result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def RemoveLink(self, request: LinkId) -> Empty: + LOGGER.debug('RemoveLink request: {:s}'.format(str(request))) + response = self.stub.RemoveLink(request) + LOGGER.debug('RemoveLink result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def GetLinkEvents(self, request: Empty) -> Iterator[LinkEvent]: + LOGGER.debug('GetLinkEvents request: {:s}'.format(str(request))) + response = self.stub.GetLinkEvents(request) + LOGGER.debug('GetLinkEvents result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def ListServiceIds(self, request: ContextId) -> ServiceIdList: + LOGGER.debug('ListServiceIds request: {:s}'.format(str(request))) + response = self.stub.ListServiceIds(request) + LOGGER.debug('ListServiceIds result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def ListServices(self, request: ContextId) -> ServiceList: + LOGGER.debug('ListServices request: {:s}'.format(str(request))) + response = self.stub.ListServices(request) + LOGGER.debug('ListServices result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def GetService(self, request: ServiceId) -> Service: + LOGGER.debug('GetService request: {:s}'.format(str(request))) + response = self.stub.GetService(request) + LOGGER.debug('GetService result: {:s}'.format(str(response))) + return response + + @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') + def SetService(self, request: Service) -> ServiceId: + LOGGER.debug('SetService request: {:s}'.format(str(request))) + response = self.stub.SetService(request) + LOGGER.debug('SetService result: {:s}'.format(str(response))) return response @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') - def AddLink(self, request : Link) -> LinkId: - LOGGER.debug('AddLink request: {}'.format(request)) - response = self.stub.AddLink(request) - LOGGER.debug('AddLink result: {}'.format(response)) + def RemoveService(self, request: ServiceId) -> Empty: + LOGGER.debug('RemoveService request: {:s}'.format(str(request))) + response = self.stub.RemoveService(request) + LOGGER.debug('RemoveService result: {:s}'.format(str(response))) return response @retry(exceptions=set(), max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect') - def DeleteLink(self, request : LinkId) -> Empty: - LOGGER.debug('DeleteLink request: {}'.format(request)) - response = self.stub.DeleteLink(request) - LOGGER.debug('DeleteLink result: {}'.format(response)) + def GetServiceEvents(self, request: Empty) -> Iterator[ServiceEvent]: + LOGGER.debug('GetServiceEvents request: {:s}'.format(str(request))) + response = self.stub.GetServiceEvents(request) + LOGGER.debug('GetServiceEvents result: {:s}'.format(str(response))) return response diff --git a/src/context/proto/context_pb2.py b/src/context/proto/context_pb2.py index 58d582f037688e25c06cbfc39cae27df46ae1fc5..7a0b096c5b1c9036929e026bb8f6de4e26992cc5 100644 --- a/src/context/proto/context_pb2.py +++ b/src/context/proto/context_pb2.py @@ -20,7 +20,7 @@ DESCRIPTOR = _descriptor.FileDescriptor( syntax='proto3', serialized_options=None, create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x87\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x08topology\x18\x02 \x03(\x0b\x32\x11.context.Topology\x12/\n\ncontroller\x18\x03 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x8f\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12\x43\n\x19\x64\x65vive_operational_status\x18\x04 \x01(\x0e\x32 .context.DeviceOperationalStatus\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12$\n\tendpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"S\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12)\n\x0c\x65ndpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\x94\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12)\n\x0c\x65ndpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12(\n\x0b\x63onstraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12,\n\rservice_state\x18\x05 \x01(\x0b\x32\x15.context.ServiceState\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"@\n\x0cServiceState\x12\x30\n\rservice_state\x18\x01 \x01(\x0e\x32\x19.context.ServiceStateEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"G\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x11\n\tport_type\x18\x02 \x01(\t\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x8d\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12.\n\x12related_service_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12!\n\x04path\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*C\n\x17\x44\x65viceOperationalStatus\x12\r\n\tUNDEFINED\x10\x00\x12\x0c\n\x08\x44ISABLED\x10\x01\x12\x0b\n\x07\x45NABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*j\n\x10ServiceStateEnum\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x00\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x01\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x02*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xa5\r\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x62\x06proto3' + serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x8f\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12\x43\n\x19\x64\x65vive_operational_status\x18\x04 \x01(\x0e\x32 .context.DeviceOperationalStatus\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12$\n\tendpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"S\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12)\n\x0c\x65ndpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\x94\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12)\n\x0c\x65ndpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12(\n\x0b\x63onstraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12,\n\rservice_state\x18\x05 \x01(\x0b\x32\x15.context.ServiceState\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"@\n\x0cServiceState\x12\x30\n\rservice_state\x18\x01 \x01(\x0e\x32\x19.context.ServiceStateEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"G\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x11\n\tport_type\x18\x02 \x01(\t\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x8d\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12.\n\x12related_service_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12!\n\x04path\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*C\n\x17\x44\x65viceOperationalStatus\x12\r\n\tUNDEFINED\x10\x00\x12\x0c\n\x08\x44ISABLED\x10\x01\x12\x0b\n\x07\x45NABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*j\n\x10ServiceStateEnum\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x00\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x01\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x02*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xa5\r\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x62\x06proto3' ) _EVENTTYPEENUM = _descriptor.EnumDescriptor( @@ -53,8 +53,8 @@ _EVENTTYPEENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=3380, - serialized_end=3486, + serialized_start=3427, + serialized_end=3533, ) _sym_db.RegisterEnumDescriptor(_EVENTTYPEENUM) @@ -99,8 +99,8 @@ _DEVICEDRIVERENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=3489, - serialized_end=3686, + serialized_start=3536, + serialized_end=3733, ) _sym_db.RegisterEnumDescriptor(_DEVICEDRIVERENUM) @@ -130,8 +130,8 @@ _DEVICEOPERATIONALSTATUS = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=3688, - serialized_end=3755, + serialized_start=3735, + serialized_end=3802, ) _sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUS) @@ -166,8 +166,8 @@ _SERVICETYPEENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=3758, - serialized_end=3887, + serialized_start=3805, + serialized_end=3934, ) _sym_db.RegisterEnumDescriptor(_SERVICETYPEENUM) @@ -197,8 +197,8 @@ _SERVICESTATEENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=3889, - serialized_end=3995, + serialized_start=3936, + serialized_end=4042, ) _sym_db.RegisterEnumDescriptor(_SERVICESTATEENUM) @@ -228,8 +228,8 @@ _CONFIGACTIONENUM = _descriptor.EnumDescriptor( ], containing_type=None, serialized_options=None, - serialized_start=3997, - serialized_end=4090, + serialized_start=4044, + serialized_end=4137, ) _sym_db.RegisterEnumDescriptor(_CONFIGACTIONENUM) @@ -404,15 +404,22 @@ _CONTEXT = _descriptor.Descriptor( is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='topology', full_name='context.Context.topology', index=1, + name='topology_ids', full_name='context.Context.topology_ids', index=1, number=2, type=11, cpp_type=10, label=3, has_default_value=False, default_value=[], message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), _descriptor.FieldDescriptor( - name='controller', full_name='context.Context.controller', index=2, - number=3, type=11, cpp_type=10, label=1, + name='service_ids', full_name='context.Context.service_ids', index=2, + number=3, type=11, cpp_type=10, label=3, + has_default_value=False, default_value=[], + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key), + _descriptor.FieldDescriptor( + name='controller', full_name='context.Context.controller', index=3, + number=4, type=11, cpp_type=10, label=1, has_default_value=False, default_value=None, message_type=None, enum_type=None, containing_type=None, is_extension=False, extension_scope=None, @@ -430,7 +437,7 @@ _CONTEXT = _descriptor.Descriptor( oneofs=[ ], serialized_start=180, - serialized_end=315, + serialized_end=362, ) @@ -461,8 +468,8 @@ _CONTEXTIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=317, - serialized_end=373, + serialized_start=364, + serialized_end=420, ) @@ -493,8 +500,8 @@ _CONTEXTLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=375, - serialized_end=424, + serialized_start=422, + serialized_end=471, ) @@ -532,8 +539,8 @@ _CONTEXTEVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=426, - serialized_end=511, + serialized_start=473, + serialized_end=558, ) @@ -571,8 +578,8 @@ _TOPOLOGYID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=513, - serialized_end=603, + serialized_start=560, + serialized_end=650, ) @@ -617,8 +624,8 @@ _TOPOLOGY = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=605, - serialized_end=731, + serialized_start=652, + serialized_end=778, ) @@ -649,8 +656,8 @@ _TOPOLOGYIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=733, - serialized_end=792, + serialized_start=780, + serialized_end=839, ) @@ -681,8 +688,8 @@ _TOPOLOGYLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=794, - serialized_end=847, + serialized_start=841, + serialized_end=894, ) @@ -720,8 +727,8 @@ _TOPOLOGYEVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=849, - serialized_end=937, + serialized_start=896, + serialized_end=984, ) @@ -752,8 +759,8 @@ _DEVICEID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=939, - serialized_end=985, + serialized_start=986, + serialized_end=1032, ) @@ -819,8 +826,8 @@ _DEVICE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=988, - serialized_end=1259, + serialized_start=1035, + serialized_end=1306, ) @@ -851,8 +858,8 @@ _DEVICECONFIG = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1261, - serialized_end=1318, + serialized_start=1308, + serialized_end=1365, ) @@ -883,8 +890,8 @@ _DEVICEIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1320, - serialized_end=1373, + serialized_start=1367, + serialized_end=1420, ) @@ -915,8 +922,8 @@ _DEVICELIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1375, - serialized_end=1421, + serialized_start=1422, + serialized_end=1468, ) @@ -954,8 +961,8 @@ _DEVICEEVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1423, - serialized_end=1505, + serialized_start=1470, + serialized_end=1552, ) @@ -986,8 +993,8 @@ _LINKID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1507, - serialized_end=1549, + serialized_start=1554, + serialized_end=1596, ) @@ -1025,8 +1032,8 @@ _LINK = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1551, - serialized_end=1634, + serialized_start=1598, + serialized_end=1681, ) @@ -1057,8 +1064,8 @@ _LINKIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1636, - serialized_end=1683, + serialized_start=1683, + serialized_end=1730, ) @@ -1089,8 +1096,8 @@ _LINKLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1685, - serialized_end=1725, + serialized_start=1732, + serialized_end=1772, ) @@ -1128,8 +1135,8 @@ _LINKEVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1727, - serialized_end=1803, + serialized_start=1774, + serialized_end=1850, ) @@ -1167,8 +1174,8 @@ _SERVICEID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1805, - serialized_end=1893, + serialized_start=1852, + serialized_end=1940, ) @@ -1234,8 +1241,8 @@ _SERVICE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=1896, - serialized_end=2172, + serialized_start=1943, + serialized_end=2219, ) @@ -1266,8 +1273,8 @@ _SERVICESTATE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2174, - serialized_end=2238, + serialized_start=2221, + serialized_end=2285, ) @@ -1298,8 +1305,8 @@ _SERVICECONFIG = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2240, - serialized_end=2298, + serialized_start=2287, + serialized_end=2345, ) @@ -1330,8 +1337,8 @@ _SERVICEIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2300, - serialized_end=2356, + serialized_start=2347, + serialized_end=2403, ) @@ -1362,8 +1369,8 @@ _SERVICELIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2358, - serialized_end=2407, + serialized_start=2405, + serialized_end=2454, ) @@ -1401,8 +1408,8 @@ _SERVICEEVENT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2409, - serialized_end=2494, + serialized_start=2456, + serialized_end=2541, ) @@ -1447,8 +1454,8 @@ _ENDPOINTID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2497, - serialized_end=2627, + serialized_start=2544, + serialized_end=2674, ) @@ -1486,8 +1493,8 @@ _ENDPOINT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2629, - serialized_end=2700, + serialized_start=2676, + serialized_end=2747, ) @@ -1532,8 +1539,8 @@ _CONFIGRULE = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2702, - serialized_end=2803, + serialized_start=2749, + serialized_end=2850, ) @@ -1571,8 +1578,8 @@ _CONSTRAINT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2805, - serialized_end=2868, + serialized_start=2852, + serialized_end=2915, ) @@ -1603,8 +1610,8 @@ _CONNECTIONID = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2870, - serialized_end=2924, + serialized_start=2917, + serialized_end=2971, ) @@ -1649,8 +1656,8 @@ _CONNECTION = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=2927, - serialized_end=3068, + serialized_start=2974, + serialized_end=3115, ) @@ -1681,8 +1688,8 @@ _CONNECTIONIDLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3070, - serialized_end=3135, + serialized_start=3117, + serialized_end=3182, ) @@ -1713,8 +1720,8 @@ _CONNECTIONLIST = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3137, - serialized_end=3195, + serialized_start=3184, + serialized_end=3242, ) @@ -1759,8 +1766,8 @@ _TERAFLOWCONTROLLER = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3197, - serialized_end=3291, + serialized_start=3244, + serialized_end=3338, ) @@ -1798,14 +1805,15 @@ _AUTHENTICATIONRESULT = _descriptor.Descriptor( extension_ranges=[], oneofs=[ ], - serialized_start=3293, - serialized_end=3378, + serialized_start=3340, + serialized_end=3425, ) _EVENT.fields_by_name['event_type'].enum_type = _EVENTTYPEENUM _CONTEXTID.fields_by_name['context_uuid'].message_type = _UUID _CONTEXT.fields_by_name['context_id'].message_type = _CONTEXTID -_CONTEXT.fields_by_name['topology'].message_type = _TOPOLOGY +_CONTEXT.fields_by_name['topology_ids'].message_type = _TOPOLOGYID +_CONTEXT.fields_by_name['service_ids'].message_type = _SERVICEID _CONTEXT.fields_by_name['controller'].message_type = _TERAFLOWCONTROLLER _CONTEXTIDLIST.fields_by_name['context_ids'].message_type = _CONTEXTID _CONTEXTLIST.fields_by_name['contexts'].message_type = _CONTEXT @@ -2210,8 +2218,8 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor( index=0, serialized_options=None, create_key=_descriptor._internal_create_key, - serialized_start=4093, - serialized_end=5794, + serialized_start=4140, + serialized_end=5841, methods=[ _descriptor.MethodDescriptor( name='ListContextIds', diff --git a/src/context/service/database/Models.py b/src/context/service/database/Models.py index 8b8d974d6c3383ba1e0241c1cb8b87c3a279fa94..962e9373a4236d11fd44c9fb80f459c43c29d715 100644 --- a/src/context/service/database/Models.py +++ b/src/context/service/database/Models.py @@ -1,3 +1,4 @@ +from typing import Dict, List from common.orm.fields.IntegerField import IntegerField from common.orm.fields.StringField import StringField from common.orm.model.Model import Model @@ -7,6 +8,23 @@ from common.orm.fields.PrimaryKeyField import PrimaryKeyField class ContextModel(Model): pk = PrimaryKeyField() + def dump_id(self) -> Dict: + return {'context_uuid': {'uuid': self.pk}} + + def dump_service_ids(self) -> List[Dict]: + db_service_pks = self.references(ServiceModel) + return [ServiceModel(self.database, pk).dump_id() for pk in db_service_pks] + + def dump_topology_ids(self) -> List[Dict]: + db_topology_pks = self.references(TopologyModel) + return [TopologyModel(self.database, pk).dump_id() for pk in db_topology_pks] + + def dump(self, include_services=True, include_topologies=True) -> Dict: # pylint: disable=arguments-differ + result = {'context_id': self.dump_id()} + if include_services: result['service_ids'] = self.dump_service_ids() + if include_topologies: result['topology_ids'] = self.dump_topology_ids() + return result + class TopologyModel(Model): pk = PrimaryKeyField() context_fk = ForeignKeyField(ContextModel) diff --git a/src/context/service/grpc_server/ContextServiceServicerImpl.py b/src/context/service/grpc_server/ContextServiceServicerImpl.py index 6bd10730357fed0d3f45aeb22a2d06bcced3225a..47967eddeeb77bc0d0478bb3556045c4160595c9 100644 --- a/src/context/service/grpc_server/ContextServiceServicerImpl.py +++ b/src/context/service/grpc_server/ContextServiceServicerImpl.py @@ -5,13 +5,14 @@ from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID from common.metrics.Metrics import create_metrics, safe_and_metered_rpc_method from common.orm.Database import Database from context.proto.context_pb2 import \ - Context, ContextEvent, ContextId, ContextIdList, ContextList, \ - Device, DeviceEvent, DeviceId, DeviceIdList, DeviceList, \ - Empty, \ - Link, LinkEvent, LinkId, LinkIdList, LinkList, \ - Service, ServiceEvent, ServiceId, ServiceIdList, ServiceList, \ + Context, ContextEvent, ContextId, ContextIdList, ContextList, \ + Device, DeviceEvent, DeviceId, DeviceIdList, DeviceList, \ + Empty, \ + Link, LinkEvent, LinkId, LinkIdList, LinkList, \ + Service, ServiceEvent, ServiceId, ServiceIdList, ServiceList, \ Topology, TopologyEvent, TopologyId, TopologyIdList, TopologyList from context.proto.context_pb2_grpc import ContextServiceServicer +from context.service.database.Models import ContextModel #from .Tools import check_link_id_request, check_link_request LOGGER = logging.getLogger(__name__) @@ -34,23 +35,33 @@ class ContextServiceServicerImpl(ContextServiceServicer): @safe_and_metered_rpc_method(METRICS, LOGGER) def ListContextIds(self, request: Empty, context : grpc.ServicerContext) -> ContextIdList: - pass + db_context_pks = sorted(list(ContextModel.get_primary_keys(self.database))) + context_ids = [ContextModel(self.database, pk).dump_id() for pk in db_context_pks] + return ContextIdList(context_ids=context_ids) @safe_and_metered_rpc_method(METRICS, LOGGER) def ListContexts(self, request: Empty, context : grpc.ServicerContext) -> ContextList: - pass + db_context_pks = sorted(list(ContextModel.get_primary_keys(self.database))) + contexts = [ContextModel(self.database, pk).dump() for pk in db_context_pks] + return ContextList(contexts=contexts) @safe_and_metered_rpc_method(METRICS, LOGGER) def GetContext(self, request: ContextId, context : grpc.ServicerContext) -> Context: - pass + db_context = ContextModel(self.database, request.context_uuid.uuid) + return Context(**db_context.dump(include_services=True, include_topologies=True)) @safe_and_metered_rpc_method(METRICS, LOGGER) def SetContext(self, request: Context, context : grpc.ServicerContext) -> ContextId: - pass + db_context = ContextModel(self.database, request.context_id.context_uuid.uuid) + db_context.save() + # TODO: add topologies and services + return ContextId(**db_context.dump_id()) @safe_and_metered_rpc_method(METRICS, LOGGER) def RemoveContext(self, request: ContextId, context : grpc.ServicerContext) -> Empty: - pass + db_context = ContextModel(self.database, request.context_uuid.uuid) + db_context.delete() + return Empty() @safe_and_metered_rpc_method(METRICS, LOGGER) def GetContextEvents(self, request: Empty, context : grpc.ServicerContext) -> Iterator[ContextEvent]: diff --git a/src/context/tests/orm_populate_data.py b/src/context/tests/old/orm_populate_data.py similarity index 100% rename from src/context/tests/orm_populate_data.py rename to src/context/tests/old/orm_populate_data.py diff --git a/src/context/tests/test_orm_backend_inmemory.py b/src/context/tests/old/test_orm_backend_inmemory.py similarity index 100% rename from src/context/tests/test_orm_backend_inmemory.py rename to src/context/tests/old/test_orm_backend_inmemory.py diff --git a/src/context/tests/test_orm_backend_redis.py b/src/context/tests/old/test_orm_backend_redis.py similarity index 100% rename from src/context/tests/test_orm_backend_redis.py rename to src/context/tests/old/test_orm_backend_redis.py diff --git a/src/context/tests/test_unitary_orm_context_inmemory.py b/src/context/tests/old/test_unitary_orm_context_inmemory.py similarity index 100% rename from src/context/tests/test_unitary_orm_context_inmemory.py rename to src/context/tests/old/test_unitary_orm_context_inmemory.py diff --git a/src/context/tests/test_unitary.py b/src/context/tests/test_unitary.py index b230ac599438db961e978ce08388a303aad86408..897dc539f0d5352fef75c58a38ad4fda1d312db0 100644 --- a/src/context/tests/test_unitary.py +++ b/src/context/tests/test_unitary.py @@ -1,36 +1,44 @@ -import copy, grpc, logging, pytest, requests, time -from google.protobuf.json_format import MessageToDict +import copy, logging, pytest +#import grpc, requests, time +#from google.protobuf.json_format import MessageToDict from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID -from common.tests.Assertions import validate_empty, validate_link_id, validate_topology, validate_topology_has_devices,\ - validate_topology_has_links, validate_topology_is_empty +from common.orm.Database import Database +from common.orm.Factory import get_database_backend, BackendEnum +#from common.tests.Assertions import validate_empty, validate_link_id, validate_topology, validate_topology_has_devices,\ +# validate_topology_has_links, validate_topology_is_empty from context.client.ContextClient import ContextClient -from context.proto.context_pb2 import Empty, Link, LinkId, Topology -from context.service.database.Database import Database -from context.service.database._engine.Factory import get_database_backend, BackendEnum +from context.proto.context_pb2 import \ + Context, ContextEvent, ContextId, ContextIdList, ContextList, \ + Device, DeviceEvent, DeviceId, DeviceIdList, DeviceList, \ + Empty, \ + Link, LinkEvent, LinkId, LinkIdList, LinkList, \ + Service, ServiceEvent, ServiceId, ServiceIdList, ServiceList, \ + Topology, TopologyEvent, TopologyId, TopologyIdList, TopologyList from context.service.grpc_server.ContextService import ContextService -from context.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, RESTAPI_SERVICE_PORT, \ - RESTAPI_BASE_URL -from context.service.rest_server.Server import Server -from context.service.rest_server.resources.Context import Context -from .populate_database import populate_example +from context.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD #, RESTAPI_SERVICE_PORT, \ +# RESTAPI_BASE_URL +#from context.service.rest_server.Server import Server +#from context.service.rest_server.resources.Context import Context +#from .populate_database import populate_example grpc_port = 10000 + GRPC_SERVICE_PORT # avoid privileged ports -restapi_port = 10000 + RESTAPI_SERVICE_PORT # avoid privileged ports +#restapi_port = 10000 + RESTAPI_SERVICE_PORT # avoid privileged ports LOGGER = logging.getLogger(__name__) LOGGER.setLevel(logging.DEBUG) -# use "copy.deepcopy" to prevent propagating forced changes during tests -CONTEXT_ID = {'contextUuid': {'uuid': DEFAULT_CONTEXT_UUID}} -TOPOLOGY_ID = {'contextId': copy.deepcopy(CONTEXT_ID), 'topoId': {'uuid': DEFAULT_TOPOLOGY_UUID}} -LINK_ID = {'link_id': {'uuid': 'DEV1/EP2 ==> DEV2/EP1'}} -LINK = { - 'link_id': {'link_id': {'uuid': 'DEV1/EP2 ==> DEV2/EP1'}}, - 'endpointList' : [ - {'topoId': copy.deepcopy(TOPOLOGY_ID), 'dev_id': {'device_id': {'uuid': 'DEV1'}}, 'port_id': {'uuid' : 'EP2'}}, - {'topoId': copy.deepcopy(TOPOLOGY_ID), 'dev_id': {'device_id': {'uuid': 'DEV2'}}, 'port_id': {'uuid' : 'EP1'}}, - ] -} +## use "copy.deepcopy" to prevent propagating forced changes during tests +CONTEXT_ID = {'context_uuid': {'uuid': DEFAULT_CONTEXT_UUID}} +CONTEXT = {'context_id': copy.deepcopy(CONTEXT_ID)} +#TOPOLOGY_ID = {'contextId': copy.deepcopy(CONTEXT_ID), 'topoId': {'uuid': DEFAULT_TOPOLOGY_UUID}} +#LINK_ID = {'link_id': {'uuid': 'DEV1/EP2 ==> DEV2/EP1'}} +#LINK = { +# 'link_id': {'link_id': {'uuid': 'DEV1/EP2 ==> DEV2/EP1'}}, +# 'endpointList' : [ +# {'topoId': copy.deepcopy(TOPOLOGY_ID), 'dev_id': {'device_id': {'uuid': 'DEV1'}}, 'port_id': {'uuid' : 'EP2'}}, +# {'topoId': copy.deepcopy(TOPOLOGY_ID), 'dev_id': {'device_id': {'uuid': 'DEV2'}}, 'port_id': {'uuid' : 'EP1'}}, +# ] +#} @pytest.fixture(scope='session') def context_database(): @@ -39,212 +47,265 @@ def context_database(): return _database @pytest.fixture(scope='session') -def context_service(context_database : Database): +def context_service(context_database : Database): # pylint: disable=redefined-outer-name _service = ContextService( context_database, port=grpc_port, max_workers=GRPC_MAX_WORKERS, grace_period=GRPC_GRACE_PERIOD) _service.start() yield _service _service.stop() -@pytest.fixture(scope='session') -def context_service_rest(context_database : Database): - _rest_server = Server(port=restapi_port, base_url=RESTAPI_BASE_URL) - _rest_server.add_resource(Context, '/context', endpoint='api.context', resource_class_args=(context_database,)) - _rest_server.start() - time.sleep(1) # bring time for the server to start - yield _rest_server - _rest_server.shutdown() - _rest_server.join() +#@pytest.fixture(scope='session') +#def context_service_rest(context_database : Database): +# _rest_server = Server(port=restapi_port, base_url=RESTAPI_BASE_URL) +# _rest_server.add_resource(Context, '/context', endpoint='api.context', resource_class_args=(context_database,)) +# _rest_server.start() +# time.sleep(1) # bring time for the server to start +# yield _rest_server +# _rest_server.shutdown() +# _rest_server.join() @pytest.fixture(scope='session') -def context_client(context_service): +def context_client(context_service : ContextService): # pylint: disable=redefined-outer-name _client = ContextClient(address='127.0.0.1', port=grpc_port) yield _client _client.close() -def test_get_topology_empty(context_client : ContextClient, context_database : Database): - # should work +def test_context_instances( + context_client : ContextClient, context_database : Database): # pylint: disable=redefined-outer-name + context_database.clear_all() - validate_topology_is_empty(MessageToDict( - context_client.GetTopology(Empty()), - including_default_value_fields=True, preserving_proto_field_name=True, - use_integers_for_enums=False)) - -def test_get_topology_completed(context_client : ContextClient, context_database : Database): - # should work - populate_example(context_database, add_services=False) - topology = MessageToDict( - context_client.GetTopology(Empty()), - including_default_value_fields=True, preserving_proto_field_name=True, - use_integers_for_enums=False) - validate_topology(topology) - validate_topology_has_devices(topology) - validate_topology_has_links(topology) - -def test_delete_link_empty_uuid(context_client : ContextClient): - # should fail with link not found - with pytest.raises(grpc._channel._InactiveRpcError) as e: - copy_link_id = copy.deepcopy(LINK_ID) - copy_link_id['link_id']['uuid'] = '' - context_client.DeleteLink(LinkId(**copy_link_id)) - assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT - msg = 'link_id.link_id.uuid() is out of range: '\ - 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).' - assert e.value.details() == msg - -def test_add_link_already_exists(context_client : ContextClient): - # should fail with link already exists - with pytest.raises(grpc._channel._InactiveRpcError) as e: - context_client.AddLink(Link(**LINK)) - assert e.value.code() == grpc.StatusCode.ALREADY_EXISTS - msg = 'Context(admin)/Topology(admin)/Link(DEV1/EP2 ==> DEV2/EP1) already exists in the database.' - assert e.value.details() == msg - -def test_delete_link(context_client : ContextClient): - # should work - validate_empty(MessageToDict( - context_client.DeleteLink(LinkId(**LINK_ID)), - including_default_value_fields=True, preserving_proto_field_name=True, - use_integers_for_enums=False)) - -def test_delete_link_not_existing(context_client : ContextClient): - # should fail with link not found - with pytest.raises(grpc._channel._InactiveRpcError) as e: - context_client.DeleteLink(LinkId(**LINK_ID)) - assert e.value.code() == grpc.StatusCode.NOT_FOUND - msg = 'Context(admin)/Topology(admin)/Link(DEV1/EP2 ==> DEV2/EP1) does not exist in the database.' - assert e.value.details() == msg - -def test_add_link_uuid_empty(context_client : ContextClient): - # should fail with link uuid empty - with pytest.raises(grpc._channel._InactiveRpcError) as e: - copy_link = copy.deepcopy(LINK) - copy_link['link_id']['link_id']['uuid'] = '' - context_client.AddLink(Link(**copy_link)) - assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT - msg = 'link.link_id.link_id.uuid() is out of range: '\ - 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).' - assert e.value.details() == msg - -def test_add_link_wrong_endpoint(context_client : ContextClient): - # should fail with wrong endpoint context - with pytest.raises(grpc._channel._InactiveRpcError) as e: - copy_link = copy.deepcopy(LINK) - copy_link['endpointList'][0]['topoId']['contextId']['contextUuid']['uuid'] = 'wrong-context' - context_client.AddLink(Link(**copy_link)) - assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT - msg = 'Context(wrong-context) in Endpoint(#0) of '\ - 'Context(admin)/Topology(admin)/Link(DEV1/EP2 ==> DEV2/EP1) mismatches acceptable Contexts({\'admin\'}). '\ - 'Optionally, leave field empty to use predefined Context(admin).' - assert e.value.details() == msg - - # should fail with wrong endpoint topology - with pytest.raises(grpc._channel._InactiveRpcError) as e: - copy_link = copy.deepcopy(LINK) - copy_link['endpointList'][0]['topoId']['topoId']['uuid'] = 'wrong-topo' - context_client.AddLink(Link(**copy_link)) - assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT - msg = 'Context(admin)/Topology(wrong-topo) in Endpoint(#0) of '\ - 'Context(admin)/Topology(admin)/Link(DEV1/EP2 ==> DEV2/EP1) mismatches acceptable Topologies({\'admin\'}). '\ - 'Optionally, leave field empty to use predefined Topology(admin).' - assert e.value.details() == msg - - # should fail with device uuid is empty - with pytest.raises(grpc._channel._InactiveRpcError) as e: - copy_link = copy.deepcopy(LINK) - copy_link['endpointList'][0]['dev_id']['device_id']['uuid'] = '' - context_client.AddLink(Link(**copy_link)) - assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT - msg = 'endpoint_id[#0].dev_id.device_id.uuid() is out of range: '\ - 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).' - assert e.value.details() == msg - - # should fail with wrong endpoint device - with pytest.raises(grpc._channel._InactiveRpcError) as e: - copy_link = copy.deepcopy(LINK) - copy_link['endpointList'][0]['dev_id']['device_id']['uuid'] = 'wrong-device' - context_client.AddLink(Link(**copy_link)) - assert e.value.code() == grpc.StatusCode.NOT_FOUND - msg = 'Context(admin)/Topology(admin)/Device(wrong-device) in Endpoint(#0) of '\ - 'Context(admin)/Topology(admin)/Link(DEV1/EP2 ==> DEV2/EP1) does not exist in the database.' - assert e.value.details() == msg - - # should fail with endpoint uuid is empty - with pytest.raises(grpc._channel._InactiveRpcError) as e: - copy_link = copy.deepcopy(LINK) - copy_link['endpointList'][0]['port_id']['uuid'] = '' - context_client.AddLink(Link(**copy_link)) - assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT - msg = 'endpoint_id[#0].port_id.uuid() is out of range: '\ - 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).' - assert e.value.details() == msg - - # should fail with wrong endpoint port - with pytest.raises(grpc._channel._InactiveRpcError) as e: - copy_link = copy.deepcopy(LINK) - copy_link['endpointList'][0]['port_id']['uuid'] = 'wrong-port' - context_client.AddLink(Link(**copy_link)) - assert e.value.code() == grpc.StatusCode.NOT_FOUND - msg = 'Context(admin)/Topology(admin)/Device(DEV1)/Port(wrong-port) in Endpoint(#0) of '\ - 'Context(admin)/Topology(admin)/Link(DEV1/EP2 ==> DEV2/EP1) does not exist in the database.' - assert e.value.details() == msg - - # should fail with endpoint device duplicated - with pytest.raises(grpc._channel._InactiveRpcError) as e: - copy_link = copy.deepcopy(LINK) - copy_link['endpointList'][1]['dev_id']['device_id']['uuid'] = 'DEV1' - context_client.AddLink(Link(**copy_link)) - assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT - msg = 'Duplicated Context(admin)/Topology(admin)/Device(DEV1) in Endpoint(#1) of '\ - 'Context(admin)/Topology(admin)/Link(DEV1/EP2 ==> DEV2/EP1).' - assert e.value.details() == msg - -def test_add_link(context_client : ContextClient): - # should work - validate_link_id(MessageToDict( - context_client.AddLink(Link(**LINK)), - including_default_value_fields=True, preserving_proto_field_name=True, - use_integers_for_enums=False)) - -def test_delete_link_2(context_client : ContextClient): - # should work - validate_empty(MessageToDict( - context_client.DeleteLink(LinkId(**LINK_ID)), - including_default_value_fields=True, preserving_proto_field_name=True, - use_integers_for_enums=False)) - -def test_add_link_default_endpoint_context_topology(context_client : ContextClient): - # should work - copy_link = copy.deepcopy(LINK) - copy_link['endpointList'][0]['topoId']['contextId']['contextUuid']['uuid'] = '' - copy_link['endpointList'][0]['topoId']['topoId']['uuid'] = '' - validate_link_id(MessageToDict( - context_client.AddLink(Link(**copy_link)), - including_default_value_fields=True, preserving_proto_field_name=True, - use_integers_for_enums=False)) - -def test_get_topology_completed_2(context_client : ContextClient): - # should work - topology = MessageToDict( - context_client.GetTopology(Empty()), - including_default_value_fields=True, preserving_proto_field_name=True, - use_integers_for_enums=False) - validate_topology(topology) - validate_topology_has_devices(topology) - validate_topology_has_links(topology) - -def test_get_topology_completed_rest_api(context_service_rest : Server): - # should work - request_url = 'http://127.0.0.1:{}{}/context'.format(restapi_port, RESTAPI_BASE_URL) - LOGGER.warning('Request: GET {}'.format(str(request_url))) - reply = requests.get(request_url) - LOGGER.warning('Reply: {}'.format(str(reply.text))) - assert reply.status_code == 200, 'Reply failed with code {}'.format(reply.status_code) - json_reply = reply.json() - topology = MessageToDict( - Topology(**json_reply['topologies'][0]), - including_default_value_fields=True, preserving_proto_field_name=True, - use_integers_for_enums=False) - validate_topology(topology) - validate_topology_has_devices(topology) - validate_topology_has_links(topology) + response = context_client.ListContextIds(Empty()) + assert len(response.context_ids) == 0 + + response = context_client.ListContexts(Empty()) + assert len(response.contexts) == 0 + + response = context_client.GetContext(ContextId(**CONTEXT_ID)) + assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID + assert len(response.topology_ids) == 0 + assert len(response.service_ids) == 0 + + db_entries = context_database.dump() + LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries))) + for db_entry in db_entries: + LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) + LOGGER.info('-----------------------------------------------------------') + assert len(db_entries) == 0 + + response = context_client.SetContext(Context(**CONTEXT)) + assert response.context_uuid.uuid == DEFAULT_CONTEXT_UUID + + db_entries = context_database.dump() + LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries))) + for db_entry in db_entries: + LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) + LOGGER.info('-----------------------------------------------------------') + assert len(db_entries) == 2 + + response = context_client.ListContextIds(Empty()) + assert len(response.context_ids) == 1 + assert response.context_ids[0].context_uuid.uuid == DEFAULT_CONTEXT_UUID + + response = context_client.ListContexts(Empty()) + assert len(response.contexts) == 1 + assert response.contexts[0].context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID + assert len(response.contexts[0].topology_ids) == 0 + assert len(response.contexts[0].service_ids) == 0 + + context_client.RemoveContext(ContextId(**CONTEXT_ID)) + + db_entries = context_database.dump() + LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries))) + for db_entry in db_entries: + LOGGER.info(' [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) + LOGGER.info('-----------------------------------------------------------') + assert len(db_entries) == 0 + + +#def test_get_topology_empty(context_client : ContextClient, context_database : Database): +# # should work +# context_database.clear_all() +# validate_topology_is_empty(MessageToDict( +# context_client.GetTopology(Empty()), +# including_default_value_fields=True, preserving_proto_field_name=True, +# use_integers_for_enums=False)) +# +#def test_get_topology_completed(context_client : ContextClient, context_database : Database): +# # should work +# populate_example(context_database, add_services=False) +# topology = MessageToDict( +# context_client.GetTopology(Empty()), +# including_default_value_fields=True, preserving_proto_field_name=True, +# use_integers_for_enums=False) +# validate_topology(topology) +# validate_topology_has_devices(topology) +# validate_topology_has_links(topology) +# +#def test_delete_link_empty_uuid(context_client : ContextClient): +# # should fail with link not found +# with pytest.raises(grpc._channel._InactiveRpcError) as e: +# copy_link_id = copy.deepcopy(LINK_ID) +# copy_link_id['link_id']['uuid'] = '' +# context_client.DeleteLink(LinkId(**copy_link_id)) +# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT +# msg = 'link_id.link_id.uuid() is out of range: '\ +# 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).' +# assert e.value.details() == msg +# +#def test_add_link_already_exists(context_client : ContextClient): +# # should fail with link already exists +# with pytest.raises(grpc._channel._InactiveRpcError) as e: +# context_client.AddLink(Link(**LINK)) +# assert e.value.code() == grpc.StatusCode.ALREADY_EXISTS +# msg = 'Context(admin)/Topology(admin)/Link(DEV1/EP2 ==> DEV2/EP1) already exists in the database.' +# assert e.value.details() == msg +# +#def test_delete_link(context_client : ContextClient): +# # should work +# validate_empty(MessageToDict( +# context_client.DeleteLink(LinkId(**LINK_ID)), +# including_default_value_fields=True, preserving_proto_field_name=True, +# use_integers_for_enums=False)) +# +#def test_delete_link_not_existing(context_client : ContextClient): +# # should fail with link not found +# with pytest.raises(grpc._channel._InactiveRpcError) as e: +# context_client.DeleteLink(LinkId(**LINK_ID)) +# assert e.value.code() == grpc.StatusCode.NOT_FOUND +# msg = 'Context(admin)/Topology(admin)/Link(DEV1/EP2 ==> DEV2/EP1) does not exist in the database.' +# assert e.value.details() == msg +# +#def test_add_link_uuid_empty(context_client : ContextClient): +# # should fail with link uuid empty +# with pytest.raises(grpc._channel._InactiveRpcError) as e: +# copy_link = copy.deepcopy(LINK) +# copy_link['link_id']['link_id']['uuid'] = '' +# context_client.AddLink(Link(**copy_link)) +# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT +# msg = 'link.link_id.link_id.uuid() is out of range: '\ +# 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).' +# assert e.value.details() == msg +# +#def test_add_link_wrong_endpoint(context_client : ContextClient): +# # should fail with wrong endpoint context +# with pytest.raises(grpc._channel._InactiveRpcError) as e: +# copy_link = copy.deepcopy(LINK) +# copy_link['endpointList'][0]['topoId']['contextId']['contextUuid']['uuid'] = 'wrong-context' +# context_client.AddLink(Link(**copy_link)) +# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT +# msg = 'Context(wrong-context) in Endpoint(#0) of '\ +# 'Context(admin)/Topology(admin)/Link(DEV1/EP2 ==> DEV2/EP1) mismatches acceptable Contexts({\'admin\'}). '\ +# 'Optionally, leave field empty to use predefined Context(admin).' +# assert e.value.details() == msg +# +# # should fail with wrong endpoint topology +# with pytest.raises(grpc._channel._InactiveRpcError) as e: +# copy_link = copy.deepcopy(LINK) +# copy_link['endpointList'][0]['topoId']['topoId']['uuid'] = 'wrong-topo' +# context_client.AddLink(Link(**copy_link)) +# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT +# msg = 'Context(admin)/Topology(wrong-topo) in Endpoint(#0) of '\ +# 'Context(admin)/Topology(admin)/Link(DEV1/EP2 ==> DEV2/EP1) mismatches acceptable Topologies({\'admin\'}). '\ +# 'Optionally, leave field empty to use predefined Topology(admin).' +# assert e.value.details() == msg +# +# # should fail with device uuid is empty +# with pytest.raises(grpc._channel._InactiveRpcError) as e: +# copy_link = copy.deepcopy(LINK) +# copy_link['endpointList'][0]['dev_id']['device_id']['uuid'] = '' +# context_client.AddLink(Link(**copy_link)) +# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT +# msg = 'endpoint_id[#0].dev_id.device_id.uuid() is out of range: '\ +# 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).' +# assert e.value.details() == msg +# +# # should fail with wrong endpoint device +# with pytest.raises(grpc._channel._InactiveRpcError) as e: +# copy_link = copy.deepcopy(LINK) +# copy_link['endpointList'][0]['dev_id']['device_id']['uuid'] = 'wrong-device' +# context_client.AddLink(Link(**copy_link)) +# assert e.value.code() == grpc.StatusCode.NOT_FOUND +# msg = 'Context(admin)/Topology(admin)/Device(wrong-device) in Endpoint(#0) of '\ +# 'Context(admin)/Topology(admin)/Link(DEV1/EP2 ==> DEV2/EP1) does not exist in the database.' +# assert e.value.details() == msg +# +# # should fail with endpoint uuid is empty +# with pytest.raises(grpc._channel._InactiveRpcError) as e: +# copy_link = copy.deepcopy(LINK) +# copy_link['endpointList'][0]['port_id']['uuid'] = '' +# context_client.AddLink(Link(**copy_link)) +# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT +# msg = 'endpoint_id[#0].port_id.uuid() is out of range: '\ +# 'allow_empty(False) min_length(None) max_length(None) allowed_lengths(None).' +# assert e.value.details() == msg +# +# # should fail with wrong endpoint port +# with pytest.raises(grpc._channel._InactiveRpcError) as e: +# copy_link = copy.deepcopy(LINK) +# copy_link['endpointList'][0]['port_id']['uuid'] = 'wrong-port' +# context_client.AddLink(Link(**copy_link)) +# assert e.value.code() == grpc.StatusCode.NOT_FOUND +# msg = 'Context(admin)/Topology(admin)/Device(DEV1)/Port(wrong-port) in Endpoint(#0) of '\ +# 'Context(admin)/Topology(admin)/Link(DEV1/EP2 ==> DEV2/EP1) does not exist in the database.' +# assert e.value.details() == msg +# +# # should fail with endpoint device duplicated +# with pytest.raises(grpc._channel._InactiveRpcError) as e: +# copy_link = copy.deepcopy(LINK) +# copy_link['endpointList'][1]['dev_id']['device_id']['uuid'] = 'DEV1' +# context_client.AddLink(Link(**copy_link)) +# assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT +# msg = 'Duplicated Context(admin)/Topology(admin)/Device(DEV1) in Endpoint(#1) of '\ +# 'Context(admin)/Topology(admin)/Link(DEV1/EP2 ==> DEV2/EP1).' +# assert e.value.details() == msg +# +#def test_add_link(context_client : ContextClient): +# # should work +# validate_link_id(MessageToDict( +# context_client.AddLink(Link(**LINK)), +# including_default_value_fields=True, preserving_proto_field_name=True, +# use_integers_for_enums=False)) +# +#def test_delete_link_2(context_client : ContextClient): +# # should work +# validate_empty(MessageToDict( +# context_client.DeleteLink(LinkId(**LINK_ID)), +# including_default_value_fields=True, preserving_proto_field_name=True, +# use_integers_for_enums=False)) +# +#def test_add_link_default_endpoint_context_topology(context_client : ContextClient): +# # should work +# copy_link = copy.deepcopy(LINK) +# copy_link['endpointList'][0]['topoId']['contextId']['contextUuid']['uuid'] = '' +# copy_link['endpointList'][0]['topoId']['topoId']['uuid'] = '' +# validate_link_id(MessageToDict( +# context_client.AddLink(Link(**copy_link)), +# including_default_value_fields=True, preserving_proto_field_name=True, +# use_integers_for_enums=False)) +# +#def test_get_topology_completed_2(context_client : ContextClient): +# # should work +# topology = MessageToDict( +# context_client.GetTopology(Empty()), +# including_default_value_fields=True, preserving_proto_field_name=True, +# use_integers_for_enums=False) +# validate_topology(topology) +# validate_topology_has_devices(topology) +# validate_topology_has_links(topology) +# +#def test_get_topology_completed_rest_api(context_service_rest : Server): +# # should work +# request_url = 'http://127.0.0.1:{}{}/context'.format(restapi_port, RESTAPI_BASE_URL) +# LOGGER.warning('Request: GET {}'.format(str(request_url))) +# reply = requests.get(request_url) +# LOGGER.warning('Reply: {}'.format(str(reply.text))) +# assert reply.status_code == 200, 'Reply failed with code {}'.format(reply.status_code) +# json_reply = reply.json() +# topology = MessageToDict( +# Topology(**json_reply['topologies'][0]), +# including_default_value_fields=True, preserving_proto_field_name=True, +# use_integers_for_enums=False) +# validate_topology(topology) +# validate_topology_has_devices(topology) +# validate_topology_has_links(topology) +# \ No newline at end of file