diff --git a/proto/context.proto b/proto/context.proto
index b4ebbb8ba02ce5ee1fc8521518e61a5566cf637c..ab8db45e14ffb127e7bc76167a8879bdfd38e632 100644
--- a/proto/context.proto
+++ b/proto/context.proto
@@ -2,35 +2,40 @@ syntax = "proto3";
 package context;
 
 service ContextService {
-  rpc GetContextIds (Empty     ) returns (ContextIdList ) {}
-  rpc GetContexts   (Empty     ) returns (ContextList   ) {}
-  rpc GetContext    (ContextId ) returns (Context       ) {}
-  rpc SetContext    (Context   ) returns (ContextId     ) {}
-  rpc DeleteContext (ContextId ) returns (Empty         ) {}
-
-  rpc GetTopologyIds(ContextId ) returns (TopologyIdList) {}
-  rpc GetTopologies (ContextId ) returns (TopologyList  ) {}
-  rpc GetTopology   (TopologyId) returns (Topology      ) {}
-  rpc SetTopology   (Topology  ) returns (TopologyId    ) {}
-  rpc DeleteTopology(TopologyId) returns (Empty         ) {}
-
-  rpc GetDeviceIds  (Empty     ) returns (DeviceIdList  ) {}
-  rpc GetDevices    (Empty     ) returns (DeviceList    ) {}
-  rpc GetDevice     (DeviceId  ) returns (Device        ) {}
-  rpc SetDevice     (Device    ) returns (DeviceId      ) {}
-  rpc RemoveDevice  (DeviceId  ) returns (Empty         ) {}
-
-  rpc GetLinkIds    (Empty     ) returns (LinkIdList    ) {}
-  rpc GetLinks      (Empty     ) returns (LinkList      ) {}
-  rpc GetLink       (LinkId    ) returns (Link          ) {}
-  rpc SetLink       (Link      ) returns (LinkId        ) {}
-  rpc DeleteLink    (LinkId    ) returns (Empty         ) {}
-
-  rpc GetServiceIds (ContextId ) returns (ServiceIdList ) {}
-  rpc GetServices   (ContextId ) returns (ServiceList   ) {}
-  rpc GetService    (ServiceId ) returns (Service       ) {}
-  rpc SetService    (Service   ) returns (ServiceId     ) {}
-  rpc DeleteService (ServiceId ) returns (Empty         ) {}
+  rpc ListContextIds   (Empty     ) returns (       ContextIdList ) {}
+  rpc ListContexts     (Empty     ) returns (       ContextList   ) {}
+  rpc GetContext       (ContextId ) returns (       Context       ) {}
+  rpc SetContext       (Context   ) returns (       ContextId     ) {}
+  rpc RemoveContext    (ContextId ) returns (       Empty         ) {}
+  rpc GetContextEvents (Empty     ) returns (stream ContextEvent  ) {}
+
+  rpc ListTopologyIds  (ContextId ) returns (       TopologyIdList) {}
+  rpc ListTopologies   (ContextId ) returns (       TopologyList  ) {}
+  rpc GetTopology      (TopologyId) returns (       Topology      ) {}
+  rpc SetTopology      (Topology  ) returns (       TopologyId    ) {}
+  rpc RemoveTopology   (TopologyId) returns (       Empty         ) {}
+  rpc GetTopologyEvents(Empty     ) returns (stream TopologyEvent ) {}
+
+  rpc ListDeviceIds    (Empty     ) returns (       DeviceIdList  ) {}
+  rpc ListDevices      (Empty     ) returns (       DeviceList    ) {}
+  rpc GetDevice        (DeviceId  ) returns (       Device        ) {}
+  rpc SetDevice        (Device    ) returns (       DeviceId      ) {}
+  rpc RemoveDevice     (DeviceId  ) returns (       Empty         ) {}
+  rpc GetDeviceEvents  (Empty     ) returns (stream DeviceEvent   ) {}
+
+  rpc ListLinkIds      (Empty     ) returns (       LinkIdList    ) {}
+  rpc ListLinks        (Empty     ) returns (       LinkList      ) {}
+  rpc GetLink          (LinkId    ) returns (       Link          ) {}
+  rpc SetLink          (Link      ) returns (       LinkId        ) {}
+  rpc RemoveLink       (LinkId    ) returns (       Empty         ) {}
+  rpc GetLinkEvents    (Empty     ) returns (stream LinkEvent     ) {}
+
+  rpc ListServiceIds   (ContextId ) returns (       ServiceIdList ) {}
+  rpc ListServices     (ContextId ) returns (       ServiceList   ) {}
+  rpc GetService       (ServiceId ) returns (       Service       ) {}
+  rpc SetService       (Service   ) returns (       ServiceId     ) {}
+  rpc RemoveService    (ServiceId ) returns (       Empty         ) {}
+  rpc GetServiceEvents (Empty     ) returns (stream ServiceEvent  ) {}
 }
 
 // ----- Generic -------------------------------------------------------------------------------------------------------
@@ -40,6 +45,17 @@ message Uuid {
   string uuid = 1;
 }
 
