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