diff --git a/manifests/.gitlab-ci.yml b/manifests/.gitlab-ci.yml
index 0c0b1d4dc0783e1bf3158d0629558b4fedd355d6..9fc872ca61752d1be012aa4b866b3b592171e2cd 100644
--- a/manifests/.gitlab-ci.yml
+++ b/manifests/.gitlab-ci.yml
@@ -6,5 +6,4 @@ dependencies all:
     - kubectl version
     - kubectl get all
     - kubectl apply -f "manifests/prometheus.yaml"
-    - kubectl apply -f "manifests/redis.yaml"
     - kubectl get all
diff --git a/manifests/contextservice.yaml b/manifests/contextservice.yaml
index cf7da7e43fbfc02f5872745fc6f10f3cfcee6cb2..97bef301c27da42eedad02377b0ebecc73701b12 100644
--- a/manifests/contextservice.yaml
+++ b/manifests/contextservice.yaml
@@ -6,6 +6,7 @@ spec:
   selector:
     matchLabels:
       app: contextservice
+  replicas: 1
   template:
     metadata:
       labels:
@@ -13,6 +14,17 @@ spec:
     spec:
       terminationGracePeriodSeconds: 5
       containers:
+      - name: redis
+        image: redis:6.2
+        ports:
+        - containerPort: 6379
+        resources:
+          requests:
+            cpu: 250m
+            memory: 512Mi
+          limits:
+            cpu: 700m
+            memory: 1024Mi
       - name: server
         image: registry.gitlab.com/teraflow-h2020/controller/context:latest
         imagePullPolicy: Always
@@ -26,6 +38,8 @@ spec:
           value: "0"
         - name: LOG_LEVEL
           value: "DEBUG"
+        - name: POPULATE_FAKE_DATA
+          value: "true"
         readinessProbe:
           exec:
             command: ["/bin/grpc_health_probe", "-addr=:1010"]
diff --git a/manifests/redis.yaml b/manifests/redis.yaml
deleted file mode 100644
index 9aaebb1673637e6afc4fcf2d5887009f5d365a4d..0000000000000000000000000000000000000000
--- a/manifests/redis.yaml
+++ /dev/null
@@ -1,54 +0,0 @@
----
-apiVersion: apps/v1
-kind: Deployment
-metadata:
-  name: redis
-spec:
-  selector:
-    matchLabels:
-      app: redis
-  replicas: 1
-  template:
-    metadata:
-      labels:
-        app: redis
-        version: v1
-    spec:
-      containers:
-      - name: redis
-        image: redis:6.2
-        ports:
-        - containerPort: 6379
----
-apiVersion: v1
-kind: Service
-metadata:
-  name: redis
-  labels:
-    app: redis
-spec:
-  type: ClusterIP
-  selector:
-    app: redis
-  ports:
-  - name: redis
-    protocol: TCP
-    port: 6379
-    targetPort: 6379
----
-apiVersion: v1
-kind: Service
-metadata:
-  name: redis-public
-  labels:
-    app: redis
-spec:
-  type: NodePort
-  selector:
-    app: redis
-  ports:
-  - name: redis
-    protocol: TCP
-    port: 6379
-    targetPort: 6379
----
diff --git a/run_local_tests.sh b/run_local_tests.sh
index 8302ea2ebdd3ead89c404c9c87f5d3d9e754a077..0987fd66854199905b1035df67ea9b4648845c3e 100755
--- a/run_local_tests.sh
+++ b/run_local_tests.sh
@@ -22,10 +22,8 @@ coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
 #coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
 #    centralizedcybersecurity/tests/test_unitary.py
 
-coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose --maxfail=1\
-    context/tests/test_unitary_fast_hasher.py \
-    context/tests/test_unitary_grpc.py \
-    #context/tests/test_unitary_rest.py
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    context/tests/test_unitary.py
 
 #coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
 #    device/tests/test_unitary_driverapi.py \
diff --git a/src/common/type_checkers/Assertions.py b/src/common/type_checkers/Assertions.py
index c7b87a671f88ab65768525c73dcf2b34361b579f..f11a059eb5463751a920b116e86438b7e1b13484 100644
--- a/src/common/type_checkers/Assertions.py
+++ b/src/common/type_checkers/Assertions.py
@@ -1,183 +1,294 @@
-def validate_empty(message):
-    assert type(message) is dict
-    assert len(message.keys()) == 0
+# ----- Enumerations ---------------------------------------------------------------------------------------------------
 
+def validate_config_action_enum(message):
+    assert isinstance(message, str)
+    assert message in [
+        'CONFIGACTION_UNDEFINED',
+        'CONFIGACTION_SET',
+        'CONFIGACTION_DELETE',
+    ]
+
+def validate_device_driver_enum(message):
+    assert isinstance(message, str)
+    assert message in [
+        'DEVICEDRIVER_UNDEFINED',
+        'DEVICEDRIVER_OPENCONFIG',
+        'DEVICEDRIVER_TRANSPORT_API',
+        'DEVICEDRIVER_P4',
+        'DEVICEDRIVER_IETF_NETWORK_TOPOLOGY',
+        'DEVICEDRIVER_ONF_TR_352',
+    ]
+
+def validate_device_operational_status_enum(message):
+    assert isinstance(message, str)
+    assert message in [
+        'DEVICEOPERATIONALSTATUS_UNDEFINED',
+        'DEVICEOPERATIONALSTATUS_DISABLED',
+        'DEVICEOPERATIONALSTATUS_ENABLED'
+    ]
+
+def validate_service_type_enum(message):
+    assert isinstance(message, str)
+    assert message in [
+        'SERVICETYPE_UNKNOWN',
+        'SERVICETYPE_L3NM',
+        'SERVICETYPE_L2NM',
+        'SERVICETYPE_TAPI_CONNECTIVITY_SERVICE',
+    ]
+
+def validate_service_state_enum(message):
+    assert isinstance(message, str)
+    assert message in [
+        'SERVICESTATUS_UNDEFINED',
+        'SERVICESTATUS_PLANNED',
+        'SERVICESTATUS_ACTIVE',
+        'SERVICESTATUS_PENDING_REMOVAL',
+    ]
+
+
+# ----- Common ---------------------------------------------------------------------------------------------------------
 def validate_uuid(message, allow_empty=False):
-    assert type(message) is dict
+    assert isinstance(message, dict)
     assert len(message.keys()) == 1
     assert 'uuid' in message
-    assert type(message['uuid']) is str
+    assert isinstance(message['uuid'], str)
     if allow_empty: return
     assert len(message['uuid']) > 1
 
+def validate_config_rule(message):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 3
+    assert 'action' in message
+    validate_config_action_enum(message['action'])
+    assert 'resource_key' in message
+    assert isinstance(message['resource_key'], str)
+    assert 'resource_value' in message
+    assert isinstance(message['resource_value'], str)
+
+def validate_config_rules(message):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 1
+    assert 'config_rules' in message
+    for config_rule in message['config_rules']: validate_config_rule(config_rule)
+
+def validate_constraint(message):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 2
+    assert 'constraint_type' in message
+    assert isinstance(message['constraint_type'], str)
+    assert 'constraint_value' in message
+    assert isinstance(message['constraint_value'], str)
+
+
+# ----- Identifiers ----------------------------------------------------------------------------------------------------
+
 def validate_context_id(message):
-    assert type(message) is dict
+    assert isinstance(message, dict)
     assert len(message.keys()) == 1
-    assert 'contextUuid' in message
-    validate_uuid(message['contextUuid'])
+    assert 'context_uuid' in message
+    validate_uuid(message['context_uuid'])
+
+def validate_service_id(message, context_uuid=None):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 2
+    assert 'context_id' in message
+    validate_context_id(message['context_id'])
+    if context_uuid is not None: assert message['context_id']['context_uuid']['uuid'] == context_uuid
+    assert 'service_uuid' in message
+    validate_uuid(message['service_uuid'])
+
+def validate_topology_id(message, context_uuid=None):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 2
+    assert 'context_id' in message
+    validate_context_id(message['context_id'])
+    if context_uuid is not None: assert message['context_id']['context_uuid']['uuid'] == context_uuid
+    assert 'topology_uuid' in message
+    validate_uuid(message['topology_uuid'])
 
 def validate_device_id(message):
-    assert type(message) is dict
+    assert isinstance(message, dict)
     assert len(message.keys()) == 1
-    assert 'device_id' in message
-    validate_uuid(message['device_id'])
+    assert 'device_uuid' in message
+    validate_uuid(message['device_uuid'])
 
 def validate_link_id(message):
-    assert type(message) is dict
+    assert isinstance(message, dict)
     assert len(message.keys()) == 1
-    assert 'link_id' in message
-    validate_uuid(message['link_id'])
+    assert 'link_uuid' in message
+    validate_uuid(message['link_uuid'])
+
+def validate_endpoint_id(message):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 3
+    assert 'topology_id' in message
+    validate_topology_id(message['topology_id'])
+    assert 'device_id' in message
+    validate_device_id(message['device_id'])
+    assert 'endpoint_uuid' in message
+    validate_uuid(message['endpoint_uuid'])
 
-def validate_topology_id(message):
-    assert type(message) is dict
-    assert len(message.keys()) == 2
-    assert 'contextId' in message
-    validate_context_id(message['contextId'])
-    assert 'topoId' in message
-    validate_uuid(message['topoId'])
 
-def validate_device_config(message):
-    assert type(message) is dict
+# ----- Lists of Identifiers -------------------------------------------------------------------------------------------
+
+def validate_context_ids(message):
+    assert isinstance(message, dict)
     assert len(message.keys()) == 1
-    assert 'device_config' in message
-    assert type(message['device_config']) is str
+    assert 'context_ids' in message
+    assert isinstance(message['context_ids'], list)
+    for context_id in message['context_ids']: validate_context_id(context_id)
 
-def validate_device_operational_status(message):
-    assert type(message) is str
-    assert message in ['KEEP_STATE', 'ENABLED', 'DISABLED']
+def validate_service_ids(message, context_uuid=None):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 1
+    assert 'service_ids' in message
+    assert isinstance(message['service_ids'], list)
+    for service_id in message['service_ids']: validate_service_id(service_id, context_uuid=context_uuid)
 
-def validate_endpoint_id(message):
-    assert type(message) is dict
+def validate_topology_ids(message, context_uuid=None):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 1
+    assert 'topology_ids' in message
+    assert isinstance(message['topology_ids'], list)
+    for topology_id in message['topology_ids']: validate_topology_id(topology_id, context_uuid=context_uuid)
+
+def validate_device_ids(message):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 1
+    assert 'device_ids' in message
+    assert isinstance(message['device_ids'], list)
+    for device_id in message['device_ids']: validate_device_id(device_id)
+
+def validate_link_ids(message):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 1
+    assert 'link_ids' in message
+    assert isinstance(message['link_ids'], list)
+    for link_id in message['link_ids']: validate_link_id(link_id)
+
+
+# ----- Objects --------------------------------------------------------------------------------------------------------
+
+def validate_context(message):
+    assert isinstance(message, dict)
     assert len(message.keys()) == 3