+enum EventTypeEnum {
+  EVENTTYPE_UNDEFINED = 0;
+  EVENTTYPE_CREATE = 1;
+  EVENTTYPE_UPDATE = 2;
+  EVENTTYPE_REMOVE = 3;
+}
+
+message Event {
+  double timestamp = 1;
+  EventTypeEnum event_type = 2;
+}
 
 // ----- Context -------------------------------------------------------------------------------------------------------
 message ContextId {
@@ -60,6 +76,11 @@ message ContextList {
   repeated Context contexts = 1;
 }
 
+message ContextEvent {
+  Event event = 1;
+  ContextId context_id = 2;
+}
+
 
 // ----- Topology ------------------------------------------------------------------------------------------------------
 message TopologyId {
@@ -69,8 +90,8 @@ message TopologyId {
 
 message Topology {
   TopologyId topology_id = 1;
-  repeated Device devices = 2;
-  repeated Link links = 3;
+  repeated DeviceId device_ids = 2;
+  repeated LinkId link_ids = 3;
 }
 
 message TopologyIdList {
@@ -81,6 +102,11 @@ message TopologyList {
   repeated Topology topologies = 1;
 }
 
+message TopologyEvent {
+  Event event = 1;
+  TopologyId topology_id = 2;
+}
+
 
 // ----- Device --------------------------------------------------------------------------------------------------------
 message DeviceId {
@@ -92,7 +118,7 @@ message Device {
   string device_type = 2;
   DeviceConfig device_config = 3;
   DeviceOperationalStatus devive_operational_status = 4;
-  repeated DeviceDriver device_drivers = 5;
+  repeated DeviceDriverEnum device_drivers = 5;
   repeated EndPoint endpoints = 6;
 }
 
@@ -100,19 +126,19 @@ message DeviceConfig {
   repeated ConfigRule config_rules = 1;
 }
 
-enum DeviceDriver {
-  DRIVER_UNDEFINED = 0; // also used for emulated
-  DRIVER_OPENCONFIG = 1;
-  DRIVER_TRANSPORT_API = 2;
-  DRIVER_P4 = 3;
-  DRIVER_IETF_NETWORK_TOPOLOGY = 4;
-  DRIVER_ONF_TR_352 = 5;
+enum DeviceDriverEnum {
+  DEVICEDRIVER_UNDEFINED = 0; // also used for emulated
+  DEVICEDRIVER_OPENCONFIG = 1;
+  DEVICEDRIVER_TRANSPORT_API = 2;
+  DEVICEDRIVER_P4 = 3;
+  DEVICEDRIVER_IETF_NETWORK_TOPOLOGY = 4;
+  DEVICEDRIVER_ONF_TR_352 = 5;
 }
 
 enum DeviceOperationalStatus {
-  KEEP_STATUS = 0; // Do not change operational status of device (used in configure)
-  DISABLED = -1;
-  ENABLED = 1;
+  UNDEFINED = 0;
+  DISABLED = 1;
+  ENABLED = 2;
 }
 
 message DeviceIdList {
@@ -123,6 +149,11 @@ message DeviceList {
   repeated Device devices = 1;
 }
 
+message DeviceEvent {
+  Event event = 1;
+  DeviceId device_id = 2;
+}
+
 
 // ----- Link ----------------------------------------------------------------------------------------------------------
 message LinkId {
@@ -131,7 +162,7 @@ message LinkId {
 
 message Link {
   LinkId link_id = 1;
-  repeated EndPointId endpoints = 2;
+  repeated EndPointId endpoint_ids = 2;
 }
 
 message LinkIdList {
@@ -142,6 +173,11 @@ message LinkList {
   repeated Link links = 1;
 }
 
+message LinkEvent {
+  Event event = 1;
+  LinkId link_id = 2;
+}
+
 
 // ----- Service -------------------------------------------------------------------------------------------------------
 message ServiceId {
@@ -151,14 +187,14 @@ message ServiceId {
 
 message Service {
   ServiceId service_id = 1;
-  ServiceType service_type = 2;
-  repeated EndPointId endpoints = 3;
+  ServiceTypeEnum service_type = 2;
+  repeated EndPointId endpoint_ids = 3;
   repeated Constraint constraints = 4;
   ServiceState service_state = 5;
   ServiceConfig service_config = 6;
 }
 
-enum ServiceType {
+enum ServiceTypeEnum {
   SERVICETYPE_UNKNOWN = 0;
   SERVICETYPE_L3NM = 1;
   SERVICETYPE_L2NM = 2;
@@ -187,6 +223,11 @@ message ServiceList {
   repeated Service services = 1;
 }
 
+message ServiceEvent {
+  Event event = 1;
+  ServiceId service_id = 2;
+}
+
 
 // ----- Endpoint ------------------------------------------------------------------------------------------------------
 message EndPointId {
@@ -202,14 +243,14 @@ message EndPoint {
 
 
 // ----- Configuration -------------------------------------------------------------------------------------------------
-enum ConfigAction {
+enum ConfigActionEnum {
   CONFIGACTION_UNDEFINED = 0;
   CONFIGACTION_SET = 1;
   CONFIGACTION_DELETE = 2;
 }
 
 message ConfigRule {
-  ConfigAction action = 1;
+  ConfigActionEnum action = 1;
   string resource_key = 2;
   string resource_value = 3;
 }
diff --git a/src/common/Checkers.py b/src/common/Checkers.py
deleted file mode 100644
index b9e0f3067357912ef8e7404768b234f3c58d40e5..0000000000000000000000000000000000000000
--- a/src/common/Checkers.py
+++ /dev/null
@@ -1,100 +0,0 @@
-from typing import Any, List, Set, Sized, Tuple, Union
-
-def chk_none(name : str, value : Any) -> Any:
-    if value is not None:
-        msg = '{}({}) is not None.'
-        raise AttributeError(msg.format(str(name), str(value)))
-    return value
-
-def chk_not_none(name : str, value : Any) -> Any:
-    if value is None:
-        msg = '{}({}) is None.'
-        raise AttributeError(msg.format(str(name), str(value)))
-    return value
-
-def chk_type(name : str, value : Any, type_or_types : Union[type, Set[type]] = set()) -> Any:
-    if not isinstance(value, type_or_types):
-        msg = '{}({}) is of a wrong type({}). Accepted type_or_types({}).'
-        raise AttributeError(msg.format(str(name), str(value), type(value).__name__, str(type_or_types)))
-    return value
-
-def chk_length(
-    name : str, value : Sized, allow_empty : bool = False,
-    min_length : Union[int, None] = None, max_length : Union[int, None] = None,
-    allowed_lengths : Union[None, int, Set[int], List[int], Tuple[int]] = None) -> Any:
-
-    length = len(chk_type(name, value, Sized))
-
-    allow_empty = chk_type('allow_empty for {}'.format(name), allow_empty, bool)
-    if not allow_empty and length == 0:
-        msg = '{}({}) is out of range: allow_empty({}) min_length({}) max_length({}) allowed_lengths({}).'
-        raise AttributeError(msg.format(
-            str(name), str(value), str(allow_empty), str(min_length), str(max_length), str(allowed_lengths)))
-
-
-    if min_length is not None:
-        min_length = chk_type('min_length for {}'.format(name), min_length, int)
-        if length < min_length:
-            msg = '{}({}) is out of range: allow_empty({}) min_length({}) max_length({}) allowed_lengths({}).'
-            raise AttributeError(msg.format(
-                str(name), str(value), str(allow_empty), str(min_length), str(max_length), str(allowed_lengths)))
-
-    if max_length is not None:
-        max_length = chk_type('max_length for {}'.format(name), max_length, int)
-        if length > max_length:
-            msg = '{}({}) is out of range: allow_empty({}) min_value({}) max_value({}) allowed_lengths({}).'
-            raise AttributeError(msg.format(
-                str(name), str(value), str(allow_empty), str(max_length), str(max_length), str(allowed_lengths)))
-
-    if allowed_lengths is not None:
-        chk_type('allowed_lengths for {}'.format(name), allowed_lengths, (int, set, list, tuple))
-        if isinstance(allowed_lengths, int):
-            fixed_length = allowed_lengths
-            if length != fixed_length:
-                msg = '{}({}) is out of range: allow_empty({}) min_value({}) max_value({}) allowed_lengths({}).'
-                raise AttributeError(msg.format(
-                    str(name), str(value), str(allow_empty), str(max_length), str(max_length), str(allowed_lengths)))
-        else:
-            for i in allowed_lengths: chk_type('allowed_lengths[#{}] for {}'.format(i, name), i, int)
-            if length not in allowed_lengths:
-                msg = '{}({}) is out of range: allow_empty({}) min_value({}) max_value({}) allowed_lengths({}).'
-                raise AttributeError(msg.format(
-                    str(name), str(value), str(allow_empty), str(max_length), str(max_length), str(allowed_lengths)))
-
-    return value
-
-def chk_string(
-    name : str, value : Any, allow_empty : bool = False,
-    min_length : Union[int, None] = None, max_length : Union[int, None] = None,
-    allowed_lengths : Union[None, int, Set[int], List[int], Tuple[int]] = None) -> str:
-
-    chk_type(name, value, str)
-    chk_length(
-        name, value, allow_empty=allow_empty, min_length=min_length, max_length=max_length,
-        allowed_lengths=allowed_lengths)
-    return value
-
-def chk_float(name, value, type_or_types=(int, float), min_value=None, max_value=None) -> float:
-    chk_not_none(name, value)
-    chk_type(name, value, type_or_types)
-    if min_value is not None:
-        chk_type(name, value, type_or_types)
-        if value < min_value:
-            msg = '{}({}) lower than min_value({}).'
-            raise AttributeError(msg.format(str(name), str(value), str(min_value)))
-    if max_value is not None:
-        chk_type(name, value, type_or_types)
-        if value > max_value:
-            msg = '{}({}) greater than max_value({}).'
-            raise AttributeError(msg.format(str(name), str(value), str(max_value)))
-    return value
-
-def chk_integer(name, value, min_value=None, max_value=None) -> int:
-    return int(chk_float(name, value, type_or_types=int, min_value=min_value, max_value=max_value))
-
-def chk_options(name, value, options):
-    chk_not_none(name, value)
-    if value not in options:
-        msg = '{}({}) is not one of options({}).'
-        raise AttributeError(msg.format(str(name), str(value), str(options)))
-    return value
diff --git a/src/context/service/database/_engine/Exceptions.py b/src/common/orm/Exceptions.py
similarity index 100%
rename from src/context/service/database/_engine/Exceptions.py
rename to src/common/orm/Exceptions.py
diff --git a/src/context/service/database/_engine/Factory.py b/src/common/orm/Factory.py
similarity index 100%
rename from src/context/service/database/_engine/Factory.py
rename to src/common/orm/Factory.py
diff --git a/src/context/service/database/_engine/_Database.py b/src/common/orm/_Database.py
similarity index 84%
rename from src/context/service/database/_engine/_Database.py
rename to src/common/orm/_Database.py
index 357a06dff18d8ca2267669dbe413439675ceaf10..95d483361ec230294027320e9dd26cf1171a3f4e 100644
--- a/src/context/service/database/_engine/_Database.py
+++ b/src/common/orm/_Database.py
@@ -1,18 +1,19 @@
 import logging
 from typing import List, Set
 from .backend._Backend import _Backend
-from .object._Object import _Object
+from .fields.PrimaryKeyField import PrimaryKeyField
+from .model.Model import Model
 from .Exceptions import MutexException
 
 LOGGER = logging.getLogger(__name__)
 
-class _Database(_Object):
+class _Database(Model):
     def __init__(self, backend : _Backend):
-        if not issubclass(backend, _Backend):
+        if not isinstance(backend, _Backend):
             str_class_path = '{}.{}'.format(_Backend.__module__, _Backend.__name__)
             raise AttributeError('backend must inherit from {}'.format(str_class_path))
         self._backend = backend
-        super().__init__(self, 'root')
+        super().__init__(self)
         self._acquired = False
         self._owner_key = None
 
@@ -22,6 +23,9 @@ class _Database(_Object):
     @property
     def backend(self) -> _Backend: return self._backend
 
+    @property
+    def backend_key(self) -> str: return ''
+
     def __enter__(self) -> '_Database':
         self._acquired, self._owner_key = self._backend.lock()
         if not self._acquired: raise MutexException('Unable to acquire database lock')
diff --git a/src/common/tests/__init__.py b/src/common/orm/__init__.py
similarity index 100%
rename from src/common/tests/__init__.py
rename to src/common/orm/__init__.py
diff --git a/src/context/service/database/_engine/backend/BackendEnum.py b/src/common/orm/backend/BackendEnum.py
similarity index 100%
rename from src/context/service/database/_engine/backend/BackendEnum.py
rename to src/common/orm/backend/BackendEnum.py
diff --git a/src/context/service/database/_engine/backend/_Backend.py b/src/common/orm/backend/_Backend.py
similarity index 100%
rename from src/context/service/database/_engine/backend/_Backend.py
rename to src/common/orm/backend/_Backend.py
diff --git a/src/context/service/database/_engine/__init__.py b/src/common/orm/backend/__init__.py
similarity index 100%
rename from src/context/service/database/_engine/__init__.py
rename to src/common/orm/backend/__init__.py
diff --git a/src/context/service/database/_engine/backend/inmemory/InMemoryBackend.py b/src/common/orm/backend/inmemory/InMemoryBackend.py
similarity index 100%
rename from src/context/service/database/_engine/backend/inmemory/InMemoryBackend.py
rename to src/common/orm/backend/inmemory/InMemoryBackend.py
diff --git a/src/context/service/database/_engine/backend/inmemory/Tools.py b/src/common/orm/backend/inmemory/Tools.py
similarity index 100%
rename from src/context/service/database/_engine/backend/inmemory/Tools.py
rename to src/common/orm/backend/inmemory/Tools.py
diff --git a/src/context/service/database/_engine/backend/__init__.py b/src/common/orm/backend/inmemory/__init__.py
similarity index 100%
rename from src/context/service/database/_engine/backend/__init__.py
rename to src/common/orm/backend/inmemory/__init__.py
diff --git a/src/context/service/database/_engine/backend/redis/Mutex.py b/src/common/orm/backend/redis/Mutex.py
similarity index 100%
rename from src/context/service/database/_engine/backend/redis/Mutex.py
rename to src/common/orm/backend/redis/Mutex.py
diff --git a/src/context/service/database/_engine/backend/redis/RedisBackend.py b/src/common/orm/backend/redis/RedisBackend.py
similarity index 100%
rename from src/context/service/database/_engine/backend/redis/RedisBackend.py
rename to src/common/orm/backend/redis/RedisBackend.py
diff --git a/src/context/service/database/_engine/backend/inmemory/__init__.py b/src/common/orm/backend/redis/__init__.py
similarity index 100%
rename from src/context/service/database/_engine/backend/inmemory/__init__.py
rename to src/common/orm/backend/redis/__init__.py
diff --git a/src/common/orm/fields/BooleanField.py b/src/common/orm/fields/BooleanField.py
new file mode 100644
index 0000000000000000000000000000000000000000..2eadaf5f3034cb11d2791b045cfb4fe7a1d9faab
--- /dev/null
+++ b/src/common/orm/fields/BooleanField.py
@@ -0,0 +1,12 @@
+from typing import Any
+from common.type_checkers.Checkers import chk_boolean, chk_not_none
+from .Field import Field
+
+class BooleanField(Field):
+    def __init__(self, *args, **kwargs) -> None:
+        super().__init__(*args, type_=bool, **kwargs)
+
+    def __set__(self, instance, value : bool) -> None:
+        if self.required: chk_not_none(self.name, value)
+        if value is None: super().__set__(instance, value)
+        super().__set__(instance, chk_boolean(self.name, value))
diff --git a/src/common/orm/fields/Field.py b/src/common/orm/fields/Field.py
new file mode 100644
index 0000000000000000000000000000000000000000..e10938c306dfd4f3934cacaf32654519e9c289e1
--- /dev/null
+++ b/src/common/orm/fields/Field.py
@@ -0,0 +1,16 @@
+from typing import Any, List, Set, Tuple, Union
+from common.type_checkers.Checkers import chk_boolean, chk_string, chk_type
+
+class Field:
+    def __init__(
+        self, name : str = None, type_ : Union[type, Set[type], Tuple[type], List[type]] = object,
+        required : bool = False) -> None:
+        self.name = None if name is None else chk_string('Field.name', name)
+        self.type_ = chk_type('Field.type', type_, (type, set, tuple, list))
+        self.required = chk_boolean('Field.required', required)
+
+    def __set__(self, instance, value : Any):
+        instance.__dict__[self.name] = value
+
+    def __delete__(self, instance):
+        raise AttributeError('Attribute "{:s}" cannot be deleted'.format(self.name))
diff --git a/src/common/orm/fields/FloatField.py b/src/common/orm/fields/FloatField.py
new file mode 100644
index 0000000000000000000000000000000000000000..f53cd25136ddb5326c7092a617110ca3007b7012
--- /dev/null
+++ b/src/common/orm/fields/FloatField.py
@@ -0,0 +1,18 @@
+from typing import Optional
+from common.type_checkers.Checkers import chk_float, chk_not_none
+from .Field import Field
+
+class FloatField(Field):
+    def __init__(
+        self, *args, min_value : Optional[float] = None, max_value : Optional[float] = None, **kwargs) -> None:
+
+        super().__init__(*args, type_=(float, int), **kwargs)
+        self._min_value = None if min_value is None else \
+            chk_float('{}.min_value'.format(self.name), min_value)
+        self._max_value = None if max_value is None else \
+            chk_float('{}.max_value'.format(self.name), max_value, min_value=self._min_value)
+
+    def __set__(self, instance, value : float) -> None:
+        if self.required: chk_not_none(self.name, value)
+        if value is None: super().__set__(instance, value)
+        super().__set__(instance, chk_float(self.name, value, min_value=self._min_value, max_value=self._max_value))
diff --git a/src/common/orm/fields/ForeignKeyField.py b/src/common/orm/fields/ForeignKeyField.py
new file mode 100644
index 0000000000000000000000000000000000000000..f6e7fd394a6a0bd548238d017ba95b8fbed05eda
--- /dev/null
+++ b/src/common/orm/fields/ForeignKeyField.py
@@ -0,0 +1,16 @@
+from typing import Optional
+from .Field import Field
+
+class ForeignKeyField(Field):
+    def __init__(self, *args, foreign_model : 'Model' = None, **kwargs) -> None:
+        self.foreign_model = foreign_model
+        super().__init__(*args, type_=(float, int), **kwargs)
+
+    def __set__(self, instance, value):
+        if self.min_value is not None and value < self.min_value:
+            raise ValueError('Attribute "{:s}" expects value >= {:s}; requested({:s})'.format(
+                str(self.name), str(self.min_value), str(value)))
+        if self.max_value is not None and value > self.max_value:
+            raise ValueError('Attribute "{:s}" expects value <= {:s}; requested({:s})'.format(
+                str(self.name), str(self.max_value), str(value)))
+        super().__set__(instance, value)
diff --git a/src/common/orm/fields/IntegerField.py b/src/common/orm/fields/IntegerField.py
new file mode 100644
index 0000000000000000000000000000000000000000..5622af9755a824689fa3b002d2a65dd84bb3d9e4
--- /dev/null
+++ b/src/common/orm/fields/IntegerField.py
@@ -0,0 +1,18 @@
+from typing import Optional
+from common.type_checkers.Checkers import chk_integer, chk_not_none
+from .Field import Field
+
+class IntegerField(Field):
+    def __init__(
+        self, *args, min_value : Optional[int] = None, max_value : Optional[int] = None, **kwargs) -> None:
+
+        super().__init__(*args, type_=int, **kwargs)
+        self._min_value = None if min_value is None else \
+            chk_integer('{}.min_value'.format(self.name), min_value)
+        self._max_value = None if max_value is None else \
+            chk_integer('{}.max_value'.format(self.name), max_value, min_value=self._min_value)
+
+    def __set__(self, instance, value : int) -> None:
+        if self.required: chk_not_none(self.name, value)
+        if value is None: super().__set__(instance, value)
+        super().__set__(instance, chk_integer(self.name, value, min_value=self._min_value, max_value=self._max_value))
diff --git a/src/common/orm/fields/PrimaryKeyField.py b/src/common/orm/fields/PrimaryKeyField.py
new file mode 100644
index 0000000000000000000000000000000000000000..9f0cdc50151f595afd6ad30f6611077f028e3ac0
--- /dev/null
+++ b/src/common/orm/fields/PrimaryKeyField.py
@@ -0,0 +1,13 @@
+from typing import Any
+from common.type_checkers.Checkers import chk_not_none
+from .StringField import StringField
+
+class PrimaryKeyField(StringField):
+    def __init__(self, *args, required : bool = True, **kwargs) -> None:
+        super().__init__(*args, required=True, allow_empty=False, min_length=1, **kwargs)
+
+    def __set__(self, instance, value : str):
+        chk_not_none(self.name, value) # Always required
+        if (self.name in instance.__dict__) and (instance.__dict__[self.name] is not None):
+            raise ValueError('PrimaryKeyField cannot be modified')
+        return super().__set__(instance, value)
diff --git a/src/common/orm/fields/StringField.py b/src/common/orm/fields/StringField.py
new file mode 100644
index 0000000000000000000000000000000000000000..ca5a5a9ccfcf258de1c9f7ce1d10e25dcddaee48
--- /dev/null
+++ b/src/common/orm/fields/StringField.py
@@ -0,0 +1,24 @@
+import re
+from typing import Optional, Pattern, Union
+from common.type_checkers.Checkers import chk_boolean, chk_integer, chk_not_none, chk_string
+from .Field import Field
+
+class StringField(Field):
+    def __init__(
+        self, *args, allow_empty : bool = False, min_length : Optional[int] = None, max_length : Optional[int] = None,
+        pattern : Optional[Union[Pattern, str]] = None, **kwargs) -> None:
+
+        super().__init__(*args, type_=str, **kwargs)
+        self._allow_empty = chk_boolean('{}.allow_empty'.format(self.name), allow_empty)
+        self._min_length = None if min_length is None else \
+            chk_integer('{}.min_length'.format(self.name), min_length, min_value=0)
+        self._max_length = None if max_length is None else \
+            chk_integer('{}.max_length'.format(self.name), max_length, min_value=self._min_length)
+        self._pattern = None if pattern is None else re.compile(pattern)
+
+    def __set__(self, instance, value : str) -> None:
+        if self.required: chk_not_none(self.name, value)
+        if value is None: super().__set__(instance, value)
+        super().__set__(instance, chk_string(
+            self.name, value, allow_empty=self._allow_empty, min_length=self._min_length, max_length=self._max_length,
+            pattern=self._pattern))
diff --git a/src/common/orm/fields/__init__.py b/src/common/orm/fields/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..b145d2b87ef70d0f2c8770a8fe07b115ca5d75c6
--- /dev/null
+++ b/src/common/orm/fields/__init__.py
@@ -0,0 +1,5 @@
+from .Field import Field
+from .FloatField import FloatField
+from .IntegerField import IntegerField
+from .StringField import StringField
+__all__ = ['Field', 'FloatField', 'IntegerField', 'StringField']
diff --git a/src/context/service/database/_engine/object/Collection.py b/src/common/orm/model/Collection.py
similarity index 92%
rename from src/context/service/database/_engine/object/Collection.py
rename to src/common/orm/model/Collection.py
index 7f8e22382ec8de3841916d7a2130fe5c51233766..30bc1b6942fd37141cc528fca10551e2e37d528f 100644
--- a/src/context/service/database/_engine/object/Collection.py
+++ b/src/common/orm/model/Collection.py
@@ -28,6 +28,10 @@ class Collection:
     def contains(self, object_uuid : str) -> bool:
         return self._backend.set_has(self._key_set, object_uuid)
 
+    def clear(self) -> None:
+        self._backend.delete(self._key_set)
+        self._backend.delete(self._key_list)
+
     def delete(self, object_uuid : str) -> None:
         if not self._backend.set_has(self._key_set, object_uuid): return
         self._backend.set_remove(self._key_set, object_uuid)
diff --git a/src/common/orm/model/Model.py b/src/common/orm/model/Model.py
new file mode 100644
index 0000000000000000000000000000000000000000..0124d163c66b6cac563fd13c6fb95eefe30ff7b1
--- /dev/null
+++ b/src/common/orm/model/Model.py
@@ -0,0 +1,93 @@
+from __future__ import annotations
+from typing import Any, Dict, Mapping, Tuple
+from common.orm.fields.PrimaryKeyField import PrimaryKeyField
+from common.type_checkers.Checkers import chk_none
+from ..backend._Backend import _Backend
+from ..fields.Field import Field
+from .Tools import NoDupOrderedDict
+
+class MetaModel(type):
+    @classmethod
+    def __prepare__(metacls, name : str, bases : Tuple[type, ...], **attrs : Any) -> Mapping[str, Any]:
+        return NoDupOrderedDict()
+
+    def __new__(metacls, name : str, bases : Tuple[type, ...], attrs : NoDupOrderedDict[str, Any]):
+        field_names = list()
+        primary_key_field = None
+        for key, value in attrs.items():
+            if not isinstance(value, Field): continue
+            attrs[key].name = key
+            field_names.append(key)
+            if isinstance(value, PrimaryKeyField):
+                if primary_key_field is None:
+                    primary_key_field = value
+                    continue
+                raise AttributeError('PrimaryKey for Model({:s}) already set to attribute({:s})'.format(
+                    str(name), str(primary_key_field.name)))
+        cls_obj = super().__new__(metacls, name, bases, dict(attrs))
+        setattr(cls_obj, '_primary_key_field', primary_key_field)
+        setattr(cls_obj, '_field_names_list', field_names)
+        setattr(cls_obj, '_field_names_set', set(field_names))
+        return cls_obj
+
+class Model(metaclass=MetaModel):
+    def __init__(self, parent : 'Model', primary_key : Any = None) -> None:
+        if not isinstance(parent, Model):
+            str_class_path = '{}.{}'.format(Model.__module__, Model.__name__)
+            raise AttributeError('parent must inherit from {}'.format(str_class_path))
+        self._parent = parent
+        self._backend = self._parent.backend
+        self._class_name = type(self).__name__
+        self._backend_key = '{:s}/{:s}'.format(self.parent.backend_key, self._class_name)
+        if self._primary_key_field is not None: # pylint: disable=no-member
+            primary_key_field_name = self._primary_key_field.name # pylint: disable=no-member
+            print('primary_key_field_name', primary_key_field_name)
+            setattr(self, primary_key_field_name, primary_key) 
+            self._backend_key += '[{:s}]'.format(getattr(self, primary_key_field_name))
+        else:
+            try:
+                chk_none('primary_key', primary_key)
+            except:
+                msg = 'Unable to set primary_key({:s}) since no PrimaryKeyField is defined in the model'
+                raise AttributeError(msg.format(str(primary_key)))
+
+    @property
+    def parent(self) -> 'Model': return self._parent
+
+    @property
+    def backend(self) -> _Backend: return self._parent.backend
+
+    @property
+    def backend_key(self) -> str: return self._backend_key
+
+    def load(self) -> None:
+        attributes = self._backend.dict_get(self._backend_key).items()
+        for name in self._field_names_list: # pylint: disable=no-member
+            if name not in attributes: continue
+            setattr(self, name, attributes[name])
+
+    def save(self) -> None:
+        attributes : Dict[str, Any] = {
+            name:repr(getattr(self, name))
+            for name in self._field_names_list # pylint: disable=no-member
+        }
+        self._backend.dict_update(self._backend_key, attributes)
+
+    def delete(self) -> None:
+        self._backend.dict_delete(self._backend_key)
+
+    def dump_id(self) -> Dict:
+        raise NotImplementedError()
+
+    def dump(self) -> Dict:
+        raise NotImplementedError()
+
+    def __repr__(self) -> str:
+        pk_field = self._primary_key_field # pylint: disable=no-member
+        pk_field_name = None if pk_field is None else pk_field.name # pylint: disable=no-member
+        arguments = ', '.join(
+            '{:s}={:s}{:s}'.format(
+                name, repr(getattr(self, name)), '(PK)' if name == pk_field_name else '')
+            for name in self._field_names_list # pylint: disable=no-member
+        )
+        return '{:s}({:s})'.format(self._class_name, arguments)
diff --git a/src/context/service/database/_engine/object/Tools.py b/src/common/orm/model/Tools.py
similarity index 65%
rename from src/context/service/database/_engine/object/Tools.py
rename to src/common/orm/model/Tools.py
index 6669d0f25d602f3028481dc7a07dc6242201eee4..3ebf63ae35a9e27d083a533ace3d1805197f166c 100644
--- a/src/context/service/database/_engine/object/Tools.py
+++ b/src/common/orm/model/Tools.py
@@ -1,3 +1,10 @@
+from collections import OrderedDict
+
+class NoDupOrderedDict(OrderedDict):
+    def __setitem__(self, key, value):
+        if key in self: raise NameError('{:s} already defined'.format(str(key)))
+        super().__setitem__(key, value)
+
 def format_key(key_pattern, instance, **kwargs):
     attributes = {}
     for attribute_name in instance.__dir__():
diff --git a/src/context/service/database/_engine/backend/redis/__init__.py b/src/common/orm/model/__init__.py
similarity index 100%
rename from src/context/service/database/_engine/backend/redis/__init__.py
rename to src/common/orm/model/__init__.py
diff --git a/src/context/service/database/_engine/object/__init__.py b/src/common/orm/tests/__init__.py
similarity index 100%
rename from src/context/service/database/_engine/object/__init__.py
rename to src/common/orm/tests/__init__.py
diff --git a/src/context/tests/populate_database.py b/src/common/orm/tests/orm_populate_data.py
similarity index 100%
rename from src/context/tests/populate_database.py
rename to src/common/orm/tests/orm_populate_data.py
diff --git a/src/common/orm/tests/test_orm_backend_inmemory.py b/src/common/orm/tests/test_orm_backend_inmemory.py
new file mode 100644
index 0000000000000000000000000000000000000000..b4bcf876e3c7097523dd94cf6b3cbf98ddd390e9
--- /dev/null
+++ b/src/common/orm/tests/test_orm_backend_inmemory.py
@@ -0,0 +1,10 @@
+import logging
+from context.service.database.Database import Database
+from context.service.database._engine.Factory import get_database_backend, BackendEnum
+from .populate_database import sequence
+
+logging.basicConfig(level=logging.INFO)
+
+def test_inmemory():
+    database_backend = get_database_backend(engine=BackendEnum.INMEMORY)
+    sequence(Database(database_backend))
diff --git a/src/context/tests/test_database_engine_redis.py b/src/common/orm/tests/test_orm_backend_redis.py
similarity index 100%
rename from src/context/tests/test_database_engine_redis.py
rename to src/common/orm/tests/test_orm_backend_redis.py
diff --git a/src/common/orm/tests/test_unitary.py b/src/common/orm/tests/test_unitary.py
new file mode 100644
index 0000000000000000000000000000000000000000..fb2525f9e69023a18cb542ef4d2e822320739498
--- /dev/null
+++ b/src/common/orm/tests/test_unitary.py
@@ -0,0 +1,102 @@
+import logging, pytest
+from common.orm._Database import _Database
+from common.orm.backend._Backend import _Backend
+from common.orm.backend.inmemory.InMemoryBackend import InMemoryBackend
+from common.orm.fields.FloatField import FloatField
+from common.orm.fields.IntegerField import IntegerField
+from common.orm.fields.PrimaryKeyField import PrimaryKeyField
+from common.orm.fields.StringField import StringField
+from common.orm.model.Model import Model
+
+logging.basicConfig(level=logging.INFO)
+
+def test_database_instantiation():
+    with pytest.raises(AttributeError) as e:
+        _Database(None)
+    str_class_path = '{}.{}'.format(_Backend.__module__, _Backend.__name__)
+    assert str(e.value) == 'backend must inherit from {}'.format(str_class_path)
+
+    assert _Database(InMemoryBackend()) is not None
+
+def test_model_without_attributes():
+    with pytest.raises(AttributeError) as e:
+        Model(None, 'valid-uuid')
+    str_class_path = '{}.{}'.format(Model.__module__, Model.__name__)
+    assert str(e.value) == 'parent must inherit from {}'.format(str_class_path)
+
+    database = _Database(InMemoryBackend())
+
+    with pytest.raises(AttributeError) as e:
+        Model(database, '')
+    assert str(e.value) == 'Unable to set primary_key() since no PrimaryKeyField is defined in the model'
+
+    with pytest.raises(AttributeError) as e:
+        Model(database, 'primary-key')
+    assert str(e.value) == 'Unable to set primary_key(primary-key) since no PrimaryKeyField is defined in the model'
+
+def test_model_with_primarykey():
+    database = _Database(InMemoryBackend())
+
+    class TestModel(Model):
+        pk = PrimaryKeyField()
+        name = StringField(min_length=1)
+        age = IntegerField(min_value=0)
+        salary = FloatField(min_value=0.0)
+
+    with pytest.raises(ValueError) as e:
+        TestModel(database)
+    assert str(e.value) == 'pk(None) is None.'
+
+    with pytest.raises(ValueError) as e:
+        TestModel(database, '')
+    assert str(e.value) == 'pk() is out of range: allow_empty(False).'
+
+    obj = TestModel(database, 'valid-pk')
+    assert obj is not None
+
+def test_model_with_primarykey_and_attributes():
+    database = _Database(InMemoryBackend())
+
+    class TestModel(Model):
+        pk = PrimaryKeyField()
+        name = StringField(min_length=1)
+        age = IntegerField(min_value=0)
+        salary = FloatField(min_value=0.0)
+
+    with pytest.raises(AttributeError) as e:
+        Attributes(obj, None, {}, {})
+    assert str(e.value) == 'key_pattern must be a non-empty instance of str'
+
+#    # should fail with invalid attribute key
+#    with pytest.raises(AttributeError) as e:
+#        Attributes(obj, '', {}, {})
+#    assert str(e.value) == 'key_pattern must be a non-empty instance of str'
+#
+#    # should fail with invalid attribute validators
+#    with pytest.raises(AttributeError) as e:
+#        Attributes(obj, 'valid-attributes-key', [], {})
+#    assert str(e.value) == 'validators must be an instance of dict'
+#
+#    # should fail with invalid attribute transcoders
+#    with pytest.raises(AttributeError) as e:
+#        Attributes(obj, 'valid-attributes-key', {}, [])
+#    assert str(e.value) == 'transcoders must be an instance of dict'
+#
+#    # should work
+#    attrs = Attributes(obj, 'valid-attributes-key', {}, {})
+#    assert attrs is not None
+
+#def testModel_attributes_gets_invalid_parameters():
+#    # should work
+#    rootModel = _Database(InMemoryBackend())
+#    validators = {'attr': lambda v: True}
+#    entity_attrs = Attributes(rootModel, 'valid-attributes-key', validators, {})
+#    assert entity_attrs is not None
+#
+#    with pytest.raises(AttributeError) as e:
+#        entity_attrs.update(update_attributes={'non-defined-attr': 'random-value'})
+#    assert str(e.value) == "Unexpected update_attributes: {'non-defined-attr': 'random-value'}"
+#
+#    with pytest.raises(AttributeError) as e:
+#        entity_attrs.update(remove_attributes=['non-defined-attr'])
+#    assert str(e.value) == "Unexpected remove_attributes: {'non-defined-attr'}"
diff --git a/src/common/tests/Assertions.py b/src/common/type_checkers/Assertions.py
similarity index 100%
rename from src/common/tests/Assertions.py
rename to src/common/type_checkers/Assertions.py
diff --git a/src/common/type_checkers/Checkers.py b/src/common/type_checkers/Checkers.py
new file mode 100644
index 0000000000000000000000000000000000000000..1876321be3e00c7e521446a3da525ebe725abe8a
--- /dev/null
+++ b/src/common/type_checkers/Checkers.py
@@ -0,0 +1,85 @@
+import re
+from typing import Any, Container, List, Optional, Pattern, Set, Sized, Tuple, Union
+
+def chk_none(name : str, value : Any) -> Any:
+    if value is None: return value
+    msg = '{}({}) is not None.'
+    raise ValueError(msg.format(str(name), str(value)))
+
+def chk_not_none(name : str, value : Any) -> Any:
+    if value is not None: return value
+    msg = '{}({}) is None.'
+    raise ValueError(msg.format(str(name), str(value)))
+
+def chk_type(name : str, value : Any, type_or_types : Union[type, Set[type]] = set()) -> Any:
+    if isinstance(value, type_or_types): return value
+    msg = '{}({}) is of a wrong type({}). Accepted type_or_types({}).'
+    raise TypeError(msg.format(str(name), str(value), type(value).__name__, str(type_or_types)))
+
+def chk_length(
+    name : str, value : Sized, allow_empty : bool = False,
+    min_length : Optional[int] = None, max_length : Optional[int] = None) -> Any:
+
+    length = len(chk_type(name, value, Sized))
+
+    allow_empty = chk_type('allow_empty for {}'.format(name), allow_empty, bool)
+    if not allow_empty and length == 0:
+        raise ValueError('{}({}) is out of range: allow_empty({}).'.format(str(name), str(value), str(allow_empty)))
+
+    if min_length is not None:
+        min_length = chk_type('min_length for {}'.format(name), min_length, int)
+        if length < min_length:
+            raise ValueError('{}({}) is out of range: min_length({}).'.format(str(name), str(value), str(min_length)))
+
+    if max_length is not None:
+        max_length = chk_type('max_length for {}'.format(name), max_length, int)
+        if length > max_length:
+            raise ValueError('{}({}) is out of range: max_value({}).'.format(str(name), str(value), str(max_length)))
+
+    return value
+
+def chk_boolean(name : str, value : Any) -> bool:
+    return chk_type(name, value, bool)
+
+def chk_string(
+    name : str, value : Any, allow_empty : bool = False,
+    min_length : Optional[int] = None, max_length : Optional[int] = None,
+    pattern : Optional[Union[Pattern, str]] = None) -> str:
+
+    chk_type(name, value, str)
+    chk_length(name, value, allow_empty=allow_empty, min_length=min_length, max_length=max_length)
+    if pattern is None: return value
+    pattern = re.compile(pattern)
+    if pattern.match(value): return value
+    raise ValueError('{}({}) does not match pattern({}).'.format(str(name), str(value), str(pattern)))
+
+def chk_float(
+    name : str, value : Any, type_or_types : Union[type, Set[type], List[type], Tuple[type]] = (int, float),
+    min_value : Optional[Union[int, float]] = None, max_value : Optional[Union[int, float]] = None) -> float:
+
+    chk_not_none(name, value)
+    chk_type(name, value, type_or_types)
+    if min_value is not None:
+        chk_type(name, value, type_or_types)
+        if value < min_value:
+            msg = '{}({}) lower than min_value({}).'
+            raise ValueError(msg.format(str(name), str(value), str(min_value)))
+    if max_value is not None:
+        chk_type(name, value, type_or_types)
+        if value > max_value:
+            msg = '{}({}) greater than max_value({}).'
+            raise ValueError(msg.format(str(name), str(value), str(max_value)))
+    return value
+
+def chk_integer(
+    name : str, value : Any,
+    min_value : Optional[Union[int, float]] = None, max_value : Optional[Union[int, float]] = None) -> int:
+
+    return int(chk_float(name, value, type_or_types=int, min_value=min_value, max_value=max_value))
+
+def chk_options(name : str, value : Any, options : Container) -> Any:
+    chk_not_none(name, value)
+    if value not in options:
+        msg = '{}({}) is not one of options({}).'
+        raise ValueError(msg.format(str(name), str(value), str(options)))
+    return value
diff --git a/src/common/type_checkers/__init__.py b/src/common/type_checkers/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/context/proto/context_pb2.py b/src/context/proto/context_pb2.py
index 6dd94bccacb32c243ba649d8211b1a78223a31ec..e852430e3381e0aff2a0651d0107d81271fcefab 100644
--- a/src/context/proto/context_pb2.py
+++ b/src/context/proto/context_pb2.py
@@ -20,55 +20,91 @@ 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\"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\"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\"t\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12 \n\x07\x64\x65vices\x18\x02 \x03(\x0b\x32\x0f.context.Device\x12\x1c\n\x05links\x18\x03 \x03(\x0b\x32\r.context.Link\";\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\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x8b\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-\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x15.context.DeviceDriver\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\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"P\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12&\n\tendpoints\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\"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\"\x8d\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12*\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x14.context.ServiceType\x12&\n\tendpoints\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\"\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\"a\n\nConfigRule\x12%\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x15.context.ConfigAction\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*\x9d\x01\n\x0c\x44\x65viceDriver\x12\x14\n\x10\x44RIVER_UNDEFINED\x10\x00\x12\x15\n\x11\x44RIVER_OPENCONFIG\x10\x01\x12\x18\n\x14\x44RIVER_TRANSPORT_API\x10\x02\x12\r\n\tDRIVER_P4\x10\x03\x12 \n\x1c\x44RIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x15\n\x11\x44RIVER_ONF_TR_352\x10\x05*N\n\x17\x44\x65viceOperationalStatus\x12\x0f\n\x0bKEEP_STATUS\x10\x00\x12\x15\n\x08\x44ISABLED\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x12\x0b\n\x07\x45NABLED\x10\x01*}\n\x0bServiceType\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*Y\n\x0c\x43onfigAction\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\xe6\n\n\x0e\x43ontextService\x12\x39\n\rGetContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x35\n\x0bGetContexts\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\rDeleteContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12?\n\x0eGetTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12<\n\rGetTopologies\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\x0e\x44\x65leteTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12\x37\n\x0cGetDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x33\n\nGetDevices\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\x33\n\nGetLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12/\n\x08GetLinks\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\nDeleteLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12=\n\rGetServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12\x39\n\x0bGetServices\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\rDeleteService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\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\"\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\"t\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12 \n\x07\x64\x65vices\x18\x02 \x03(\x0b\x32\x0f.context.Device\x12\x1c\n\x05links\x18\x03 \x03(\x0b\x32\r.context.Link\";\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\"P\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12&\n\tendpoints\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\"\x91\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\tendpoints\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*N\n\x17\x44\x65viceOperationalStatus\x12\x0f\n\x0bKEEP_STATUS\x10\x00\x12\x15\n\x08\x44ISABLED\x10\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x12\x0b\n\x07\x45NABLED\x10\x01*\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'
 )
 
-_DEVICEDRIVER = _descriptor.EnumDescriptor(
-  name='DeviceDriver',
-  full_name='context.DeviceDriver',
+_EVENTTYPEENUM = _descriptor.EnumDescriptor(
+  name='EventTypeEnum',
+  full_name='context.EventTypeEnum',
   filename=None,
   file=DESCRIPTOR,
   create_key=_descriptor._internal_create_key,
   values=[
     _descriptor.EnumValueDescriptor(
-      name='DRIVER_UNDEFINED', index=0, number=0,
+      name='EVENTTYPE_UNDEFINED', index=0, number=0,
       serialized_options=None,
       type=None,
       create_key=_descriptor._internal_create_key),
     _descriptor.EnumValueDescriptor(
-      name='DRIVER_OPENCONFIG', index=1, number=1,
+      name='EVENTTYPE_CREATE', index=1, number=1,
       serialized_options=None,
       type=None,
       create_key=_descriptor._internal_create_key),
     _descriptor.EnumValueDescriptor(
-      name='DRIVER_TRANSPORT_API', index=2, number=2,
+      name='EVENTTYPE_UPDATE', index=2, number=2,
       serialized_options=None,
       type=None,
       create_key=_descriptor._internal_create_key),
     _descriptor.EnumValueDescriptor(
-      name='DRIVER_P4', index=3, number=3,
+      name='EVENTTYPE_REMOVE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=3364,
+  serialized_end=3470,
+)
+_sym_db.RegisterEnumDescriptor(_EVENTTYPEENUM)
+
+EventTypeEnum = enum_type_wrapper.EnumTypeWrapper(_EVENTTYPEENUM)
+_DEVICEDRIVERENUM = _descriptor.EnumDescriptor(
+  name='DeviceDriverEnum',
+  full_name='context.DeviceDriverEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_OPENCONFIG', index=1, number=1,
       serialized_options=None,
       type=None,
       create_key=_descriptor._internal_create_key),
     _descriptor.EnumValueDescriptor(
-      name='DRIVER_IETF_NETWORK_TOPOLOGY', index=4, number=4,
+      name='DEVICEDRIVER_TRANSPORT_API', index=2, number=2,
       serialized_options=None,
       type=None,
       create_key=_descriptor._internal_create_key),
     _descriptor.EnumValueDescriptor(
-      name='DRIVER_ONF_TR_352', index=5, number=5,
+      name='DEVICEDRIVER_P4', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_IETF_NETWORK_TOPOLOGY', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_ONF_TR_352', index=5, number=5,
       serialized_options=None,
       type=None,
       create_key=_descriptor._internal_create_key),
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=2855,
-  serialized_end=3012,
+  serialized_start=3473,
+  serialized_end=3670,
 )
-_sym_db.RegisterEnumDescriptor(_DEVICEDRIVER)
+_sym_db.RegisterEnumDescriptor(_DEVICEDRIVERENUM)
 
-DeviceDriver = enum_type_wrapper.EnumTypeWrapper(_DEVICEDRIVER)
+DeviceDriverEnum = enum_type_wrapper.EnumTypeWrapper(_DEVICEDRIVERENUM)
 _DEVICEOPERATIONALSTATUS = _descriptor.EnumDescriptor(
   name='DeviceOperationalStatus',
   full_name='context.DeviceOperationalStatus',
@@ -94,15 +130,15 @@ _DEVICEOPERATIONALSTATUS = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3014,
-  serialized_end=3092,
+  serialized_start=3672,
+  serialized_end=3750,
 )
 _sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUS)
 
 DeviceOperationalStatus = enum_type_wrapper.EnumTypeWrapper(_DEVICEOPERATIONALSTATUS)
-_SERVICETYPE = _descriptor.EnumDescriptor(
-  name='ServiceType',
-  full_name='context.ServiceType',
+_SERVICETYPEENUM = _descriptor.EnumDescriptor(
+  name='ServiceTypeEnum',
+  full_name='context.ServiceTypeEnum',
   filename=None,
   file=DESCRIPTOR,
   create_key=_descriptor._internal_create_key,
@@ -130,12 +166,12 @@ _SERVICETYPE = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3094,
-  serialized_end=3219,
+  serialized_start=3753,
+  serialized_end=3882,
 )
-_sym_db.RegisterEnumDescriptor(_SERVICETYPE)
+_sym_db.RegisterEnumDescriptor(_SERVICETYPEENUM)
 
-ServiceType = enum_type_wrapper.EnumTypeWrapper(_SERVICETYPE)
+ServiceTypeEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICETYPEENUM)
 _SERVICESTATEENUM = _descriptor.EnumDescriptor(
   name='ServiceStateEnum',
   full_name='context.ServiceStateEnum',
@@ -161,15 +197,15 @@ _SERVICESTATEENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3221,
-  serialized_end=3327,
+  serialized_start=3884,
+  serialized_end=3990,
 )
 _sym_db.RegisterEnumDescriptor(_SERVICESTATEENUM)
 
 ServiceStateEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICESTATEENUM)
-_CONFIGACTION = _descriptor.EnumDescriptor(
-  name='ConfigAction',
-  full_name='context.ConfigAction',
+_CONFIGACTIONENUM = _descriptor.EnumDescriptor(
+  name='ConfigActionEnum',
+  full_name='context.ConfigActionEnum',
   filename=None,
   file=DESCRIPTOR,
   create_key=_descriptor._internal_create_key,
@@ -192,18 +228,22 @@ _CONFIGACTION = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3329,
-  serialized_end=3418,
+  serialized_start=3992,
+  serialized_end=4085,
 )
-_sym_db.RegisterEnumDescriptor(_CONFIGACTION)
-
-ConfigAction = enum_type_wrapper.EnumTypeWrapper(_CONFIGACTION)
-DRIVER_UNDEFINED = 0
-DRIVER_OPENCONFIG = 1
-DRIVER_TRANSPORT_API = 2
-DRIVER_P4 = 3
-DRIVER_IETF_NETWORK_TOPOLOGY = 4
-DRIVER_ONF_TR_352 = 5
+_sym_db.RegisterEnumDescriptor(_CONFIGACTIONENUM)
+
+ConfigActionEnum = enum_type_wrapper.EnumTypeWrapper(_CONFIGACTIONENUM)
+EVENTTYPE_UNDEFINED = 0
+EVENTTYPE_CREATE = 1
+EVENTTYPE_UPDATE = 2
+EVENTTYPE_REMOVE = 3
+DEVICEDRIVER_UNDEFINED = 0
+DEVICEDRIVER_OPENCONFIG = 1
+DEVICEDRIVER_TRANSPORT_API = 2
+DEVICEDRIVER_P4 = 3
+DEVICEDRIVER_IETF_NETWORK_TOPOLOGY = 4
+DEVICEDRIVER_ONF_TR_352 = 5
 KEEP_STATUS = 0
 DISABLED = -1
 ENABLED = 1
@@ -277,6 +317,45 @@ _UUID = _descriptor.Descriptor(
 )
 
 
+_EVENT = _descriptor.Descriptor(
+  name='Event',
+  full_name='context.Event',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='timestamp', full_name='context.Event.timestamp', index=0,
+      number=1, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      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='event_type', full_name='context.Event.event_type', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      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),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=57,
+  serialized_end=127,
+)
+
+
 _CONTEXTID = _descriptor.Descriptor(
   name='ContextId',
   full_name='context.ContextId',
@@ -304,8 +383,8 @@ _CONTEXTID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=57,
-  serialized_end=105,
+  serialized_start=129,
+  serialized_end=177,
 )
 
 
@@ -350,8 +429,8 @@ _CONTEXT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=108,
-  serialized_end=243,
+  serialized_start=180,
+  serialized_end=315,
 )
 
 
@@ -382,8 +461,8 @@ _CONTEXTIDLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=245,
-  serialized_end=301,
+  serialized_start=317,
+  serialized_end=373,
 )
 
 
@@ -414,8 +493,47 @@ _CONTEXTLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=303,
-  serialized_end=352,
+  serialized_start=375,
+  serialized_end=424,
+)
+
+
+_CONTEXTEVENT = _descriptor.Descriptor(
+  name='ContextEvent',
+  full_name='context.ContextEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.ContextEvent.event', index=0,
+      number=1, 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,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.ContextEvent.context_id', index=1,
+      number=2, 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,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=426,
+  serialized_end=511,
 )
 
 
@@ -453,8 +571,8 @@ _TOPOLOGYID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=354,
-  serialized_end=444,
+  serialized_start=513,
+  serialized_end=603,
 )
 
 
@@ -499,8 +617,8 @@ _TOPOLOGY = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=446,
-  serialized_end=562,
+  serialized_start=605,
+  serialized_end=721,
 )
 
 
@@ -531,8 +649,8 @@ _TOPOLOGYIDLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=564,
-  serialized_end=623,
+  serialized_start=723,
+  serialized_end=782,
 )
 
 
@@ -563,8 +681,47 @@ _TOPOLOGYLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=625,
-  serialized_end=678,
+  serialized_start=784,
+  serialized_end=837,
+)
+
+
+_TOPOLOGYEVENT = _descriptor.Descriptor(
+  name='TopologyEvent',
+  full_name='context.TopologyEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.TopologyEvent.event', index=0,
+      number=1, 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,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='topology_id', full_name='context.TopologyEvent.topology_id', index=1,
+      number=2, 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,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=839,
+  serialized_end=927,
 )
 
 
@@ -595,8 +752,8 @@ _DEVICEID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=680,
-  serialized_end=726,
+  serialized_start=929,
+  serialized_end=975,
 )
 
 
@@ -662,8 +819,8 @@ _DEVICE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=729,
-  serialized_end=996,
+  serialized_start=978,
+  serialized_end=1249,
 )
 
 
@@ -694,8 +851,8 @@ _DEVICECONFIG = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=998,
-  serialized_end=1055,
+  serialized_start=1251,
+  serialized_end=1308,
 )
 
 
@@ -726,8 +883,8 @@ _DEVICEIDLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1057,
-  serialized_end=1110,
+  serialized_start=1310,
+  serialized_end=1363,
 )
 
 
@@ -758,8 +915,47 @@ _DEVICELIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1112,
-  serialized_end=1158,
+  serialized_start=1365,
+  serialized_end=1411,
+)
+
+
+_DEVICEEVENT = _descriptor.Descriptor(
+  name='DeviceEvent',
+  full_name='context.DeviceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.DeviceEvent.event', index=0,
+      number=1, 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,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_id', full_name='context.DeviceEvent.device_id', index=1,
+      number=2, 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,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1413,
+  serialized_end=1495,
 )
 
 
@@ -790,8 +986,8 @@ _LINKID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1160,
-  serialized_end=1202,
+  serialized_start=1497,
+  serialized_end=1539,
 )
 
 
@@ -829,8 +1025,8 @@ _LINK = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1204,
-  serialized_end=1284,
+  serialized_start=1541,
+  serialized_end=1621,
 )
 
 
@@ -861,8 +1057,8 @@ _LINKIDLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1286,
-  serialized_end=1333,
+  serialized_start=1623,
+  serialized_end=1670,
 )
 
 
@@ -893,8 +1089,47 @@ _LINKLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1335,
-  serialized_end=1375,
+  serialized_start=1672,
+  serialized_end=1712,
+)
+
+
+_LINKEVENT = _descriptor.Descriptor(
+  name='LinkEvent',
+  full_name='context.LinkEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.LinkEvent.event', index=0,
+      number=1, 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,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='link_id', full_name='context.LinkEvent.link_id', index=1,
+      number=2, 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,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1714,
+  serialized_end=1790,
 )
 
 
