diff --git a/scripts/run_tests_locally-context.sh b/scripts/run_tests_locally-context.sh
index 9e5ac4b92b5d55509173b23f0896cb108bdd3a1e..a9e601208aa9259219708a5e1ca770232e44faa6 100755
--- a/scripts/run_tests_locally-context.sh
+++ b/scripts/run_tests_locally-context.sh
@@ -22,6 +22,7 @@ RCFILE=$PROJECTDIR/coverage/.coveragerc
 K8S_NAMESPACE="tf-dev"
 K8S_HOSTNAME="kubernetes-master"
 
+kubectl --namespace $K8S_NAMESPACE expose deployment contextservice --port=6379 --name=redis-tests --type=NodePort
 export REDIS_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
 export REDIS_SERVICE_PORT=$(kubectl get service redis-tests --namespace $K8S_NAMESPACE -o 'jsonpath={.spec.ports[?(@.port==6379)].nodePort}')
 
diff --git a/src/context/service/database/ConfigModel.py b/src/context/service/database/ConfigModel.py
index e36fc58cfa2a42425004f6c9766457c5d1c53896..bb2a37467ce3ad451bd29f824a5092ec1ad43cee 100644
--- a/src/context/service/database/ConfigModel.py
+++ b/src/context/service/database/ConfigModel.py
@@ -41,6 +41,11 @@ grpc_to_enum__config_action = functools.partial(
 class ConfigModel(Model): # pylint: disable=abstract-method
     pk = PrimaryKeyField()
 
+    def delete(self) -> None:
+        db_config_rule_pks = self.references(ConfigRuleModel)
+        for pk,_ in db_config_rule_pks: ConfigRuleModel(self.database, pk).delete()
+        super().delete()
+
     def dump(self) -> List[Dict]:
         db_config_rule_pks = self.references(ConfigRuleModel)
         config_rules = [ConfigRuleModel(self.database, pk).dump(include_position=True) for pk,_ in db_config_rule_pks]
diff --git a/src/context/service/database/ConnectionModel.py b/src/context/service/database/ConnectionModel.py
index 1d3f093727fc59b06b13e9f39636bbd9da3b010a..4cbed43a40f3538633216f09060f8a2483fe5e1f 100644
--- a/src/context/service/database/ConnectionModel.py
+++ b/src/context/service/database/ConnectionModel.py
@@ -32,6 +32,11 @@ LOGGER = logging.getLogger(__name__)
 class PathModel(Model): # pylint: disable=abstract-method
     pk = PrimaryKeyField()
 
+    def delete(self) -> None:
+        for db_path_hop_pk,_ in self.references(PathHopModel):
+            PathHopModel(self.database, db_path_hop_pk).delete()
+        super().delete()
+
     def dump(self) -> List[Dict]:
         db_path_hop_pks = self.references(PathHopModel)
         path_hops = [PathHopModel(self.database, pk).dump(include_position=True) for pk,_ in db_path_hop_pks]
@@ -56,6 +61,18 @@ class ConnectionModel(Model):
     service_fk = ForeignKeyField(ServiceModel, required=False)
     path_fk = ForeignKeyField(PathModel, required=True)
 
+    def delete(self) -> None:
+        # pylint: disable=import-outside-toplevel
+        from .RelationModels import ConnectionSubServiceModel
+
+        # Do not remove sub-services automatically. They are supported by real services, so Service component should
+        # deal with the correct removal workflow to deconfigure the devices.
+        for db_connection_sub_service_pk,_ in self.references(ConnectionSubServiceModel):
+            ConnectionSubServiceModel(self.database, db_connection_sub_service_pk).delete()
+
+        super().delete()
+        PathModel(self.database, self.path_fk).delete()
+
     def dump_id(self) -> Dict:
         return {
             'connection_uuid': {'uuid': self.connection_uuid},
@@ -108,7 +125,7 @@ def set_path(
 
     str_path_key = connection_uuid if len(path_name) == 0 else key_to_str([connection_uuid, path_name], separator=':')
     result : Tuple[PathModel, bool] = get_or_create_object(database, PathModel, str_path_key)
-    db_path, created = result
+    db_path, created = result # pylint: disable=unused-variable
 
     db_path_hop_pks : Set[str] = set(map(operator.itemgetter(0), db_path.references(PathHopModel)))
     db_objects : List[Tuple[Union[PathModel, PathHopModel], bool]] = [db_path]
@@ -127,7 +144,7 @@ def set_path(
         db_endpoint : EndPointModel = get_object(database, EndPointModel, str_endpoint_key)
 
         result : Tuple[PathHopModel, bool] = set_path_hop(database, db_path, position, db_endpoint)
-        db_path_hop, updated = result
+        db_path_hop, updated = result # pylint: disable=unused-variable
         db_objects.append(db_path_hop)
         db_path_hop_pks.discard(db_path_hop.instance_key)
 
diff --git a/src/context/service/database/ConstraintModel.py b/src/context/service/database/ConstraintModel.py
index 61310dd57c710d84e500c25bb83e6f59ce78fb94..a35ec250d8a62a8a2534e9f27ddecac801db6eff 100644
--- a/src/context/service/database/ConstraintModel.py
+++ b/src/context/service/database/ConstraintModel.py
@@ -13,11 +13,13 @@
 # limitations under the License.
 
 import logging, operator
-from typing import Dict, List, Tuple, Type, Union
+from enum import Enum
+from typing import Dict, List, Optional, Tuple, Type, Union
 from common.orm.Database import Database
-from common.orm.HighLevel import get_or_create_object, update_or_create_object
+from common.orm.HighLevel import get_object, get_or_create_object, update_or_create_object
 from common.orm.backend.Tools import key_to_str
 from common.orm.fields.BooleanField import BooleanField
+from common.orm.fields.EnumeratedField import EnumeratedField
 from common.orm.fields.FloatField import FloatField
 from common.orm.fields.ForeignKeyField import ForeignKeyField
 from common.orm.fields.IntegerField import IntegerField
@@ -34,101 +36,123 @@ LOGGER = logging.getLogger(__name__)
 class ConstraintsModel(Model): # pylint: disable=abstract-method
     pk = PrimaryKeyField()
 
+    def delete(self) -> None:
+        db_constraint_pks = self.references(ConstraintModel)
+        for pk,_ in db_constraint_pks: ConstraintModel(self.database, pk).delete()
+        super().delete()
+
     def dump(self) -> List[Dict]:
         db_constraint_pks = self.references(ConstraintModel)
         constraints = [ConstraintModel(self.database, pk).dump(include_position=True) for pk,_ in db_constraint_pks]
         constraints = sorted(constraints, key=operator.itemgetter('position'))
         return [remove_dict_key(constraint, 'position') for constraint in constraints]
 
-class ConstraintModel(Model): # pylint: disable=abstract-method
-    pk = PrimaryKeyField()
-    constraints_fk = ForeignKeyField(ConstraintsModel)
-    position = IntegerField(min_value=0, required=True)
-
-    def dump(self, include_position=True) -> Dict: # pylint: disable=arguments-differ
-        result = {}
-        if include_position: result['position'] = self.position
-        return result
-
-class ConstraintCustomModel(ConstraintModel): # pylint: disable=abstract-method
+class ConstraintCustomModel(Model): # pylint: disable=abstract-method
     constraint_type = StringField(required=True, allow_empty=False)
     constraint_value = StringField(required=True, allow_empty=False)
 
-    def dump(self, include_position=True) -> Dict: # pylint: disable=arguments-differ
-        result = {
-            'custom': {
-                'constraint_type': self.constraint_type,
-                'constraint_value': self.constraint_value,
-            },
-        }
-        result.update(super().dump(include_position=include_position))
-        return result
-
-class ConstraintEndpointLocationModel(ConstraintModel): # pylint: disable=abstract-method
+    def dump(self) -> Dict: # pylint: disable=arguments-differ
+        return {'custom': {'constraint_type': self.constraint_type, 'constraint_value': self.constraint_value}}
+
+Union_ConstraintEndpoint = Union[
+    'ConstraintEndpointLocationGpsPositionModel', 'ConstraintEndpointLocationRegionModel',
+    'ConstraintEndpointPriorityModel'
+]
+def dump_endpoint_id(endpoint_constraint : Union_ConstraintEndpoint):
+    db_endpoints_pks = list(endpoint_constraint.references(EndPointModel))
+    num_endpoints = len(db_endpoints_pks)
+    if num_endpoints != 1:
+        raise Exception('Wrong number({:d}) of associated Endpoints with constraint'.format(num_endpoints))
+    db_endpoint = EndPointModel(endpoint_constraint.database, db_endpoints_pks[0])
+    return db_endpoint.dump_id()
+
+class ConstraintEndpointLocationRegionModel(Model): # pylint: disable=abstract-method
     endpoint_fk = ForeignKeyField(EndPointModel)
-
-    def dump(self, include_position=True) -> Dict: # pylint: disable=arguments-differ
-        db_endpoints_pks = list(self.references(EndPointModel))
-        num_endpoints = len(db_endpoints_pks)
-        if num_endpoints != 1:
-            raise Exception('Wrong number({:d}) of associated Endpoints with constraint'.format(num_endpoints))
-        db_endpoint = EndPointModel(self.database, db_endpoints_pks[0])
-        result = {'endpoint_id': db_endpoint.dump_id()}
-        result.update(super().dump(include_position=include_position))
-        return result
-
-class ConstraintEndpointLocationRegionModel(ConstraintEndpointLocationModel): # pylint: disable=abstract-method
     region = StringField(required=True, allow_empty=False)
 
-    def dump(self, include_position=True) -> Dict: # pylint: disable=arguments-differ
-        result = super().dump(include_position=include_position)
-        result['endpoint_location'].setdefault('region', {}).setdefault('region', self.region)
-        return result
+    def dump(self) -> Dict: # pylint: disable=arguments-differ
+        return {'endpoint_location': {'endpoint_id': dump_endpoint_id(self), 'region': self.region}}
 
-class ConstraintEndpointLocationGpsPositionModel(ConstraintEndpointLocationModel): # pylint: disable=abstract-method
+class ConstraintEndpointLocationGpsPositionModel(Model): # pylint: disable=abstract-method
+    endpoint_fk = ForeignKeyField(EndPointModel)
     latitude = FloatField(required=True, min_value=-90.0, max_value=90.0)
     longitude = FloatField(required=True, min_value=-180.0, max_value=180.0)
 
-    def dump(self, include_position=True) -> Dict: # pylint: disable=arguments-differ
-        result = super().dump(include_position=include_position)
-        gps_position = result['endpoint_location'].setdefault('gps_position', {})
-        gps_position['latitude' ] = self.latitude
-        gps_position['longitude'] = self.longitude
-        return result
+    def dump(self) -> Dict: # pylint: disable=arguments-differ
+        gps_position = {'latitude': self.latitude, 'longitude': self.longitude}
+        return {'endpoint_location': {'endpoint_id': dump_endpoint_id(self), 'gps_position': gps_position}}
 
-class ConstraintEndpointPriorityModel(ConstraintModel): # pylint: disable=abstract-method
+class ConstraintEndpointPriorityModel(Model): # pylint: disable=abstract-method
     endpoint_fk = ForeignKeyField(EndPointModel)
     priority = FloatField(required=True)
 
-    def dump(self, include_position=True) -> Dict: # pylint: disable=arguments-differ
-        db_endpoints_pks = list(self.references(EndPointModel))
-        num_endpoints = len(db_endpoints_pks)
-        if num_endpoints != 1:
-            raise Exception('Wrong number({:d}) of associated Endpoints with constraint'.format(num_endpoints))
-        db_endpoint = EndPointModel(self.database, db_endpoints_pks[0])
-        result = {'endpoint_id': db_endpoint.dump_id(), 'priority': self.priority}
-        result.update(super().dump(include_position=include_position))
-        return result
+    def dump(self) -> Dict: # pylint: disable=arguments-differ
+        return {'endpoint_priority': {'endpoint_id': dump_endpoint_id(self), 'priority': self.priority}}
 
-class ConstraintSlaAvailabilityModel(ConstraintModel): # pylint: disable=abstract-method
+class ConstraintSlaAvailabilityModel(Model): # pylint: disable=abstract-method
     num_disjoint_paths = IntegerField(required=True, min_value=1)
     all_active = BooleanField(required=True)
 
+    def dump(self) -> Dict: # pylint: disable=arguments-differ
+        return {'sla_availability': {'num_disjoint_paths': self.num_disjoint_paths, 'all_active': self.all_active}}
+
+# enum values should match name of field in ConstraintModel
+class ConstraintKindEnum(Enum):
+    CUSTOM                        = 'custom'
+    ENDPOINT_LOCATION_REGION      = 'ep_loc_region'
+    ENDPOINT_LOCATION_GPSPOSITION = 'ep_loc_gpspos'
+    ENDPOINT_PRIORITY             = 'ep_priority'
+    SLA_AVAILABILITY              = 'sla_avail'
+
+Union_SpecificConstraint = Union[
+    ConstraintCustomModel, ConstraintEndpointLocationRegionModel, ConstraintEndpointLocationGpsPositionModel,
+    ConstraintEndpointPriorityModel, ConstraintSlaAvailabilityModel,
+]
+
+class ConstraintModel(Model): # pylint: disable=abstract-method
+    pk = PrimaryKeyField()
+    constraints_fk = ForeignKeyField(ConstraintsModel)
+    kind = EnumeratedField(ConstraintKindEnum)
+    position = IntegerField(min_value=0, required=True)
+    constraint_custom_fk        = ForeignKeyField(ConstraintCustomModel, required=False)
+    constraint_ep_loc_region_fk = ForeignKeyField(ConstraintEndpointLocationRegionModel, required=False)
+    constraint_ep_loc_gpspos_fk = ForeignKeyField(ConstraintEndpointLocationGpsPositionModel, required=False)
+    constraint_ep_priority_fk   = ForeignKeyField(ConstraintEndpointPriorityModel, required=False)
+    constraint_sla_avail_fk     = ForeignKeyField(ConstraintSlaAvailabilityModel, required=False)
+
+    def delete(self) -> None:
+        field_name = 'constraint_{:s}_fk'.format(str(self.kind.value))
+        specific_fk_value : Optional[ForeignKeyField] = getattr(self, field_name, None)
+        if specific_fk_value is None:
+            raise Exception('Unable to find constraint key for field_name({:s})'.format(field_name))
+        specific_fk_class = getattr(ConstraintModel, field_name, None)
+        foreign_model_class : Model = specific_fk_class.foreign_model
+        super().delete()
+        get_object(self.database, foreign_model_class, str(specific_fk_value)).delete()
+
     def dump(self, include_position=True) -> Dict: # pylint: disable=arguments-differ
-        result = {'num_disjoint_paths': self.num_disjoint_paths, 'all_active': self.all_active}
-        result.update(super().dump(include_position=include_position))
+        field_name = 'constraint_{:s}_fk'.format(str(self.kind.value))
+        specific_fk_value : Optional[ForeignKeyField] = getattr(self, field_name, None)
+        if specific_fk_value is None:
+            raise Exception('Unable to find constraint key for field_name({:s})'.format(field_name))
+        specific_fk_class = getattr(ConstraintModel, field_name, None)
+        foreign_model_class : Model = specific_fk_class.foreign_model
+        constraint : Union_SpecificConstraint = get_object(self.database, foreign_model_class, str(specific_fk_value))
+        result = constraint.dump()
+        if include_position: result['position'] = self.position
         return result
 
-def parse_constraint_custom(database : Database, grpc_constraint) -> Tuple[Type, str, Dict]:
+Tuple_ConstraintSpecs = Tuple[Type, str, Dict, ConstraintKindEnum]
+def parse_constraint_custom(database : Database, grpc_constraint) -> Tuple_ConstraintSpecs:
     constraint_class = ConstraintCustomModel
     str_constraint_id = grpc_constraint.custom.constraint_type
     constraint_data = {
         'constraint_type' : grpc_constraint.custom.constraint_type,
         'constraint_value': grpc_constraint.custom.constraint_value,
     }
-    return constraint_class, str_constraint_id, constraint_data
+    return constraint_class, str_constraint_id, constraint_data, ConstraintKindEnum.CUSTOM
 
-def parse_constraint_endpoint_location(database : Database, grpc_constraint) -> Tuple[Type, str, Dict]:
+def parse_constraint_endpoint_location(database : Database, grpc_constraint) -> Tuple_ConstraintSpecs:
     grpc_endpoint_id = grpc_constraint.endpoint_location.endpoint_id
     str_endpoint_key, db_endpoint = get_endpoint(database, grpc_endpoint_id)
 
@@ -140,16 +164,17 @@ def parse_constraint_endpoint_location(database : Database, grpc_constraint) ->
     if location_kind == 'region':
         constraint_class = ConstraintEndpointLocationRegionModel
         constraint_data.update({'region': grpc_location.region})
+        return constraint_class, str_constraint_id, constraint_data, ConstraintKindEnum.ENDPOINT_LOCATION_REGION
     elif location_kind == 'gps_position':
         constraint_class = ConstraintEndpointLocationGpsPositionModel
         gps_position = grpc_location.gps_position
         constraint_data.update({'latitude': gps_position.latitude, 'longitude': gps_position.longitude})
+        return constraint_class, str_constraint_id, constraint_data, ConstraintKindEnum.ENDPOINT_LOCATION_GPSPOSITION
     else:
         MSG = 'Location kind {:s} in Constraint of kind endpoint_location is not implemented: {:s}'
         raise NotImplementedError(MSG.format(location_kind, grpc_message_to_json_string(grpc_constraint)))
-    return constraint_class, str_constraint_id, constraint_data
 
-def parse_constraint_endpoint_priority(database : Database, grpc_constraint) -> Tuple[Type, str, Dict]:
+def parse_constraint_endpoint_priority(database : Database, grpc_constraint) -> Tuple_ConstraintSpecs:
     grpc_endpoint_id = grpc_constraint.endpoint_priority.endpoint_id
     str_endpoint_key, db_endpoint = get_endpoint(database, grpc_endpoint_id)
 
@@ -158,16 +183,16 @@ def parse_constraint_endpoint_priority(database : Database, grpc_constraint) ->
     priority = grpc_constraint.endpoint_priority.priority
     constraint_data = {'endpoint_fk': db_endpoint, 'priority': priority}
 
-    return constraint_class, str_constraint_id, constraint_data
+    return constraint_class, str_constraint_id, constraint_data, ConstraintKindEnum.ENDPOINT_PRIORITY
 
-def parse_constraint_sla_availability(database : Database, grpc_constraint) -> Tuple[Type, str, Dict]:
+def parse_constraint_sla_availability(database : Database, grpc_constraint) -> Tuple_ConstraintSpecs:
     constraint_class = ConstraintSlaAvailabilityModel
     str_constraint_id = ''
     constraint_data = {
         'num_disjoint_paths' : grpc_constraint.sla_availability.num_disjoint_paths,
         'all_active': grpc_constraint.sla_availability.all_active,
     }
-    return constraint_class, str_constraint_id, constraint_data
+    return constraint_class, str_constraint_id, constraint_data, ConstraintKindEnum.SLA_AVAILABILITY
 
 CONSTRAINT_PARSERS = {
     'custom'            : parse_constraint_custom,
@@ -176,25 +201,39 @@ CONSTRAINT_PARSERS = {
     'sla_availability'  : parse_constraint_sla_availability,
 }
 
+Union_ConstraintModel = Union[
+    ConstraintCustomModel, ConstraintEndpointLocationGpsPositionModel, ConstraintEndpointLocationRegionModel,
+    ConstraintEndpointPriorityModel, ConstraintSlaAvailabilityModel
+]
+
 def set_constraint(
-    database : Database, db_constraints : ConstraintsModel, grpc_constraint, position : int
-) -> Tuple[Constraint, bool]:
-    constraint_kind = str(grpc_constraint.WhichOneof('constraint'))
+    database : Database, db_constraints : ConstraintsModel, grpc_constraint : Constraint, position : int
+) -> Tuple[Union_ConstraintModel, bool]:
+    grpc_constraint_kind = str(grpc_constraint.WhichOneof('constraint'))
 
-    parser = CONSTRAINT_PARSERS.get(constraint_kind)
+    parser = CONSTRAINT_PARSERS.get(grpc_constraint_kind)
     if parser is None:
         raise NotImplementedError('Constraint of kind {:s} is not implemented: {:s}'.format(
-            constraint_kind, grpc_message_to_json_string(grpc_constraint)))
-
-    constraint_class, str_constraint_id, constraint_data = parser(database, grpc_constraint)
+            grpc_constraint_kind, grpc_message_to_json_string(grpc_constraint)))
 
-    str_constraint_key_hash = fast_hasher(':'.join([constraint_kind, str_constraint_id]))
+    # create specific constraint
+    constraint_class, str_constraint_id, constraint_data, constraint_kind = parser(database, grpc_constraint)
+    str_constraint_key_hash = fast_hasher(':'.join([constraint_kind.value, str_constraint_id]))
     str_constraint_key = key_to_str([db_constraints.pk, str_constraint_key_hash], separator=':')
-    constraint_data.update({'constraints_fk': db_constraints, 'position': position})
+    result : Tuple[Union_ConstraintModel, bool] = update_or_create_object(
+        database, constraint_class, str_constraint_key, constraint_data)
+    db_specific_constraint, updated = result
 
+    # create generic constraint
+    constraint_fk_field_name = 'constraint_{:s}_fk'.format(constraint_kind.value)
+    constraint_data = {
+        'constraints_fk': db_constraints, 'position': position, 'kind': constraint_kind,
+        constraint_fk_field_name: db_specific_constraint
+    }
     result : Tuple[ConstraintModel, bool] = update_or_create_object(
-        database, constraint_class, str_constraint_key, constraint_data)
+        database, ConstraintModel, str_constraint_key, constraint_data)
     db_constraint, updated = result
+
     return db_constraint, updated
 
 def set_constraints(
@@ -208,7 +247,8 @@ def set_constraints(
     db_objects = [(db_constraints, created)]
 
     for position,grpc_constraint in enumerate(grpc_constraints):
-        result : Tuple[ConstraintModel, bool] = set_constraint(database, db_constraints, grpc_constraint, position)
+        result : Tuple[ConstraintModel, bool] = set_constraint(
+            database, db_constraints, grpc_constraint, position)
         db_constraint, updated = result
         db_objects.append((db_constraint, updated))
 
diff --git a/src/context/service/database/DeviceModel.py b/src/context/service/database/DeviceModel.py
index 0f0201190542397a34b68fa217706c904606ead3..0d42326793b44473d8aef3da2c3e9ce8464bd1c4 100644
--- a/src/context/service/database/DeviceModel.py
+++ b/src/context/service/database/DeviceModel.py
@@ -54,6 +54,24 @@ class DeviceModel(Model):
     device_config_fk = ForeignKeyField(ConfigModel)
     device_operational_status = EnumeratedField(ORM_DeviceOperationalStatusEnum, required=True)
 
+    def delete(self) -> None:
+        # pylint: disable=import-outside-toplevel
+        from .EndPointModel import EndPointModel
+        from .RelationModels import TopologyDeviceModel
+
+        for db_endpoint_pk,_ in self.references(EndPointModel):
+            EndPointModel(self.database, db_endpoint_pk).delete()
+
+        for db_topology_device_pk,_ in self.references(TopologyDeviceModel):
+            TopologyDeviceModel(self.database, db_topology_device_pk).delete()
+
+        for db_driver_pk,_ in self.references(DriverModel):
+            DriverModel(self.database, db_driver_pk).delete()
+
+        super().delete()
+
+        ConfigModel(self.database, self.device_config_fk).delete()
+
     def dump_id(self) -> Dict:
         return {'device_uuid': {'uuid': self.device_uuid}}
 
diff --git a/src/context/service/database/EndPointModel.py b/src/context/service/database/EndPointModel.py
index 29ac43db9ae48e8369591b690af3cadf77335334..aeef91b654dfaaaaf14d53f625126632b7303741 100644
--- a/src/context/service/database/EndPointModel.py
+++ b/src/context/service/database/EndPointModel.py
@@ -36,6 +36,11 @@ class EndPointModel(Model):
     endpoint_uuid = StringField(required=True, allow_empty=False)
     endpoint_type = StringField()
 
+    def delete(self) -> None:
+        for db_kpi_sample_type_pk,_ in self.references(KpiSampleTypeModel):
+            KpiSampleTypeModel(self.database, db_kpi_sample_type_pk).delete()
+        super().delete()
+
     def dump_id(self) -> Dict:
         device_id = DeviceModel(self.database, self.device_fk).dump_id()
         result = {
diff --git a/src/context/service/database/LinkModel.py b/src/context/service/database/LinkModel.py
index 742044b9758df297413ad2d0318520c825e8b738..8f1d971c3127371e0d9a1a401d885a02269bd8dd 100644
--- a/src/context/service/database/LinkModel.py
+++ b/src/context/service/database/LinkModel.py
@@ -25,6 +25,18 @@ class LinkModel(Model):
     pk = PrimaryKeyField()
     link_uuid = StringField(required=True, allow_empty=False)
 
+    def delete(self) -> None:
+        #pylint: disable=import-outside-toplevel
+        from .RelationModels import LinkEndPointModel, TopologyLinkModel
+
+        for db_link_endpoint_pk,_ in self.references(LinkEndPointModel):
+            LinkEndPointModel(self.database, db_link_endpoint_pk).delete()
+
+        for db_topology_link_pk,_ in self.references(TopologyLinkModel):
+            TopologyLinkModel(self.database, db_topology_link_pk).delete()
+
+        super().delete()
+
     def dump_id(self) -> Dict:
         return {'link_uuid': {'uuid': self.link_uuid}}
 
diff --git a/src/context/service/database/ServiceModel.py b/src/context/service/database/ServiceModel.py
index cf756af60a8178a9ae2fda2a5fa5ddeebc73912c..8b32d1cc9eeec248d1097f972df93dbd2c0882fa 100644
--- a/src/context/service/database/ServiceModel.py
+++ b/src/context/service/database/ServiceModel.py
@@ -56,6 +56,18 @@ class ServiceModel(Model):
     service_status = EnumeratedField(ORM_ServiceStatusEnum, required=True)
     service_config_fk = ForeignKeyField(ConfigModel)
 
+    def delete(self) -> None:
+        #pylint: disable=import-outside-toplevel
+        from .RelationModels import ServiceEndPointModel
+
+        for db_service_endpoint_pk,_ in self.references(ServiceEndPointModel):
+            ServiceEndPointModel(self.database, db_service_endpoint_pk).delete()
+
+        super().delete()
+
+        ConfigModel(self.database, self.service_config_fk).delete()
+        ConstraintsModel(self.database, self.service_constraints_fk).delete()
+
     def dump_id(self) -> Dict:
         context_id = ContextModel(self.database, self.context_fk).dump_id()
         return {
diff --git a/src/context/service/database/SliceModel.py b/src/context/service/database/SliceModel.py
index a185afed80aff870d7c7b93adee032261effa731..bc00ada43758c9c5ffefbb88a87134aa46fbd73a 100644
--- a/src/context/service/database/SliceModel.py
+++ b/src/context/service/database/SliceModel.py
@@ -47,6 +47,24 @@ class SliceModel(Model):
     slice_status = EnumeratedField(ORM_SliceStatusEnum, required=True)
     slice_config_fk = ForeignKeyField(ConfigModel)
 
+    def delete(self) -> None:
+        # pylint: disable=import-outside-toplevel
+        from .RelationModels import SliceEndPointModel, SliceServiceModel, SliceSubSliceModel
+
+        for db_slice_endpoint_pk,_ in self.references(SliceEndPointModel):
+            SliceEndPointModel(self.database, db_slice_endpoint_pk).delete()
+
+        for db_slice_service_pk,_ in self.references(SliceServiceModel):
+            SliceServiceModel(self.database, db_slice_service_pk).delete()
+
+        for db_slice_subslice_pk,_ in self.references(SliceSubSliceModel):
+            SliceSubSliceModel(self.database, db_slice_subslice_pk).delete()
+
+        super().delete()
+
+        ConfigModel(self.database, self.slice_config_fk).delete()
+        ConstraintsModel(self.database, self.slice_constraints_fk).delete()
+
     def dump_id(self) -> Dict:
         context_id = ContextModel(self.database, self.context_fk).dump_id()
         return {
diff --git a/src/context/service/grpc_server/ContextServiceServicerImpl.py b/src/context/service/grpc_server/ContextServiceServicerImpl.py
index 012de343f4f944913c40a882fc6c676d70816628..4c8f957ecb70765cbd36032fca7bfacc27f9b5ae 100644
--- a/src/context/service/grpc_server/ContextServiceServicerImpl.py
+++ b/src/context/service/grpc_server/ContextServiceServicerImpl.py
@@ -31,23 +31,24 @@ from common.proto.context_pb2 import (
 from common.proto.context_pb2_grpc import ContextServiceServicer
 from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method
 from common.rpc_method_wrapper.ServiceExceptions import InvalidArgumentException
-from context.service.database.ConfigModel import ConfigModel, ConfigRuleModel, grpc_config_rules_to_raw, update_config
-from context.service.database.ConnectionModel import ConnectionModel, PathHopModel, PathModel, set_path
-from context.service.database.ConstraintModel import ConstraintModel, ConstraintsModel, set_constraints
+from context.service.database.ConfigModel import grpc_config_rules_to_raw, update_config
+from context.service.database.ConnectionModel import ConnectionModel, set_path
+from context.service.database.ConstraintModel import set_constraints
 from context.service.database.ContextModel import ContextModel
-from context.service.database.DeviceModel import (
-    DeviceModel, DriverModel, grpc_to_enum__device_operational_status, set_drivers)
-from context.service.database.EndPointModel import EndPointModel, KpiSampleTypeModel, set_kpi_sample_types
+from context.service.database.DeviceModel import DeviceModel, grpc_to_enum__device_operational_status, set_drivers
+from context.service.database.EndPointModel import EndPointModel, set_kpi_sample_types
 from context.service.database.Events import notify_event
 from context.service.database.LinkModel import LinkModel
 from context.service.database.RelationModels import (
-    ConnectionSubServiceModel, LinkEndPointModel, ServiceEndPointModel, SliceEndPointModel, SliceServiceModel, SliceSubSliceModel, TopologyDeviceModel, TopologyLinkModel)
+    ConnectionSubServiceModel, LinkEndPointModel, ServiceEndPointModel, SliceEndPointModel, SliceServiceModel,
+    SliceSubSliceModel, TopologyDeviceModel, TopologyLinkModel)
 from context.service.database.ServiceModel import (
     ServiceModel, grpc_to_enum__service_status, grpc_to_enum__service_type)
 from context.service.database.SliceModel import SliceModel, grpc_to_enum__slice_status
 from context.service.database.TopologyModel import TopologyModel
 from .Constants import (
-    CONSUME_TIMEOUT, TOPIC_CONNECTION, TOPIC_CONTEXT, TOPIC_DEVICE, TOPIC_LINK, TOPIC_SERVICE, TOPIC_SLICE, TOPIC_TOPOLOGY)
+    CONSUME_TIMEOUT, TOPIC_CONNECTION, TOPIC_CONTEXT, TOPIC_DEVICE, TOPIC_LINK, TOPIC_SERVICE, TOPIC_SLICE,
+    TOPIC_TOPOLOGY)
 
 LOGGER = logging.getLogger(__name__)
 
@@ -336,25 +337,7 @@ class ContextServiceServicerImpl(ContextServiceServicer):
             if not found: return Empty()
 
             dict_device_id = db_device.dump_id()
-
-            for db_endpoint_pk,_ in db_device.references(EndPointModel):
-                db_endpoint = EndPointModel(self.database, db_endpoint_pk)
-                for db_kpi_sample_type_pk,_ in db_endpoint.references(KpiSampleTypeModel):
-                    KpiSampleTypeModel(self.database, db_kpi_sample_type_pk).delete()
-                db_endpoint.delete()
-
-            for db_topology_device_pk,_ in db_device.references(TopologyDeviceModel):
-                TopologyDeviceModel(self.database, db_topology_device_pk).delete()
-
-            for db_driver_pk,_ in db_device.references(DriverModel):
-                DriverModel(self.database, db_driver_pk).delete()
-
-            db_config = ConfigModel(self.database, db_device.device_config_fk)
-            for db_config_rule_pk,_ in db_config.references(ConfigRuleModel):
-                ConfigRuleModel(self.database, db_config_rule_pk).delete()
-
             db_device.delete()
-            db_config.delete()
 
             event_type = EventTypeEnum.EVENTTYPE_REMOVE
             notify_event(self.messagebroker, TOPIC_DEVICE, event_type, {'device_id': dict_device_id})
@@ -443,14 +426,8 @@ class ContextServiceServicerImpl(ContextServiceServicer):
             if not found: return Empty()
 
             dict_link_id = db_link.dump_id()
-
-            for db_link_endpoint_pk,_ in db_link.references(LinkEndPointModel):
-                LinkEndPointModel(self.database, db_link_endpoint_pk).delete()
-
-            for db_topology_link_pk,_ in db_link.references(TopologyLinkModel):
-                TopologyLinkModel(self.database, db_topology_link_pk).delete()
-
             db_link.delete()
+
             event_type = EventTypeEnum.EVENTTYPE_REMOVE
             notify_event(self.messagebroker, TOPIC_LINK, event_type, {'link_id': dict_link_id})
             return Empty()
@@ -557,21 +534,7 @@ class ContextServiceServicerImpl(ContextServiceServicer):
             if not found: return Empty()
 
             dict_service_id = db_service.dump_id()
-
-            for db_service_endpoint_pk,_ in db_service.references(ServiceEndPointModel):
-                ServiceEndPointModel(self.database, db_service_endpoint_pk).delete()
-
-            db_config = ConfigModel(self.database, db_service.service_config_fk)
-            for db_config_rule_pk,_ in db_config.references(ConfigRuleModel):
-                ConfigRuleModel(self.database, db_config_rule_pk).delete()
-
-            db_constraints = ConstraintsModel(self.database, db_service.service_constraints_fk)
-            for db_constraint_pk,_ in db_constraints.references(ConstraintModel):
-                ConstraintModel(self.database, db_constraint_pk).delete()
-
             db_service.delete()
-            db_config.delete()
-            db_constraints.delete()
 
             event_type = EventTypeEnum.EVENTTYPE_REMOVE
             notify_event(self.messagebroker, TOPIC_SERVICE, event_type, {'service_id': dict_service_id})
@@ -703,27 +666,7 @@ class ContextServiceServicerImpl(ContextServiceServicer):
             if not found: return Empty()
 
             dict_slice_id = db_slice.dump_id()
-
-            for db_slice_endpoint_pk,_ in db_slice.references(SliceEndPointModel):
-                SliceEndPointModel(self.database, db_slice_endpoint_pk).delete()
-
-            db_config = ConfigModel(self.database, db_slice.slice_config_fk)
-            for db_config_rule_pk,_ in db_config.references(ConfigRuleModel):
-                ConfigRuleModel(self.database, db_config_rule_pk).delete()
-
-            db_constraints = ConstraintsModel(self.database, db_slice.slice_constraints_fk)
-            for db_constraint_pk,_ in db_constraints.references(ConstraintModel):
-                ConstraintModel(self.database, db_constraint_pk).delete()
-
-            for db_slice_service_pk,_ in db_slice.references(SliceServiceModel):
-                SliceServiceModel(self.database, db_slice_service_pk).delete()
-
-            for db_slice_subslice_pk,_ in db_slice.references(SliceSubSliceModel):
-                SliceSubSliceModel(self.database, db_slice_subslice_pk).delete()
-
             db_slice.delete()
-            db_config.delete()
-            db_constraints.delete()
 
             event_type = EventTypeEnum.EVENTTYPE_REMOVE
             notify_event(self.messagebroker, TOPIC_SLICE, event_type, {'slice_id': dict_slice_id})
@@ -808,20 +751,7 @@ class ContextServiceServicerImpl(ContextServiceServicer):
             if not found: return Empty()
 
             dict_connection_id = db_connection.dump_id()
-
-            db_path = PathModel(self.database, db_connection.path_fk)
-            for db_path_hop_pk,_ in db_path.references(PathHopModel):
-                PathHopModel(self.database, db_path_hop_pk).delete()
-
-            # Do not remove sub-services automatically. They are supported by real services, so Service component should
-            # deal with the correct removal workflow to deconfigure the devices.
-            for db_connection_sub_service_pk,_ in db_connection.references(ConnectionSubServiceModel):
-                db_connection_sub_service : ConnectionSubServiceModel = get_object(
-                    self.database, ConnectionSubServiceModel, db_connection_sub_service_pk)
-                db_connection_sub_service.delete()
-
             db_connection.delete()
-            db_path.delete()
 
             event_type = EventTypeEnum.EVENTTYPE_REMOVE
             notify_event(self.messagebroker, TOPIC_CONNECTION, event_type, {'connection_id': dict_connection_id})
diff --git a/src/context/tests/test_unitary.py b/src/context/tests/test_unitary.py
index efdd1f8b96a09b31b7d144b676ddd355152fc003..b46c9468c56974be5c987dbbc284daae337d3c7b 100644
--- a/src/context/tests/test_unitary.py
+++ b/src/context/tests/test_unitary.py
@@ -846,7 +846,7 @@ def test_grpc_service(
     for db_entry in db_entries:
         LOGGER.info('  [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
     LOGGER.info('-----------------------------------------------------------')
-    assert len(db_entries) == 84
+    assert len(db_entries) == 89
 
     # ----- Get when the object exists ---------------------------------------------------------------------------------
     response = context_client_grpc.GetService(ServiceId(**SERVICE_R1_R2_ID))
@@ -1042,7 +1042,7 @@ def test_grpc_connection(
     for db_entry in db_entries:
         LOGGER.info('  [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
     LOGGER.info('-----------------------------------------------------------')
-    assert len(db_entries) == 137
+    assert len(db_entries) == 150
 
     # ----- Create the object ------------------------------------------------------------------------------------------
     with pytest.raises(grpc.RpcError) as e:
@@ -1082,7 +1082,7 @@ def test_grpc_connection(
     for db_entry in db_entries:
         LOGGER.info('  [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
     LOGGER.info('-----------------------------------------------------------')
-    assert len(db_entries) == 153
+    assert len(db_entries) == 166
 
     # ----- Get when the object exists ---------------------------------------------------------------------------------
     response = context_client_grpc.GetConnection(ConnectionId(**CONNECTION_R1_R3_ID))