-    assert 'topoId' in message
-    validate_topology_id(message['topoId'])
-    assert 'dev_id' in message
-    validate_device_id(message['dev_id'])
-    assert 'port_id' in message
-    validate_uuid(message['port_id'])
+    assert 'context_id' in message
+    validate_context_id(message['context_id'])
+    context_uuid = message['context_id']['context_uuid']['uuid']
+    assert 'service_ids' in message
+    assert isinstance(message['service_ids'], list)
+    for service_id in message['service_ids']: validate_service_id(service_id, context_uuid=context_uuid)
+    assert 'topology_ids' in message
+    assert isinstance(message['topology_ids'], list)
+    for topology_id in message['topology_ids']: validate_topology_id(topology_id, context_uuid=context_uuid)
+
+def validate_service_state(message):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 1
+    assert 'service_status' in message
+    validate_service_state_enum(message['service_status'])
+
+def validate_service(message):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 6
+    assert 'service_id' in message
+    validate_service_id(message['service_id'])
+    assert 'service_type' in message
+    validate_service_type_enum(message['service_type'])
+    assert 'service_endpoint_ids' in message
+    assert isinstance(message['service_endpoint_ids'], list)
+    for endpoint_id in message['service_endpoint_ids']: validate_endpoint_id(endpoint_id)
+    assert 'service_constraints' in message
+    assert isinstance(message['service_constraints'], list)
+    for constraint in message['service_constraints']: validate_constraint(constraint)
+    assert 'service_status' in message
+    validate_service_state(message['service_status'])
+    assert 'service_config' in message
+    validate_config_rules(message['service_config'])
+
+def validate_topology(message, num_devices=None, num_links=None):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 3
+    assert 'topology_id' in message
+    validate_topology_id(message['topology_id'])
+    assert 'device_ids' in message
+    assert isinstance(message['device_ids'], list)
+    if num_devices is not None: assert len(message['device_ids']) == num_devices
+    for device_id in message['device_ids']: validate_device_id(device_id)
+    assert 'link_ids' in message
+    assert isinstance(message['link_ids'], list)
+    if num_links is not None: assert len(message['link_ids']) == num_links
+    for link_id in message['link_ids']: validate_link_id(link_id)
 
 def validate_endpoint(message):
-    assert type(message) is dict
+    assert isinstance(message, dict)
     assert len(message.keys()) == 2
-    assert 'port_id' in message
-    validate_endpoint_id(message['port_id'])
-    assert 'port_type' in message
-    assert type(message['port_type']) is str
+    assert 'endpoint_id' in message
+    validate_endpoint_id(message['endpoint_id'])
+    assert 'endpoint_type' in message
+    assert isinstance(message['endpoint_type'], str)
 
 def validate_device(message):
-    assert type(message) is dict
-    assert len(message.keys()) == 5
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 6
     assert 'device_id' in message
     validate_device_id(message['device_id'])
     assert 'device_type' in message
-    assert type(message['device_type']) is str
+    assert isinstance(message['device_type'], str)
     assert 'device_config' in message
-    validate_device_config(message['device_config'])
-    assert 'devOperationalStatus' in message
-    validate_device_operational_status(message['devOperationalStatus'])
-    assert 'endpointList' in message
-    assert type(message['endpointList']) is list
-    for endpoint in message['endpointList']: validate_endpoint(endpoint)
+    validate_config_rules(message['device_config'])
+    assert 'device_operational_status' in message
+    validate_device_operational_status_enum(message['device_operational_status'])
+    assert 'device_drivers' in message
+    assert isinstance(message['device_drivers'], list)
+    for driver in message['device_drivers']: validate_device_driver_enum(driver)
+    assert 'device_endpoints' in message
+    assert isinstance(message['device_endpoints'], list)
+    for endpoint in message['device_endpoints']: validate_endpoint(endpoint)
 
 def validate_link(message):
-    assert type(message) is dict
+    assert isinstance(message, dict)
     assert len(message.keys()) == 2
     assert 'link_id' in message
     validate_link_id(message['link_id'])
-    assert 'endpointList' in message
-    assert type(message['endpointList']) is list
-    for endpoint_id in message['endpointList']: validate_endpoint_id(endpoint_id)
-
-def validate_topology(message):
-    assert type(message) is dict
-    assert len(message.keys()) > 0
-    assert 'topoId' in message
-    validate_topology_id(message['topoId'])
-    assert 'device' in message
-    assert type(message['device']) is list
-    for device in message['device']: validate_device(device)
-    assert 'link' in message
-    assert type(message['link']) is list
-    for link in message['link']: validate_link(link)
-
-def validate_topology_is_empty(message):
-    validate_topology(message)
-    assert len(message['device']) == 0
-    assert len(message['link']) == 0
-
-def validate_topology_has_devices(message):
-    validate_topology(message)
-    assert len(message['device']) > 0
-
-def validate_topology_has_links(message):
-    validate_topology(message)
-    assert len(message['link']) > 0
+    assert 'link_endpoint_ids' in message
+    assert isinstance(message['link_endpoint_ids'], list)
+    for endpoint_id in message['link_endpoint_ids']: validate_endpoint_id(endpoint_id)
 
-def validate_constraint(message):
-    assert type(message) is dict
-    assert len(message.keys()) == 2
-    assert 'constraint_type' in message
-    assert type(message['constraint_type']) is str
-    assert 'constraint_value' in message
-    assert type(message['constraint_value']) is str
 
-def validate_service_id(message):
-    assert type(message) is dict
-    assert len(message.keys()) == 2
-    assert 'contextId' in message
-    validate_context_id(message['contextId'])
-    assert 'cs_id' in message
-    validate_uuid(message['cs_id'])
+# ----- Lists of Objects -----------------------------------------------------------------------------------------------
 
-def validate_service_config(message):
-    assert type(message) is dict
+def validate_contexts(message):
+    assert isinstance(message, dict)
     assert len(message.keys()) == 1
-    assert 'serviceConfig' in message
-    assert type(message['serviceConfig']) is str
+    assert 'contexts' in message
+    assert isinstance(message['contexts'], list)
+    for context in message['contexts']: validate_context(context)
 
-def validate_service_type(message):
-    assert type(message) is str
-    assert message in ['UNKNOWN', 'L3NM', 'L2NM', 'TAPI_CONNECTIVITY_SERVICE']
+def validate_services(message):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 1
+    assert 'services' in message
+    assert isinstance(message['services'], list)
+    for service in message['services']: validate_service(service)
 
-def validate_service_state_enum(message):
-    assert type(message) is str
-    assert message in ['PLANNED', 'ACTIVE', 'PENDING_REMOVAL']
+def validate_topologies(message):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 1
+    assert 'topologies' in message
+    assert isinstance(message['topologies'], list)
+    for topology in message['topologies']: validate_topology(topology)
 
-def validate_service_state(message):
-    assert type(message) is dict
+def validate_devices(message):
+    assert isinstance(message, dict)
     assert len(message.keys()) == 1
-    assert 'serviceState' in message
-    validate_service_state_enum(message['serviceState'])
+    assert 'devices' in message
+    assert isinstance(message['devices'], list)
+    for device in message['devices']: validate_device(device)
 
-def validate_service(message):
-    assert type(message) is dict
-    assert len(message.keys()) == 6
-    assert 'cs_id' in message
-    validate_service_id(message['cs_id'])
-    assert 'serviceType' in message
-    validate_service_type(message['serviceType'])
-    assert 'endpointList' in message
-    assert type(message['endpointList']) is list
-    for endpoint_id in message['endpointList']: validate_endpoint_id(endpoint_id)
-    assert 'constraint' in message
-    assert type(message['constraint']) is list
-    for constraint in message['constraint']: validate_constraint(constraint)
-    assert 'serviceState' in message
-    validate_service_state(message['serviceState'])
-    assert 'serviceConfig' in message
-    validate_service_config(message['serviceConfig'])
-
-def validate_service_list(message):
-    assert type(message) is dict
-    assert len(message.keys()) == 1
-    assert 'cs' in message
-    assert type(message['cs']) is list
-    for cs in message['cs']: validate_service(cs)
-
-def validate_service_list_is_empty(message):
-    validate_service_list(message)
-    assert len(message['cs']) == 0
-
-def validate_service_list_is_not_empty(message):
-    validate_service_list(message)
-    assert len(message['cs']) > 0
+def validate_links(message):
+    assert isinstance(message, dict)
+    assert len(message.keys()) == 1
+    assert 'links' in message
+    assert isinstance(message['links'], list)
+    for link in message['links']: validate_link(link)
diff --git a/src/context/Config.py b/src/context/Config.py
index c4a21d97b63e17466bd7b47596cf0daa54ba4a64..9892899fdec0419ea2332547f6c9141a060d7a3e 100644
--- a/src/context/Config.py
+++ b/src/context/Config.py
@@ -1,7 +1,7 @@
 import logging
 
 # General settings
-LOG_LEVEL = logging.WARNING
+LOG_LEVEL = logging.INFO
 
 # gRPC settings
 GRPC_SERVICE_PORT = 10100