@@ -932,8 +1167,8 @@ _SERVICEID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1377,
-  serialized_end=1465,
+  serialized_start=1792,
+  serialized_end=1880,
 )
 
 
@@ -999,8 +1234,8 @@ _SERVICE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1468,
-  serialized_end=1737,
+  serialized_start=1883,
+  serialized_end=2156,
 )
 
 
@@ -1031,8 +1266,8 @@ _SERVICESTATE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1739,
-  serialized_end=1803,
+  serialized_start=2158,
+  serialized_end=2222,
 )
 
 
@@ -1063,8 +1298,8 @@ _SERVICECONFIG = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1805,
-  serialized_end=1863,
+  serialized_start=2224,
+  serialized_end=2282,
 )
 
 
@@ -1095,8 +1330,8 @@ _SERVICEIDLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1865,
-  serialized_end=1921,
+  serialized_start=2284,
+  serialized_end=2340,
 )
 
 
@@ -1127,8 +1362,47 @@ _SERVICELIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1923,
-  serialized_end=1972,
+  serialized_start=2342,
+  serialized_end=2391,
+)
+
+
+_SERVICEEVENT = _descriptor.Descriptor(
+  name='ServiceEvent',
+  full_name='context.ServiceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.ServiceEvent.event', index=0,
+      number=1, 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,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_id', full_name='context.ServiceEvent.service_id', index=1,
+      number=2, 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,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2393,
+  serialized_end=2478,
 )
 
 