diff --git a/src/context/service/__main__.py b/src/context/service/__main__.py
index 979ee588d2790461937fa06b85106a6665f4197b..985a8e528d2cd08918c8e093adb38f54037c1354 100644
--- a/src/context/service/__main__.py
+++ b/src/context/service/__main__.py
@@ -11,7 +11,7 @@ from context.Config import (
 from context.service.Populate import populate
 from context.service.grpc_server.ContextService import ContextService
 from context.service.rest_server.Server import Server
-from context.service.rest_server.resources.Context import Context
+from context.service.rest_server.Resources import RESOURCES
 
 terminate = threading.Event()
 logger = None
@@ -31,6 +31,7 @@ def main():
     restapi_base_url     = get_setting('RESTAPI_BASE_URL',                 default=RESTAPI_BASE_URL    )
     metrics_port         = get_setting('METRICS_PORT',                     default=METRICS_PORT        )
     populate_fake_data   = get_setting('POPULATE_FAKE_DATA',               default=POPULATE_FAKE_DATA  )
+    if isinstance(populate_fake_data, str): populate_fake_data = (populate_fake_data.upper() in {'T', '1', 'TRUE'})
 
     logging.basicConfig(level=log_level)
     logger = logging.getLogger(__name__)
@@ -55,7 +56,8 @@ def main():
     grpc_service.start()
 
     rest_server = Server(port=restapi_service_port, base_url=restapi_base_url)
-    rest_server.add_resource(Context, '/context', endpoint='api.context', resource_class_args=(database,))
+    for endpoint_name, resource_class, resource_url in RESOURCES:
+        rest_server.add_resource(resource_class, resource_url, endpoint=endpoint_name, resource_class_args=(database,))
     rest_server.start()
 
     if populate_fake_data:
diff --git a/src/context/service/grpc_server/ContextService.py b/src/context/service/grpc_server/ContextService.py
index 544dcad424589ac3c9b9e2eee0be47ea2c467611..ab7653e37d318d0bfeea4a60213206d391c0dfda 100644
--- a/src/context/service/grpc_server/ContextService.py
+++ b/src/context/service/grpc_server/ContextService.py
@@ -29,8 +29,8 @@ class ContextService:
         self.server = None
 
     def start(self):
-        self.endpoint = '{:s}:{:s}'.format(self.address, self.port)
-        LOGGER.debug('Starting Service (tentative endpoint: {:s}, max_workers: {:s})...'.format(
+        self.endpoint = '{:s}:{:s}'.format(self.address, str(self.port))
+        LOGGER.info('Starting Service (tentative endpoint: {:s}, max_workers: {:s})...'.format(
             str(self.endpoint), str(self.max_workers)))
 
         self.pool = futures.ThreadPoolExecutor(max_workers=self.max_workers)
diff --git a/src/context/service/grpc_server/ContextServiceServicerImpl.py b/src/context/service/grpc_server/ContextServiceServicerImpl.py
index f39c7773917898efbfdfbb083d3630292710c4a3..d8f7b648b4b919cc61330f236195c444f550ede1 100644
--- a/src/context/service/grpc_server/ContextServiceServicerImpl.py
+++ b/src/context/service/grpc_server/ContextServiceServicerImpl.py
@@ -71,26 +71,33 @@ class ContextServiceServicerImpl(ContextServiceServicer):
     @safe_and_metered_rpc_method(METRICS, LOGGER)
     def SetContext(self, request: Context, context : grpc.ServicerContext) -> ContextId:
         context_uuid = request.context_id.context_uuid.uuid
-        result : Tuple[ContextModel, bool] = update_or_create_object(
-            self.database, ContextModel, context_uuid, {'context_uuid': context_uuid})
-        db_context, updated = result
 
         for i,topology_id in enumerate(request.topology_ids):
             topology_context_uuid = topology_id.context_id.context_uuid.uuid
-            topology_uuid = topology_id.topology_uuid.uuid
             if topology_context_uuid != context_uuid:
                 raise InvalidArgumentException(
                     'request.topology_ids[{:d}].context_id.context_uuid.uuid'.format(i), topology_context_uuid,
                     ['should be == {:s}({:s})'.format('request.context_id.context_uuid.uuid', context_uuid)])
-            get_object(self.database, TopologyModel, [context_uuid, topology_uuid]) # just to confirm it exists
 
         for i,service_id in enumerate(request.service_ids):
             service_context_uuid = service_id.context_id.context_uuid.uuid
-            service_uuid = service_id.service_uuid.uuid
             if service_context_uuid != context_uuid:
                 raise InvalidArgumentException(
                     'request.service_ids[{:d}].context_id.context_uuid.uuid'.format(i), service_context_uuid,
                     ['should be == {:s}({:s})'.format('request.context_id.context_uuid.uuid', context_uuid)])
+
+        result : Tuple[ContextModel, bool] = update_or_create_object(
+            self.database, ContextModel, context_uuid, {'context_uuid': context_uuid})
+        db_context, updated = result
+
+        for i,topology_id in enumerate(request.topology_ids):
+            topology_context_uuid = topology_id.context_id.context_uuid.uuid
+            topology_uuid = topology_id.topology_uuid.uuid
+            get_object(self.database, TopologyModel, [context_uuid, topology_uuid]) # just to confirm it exists
+
+        for i,service_id in enumerate(request.service_ids):
+            service_context_uuid = service_id.context_id.context_uuid.uuid
+            service_uuid = service_id.service_uuid.uuid
             get_object(self.database, ServiceModel, [context_uuid, service_uuid]) # just to confirm it exists
 
         event_type = EventTypeEnum.EVENTTYPE_UPDATE if updated else EventTypeEnum.EVENTTYPE_CREATE
@@ -221,6 +228,14 @@ class ContextServiceServicerImpl(ContextServiceServicer):
     def SetDevice(self, request: Device, context : grpc.ServicerContext) -> DeviceId:
         device_uuid = request.device_id.device_uuid.uuid
 
+        for i,endpoint in enumerate(request.device_endpoints):
+            endpoint_device_uuid = endpoint.endpoint_id.device_id.device_uuid.uuid
+            if len(endpoint_device_uuid) == 0: endpoint_device_uuid = device_uuid
+            if device_uuid != endpoint_device_uuid:
+                raise InvalidArgumentException(
+                    'request.device_endpoints[{:d}].device_id.device_uuid.uuid'.format(i), endpoint_device_uuid,
+                    ['should be == {:s}({:s})'.format('request.device_id.device_uuid.uuid', device_uuid)])
+
         running_config_result = set_config(self.database, device_uuid, 'running', request.device_config.config_rules)
         db_running_config = running_config_result[0][0]
 
@@ -238,10 +253,6 @@ class ContextServiceServicerImpl(ContextServiceServicer):
             endpoint_uuid = endpoint.endpoint_id.endpoint_uuid.uuid
             endpoint_device_uuid = endpoint.endpoint_id.device_id.device_uuid.uuid
             if len(endpoint_device_uuid) == 0: endpoint_device_uuid = device_uuid
-            if device_uuid != endpoint_device_uuid:
-                raise InvalidArgumentException(
-                    'request.device_endpoints[{:d}].device_id.device_uuid.uuid'.format(i), endpoint_device_uuid,
-                    ['should be == {:s}({:s})'.format('request.device_id.device_uuid.uuid', device_uuid)])
 
             str_endpoint_key = key_to_str([device_uuid, endpoint_uuid])
             endpoint_attributes = {
@@ -426,6 +437,14 @@ class ContextServiceServicerImpl(ContextServiceServicer):
         context_uuid = request.service_id.context_id.context_uuid.uuid
         db_context : ContextModel = get_object(self.database, ContextModel, context_uuid)
 
+        for i,endpoint_id in enumerate(request.service_endpoint_ids):
+            endpoint_topology_context_uuid = endpoint_id.topology_id.context_id.context_uuid.uuid
+            if len(endpoint_topology_context_uuid) > 0 and context_uuid != endpoint_topology_context_uuid:
+                raise InvalidArgumentException(
+                    'request.service_endpoint_ids[{:d}].topology_id.context_id.context_uuid.uuid'.format(i),
+                    endpoint_topology_context_uuid,
+                    ['should be == {:s}({:s})'.format('request.service_id.context_id.context_uuid.uuid', context_uuid)])
+
         service_uuid = request.service_id.service_uuid.uuid
         str_service_key = key_to_str([context_uuid, service_uuid])
 
@@ -453,12 +472,6 @@ class ContextServiceServicerImpl(ContextServiceServicer):
             endpoint_topology_uuid         = endpoint_id.topology_id.topology_uuid.uuid
             endpoint_topology_context_uuid = endpoint_id.topology_id.context_id.context_uuid.uuid
 
-            if len(endpoint_topology_context_uuid) > 0 and context_uuid != endpoint_topology_context_uuid:
-                raise InvalidArgumentException(
-                    'request.service_endpoint_ids[{:d}].topology_id.context_id.context_uuid.uuid'.format(i),
-                    endpoint_topology_context_uuid,
-                    ['should be == {:s}({:s})'.format('request.service_id.context_id.context_uuid.uuid', context_uuid)])
-
             str_endpoint_key = key_to_str([endpoint_device_uuid, endpoint_uuid])
             if len(endpoint_topology_context_uuid) > 0 and len(endpoint_topology_uuid) > 0:
                 str_topology_key = key_to_str([endpoint_topology_context_uuid, endpoint_topology_uuid])
diff --git a/src/context/service/rest_server/Resources.py b/src/context/service/rest_server/Resources.py
new file mode 100644
index 0000000000000000000000000000000000000000..54a21ed3984ced399d82f72b7ca7f77e447f0459
--- /dev/null
+++ b/src/context/service/rest_server/Resources.py
@@ -0,0 +1,130 @@
+from flask.json import jsonify
+from flask_restful import Resource
+from google.protobuf.json_format import MessageToDict
+from common.message_broker.Factory import LOGGER
+from common.orm.Database import Database
+from context.proto.context_pb2 import ContextId, DeviceId, Empty, LinkId, ServiceId, TopologyId
+from context.service.grpc_server.ContextServiceServicerImpl import ContextServiceServicerImpl
+
+def grpc_context_id(context_uuid):
+    return ContextId(**{
+        'context_uuid': {'uuid': context_uuid}
+    })
+
+def grpc_topology_id(context_uuid, topology_uuid):
+    return TopologyId(**{
+        'context_id': {'context_uuid': {'uuid': context_uuid}},
+        'topology_uuid': {'uuid': topology_uuid}
+    })
+
+def grpc_service_id(context_uuid, service_uuid):
+    return ServiceId(**{
+        'context_id': {'context_uuid': {'uuid': context_uuid}},
+        'service_uuid': {'uuid': service_uuid}
+    })
+
+def grpc_device_id(device_uuid):
+    return DeviceId(**{
+        'device_uuid': {'uuid': device_uuid}
+    })
+
+def grpc_link_id(link_uuid):
+    return LinkId(**{
+        'link_uuid': {'uuid': link_uuid}
+    })
+
+def format_grpc_to_json(grpc_reply):
+    return jsonify(MessageToDict(
+        grpc_reply, including_default_value_fields=True, preserving_proto_field_name=True,
+        use_integers_for_enums=False))
+
+class _Resource(Resource):
+    def __init__(self, database : Database) -> None:
+        super().__init__()
+        self.database = database
+        self.servicer = ContextServiceServicerImpl(self.database, None)
+
+class ContextIds(_Resource):
+    def get(self):
+        return format_grpc_to_json(self.servicer.ListContextIds(Empty(), None))
+
+class Contexts(_Resource):
+    def get(self):
+        return format_grpc_to_json(self.servicer.ListContexts(Empty(), None))
+
+class Context(_Resource):
+    def get(self, context_uuid : str):
+        return format_grpc_to_json(self.servicer.GetContext(grpc_context_id(context_uuid), None))
+
+class TopologyIds(_Resource):
+    def get(self, context_uuid : str):
+        return format_grpc_to_json(self.servicer.ListTopologyIds(grpc_context_id(context_uuid), None))
+
+class Topologies(_Resource):
+    def get(self, context_uuid : str):
+        return format_grpc_to_json(self.servicer.ListTopologies(grpc_context_id(context_uuid), None))
+
+class Topology(_Resource):
+    def get(self, context_uuid : str, topology_uuid : str):
+        return format_grpc_to_json(self.servicer.GetTopology(grpc_topology_id(context_uuid, topology_uuid), None))
+
+class ServiceIds(_Resource):
+    def get(self, context_uuid : str):
+        return format_grpc_to_json(self.servicer.ListServiceIds(grpc_context_id(context_uuid), None))
+
+class Services(_Resource):
+    def get(self, context_uuid : str):
+        return format_grpc_to_json(self.servicer.ListServices(grpc_context_id(context_uuid), None))
+
+class Service(_Resource):
+    def get(self, context_uuid : str, service_uuid : str):
+        return format_grpc_to_json(self.servicer.GetService(grpc_service_id(context_uuid, service_uuid), None))
+
+class DeviceIds(_Resource):
+    def get(self):
+        return format_grpc_to_json(self.servicer.ListDeviceIds(Empty(), None))
+
+class Devices(_Resource):
+    def get(self):
+        return format_grpc_to_json(self.servicer.ListDevices(Empty(), None))
+
+class Device(_Resource):
+    def get(self, device_uuid : str):
+        return format_grpc_to_json(self.servicer.GetDevice(grpc_device_id(device_uuid), None))
+
+class LinkIds(_Resource):
+    def get(self):
+        return format_grpc_to_json(self.servicer.ListLinkIds(Empty(), None))
+
+class Links(_Resource):
+    def get(self):
+        return format_grpc_to_json(self.servicer.ListLinks(Empty(), None))
+
+class Link(_Resource):
+    def get(self, link_uuid : str):
+        return format_grpc_to_json(self.servicer.GetLink(grpc_link_id(link_uuid), None))
+
+# Use 'path' type in Service and Sink because service_uuid and link_uuid might contain char '/' and Flask is unable to
+# recognize them in 'string' type.
+RESOURCES = [
+    # (endpoint_name, resource_class, resource_url)
+    ('api.context_ids',  ContextIds,  '/context_ids'),
+    ('api.contexts',     Contexts,    '/contexts'),
+    ('api.context',      Context,     '/context/<string:context_uuid>'),
+
+    ('api.topology_ids', TopologyIds, '/context/<string:context_uuid>/topology_ids'),
+    ('api.topologies',   Topologies,  '/context/<string:context_uuid>/topologies'),
+    ('api.topology',     Topology,    '/context/<string:context_uuid>/topology/<string:topology_uuid>'),
+
+    ('api.service_ids',  ServiceIds,  '/context/<string:context_uuid>/service_ids'),
+    ('api.services',     Services,    '/context/<string:context_uuid>/services'),
+    ('api.service',      Service,     '/context/<string:context_uuid>/service/<path:service_uuid>'),
+
+    ('api.device_ids',   DeviceIds,   '/device_ids'),
+    ('api.devices',      Devices,     '/devices'),
+    ('api.device',       Device,      '/device/<string:device_uuid>'),
+
+    ('api.link_ids',     LinkIds,     '/link_ids'),
+    ('api.links',        Links,       '/links'),
+    ('api.link',         Link,        '/link/<path:link_uuid>'),
+]
diff --git a/src/context/service/rest_server/Server.py b/src/context/service/rest_server/Server.py
index 16badfce8c84f058aeaeac79993ada726a17f06a..3095d77c48e756dd0c5d655b06a2b0625bcc89d5 100644
--- a/src/context/service/rest_server/Server.py
+++ b/src/context/service/rest_server/Server.py
@@ -15,6 +15,8 @@ class Server(threading.Thread):
         self.host = host
         self.port = port
         self.base_url = base_url
+        self.srv = None
+        self.ctx = None
         self.app = Flask(__name__)
         self.api = Api(self.app, prefix=self.base_url)
 
diff --git a/src/context/service/rest_server/resources/Context.py b/src/context/service/rest_server/resources/Context.py
deleted file mode 100644
index 557654924bd838c557751f7b941953988f7bc7a2..0000000000000000000000000000000000000000
--- a/src/context/service/rest_server/resources/Context.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from flask.json import jsonify
-from flask_restful import Resource
-from google.protobuf.json_format import MessageToDict
-from common.orm.Database import Database
-from context.proto.context_pb2 import Empty
-from context.service.grpc_server.ContextServiceServicerImpl import ContextServiceServicerImpl
-
-class Context(Resource):
-    def __init__(self, database : Database) -> None:
-        super().__init__()
-        self.database = database
-
-    def get(self):
-        servicer = ContextServiceServicerImpl(self.database, None)
-        return jsonify(MessageToDict(servicer.ListContexts(Empty(), None)))
diff --git a/src/context/service/rest_server/resources/__init__.py b/src/context/service/rest_server/resources/__init__.py
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/context/tests/example_objects.py b/src/context/tests/example_objects.py
index 9fb48f038f23ebddb89fe3608899bf579aca0e49..81339c04e1fe77667bd41179f3fa0813c5fc69df 100644
--- a/src/context/tests/example_objects.py
+++ b/src/context/tests/example_objects.py
@@ -18,7 +18,11 @@ def endpoint(topology_id, device_id, endpoint_uuid, endpoint_type):
 
 ## use "deepcopy" to prevent propagating forced changes during tests
 CONTEXT_ID = {'context_uuid': {'uuid': DEFAULT_CONTEXT_UUID}}
-CONTEXT = {'context_id': deepcopy(CONTEXT_ID)}
+CONTEXT = {
+    'context_id': deepcopy(CONTEXT_ID),
+    'topology_ids': [],
+    'service_ids': [],
+}
 
 TOPOLOGY_ID = {
     'context_id': deepcopy(CONTEXT_ID),
diff --git a/src/context/tests/test_unitary_grpc.py b/src/context/tests/test_unitary.py
similarity index 71%
rename from src/context/tests/test_unitary_grpc.py
rename to src/context/tests/test_unitary.py
index 6581b60b3192dae9c2750e2a7abb356a6361ffd2..db706948fc46bf8397a3894ecd62e212301d88c8 100644
--- a/src/context/tests/test_unitary_grpc.py
+++ b/src/context/tests/test_unitary.py
@@ -1,4 +1,4 @@
-import copy, grpc, logging, pytest, threading
+import copy, grpc, logging, pytest, requests, threading, time, urllib
 from queue import Queue
 from typing import Tuple
 from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID
@@ -6,13 +6,23 @@ from common.orm.Database import Database
 from common.orm.Factory import get_database_backend, BackendEnum as DatabaseBackendEnum
 from common.message_broker.Factory import get_messagebroker_backend, BackendEnum as MessageBrokerBackendEnum
 from common.message_broker.MessageBroker import MessageBroker
-from context.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD
+from common.type_checkers.Assertions import (
+    validate_context, validate_context_ids, validate_contexts, validate_device, validate_device_ids, validate_devices,
+    validate_link, validate_link_ids, validate_links, validate_service, validate_service_ids, validate_services,
+    validate_topologies, validate_topology, validate_topology_ids)
+from context.Config import (
+    GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, RESTAPI_SERVICE_PORT, RESTAPI_BASE_URL)
 from context.client.ContextClient import ContextClient
 from context.proto.context_pb2 import (
     Context, ContextEvent, ContextId, Device, DeviceEvent, DeviceId, DeviceOperationalStatusEnum, Empty,
     EventTypeEnum, Link, LinkEvent, LinkId, Service, ServiceEvent, ServiceId, ServiceStatusEnum, ServiceTypeEnum,
     Topology, TopologyEvent, TopologyId)
+from context.service.database.Tools import (
+    FASTHASHER_DATA_ACCEPTED_FORMAT, FASTHASHER_ITEM_ACCEPTED_FORMAT, fast_hasher)
 from context.service.grpc_server.ContextService import ContextService
+from context.service.Populate import populate
+from context.service.rest_server.Server import Server as RestServer
+from context.service.rest_server.Resources import RESOURCES
 from .example_objects import (
     CONTEXT, CONTEXT_ID, DEVICE1, DEVICE1_ID, DEVICE1_UUID, DEVICE2, DEVICE2_ID, DEVICE2_UUID, LINK_DEV1_DEV2,
     LINK_DEV1_DEV2_ID, LINK_DEV1_DEV2_UUID, SERVICE_DEV1_DEV2, SERVICE_DEV1_DEV2_ID, SERVICE_DEV1_DEV2_UUID, TOPOLOGY,
@@ -21,7 +31,8 @@ from .example_objects import (
 LOGGER = logging.getLogger(__name__)
 LOGGER.setLevel(logging.DEBUG)
 
-GRPC_PORT = 10000 + GRPC_SERVICE_PORT # avoid privileged ports
+GRPC_PORT    = 10000 + GRPC_SERVICE_PORT    # avoid privileged ports
+RESTAPI_PORT = 10000 + RESTAPI_SERVICE_PORT # avoid privileged ports
 
 REDIS_CONFIG = {
     'REDIS_SERVICE_HOST': '10.1.7.194',
@@ -45,7 +56,7 @@ def context_db_mb(request) -> Tuple[Database, MessageBroker]:
     _message_broker.terminate()
 
 @pytest.fixture(scope='session')
-def context_service(context_db_mb : Tuple[Database, MessageBroker]): # pylint: disable=redefined-outer-name
+def context_service_grpc(context_db_mb : Tuple[Database, MessageBroker]): # pylint: disable=redefined-outer-name
     _service = ContextService(
         context_db_mb[0], context_db_mb[1], port=GRPC_PORT, max_workers=GRPC_MAX_WORKERS,
         grace_period=GRPC_GRACE_PERIOD)
@@ -54,21 +65,40 @@ def context_service(context_db_mb : Tuple[Database, MessageBroker]): # pylint: d
     _service.stop()
 
 @pytest.fixture(scope='session')
-def context_client(context_service : ContextService): # pylint: disable=redefined-outer-name
+def context_service_rest(context_db_mb : Tuple[Database, MessageBroker]): # pylint: disable=redefined-outer-name
+    database = context_db_mb[0]
+    _rest_server = RestServer(port=RESTAPI_PORT, base_url=RESTAPI_BASE_URL)
+    for endpoint_name, resource_class, resource_url in RESOURCES:
+        _rest_server.add_resource(resource_class, resource_url, endpoint=endpoint_name, resource_class_args=(database,))
+    _rest_server.start()
+    time.sleep(1) # bring time for the server to start
+    yield _rest_server
+    _rest_server.shutdown()
+    _rest_server.join()
+
+@pytest.fixture(scope='session')
+def context_client_grpc(context_service_grpc : ContextService): # pylint: disable=redefined-outer-name
     _client = ContextClient(address='127.0.0.1', port=GRPC_PORT)
     yield _client
     _client.close()
 
+def do_rest_request(url : str):
+    request_url = 'http://127.0.0.1:{:s}{:s}{:s}'.format(str(RESTAPI_PORT), str(RESTAPI_BASE_URL), url)
+    LOGGER.warning('Request: GET {:s}'.format(str(request_url)))
+    reply = requests.get(request_url)
+    LOGGER.warning('Reply: {:s}'.format(str(reply.text)))
+    assert reply.status_code == 200, 'Reply failed with code {}'.format(reply.status_code)
+    return reply.json()
 
 class EventsCollector:
-    def __init__(self, context_client : ContextClient) -> None: # pylint: disable=redefined-outer-name
+    def __init__(self, context_client_grpc : ContextClient) -> None: # pylint: disable=redefined-outer-name
         self._events_queue = Queue()
 
-        self._context_stream  = context_client.GetContextEvents(Empty())
-        self._topology_stream = context_client.GetTopologyEvents(Empty())
-        self._device_stream   = context_client.GetDeviceEvents(Empty())
-        self._link_stream     = context_client.GetLinkEvents(Empty())
-        self._service_stream  = context_client.GetServiceEvents(Empty())
+        self._context_stream  = context_client_grpc.GetContextEvents(Empty())
+        self._topology_stream = context_client_grpc.GetTopologyEvents(Empty())
+        self._device_stream   = context_client_grpc.GetDeviceEvents(Empty())
+        self._link_stream     = context_client_grpc.GetLinkEvents(Empty())
+        self._service_stream  = context_client_grpc.GetServiceEvents(Empty())
 
         self._context_thread  = threading.Thread(target=self._collect, args=(self._context_stream ,), daemon=False)
         self._topology_thread = threading.Thread(target=self._collect, args=(self._topology_stream,), daemon=False)
@@ -108,8 +138,10 @@ class EventsCollector:
         self._service_thread.join()
 
 
-def test_context(
-    context_client : ContextClient,                     # pylint: disable=redefined-outer-name
+# ----- Test gRPC methods ----------------------------------------------------------------------------------------------
+
+def test_grpc_context(
+    context_client_grpc : ContextClient,                     # pylint: disable=redefined-outer-name
     context_db_mb : Tuple[Database, MessageBroker]):    # pylint: disable=redefined-outer-name
     context_database = context_db_mb[0]
 
@@ -117,20 +149,20 @@ def test_context(
     context_database.clear_all()
 
     # ----- Initialize the EventsCollector -----------------------------------------------------------------------------
-    events_collector = EventsCollector(context_client)
+    events_collector = EventsCollector(context_client_grpc)
     events_collector.start()
 
     # ----- Get when the object does not exist -------------------------------------------------------------------------
     with pytest.raises(grpc.RpcError) as e:
-        context_client.GetContext(ContextId(**CONTEXT_ID))
+        context_client_grpc.GetContext(ContextId(**CONTEXT_ID))
     assert e.value.code() == grpc.StatusCode.NOT_FOUND
     assert e.value.details() == 'Context({:s}) not found'.format(DEFAULT_CONTEXT_UUID)
 
     # ----- List when the object does not exist ------------------------------------------------------------------------
-    response = context_client.ListContextIds(Empty())
+    response = context_client_grpc.ListContextIds(Empty())
     assert len(response.context_ids) == 0
 
-    response = context_client.ListContexts(Empty())
+    response = context_client_grpc.ListContexts(Empty())
     assert len(response.contexts) == 0
 
     # ----- Dump state of database before create the object ------------------------------------------------------------
@@ -142,9 +174,31 @@ def test_context(
     assert len(db_entries) == 0
 
     # ----- Create the object ------------------------------------------------------------------------------------------
-    response = context_client.SetContext(Context(**CONTEXT))
+    response = context_client_grpc.SetContext(Context(**CONTEXT))
     assert response.context_uuid.uuid == DEFAULT_CONTEXT_UUID
 
+    with pytest.raises(grpc.RpcError) as e:
+        WRONG_TOPOLOGY_ID = copy.deepcopy(TOPOLOGY_ID)
+        WRONG_TOPOLOGY_ID['context_id']['context_uuid']['uuid'] = 'wrong-context-uuid'
+        WRONG_CONTEXT = copy.deepcopy(CONTEXT)
+        WRONG_CONTEXT['topology_ids'].append(WRONG_TOPOLOGY_ID)
+        context_client_grpc.SetContext(Context(**WRONG_CONTEXT))
+    assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
+    msg = 'request.topology_ids[0].context_id.context_uuid.uuid(wrong-context-uuid) is invalid; '\
+          'should be == request.context_id.context_uuid.uuid(admin)'
+    assert e.value.details() == msg
+
+    with pytest.raises(grpc.RpcError) as e:
+        WRONG_SERVICE_ID = copy.deepcopy(SERVICE_DEV1_DEV2_ID)
+        WRONG_SERVICE_ID['context_id']['context_uuid']['uuid'] = 'wrong-context-uuid'
+        WRONG_CONTEXT = copy.deepcopy(CONTEXT)
+        WRONG_CONTEXT['service_ids'].append(WRONG_SERVICE_ID)
+        context_client_grpc.SetContext(Context(**WRONG_CONTEXT))
+    assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
+    msg = 'request.service_ids[0].context_id.context_uuid.uuid(wrong-context-uuid) is invalid; '\
+          'should be == request.context_id.context_uuid.uuid(admin)'
+    assert e.value.details() == msg
+
     # ----- Check create event -----------------------------------------------------------------------------------------
     event = events_collector.get_event(block=True)
     assert isinstance(event, ContextEvent)
@@ -152,7 +206,7 @@ def test_context(
     assert event.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
 
     # ----- Update the object ------------------------------------------------------------------------------------------
-    response = context_client.SetContext(Context(**CONTEXT))
+    response = context_client_grpc.SetContext(Context(**CONTEXT))
     assert response.context_uuid.uuid == DEFAULT_CONTEXT_UUID
 
     # ----- Check update event -----------------------------------------------------------------------------------------
@@ -170,24 +224,24 @@ def test_context(
     assert len(db_entries) == 2
 
     # ----- Get when the object exists ---------------------------------------------------------------------------------
-    response = context_client.GetContext(ContextId(**CONTEXT_ID))
+    response = context_client_grpc.GetContext(ContextId(**CONTEXT_ID))
     assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert len(response.topology_ids) == 0
     assert len(response.service_ids) == 0
 
     # ----- List when the object exists --------------------------------------------------------------------------------
-    response = context_client.ListContextIds(Empty())
+    response = context_client_grpc.ListContextIds(Empty())
     assert len(response.context_ids) == 1
     assert response.context_ids[0].context_uuid.uuid == DEFAULT_CONTEXT_UUID
 
-    response = context_client.ListContexts(Empty())
+    response = context_client_grpc.ListContexts(Empty())
     assert len(response.contexts) == 1
     assert response.contexts[0].context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert len(response.contexts[0].topology_ids) == 0
     assert len(response.contexts[0].service_ids) == 0
 
     # ----- Remove the object ------------------------------------------------------------------------------------------
-    context_client.RemoveContext(ContextId(**CONTEXT_ID))
+    context_client_grpc.RemoveContext(ContextId(**CONTEXT_ID))
 
     # ----- Check remove event -----------------------------------------------------------------------------------------
     event = events_collector.get_event(block=True)
@@ -207,8 +261,8 @@ def test_context(
     assert len(db_entries) == 0
 
 
-def test_topology(
-    context_client : ContextClient,                     # pylint: disable=redefined-outer-name
+def test_grpc_topology(
+    context_client_grpc : ContextClient,                     # pylint: disable=redefined-outer-name
     context_db_mb : Tuple[Database, MessageBroker]):    # pylint: disable=redefined-outer-name
     context_database = context_db_mb[0]
 
@@ -216,11 +270,11 @@ def test_topology(
     context_database.clear_all()
 
     # ----- Initialize the EventsCollector -----------------------------------------------------------------------------
-    events_collector = EventsCollector(context_client)
+    events_collector = EventsCollector(context_client_grpc)
     events_collector.start()
 
     # ----- Prepare dependencies for the test and capture related events -----------------------------------------------
-    response = context_client.SetContext(Context(**CONTEXT))
+    response = context_client_grpc.SetContext(Context(**CONTEXT))
     assert response.context_uuid.uuid == DEFAULT_CONTEXT_UUID
 
     event = events_collector.get_event(block=True)
@@ -230,15 +284,15 @@ def test_topology(
 
     # ----- Get when the object does not exist -------------------------------------------------------------------------
     with pytest.raises(grpc.RpcError) as e:
-        context_client.GetTopology(TopologyId(**TOPOLOGY_ID))
+        context_client_grpc.GetTopology(TopologyId(**TOPOLOGY_ID))
     assert e.value.code() == grpc.StatusCode.NOT_FOUND
     assert e.value.details() == 'Topology({:s}/{:s}) not found'.format(DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID)
 
     # ----- List when the object does not exist ------------------------------------------------------------------------
-    response = context_client.ListTopologyIds(ContextId(**CONTEXT_ID))
+    response = context_client_grpc.ListTopologyIds(ContextId(**CONTEXT_ID))
     assert len(response.topology_ids) == 0
 
-    response = context_client.ListTopologies(ContextId(**CONTEXT_ID))
+    response = context_client_grpc.ListTopologies(ContextId(**CONTEXT_ID))
     assert len(response.topologies) == 0
 
     # ----- Dump state of database before create the object ------------------------------------------------------------
@@ -250,10 +304,15 @@ def test_topology(
     assert len(db_entries) == 2
 
     # ----- Create the object ------------------------------------------------------------------------------------------
-    response = context_client.SetTopology(Topology(**TOPOLOGY))
+    response = context_client_grpc.SetTopology(Topology(**TOPOLOGY))
     assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert response.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
 
+    CONTEXT_WITH_TOPOLOGY = copy.deepcopy(CONTEXT)
+    CONTEXT_WITH_TOPOLOGY['topology_ids'].append(TOPOLOGY_ID)
+    response = context_client_grpc.SetContext(Context(**CONTEXT_WITH_TOPOLOGY))
+    assert response.context_uuid.uuid == DEFAULT_CONTEXT_UUID
+
     # ----- Check create event -----------------------------------------------------------------------------------------
     event = events_collector.get_event(block=True)
     assert isinstance(event, TopologyEvent)
@@ -261,8 +320,13 @@ def test_topology(
     assert event.topology_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert event.topology_id.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
 
+    event = events_collector.get_event(block=True)
+    assert isinstance(event, ContextEvent)
+    assert event.event.event_type == EventTypeEnum.EVENTTYPE_UPDATE
+    assert event.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
+
     # ----- Update the object ------------------------------------------------------------------------------------------
-    response = context_client.SetTopology(Topology(**TOPOLOGY))
+    response = context_client_grpc.SetTopology(Topology(**TOPOLOGY))
     assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert response.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
 
@@ -282,19 +346,19 @@ def test_topology(
     assert len(db_entries) == 5
 
     # ----- Get when the object exists ---------------------------------------------------------------------------------
-    response = context_client.GetTopology(TopologyId(**TOPOLOGY_ID))
+    response = context_client_grpc.GetTopology(TopologyId(**TOPOLOGY_ID))
     assert response.topology_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert response.topology_id.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
     assert len(response.device_ids) == 0
     assert len(response.link_ids) == 0
 
     # ----- List when the object exists --------------------------------------------------------------------------------
-    response = context_client.ListTopologyIds(ContextId(**CONTEXT_ID))
+    response = context_client_grpc.ListTopologyIds(ContextId(**CONTEXT_ID))
     assert len(response.topology_ids) == 1
     assert response.topology_ids[0].context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert response.topology_ids[0].topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
 
-    response = context_client.ListTopologies(ContextId(**CONTEXT_ID))
+    response = context_client_grpc.ListTopologies(ContextId(**CONTEXT_ID))
     assert len(response.topologies) == 1
     assert response.topologies[0].topology_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert response.topologies[0].topology_id.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
@@ -302,8 +366,8 @@ def test_topology(
     assert len(response.topologies[0].link_ids) == 0
 
     # ----- Remove the object ------------------------------------------------------------------------------------------
-    context_client.RemoveTopology(TopologyId(**TOPOLOGY_ID))
-    context_client.RemoveContext(ContextId(**CONTEXT_ID))
+    context_client_grpc.RemoveTopology(TopologyId(**TOPOLOGY_ID))
+    context_client_grpc.RemoveContext(ContextId(**CONTEXT_ID))
 
     # ----- Check remove event -----------------------------------------------------------------------------------------
     event = events_collector.get_event(block=True)
@@ -329,8 +393,8 @@ def test_topology(
     assert len(db_entries) == 0
 
 
-def test_device(
-    context_client : ContextClient,                     # pylint: disable=redefined-outer-name
+def test_grpc_device(
+    context_client_grpc : ContextClient,                     # pylint: disable=redefined-outer-name
     context_db_mb : Tuple[Database, MessageBroker]):    # pylint: disable=redefined-outer-name
     context_database = context_db_mb[0]
 
@@ -338,14 +402,14 @@ def test_device(
     context_database.clear_all()
 
     # ----- Initialize the EventsCollector -----------------------------------------------------------------------------
-    events_collector = EventsCollector(context_client)
+    events_collector = EventsCollector(context_client_grpc)
     events_collector.start()
 
     # ----- Prepare dependencies for the test and capture related events -----------------------------------------------
-    response = context_client.SetContext(Context(**CONTEXT))
+    response = context_client_grpc.SetContext(Context(**CONTEXT))
     assert response.context_uuid.uuid == DEFAULT_CONTEXT_UUID
 
-    response = context_client.SetTopology(Topology(**TOPOLOGY))
+    response = context_client_grpc.SetTopology(Topology(**TOPOLOGY))
     assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert response.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
 
@@ -362,15 +426,15 @@ def test_device(
 
     # ----- Get when the object does not exist -------------------------------------------------------------------------
     with pytest.raises(grpc.RpcError) as e:
-        context_client.GetDevice(DeviceId(**DEVICE1_ID))
+        context_client_grpc.GetDevice(DeviceId(**DEVICE1_ID))
     assert e.value.code() == grpc.StatusCode.NOT_FOUND
     assert e.value.details() == 'Device({:s}) not found'.format(DEVICE1_UUID)
 
     # ----- List when the object does not exist ------------------------------------------------------------------------
-    response = context_client.ListDeviceIds(Empty())
+    response = context_client_grpc.ListDeviceIds(Empty())
     assert len(response.device_ids) == 0
 
-    response = context_client.ListDevices(Empty())
+    response = context_client_grpc.ListDevices(Empty())
     assert len(response.devices) == 0
 
     # ----- Dump state of database before create the object ------------------------------------------------------------
@@ -382,7 +446,16 @@ def test_device(
     assert len(db_entries) == 5
 
     # ----- Create the object ------------------------------------------------------------------------------------------
-    response = context_client.SetDevice(Device(**DEVICE1))
+    with pytest.raises(grpc.RpcError) as e:
+        WRONG_DEVICE = copy.deepcopy(DEVICE1)
+        WRONG_DEVICE['device_endpoints'][0]['endpoint_id']['device_id']['device_uuid']['uuid'] = 'wrong-device-uuid'
+        context_client_grpc.SetDevice(Device(**WRONG_DEVICE))
+    assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
+    msg = 'request.device_endpoints[0].device_id.device_uuid.uuid(wrong-device-uuid) is invalid; '\
+          'should be == request.device_id.device_uuid.uuid(DEV1)'
+    assert e.value.details() == msg
+
+    response = context_client_grpc.SetDevice(Device(**DEVICE1))
     assert response.device_uuid.uuid == DEVICE1_UUID
 
     # ----- Check create event -----------------------------------------------------------------------------------------
@@ -392,7 +465,7 @@ def test_device(
     assert event.device_id.device_uuid.uuid == DEVICE1_UUID
 
     # ----- Update the object ------------------------------------------------------------------------------------------
-    response = context_client.SetDevice(Device(**DEVICE1))
+    response = context_client_grpc.SetDevice(Device(**DEVICE1))
     assert response.device_uuid.uuid == DEVICE1_UUID
 
     # ----- Check update event -----------------------------------------------------------------------------------------
@@ -410,7 +483,7 @@ def test_device(
     assert len(db_entries) == 25
 
     # ----- Get when the object exists ---------------------------------------------------------------------------------
-    response = context_client.GetDevice(DeviceId(**DEVICE1_ID))
+    response = context_client_grpc.GetDevice(DeviceId(**DEVICE1_ID))
     assert response.device_id.device_uuid.uuid == DEVICE1_UUID
     assert response.device_type == 'packet-router'
     assert len(response.device_config.config_rules) == 3
@@ -419,11 +492,11 @@ def test_device(
     assert len(response.device_endpoints) == 3
 
     # ----- List when the object exists --------------------------------------------------------------------------------
-    response = context_client.ListDeviceIds(Empty())
+    response = context_client_grpc.ListDeviceIds(Empty())
     assert len(response.device_ids) == 1
     assert response.device_ids[0].device_uuid.uuid == DEVICE1_UUID
 
-    response = context_client.ListDevices(Empty())
+    response = context_client_grpc.ListDevices(Empty())
     assert len(response.devices) == 1
     assert response.devices[0].device_id.device_uuid.uuid == DEVICE1_UUID
     assert response.devices[0].device_type == 'packet-router'
@@ -435,7 +508,7 @@ def test_device(
     # ----- Create object relation -------------------------------------------------------------------------------------
     TOPOLOGY_WITH_DEVICE = copy.deepcopy(TOPOLOGY)
     TOPOLOGY_WITH_DEVICE['device_ids'].append(DEVICE1_ID)
-    response = context_client.SetTopology(Topology(**TOPOLOGY_WITH_DEVICE))
+    response = context_client_grpc.SetTopology(Topology(**TOPOLOGY_WITH_DEVICE))
     assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert response.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
 
@@ -447,7 +520,7 @@ def test_device(
     assert response.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
 
     # ----- Check relation was created ---------------------------------------------------------------------------------
-    response = context_client.GetTopology(TopologyId(**TOPOLOGY_ID))
+    response = context_client_grpc.GetTopology(TopologyId(**TOPOLOGY_ID))
     assert response.topology_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert response.topology_id.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
     assert len(response.device_ids) == 1
@@ -463,9 +536,9 @@ def test_device(
     assert len(db_entries) == 25
 
     # ----- Remove the object ------------------------------------------------------------------------------------------
-    context_client.RemoveDevice(DeviceId(**DEVICE1_ID))
-    context_client.RemoveTopology(TopologyId(**TOPOLOGY_ID))
-    context_client.RemoveContext(ContextId(**CONTEXT_ID))
+    context_client_grpc.RemoveDevice(DeviceId(**DEVICE1_ID))
+    context_client_grpc.RemoveTopology(TopologyId(**TOPOLOGY_ID))
+    context_client_grpc.RemoveContext(ContextId(**CONTEXT_ID))
 
     # ----- Check remove event -----------------------------------------------------------------------------------------
     event = events_collector.get_event(block=True)
@@ -496,8 +569,8 @@ def test_device(
     assert len(db_entries) == 0
 
 
-def test_link(
-    context_client : ContextClient,                     # pylint: disable=redefined-outer-name
+def test_grpc_link(
+    context_client_grpc : ContextClient,                     # pylint: disable=redefined-outer-name
     context_db_mb : Tuple[Database, MessageBroker]):    # pylint: disable=redefined-outer-name
     context_database = context_db_mb[0]
 
@@ -505,21 +578,21 @@ def test_link(
     context_database.clear_all()
 
     # ----- Initialize the EventsCollector -----------------------------------------------------------------------------
-    events_collector = EventsCollector(context_client)
+    events_collector = EventsCollector(context_client_grpc)
     events_collector.start()
 
     # ----- Prepare dependencies for the test and capture related events -----------------------------------------------
-    response = context_client.SetContext(Context(**CONTEXT))
+    response = context_client_grpc.SetContext(Context(**CONTEXT))
     assert response.context_uuid.uuid == DEFAULT_CONTEXT_UUID
 
-    response = context_client.SetTopology(Topology(**TOPOLOGY))
+    response = context_client_grpc.SetTopology(Topology(**TOPOLOGY))
     assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert response.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
 
-    response = context_client.SetDevice(Device(**DEVICE1))
+    response = context_client_grpc.SetDevice(Device(**DEVICE1))
     assert response.device_uuid.uuid == DEVICE1_UUID
 
-    response = context_client.SetDevice(Device(**DEVICE2))
+    response = context_client_grpc.SetDevice(Device(**DEVICE2))
     assert response.device_uuid.uuid == DEVICE2_UUID
 
     event = events_collector.get_event(block=True)
@@ -545,15 +618,15 @@ def test_link(
 
     # ----- Get when the object does not exist -------------------------------------------------------------------------
     with pytest.raises(grpc.RpcError) as e:
-        context_client.GetLink(LinkId(**LINK_DEV1_DEV2_ID))
+        context_client_grpc.GetLink(LinkId(**LINK_DEV1_DEV2_ID))
     assert e.value.code() == grpc.StatusCode.NOT_FOUND
     assert e.value.details() == 'Link({:s}) not found'.format(LINK_DEV1_DEV2_UUID)
 
     # ----- List when the object does not exist ------------------------------------------------------------------------
-    response = context_client.ListLinkIds(Empty())
+    response = context_client_grpc.ListLinkIds(Empty())
     assert len(response.link_ids) == 0
 
-    response = context_client.ListLinks(Empty())
+    response = context_client_grpc.ListLinks(Empty())
     assert len(response.links) == 0
 
     # ----- Dump state of database before create the object ------------------------------------------------------------
@@ -565,7 +638,7 @@ def test_link(
     assert len(db_entries) == 38
 
     # ----- Create the object ------------------------------------------------------------------------------------------
-    response = context_client.SetLink(Link(**LINK_DEV1_DEV2))
+    response = context_client_grpc.SetLink(Link(**LINK_DEV1_DEV2))
     assert response.link_uuid.uuid == LINK_DEV1_DEV2_UUID
 
     # ----- Check create event -----------------------------------------------------------------------------------------
@@ -575,7 +648,7 @@ def test_link(
     assert event.link_id.link_uuid.uuid == LINK_DEV1_DEV2_UUID
 
     # ----- Update the object ------------------------------------------------------------------------------------------
-    response = context_client.SetLink(Link(**LINK_DEV1_DEV2))
+    response = context_client_grpc.SetLink(Link(**LINK_DEV1_DEV2))
     assert response.link_uuid.uuid == LINK_DEV1_DEV2_UUID
 
     # ----- Check update event -----------------------------------------------------------------------------------------
@@ -593,16 +666,16 @@ def test_link(
     assert len(db_entries) == 48
 
     # ----- Get when the object exists ---------------------------------------------------------------------------------
-    response = context_client.GetLink(LinkId(**LINK_DEV1_DEV2_ID))
+    response = context_client_grpc.GetLink(LinkId(**LINK_DEV1_DEV2_ID))
     assert response.link_id.link_uuid.uuid == LINK_DEV1_DEV2_UUID
     assert len(response.link_endpoint_ids) == 2
 
     # ----- List when the object exists --------------------------------------------------------------------------------
-    response = context_client.ListLinkIds(Empty())
+    response = context_client_grpc.ListLinkIds(Empty())
     assert len(response.link_ids) == 1
     assert response.link_ids[0].link_uuid.uuid == LINK_DEV1_DEV2_UUID
 
-    response = context_client.ListLinks(Empty())
+    response = context_client_grpc.ListLinks(Empty())
     assert len(response.links) == 1
     assert response.links[0].link_id.link_uuid.uuid == LINK_DEV1_DEV2_UUID
     assert len(response.links[0].link_endpoint_ids) == 2
@@ -610,7 +683,7 @@ def test_link(
     # ----- Create object relation -------------------------------------------------------------------------------------
     TOPOLOGY_WITH_LINK = copy.deepcopy(TOPOLOGY)
     TOPOLOGY_WITH_LINK['link_ids'].append(LINK_DEV1_DEV2_ID)
-    response = context_client.SetTopology(Topology(**TOPOLOGY_WITH_LINK))
+    response = context_client_grpc.SetTopology(Topology(**TOPOLOGY_WITH_LINK))
     assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert response.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
 
@@ -622,7 +695,7 @@ def test_link(
     assert response.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
 
     # ----- Check relation was created ---------------------------------------------------------------------------------
-    response = context_client.GetTopology(TopologyId(**TOPOLOGY_ID))
+    response = context_client_grpc.GetTopology(TopologyId(**TOPOLOGY_ID))
     assert response.topology_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert response.topology_id.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
     assert len(response.device_ids) == 2
@@ -639,11 +712,11 @@ def test_link(
     assert len(db_entries) == 48
 
     # ----- Remove the object ------------------------------------------------------------------------------------------
-    context_client.RemoveLink(LinkId(**LINK_DEV1_DEV2_ID))
-    context_client.RemoveDevice(DeviceId(**DEVICE1_ID))
-    context_client.RemoveDevice(DeviceId(**DEVICE2_ID))
-    context_client.RemoveTopology(TopologyId(**TOPOLOGY_ID))
-    context_client.RemoveContext(ContextId(**CONTEXT_ID))
+    context_client_grpc.RemoveLink(LinkId(**LINK_DEV1_DEV2_ID))
+    context_client_grpc.RemoveDevice(DeviceId(**DEVICE1_ID))
+    context_client_grpc.RemoveDevice(DeviceId(**DEVICE2_ID))
+    context_client_grpc.RemoveTopology(TopologyId(**TOPOLOGY_ID))
+    context_client_grpc.RemoveContext(ContextId(**CONTEXT_ID))
 
     # ----- Check remove event -----------------------------------------------------------------------------------------
     event = events_collector.get_event(block=True)
@@ -684,8 +757,8 @@ def test_link(
     assert len(db_entries) == 0
 
 
-def test_service(
-    context_client : ContextClient,                     # pylint: disable=redefined-outer-name
+def test_grpc_service(
+    context_client_grpc : ContextClient,                     # pylint: disable=redefined-outer-name
     context_db_mb : Tuple[Database, MessageBroker]):    # pylint: disable=redefined-outer-name
     context_database = context_db_mb[0]
 
@@ -693,21 +766,21 @@ def test_service(
     context_database.clear_all()
 
     # ----- Initialize the EventsCollector -----------------------------------------------------------------------------
-    events_collector = EventsCollector(context_client)
+    events_collector = EventsCollector(context_client_grpc)
     events_collector.start()
 
     # ----- Prepare dependencies for the test and capture related events -----------------------------------------------
-    response = context_client.SetContext(Context(**CONTEXT))
+    response = context_client_grpc.SetContext(Context(**CONTEXT))
     assert response.context_uuid.uuid == DEFAULT_CONTEXT_UUID
 
-    response = context_client.SetTopology(Topology(**TOPOLOGY))
+    response = context_client_grpc.SetTopology(Topology(**TOPOLOGY))
     assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert response.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
 
-    response = context_client.SetDevice(Device(**DEVICE1))
+    response = context_client_grpc.SetDevice(Device(**DEVICE1))
     assert response.device_uuid.uuid == DEVICE1_UUID
 
-    response = context_client.SetDevice(Device(**DEVICE2))
+    response = context_client_grpc.SetDevice(Device(**DEVICE2))
     assert response.device_uuid.uuid == DEVICE2_UUID
 
     event = events_collector.get_event(block=True)
@@ -733,15 +806,15 @@ def test_service(
 
     # ----- Get when the object does not exist -------------------------------------------------------------------------
     with pytest.raises(grpc.RpcError) as e:
-        context_client.GetService(ServiceId(**SERVICE_DEV1_DEV2_ID))
+        context_client_grpc.GetService(ServiceId(**SERVICE_DEV1_DEV2_ID))
     assert e.value.code() == grpc.StatusCode.NOT_FOUND
     assert e.value.details() == 'Service({:s}/{:s}) not found'.format(DEFAULT_CONTEXT_UUID, SERVICE_DEV1_DEV2_UUID)
 
     # ----- List when the object does not exist ------------------------------------------------------------------------
-    response = context_client.ListServiceIds(ContextId(**CONTEXT_ID))
+    response = context_client_grpc.ListServiceIds(ContextId(**CONTEXT_ID))
     assert len(response.service_ids) == 0
 
-    response = context_client.ListServices(ContextId(**CONTEXT_ID))
+    response = context_client_grpc.ListServices(ContextId(**CONTEXT_ID))
     assert len(response.services) == 0
 
     # ----- Dump state of database before create the object ------------------------------------------------------------
@@ -753,10 +826,25 @@ def test_service(
     assert len(db_entries) == 38
 
     # ----- Create the object ------------------------------------------------------------------------------------------
-    response = context_client.SetService(Service(**SERVICE_DEV1_DEV2))
+    with pytest.raises(grpc.RpcError) as e:
+        WRONG_SERVICE = copy.deepcopy(SERVICE_DEV1_DEV2)
+        WRONG_SERVICE['service_endpoint_ids'][0]\
+            ['topology_id']['context_id']['context_uuid']['uuid'] = 'wrong-context-uuid'
+        context_client_grpc.SetService(Service(**WRONG_SERVICE))
+    assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
+    msg = 'request.service_endpoint_ids[0].topology_id.context_id.context_uuid.uuid(wrong-context-uuid) is invalid; '\
+          'should be == request.service_id.context_id.context_uuid.uuid(admin)'
+    assert e.value.details() == msg
+
+    response = context_client_grpc.SetService(Service(**SERVICE_DEV1_DEV2))
     assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert response.service_uuid.uuid == SERVICE_DEV1_DEV2_UUID
 
+    CONTEXT_WITH_SERVICE = copy.deepcopy(CONTEXT)
+    CONTEXT_WITH_SERVICE['service_ids'].append(SERVICE_DEV1_DEV2_ID)
+    response = context_client_grpc.SetContext(Context(**CONTEXT_WITH_SERVICE))
+    assert response.context_uuid.uuid == DEFAULT_CONTEXT_UUID
+
     # ----- Check create event -----------------------------------------------------------------------------------------
     event = events_collector.get_event(block=True)
     assert isinstance(event, ServiceEvent)
@@ -764,8 +852,13 @@ def test_service(
     assert event.service_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert event.service_id.service_uuid.uuid == SERVICE_DEV1_DEV2_UUID
 
+    event = events_collector.get_event(block=True)
+    assert isinstance(event, ContextEvent)
+    assert event.event.event_type == EventTypeEnum.EVENTTYPE_UPDATE
+    assert event.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
+
     # ----- Update the object ------------------------------------------------------------------------------------------
-    response = context_client.SetService(Service(**SERVICE_DEV1_DEV2))
+    response = context_client_grpc.SetService(Service(**SERVICE_DEV1_DEV2))
     assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert response.service_uuid.uuid == SERVICE_DEV1_DEV2_UUID
 
@@ -785,7 +878,7 @@ def test_service(
     assert len(db_entries) == 57
 
     # ----- Get when the object exists ---------------------------------------------------------------------------------
-    response = context_client.GetService(ServiceId(**SERVICE_DEV1_DEV2_ID))
+    response = context_client_grpc.GetService(ServiceId(**SERVICE_DEV1_DEV2_ID))
     assert response.service_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert response.service_id.service_uuid.uuid == SERVICE_DEV1_DEV2_UUID
     assert response.service_type == ServiceTypeEnum.SERVICETYPE_L3NM
@@ -795,12 +888,12 @@ def test_service(
     assert len(response.service_config.config_rules) == 3
 
     # ----- List when the object exists --------------------------------------------------------------------------------
-    response = context_client.ListServiceIds(ContextId(**CONTEXT_ID))
+    response = context_client_grpc.ListServiceIds(ContextId(**CONTEXT_ID))
     assert len(response.service_ids) == 1
     assert response.service_ids[0].context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert response.service_ids[0].service_uuid.uuid == SERVICE_DEV1_DEV2_UUID
 
-    response = context_client.ListServices(ContextId(**CONTEXT_ID))
+    response = context_client_grpc.ListServices(ContextId(**CONTEXT_ID))
     assert len(response.services) == 1
     assert response.services[0].service_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
     assert response.services[0].service_id.service_uuid.uuid == SERVICE_DEV1_DEV2_UUID
@@ -811,11 +904,11 @@ def test_service(
     assert len(response.services[0].service_config.config_rules) == 3
 
     # ----- Remove the object ------------------------------------------------------------------------------------------
-    context_client.RemoveService(ServiceId(**SERVICE_DEV1_DEV2_ID))
-    context_client.RemoveDevice(DeviceId(**DEVICE1_ID))
-    context_client.RemoveDevice(DeviceId(**DEVICE2_ID))
-    context_client.RemoveTopology(TopologyId(**TOPOLOGY_ID))
-    context_client.RemoveContext(ContextId(**CONTEXT_ID))
+    context_client_grpc.RemoveService(ServiceId(**SERVICE_DEV1_DEV2_ID))
+    context_client_grpc.RemoveDevice(DeviceId(**DEVICE1_ID))
+    context_client_grpc.RemoveDevice(DeviceId(**DEVICE2_ID))
+    context_client_grpc.RemoveTopology(TopologyId(**TOPOLOGY_ID))
+    context_client_grpc.RemoveContext(ContextId(**CONTEXT_ID))
 
     # ----- Check remove event -----------------------------------------------------------------------------------------
     event = events_collector.get_event(block=True)
@@ -854,3 +947,113 @@ def test_service(
         LOGGER.info('  [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
     LOGGER.info('-----------------------------------------------------------')
     assert len(db_entries) == 0
+
+
+# ----- Test REST API methods ------------------------------------------------------------------------------------------
+
+def test_rest_populate_database(
+    context_db_mb : Tuple[Database, MessageBroker], # pylint: disable=redefined-outer-name
+    context_service_grpc : ContextService           # pylint: disable=redefined-outer-name
+    ):
+    database = context_db_mb[0]
+    database.clear_all()
+    populate('127.0.0.1', GRPC_PORT)
+
+
+def test_rest_get_context_ids(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+    reply = do_rest_request('/context_ids')
+    validate_context_ids(reply)
+
+def test_rest_get_contexts(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+    reply = do_rest_request('/contexts')
+    validate_contexts(reply)
+
+def test_rest_get_context(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+    context_uuid = urllib.parse.quote('admin')
+    reply = do_rest_request('/context/{:s}'.format(context_uuid))
+    validate_context(reply)
+
+def test_rest_get_topology_ids(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+    context_uuid = urllib.parse.quote('admin')
+    reply = do_rest_request('/context/{:s}/topology_ids'.format(context_uuid))
+    validate_topology_ids(reply)
+
+def test_rest_get_topologies(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+    context_uuid = urllib.parse.quote('admin')
+    reply = do_rest_request('/context/{:s}/topologies'.format(context_uuid))
+    validate_topologies(reply)
+
+def test_rest_get_topology(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+    context_uuid = urllib.parse.quote('admin')
+    topology_uuid = urllib.parse.quote('admin')
+    reply = do_rest_request('/context/{:s}/topology/{:s}'.format(context_uuid, topology_uuid))
+    validate_topology(reply, num_devices=3, num_links=3)
+
+def test_rest_get_service_ids(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+    context_uuid = urllib.parse.quote('admin')
+    reply = do_rest_request('/context/{:s}/service_ids'.format(context_uuid))
+    validate_service_ids(reply)
+
+def test_rest_get_services(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+    context_uuid = urllib.parse.quote('admin')
+    reply = do_rest_request('/context/{:s}/services'.format(context_uuid))
+    validate_services(reply)
+
+def test_rest_get_service(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+    context_uuid = urllib.parse.quote('admin')
+    service_uuid = urllib.parse.quote('SVC:DEV1/EP100-DEV2/EP100', safe='')
+    reply = do_rest_request('/context/{:s}/service/{:s}'.format(context_uuid, service_uuid))
+    validate_service(reply)
+
+def test_rest_get_device_ids(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+    reply = do_rest_request('/device_ids')
+    validate_device_ids(reply)
+
+def test_rest_get_devices(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+    reply = do_rest_request('/devices')
+    validate_devices(reply)
+
+def test_rest_get_device(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+    device_uuid = urllib.parse.quote('DEV1', safe='')
+    reply = do_rest_request('/device/{:s}'.format(device_uuid))
+    validate_device(reply)
+
+def test_rest_get_link_ids(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+    reply = do_rest_request('/link_ids')
+    validate_link_ids(reply)
+
+def test_rest_get_links(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+    reply = do_rest_request('/links')
+    validate_links(reply)
+
+def test_rest_get_link(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
+    link_uuid = urllib.parse.quote('DEV1/EP2 ==> DEV2/EP1', safe='')
+    reply = do_rest_request('/link/{:s}'.format(link_uuid))
+    validate_link(reply)
+
+
+# ----- Test misc. Context internal tools ------------------------------------------------------------------------------
+
+def test_tools_fast_string_hasher():
+    with pytest.raises(TypeError) as e:
+        fast_hasher(27)
+    assert str(e.value) == "data(27) must be " + FASTHASHER_DATA_ACCEPTED_FORMAT + ", found <class 'int'>"
+
+    with pytest.raises(TypeError) as e:
+        fast_hasher({27})
+    assert str(e.value) == "data({27}) must be " + FASTHASHER_DATA_ACCEPTED_FORMAT + ", found <class 'set'>"
+
+    with pytest.raises(TypeError) as e:
+        fast_hasher({'27'})
+    assert str(e.value) == "data({'27'}) must be " + FASTHASHER_DATA_ACCEPTED_FORMAT + ", found <class 'set'>"
+
+    with pytest.raises(TypeError) as e:
+        fast_hasher([27])
+    assert str(e.value) == "data[0](27) must be " + FASTHASHER_ITEM_ACCEPTED_FORMAT + ", found <class 'int'>"
+
+    fast_hasher('hello-world')
+    fast_hasher('hello-world'.encode('UTF-8'))
+    fast_hasher(['hello', 'world'])
+    fast_hasher(('hello', 'world'))
+    fast_hasher(['hello'.encode('UTF-8'), 'world'.encode('UTF-8')])
+    fast_hasher(('hello'.encode('UTF-8'), 'world'.encode('UTF-8')))
diff --git a/src/context/tests/test_unitary_fast_hasher.py b/src/context/tests/test_unitary_fast_hasher.py
deleted file mode 100644
index 94ce3aebe21752c3311a38bb92a285aa83e337f5..0000000000000000000000000000000000000000
--- a/src/context/tests/test_unitary_fast_hasher.py
+++ /dev/null
@@ -1,30 +0,0 @@
-import logging, pytest
-from context.service.database.Tools import (
-    FASTHASHER_DATA_ACCEPTED_FORMAT, FASTHASHER_ITEM_ACCEPTED_FORMAT, fast_hasher)
-
-LOGGER = logging.getLogger(__name__)
-LOGGER.setLevel(logging.DEBUG)
-
-def test_fast_hasher():
-    with pytest.raises(TypeError) as e:
-        fast_hasher(27)
-    assert str(e.value) == "data(27) must be " + FASTHASHER_DATA_ACCEPTED_FORMAT + ", found <class 'int'>"
-
-    with pytest.raises(TypeError) as e:
-        fast_hasher({27})
-    assert str(e.value) == "data({27}) must be " + FASTHASHER_DATA_ACCEPTED_FORMAT + ", found <class 'set'>"
-
-    with pytest.raises(TypeError) as e:
-        fast_hasher({'27'})
-    assert str(e.value) == "data({'27'}) must be " + FASTHASHER_DATA_ACCEPTED_FORMAT + ", found <class 'set'>"
-
-    with pytest.raises(TypeError) as e:
-        fast_hasher([27])
-    assert str(e.value) == "data[0](27) must be " + FASTHASHER_ITEM_ACCEPTED_FORMAT + ", found <class 'int'>"
-
-    fast_hasher('hello-world')
-    fast_hasher('hello-world'.encode('UTF-8'))
-    fast_hasher(['hello', 'world'])
-    fast_hasher(('hello', 'world'))
-    fast_hasher(['hello'.encode('UTF-8'), 'world'.encode('UTF-8')])
-    fast_hasher(('hello'.encode('UTF-8'), 'world'.encode('UTF-8')))
diff --git a/src/context/tests/test_unitary_rest.py b/src/context/tests/test_unitary_rest.py
deleted file mode 100644
index 01c58581a274ac74aa8162d06d4551fbed3a77fa..0000000000000000000000000000000000000000
--- a/src/context/tests/test_unitary_rest.py
+++ /dev/null
@@ -1,57 +0,0 @@
-import logging, pytest, requests, time
-from google.protobuf.json_format import MessageToDict
-from common.orm.Database import Database
-from common.orm.Factory import get_database_backend, BackendEnum
-from context.proto.context_pb2 import Context, Topology
-from context.Config import RESTAPI_SERVICE_PORT, RESTAPI_BASE_URL
-from context.service.rest_server.Server import Server
-from context.service.rest_server.resources.Context import Context
-#from .populate_database import populate_example
-
-LOGGER = logging.getLogger(__name__)
-LOGGER.setLevel(logging.DEBUG)
-
-RESTAPI_PORT = 10000 + RESTAPI_SERVICE_PORT # avoid privileged ports
-
-SCENARIOS = [
-    (BackendEnum.INMEMORY, {}),
-    #(BackendEnum.REDIS,    {
-    #    'REDIS_SERVICE_HOST': '10.1.7.194',
-    #    'REDIS_SERVICE_PORT': 30283,
-    #    'REDIS_DATABASE_ID': 0,
-    #}),
-]
-
-@pytest.fixture(scope='session', ids=[str(scenario[0].value) for scenario in SCENARIOS], params=SCENARIOS)
-def context_database(request):
-    backend,settings = request.param
-    LOGGER.info('Running fixture with backend={}, settings={}...'.format(str(backend), str(settings)))
-    database_backend = get_database_backend(backend=backend, **settings)
-    _database = Database(database_backend)
-    return _database
-
-@pytest.fixture(scope='session')
-def context_service_rest(context_database : Database): # pylint: disable=redefined-outer-name
-    _rest_server = Server(port=RESTAPI_PORT, base_url=RESTAPI_BASE_URL)
-    _rest_server.add_resource(Context, '/context', endpoint='api.context', resource_class_args=(context_database,))
-    _rest_server.start()
-    time.sleep(1) # bring time for the server to start
-    yield _rest_server
-    _rest_server.shutdown()
-    _rest_server.join()
-
-def test_get_topology_completed_rest_api(context_service_rest : Server): # pylint: disable=redefined-outer-name
-    # should work
-    request_url = 'http://127.0.0.1:{}{}/context'.format(RESTAPI_PORT, RESTAPI_BASE_URL)
-    LOGGER.warning('Request: GET {}'.format(str(request_url)))
-    reply = requests.get(request_url)
-    LOGGER.warning('Reply: {}'.format(str(reply.text)))
-    assert reply.status_code == 200, 'Reply failed with code {}'.format(reply.status_code)
-    json_reply = reply.json()
-    topology = MessageToDict(
-        Topology(**json_reply['topologies'][0]),
-        including_default_value_fields=True, preserving_proto_field_name=True,
-        use_integers_for_enums=False)
-    validate_topology(topology)
-    validate_topology_has_devices(topology)
-    validate_topology_has_links(topology)