@@ -1173,8 +1447,8 @@ _ENDPOINTID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1975,
-  serialized_end=2105,
+  serialized_start=2481,
+  serialized_end=2611,
 )
 
 
@@ -1212,8 +1486,8 @@ _ENDPOINT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2107,
-  serialized_end=2178,
+  serialized_start=2613,
+  serialized_end=2684,
 )
 
 
@@ -1258,8 +1532,8 @@ _CONFIGRULE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2180,
-  serialized_end=2277,
+  serialized_start=2686,
+  serialized_end=2787,
 )
 
 
@@ -1297,8 +1571,8 @@ _CONSTRAINT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2279,
-  serialized_end=2342,
+  serialized_start=2789,
+  serialized_end=2852,
 )
 
 
@@ -1329,8 +1603,8 @@ _CONNECTIONID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2344,
-  serialized_end=2398,
+  serialized_start=2854,
+  serialized_end=2908,
 )
 
 
@@ -1375,8 +1649,8 @@ _CONNECTION = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2401,
-  serialized_end=2542,
+  serialized_start=2911,
+  serialized_end=3052,
 )
 
 
@@ -1407,8 +1681,8 @@ _CONNECTIONIDLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2544,
-  serialized_end=2609,
+  serialized_start=3054,
+  serialized_end=3119,
 )
 
 
@@ -1439,8 +1713,8 @@ _CONNECTIONLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2611,
-  serialized_end=2669,
+  serialized_start=3121,
+  serialized_end=3179,
 )
 
 
@@ -1485,8 +1759,8 @@ _TERAFLOWCONTROLLER = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2671,
-  serialized_end=2765,
+  serialized_start=3181,
+  serialized_end=3275,
 )
 
 
@@ -1524,16 +1798,19 @@ _AUTHENTICATIONRESULT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2767,
-  serialized_end=2852,
+  serialized_start=3277,
+  serialized_end=3362,
 )
 
+_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['controller'].message_type = _TERAFLOWCONTROLLER
 _CONTEXTIDLIST.fields_by_name['context_ids'].message_type = _CONTEXTID
 _CONTEXTLIST.fields_by_name['contexts'].message_type = _CONTEXT
+_CONTEXTEVENT.fields_by_name['event'].message_type = _EVENT
+_CONTEXTEVENT.fields_by_name['context_id'].message_type = _CONTEXTID
 _TOPOLOGYID.fields_by_name['context_id'].message_type = _CONTEXTID
 _TOPOLOGYID.fields_by_name['topology_uuid'].message_type = _UUID
 _TOPOLOGY.fields_by_name['topology_id'].message_type = _TOPOLOGYID
@@ -1541,24 +1818,30 @@ _TOPOLOGY.fields_by_name['devices'].message_type = _DEVICE
 _TOPOLOGY.fields_by_name['links'].message_type = _LINK
 _TOPOLOGYIDLIST.fields_by_name['topology_ids'].message_type = _TOPOLOGYID
 _TOPOLOGYLIST.fields_by_name['topologies'].message_type = _TOPOLOGY
+_TOPOLOGYEVENT.fields_by_name['event'].message_type = _EVENT
+_TOPOLOGYEVENT.fields_by_name['topology_id'].message_type = _TOPOLOGYID
 _DEVICEID.fields_by_name['device_uuid'].message_type = _UUID
 _DEVICE.fields_by_name['device_id'].message_type = _DEVICEID
 _DEVICE.fields_by_name['device_config'].message_type = _DEVICECONFIG
 _DEVICE.fields_by_name['devive_operational_status'].enum_type = _DEVICEOPERATIONALSTATUS
-_DEVICE.fields_by_name['device_drivers'].enum_type = _DEVICEDRIVER
+_DEVICE.fields_by_name['device_drivers'].enum_type = _DEVICEDRIVERENUM
 _DEVICE.fields_by_name['endpoints'].message_type = _ENDPOINT
 _DEVICECONFIG.fields_by_name['config_rules'].message_type = _CONFIGRULE
 _DEVICEIDLIST.fields_by_name['device_ids'].message_type = _DEVICEID
 _DEVICELIST.fields_by_name['devices'].message_type = _DEVICE
+_DEVICEEVENT.fields_by_name['event'].message_type = _EVENT
+_DEVICEEVENT.fields_by_name['device_id'].message_type = _DEVICEID
 _LINKID.fields_by_name['link_uuid'].message_type = _UUID
 _LINK.fields_by_name['link_id'].message_type = _LINKID
 _LINK.fields_by_name['endpoints'].message_type = _ENDPOINTID
 _LINKIDLIST.fields_by_name['link_ids'].message_type = _LINKID
 _LINKLIST.fields_by_name['links'].message_type = _LINK
+_LINKEVENT.fields_by_name['event'].message_type = _EVENT
+_LINKEVENT.fields_by_name['link_id'].message_type = _LINKID
 _SERVICEID.fields_by_name['context_id'].message_type = _CONTEXTID
 _SERVICEID.fields_by_name['service_uuid'].message_type = _UUID
 _SERVICE.fields_by_name['service_id'].message_type = _SERVICEID
-_SERVICE.fields_by_name['service_type'].enum_type = _SERVICETYPE
+_SERVICE.fields_by_name['service_type'].enum_type = _SERVICETYPEENUM
 _SERVICE.fields_by_name['endpoints'].message_type = _ENDPOINTID
 _SERVICE.fields_by_name['constraints'].message_type = _CONSTRAINT
 _SERVICE.fields_by_name['service_state'].message_type = _SERVICESTATE
@@ -1567,11 +1850,13 @@ _SERVICESTATE.fields_by_name['service_state'].enum_type = _SERVICESTATEENUM
 _SERVICECONFIG.fields_by_name['config_rules'].message_type = _CONFIGRULE
 _SERVICEIDLIST.fields_by_name['service_ids'].message_type = _SERVICEID
 _SERVICELIST.fields_by_name['services'].message_type = _SERVICE
+_SERVICEEVENT.fields_by_name['event'].message_type = _EVENT
+_SERVICEEVENT.fields_by_name['service_id'].message_type = _SERVICEID
 _ENDPOINTID.fields_by_name['topology_id'].message_type = _TOPOLOGYID
 _ENDPOINTID.fields_by_name['device_id'].message_type = _DEVICEID
 _ENDPOINTID.fields_by_name['endpoint_uuid'].message_type = _UUID
 _ENDPOINT.fields_by_name['endpoint_id'].message_type = _ENDPOINTID
-_CONFIGRULE.fields_by_name['action'].enum_type = _CONFIGACTION
+_CONFIGRULE.fields_by_name['action'].enum_type = _CONFIGACTIONENUM
 _CONNECTIONID.fields_by_name['connection_uuid'].message_type = _UUID
 _CONNECTION.fields_by_name['connection_id'].message_type = _CONNECTIONID
 _CONNECTION.fields_by_name['related_service_id'].message_type = _SERVICEID
@@ -1582,29 +1867,35 @@ _TERAFLOWCONTROLLER.fields_by_name['context_id'].message_type = _CONTEXTID
 _AUTHENTICATIONRESULT.fields_by_name['context_id'].message_type = _CONTEXTID
 DESCRIPTOR.message_types_by_name['Empty'] = _EMPTY
 DESCRIPTOR.message_types_by_name['Uuid'] = _UUID
+DESCRIPTOR.message_types_by_name['Event'] = _EVENT
 DESCRIPTOR.message_types_by_name['ContextId'] = _CONTEXTID
 DESCRIPTOR.message_types_by_name['Context'] = _CONTEXT
 DESCRIPTOR.message_types_by_name['ContextIdList'] = _CONTEXTIDLIST
 DESCRIPTOR.message_types_by_name['ContextList'] = _CONTEXTLIST
+DESCRIPTOR.message_types_by_name['ContextEvent'] = _CONTEXTEVENT
 DESCRIPTOR.message_types_by_name['TopologyId'] = _TOPOLOGYID
 DESCRIPTOR.message_types_by_name['Topology'] = _TOPOLOGY
 DESCRIPTOR.message_types_by_name['TopologyIdList'] = _TOPOLOGYIDLIST
 DESCRIPTOR.message_types_by_name['TopologyList'] = _TOPOLOGYLIST
+DESCRIPTOR.message_types_by_name['TopologyEvent'] = _TOPOLOGYEVENT
 DESCRIPTOR.message_types_by_name['DeviceId'] = _DEVICEID
 DESCRIPTOR.message_types_by_name['Device'] = _DEVICE
 DESCRIPTOR.message_types_by_name['DeviceConfig'] = _DEVICECONFIG
 DESCRIPTOR.message_types_by_name['DeviceIdList'] = _DEVICEIDLIST
 DESCRIPTOR.message_types_by_name['DeviceList'] = _DEVICELIST
+DESCRIPTOR.message_types_by_name['DeviceEvent'] = _DEVICEEVENT
 DESCRIPTOR.message_types_by_name['LinkId'] = _LINKID
 DESCRIPTOR.message_types_by_name['Link'] = _LINK
 DESCRIPTOR.message_types_by_name['LinkIdList'] = _LINKIDLIST
 DESCRIPTOR.message_types_by_name['LinkList'] = _LINKLIST
+DESCRIPTOR.message_types_by_name['LinkEvent'] = _LINKEVENT
 DESCRIPTOR.message_types_by_name['ServiceId'] = _SERVICEID
 DESCRIPTOR.message_types_by_name['Service'] = _SERVICE
 DESCRIPTOR.message_types_by_name['ServiceState'] = _SERVICESTATE
 DESCRIPTOR.message_types_by_name['ServiceConfig'] = _SERVICECONFIG
 DESCRIPTOR.message_types_by_name['ServiceIdList'] = _SERVICEIDLIST
 DESCRIPTOR.message_types_by_name['ServiceList'] = _SERVICELIST
+DESCRIPTOR.message_types_by_name['ServiceEvent'] = _SERVICEEVENT
 DESCRIPTOR.message_types_by_name['EndPointId'] = _ENDPOINTID
 DESCRIPTOR.message_types_by_name['EndPoint'] = _ENDPOINT
 DESCRIPTOR.message_types_by_name['ConfigRule'] = _CONFIGRULE
@@ -1615,11 +1906,12 @@ DESCRIPTOR.message_types_by_name['ConnectionIdList'] = _CONNECTIONIDLIST
 DESCRIPTOR.message_types_by_name['ConnectionList'] = _CONNECTIONLIST
 DESCRIPTOR.message_types_by_name['TeraFlowController'] = _TERAFLOWCONTROLLER
 DESCRIPTOR.message_types_by_name['AuthenticationResult'] = _AUTHENTICATIONRESULT
-DESCRIPTOR.enum_types_by_name['DeviceDriver'] = _DEVICEDRIVER
+DESCRIPTOR.enum_types_by_name['EventTypeEnum'] = _EVENTTYPEENUM
+DESCRIPTOR.enum_types_by_name['DeviceDriverEnum'] = _DEVICEDRIVERENUM
 DESCRIPTOR.enum_types_by_name['DeviceOperationalStatus'] = _DEVICEOPERATIONALSTATUS
-DESCRIPTOR.enum_types_by_name['ServiceType'] = _SERVICETYPE
+DESCRIPTOR.enum_types_by_name['ServiceTypeEnum'] = _SERVICETYPEENUM
 DESCRIPTOR.enum_types_by_name['ServiceStateEnum'] = _SERVICESTATEENUM
-DESCRIPTOR.enum_types_by_name['ConfigAction'] = _CONFIGACTION
+DESCRIPTOR.enum_types_by_name['ConfigActionEnum'] = _CONFIGACTIONENUM
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
 Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), {
@@ -1636,6 +1928,13 @@ Uuid = _reflection.GeneratedProtocolMessageType('Uuid', (_message.Message,), {
   })
 _sym_db.RegisterMessage(Uuid)
 
+Event = _reflection.GeneratedProtocolMessageType('Event', (_message.Message,), {
+  'DESCRIPTOR' : _EVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Event)
+  })
+_sym_db.RegisterMessage(Event)
+
 ContextId = _reflection.GeneratedProtocolMessageType('ContextId', (_message.Message,), {
   'DESCRIPTOR' : _CONTEXTID,
   '__module__' : 'context_pb2'
@@ -1664,6 +1963,13 @@ ContextList = _reflection.GeneratedProtocolMessageType('ContextList', (_message.
   })
 _sym_db.RegisterMessage(ContextList)
 
+ContextEvent = _reflection.GeneratedProtocolMessageType('ContextEvent', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextEvent)
+  })
+_sym_db.RegisterMessage(ContextEvent)
+
 TopologyId = _reflection.GeneratedProtocolMessageType('TopologyId', (_message.Message,), {
   'DESCRIPTOR' : _TOPOLOGYID,
   '__module__' : 'context_pb2'
@@ -1692,6 +1998,13 @@ TopologyList = _reflection.GeneratedProtocolMessageType('TopologyList', (_messag
   })
 _sym_db.RegisterMessage(TopologyList)
 
+TopologyEvent = _reflection.GeneratedProtocolMessageType('TopologyEvent', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyEvent)
+  })
+_sym_db.RegisterMessage(TopologyEvent)
+
 DeviceId = _reflection.GeneratedProtocolMessageType('DeviceId', (_message.Message,), {
   'DESCRIPTOR' : _DEVICEID,
   '__module__' : 'context_pb2'
@@ -1727,6 +2040,13 @@ DeviceList = _reflection.GeneratedProtocolMessageType('DeviceList', (_message.Me
   })
 _sym_db.RegisterMessage(DeviceList)
 
+DeviceEvent = _reflection.GeneratedProtocolMessageType('DeviceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceEvent)
+  })
+_sym_db.RegisterMessage(DeviceEvent)
+
 LinkId = _reflection.GeneratedProtocolMessageType('LinkId', (_message.Message,), {
   'DESCRIPTOR' : _LINKID,
   '__module__' : 'context_pb2'
@@ -1755,6 +2075,13 @@ LinkList = _reflection.GeneratedProtocolMessageType('LinkList', (_message.Messag
   })
 _sym_db.RegisterMessage(LinkList)
 
+LinkEvent = _reflection.GeneratedProtocolMessageType('LinkEvent', (_message.Message,), {
+  'DESCRIPTOR' : _LINKEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkEvent)
+  })
+_sym_db.RegisterMessage(LinkEvent)
+
 ServiceId = _reflection.GeneratedProtocolMessageType('ServiceId', (_message.Message,), {
   'DESCRIPTOR' : _SERVICEID,
   '__module__' : 'context_pb2'
@@ -1797,6 +2124,13 @@ ServiceList = _reflection.GeneratedProtocolMessageType('ServiceList', (_message.
   })
 _sym_db.RegisterMessage(ServiceList)
 
+ServiceEvent = _reflection.GeneratedProtocolMessageType('ServiceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceEvent)
+  })
+_sym_db.RegisterMessage(ServiceEvent)
+
 EndPointId = _reflection.GeneratedProtocolMessageType('EndPointId', (_message.Message,), {
   'DESCRIPTOR' : _ENDPOINTID,
   '__module__' : 'context_pb2'
@@ -1876,12 +2210,12 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=3421,
-  serialized_end=4803,
+  serialized_start=4088,
+  serialized_end=5789,
   methods=[
   _descriptor.MethodDescriptor(
-    name='GetContextIds',
-    full_name='context.ContextService.GetContextIds',
+    name='ListContextIds',
+    full_name='context.ContextService.ListContextIds',
     index=0,
     containing_service=None,
     input_type=_EMPTY,
@@ -1890,8 +2224,8 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
     create_key=_descriptor._internal_create_key,
   ),
   _descriptor.MethodDescriptor(
-    name='GetContexts',
-    full_name='context.ContextService.GetContexts',
+    name='ListContexts',
+    full_name='context.ContextService.ListContexts',
     index=1,
     containing_service=None,
     input_type=_EMPTY,
@@ -1920,8 +2254,8 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
     create_key=_descriptor._internal_create_key,
   ),
   _descriptor.MethodDescriptor(
-    name='DeleteContext',
-    full_name='context.ContextService.DeleteContext',
+    name='RemoveContext',
+    full_name='context.ContextService.RemoveContext',
     index=4,
     containing_service=None,
     input_type=_CONTEXTID,
@@ -1930,19 +2264,29 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
     create_key=_descriptor._internal_create_key,
   ),
   _descriptor.MethodDescriptor(
-    name='GetTopologyIds',
-    full_name='context.ContextService.GetTopologyIds',
+    name='GetContextEvents',
+    full_name='context.ContextService.GetContextEvents',
     index=5,
     containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONTEXTEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListTopologyIds',
+    full_name='context.ContextService.ListTopologyIds',
+    index=6,
+    containing_service=None,
     input_type=_CONTEXTID,
     output_type=_TOPOLOGYIDLIST,
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
   _descriptor.MethodDescriptor(
-    name='GetTopologies',
-    full_name='context.ContextService.GetTopologies',
-    index=6,
+    name='ListTopologies',
+    full_name='context.ContextService.ListTopologies',
+    index=7,
     containing_service=None,
     input_type=_CONTEXTID,
     output_type=_TOPOLOGYLIST,
@@ -1952,7 +2296,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetTopology',
     full_name='context.ContextService.GetTopology',
-    index=7,
+    index=8,
     containing_service=None,
     input_type=_TOPOLOGYID,
     output_type=_TOPOLOGY,
@@ -1962,7 +2306,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='SetTopology',
     full_name='context.ContextService.SetTopology',
-    index=8,
+    index=9,
     containing_service=None,
     input_type=_TOPOLOGY,
     output_type=_TOPOLOGYID,
@@ -1970,9 +2314,9 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
     create_key=_descriptor._internal_create_key,
   ),
   _descriptor.MethodDescriptor(
-    name='DeleteTopology',
-    full_name='context.ContextService.DeleteTopology',
-    index=9,
+    name='RemoveTopology',
+    full_name='context.ContextService.RemoveTopology',
+    index=10,
     containing_service=None,
     input_type=_TOPOLOGYID,
     output_type=_EMPTY,
@@ -1980,9 +2324,19 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
     create_key=_descriptor._internal_create_key,
   ),
   _descriptor.MethodDescriptor(
-    name='GetDeviceIds',
-    full_name='context.ContextService.GetDeviceIds',
-    index=10,
+    name='GetTopologyEvents',
+    full_name='context.ContextService.GetTopologyEvents',
+    index=11,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_TOPOLOGYEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListDeviceIds',
+    full_name='context.ContextService.ListDeviceIds',
+    index=12,
     containing_service=None,
     input_type=_EMPTY,
     output_type=_DEVICEIDLIST,
@@ -1990,9 +2344,9 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
     create_key=_descriptor._internal_create_key,
   ),
   _descriptor.MethodDescriptor(
-    name='GetDevices',
-    full_name='context.ContextService.GetDevices',
-    index=11,
+    name='ListDevices',
+    full_name='context.ContextService.ListDevices',
+    index=13,
     containing_service=None,
     input_type=_EMPTY,
     output_type=_DEVICELIST,
@@ -2002,7 +2356,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetDevice',
     full_name='context.ContextService.GetDevice',
-    index=12,
+    index=14,
     containing_service=None,
     input_type=_DEVICEID,
     output_type=_DEVICE,
@@ -2012,7 +2366,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='SetDevice',
     full_name='context.ContextService.SetDevice',
-    index=13,
+    index=15,
     containing_service=None,
     input_type=_DEVICE,
     output_type=_DEVICEID,
@@ -2022,7 +2376,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='RemoveDevice',
     full_name='context.ContextService.RemoveDevice',
-    index=14,
+    index=16,
     containing_service=None,
     input_type=_DEVICEID,
     output_type=_EMPTY,
@@ -2030,9 +2384,19 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
     create_key=_descriptor._internal_create_key,
   ),
   _descriptor.MethodDescriptor(
-    name='GetLinkIds',
-    full_name='context.ContextService.GetLinkIds',
-    index=15,
+    name='GetDeviceEvents',
+    full_name='context.ContextService.GetDeviceEvents',
+    index=17,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_DEVICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListLinkIds',
+    full_name='context.ContextService.ListLinkIds',
+    index=18,
     containing_service=None,
     input_type=_EMPTY,
     output_type=_LINKIDLIST,
@@ -2040,9 +2404,9 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
     create_key=_descriptor._internal_create_key,
   ),
   _descriptor.MethodDescriptor(
-    name='GetLinks',
-    full_name='context.ContextService.GetLinks',
-    index=16,
+    name='ListLinks',
+    full_name='context.ContextService.ListLinks',
+    index=19,
     containing_service=None,
     input_type=_EMPTY,
     output_type=_LINKLIST,
@@ -2052,7 +2416,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetLink',
     full_name='context.ContextService.GetLink',
-    index=17,
+    index=20,
     containing_service=None,
     input_type=_LINKID,
     output_type=_LINK,
@@ -2062,7 +2426,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='SetLink',
     full_name='context.ContextService.SetLink',
-    index=18,
+    index=21,
     containing_service=None,
     input_type=_LINK,
     output_type=_LINKID,
@@ -2070,9 +2434,9 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
     create_key=_descriptor._internal_create_key,
   ),
   _descriptor.MethodDescriptor(
-    name='DeleteLink',
-    full_name='context.ContextService.DeleteLink',
-    index=19,
+    name='RemoveLink',
+    full_name='context.ContextService.RemoveLink',
+    index=22,
     containing_service=None,
     input_type=_LINKID,
     output_type=_EMPTY,
@@ -2080,9 +2444,19 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
     create_key=_descriptor._internal_create_key,
   ),
   _descriptor.MethodDescriptor(
-    name='GetServiceIds',
-    full_name='context.ContextService.GetServiceIds',
-    index=20,
+    name='GetLinkEvents',
+    full_name='context.ContextService.GetLinkEvents',
+    index=23,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_LINKEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListServiceIds',
+    full_name='context.ContextService.ListServiceIds',
+    index=24,
     containing_service=None,
     input_type=_CONTEXTID,
     output_type=_SERVICEIDLIST,
@@ -2090,9 +2464,9 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
     create_key=_descriptor._internal_create_key,
   ),
   _descriptor.MethodDescriptor(
-    name='GetServices',
-    full_name='context.ContextService.GetServices',
-    index=21,
+    name='ListServices',
+    full_name='context.ContextService.ListServices',
+    index=25,
     containing_service=None,
     input_type=_CONTEXTID,
     output_type=_SERVICELIST,
@@ -2102,7 +2476,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetService',
     full_name='context.ContextService.GetService',
-    index=22,
+    index=26,
     containing_service=None,
     input_type=_SERVICEID,
     output_type=_SERVICE,
@@ -2112,7 +2486,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='SetService',
     full_name='context.ContextService.SetService',
-    index=23,
+    index=27,
     containing_service=None,
     input_type=_SERVICE,
     output_type=_SERVICEID,
@@ -2120,15 +2494,25 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
     create_key=_descriptor._internal_create_key,
   ),
   _descriptor.MethodDescriptor(
-    name='DeleteService',
-    full_name='context.ContextService.DeleteService',
-    index=24,
+    name='RemoveService',
+    full_name='context.ContextService.RemoveService',
+    index=28,
     containing_service=None,
     input_type=_SERVICEID,
     output_type=_EMPTY,
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
+  _descriptor.MethodDescriptor(
+    name='GetServiceEvents',
+    full_name='context.ContextService.GetServiceEvents',
+    index=29,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_SERVICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
 ])
 _sym_db.RegisterServiceDescriptor(_CONTEXTSERVICE)
 
diff --git a/src/context/proto/context_pb2_grpc.py b/src/context/proto/context_pb2_grpc.py
index 2dd4f98d6cd76184c7aeadfa3e719806e5c883dd..63a7edb530ab138e7f2d6c2ba2d6075db52e2fee 100644
--- a/src/context/proto/context_pb2_grpc.py
+++ b/src/context/proto/context_pb2_grpc.py
@@ -14,13 +14,13 @@ class ContextServiceStub(object):
         Args:
             channel: A grpc.Channel.
         """
-        self.GetContextIds = channel.unary_unary(
-                '/context.ContextService/GetContextIds',
+        self.ListContextIds = channel.unary_unary(
+                '/context.ContextService/ListContextIds',
                 request_serializer=context__pb2.Empty.SerializeToString,
                 response_deserializer=context__pb2.ContextIdList.FromString,
                 )
-        self.GetContexts = channel.unary_unary(
-                '/context.ContextService/GetContexts',
+        self.ListContexts = channel.unary_unary(
+                '/context.ContextService/ListContexts',
                 request_serializer=context__pb2.Empty.SerializeToString,
                 response_deserializer=context__pb2.ContextList.FromString,
                 )
@@ -34,18 +34,23 @@ class ContextServiceStub(object):
                 request_serializer=context__pb2.Context.SerializeToString,
                 response_deserializer=context__pb2.ContextId.FromString,
                 )
-        self.DeleteContext = channel.unary_unary(
-                '/context.ContextService/DeleteContext',
+        self.RemoveContext = channel.unary_unary(
+                '/context.ContextService/RemoveContext',
                 request_serializer=context__pb2.ContextId.SerializeToString,
                 response_deserializer=context__pb2.Empty.FromString,
                 )
-        self.GetTopologyIds = channel.unary_unary(
-                '/context.ContextService/GetTopologyIds',
+        self.GetContextEvents = channel.unary_stream(
+                '/context.ContextService/GetContextEvents',
+                request_serializer=context__pb2.Empty.SerializeToString,
+                response_deserializer=context__pb2.ContextEvent.FromString,
+                )
+        self.ListTopologyIds = channel.unary_unary(
+                '/context.ContextService/ListTopologyIds',
                 request_serializer=context__pb2.ContextId.SerializeToString,
                 response_deserializer=context__pb2.TopologyIdList.FromString,
                 )
-        self.GetTopologies = channel.unary_unary(
-                '/context.ContextService/GetTopologies',
+        self.ListTopologies = channel.unary_unary(
+                '/context.ContextService/ListTopologies',
                 request_serializer=context__pb2.ContextId.SerializeToString,
                 response_deserializer=context__pb2.TopologyList.FromString,
                 )
@@ -59,18 +64,23 @@ class ContextServiceStub(object):
                 request_serializer=context__pb2.Topology.SerializeToString,
                 response_deserializer=context__pb2.TopologyId.FromString,
                 )
-        self.DeleteTopology = channel.unary_unary(
-                '/context.ContextService/DeleteTopology',
+        self.RemoveTopology = channel.unary_unary(
+                '/context.ContextService/RemoveTopology',
                 request_serializer=context__pb2.TopologyId.SerializeToString,
                 response_deserializer=context__pb2.Empty.FromString,
                 )
-        self.GetDeviceIds = channel.unary_unary(
-                '/context.ContextService/GetDeviceIds',
+        self.GetTopologyEvents = channel.unary_stream(
+                '/context.ContextService/GetTopologyEvents',
+                request_serializer=context__pb2.Empty.SerializeToString,
+                response_deserializer=context__pb2.TopologyEvent.FromString,
+                )
+        self.ListDeviceIds = channel.unary_unary(
+                '/context.ContextService/ListDeviceIds',
                 request_serializer=context__pb2.Empty.SerializeToString,
                 response_deserializer=context__pb2.DeviceIdList.FromString,
                 )
-        self.GetDevices = channel.unary_unary(
-                '/context.ContextService/GetDevices',
+        self.ListDevices = channel.unary_unary(
+                '/context.ContextService/ListDevices',
                 request_serializer=context__pb2.Empty.SerializeToString,
                 response_deserializer=context__pb2.DeviceList.FromString,
                 )
@@ -89,13 +99,18 @@ class ContextServiceStub(object):
                 request_serializer=context__pb2.DeviceId.SerializeToString,
                 response_deserializer=context__pb2.Empty.FromString,
                 )
-        self.GetLinkIds = channel.unary_unary(
-                '/context.ContextService/GetLinkIds',
+        self.GetDeviceEvents = channel.unary_stream(
+                '/context.ContextService/GetDeviceEvents',
+                request_serializer=context__pb2.Empty.SerializeToString,
+                response_deserializer=context__pb2.DeviceEvent.FromString,
+                )
+        self.ListLinkIds = channel.unary_unary(
+                '/context.ContextService/ListLinkIds',
                 request_serializer=context__pb2.Empty.SerializeToString,
                 response_deserializer=context__pb2.LinkIdList.FromString,
                 )
-        self.GetLinks = channel.unary_unary(
-                '/context.ContextService/GetLinks',
+        self.ListLinks = channel.unary_unary(
+                '/context.ContextService/ListLinks',
                 request_serializer=context__pb2.Empty.SerializeToString,
                 response_deserializer=context__pb2.LinkList.FromString,
                 )
@@ -109,18 +124,23 @@ class ContextServiceStub(object):
                 request_serializer=context__pb2.Link.SerializeToString,
                 response_deserializer=context__pb2.LinkId.FromString,
                 )
-        self.DeleteLink = channel.unary_unary(
-                '/context.ContextService/DeleteLink',
+        self.RemoveLink = channel.unary_unary(
+                '/context.ContextService/RemoveLink',
                 request_serializer=context__pb2.LinkId.SerializeToString,
                 response_deserializer=context__pb2.Empty.FromString,
                 )
-        self.GetServiceIds = channel.unary_unary(
-                '/context.ContextService/GetServiceIds',
+        self.GetLinkEvents = channel.unary_stream(
+                '/context.ContextService/GetLinkEvents',
+                request_serializer=context__pb2.Empty.SerializeToString,
+                response_deserializer=context__pb2.LinkEvent.FromString,
+                )
+        self.ListServiceIds = channel.unary_unary(
+                '/context.ContextService/ListServiceIds',
                 request_serializer=context__pb2.ContextId.SerializeToString,
                 response_deserializer=context__pb2.ServiceIdList.FromString,
                 )
-        self.GetServices = channel.unary_unary(
-                '/context.ContextService/GetServices',
+        self.ListServices = channel.unary_unary(
+                '/context.ContextService/ListServices',
                 request_serializer=context__pb2.ContextId.SerializeToString,
                 response_deserializer=context__pb2.ServiceList.FromString,
                 )
@@ -134,23 +154,28 @@ class ContextServiceStub(object):
                 request_serializer=context__pb2.Service.SerializeToString,
                 response_deserializer=context__pb2.ServiceId.FromString,
                 )
-        self.DeleteService = channel.unary_unary(
-                '/context.ContextService/DeleteService',
+        self.RemoveService = channel.unary_unary(
+                '/context.ContextService/RemoveService',
                 request_serializer=context__pb2.ServiceId.SerializeToString,
                 response_deserializer=context__pb2.Empty.FromString,
                 )
+        self.GetServiceEvents = channel.unary_stream(
+                '/context.ContextService/GetServiceEvents',
+                request_serializer=context__pb2.Empty.SerializeToString,
+                response_deserializer=context__pb2.ServiceEvent.FromString,
+                )
 
 
 class ContextServiceServicer(object):
     """Missing associated documentation comment in .proto file."""
 
-    def GetContextIds(self, request, context):
+    def ListContextIds(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
-    def GetContexts(self, request, context):
+    def ListContexts(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
@@ -168,19 +193,25 @@ class ContextServiceServicer(object):
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
-    def DeleteContext(self, request, context):
+    def RemoveContext(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def GetContextEvents(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
-    def GetTopologyIds(self, request, context):
+    def ListTopologyIds(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
-    def GetTopologies(self, request, context):
+    def ListTopologies(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
@@ -198,19 +229,25 @@ class ContextServiceServicer(object):
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
-    def DeleteTopology(self, request, context):
+    def RemoveTopology(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
-    def GetDeviceIds(self, request, context):
+    def GetTopologyEvents(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
-    def GetDevices(self, request, context):
+    def ListDeviceIds(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def ListDevices(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
@@ -234,13 +271,19 @@ class ContextServiceServicer(object):
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
-    def GetLinkIds(self, request, context):
+    def GetDeviceEvents(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def ListLinkIds(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
-    def GetLinks(self, request, context):
+    def ListLinks(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
@@ -258,19 +301,25 @@ class ContextServiceServicer(object):
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
-    def DeleteLink(self, request, context):
+    def RemoveLink(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def GetLinkEvents(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
-    def GetServiceIds(self, request, context):
+    def ListServiceIds(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
-    def GetServices(self, request, context):
+    def ListServices(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
@@ -288,7 +337,13 @@ class ContextServiceServicer(object):
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
-    def DeleteService(self, request, context):
+    def RemoveService(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def GetServiceEvents(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
@@ -297,13 +352,13 @@ class ContextServiceServicer(object):
 
 def add_ContextServiceServicer_to_server(servicer, server):
     rpc_method_handlers = {
-            'GetContextIds': grpc.unary_unary_rpc_method_handler(
-                    servicer.GetContextIds,
+            'ListContextIds': grpc.unary_unary_rpc_method_handler(
+                    servicer.ListContextIds,
                     request_deserializer=context__pb2.Empty.FromString,
                     response_serializer=context__pb2.ContextIdList.SerializeToString,
             ),
-            'GetContexts': grpc.unary_unary_rpc_method_handler(
-                    servicer.GetContexts,
+            'ListContexts': grpc.unary_unary_rpc_method_handler(
+                    servicer.ListContexts,
                     request_deserializer=context__pb2.Empty.FromString,
                     response_serializer=context__pb2.ContextList.SerializeToString,
             ),
@@ -317,18 +372,23 @@ def add_ContextServiceServicer_to_server(servicer, server):
                     request_deserializer=context__pb2.Context.FromString,
                     response_serializer=context__pb2.ContextId.SerializeToString,
             ),
-            'DeleteContext': grpc.unary_unary_rpc_method_handler(
-                    servicer.DeleteContext,
+            'RemoveContext': grpc.unary_unary_rpc_method_handler(
+                    servicer.RemoveContext,
                     request_deserializer=context__pb2.ContextId.FromString,
                     response_serializer=context__pb2.Empty.SerializeToString,
             ),
-            'GetTopologyIds': grpc.unary_unary_rpc_method_handler(
-                    servicer.GetTopologyIds,
+            'GetContextEvents': grpc.unary_stream_rpc_method_handler(
+                    servicer.GetContextEvents,
+                    request_deserializer=context__pb2.Empty.FromString,
+                    response_serializer=context__pb2.ContextEvent.SerializeToString,
+            ),
+            'ListTopologyIds': grpc.unary_unary_rpc_method_handler(
+                    servicer.ListTopologyIds,
                     request_deserializer=context__pb2.ContextId.FromString,
                     response_serializer=context__pb2.TopologyIdList.SerializeToString,
             ),
-            'GetTopologies': grpc.unary_unary_rpc_method_handler(
-                    servicer.GetTopologies,
+            'ListTopologies': grpc.unary_unary_rpc_method_handler(
+                    servicer.ListTopologies,
                     request_deserializer=context__pb2.ContextId.FromString,
                     response_serializer=context__pb2.TopologyList.SerializeToString,
             ),
@@ -342,18 +402,23 @@ def add_ContextServiceServicer_to_server(servicer, server):
                     request_deserializer=context__pb2.Topology.FromString,
                     response_serializer=context__pb2.TopologyId.SerializeToString,
             ),
-            'DeleteTopology': grpc.unary_unary_rpc_method_handler(
-                    servicer.DeleteTopology,
+            'RemoveTopology': grpc.unary_unary_rpc_method_handler(
+                    servicer.RemoveTopology,
                     request_deserializer=context__pb2.TopologyId.FromString,
                     response_serializer=context__pb2.Empty.SerializeToString,
             ),
-            'GetDeviceIds': grpc.unary_unary_rpc_method_handler(
-                    servicer.GetDeviceIds,
+            'GetTopologyEvents': grpc.unary_stream_rpc_method_handler(
+                    servicer.GetTopologyEvents,
+                    request_deserializer=context__pb2.Empty.FromString,
+                    response_serializer=context__pb2.TopologyEvent.SerializeToString,
+            ),
+            'ListDeviceIds': grpc.unary_unary_rpc_method_handler(
+                    servicer.ListDeviceIds,
                     request_deserializer=context__pb2.Empty.FromString,
                     response_serializer=context__pb2.DeviceIdList.SerializeToString,
             ),
-            'GetDevices': grpc.unary_unary_rpc_method_handler(
-                    servicer.GetDevices,
+            'ListDevices': grpc.unary_unary_rpc_method_handler(
+                    servicer.ListDevices,
                     request_deserializer=context__pb2.Empty.FromString,
                     response_serializer=context__pb2.DeviceList.SerializeToString,
             ),
@@ -372,13 +437,18 @@ def add_ContextServiceServicer_to_server(servicer, server):
                     request_deserializer=context__pb2.DeviceId.FromString,
                     response_serializer=context__pb2.Empty.SerializeToString,
             ),
-            'GetLinkIds': grpc.unary_unary_rpc_method_handler(
-                    servicer.GetLinkIds,
+            'GetDeviceEvents': grpc.unary_stream_rpc_method_handler(
+                    servicer.GetDeviceEvents,
+                    request_deserializer=context__pb2.Empty.FromString,
+                    response_serializer=context__pb2.DeviceEvent.SerializeToString,
+            ),
+            'ListLinkIds': grpc.unary_unary_rpc_method_handler(
+                    servicer.ListLinkIds,
                     request_deserializer=context__pb2.Empty.FromString,
                     response_serializer=context__pb2.LinkIdList.SerializeToString,
             ),
-            'GetLinks': grpc.unary_unary_rpc_method_handler(
-                    servicer.GetLinks,
+            'ListLinks': grpc.unary_unary_rpc_method_handler(
+                    servicer.ListLinks,
                     request_deserializer=context__pb2.Empty.FromString,
                     response_serializer=context__pb2.LinkList.SerializeToString,
             ),
@@ -392,18 +462,23 @@ def add_ContextServiceServicer_to_server(servicer, server):
                     request_deserializer=context__pb2.Link.FromString,
                     response_serializer=context__pb2.LinkId.SerializeToString,
             ),
-            'DeleteLink': grpc.unary_unary_rpc_method_handler(
-                    servicer.DeleteLink,
+            'RemoveLink': grpc.unary_unary_rpc_method_handler(
+                    servicer.RemoveLink,
                     request_deserializer=context__pb2.LinkId.FromString,
                     response_serializer=context__pb2.Empty.SerializeToString,
             ),
-            'GetServiceIds': grpc.unary_unary_rpc_method_handler(
-                    servicer.GetServiceIds,
+            'GetLinkEvents': grpc.unary_stream_rpc_method_handler(
+                    servicer.GetLinkEvents,
+                    request_deserializer=context__pb2.Empty.FromString,
+                    response_serializer=context__pb2.LinkEvent.SerializeToString,
+            ),
+            'ListServiceIds': grpc.unary_unary_rpc_method_handler(
+                    servicer.ListServiceIds,
                     request_deserializer=context__pb2.ContextId.FromString,
                     response_serializer=context__pb2.ServiceIdList.SerializeToString,
             ),
-            'GetServices': grpc.unary_unary_rpc_method_handler(
-                    servicer.GetServices,
+            'ListServices': grpc.unary_unary_rpc_method_handler(
+                    servicer.ListServices,
                     request_deserializer=context__pb2.ContextId.FromString,
                     response_serializer=context__pb2.ServiceList.SerializeToString,
             ),
@@ -417,11 +492,16 @@ def add_ContextServiceServicer_to_server(servicer, server):
                     request_deserializer=context__pb2.Service.FromString,
                     response_serializer=context__pb2.ServiceId.SerializeToString,
             ),
-            'DeleteService': grpc.unary_unary_rpc_method_handler(
-                    servicer.DeleteService,
+            'RemoveService': grpc.unary_unary_rpc_method_handler(
+                    servicer.RemoveService,
                     request_deserializer=context__pb2.ServiceId.FromString,
                     response_serializer=context__pb2.Empty.SerializeToString,
             ),
+            'GetServiceEvents': grpc.unary_stream_rpc_method_handler(
+                    servicer.GetServiceEvents,
+                    request_deserializer=context__pb2.Empty.FromString,
+                    response_serializer=context__pb2.ServiceEvent.SerializeToString,
+            ),
     }
     generic_handler = grpc.method_handlers_generic_handler(
             'context.ContextService', rpc_method_handlers)
@@ -433,7 +513,7 @@ class ContextService(object):
     """Missing associated documentation comment in .proto file."""
 
     @staticmethod
-    def GetContextIds(request,
+    def ListContextIds(request,
             target,
             options=(),
             channel_credentials=None,
@@ -443,14 +523,14 @@ class ContextService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/context.ContextService/GetContextIds',
+        return grpc.experimental.unary_unary(request, target, '/context.ContextService/ListContextIds',
             context__pb2.Empty.SerializeToString,
             context__pb2.ContextIdList.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
     @staticmethod
-    def GetContexts(request,
+    def ListContexts(request,
             target,
             options=(),
             channel_credentials=None,
@@ -460,7 +540,7 @@ class ContextService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/context.ContextService/GetContexts',
+        return grpc.experimental.unary_unary(request, target, '/context.ContextService/ListContexts',
             context__pb2.Empty.SerializeToString,
             context__pb2.ContextList.FromString,
             options, channel_credentials,
@@ -501,7 +581,7 @@ class ContextService(object):
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
     @staticmethod
-    def DeleteContext(request,
+    def RemoveContext(request,
             target,
             options=(),
             channel_credentials=None,
@@ -511,14 +591,14 @@ class ContextService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/context.ContextService/DeleteContext',
+        return grpc.experimental.unary_unary(request, target, '/context.ContextService/RemoveContext',
             context__pb2.ContextId.SerializeToString,
             context__pb2.Empty.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
     @staticmethod
-    def GetTopologyIds(request,
+    def GetContextEvents(request,
             target,
             options=(),
             channel_credentials=None,
@@ -528,14 +608,31 @@ class ContextService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/context.ContextService/GetTopologyIds',
+        return grpc.experimental.unary_stream(request, target, '/context.ContextService/GetContextEvents',
+            context__pb2.Empty.SerializeToString,
+            context__pb2.ContextEvent.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def ListTopologyIds(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/context.ContextService/ListTopologyIds',
             context__pb2.ContextId.SerializeToString,
             context__pb2.TopologyIdList.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
     @staticmethod
-    def GetTopologies(request,
+    def ListTopologies(request,
             target,
             options=(),
             channel_credentials=None,
@@ -545,7 +642,7 @@ class ContextService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/context.ContextService/GetTopologies',
+        return grpc.experimental.unary_unary(request, target, '/context.ContextService/ListTopologies',
             context__pb2.ContextId.SerializeToString,
             context__pb2.TopologyList.FromString,
             options, channel_credentials,
@@ -586,7 +683,7 @@ class ContextService(object):
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
     @staticmethod
-    def DeleteTopology(request,
+    def RemoveTopology(request,
             target,
             options=(),
             channel_credentials=None,
@@ -596,14 +693,31 @@ class ContextService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/context.ContextService/DeleteTopology',
+        return grpc.experimental.unary_unary(request, target, '/context.ContextService/RemoveTopology',
             context__pb2.TopologyId.SerializeToString,
             context__pb2.Empty.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
     @staticmethod
-    def GetDeviceIds(request,
+    def GetTopologyEvents(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_stream(request, target, '/context.ContextService/GetTopologyEvents',
+            context__pb2.Empty.SerializeToString,
+            context__pb2.TopologyEvent.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def ListDeviceIds(request,
             target,
             options=(),
             channel_credentials=None,
@@ -613,14 +727,14 @@ class ContextService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/context.ContextService/GetDeviceIds',
+        return grpc.experimental.unary_unary(request, target, '/context.ContextService/ListDeviceIds',
             context__pb2.Empty.SerializeToString,
             context__pb2.DeviceIdList.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
     @staticmethod
-    def GetDevices(request,
+    def ListDevices(request,
             target,
             options=(),
             channel_credentials=None,
@@ -630,7 +744,7 @@ class ContextService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/context.ContextService/GetDevices',
+        return grpc.experimental.unary_unary(request, target, '/context.ContextService/ListDevices',
             context__pb2.Empty.SerializeToString,
             context__pb2.DeviceList.FromString,
             options, channel_credentials,
@@ -688,7 +802,24 @@ class ContextService(object):
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
     @staticmethod
-    def GetLinkIds(request,
+    def GetDeviceEvents(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_stream(request, target, '/context.ContextService/GetDeviceEvents',
+            context__pb2.Empty.SerializeToString,
+            context__pb2.DeviceEvent.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def ListLinkIds(request,
             target,
             options=(),
             channel_credentials=None,
@@ -698,14 +829,14 @@ class ContextService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/context.ContextService/GetLinkIds',
+        return grpc.experimental.unary_unary(request, target, '/context.ContextService/ListLinkIds',
             context__pb2.Empty.SerializeToString,
             context__pb2.LinkIdList.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
     @staticmethod
-    def GetLinks(request,
+    def ListLinks(request,
             target,
             options=(),
             channel_credentials=None,
@@ -715,7 +846,7 @@ class ContextService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/context.ContextService/GetLinks',
+        return grpc.experimental.unary_unary(request, target, '/context.ContextService/ListLinks',
             context__pb2.Empty.SerializeToString,
             context__pb2.LinkList.FromString,
             options, channel_credentials,
@@ -756,7 +887,7 @@ class ContextService(object):
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
     @staticmethod
-    def DeleteLink(request,
+    def RemoveLink(request,
             target,
             options=(),
             channel_credentials=None,
@@ -766,14 +897,14 @@ class ContextService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/context.ContextService/DeleteLink',
+        return grpc.experimental.unary_unary(request, target, '/context.ContextService/RemoveLink',
             context__pb2.LinkId.SerializeToString,
             context__pb2.Empty.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
     @staticmethod
-    def GetServiceIds(request,
+    def GetLinkEvents(request,
             target,
             options=(),
             channel_credentials=None,
@@ -783,14 +914,31 @@ class ContextService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/context.ContextService/GetServiceIds',
+        return grpc.experimental.unary_stream(request, target, '/context.ContextService/GetLinkEvents',
+            context__pb2.Empty.SerializeToString,
+            context__pb2.LinkEvent.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def ListServiceIds(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/context.ContextService/ListServiceIds',
             context__pb2.ContextId.SerializeToString,
             context__pb2.ServiceIdList.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
     @staticmethod
-    def GetServices(request,
+    def ListServices(request,
             target,
             options=(),
             channel_credentials=None,
@@ -800,7 +948,7 @@ class ContextService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/context.ContextService/GetServices',
+        return grpc.experimental.unary_unary(request, target, '/context.ContextService/ListServices',
             context__pb2.ContextId.SerializeToString,
             context__pb2.ServiceList.FromString,
             options, channel_credentials,
@@ -841,7 +989,7 @@ class ContextService(object):
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
     @staticmethod
-    def DeleteService(request,
+    def RemoveService(request,
             target,
             options=(),
             channel_credentials=None,
@@ -851,8 +999,25 @@ class ContextService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/context.ContextService/DeleteService',
+        return grpc.experimental.unary_unary(request, target, '/context.ContextService/RemoveService',
             context__pb2.ServiceId.SerializeToString,
             context__pb2.Empty.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def GetServiceEvents(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_stream(request, target, '/context.ContextService/GetServiceEvents',
+            context__pb2.Empty.SerializeToString,
+            context__pb2.ServiceEvent.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/src/context/service/database/Database.py b/src/context/service/database/Database.py
index eb0117d1a0bfae4217be3a76467ed6e44552ecb7..e276f89bc6688f41db314cbd74d4ac9328bb59c0 100644
--- a/src/context/service/database/Database.py
+++ b/src/context/service/database/Database.py
@@ -3,9 +3,8 @@ from typing import Optional, Union
 from ._engine._Database import _Database
 from ._engine.Factory import BackendEnum, get_database_backend
 from ._engine.object.Collection import Collection
-
-#from .context.Context import Context
-#from .context.Keys import KEY_CONTEXTS
+from .objects._Keys import KEY_CONTEXTS
+from .objects.Context import Context
 
 LOGGER = logging.getLogger(__name__)
 
diff --git a/src/context/service/database/_engine/object/Attributes.py b/src/context/service/database/_engine/object/Attributes.py
deleted file mode 100644
index 91e9e29923ec0e908fb4a470eb94578939b00479..0000000000000000000000000000000000000000
--- a/src/context/service/database/_engine/object/Attributes.py
+++ /dev/null
@@ -1,71 +0,0 @@
-from __future__ import annotations
-import copy
-from typing import Any, Callable, Dict, List, Set
-from ..backend._Backend import _Backend
-from ._Object import _Object
-from .Tools import format_key
-
-class Attributes:
-    def __init__(
-        self, parent : _Object, key_pattern : str, validators : Dict[str, Callable[[Any], bool]],
-        transcoders : Dict[str, Dict[Any, Callable[[Any], Any]]] = {}):
-
-        if not issubclass(parent, _Object):
-            str_class_path = '{}.{}'.format(_Object.__module__, _Object.__name__)
-            raise AttributeError('parent must inherit from {}'.format(str_class_path))
-        if (not isinstance(key_pattern, str)) or (len(key_pattern) == 0):
-            raise AttributeError('key_pattern must be a non-empty instance of str')
-        if not isinstance(validators, dict):
-            raise AttributeError('validators must be an instance of dict')
-        # TODO: implement validation of entries in validators
-        if not isinstance(transcoders, dict):
-            raise AttributeError('transcoders must be an instance of dict')
-        # TODO: implement validation of entries in transcoders
-
-        self._parent = parent
-        self._backend : _Backend = self._parent.backend
-        self._key = format_key(key_pattern, self._parent)
-        self._validators = validators
-        self._transcoders = transcoders
-
-    def validate(self, update_attributes : Dict[str, Any], remove_attributes : Set[str], attribute_name : str) -> None:
-        remove_attributes.discard(attribute_name)
-        value = update_attributes.pop(attribute_name, None)
-        if value is None: return
-        validator = self._validators.get(attribute_name)
-        if validator is None: return
-        if not validator(value): raise AttributeError('{} is invalid'.format(attribute_name))
-
-    def transcode(self, attribute_name : str, attribute_value : Any) -> Any:
-        transcoder_set = self._transcoders.get(attribute_name, {})
-        transcoder = transcoder_set.get(type(attribute_value))
-        return attribute_value if transcoder is None else transcoder(attribute_value)
-
-    def get(self, attributes : List[str] = []) -> Dict[str, Any]:
-        return {
-            k:self.transcode(k, v)
-            for k,v in self._backend.dict_get(self._key, fields=attributes).items()
-        }
-
-    def update(self, update_attributes : Dict[str, Any] = {}, remove_attributes : List[str] = []) -> 'Attributes':
-        remove_attributes = set(remove_attributes)
-        copy_update_attributes = copy.deepcopy(update_attributes)
-        copy_remove_attributes = copy.deepcopy(remove_attributes)
-
-        for attribute_name in self._validators.keys():
-            self.validate(copy_update_attributes, copy_remove_attributes, attribute_name)
-            attribute_value = update_attributes.get(attribute_name)
-            if attribute_value is None: continue
-            update_attributes[attribute_name] = self.transcode(attribute_name, attribute_value)
-
-        if len(copy_update_attributes) > 0:
-            raise AttributeError('Unexpected update_attributes: {}'.format(str(copy_update_attributes)))
-
-        if len(copy_remove_attributes) > 0:
-            raise AttributeError('Unexpected remove_attributes: {}'.format(str(copy_remove_attributes)))
-
-        self._backend.dict_update(self._key, update_attributes, remove_attributes)
-        return self
-
-    def delete(self, attributes : List[str] = []) -> None:
-        self._backend.dict_delete(self._key, attributes)
diff --git a/src/context/service/database/_engine/object/_Object.py b/src/context/service/database/_engine/object/_Object.py
deleted file mode 100644
index 667f149a290a656f0d1f6b9851b8b04799ed321e..0000000000000000000000000000000000000000
--- a/src/context/service/database/_engine/object/_Object.py
+++ /dev/null
@@ -1,30 +0,0 @@
-from typing import Dict
-from ..backend._Backend import _Backend
-
-class _Object:
-    def __init__(self, parent, object_uuid : str):
-        if not issubclass(parent, _Object):
-            str_class_path = '{}.{}'.format(_Object.__module__, _Object.__name__)
-            raise AttributeError('parent must inherit from {}'.format(str_class_path))
-        if (not isinstance(object_uuid, str)) or (len(object_uuid) == 0):
-            raise AttributeError('object_uuid must be a non-empty instance of str')
-        self._object_uuid = object_uuid
-        self._parent = parent
-
-    @property
-    def parent(self) -> '_Object': return self._parent
-
-    @property
-    def backend(self) -> _Backend: return self._parent.backend
-
-    def create(self) -> None:
-        raise NotImplementedError()
-
-    def delete(self) -> None:
-        raise NotImplementedError()
-
-    def dump_id(self) -> Dict:
-        raise NotImplementedError()
-
-    def dump(self) -> Dict:
-        raise NotImplementedError()
diff --git a/src/context/service/database/_engine/object/_ObjectWithAttributes.py b/src/context/service/database/_engine/object/_ObjectWithAttributes.py
deleted file mode 100644
index 4eb851ff036f2c9193475e4577927042b4e0bd83..0000000000000000000000000000000000000000
--- a/src/context/service/database/_engine/object/_ObjectWithAttributes.py
+++ /dev/null
@@ -1,14 +0,0 @@
-from typing import Any, Callable, Dict
-from ._Object import _Object
-from .Attributes import Attributes
-
-class _ObjectWithAttributes(_Object):
-    def __init__(
-        self, parent, object_uuid: str, key_pattern : str, validators : Dict[str, Callable[[Any], bool]],
-        transcoders : Dict[str, Dict[Any, Callable[[Any], Any]]] = {}) -> None:
-
-        super().__init__(parent, object_uuid)
-        self._attributes = Attributes(parent, key_pattern, validators, transcoders=transcoders)
-
-    @property
-    def attributes(self) -> Attributes: return self._attributes
diff --git a/src/context/service/database/objects/Context.py b/src/context/service/database/objects/Context.py
index 54bef2a45071ea2661b43f81bd875dc1aa99ec2a..5e9daf0b03235a0bc3cdee5b5a3b253d71d52feb 100644
--- a/src/context/service/database/objects/Context.py
+++ b/src/context/service/database/objects/Context.py
@@ -1,9 +1,11 @@
+from __future__ import annotations
 from typing import TYPE_CHECKING, Dict, List
-from ..entity._Entity import _Entity
-from ..entity.EntityCollection import EntityCollection
-from .service.Service import Service
-from .topology.Topology import Topology
-from .Keys import KEY_CONTEXT, KEY_SERVICES, KEY_TOPOLOGIES
+from .._engine.object._Object import _Object
+from .._engine.object.Attributes import Attributes
+from .._engine.object.Collection import Collection
+from ._Keys import KEY_CONTEXT, KEY_SERVICES, KEY_TOPOLOGIES
+from .Service import Service
+from .Topology import Topology
 
 if TYPE_CHECKING:
     from ..Database import Database
@@ -11,11 +13,12 @@ if TYPE_CHECKING:
 VALIDATORS = {}  # no attributes accepted
 TRANSCODERS = {} # no transcoding applied to attributes
 
-class Context(_Entity):
+class Context(_Object):
     def __init__(self, context_uuid : str, parent : 'Database'):
-        super().__init__(parent, context_uuid, KEY_CONTEXT, VALIDATORS, TRANSCODERS)
-        self._topologies = EntityCollection(self, KEY_TOPOLOGIES)
-        self._services = EntityCollection(self, KEY_SERVICES)
+        super().__init__(parent, context_uuid)
+        self._attributes = Attributes(parent, KEY_CONTEXT, VALIDATORS, TRANSCODERS)
+        self._services = Collection(self, KEY_SERVICES)
+        self._topologies = Collection(self, KEY_TOPOLOGIES)
 
     @property
     def parent(self) -> 'Database': return self._parent
@@ -24,46 +27,46 @@ class Context(_Entity):
     def context(self) -> 'Context': return self
 
     @property
-    def context_uuid(self) -> str: return self._entity_uuid
+    def context_uuid(self) -> str: return self._object_uuid
 
     @property
-    def topologies(self) -> EntityCollection: return self._topologies
+    def attributes(self) -> Attributes: return self._attributes
 
     @property
-    def services(self) -> EntityCollection: return self._services
+    def services(self) -> Collection: return self._services
 
-    def topology(self, topology_uuid : str) -> Topology: return Topology(topology_uuid, self)
+    @property
+    def topologies(self) -> Collection: return self._topologies
 
     def service(self, service_uuid : str) -> Service: return Service(service_uuid, self)
 
+    def topology(self, topology_uuid : str) -> Topology: return Topology(topology_uuid, self)
+
     def create(self) -> 'Context':
         self.parent.contexts.add(self.context_uuid)
         return self
 
+    def update(self, update_attributes={}, remove_attributes=[]) -> 'Context':
+        self.attributes.update(update_attributes=update_attributes, remove_attributes=remove_attributes)
+        return self
+
     def delete(self):
         for service_uuid in self.services.get(): self.service(service_uuid).delete()
         for topology_uuid in self.topologies.get(): self.topology(topology_uuid).delete()
-        self.parent.contexts.delete(self.context_uuid)
         self.attributes.delete()
+        self.parent.contexts.delete(self.context_uuid)
 
     def dump_id(self) -> Dict:
-        return {
-            'contextUuid': {'uuid': self.context_uuid},
-        }
-
-    def dump_topologies(self) -> List:
-        return [
-            self.topology(topology_uuid).dump() for topology_uuid in self.topologies.get()
-        ]
-
-    def dump_services(self) -> List:
-        return [
-            self.service(service_uuid).dump() for service_uuid in self.services.get()
-        ]
-
-    def dump(self) -> Dict:
-        return {
-            'contextId': self.dump_id(),
-            'topologies': self.dump_topologies(),
-            'services': self.dump_services(),
-        }
+        return {'context_uuid': {'uuid': self.context_uuid}}
+
+    def dump_services(self) -> List[Dict]:
+        return [self.service(service_uuid).dump() for service_uuid in self.services.get()]
+
+    def dump_topologies(self) -> List[Dict]:
+        return [self.topology(topology_uuid).dump() for topology_uuid in self.topologies.get()]
+
+    def dump(self, include_services=True, include_topologies=True) -> Dict:
+        result = {'context_id': self.dump_id()}
+        if include_services: result['services'] = self.dump_services()
+        if include_topologies: result['topologies'] = self.dump_topologies()
+        return result
diff --git a/src/context/service/database/objects/Device.py b/src/context/service/database/objects/Device.py
index 1b68e271935467a81e8f577b82f2d7c26dca69b2..e455bd8b60b3e5f09ea55f537ed164762966322f 100644
--- a/src/context/service/database/objects/Device.py
+++ b/src/context/service/database/objects/Device.py
@@ -1,33 +1,36 @@
 from __future__ import annotations
-from typing import TYPE_CHECKING, Dict
-from ....entity._Entity import _Entity
-from ....entity.EntityCollection import EntityCollection
-from ...Keys import KEY_DEVICE, KEY_DEVICE_ENDPOINTS
+from typing import TYPE_CHECKING, Dict, List
+from .._engine.object._Object import _Object
+from .._engine.object.Attributes import Attributes
+from .._engine.object.Collection import Collection
+from ._Keys import KEY_DEVICE, KEY_DEVICE_DRIVERS, KEY_DEVICE_ENDPOINTS
+from .DeviceOperationalStatus import DeviceOperationalStatus, to_deviceoperationalstatus_enum
 from .Endpoint import Endpoint
-from .OperationalStatus import OperationalStatus, to_operationalstatus_enum
 
 if TYPE_CHECKING:
-    from ...Context import Context
-    from ..Topology import Topology
+    from .Context import Context
+    from .Topology import Topology
 
 VALIDATORS = {
     'device_type': lambda v: v is not None and isinstance(v, str) and (len(v) > 0),
     'device_config': lambda v: v is not None and isinstance(v, str) and (len(v) > 0),
-    'device_operational_status': lambda v: v is not None and isinstance(v, OperationalStatus),
+    'device_operational_status': lambda v: v is not None and isinstance(v, DeviceOperationalStatus),
 }
 
 TRANSCODERS = {
     'device_operational_status': {
-        OperationalStatus: lambda v: v.value,
-        int              : lambda v: to_operationalstatus_enum(v),
-        str              : lambda v: to_operationalstatus_enum(v),
+        DeviceOperationalStatus: lambda v: v.value,
+        int                    : lambda v: to_deviceoperationalstatus_enum(v),
+        str                    : lambda v: to_deviceoperationalstatus_enum(v),
     }
 }
 
-class Device(_Entity):
+class Device(_Object):
     def __init__(self, device_uuid : str, parent : 'Topology'):
-        super().__init__(parent, device_uuid, KEY_DEVICE, VALIDATORS, TRANSCODERS)
-        self._endpoints = EntityCollection(self, KEY_DEVICE_ENDPOINTS)
+        super().__init__(parent, device_uuid)
+        self._attributes = Attributes(parent, KEY_DEVICE, VALIDATORS, TRANSCODERS)
+        self._drivers = Collection(self, KEY_DEVICE_DRIVERS)
+        self._endpoints = Collection(self, KEY_DEVICE_ENDPOINTS)
 
     @property
     def parent(self) -> 'Topology': return self._parent
@@ -45,14 +48,22 @@ class Device(_Entity):
     def topology_uuid(self) -> str: return self.parent.topology_uuid
 
     @property
-    def device_uuid(self) -> str: return self._entity_uuid
+    def device_uuid(self) -> str: return self._object_uuid
 
     @property
-    def endpoints(self) -> EntityCollection: return self._endpoints
+    def attributes(self) -> Attributes: return self._attributes
+
+    @property
+    def drivers(self) -> Collection: return self._drivers
+
+    @property
+    def endpoints(self) -> Collection: return self._endpoints
 
     def endpoint(self, endpoint_uuid : str) -> Endpoint: return Endpoint(endpoint_uuid, self)
 
-    def create(self, device_type : str, device_config : str, device_operational_status : OperationalStatus) -> 'Device':
+    def create(
+        self, device_type : str, device_config : str, device_operational_status : DeviceOperationalStatus) -> 'Device':
+
         self.update(update_attributes={
             'device_type': device_type,
             'device_config': device_config,
@@ -67,23 +78,30 @@ class Device(_Entity):
 
     def delete(self) -> None:
         for endpoint_uuid in self.endpoints.get(): self.endpoint(endpoint_uuid).delete()
+        self.drivers.clear()
         self.attributes.delete()
         self.parent.devices.delete(self.device_uuid)
 
     def dump_id(self) -> Dict:
-        return {
-            'device_id': {'uuid': self.device_uuid},
-        }
+        return {'device_uuid': {'uuid': self.device_uuid}}
+
+    def dump_drivers(self) -> List[str]:
+        return self.drivers.get()
 
-    def dump(self) -> Dict:
+    def dump_endpoints(self) -> List[Dict]:
+        return [self.endpoint(endpoint_uuid).dump() for endpoint_uuid in self.endpoints.get()]
+
+    def dump(self, include_drivers=True, include_endpoints=True) -> Dict:
         attributes = self.attributes.get()
-        dev_op_status = attributes.get('device_operational_status', None)
-        if isinstance(dev_op_status, OperationalStatus): dev_op_status = dev_op_status.value
-        endpoints = [self.endpoint(endpoint_uuid).dump() for endpoint_uuid in self.endpoints.get()]
-        return {
+        device_operational_status = attributes.get('device_operational_status', None)
+        if isinstance(device_operational_status, DeviceOperationalStatus):
+            device_operational_status = device_operational_status.value
+        result = {
             'device_id': self.dump_id(),
             'device_type': attributes.get('device_type', None),
             'device_config': {'device_config': attributes.get('device_config', None)},
-            'devOperationalStatus': dev_op_status,
-            'endpointList': endpoints
+            'device_operational_status': device_operational_status,
         }
+        if include_drivers: result['device_drivers'] = self.dump_drivers()
+        if include_endpoints: result['endpoints'] = self.dump_endpoints()
+        return result
diff --git a/src/context/service/database/objects/DeviceOperationalStatus.py b/src/context/service/database/objects/DeviceOperationalStatus.py
new file mode 100644
index 0000000000000000000000000000000000000000..dc95e97fd6a2acefdbb094a4e2d2df6cd379d1ce
--- /dev/null
+++ b/src/context/service/database/objects/DeviceOperationalStatus.py
@@ -0,0 +1,27 @@
+from enum import Enum
+
+class DeviceOperationalStatus(Enum):
+    UNDEFINED = 0
+    DISABLED = 1
+    ENABLED = 2
+
+ANY_TO_ENUM = {
+    0: DeviceOperationalStatus.UNDEFINED,
+    1: DeviceOperationalStatus.DISABLED,
+    2: DeviceOperationalStatus.ENABLED,
+
+    '0': DeviceOperationalStatus.UNDEFINED,
+    '1': DeviceOperationalStatus.DISABLED,
+    '2': DeviceOperationalStatus.ENABLED,
+
+    'UNDEFINED': DeviceOperationalStatus.UNDEFINED,
+    'DISABLED': DeviceOperationalStatus.DISABLED,
+    'ENABLED': DeviceOperationalStatus.ENABLED,
+}
+
+def deviceoperationalstatus_enum_values():
+    return {m.value for m in DeviceOperationalStatus.__members__.values()}
+
+def to_deviceoperationalstatus_enum(int_or_str):
+    if isinstance(int_or_str, str): int_or_str = int_or_str.upper()
+    return ANY_TO_ENUM.get(int_or_str)
diff --git a/src/context/service/database/objects/Endpoint.py b/src/context/service/database/objects/Endpoint.py
index bc36a93f2d24bdbc967b4bb3171a6de10a4989df..d647a9e2699dc38d0c06db3f5b6eac65eeca5088 100644
--- a/src/context/service/database/objects/Endpoint.py
+++ b/src/context/service/database/objects/Endpoint.py
@@ -1,11 +1,12 @@
 from __future__ import annotations
-from typing import TYPE_CHECKING, Dict
-from ....entity._Entity import _Entity
-from ...Keys import KEY_DEVICE_ENDPOINT
+from typing import TYPE_CHECKING, Dict, List
+from .._engine.object._Object import _Object
+from .._engine.object.Attributes import Attributes
+from ._Keys import KEY_DEVICE_ENDPOINT
 
 if TYPE_CHECKING:
-    from ...Context import Context
-    from ..Topology import Topology
+    from .Context import Context
+    from .Topology import Topology
     from .Device import Device
 
 VALIDATORS = {
@@ -14,9 +15,10 @@ VALIDATORS = {
 
 TRANSCODERS = {} # no transcoding applied to attributes
 
-class Endpoint(_Entity):
+class Endpoint(_Object):
     def __init__(self, endpoint_uuid : str, parent : 'Device'):
-        super().__init__(parent, endpoint_uuid, KEY_DEVICE_ENDPOINT, VALIDATORS, TRANSCODERS)
+        super().__init__(parent, endpoint_uuid)
+        self._attributes = Attributes(parent, KEY_DEVICE_ENDPOINT, VALIDATORS, TRANSCODERS)
 
     @property
     def parent(self) -> 'Device': return self._parent
@@ -40,7 +42,10 @@ class Endpoint(_Entity):
     def device_uuid(self) -> str: return self.parent.device_uuid
 
     @property
-    def endpoint_uuid(self) -> str: return self._entity_uuid
+    def endpoint_uuid(self) -> str: return self._object_uuid
+
+    @property
+    def attributes(self) -> Attributes: return self._attributes
 
     def create(self, port_type : str) -> 'Endpoint':
         self.update(update_attributes={
@@ -59,14 +64,14 @@ class Endpoint(_Entity):
 
     def dump_id(self) -> Dict:
         return {
-            'topoId': self.topology.dump_id(),
-            'dev_id': self.device.dump_id(),
-            'port_id': {'uuid': self.endpoint_uuid},
+            'topology_id': self.topology.dump_id(),
+            'device_id': self.device.dump_id(),
+            'endpoint_uuid': {'uuid': self.endpoint_uuid},
         }
 
     def dump(self) -> Dict:
         attributes = self.attributes.get()
         return {
-            'port_id': self.dump_id(),
+            'endpoint_id': self.dump_id(),
             'port_type': attributes.get('port_type', None),
         }
diff --git a/src/context/service/database/objects/Link.py b/src/context/service/database/objects/Link.py
index 3c7976d5985cad8e058d415e1019de29a3850f58..6e49ec62e60ffd2e50a5421abc1a13cafa5562f5 100644
--- a/src/context/service/database/objects/Link.py
+++ b/src/context/service/database/objects/Link.py
@@ -1,21 +1,22 @@
 from __future__ import annotations
-from typing import TYPE_CHECKING, Dict
-from ....entity._Entity import _Entity
-from ....entity.EntityCollection import EntityCollection
-from ...Keys import KEY_LINK, KEY_LINK_ENDPOINTS
-from .Endpoint import Endpoint
+from typing import TYPE_CHECKING, Dict, List
+from .._engine.object._Object import _Object
+from .._engine.object.Attributes import Attributes
+from .._engine.object.Collection import Collection
+from ._Keys import KEY_LINK #, KEY_LINK_ENDPOINTS
 
 if TYPE_CHECKING:
-    from ...Context import Context
-    from ..Topology import Topology
+    from .Context import Context
+    from .Topology import Topology
 
 VALIDATORS = {}  # no attributes accepted
 TRANSCODERS = {} # no transcoding applied to attributes
 
-class Link(_Entity):
+class Link(_Object):
     def __init__(self, link_uuid : str, parent : 'Topology'):
-        super().__init__(parent, link_uuid, KEY_LINK, VALIDATORS, TRANSCODERS)
-        self._endpoints = EntityCollection(self, KEY_LINK_ENDPOINTS)
+        super().__init__(parent, link_uuid)
+        self._attributes = Attributes(parent, KEY_LINK, VALIDATORS, TRANSCODERS)
+        self._endpoints = Collection(self, KEY_LINK_ENDPOINTS)
 
     @property
     def parent(self) -> 'Topology': return self._parent
@@ -33,10 +34,13 @@ class Link(_Entity):
     def topology_uuid(self) -> str: return self.parent.topology_uuid
 
     @property
-    def link_uuid(self) -> str: return self._entity_uuid
+    def link_uuid(self) -> str: return self._object_uuid
 
     @property
-    def endpoints(self) -> EntityCollection: return self._endpoints
+    def attributes(self) -> Attributes: return self._attributes
+
+    @property
+    def endpoints(self) -> Collection: return self._endpoints
 
     def endpoint(self, link_endpoint_uuid : str) -> Endpoint: return Endpoint(link_endpoint_uuid, self)
 
@@ -44,19 +48,22 @@ class Link(_Entity):
         self.parent.links.add(self.link_uuid)
         return self
 
+    def update(self, update_attributes={}, remove_attributes=[]) -> 'Link':
+        self.attributes.update(update_attributes=update_attributes, remove_attributes=remove_attributes)
+        return self
+
     def delete(self) -> None:
         for endpoint_uuid in self.endpoints.get(): self.endpoint(endpoint_uuid).delete()
         self.attributes.delete()
         self.parent.links.delete(self.link_uuid)
 
     def dump_id(self) -> Dict:
-        return {
-            'link_id': {'uuid': self.link_uuid},
-        }
-
-    def dump(self) -> Dict:
-        endpoints = [self.endpoint(link_endpoint_uuid).dump() for link_endpoint_uuid in self.endpoints.get()]
-        return {
-            'link_id': self.dump_id(),
-            'endpointList': endpoints
-        }
+        return {'link_uuid': {'uuid': self.link_uuid}}
+
+    def dump_endpoints(self) -> List[Dict]:
+        return [self.endpoint(endpoint_uuid).dump() for endpoint_uuid in self.endpoints.get()]
+
+    def dump(self, include_endpoints=True) -> Dict:
+        result = {'link_id': self.dump_id()}
+        if include_endpoints: result['endpoints'] = self.dump_endpoints()
+        return result
diff --git a/src/context/service/database/objects/OperationalStatus.py b/src/context/service/database/objects/OperationalStatus.py
deleted file mode 100644
index c726b32ef5b03feb8c0a04a586cf7ef4cd250263..0000000000000000000000000000000000000000
--- a/src/context/service/database/objects/OperationalStatus.py
+++ /dev/null
@@ -1,27 +0,0 @@
-from enum import Enum
-
-class OperationalStatus(Enum):
-    KEEP_STATE = 0  # Do not change operational status of device (used in configure)
-    DISABLED = -1
-    ENABLED = 1
-
-ANY_TO_ENUM = {
-     1: OperationalStatus.ENABLED,
-     0: OperationalStatus.KEEP_STATE,
-    -1: OperationalStatus.DISABLED,
-
-     '1': OperationalStatus.ENABLED,
-     '0': OperationalStatus.KEEP_STATE,
-    '-1': OperationalStatus.DISABLED,
-
-    'enabled': OperationalStatus.ENABLED,
-    'disabled': OperationalStatus.DISABLED,
-    'keep_state': OperationalStatus.KEEP_STATE,
-}
-
-def operationalstatus_enum_values():
-    return {m.value for m in OperationalStatus.__members__.values()}
-
-def to_operationalstatus_enum(int_or_str):
-    if isinstance(int_or_str, str): int_or_str = int_or_str.lower()
-    return ANY_TO_ENUM.get(int_or_str)
diff --git a/src/context/service/database/objects/Service.py b/src/context/service/database/objects/Service.py
index 0b5e69fce53992a392aa626856a1cb6b0ae33575..96ba3efc35869b4eac937556a628d8a33407576d 100644
--- a/src/context/service/database/objects/Service.py
+++ b/src/context/service/database/objects/Service.py
@@ -1,15 +1,16 @@
 from __future__ import annotations
 from typing import TYPE_CHECKING, Dict
-from ...entity._Entity import _Entity
-from ...entity.EntityCollection import EntityCollection
-from ..Keys import KEY_SERVICE, KEY_SERVICE_CONSTRAINTS, KEY_SERVICE_ENDPOINTS
+from .._engine.object._Object import _Object
+from .._engine.object.Attributes import Attributes
+from .._engine.object.Collection import Collection
+from ._Keys import KEY_SERVICE, KEY_SERVICE_CONSTRAINTS, KEY_SERVICE_ENDPOINTS
 from .Constraint import Constraint
 from .Endpoint import Endpoint
 from .ServiceState import ServiceState, to_servicestate_enum
 from .ServiceType import ServiceType, to_servicetype_enum
 
 if TYPE_CHECKING:
-    from ..Context import Context
+    from .Context import Context
 
 VALIDATORS = {
     'service_type': lambda v: v is not None and isinstance(v, ServiceType),
@@ -30,11 +31,12 @@ TRANSCODERS = {
     },
 }
 
-class Service(_Entity):
+class Service(_Object):
     def __init__(self, service_uuid : str, parent : 'Context'):
-        super().__init__(parent, service_uuid, KEY_SERVICE, VALIDATORS, TRANSCODERS)
-        self._endpoints = EntityCollection(self, KEY_SERVICE_ENDPOINTS)
-        self._constraints = EntityCollection(self, KEY_SERVICE_CONSTRAINTS)
+        super().__init__(parent, service_uuid)
+        self._attributes = Attributes(KEY_SERVICE, VALIDATORS, TRANSCODERS)
+        self._endpoints = Collection(self, KEY_SERVICE_ENDPOINTS)
+        self._constraints = Collection(self, KEY_SERVICE_CONSTRAINTS)
 
     @property
     def parent(self) -> 'Context': return self._parent
@@ -46,13 +48,16 @@ class Service(_Entity):
     def context_uuid(self) -> str: return self.context.context_uuid
 
     @property
-    def service_uuid(self) -> str: return self._entity_uuid
+    def service_uuid(self) -> str: return self._object_uuid
 
     @property
-    def endpoints(self) -> EntityCollection: return self._endpoints
+    def attributes(self) -> Attributes: return self._attributes
 
     @property
-    def constraints(self) -> EntityCollection: return self._constraints
+    def endpoints(self) -> Collection: return self._endpoints
+
+    @property
+    def constraints(self) -> Collection: return self._constraints
 
     def endpoint(self, endpoint_uuid : str) -> Endpoint: return Endpoint(endpoint_uuid, self)
 
diff --git a/src/context/service/database/objects/ServiceState.py b/src/context/service/database/objects/ServiceState.py
index 3855138d99c40b743885f256fe3aafbaa44aa18b..b0548e5b78333cf5748b363cf8758c281fca049d 100644
--- a/src/context/service/database/objects/ServiceState.py
+++ b/src/context/service/database/objects/ServiceState.py
@@ -23,5 +23,5 @@ def servicestate_enum_values():
     return {m.value for m in ServiceState.__members__.values()}
 
 def to_servicestate_enum(int_or_str):
-    if isinstance(int_or_str, str): int_or_str = int_or_str.lower()
+    if isinstance(int_or_str, str): int_or_str = int_or_str.upper()
     return ANY_TO_ENUM.get(int_or_str)
diff --git a/src/context/service/database/objects/ServiceType.py b/src/context/service/database/objects/ServiceType.py
index c779fc31c89c8746a547a38135f99d07716e2bbb..d78e5320c0726d5c5a39ec164719b8a708730f87 100644
--- a/src/context/service/database/objects/ServiceType.py
+++ b/src/context/service/database/objects/ServiceType.py
@@ -27,5 +27,5 @@ def servicetype_enum_values():
     return {m.value for m in ServiceType.__members__.values()}
 
 def to_servicetype_enum(int_or_str):
-    if isinstance(int_or_str, str): int_or_str = int_or_str.lower()
+    if isinstance(int_or_str, str): int_or_str = int_or_str.upper()
     return ANY_TO_ENUM.get(int_or_str)
diff --git a/src/context/service/database/objects/Topology.py b/src/context/service/database/objects/Topology.py
index ef8e802d7fef3bf2367ac4bfd90c57386a2a7d51..adf18472f58a076979cbb03bc08afb33fc685440 100644
--- a/src/context/service/database/objects/Topology.py
+++ b/src/context/service/database/objects/Topology.py
@@ -1,22 +1,24 @@
 from __future__ import annotations
-from typing import TYPE_CHECKING, Dict
-from ...entity._Entity import _Entity
-from ...entity.EntityCollection import EntityCollection
-from ..Keys import KEY_TOPOLOGY, KEY_DEVICES, KEY_LINKS
-from .device.Device import Device
-from .link.Link import Link
+from typing import TYPE_CHECKING, Dict, List
+from .._engine.object._Object import _Object
+from .._engine.object.Attributes import Attributes
+from .._engine.object.Collection import Collection
+from ._Keys import KEY_TOPOLOGY, KEY_DEVICES, KEY_LINKS
+from .Device import Device
+from .Link import Link
 
 if TYPE_CHECKING:
-    from ..Context import Context
+    from .Context import Context
 
 VALIDATORS = {}  # no attributes accepted
 TRANSCODERS = {} # no transcoding applied to attributes
 
-class Topology(_Entity):
+class Topology(_Object):
     def __init__(self, topology_uuid : str, parent : 'Context'):
-        super().__init__(parent, topology_uuid, KEY_TOPOLOGY, VALIDATORS, TRANSCODERS)
-        self._devices = EntityCollection(self, KEY_DEVICES)
-        self._links = EntityCollection(self, KEY_LINKS)
+        super().__init__(parent, topology_uuid)
+        self._attributes = Attributes(parent, KEY_TOPOLOGY, VALIDATORS, TRANSCODERS)
+        self._devices = Collection(self, KEY_DEVICES)
+        self._links = Collection(self, KEY_LINKS)
 
     @property
     def parent(self) -> 'Context': return self._parent
@@ -28,13 +30,16 @@ class Topology(_Entity):
     def context_uuid(self) -> str: return self.context.context_uuid
 
     @property
-    def topology_uuid(self) -> str: return self._entity_uuid
+    def topology_uuid(self) -> str: return self._object_uuid
 
     @property
-    def devices(self) -> EntityCollection: return self._devices
+    def attributes(self) -> Attributes: return self._attributes
 
     @property
-    def links(self) -> EntityCollection: return self._links
+    def devices(self) -> Collection: return self._devices
+
+    @property
+    def links(self) -> Collection: return self._links
 
     def device(self, device_uuid : str) -> Device: return Device(device_uuid, self)
 
@@ -44,6 +49,10 @@ class Topology(_Entity):
         self.parent.topologies.add(self.topology_uuid)
         return self
 
+    def update(self, update_attributes={}, remove_attributes=[]) -> 'Topology':
+        self.attributes.update(update_attributes=update_attributes, remove_attributes=remove_attributes)
+        return self
+
     def delete(self) -> None:
         for device_uuid in self.devices.get(): self.device(device_uuid).delete()
         for link_uuid in self.links.get(): self.link(link_uuid).delete()
@@ -52,15 +61,18 @@ class Topology(_Entity):
 
     def dump_id(self) -> Dict:
         return {
-            'contextId': self.context.dump_id(),
-            'topoId': {'uuid': self.topology_uuid},
+            'context_id': self.context.dump_id(),
+            'topology_uuid': {'uuid': self.topology_uuid},
         }
 
-    def dump(self) -> Dict:
-        devices = [self.device(device_uuid).dump() for device_uuid in self.devices.get()]
-        links = [self.link(link_uuid).dump() for link_uuid in self.links.get()]
-        return {
-            'topoId': self.dump_id(),
-            'device': devices,
-            'link': links,
-        }
+    def dump_devices(self) -> List[Dict]:
+        return [self.device(device_uuid).dump() for device_uuid in self.devices.get()]
+
+    def dump_links(self) -> List[Dict]:
+        return [self.link(link_uuid).dump() for link_uuid in self.links.get()]
+
+    def dump(self, include_devices=True, include_links=True) -> Dict:
+        result = {'topology_id': self.dump_id()}
+        if include_devices: result['devices'] = self.dump_devices()
+        if include_links: result['links'] = self.dump_links()
+        return result
diff --git a/src/context/service/database/objects/Keys.py b/src/context/service/database/objects/_Keys.py
similarity index 56%
rename from src/context/service/database/objects/Keys.py
rename to src/context/service/database/objects/_Keys.py
index 0842bb4e4e639c8fc83a0733e8c951eb4994fafe..7352e59078fb8d25d1f7b15bce5500d570a383a2 100644
--- a/src/context/service/database/objects/Keys.py
+++ b/src/context/service/database/objects/_Keys.py
@@ -13,6 +13,7 @@ KEY_LINKS               = KEY_TOPOLOGY + '/links{container_name}'
 
 # Context.Topology.Device keys
 KEY_DEVICE              = KEY_TOPOLOGY + '/device[{device_uuid}]'
+KEY_DEVICE_DRIVERS      = KEY_DEVICE   + '/drivers{container_name}'
 KEY_DEVICE_ENDPOINTS    = KEY_DEVICE   + '/endpoints{container_name}'
 
 # Context.Topology.Device.Endpoint keys
@@ -20,18 +21,18 @@ KEY_DEVICE_ENDPOINT     = KEY_DEVICE   + '/endpoint[{endpoint_uuid}]'
 
 # Context.Topology.Link keys
 KEY_LINK                = KEY_TOPOLOGY + '/link[{link_uuid}]'
-KEY_LINK_ENDPOINTS      = KEY_LINK     + '/endpoints{container_name}'
-
-# Context.Topology.Link.Endpoint Keys
-KEY_LINK_ENDPOINT       = KEY_LINK     + '/endpoint[{endpoint_uuid}]'
-
-# Service keys
-KEY_SERVICE             = KEY_CONTEXT  + '/service[{service_uuid}]'
-KEY_SERVICE_ENDPOINTS   = KEY_SERVICE  + '/endpoints{container_name}'
-KEY_SERVICE_CONSTRAINTS = KEY_SERVICE  + '/constraints{container_name}'
-
-# Context.Service.Endpoint Keys
-KEY_SERVICE_ENDPOINT    = KEY_SERVICE  + '/endpoint[{endpoint_uuid}]'
-
-# Context.Service.Constraint Keys
-KEY_SERVICE_CONSTRAINT  = KEY_SERVICE  + '/constraint[{constraint_type}]'
+#KEY_LINK_ENDPOINTS      = KEY_LINK     + '/endpoints{container_name}'
+#
+## Context.Topology.Link.Endpoint Keys
+#KEY_LINK_ENDPOINT       = KEY_LINK     + '/endpoint[{endpoint_uuid}]'
+#
+## Service keys
+#KEY_SERVICE             = KEY_CONTEXT  + '/service[{service_uuid}]'
+#KEY_SERVICE_ENDPOINTS   = KEY_SERVICE  + '/endpoints{container_name}'
+#KEY_SERVICE_CONSTRAINTS = KEY_SERVICE  + '/constraints{container_name}'
+#
+## Context.Service.Endpoint Keys
+#KEY_SERVICE_ENDPOINT    = KEY_SERVICE  + '/endpoint[{endpoint_uuid}]'
+#
+## Context.Service.Constraint Keys
+#KEY_SERVICE_CONSTRAINT  = KEY_SERVICE  + '/constraint[{constraint_type}]'
diff --git a/src/context/tests/test_database_engine_inmemory.py b/src/context/tests/test_database_engine_inmemory.py
deleted file mode 100644
index c3d894f1788f7e0e1ddb03efcb7c0b26c2ec098a..0000000000000000000000000000000000000000
--- a/src/context/tests/test_database_engine_inmemory.py
+++ /dev/null
@@ -1,10 +0,0 @@
-import logging
-from context.service.database.Factory import get_database, DatabaseEngineEnum
-from .populate_database import sequence
-
-logging.basicConfig(level=logging.INFO)
-
-def test_inmemory():
-    database = get_database(
-        engine=DatabaseEngineEnum.INMEMORY)
-    sequence(database)
diff --git a/src/context/tests/test_database_unitary.py b/src/context/tests/test_database_unitary.py
deleted file mode 100644
index 72539d2a728e171394f14cf00bf73df4bd36875c..0000000000000000000000000000000000000000
--- a/src/context/tests/test_database_unitary.py
+++ /dev/null
@@ -1,75 +0,0 @@
-import logging, pytest
-from context.service.database.api.Database import Database
-from context.service.database.api.entity._Entity import _Entity
-from context.service.database.api.entity.EntityAttributes import EntityAttributes
-from context.service.database.api.Exceptions import WrongDatabaseEngine
-from context.service.database.engines._DatabaseEngine import _DatabaseEngine
-from context.service.database.engines.inmemory.InMemoryDatabaseEngine import InMemoryDatabaseEngine
-
-logging.basicConfig(level=logging.INFO)
-
-def test_database_gets_none_database_engine():
-    # should fail with invalid database engine
-    with pytest.raises(WrongDatabaseEngine) as e:
-        Database(None)
-    assert str(e.value) == 'database_engine must inherit from _DatabaseEngine'
-
-def test_database_gets_correct_database_engine():
-    # should work
-    assert Database(InMemoryDatabaseEngine()) is not None
-
-def test_entity_gets_invalid_parameters():
-
-    # should fail with invalid parent
-    with pytest.raises(AttributeError) as e:
-        _Entity(None, 'valid-uuid', 'valid-attributes-key', {}, {})
-    assert str(e.value) == 'parent must be an instance of _Entity'
-
-    # should fail with invalid entity uuid
-    with pytest.raises(AttributeError) as e:
-        _Entity(Database(InMemoryDatabaseEngine()), None, 'valid-attributes-key', {}, {})
-    assert str(e.value) == 'entity_uuid must be a non-empty instance of str'
-
-    # should fail with invalid entity uuid
-    with pytest.raises(AttributeError) as e:
-        _Entity(Database(InMemoryDatabaseEngine()), '', 'valid-attributes-key', {}, {})
-    assert str(e.value) == 'entity_uuid must be a non-empty instance of str'
-
-    # should fail with invalid attribute key
-    with pytest.raises(AttributeError) as e:
-        _Entity(Database(InMemoryDatabaseEngine()), 'valid-uuid', None, {}, {})
-    assert str(e.value) == 'attributes_key must be a non-empty instance of str'
-
-    # should fail with invalid attribute key
-    with pytest.raises(AttributeError) as e:
-        _Entity(Database(InMemoryDatabaseEngine()), 'valid-uuid', '', {}, {})
-    assert str(e.value) == 'attributes_key must be a non-empty instance of str'
-
-    # should fail with invalid attribute validators
-    with pytest.raises(AttributeError) as e:
-        _Entity(Database(InMemoryDatabaseEngine()), 'valid-uuid', 'valid-attributes-key', [], {})
-    assert str(e.value) == 'attribute_validators must be an instance of dict'
-
-    # should fail with invalid attribute transcoders
-    with pytest.raises(AttributeError) as e:
-        _Entity(Database(InMemoryDatabaseEngine()), 'valid-uuid', 'valid-attributes-key', {}, [])
-    assert str(e.value) == 'attribute_transcoders must be an instance of dict'
-
-    # should work
-    assert _Entity(Database(InMemoryDatabaseEngine()), 'valid-uuid', 'valid-attributes-key', {}, {}) is not None
-
-def test_entity_attributes_gets_invalid_parameters():
-
-    # should work
-    root_entity = Database(InMemoryDatabaseEngine())
-    validators = {'attr': lambda v: True}
-    entity_attrs = EntityAttributes(root_entity, 'valid-attributes-key', validators, {})
-    assert entity_attrs is not None
-
-    with pytest.raises(AttributeError) as e:
-        entity_attrs.update(update_attributes={'non-defined-attr': 'random-value'})
-    assert str(e.value) == "Unexpected update_attributes: {'non-defined-attr': 'random-value'}"
-
-    with pytest.raises(AttributeError) as e:
-        entity_attrs.update(remove_attributes=['non-defined-attr'])
-    assert str(e.value) == "Unexpected remove_attributes: {'non-defined-attr'}"
diff --git a/src/context/tests/test_unitary.py b/src/context/tests/test_unitary.py
index f7f81fdde989a8d58b17bd93e93aa1225cd7cabc..b230ac599438db961e978ce08388a303aad86408 100644
--- a/src/context/tests/test_unitary.py
+++ b/src/context/tests/test_unitary.py
@@ -5,8 +5,8 @@ from common.tests.Assertions import validate_empty, validate_link_id, validate_t
     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.Factory import get_database, DatabaseEngineEnum
-from context.service.database.api.Database import Database
+from context.service.database.Database import Database
+from context.service.database._engine.Factory import get_database_backend, BackendEnum
 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
@@ -34,7 +34,8 @@ LINK = {
 
 @pytest.fixture(scope='session')
 def context_database():
-    _database = get_database(engine=DatabaseEngineEnum.INMEMORY)
+    database_backend = get_database_backend(engine=BackendEnum.INMEMORY)
+    _database = Database(database_backend)
     return _database
 
 @pytest.fixture(scope='session')