diff --git a/src/context/service/ContextServiceServicerImpl.py b/src/context/service/ContextServiceServicerImpl.py
index 6914e05a01b8382968b656ce818b91f10ffd7329..edb5095b99f393a040e976c3841d82349a0d9450 100644
--- a/src/context/service/ContextServiceServicerImpl.py
+++ b/src/context/service/ContextServiceServicerImpl.py
@@ -38,7 +38,7 @@ from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered
 from .database.Context import context_delete, context_get, context_list_ids, context_list_objs, context_set
 from .database.Device import device_delete, device_get, device_list_ids, device_list_objs, device_set
 from .database.Link import link_delete, link_get, link_list_ids, link_list_objs, link_set
-#from .database.Service import service_delete, service_get, service_list_ids, service_list_objs, service_set
+from .database.Service import service_delete, service_get, service_list_ids, service_list_objs, service_set
 from .database.Topology import topology_delete, topology_get, topology_list_ids, topology_list_objs, topology_set
 #from common.tools.grpc.Tools import grpc_message_to_json, grpc_message_to_json_string
 #from context.service.Database import Database
@@ -231,31 +231,31 @@ class ContextServiceServicerImpl(ContextServiceServicer, ContextPolicyServiceSer
 
     # ----- Service ----------------------------------------------------------------------------------------------------
 
-#    @safe_and_metered_rpc_method(METRICS, LOGGER)
-#    def ListServiceIds(self, request : ContextId, context : grpc.ServicerContext) -> ServiceIdList:
-#        return service_list_ids(self.db_engine, request)
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def ListServiceIds(self, request : ContextId, context : grpc.ServicerContext) -> ServiceIdList:
+        return service_list_ids(self.db_engine, request)
 
-#    @safe_and_metered_rpc_method(METRICS, LOGGER)
-#    def ListServices(self, request : ContextId, context : grpc.ServicerContext) -> ServiceList:
-#        return service_list_objs(self.db_engine, request)
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def ListServices(self, request : ContextId, context : grpc.ServicerContext) -> ServiceList:
+        return service_list_objs(self.db_engine, request)
 
-#    @safe_and_metered_rpc_method(METRICS, LOGGER)
-#    def GetService(self, request : ServiceId, context : grpc.ServicerContext) -> Service:
-#        return service_get(self.db_engine, request)
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def GetService(self, request : ServiceId, context : grpc.ServicerContext) -> Service:
+        return service_get(self.db_engine, request)
 
-#    @safe_and_metered_rpc_method(METRICS, LOGGER)
-#    def SetService(self, request : Service, context : grpc.ServicerContext) -> ServiceId:
-#        service_id,updated = service_set(self.db_engine, request)
-#        #event_type = EventTypeEnum.EVENTTYPE_UPDATE if updated else EventTypeEnum.EVENTTYPE_CREATE
-#        #notify_event(self.messagebroker, TOPIC_SERVICE, event_type, {'service_id': service_id})
-#        return service_id
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def SetService(self, request : Service, context : grpc.ServicerContext) -> ServiceId:
+        service_id,updated = service_set(self.db_engine, request)
+        #event_type = EventTypeEnum.EVENTTYPE_UPDATE if updated else EventTypeEnum.EVENTTYPE_CREATE
+        #notify_event(self.messagebroker, TOPIC_SERVICE, event_type, {'service_id': service_id})
+        return service_id
 
-#    @safe_and_metered_rpc_method(METRICS, LOGGER)
-#    def RemoveService(self, request : ServiceId, context : grpc.ServicerContext) -> Empty:
-#        deleted = service_delete(self.db_engine, request)
-#        #if deleted:
-#        #    notify_event(self.messagebroker, TOPIC_SERVICE, EventTypeEnum.EVENTTYPE_REMOVE, {'service_id': request})
-#        return Empty()
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def RemoveService(self, request : ServiceId, context : grpc.ServicerContext) -> Empty:
+        deleted = service_delete(self.db_engine, request)
+        #if deleted:
+        #    notify_event(self.messagebroker, TOPIC_SERVICE, EventTypeEnum.EVENTTYPE_REMOVE, {'service_id': request})
+        return Empty()
 
     @safe_and_metered_rpc_method(METRICS, LOGGER)
     def GetServiceEvents(self, request : Empty, context : grpc.ServicerContext) -> Iterator[ServiceEvent]:
diff --git a/src/context/service/database/ConfigRule.py b/src/context/service/database/ConfigRule.py
new file mode 100644
index 0000000000000000000000000000000000000000..af1dd1ec5689f53bd9180e504f3c3acb57f49532
--- /dev/null
+++ b/src/context/service/database/ConfigRule.py
@@ -0,0 +1,185 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from sqlalchemy import delete
+from sqlalchemy.dialects.postgresql import insert
+from sqlalchemy.orm import Session
+from typing import Dict, List, Optional
+from common.proto.context_pb2 import ConfigRule
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from .models.enums.ConfigAction import grpc_to_enum__config_action
+from .models.ConfigRuleModel import ConfigRuleKindEnum, ConfigRuleModel
+from .uuids._Builder import get_uuid_random
+
+def compose_config_rules_data(
+    config_rules : List[ConfigRule],
+    device_uuid : Optional[str] = None, service_uuid : Optional[str] = None, slice_uuid : Optional[str] = None
+) -> List[Dict]:
+    dict_config_rules : List[Dict] = list()
+    for position,config_rule in enumerate(config_rules):
+        configrule_uuid = get_uuid_random()
+        str_kind = config_rule.WhichOneof('config_rule')
+        dict_config_rule = {
+            'configrule_uuid': configrule_uuid,
+            'position'       : position,
+            'kind'           : ConfigRuleKindEnum._member_map_.get(str_kind.upper()), # pylint: disable=no-member
+            'action'         : grpc_to_enum__config_action(config_rule.action),
+            'data'           : grpc_message_to_json_string(getattr(config_rule, str_kind, {})),
+        }
+        if device_uuid  is not None: dict_config_rule['device_uuid' ] = device_uuid
+        if service_uuid is not None: dict_config_rule['service_uuid'] = service_uuid
+        if slice_uuid   is not None: dict_config_rule['slice_uuid'  ] = slice_uuid
+        dict_config_rules.append(dict_config_rule)
+    return dict_config_rules
+
+def upsert_config_rules(
+    session : Session, config_rules : List[Dict],
+    device_uuid : Optional[str] = None, service_uuid : Optional[str] = None, slice_uuid : Optional[str] = None
+) -> None:
+    stmt = delete(ConfigRuleModel)
+    if device_uuid  is not None: stmt = stmt.where(ConfigRuleModel.device_uuid  == device_uuid )
+    if service_uuid is not None: stmt = stmt.where(ConfigRuleModel.service_uuid == service_uuid)
+    if slice_uuid   is not None: stmt = stmt.where(ConfigRuleModel.slice_uuid   == slice_uuid  )
+    session.execute(stmt)
+    session.execute(insert(ConfigRuleModel).values(config_rules))
+
+
+#Union_SpecificConfigRule = Union[
+#    ConfigRuleCustomModel, ConfigRuleAclModel
+#]
+#
+#def set_config_rule(
+#    database : Database, db_config : ConfigModel, position : int, resource_key : str, resource_value : str,
+#): # -> Tuple[ConfigRuleModel, bool]:
+#
+#    str_rule_key_hash = fast_hasher(resource_key)
+#    str_config_rule_key = key_to_str([db_config.config_uuid, str_rule_key_hash], separator=':')
+#
+#    data = {'config_fk': db_config, 'position': position, 'action': ORM_ConfigActionEnum.SET, 'key': resource_key,
+#            'value': resource_value}
+#    to_add = ConfigRuleModel(**data)
+#
+#    result = database.create_or_update(to_add)
+#    return result
+#Tuple_ConfigRuleSpecs = Tuple[Type, str, Dict, ConfigRuleKindEnum]
+#
+#def parse_config_rule_custom(database : Database, grpc_config_rule) -> Tuple_ConfigRuleSpecs:
+#    config_rule_class = ConfigRuleCustomModel
+#    str_config_rule_id = grpc_config_rule.custom.resource_key
+#    config_rule_data = {
+#        'key'  : grpc_config_rule.custom.resource_key,
+#        'value': grpc_config_rule.custom.resource_value,
+#    }
+#    return config_rule_class, str_config_rule_id, config_rule_data, ConfigRuleKindEnum.CUSTOM
+#
+#def parse_config_rule_acl(database : Database, grpc_config_rule) -> Tuple_ConfigRuleSpecs:
+#    config_rule_class = ConfigRuleAclModel
+#    grpc_endpoint_id = grpc_config_rule.acl.endpoint_id
+#    grpc_rule_set = grpc_config_rule.acl.rule_set
+#    device_uuid = grpc_endpoint_id.device_id.device_uuid.uuid
+#    endpoint_uuid = grpc_endpoint_id.endpoint_uuid.uuid
+#    str_endpoint_key = '/'.join([device_uuid, endpoint_uuid])
+#    #str_endpoint_key, db_endpoint = get_endpoint(database, grpc_endpoint_id)
+#    str_config_rule_id = ':'.join([str_endpoint_key, grpc_rule_set.name])
+#    config_rule_data = {
+#        #'endpoint_fk': db_endpoint,
+#        'endpoint_id': grpc_message_to_json_string(grpc_endpoint_id),
+#        'acl_data': grpc_message_to_json_string(grpc_rule_set),
+#    }
+#    return config_rule_class, str_config_rule_id, config_rule_data, ConfigRuleKindEnum.ACL
+#
+#CONFIGRULE_PARSERS = {
+#    'custom': parse_config_rule_custom,
+#    'acl'   : parse_config_rule_acl,
+#}
+#
+#Union_ConfigRuleModel = Union[
+#    ConfigRuleCustomModel, ConfigRuleAclModel,
+#]
+#
+#def set_config_rule(
+#    database : Database, db_config : ConfigModel, grpc_config_rule : ConfigRule, position : int
+#) -> Tuple[Union_ConfigRuleModel, bool]:
+#    grpc_config_rule_kind = str(grpc_config_rule.WhichOneof('config_rule'))
+#    parser = CONFIGRULE_PARSERS.get(grpc_config_rule_kind)
+#    if parser is None:
+#        raise NotImplementedError('ConfigRule of kind {:s} is not implemented: {:s}'.format(
+#            grpc_config_rule_kind, grpc_message_to_json_string(grpc_config_rule)))
+#
+#    # create specific ConfigRule
+#    config_rule_class, str_config_rule_id, config_rule_data, config_rule_kind = parser(database, grpc_config_rule)
+#    str_config_rule_key_hash = fast_hasher(':'.join([config_rule_kind.value, str_config_rule_id]))
+#    str_config_rule_key = key_to_str([db_config.pk, str_config_rule_key_hash], separator=':')
+#    result : Tuple[Union_ConfigRuleModel, bool] = update_or_create_object(
+#        database, config_rule_class, str_config_rule_key, config_rule_data)
+#    db_specific_config_rule, updated = result
+#
+#    # create generic ConfigRule
+#    config_rule_fk_field_name = 'config_rule_{:s}_fk'.format(config_rule_kind.value)
+#    config_rule_data = {
+#        'config_fk': db_config, 'kind': config_rule_kind, 'position': position,
+#        'action': ORM_ConfigActionEnum.SET,
+#        config_rule_fk_field_name: db_specific_config_rule
+#    }
+#    result : Tuple[ConfigRuleModel, bool] = update_or_create_object(
+#        database, ConfigRuleModel, str_config_rule_key, config_rule_data)
+#    db_config_rule, updated = result
+#
+#    return db_config_rule, updated
+#
+#def delete_config_rule(
+#    database : Database, db_config : ConfigModel, grpc_config_rule : ConfigRule
+#) -> None:
+#    grpc_config_rule_kind = str(grpc_config_rule.WhichOneof('config_rule'))
+#    parser = CONFIGRULE_PARSERS.get(grpc_config_rule_kind)
+#    if parser is None:
+#        raise NotImplementedError('ConfigRule of kind {:s} is not implemented: {:s}'.format(
+#            grpc_config_rule_kind, grpc_message_to_json_string(grpc_config_rule)))
+#
+#    # delete generic config rules; self deletes specific config rule
+#    _, str_config_rule_id, _, config_rule_kind = parser(database, grpc_config_rule)
+#    str_config_rule_key_hash = fast_hasher(':'.join([config_rule_kind.value, str_config_rule_id]))
+#    str_config_rule_key = key_to_str([db_config.pk, str_config_rule_key_hash], separator=':')
+#    db_config_rule : Optional[ConfigRuleModel] = get_object(
+#        database, ConfigRuleModel, str_config_rule_key, raise_if_not_found=False)
+#    if db_config_rule is None: return
+#    db_config_rule.delete()
+#
+#def update_config(
+#    database : Database, db_parent_pk : str, config_name : str, grpc_config_rules
+#) -> List[Tuple[Union[ConfigModel, ConfigRuleModel], bool]]:
+#
+#    str_config_key = key_to_str([config_name, db_parent_pk], separator=':')
+#    result : Tuple[ConfigModel, bool] = get_or_create_object(database, ConfigModel, str_config_key)
+#    db_config, created = result
+#
+#    db_objects = [(db_config, created)]
+#
+#    for position,grpc_config_rule in enumerate(grpc_config_rules):
+#        action = grpc_to_enum__config_action(grpc_config_rule.action)
+#
+#        if action == ORM_ConfigActionEnum.SET:
+#            result : Tuple[ConfigRuleModel, bool] = set_config_rule(
+#                database, db_config, grpc_config_rule, position)
+#            db_config_rule, updated = result
+#            db_objects.append((db_config_rule, updated))
+#        elif action == ORM_ConfigActionEnum.DELETE:
+#            delete_config_rule(database, db_config, grpc_config_rule)
+#        else:
+#            msg = 'Unsupported Action({:s}) for ConfigRule({:s})'
+#            str_action = str(ConfigActionEnum.Name(action))
+#            str_config_rule = grpc_message_to_json_string(grpc_config_rule)
+#            raise AttributeError(msg.format(str_action, str_config_rule))
+#
+#    return db_objects
diff --git a/src/context/service/database/Constraint.py b/src/context/service/database/Constraint.py
new file mode 100644
index 0000000000000000000000000000000000000000..5c94d13c07d247f53d59f6a6da73bef1370754e3
--- /dev/null
+++ b/src/context/service/database/Constraint.py
@@ -0,0 +1,110 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from sqlalchemy import delete
+from sqlalchemy.dialects.postgresql import insert
+from sqlalchemy.orm import Session
+from typing import Dict, List, Optional
+from common.proto.context_pb2 import Constraint
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from .models.ConstraintModel import ConstraintKindEnum, ConstraintModel
+from .uuids._Builder import get_uuid_random
+
+def compose_constraints_data(
+    constraints : List[Constraint],
+    service_uuid : Optional[str] = None, slice_uuid : Optional[str] = None
+) -> List[Dict]:
+    dict_constraints : List[Dict] = list()
+    for position,constraint in enumerate(constraints):
+        str_kind = constraint.WhichOneof('constraint')
+        dict_constraint = {
+            'constraint_uuid': get_uuid_random(),
+            'position'       : position,
+            'kind'           : ConstraintKindEnum._member_map_.get(str_kind.upper()), # pylint: disable=no-member
+            'data'           : grpc_message_to_json_string(getattr(constraint, str_kind, {})),
+        }
+        if service_uuid is not None: dict_constraint['service_uuid'] = service_uuid
+        if slice_uuid   is not None: dict_constraint['slice_uuid'  ] = slice_uuid
+        dict_constraints.append(dict_constraint)
+    return dict_constraints
+
+def upsert_constraints(
+    session : Session, constraints : List[Dict],
+    service_uuid : Optional[str] = None, slice_uuid : Optional[str] = None
+) -> None:
+    stmt = delete(ConstraintModel)
+    if service_uuid is not None: stmt = stmt.where(ConstraintModel.service_uuid == service_uuid)
+    if slice_uuid   is not None: stmt = stmt.where(ConstraintModel.slice_uuid   == slice_uuid  )
+    session.execute(stmt)
+    session.execute(insert(ConstraintModel).values(constraints))
+
+#    def set_constraint(self, db_constraints: ConstraintsModel, grpc_constraint: Constraint, position: int
+#    ) -> Tuple[Union_ConstraintModel, bool]:
+#        with self.session() as session:
+#
+#            grpc_constraint_kind = str(grpc_constraint.WhichOneof('constraint'))
+#
+#            parser = CONSTRAINT_PARSERS.get(grpc_constraint_kind)
+#            if parser is None:
+#                raise NotImplementedError('Constraint of kind {:s} is not implemented: {:s}'.format(
+#                    grpc_constraint_kind, grpc_message_to_json_string(grpc_constraint)))
+#
+#            # create specific constraint
+#            constraint_class, str_constraint_id, constraint_data, constraint_kind = parser(grpc_constraint)
+#            str_constraint_id = str(uuid.uuid4())
+#            LOGGER.info('str_constraint_id: {}'.format(str_constraint_id))
+#            # 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=':')
+#
+#            # result : Tuple[Union_ConstraintModel, bool] = update_or_create_object(
+#            #     database, constraint_class, str_constraint_key, constraint_data)
+#            constraint_data[constraint_class.main_pk_name()] = str_constraint_id
+#            db_new_constraint = constraint_class(**constraint_data)
+#            result: Tuple[Union_ConstraintModel, bool] = self.database.create_or_update(db_new_constraint)
+#            db_specific_constraint, updated = result
+#
+#            # create generic constraint
+#            # constraint_fk_field_name = 'constraint_uuid'.format(constraint_kind.value)
+#            constraint_data = {
+#                'constraints_uuid': db_constraints.constraints_uuid, 'position': position, 'kind': constraint_kind
+#            }
+#
+#            db_new_constraint = ConstraintModel(**constraint_data)
+#            result: Tuple[Union_ConstraintModel, bool] = self.database.create_or_update(db_new_constraint)
+#            db_constraint, updated = result
+#
+#            return db_constraint, updated
+#
+#    def set_constraints(self, service_uuid: str, constraints_name : str, grpc_constraints
+#    ) -> List[Tuple[Union[ConstraintsModel, ConstraintModel], bool]]:
+#        with self.session() as session:
+#            # str_constraints_key = key_to_str([db_parent_pk, constraints_name], separator=':')
+#            # result : Tuple[ConstraintsModel, bool] = get_or_create_object(database, ConstraintsModel, str_constraints_key)
+#            result = session.query(ConstraintsModel).filter_by(constraints_uuid=service_uuid).one_or_none()
+#            created = None
+#            if result:
+#                created = True
+#            session.query(ConstraintsModel).filter_by(constraints_uuid=service_uuid).one_or_none()
+#            db_constraints = ConstraintsModel(constraints_uuid=service_uuid)
+#            session.add(db_constraints)
+#
+#            db_objects = [(db_constraints, created)]
+#
+#            for position,grpc_constraint in enumerate(grpc_constraints):
+#                result : Tuple[ConstraintModel, bool] = self.set_constraint(
+#                    db_constraints, grpc_constraint, position)
+#                db_constraint, updated = result
+#                db_objects.append((db_constraint, updated))
+#
+#            return db_objects
diff --git a/src/context/service/database/Device.py b/src/context/service/database/Device.py
index a0e0a53e5c766c48cfdc6b8fde2c432bf4d634db..7607a2349fd109134f1680161a36c3ccea926262 100644
--- a/src/context/service/database/Device.py
+++ b/src/context/service/database/Device.py
@@ -12,25 +12,21 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from sqlalchemy import delete
 from sqlalchemy.dialects.postgresql import insert
 from sqlalchemy.engine import Engine
 from sqlalchemy.orm import Session, sessionmaker
 from sqlalchemy_cockroachdb import run_transaction
-from typing import Dict, List, Optional, Set, Tuple
+from typing import Dict, List, Optional, Set
 from common.proto.context_pb2 import Device, DeviceId, DeviceIdList, DeviceList
 from common.rpc_method_wrapper.ServiceExceptions import InvalidArgumentException, NotFoundException
 from common.tools.object_factory.Device import json_device_id
-from common.tools.grpc.Tools import grpc_message_to_json_string
-from .models.ConfigRuleModel import ConfigRuleKindEnum, ConfigRuleModel
+from context.service.database.ConfigRule import compose_config_rules_data, upsert_config_rules
 from .models.DeviceModel import DeviceModel
 from .models.EndPointModel import EndPointModel
 from .models.RelationModels import TopologyDeviceModel
-from .models.enums.ConfigAction import grpc_to_enum__config_action
 from .models.enums.DeviceDriver import grpc_to_enum__device_driver
 from .models.enums.DeviceOperationalStatus import grpc_to_enum__device_operational_status
 from .models.enums.KpiSampleType import grpc_to_enum__kpi_sample_type
-from .uuids._Builder import get_uuid_random
 from .uuids.Device import device_get_uuid
 from .uuids.EndPoint import endpoint_get_uuid
 
@@ -108,18 +104,7 @@ def device_set(db_engine : Engine, request : Device) -> bool:
             })
             topology_uuids.add(endpoint_topology_uuid)
 
-    config_rules : List[Dict] = list()
-    for position,config_rule in enumerate(request.device_config.config_rules):
-        configrule_uuid = get_uuid_random()
-        str_kind = config_rule.WhichOneof('config_rule')
-        config_rules.append({
-            'configrule_uuid': configrule_uuid,
-            'device_uuid'    : device_uuid,
-            'position'       : position,
-            'kind'           : ConfigRuleKindEnum._member_map_.get(str_kind.upper()), # pylint: disable=no-member
-            'action'         : grpc_to_enum__config_action(config_rule.action),
-            'data'           : grpc_message_to_json_string(getattr(config_rule, str_kind, {})),
-        })
+    config_rules = compose_config_rules_data(request.device_config.config_rules, device_uuid=device_uuid)
 
     device_data = [{
         'device_uuid'              : device_uuid,
@@ -157,8 +142,7 @@ def device_set(db_engine : Engine, request : Device) -> bool:
             index_elements=[TopologyDeviceModel.topology_uuid, TopologyDeviceModel.device_uuid]
         ))
 
-        session.execute(delete(ConfigRuleModel).where(ConfigRuleModel.device_uuid == device_uuid))
-        session.execute(insert(ConfigRuleModel).values(config_rules))
+        upsert_config_rules(session, config_rules, device_uuid=device_uuid)
 
     run_transaction(sessionmaker(bind=db_engine), callback)
     updated = False # TODO: improve and check if created/updated
@@ -167,143 +151,6 @@ def device_set(db_engine : Engine, request : Device) -> bool:
 def device_delete(db_engine : Engine, request : DeviceId) -> bool:
     device_uuid = device_get_uuid(request, allow_random=False)
     def callback(session : Session) -> bool:
-        #session.query(TopologyDeviceModel).filter_by(device_uuid=device_uuid).delete()
         num_deleted = session.query(DeviceModel).filter_by(device_uuid=device_uuid).delete()
-        #db_device = session.query(DeviceModel).filter_by(device_uuid=device_uuid).one_or_none()
-        #session.query(ConfigRuleModel).filter_by(config_uuid=db_device.device_config_uuid).delete()
-        #session.query(ConfigModel).filter_by(config_uuid=db_device.device_config_uuid).delete()
-        #session.query(DeviceModel).filter_by(device_uuid=device_uuid).delete()
         return num_deleted > 0
     return run_transaction(sessionmaker(bind=db_engine), callback)
-
-
-
-
-#Union_SpecificConfigRule = Union[
-#    ConfigRuleCustomModel, ConfigRuleAclModel
-#]
-#
-#def set_config_rule(
-#    database : Database, db_config : ConfigModel, position : int, resource_key : str, resource_value : str,
-#): # -> Tuple[ConfigRuleModel, bool]:
-#
-#    str_rule_key_hash = fast_hasher(resource_key)
-#    str_config_rule_key = key_to_str([db_config.config_uuid, str_rule_key_hash], separator=':')
-#
-#    data = {'config_fk': db_config, 'position': position, 'action': ORM_ConfigActionEnum.SET, 'key': resource_key,
-#            'value': resource_value}
-#    to_add = ConfigRuleModel(**data)
-#
-#    result = database.create_or_update(to_add)
-#    return result
-#Tuple_ConfigRuleSpecs = Tuple[Type, str, Dict, ConfigRuleKindEnum]
-#
-#def parse_config_rule_custom(database : Database, grpc_config_rule) -> Tuple_ConfigRuleSpecs:
-#    config_rule_class = ConfigRuleCustomModel
-#    str_config_rule_id = grpc_config_rule.custom.resource_key
-#    config_rule_data = {
-#        'key'  : grpc_config_rule.custom.resource_key,
-#        'value': grpc_config_rule.custom.resource_value,
-#    }
-#    return config_rule_class, str_config_rule_id, config_rule_data, ConfigRuleKindEnum.CUSTOM
-#
-#def parse_config_rule_acl(database : Database, grpc_config_rule) -> Tuple_ConfigRuleSpecs:
-#    config_rule_class = ConfigRuleAclModel
-#    grpc_endpoint_id = grpc_config_rule.acl.endpoint_id
-#    grpc_rule_set = grpc_config_rule.acl.rule_set
-#    device_uuid = grpc_endpoint_id.device_id.device_uuid.uuid
-#    endpoint_uuid = grpc_endpoint_id.endpoint_uuid.uuid
-#    str_endpoint_key = '/'.join([device_uuid, endpoint_uuid])
-#    #str_endpoint_key, db_endpoint = get_endpoint(database, grpc_endpoint_id)
-#    str_config_rule_id = ':'.join([str_endpoint_key, grpc_rule_set.name])
-#    config_rule_data = {
-#        #'endpoint_fk': db_endpoint,
-#        'endpoint_id': grpc_message_to_json_string(grpc_endpoint_id),
-#        'acl_data': grpc_message_to_json_string(grpc_rule_set),
-#    }
-#    return config_rule_class, str_config_rule_id, config_rule_data, ConfigRuleKindEnum.ACL
-#
-#CONFIGRULE_PARSERS = {
-#    'custom': parse_config_rule_custom,
-#    'acl'   : parse_config_rule_acl,
-#}
-#
-#Union_ConfigRuleModel = Union[
-#    ConfigRuleCustomModel, ConfigRuleAclModel,
-#]
-#
-#def set_config_rule(
-#    database : Database, db_config : ConfigModel, grpc_config_rule : ConfigRule, position : int
-#) -> Tuple[Union_ConfigRuleModel, bool]:
-#    grpc_config_rule_kind = str(grpc_config_rule.WhichOneof('config_rule'))
-#    parser = CONFIGRULE_PARSERS.get(grpc_config_rule_kind)
-#    if parser is None:
-#        raise NotImplementedError('ConfigRule of kind {:s} is not implemented: {:s}'.format(
-#            grpc_config_rule_kind, grpc_message_to_json_string(grpc_config_rule)))
-#
-#    # create specific ConfigRule
-#    config_rule_class, str_config_rule_id, config_rule_data, config_rule_kind = parser(database, grpc_config_rule)
-#    str_config_rule_key_hash = fast_hasher(':'.join([config_rule_kind.value, str_config_rule_id]))
-#    str_config_rule_key = key_to_str([db_config.pk, str_config_rule_key_hash], separator=':')
-#    result : Tuple[Union_ConfigRuleModel, bool] = update_or_create_object(
-#        database, config_rule_class, str_config_rule_key, config_rule_data)
-#    db_specific_config_rule, updated = result
-#
-#    # create generic ConfigRule
-#    config_rule_fk_field_name = 'config_rule_{:s}_fk'.format(config_rule_kind.value)
-#    config_rule_data = {
-#        'config_fk': db_config, 'kind': config_rule_kind, 'position': position,
-#        'action': ORM_ConfigActionEnum.SET,
-#        config_rule_fk_field_name: db_specific_config_rule
-#    }
-#    result : Tuple[ConfigRuleModel, bool] = update_or_create_object(
-#        database, ConfigRuleModel, str_config_rule_key, config_rule_data)
-#    db_config_rule, updated = result
-#
-#    return db_config_rule, updated
-#
-#def delete_config_rule(
-#    database : Database, db_config : ConfigModel, grpc_config_rule : ConfigRule
-#) -> None:
-#    grpc_config_rule_kind = str(grpc_config_rule.WhichOneof('config_rule'))
-#    parser = CONFIGRULE_PARSERS.get(grpc_config_rule_kind)
-#    if parser is None:
-#        raise NotImplementedError('ConfigRule of kind {:s} is not implemented: {:s}'.format(
-#            grpc_config_rule_kind, grpc_message_to_json_string(grpc_config_rule)))
-#
-#    # delete generic config rules; self deletes specific config rule
-#    _, str_config_rule_id, _, config_rule_kind = parser(database, grpc_config_rule)
-#    str_config_rule_key_hash = fast_hasher(':'.join([config_rule_kind.value, str_config_rule_id]))
-#    str_config_rule_key = key_to_str([db_config.pk, str_config_rule_key_hash], separator=':')
-#    db_config_rule : Optional[ConfigRuleModel] = get_object(
-#        database, ConfigRuleModel, str_config_rule_key, raise_if_not_found=False)
-#    if db_config_rule is None: return
-#    db_config_rule.delete()
-#
-#def update_config(
-#    database : Database, db_parent_pk : str, config_name : str, grpc_config_rules
-#) -> List[Tuple[Union[ConfigModel, ConfigRuleModel], bool]]:
-#
-#    str_config_key = key_to_str([config_name, db_parent_pk], separator=':')
-#    result : Tuple[ConfigModel, bool] = get_or_create_object(database, ConfigModel, str_config_key)
-#    db_config, created = result
-#
-#    db_objects = [(db_config, created)]
-#
-#    for position,grpc_config_rule in enumerate(grpc_config_rules):
-#        action = grpc_to_enum__config_action(grpc_config_rule.action)
-#
-#        if action == ORM_ConfigActionEnum.SET:
-#            result : Tuple[ConfigRuleModel, bool] = set_config_rule(
-#                database, db_config, grpc_config_rule, position)
-#            db_config_rule, updated = result
-#            db_objects.append((db_config_rule, updated))
-#        elif action == ORM_ConfigActionEnum.DELETE:
-#            delete_config_rule(database, db_config, grpc_config_rule)
-#        else:
-#            msg = 'Unsupported Action({:s}) for ConfigRule({:s})'
-#            str_action = str(ConfigActionEnum.Name(action))
-#            str_config_rule = grpc_message_to_json_string(grpc_config_rule)
-#            raise AttributeError(msg.format(str_action, str_config_rule))
-#
-#    return db_objects
diff --git a/src/context/service/database/Link.py b/src/context/service/database/Link.py
index 93f90b3ea0aeba5b97ba8a360be1f289eb8f0d0a..9f11cad2376b0d36ba5db5addff43097d1de26c3 100644
--- a/src/context/service/database/Link.py
+++ b/src/context/service/database/Link.py
@@ -108,10 +108,6 @@ def link_set(db_engine : Engine, request : Link) -> bool:
 def link_delete(db_engine : Engine, request : LinkId) -> bool:
     link_uuid = link_get_uuid(request, allow_random=False)
     def callback(session : Session) -> bool:
-        #session.query(TopologyLinkModel).filter_by(link_uuid=link_uuid).delete()
-        #session.query(LinkEndPointModel).filter_by(link_uuid=link_uuid).delete()
         num_deleted = session.query(LinkModel).filter_by(link_uuid=link_uuid).delete()
-        #db_link = session.query(LinkModel).filter_by(link_uuid=link_uuid).one_or_none()
-        #session.query(LinkModel).filter_by(link_uuid=link_uuid).delete()
         return num_deleted > 0
     return run_transaction(sessionmaker(bind=db_engine), callback)
diff --git a/src/context/service/database/Service.py b/src/context/service/database/Service.py
index 3b6b4cc267c8087a2d1b2bc2c1e856b8ee22fbd7..7e3d9d044b1991c145528897bc28c09889ae1862 100644
--- a/src/context/service/database/Service.py
+++ b/src/context/service/database/Service.py
@@ -12,7 +12,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import time
 from sqlalchemy.dialects.postgresql import insert
 from sqlalchemy.engine import Engine
 from sqlalchemy.orm import Session, sessionmaker
@@ -20,10 +19,20 @@ from sqlalchemy_cockroachdb import run_transaction
 from typing import Dict, List, Optional
 from common.proto.context_pb2 import ContextId, Service, ServiceId, ServiceIdList, ServiceList
 from common.rpc_method_wrapper.ServiceExceptions import InvalidArgumentException, NotFoundException
+from common.tools.object_factory.Context import json_context_id
+from common.tools.object_factory.Service import json_service_id
+from context.service.database.ConfigRule import compose_config_rules_data, upsert_config_rules
+from context.service.database.Constraint import compose_constraints_data, upsert_constraints
+from .models.enums.ServiceStatus import grpc_to_enum__service_status
+from .models.enums.ServiceType import grpc_to_enum__service_type
+from .models.RelationModels import ServiceEndPointModel
 from .models.ServiceModel import ServiceModel
+from .uuids.Context import context_get_uuid
+from .uuids.EndPoint import endpoint_get_uuid
+from .uuids.Service import service_get_uuid
 
 def service_list_ids(db_engine : Engine, request : ContextId) -> ServiceIdList:
-    context_uuid = request.context_uuid.uuid
+    context_uuid = context_get_uuid(request, allow_random=False)
     def callback(session : Session) -> List[Dict]:
         obj_list : List[ServiceModel] = session.query(ServiceModel).filter_by(context_uuid=context_uuid).all()
         #.options(selectinload(ContextModel.service)).filter_by(context_uuid=context_uuid).one_or_none()
@@ -31,7 +40,7 @@ def service_list_ids(db_engine : Engine, request : ContextId) -> ServiceIdList:
     return ServiceIdList(service_ids=run_transaction(sessionmaker(bind=db_engine), callback))
 
 def service_list_objs(db_engine : Engine, request : ContextId) -> ServiceList:
-    context_uuid = request.context_uuid.uuid
+    context_uuid = context_get_uuid(request, allow_random=False)
     def callback(session : Session) -> List[Dict]:
         obj_list : List[ServiceModel] = session.query(ServiceModel).filter_by(context_uuid=context_uuid).all()
         #.options(selectinload(ContextModel.service)).filter_by(context_uuid=context_uuid).one_or_none()
@@ -39,225 +48,87 @@ def service_list_objs(db_engine : Engine, request : ContextId) -> ServiceList:
     return ServiceList(services=run_transaction(sessionmaker(bind=db_engine), callback))
 
 def service_get(db_engine : Engine, request : ServiceId) -> Service:
-    context_uuid = request.context_id.context_uuid.uuid
-    service_uuid = request.service_uuid.uuid
-
+    _,service_uuid = service_get_uuid(request, allow_random=False)
     def callback(session : Session) -> Optional[Dict]:
         obj : Optional[ServiceModel] = session.query(ServiceModel)\
-            .filter_by(context_uuid=context_uuid, service_uuid=service_uuid).one_or_none()
+            .filter_by(service_uuid=service_uuid).one_or_none()
         return None if obj is None else obj.dump()
     obj = run_transaction(sessionmaker(bind=db_engine), callback)
     if obj is None:
-        obj_uuid = '{:s}/{:s}'.format(context_uuid, service_uuid)
-        raise NotFoundException('Service', obj_uuid)
+        context_uuid = context_get_uuid(request.context_id, allow_random=False)
+        raw_service_uuid = '{:s}/{:s}'.format(request.context_id.context_uuid.uuid, request.service_uuid.uuid)
+        raise NotFoundException('Service', raw_service_uuid, extra_details=[
+            'context_uuid generated was: {:s}'.format(context_uuid),
+            'service_uuid generated was: {:s}'.format(service_uuid),
+        ])
     return Service(**obj)
 
 def service_set(db_engine : Engine, request : Service) -> bool:
-    context_uuid = request.service_id.context_id.context_uuid.uuid
-    service_uuid = request.service_id.service_uuid.uuid
-    service_name = request.name
+    raw_context_uuid = request.service_id.context_id.context_uuid.uuid
+    raw_service_uuid = request.service_id.service_uuid.uuid
+    raw_service_name = request.name
+    service_name = raw_service_uuid if len(raw_service_name) == 0 else raw_service_name
+    context_uuid,service_uuid = service_get_uuid(request.service_id, service_name=service_name, allow_random=True)
+
+    service_type = grpc_to_enum__service_type(request.service_type)
+    service_status = grpc_to_enum__service_status(request.service_status.service_status)
 
+    service_endpoints_data : List[Dict] = list()
     for i,endpoint_id in enumerate(request.service_endpoint_ids):
         endpoint_context_uuid = endpoint_id.topology_id.context_id.context_uuid.uuid
-        if len(endpoint_context_uuid) > 0 and context_uuid != endpoint_context_uuid:
+        if len(endpoint_context_uuid) == 0: endpoint_context_uuid = context_uuid
+        if endpoint_context_uuid not in {raw_context_uuid, context_uuid}:
             raise InvalidArgumentException(
                 'request.service_endpoint_ids[{:d}].topology_id.context_id.context_uuid.uuid'.format(i),
                 endpoint_context_uuid,
-                ['should be == {:s}({:s})'.format('request.service_id.context_id.context_uuid.uuid', context_uuid)])
+                ['should be == request.service_id.context_id.context_uuid.uuid({:s})'.format(raw_context_uuid)])
+
+        _, _, endpoint_uuid = endpoint_get_uuid(endpoint_id, allow_random=False)
+        service_endpoints_data.append({
+            'service_uuid' : service_uuid,
+            'endpoint_uuid': endpoint_uuid,
+        })
 
+    constraints = compose_constraints_data(request.service_constraints, service_uuid=service_uuid)
+    config_rules = compose_config_rules_data(request.service_config.config_rules, service_uuid=service_uuid)
+
+    service_data = [{
+        'context_uuid'  : context_uuid,
+        'service_uuid'  : service_uuid,
+        'service_name'  : service_name,
+        'service_type'  : service_type,
+        'service_status': service_status,
+    }]
 
     def callback(session : Session) -> None:
-        service_data = [{
-            'context_uuid' : context_uuid,
-            'service_uuid': service_uuid,
-            'service_name': service_name,
-            'created_at'   : time.time(),
-        }]
         stmt = insert(ServiceModel).values(service_data)
         stmt = stmt.on_conflict_do_update(
-            index_elements=[ServiceModel.context_uuid, ServiceModel.service_uuid],
-            set_=dict(service_name = stmt.excluded.service_name)
+            index_elements=[ServiceModel.service_uuid],
+            set_=dict(
+                service_name   = stmt.excluded.service_name,
+                service_type   = stmt.excluded.service_type,
+                service_status = stmt.excluded.service_status,
+            )
         )
         session.execute(stmt)
 
-    run_transaction(sessionmaker(bind=db_engine), callback)
-    return False # TODO: improve and check if created/updated
-
+        stmt = insert(ServiceEndPointModel).values(service_endpoints_data)
+        stmt = stmt.on_conflict_do_nothing(
+            index_elements=[ServiceEndPointModel.service_uuid, ServiceEndPointModel.endpoint_uuid]
+        )
+        session.execute(stmt)
 
-#        # db_context : ContextModel = get_object(self.database, ContextModel, context_uuid)
-#        db_context = session.query(ContextModel).filter_by(context_uuid=context_uuid).one_or_none()
-#        # str_service_key = key_to_str([context_uuid, service_uuid])
-#        constraints_result = self.set_constraints(service_uuid, 'constraints', request.service_constraints)
-#        db_constraints = constraints_result[0][0]
-#
-#        config_rules = grpc_config_rules_to_raw(request.service_config.config_rules)
-#        running_config_result = update_config(self.database, str_service_key, 'running', config_rules)
-#        db_running_config = running_config_result[0][0]
-#
-#        result : Tuple[ServiceModel, bool] = update_or_create_object(self.database, ServiceModel, str_service_key, {
-#            'context_fk'            : db_context,
-#            'service_uuid'          : service_uuid,
-#            'service_type'          : grpc_to_enum__service_type(request.service_type),
-#            'service_constraints_fk': db_constraints,
-#            'service_status'        : grpc_to_enum__service_status(request.service_status.service_status),
-#            'service_config_fk'     : db_running_config,
-#        })
-#        db_service, updated = result
-#
-#        for i,endpoint_id in enumerate(request.service_endpoint_ids):
-#            endpoint_uuid                  = endpoint_id.endpoint_uuid.uuid
-#            endpoint_device_uuid           = endpoint_id.device_id.device_uuid.uuid
-#            endpoint_topology_uuid         = endpoint_id.topology_id.topology_uuid.uuid
-#            endpoint_topology_context_uuid = endpoint_id.topology_id.context_id.context_uuid.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])
-#                str_endpoint_key = key_to_str([str_endpoint_key, str_topology_key], separator=':')
-#
-#            db_endpoint : EndPointModel = get_object(self.database, EndPointModel, str_endpoint_key)
-#
-#            str_service_endpoint_key = key_to_str([service_uuid, str_endpoint_key], separator='--')
-#            result : Tuple[ServiceEndPointModel, bool] = get_or_create_object(
-#                self.database, ServiceEndPointModel, str_service_endpoint_key, {
-#                    'service_fk': db_service, 'endpoint_fk': db_endpoint})
-#            #db_service_endpoint, service_endpoint_created = result
-#
-#        event_type = EventTypeEnum.EVENTTYPE_UPDATE if updated else EventTypeEnum.EVENTTYPE_CREATE
-#        dict_service_id = db_service.dump_id()
-#        notify_event(self.messagebroker, TOPIC_SERVICE, event_type, {'service_id': dict_service_id})
-#        return ServiceId(**dict_service_id)
-#    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])
-#
-#    constraints_result = set_constraints(
-#        self.database, str_service_key, 'service', request.service_constraints)
-#    db_constraints = constraints_result[0][0]
-#
-#    running_config_rules = update_config(
-#        self.database, str_service_key, 'service', request.service_config.config_rules)
-#    db_running_config = running_config_rules[0][0]
-#
-#    result : Tuple[ServiceModel, bool] = update_or_create_object(self.database, ServiceModel, str_service_key, {
-#        'context_fk'            : db_context,
-#        'service_uuid'          : service_uuid,
-#        'service_type'          : grpc_to_enum__service_type(request.service_type),
-#        'service_constraints_fk': db_constraints,
-#        'service_status'        : grpc_to_enum__service_status(request.service_status.service_status),
-#        'service_config_fk'     : db_running_config,
-#    })
-#    db_service, updated = result
-#
-#    for i,endpoint_id in enumerate(request.service_endpoint_ids):
-#        endpoint_uuid                  = endpoint_id.endpoint_uuid.uuid
-#        endpoint_device_uuid           = endpoint_id.device_id.device_uuid.uuid
-#        endpoint_topology_uuid         = endpoint_id.topology_id.topology_uuid.uuid
-#        endpoint_topology_context_uuid = endpoint_id.topology_id.context_id.context_uuid.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])
-#            str_endpoint_key = key_to_str([str_endpoint_key, str_topology_key], separator=':')
-#
-#        db_endpoint : EndPointModel = get_object(self.database, EndPointModel, str_endpoint_key)
-#
-#        str_service_endpoint_key = key_to_str([service_uuid, str_endpoint_key], separator='--')
-#        result : Tuple[ServiceEndPointModel, bool] = get_or_create_object(
-#            self.database, ServiceEndPointModel, str_service_endpoint_key, {
-#                'service_fk': db_service, 'endpoint_fk': db_endpoint})
-#        #db_service_endpoint, service_endpoint_created = result
-#
-#    event_type = EventTypeEnum.EVENTTYPE_UPDATE if updated else EventTypeEnum.EVENTTYPE_CREATE
-#    dict_service_id = db_service.dump_id()
-#    notify_event(self.messagebroker, TOPIC_SERVICE, event_type, {'service_id': dict_service_id})
-#    return ServiceId(**dict_service_id)
+        upsert_constraints(session, constraints, service_uuid=service_uuid)
+        upsert_config_rules(session, config_rules, service_uuid=service_uuid)
 
+    run_transaction(sessionmaker(bind=db_engine), callback)
+    updated = False # TODO: improve and check if created/updated
+    return ServiceId(**json_service_id(service_uuid, json_context_id(context_uuid))),updated
 
-#    def set_constraint(self, db_constraints: ConstraintsModel, grpc_constraint: Constraint, position: int
-#    ) -> Tuple[Union_ConstraintModel, bool]:
-#        with self.session() as session:
-#
-#            grpc_constraint_kind = str(grpc_constraint.WhichOneof('constraint'))
-#
-#            parser = CONSTRAINT_PARSERS.get(grpc_constraint_kind)
-#            if parser is None:
-#                raise NotImplementedError('Constraint of kind {:s} is not implemented: {:s}'.format(
-#                    grpc_constraint_kind, grpc_message_to_json_string(grpc_constraint)))
-#
-#            # create specific constraint
-#            constraint_class, str_constraint_id, constraint_data, constraint_kind = parser(grpc_constraint)
-#            str_constraint_id = str(uuid.uuid4())
-#            LOGGER.info('str_constraint_id: {}'.format(str_constraint_id))
-#            # 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=':')
-#
-#            # result : Tuple[Union_ConstraintModel, bool] = update_or_create_object(
-#            #     database, constraint_class, str_constraint_key, constraint_data)
-#            constraint_data[constraint_class.main_pk_name()] = str_constraint_id
-#            db_new_constraint = constraint_class(**constraint_data)
-#            result: Tuple[Union_ConstraintModel, bool] = self.database.create_or_update(db_new_constraint)
-#            db_specific_constraint, updated = result
-#
-#            # create generic constraint
-#            # constraint_fk_field_name = 'constraint_uuid'.format(constraint_kind.value)
-#            constraint_data = {
-#                'constraints_uuid': db_constraints.constraints_uuid, 'position': position, 'kind': constraint_kind
-#            }
-#
-#            db_new_constraint = ConstraintModel(**constraint_data)
-#            result: Tuple[Union_ConstraintModel, bool] = self.database.create_or_update(db_new_constraint)
-#            db_constraint, updated = result
-#
-#            return db_constraint, updated
-#
-#    def set_constraints(self, service_uuid: str, constraints_name : str, grpc_constraints
-#    ) -> List[Tuple[Union[ConstraintsModel, ConstraintModel], bool]]:
-#        with self.session() as session:
-#            # str_constraints_key = key_to_str([db_parent_pk, constraints_name], separator=':')
-#            # result : Tuple[ConstraintsModel, bool] = get_or_create_object(database, ConstraintsModel, str_constraints_key)
-#            result = session.query(ConstraintsModel).filter_by(constraints_uuid=service_uuid).one_or_none()
-#            created = None
-#            if result:
-#                created = True
-#            session.query(ConstraintsModel).filter_by(constraints_uuid=service_uuid).one_or_none()
-#            db_constraints = ConstraintsModel(constraints_uuid=service_uuid)
-#            session.add(db_constraints)
-#
-#            db_objects = [(db_constraints, created)]
-#
-#            for position,grpc_constraint in enumerate(grpc_constraints):
-#                result : Tuple[ConstraintModel, bool] = self.set_constraint(
-#                    db_constraints, grpc_constraint, position)
-#                db_constraint, updated = result
-#                db_objects.append((db_constraint, updated))
-#
-#            return db_objects
 
 def service_delete(db_engine : Engine, request : ServiceId) -> bool:
-    context_uuid = request.context_id.context_uuid.uuid
-    service_uuid = request.service_uuid.uuid
+    _,service_uuid = service_get_uuid(request, allow_random=False)
     def callback(session : Session) -> bool:
-        num_deleted = session.query(ServiceModel)\
-            .filter_by(context_uuid=context_uuid, service_uuid=service_uuid).delete()
+        num_deleted = session.query(ServiceModel).filter_by(service_uuid=service_uuid).delete()
         return num_deleted > 0
     return run_transaction(sessionmaker(bind=db_engine), callback)
-
-    # def delete(self) -> None:
-    #     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()
diff --git a/src/context/service/database/Topology.py b/src/context/service/database/Topology.py
index 25fa02f4b6a336d8b1e6c1489c09ed2be0a76006..ae8d0a8bd889a37bea82ff699ce75e521b6faf23 100644
--- a/src/context/service/database/Topology.py
+++ b/src/context/service/database/Topology.py
@@ -12,20 +12,22 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import logging
 from sqlalchemy.dialects.postgresql import insert
 from sqlalchemy.engine import Engine
 from sqlalchemy.orm import Session, sessionmaker
 from sqlalchemy_cockroachdb import run_transaction
-from typing import Dict, List, Optional, Set
+from typing import Dict, List, Optional
 from common.proto.context_pb2 import ContextId, Topology, TopologyId, TopologyIdList, TopologyList
-from common.rpc_method_wrapper.ServiceExceptions import InvalidArgumentsException, NotFoundException
+from common.rpc_method_wrapper.ServiceExceptions import NotFoundException
 from common.tools.object_factory.Context import json_context_id
 from common.tools.object_factory.Topology import json_topology_id
-#from .models.RelationModels import TopologyDeviceModel, TopologyLinkModel
 from .models.TopologyModel import TopologyModel
 from .uuids.Context import context_get_uuid
 from .uuids.Topology import topology_get_uuid
 
+LOGGER = logging.getLogger(__name__)
+
 def topology_list_ids(db_engine : Engine, request : ContextId) -> TopologyIdList:
     context_uuid = context_get_uuid(request, allow_random=False)
     def callback(session : Session) -> List[Dict]:
@@ -63,21 +65,15 @@ def topology_set(db_engine : Engine, request : Topology) -> bool:
     if len(topology_name) == 0: topology_name = request.topology_id.topology_uuid.uuid
     context_uuid,topology_uuid = topology_get_uuid(request.topology_id, topology_name=topology_name, allow_random=True)
 
-    #device_uuids : Set[str] = set()
-    #devices_to_add : List[Dict] = list()
-    #for device_id in request.device_ids:
-    #    device_uuid = device_id.device_uuid.uuid
-    #    if device_uuid in device_uuids: continue
-    #    devices_to_add.append({'topology_uuid': topology_uuid, 'device_uuid': device_uuid})
-    #    device_uuids.add(device_uuid)
+    # Ignore request.device_ids and request.link_ids. They are used for retrieving devices and links added into the
+    # topology. Explicit addition into the topology is done automatically when creating the devices and links, based
+    # on the topologies specified in the endpoints associated with the devices and links.
+
+    if len(request.device_ids) > 0:   # pragma: no cover
+        LOGGER.warning('Items in field "device_ids" ignored. This field is used for retrieval purposes only.')
 
-    #link_uuids : Set[str] = set()
-    #links_to_add : List[Dict] = list()
-    #for link_id in request.link_ids:
-    #    link_uuid = link_id.link_uuid.uuid
-    #    if link_uuid in link_uuids: continue
-    #    links_to_add.append({'topology_uuid': topology_uuid, 'link_uuid': link_uuid})
-    #    link_uuids.add(link_uuid)
+    if len(request.link_ids) > 0:    # pragma: no cover
+        LOGGER.warning('Items in field "link_ids" ignored. This field is used for retrieval purposes only.')
 
     topology_data = [{
         'context_uuid' : context_uuid,
@@ -93,16 +89,6 @@ def topology_set(db_engine : Engine, request : Topology) -> bool:
         )
         session.execute(stmt)
 
-        #if len(devices_to_add) > 0:
-        #    session.execute(insert(TopologyDeviceModel).values(devices_to_add).on_conflict_do_nothing(
-        #        index_elements=[TopologyDeviceModel.topology_uuid, TopologyDeviceModel.device_uuid]
-        #    ))
-
-        #if len(links_to_add) > 0:
-        #    session.execute(insert(TopologyLinkModel).values(links_to_add).on_conflict_do_nothing(
-        #        index_elements=[TopologyLinkModel.topology_uuid, TopologyLinkModel.link_uuid]
-        #    ))
-
     run_transaction(sessionmaker(bind=db_engine), callback)
     updated = False # TODO: improve and check if created/updated
     return TopologyId(**json_topology_id(topology_uuid, json_context_id(context_uuid))),updated
@@ -110,7 +96,6 @@ def topology_set(db_engine : Engine, request : Topology) -> bool:
 def topology_delete(db_engine : Engine, request : TopologyId) -> bool:
     _,topology_uuid = topology_get_uuid(request, allow_random=False)
     def callback(session : Session) -> bool:
-        num_deleted = session.query(TopologyModel)\
-            .filter_by(topology_uuid=topology_uuid).delete()
+        num_deleted = session.query(TopologyModel).filter_by(topology_uuid=topology_uuid).delete()
         return num_deleted > 0
     return run_transaction(sessionmaker(bind=db_engine), callback)
diff --git a/src/context/service/database/models/ConfigRuleModel.py b/src/context/service/database/models/ConfigRuleModel.py
index 9d56344e8fa1a2983d757e58f2700d510970727f..11e151ef66e9f06649579fea96ff18bdc1f855d0 100644
--- a/src/context/service/database/models/ConfigRuleModel.py
+++ b/src/context/service/database/models/ConfigRuleModel.py
@@ -28,15 +28,17 @@ class ConfigRuleModel(_Base):
     __tablename__ = 'configrule'
 
     configrule_uuid = Column(UUID(as_uuid=False), primary_key=True)
-    device_uuid     = Column(ForeignKey('device.device_uuid', ondelete='CASCADE'))
+    device_uuid     = Column(ForeignKey('device.device_uuid',   ondelete='CASCADE'), nullable=True)
+    service_uuid    = Column(ForeignKey('service.service_uuid', ondelete='CASCADE'), nullable=True)
     position        = Column(Integer, nullable=False)
-    kind            = Column(Enum(ConfigRuleKindEnum))
-    action          = Column(Enum(ORM_ConfigActionEnum))
+    kind            = Column(Enum(ConfigRuleKindEnum), nullable=False)
+    action          = Column(Enum(ORM_ConfigActionEnum), nullable=False)
     data            = Column(String, nullable=False)
 
     __table_args__ = (
         CheckConstraint(position >= 0, name='check_position_value'),
         #UniqueConstraint('device_uuid', 'position', name='unique_per_device'),
+        #UniqueConstraint('service_uuid', 'position', name='unique_per_service'),
     )
 
     def dump(self) -> Dict:
diff --git a/src/context/service/database/models/ConstraintModel.py b/src/context/service/database/models/ConstraintModel.py
index d616c3a7fe86adfccd37faa39fef737a4e21dfeb..118ae950556d6e7377053aa56c276cfcc653226a 100644
--- a/src/context/service/database/models/ConstraintModel.py
+++ b/src/context/service/database/models/ConstraintModel.py
@@ -12,144 +12,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import logging, operator
-from typing import Dict, List, Optional, Tuple, Type, Union
-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.proto.context_pb2 import Constraint
-from common.tools.grpc.Tools import grpc_message_to_json_string
-from .EndPointModel import EndPointModel
-from .Tools import fast_hasher
-from sqlalchemy import Column, ForeignKey, String, Float, CheckConstraint, Integer, Boolean, Enum
+import enum, json
+from sqlalchemy import CheckConstraint, Column, Enum, ForeignKey, Integer, String
 from sqlalchemy.dialects.postgresql import UUID
-from context.service.database.models._Base import Base
-import enum
+from typing import Dict
+from ._Base import _Base
 
-LOGGER = logging.getLogger(__name__)
-
-def remove_dict_key(dictionary : Dict, key : str):
-    dictionary.pop(key, None)
-    return dictionary
-
-class ConstraintsModel(Base): # pylint: disable=abstract-method
-    __tablename__ = 'Constraints'
-    constraints_uuid = Column(UUID(as_uuid=False), primary_key=True, unique=True)
-
-    @staticmethod
-    def main_pk_name():
-        return 'constraints_uuid'
-
-
-    def dump(self, constraints) -> List[Dict]:
-        constraints = sorted(constraints, key=operator.itemgetter('position'))
-        return [remove_dict_key(constraint, 'position') for constraint in constraints]
-
-
-class ConstraintCustomModel(Base): # pylint: disable=abstract-method
-    __tablename__ = 'ConstraintCustom'
-    constraint_uuid = Column(UUID(as_uuid=False), primary_key=True, unique=True)
-    constraint_type = Column(String, nullable=False)
-    constraint_value = Column(String, nullable=False)
-
-    @staticmethod
-    def main_pk_name():
-        return 'constraint_uuid'
-
-
-    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'
-]
-
-class ConstraintEndpointLocationRegionModel(Model): # pylint: disable=abstract-method
-    endpoint_fk = ForeignKeyField(EndPointModel)
-    region = StringField(required=True, allow_empty=False)
-
-    def dump(self) -> Dict: # pylint: disable=arguments-differ
-        json_endpoint_id = EndPointModel(self.database, self.endpoint_fk).dump_id()
-        return {'endpoint_location': {'endpoint_id': json_endpoint_id, 'location': {'region': self.region}}}
-
-# 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(Base): # pylint: disable=abstract-method
-    __tablename__ = 'ConstraintEndpointLocationRegion'
-    constraint_uuid = Column(UUID(as_uuid=False), primary_key=True, unique=True)
-    endpoint_uuid = Column(UUID(as_uuid=False), ForeignKey("EndPoint.endpoint_uuid"))
-    region = Column(String, nullable=False)
-
-    @staticmethod
-    def main_pk_name():
-        return 'constraint_uuid'
-
-    def dump(self, endpoint) -> Dict: # pylint: disable=arguments-differ
-        return {'endpoint_location': {'endpoint_id': endpoint.dump_id(), 'region': self.region}}
-
-    def dump(self) -> Dict: # pylint: disable=arguments-differ
-        gps_position = {'latitude': self.latitude, 'longitude': self.longitude}
-        json_endpoint_id = EndPointModel(self.database, self.endpoint_fk).dump_id()
-        return {'endpoint_location': {'endpoint_id': json_endpoint_id, 'location': {'gps_position': gps_position}}}
-
-class ConstraintEndpointPriorityModel(Model): # pylint: disable=abstract-method
-    endpoint_fk = ForeignKeyField(EndPointModel)
-    priority = IntegerField(required=True, min_value=0)
-
-    def dump(self) -> Dict: # pylint: disable=arguments-differ
-        json_endpoint_id = EndPointModel(self.database, self.endpoint_fk).dump_id()
-        return {'endpoint_priority': {'endpoint_id': json_endpoint_id, 'priority': self.priority}}
-
-class ConstraintEndpointLocationGpsPositionModel(Base): # pylint: disable=abstract-method
-    __tablename__ = 'ConstraintEndpointLocationGpsPosition'
-    constraint_uuid = Column(UUID(as_uuid=False), primary_key=True, unique=True)
-    endpoint_uuid = Column(UUID(as_uuid=False), ForeignKey("EndPoint.endpoint_uuid"))
-    latitude = Column(Float, CheckConstraint('latitude > -90.0 AND latitude < 90.0'), nullable=False)
-    longitude = Column(Float, CheckConstraint('longitude > -90.0 AND longitude < 90.0'), nullable=False)
-
-    def dump(self, endpoint) -> Dict: # pylint: disable=arguments-differ
-        gps_position = {'latitude': self.latitude, 'longitude': self.longitude}
-        return {'endpoint_location': {'endpoint_id': endpoint.dump_id(), 'gps_position': gps_position}}
-
-
-class ConstraintEndpointPriorityModel(Base): # pylint: disable=abstract-method
-    __tablename__ = 'ConstraintEndpointPriority'
-    constraint_uuid = Column(UUID(as_uuid=False), primary_key=True, unique=True)
-    endpoint_uuid = Column(UUID(as_uuid=False), ForeignKey("EndPoint.endpoint_uuid"))
-    # endpoint_fk = ForeignKeyField(EndPointModel)
-    # priority = FloatField(required=True)
-    priority = Column(Float, nullable=False)
-    @staticmethod
-    def main_pk_name():
-        return 'constraint_uuid'
-
-    def dump(self, endpoint) -> Dict: # pylint: disable=arguments-differ
-        return {'endpoint_priority': {'endpoint_id': endpoint.dump_id(), 'priority': self.priority}}
-
-
-class ConstraintSlaAvailabilityModel(Base): # pylint: disable=abstract-method
-    __tablename__ = 'ConstraintSlaAvailability'
-    constraint_uuid = Column(UUID(as_uuid=False), primary_key=True, unique=True)
-    # num_disjoint_paths = IntegerField(required=True, min_value=1)
-    num_disjoint_paths = Column(Integer, CheckConstraint('num_disjoint_paths > 1'), nullable=False)
-    # all_active = BooleanField(required=True)
-    all_active = Column(Boolean, nullable=False)
-    @staticmethod
-    def main_pk_name():
-        return 'constraint_uuid'
-
-    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
+# Enum values should match name of field in ConstraintModel
 class ConstraintKindEnum(enum.Enum):
     CUSTOM                        = 'custom'
     ENDPOINT_LOCATION_REGION      = 'ep_loc_region'
@@ -157,215 +26,370 @@ class ConstraintKindEnum(enum.Enum):
     ENDPOINT_PRIORITY             = 'ep_priority'
     SLA_AVAILABILITY              = 'sla_avail'
 
-Union_SpecificConstraint = Union[
-    ConstraintCustomModel, ConstraintEndpointLocationRegionModel, ConstraintEndpointLocationGpsPositionModel,
-    ConstraintEndpointPriorityModel, ConstraintSlaAvailabilityModel,
-]
-
-class ConstraintModel(Base): # pylint: disable=abstract-method
-    __tablename__ = 'Constraint'
-    # pk = PrimaryKeyField()
-    # constraints_fk = ForeignKeyField(ConstraintsModel)
-    constraint_uuid = Column(UUID(as_uuid=False), primary_key=True, unique=True)
-    constraints_uuid = Column(UUID(as_uuid=False), ForeignKey("Constraints.constraints_uuid"), primary_key=True)
-    # kind = EnumeratedField(ConstraintKindEnum)
-    kind = Column(Enum(ConstraintKindEnum, create_constraint=False, native_enum=False))
-    # position = IntegerField(min_value=0, required=True)
-    position = Column(Integer, CheckConstraint('position >= 0'), nullable=False)
-    # constraint_custom_fk        = ForeignKeyField(ConstraintCustomModel, required=False)
-    constraint_custom = Column(UUID(as_uuid=False), ForeignKey("ConstraintCustom.constraint_uuid"))
-    # constraint_ep_loc_region_fk = ForeignKeyField(ConstraintEndpointLocationRegionModel, required=False)
-    constraint_ep_loc_region = Column(UUID(as_uuid=False), ForeignKey("ConstraintEndpointLocationRegion.constraint_uuid"))
-    # constraint_ep_loc_gpspos_fk = ForeignKeyField(ConstraintEndpointLocationGpsPositionModel, required=False)
-    constraint_ep_loc_gpspos = Column(UUID(as_uuid=False), ForeignKey("ConstraintEndpointLocationGpsPosition.constraint_uuid"))
-    # constraint_ep_priority_fk   = ForeignKeyField(ConstraintEndpointPriorityModel, required=False)
-    constraint_ep_priority = Column(UUID(as_uuid=False), ForeignKey("ConstraintEndpointPriority.constraint_uuid"),)
-    # constraint_sla_avail_fk     = ForeignKeyField(ConstraintSlaAvailabilityModel, required=False)
-    constraint_sla_avail = Column(UUID(as_uuid=False), ForeignKey("ConstraintSlaAvailability.constraint_uuid"))
-
-    @staticmethod
-    def main_pk_name():
-        return 'constraint_uuid'
-
-    # 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
-        field_name = 'constraint_{:s}'.format(str(self.kind.value))
-        specific_fk_value = 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: Base = 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
-
-Tuple_ConstraintSpecs = Tuple[Type, str, Dict, ConstraintKindEnum]
-
-def parse_constraint_custom(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, ConstraintKindEnum.CUSTOM
-
-def parse_constraint_endpoint_location(db_endpoint, grpc_constraint) -> Tuple_ConstraintSpecs:
-    grpc_endpoint_id = grpc_constraint.endpoint_location.endpoint_id
-    # str_endpoint_key, db_endpoint = get_endpoint(database, grpc_endpoint_id)
-
-    str_constraint_id = db_endpoint.endpoint_uuid
-    constraint_data = {'endpoint_fk': db_endpoint}
-
-    grpc_location = grpc_constraint.endpoint_location.location
-    location_kind = str(grpc_location.WhichOneof('location'))
-    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)))
-
-def parse_constraint_endpoint_priority(db_endpoint, grpc_constraint) -> Tuple_ConstraintSpecs:
-    grpc_endpoint_id = grpc_constraint.endpoint_priority.endpoint_id
-    # str_endpoint_key, db_endpoint = get_endpoint(database, grpc_endpoint_id)
-
-    constraint_class = ConstraintEndpointPriorityModel
-    str_constraint_id = db_endpoint.endpoint_uuid
-    priority = grpc_constraint.endpoint_priority.priority
-    constraint_data = {'endpoint_fk': db_endpoint, 'priority': priority}
-
-    return constraint_class, str_constraint_id, constraint_data, ConstraintKindEnum.ENDPOINT_PRIORITY
-
-def parse_constraint_sla_availability(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, ConstraintKindEnum.SLA_AVAILABILITY
-
-CONSTRAINT_PARSERS = {
-    'custom'            : parse_constraint_custom,
-    'endpoint_location' : parse_constraint_endpoint_location,
-    'endpoint_priority' : parse_constraint_endpoint_priority,
-    'sla_availability'  : parse_constraint_sla_availability,
-}
-
-Union_ConstraintModel = Union[
-    ConstraintCustomModel, ConstraintEndpointLocationGpsPositionModel, ConstraintEndpointLocationRegionModel,
-    ConstraintEndpointPriorityModel, ConstraintSlaAvailabilityModel
-]
-
-# def set_constraint(
-#     db_constraints : ConstraintsModel, grpc_constraint : Constraint, position : int
-# ) -> Tuple[Union_ConstraintModel, bool]:
-#     grpc_constraint_kind = str(grpc_constraint.WhichOneof('constraint'))
-#
-#     parser = CONSTRAINT_PARSERS.get(grpc_constraint_kind)
-#     if parser is None:
-#         raise NotImplementedError('Constraint of kind {:s} is not implemented: {:s}'.format(
-#             grpc_constraint_kind, grpc_message_to_json_string(grpc_constraint)))
-#
-#     # 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=':')
-#     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, ConstraintModel, str_constraint_key, constraint_data)
-#     db_constraint, updated = result
-#
-#     return db_constraint, updated
-#
-# def set_constraints(
-#     database : Database, db_parent_pk : str, constraints_name : str, grpc_constraints
-# ) -> List[Tuple[Union[ConstraintsModel, ConstraintModel], bool]]:
-#
-#     str_constraints_key = key_to_str([db_parent_pk, constraints_name], separator=':')
-#     result : Tuple[ConstraintsModel, bool] = get_or_create_object(database, ConstraintsModel, str_constraints_key)
-#     db_constraints, created = result
-#
-#     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)
-#         db_constraint, updated = result
-#         db_objects.append((db_constraint, updated))
-#
-#     return db_objects
-def set_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(grpc_constraint_kind)
-    if parser is None:
-        raise NotImplementedError('Constraint of kind {:s} is not implemented: {:s}'.format(
-            grpc_constraint_kind, grpc_message_to_json_string(grpc_constraint)))
-
-    # 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=':')
-    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, ConstraintModel, str_constraint_key, constraint_data)
-    db_constraint, updated = result
-
-    return db_constraint, updated
-
-def set_constraints(
-    database : Database, db_parent_pk : str, constraints_name : str, grpc_constraints
-) -> List[Tuple[Union[ConstraintsModel, ConstraintModel], bool]]:
-
-    str_constraints_key = key_to_str([constraints_name, db_parent_pk], separator=':')
-    result : Tuple[ConstraintsModel, bool] = get_or_create_object(database, ConstraintsModel, str_constraints_key)
-    db_constraints, created = result
-
-    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)
-        db_constraint, updated = result
-        db_objects.append((db_constraint, updated))
-
-    return db_objects
+class ConstraintModel(_Base):
+    __tablename__ = 'constraint'
+
+    constraint_uuid = Column(UUID(as_uuid=False), primary_key=True)
+    service_uuid    = Column(ForeignKey('service.service_uuid', ondelete='CASCADE'), nullable=False)
+    position        = Column(Integer, nullable=False)
+    kind            = Column(Enum(ConstraintKindEnum), nullable=False)
+    data            = Column(String, nullable=False)
+
+    __table_args__ = (
+        CheckConstraint(position >= 0, name='check_position_value'),
+        #UniqueConstraint('service_uuid', 'position', name='unique_per_service'),
+    )
+
+    def dump(self) -> Dict:
+        return {self.kind.value: json.loads(self.data)}
+
+
+#import logging, operator
+#from typing import Dict, List, Optional, Tuple, Type, Union
+#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.proto.context_pb2 import Constraint
+#from common.tools.grpc.Tools import grpc_message_to_json_string
+#from .EndPointModel import EndPointModel
+#from .Tools import fast_hasher
+#from sqlalchemy import Column, ForeignKey, String, Float, CheckConstraint, Integer, Boolean, Enum
+#from sqlalchemy.dialects.postgresql import UUID
+#from context.service.database.models._Base import Base
+#import enum
+#
+#LOGGER = logging.getLogger(__name__)
+#
+#def remove_dict_key(dictionary : Dict, key : str):
+#    dictionary.pop(key, None)
+#    return dictionary
+#
+#class ConstraintsModel(Base): # pylint: disable=abstract-method
+#    __tablename__ = 'Constraints'
+#    constraints_uuid = Column(UUID(as_uuid=False), primary_key=True, unique=True)
+#
+#    @staticmethod
+#    def main_pk_name():
+#        return 'constraints_uuid'
+#
+#
+#    def dump(self, constraints) -> List[Dict]:
+#        constraints = sorted(constraints, key=operator.itemgetter('position'))
+#        return [remove_dict_key(constraint, 'position') for constraint in constraints]
+#
+#
+#class ConstraintCustomModel(Base): # pylint: disable=abstract-method
+#    __tablename__ = 'ConstraintCustom'
+#    constraint_uuid = Column(UUID(as_uuid=False), primary_key=True, unique=True)
+#    constraint_type = Column(String, nullable=False)
+#    constraint_value = Column(String, nullable=False)
+#
+#    @staticmethod
+#    def main_pk_name():
+#        return 'constraint_uuid'
+#
+#
+#    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'
+#]
+#
+#class ConstraintEndpointLocationRegionModel(Model): # pylint: disable=abstract-method
+#    endpoint_fk = ForeignKeyField(EndPointModel)
+#    region = StringField(required=True, allow_empty=False)
+#
+#    def dump(self) -> Dict: # pylint: disable=arguments-differ
+#        json_endpoint_id = EndPointModel(self.database, self.endpoint_fk).dump_id()
+#        return {'endpoint_location': {'endpoint_id': json_endpoint_id, 'location': {'region': self.region}}}
+#
+## 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(Base): # pylint: disable=abstract-method
+#    __tablename__ = 'ConstraintEndpointLocationRegion'
+#    constraint_uuid = Column(UUID(as_uuid=False), primary_key=True, unique=True)
+#    endpoint_uuid = Column(UUID(as_uuid=False), ForeignKey("EndPoint.endpoint_uuid"))
+#    region = Column(String, nullable=False)
+#
+#    @staticmethod
+#    def main_pk_name():
+#        return 'constraint_uuid'
+#
+#    def dump(self, endpoint) -> Dict: # pylint: disable=arguments-differ
+#        return {'endpoint_location': {'endpoint_id': endpoint.dump_id(), 'region': self.region}}
+#
+#    def dump(self) -> Dict: # pylint: disable=arguments-differ
+#        gps_position = {'latitude': self.latitude, 'longitude': self.longitude}
+#        json_endpoint_id = EndPointModel(self.database, self.endpoint_fk).dump_id()
+#        return {'endpoint_location': {'endpoint_id': json_endpoint_id, 'location': {'gps_position': gps_position}}}
+#
+#class ConstraintEndpointPriorityModel(Model): # pylint: disable=abstract-method
+#    endpoint_fk = ForeignKeyField(EndPointModel)
+#    priority = IntegerField(required=True, min_value=0)
+#
+#    def dump(self) -> Dict: # pylint: disable=arguments-differ
+#        json_endpoint_id = EndPointModel(self.database, self.endpoint_fk).dump_id()
+#        return {'endpoint_priority': {'endpoint_id': json_endpoint_id, 'priority': self.priority}}
+#
+#class ConstraintEndpointLocationGpsPositionModel(Base): # pylint: disable=abstract-method
+#    __tablename__ = 'ConstraintEndpointLocationGpsPosition'
+#    constraint_uuid = Column(UUID(as_uuid=False), primary_key=True, unique=True)
+#    endpoint_uuid = Column(UUID(as_uuid=False), ForeignKey("EndPoint.endpoint_uuid"))
+#    latitude = Column(Float, CheckConstraint('latitude > -90.0 AND latitude < 90.0'), nullable=False)
+#    longitude = Column(Float, CheckConstraint('longitude > -90.0 AND longitude < 90.0'), nullable=False)
+#
+#    def dump(self, endpoint) -> Dict: # pylint: disable=arguments-differ
+#        gps_position = {'latitude': self.latitude, 'longitude': self.longitude}
+#        return {'endpoint_location': {'endpoint_id': endpoint.dump_id(), 'gps_position': gps_position}}
+#
+#
+#class ConstraintEndpointPriorityModel(Base): # pylint: disable=abstract-method
+#    __tablename__ = 'ConstraintEndpointPriority'
+#    constraint_uuid = Column(UUID(as_uuid=False), primary_key=True, unique=True)
+#    endpoint_uuid = Column(UUID(as_uuid=False), ForeignKey("EndPoint.endpoint_uuid"))
+#    # endpoint_fk = ForeignKeyField(EndPointModel)
+#    # priority = FloatField(required=True)
+#    priority = Column(Float, nullable=False)
+#    @staticmethod
+#    def main_pk_name():
+#        return 'constraint_uuid'
+#
+#    def dump(self, endpoint) -> Dict: # pylint: disable=arguments-differ
+#        return {'endpoint_priority': {'endpoint_id': endpoint.dump_id(), 'priority': self.priority}}
+#
+#
+#class ConstraintSlaAvailabilityModel(Base): # pylint: disable=abstract-method
+#    __tablename__ = 'ConstraintSlaAvailability'
+#    constraint_uuid = Column(UUID(as_uuid=False), primary_key=True, unique=True)
+#    # num_disjoint_paths = IntegerField(required=True, min_value=1)
+#    num_disjoint_paths = Column(Integer, CheckConstraint('num_disjoint_paths > 1'), nullable=False)
+#    # all_active = BooleanField(required=True)
+#    all_active = Column(Boolean, nullable=False)
+#    @staticmethod
+#    def main_pk_name():
+#        return 'constraint_uuid'
+#
+#    def dump(self) -> Dict: # pylint: disable=arguments-differ
+#        return {'sla_availability': {'num_disjoint_paths': self.num_disjoint_paths, 'all_active': self.all_active}}
+#
+#Union_SpecificConstraint = Union[
+#    ConstraintCustomModel, ConstraintEndpointLocationRegionModel, ConstraintEndpointLocationGpsPositionModel,
+#    ConstraintEndpointPriorityModel, ConstraintSlaAvailabilityModel,
+#]
+#
+#class ConstraintModel(Base): # pylint: disable=abstract-method
+#    __tablename__ = 'Constraint'
+#    # pk = PrimaryKeyField()
+#    # constraints_fk = ForeignKeyField(ConstraintsModel)
+#    constraint_uuid = Column(UUID(as_uuid=False), primary_key=True, unique=True)
+#    constraints_uuid = Column(UUID(as_uuid=False), ForeignKey("Constraints.constraints_uuid"), primary_key=True)
+#    # kind = EnumeratedField(ConstraintKindEnum)
+#    kind = Column(Enum(ConstraintKindEnum, create_constraint=False, native_enum=False))
+#    # position = IntegerField(min_value=0, required=True)
+#    position = Column(Integer, CheckConstraint('position >= 0'), nullable=False)
+#    # constraint_custom_fk        = ForeignKeyField(ConstraintCustomModel, required=False)
+#    constraint_custom = Column(UUID(as_uuid=False), ForeignKey("ConstraintCustom.constraint_uuid"))
+#    # constraint_ep_loc_region_fk = ForeignKeyField(ConstraintEndpointLocationRegionModel, required=False)
+#    constraint_ep_loc_region = Column(UUID(as_uuid=False), ForeignKey("ConstraintEndpointLocationRegion.constraint_uuid"))
+#    # constraint_ep_loc_gpspos_fk = ForeignKeyField(ConstraintEndpointLocationGpsPositionModel, required=False)
+#    constraint_ep_loc_gpspos = Column(UUID(as_uuid=False), ForeignKey("ConstraintEndpointLocationGpsPosition.constraint_uuid"))
+#    # constraint_ep_priority_fk   = ForeignKeyField(ConstraintEndpointPriorityModel, required=False)
+#    constraint_ep_priority = Column(UUID(as_uuid=False), ForeignKey("ConstraintEndpointPriority.constraint_uuid"),)
+#    # constraint_sla_avail_fk     = ForeignKeyField(ConstraintSlaAvailabilityModel, required=False)
+#    constraint_sla_avail = Column(UUID(as_uuid=False), ForeignKey("ConstraintSlaAvailability.constraint_uuid"))
+#
+#    @staticmethod
+#    def main_pk_name():
+#        return 'constraint_uuid'
+#
+#    # 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
+#        field_name = 'constraint_{:s}'.format(str(self.kind.value))
+#        specific_fk_value = 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: Base = 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
+#
+#Tuple_ConstraintSpecs = Tuple[Type, str, Dict, ConstraintKindEnum]
+#
+#def parse_constraint_custom(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, ConstraintKindEnum.CUSTOM
+#
+#def parse_constraint_endpoint_location(db_endpoint, grpc_constraint) -> Tuple_ConstraintSpecs:
+#    grpc_endpoint_id = grpc_constraint.endpoint_location.endpoint_id
+#    # str_endpoint_key, db_endpoint = get_endpoint(database, grpc_endpoint_id)
+#
+#    str_constraint_id = db_endpoint.endpoint_uuid
+#    constraint_data = {'endpoint_fk': db_endpoint}
+#
+#    grpc_location = grpc_constraint.endpoint_location.location
+#    location_kind = str(grpc_location.WhichOneof('location'))
+#    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)))
+#
+#def parse_constraint_endpoint_priority(db_endpoint, grpc_constraint) -> Tuple_ConstraintSpecs:
+#    grpc_endpoint_id = grpc_constraint.endpoint_priority.endpoint_id
+#    # str_endpoint_key, db_endpoint = get_endpoint(database, grpc_endpoint_id)
+#
+#    constraint_class = ConstraintEndpointPriorityModel
+#    str_constraint_id = db_endpoint.endpoint_uuid
+#    priority = grpc_constraint.endpoint_priority.priority
+#    constraint_data = {'endpoint_fk': db_endpoint, 'priority': priority}
+#
+#    return constraint_class, str_constraint_id, constraint_data, ConstraintKindEnum.ENDPOINT_PRIORITY
+#
+#def parse_constraint_sla_availability(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, ConstraintKindEnum.SLA_AVAILABILITY
+#
+#CONSTRAINT_PARSERS = {
+#    'custom'            : parse_constraint_custom,
+#    'endpoint_location' : parse_constraint_endpoint_location,
+#    'endpoint_priority' : parse_constraint_endpoint_priority,
+#    'sla_availability'  : parse_constraint_sla_availability,
+#}
+#
+#Union_ConstraintModel = Union[
+#    ConstraintCustomModel, ConstraintEndpointLocationGpsPositionModel, ConstraintEndpointLocationRegionModel,
+#    ConstraintEndpointPriorityModel, ConstraintSlaAvailabilityModel
+#]
+#
+## def set_constraint(
+##     db_constraints : ConstraintsModel, grpc_constraint : Constraint, position : int
+## ) -> Tuple[Union_ConstraintModel, bool]:
+##     grpc_constraint_kind = str(grpc_constraint.WhichOneof('constraint'))
+##
+##     parser = CONSTRAINT_PARSERS.get(grpc_constraint_kind)
+##     if parser is None:
+##         raise NotImplementedError('Constraint of kind {:s} is not implemented: {:s}'.format(
+##             grpc_constraint_kind, grpc_message_to_json_string(grpc_constraint)))
+##
+##     # 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=':')
+##     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, ConstraintModel, str_constraint_key, constraint_data)
+##     db_constraint, updated = result
+##
+##     return db_constraint, updated
+##
+## def set_constraints(
+##     database : Database, db_parent_pk : str, constraints_name : str, grpc_constraints
+## ) -> List[Tuple[Union[ConstraintsModel, ConstraintModel], bool]]:
+##
+##     str_constraints_key = key_to_str([db_parent_pk, constraints_name], separator=':')
+##     result : Tuple[ConstraintsModel, bool] = get_or_create_object(database, ConstraintsModel, str_constraints_key)
+##     db_constraints, created = result
+##
+##     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)
+##         db_constraint, updated = result
+##         db_objects.append((db_constraint, updated))
+##
+##     return db_objects
+#def set_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(grpc_constraint_kind)
+#    if parser is None:
+#        raise NotImplementedError('Constraint of kind {:s} is not implemented: {:s}'.format(
+#            grpc_constraint_kind, grpc_message_to_json_string(grpc_constraint)))
+#
+#    # 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=':')
+#    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, ConstraintModel, str_constraint_key, constraint_data)
+#    db_constraint, updated = result
+#
+#    return db_constraint, updated
+#
+#def set_constraints(
+#    database : Database, db_parent_pk : str, constraints_name : str, grpc_constraints
+#) -> List[Tuple[Union[ConstraintsModel, ConstraintModel], bool]]:
+#
+#    str_constraints_key = key_to_str([constraints_name, db_parent_pk], separator=':')
+#    result : Tuple[ConstraintsModel, bool] = get_or_create_object(database, ConstraintsModel, str_constraints_key)
+#    db_constraints, created = result
+#
+#    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)
+#        db_constraint, updated = result
+#        db_objects.append((db_constraint, updated))
+#
+#    return db_objects
diff --git a/src/context/service/database/models/ContextModel.py b/src/context/service/database/models/ContextModel.py
index 84039dea9a5a9c52376b08d8af499b711d509f1b..1a282e8bd4c9ac0e74b1257f035997393a04347c 100644
--- a/src/context/service/database/models/ContextModel.py
+++ b/src/context/service/database/models/ContextModel.py
@@ -25,7 +25,7 @@ class ContextModel(_Base):
     context_name = Column(String, nullable=False)
 
     topologies = relationship('TopologyModel', back_populates='context')
-    #services   = relationship('ServiceModel',  back_populates='context')
+    services   = relationship('ServiceModel',  back_populates='context')
     #slices     = relationship('SliceModel', back_populates='context')
 
     def dump_id(self) -> Dict:
@@ -36,6 +36,6 @@ class ContextModel(_Base):
             'context_id'  : self.dump_id(),
             'name'        : self.context_name,
             'topology_ids': [obj.dump_id() for obj in self.topologies],
-            #'service_ids' : [obj.dump_id() for obj in self.services ],
-            #'slice_ids'   : [obj.dump_id() for obj in self.slices   ],
+            'service_ids' : [obj.dump_id() for obj in self.services  ],
+            #'slice_ids'   : [obj.dump_id() for obj in self.slices    ],
         }
diff --git a/src/context/service/database/models/DeviceModel.py b/src/context/service/database/models/DeviceModel.py
index 50db8e7bb7a93131e3a4ef635a887eb62316022f..74fa70cf8c75ffab11a363df39211a941b7f2c3f 100644
--- a/src/context/service/database/models/DeviceModel.py
+++ b/src/context/service/database/models/DeviceModel.py
@@ -14,8 +14,8 @@
 
 import operator
 from typing import Dict
-from sqlalchemy import Column, String, Enum
-from sqlalchemy.dialects.postgresql import UUID, ARRAY
+from sqlalchemy import Column, Enum, String
+from sqlalchemy.dialects.postgresql import ARRAY, UUID
 from sqlalchemy.orm import relationship
 from .enums.DeviceDriver import ORM_DeviceDriverEnum
 from .enums.DeviceOperationalStatus import ORM_DeviceOperationalStatusEnum
@@ -27,7 +27,7 @@ class DeviceModel(_Base):
     device_uuid = Column(UUID(as_uuid=False), primary_key=True)
     device_name = Column(String, nullable=False)
     device_type = Column(String, nullable=False)
-    device_operational_status = Column(Enum(ORM_DeviceOperationalStatusEnum))
+    device_operational_status = Column(Enum(ORM_DeviceOperationalStatusEnum), nullable=False)
     device_drivers = Column(ARRAY(Enum(ORM_DeviceDriverEnum), dimensions=1))
 
     #topology_devices = relationship('TopologyDeviceModel', back_populates='device')
diff --git a/src/context/service/database/models/EndPointModel.py b/src/context/service/database/models/EndPointModel.py
index f9d5f7658a041f3670fe3256e9c3a863f4682d5b..b69b4978b99c722f6af57fd4095dde1c4fb6df0a 100644
--- a/src/context/service/database/models/EndPointModel.py
+++ b/src/context/service/database/models/EndPointModel.py
@@ -23,10 +23,10 @@ class EndPointModel(_Base):
     __tablename__ = 'endpoint'
 
     endpoint_uuid    = Column(UUID(as_uuid=False), primary_key=True)
-    device_uuid      = Column(UUID(as_uuid=False), ForeignKey('device.device_uuid',     ondelete='CASCADE' ))
-    topology_uuid    = Column(UUID(as_uuid=False), ForeignKey('topology.topology_uuid', ondelete='RESTRICT'))
-    name             = Column(String)
-    endpoint_type    = Column(String)
+    device_uuid      = Column(ForeignKey('device.device_uuid',     ondelete='CASCADE' ), nullable=False)
+    topology_uuid    = Column(ForeignKey('topology.topology_uuid', ondelete='RESTRICT'), nullable=False)
+    name             = Column(String, nullable=False)
+    endpoint_type    = Column(String, nullable=False)
     kpi_sample_types = Column(ARRAY(Enum(ORM_KpiSampleTypeEnum), dimensions=1))
 
     device            = relationship('DeviceModel',          back_populates='endpoints')
diff --git a/src/context/service/database/models/LinkModel.py b/src/context/service/database/models/LinkModel.py
index 053dc0122797c99a956053d40af00e51559cbda5..fd4f80c166998e726d16ef0f7075a0f186a372c1 100644
--- a/src/context/service/database/models/LinkModel.py
+++ b/src/context/service/database/models/LinkModel.py
@@ -25,7 +25,7 @@ class LinkModel(_Base):
     link_name  = Column(String, nullable=False)
 
     #topology_links = relationship('TopologyLinkModel', back_populates='link')
-    link_endpoints = relationship('LinkEndPointModel', back_populates='link') #, lazy='joined')
+    link_endpoints = relationship('LinkEndPointModel') # lazy='joined', back_populates='link'
 
     def dump_id(self) -> Dict:
         return {'link_uuid': {'uuid': self.link_uuid}}
diff --git a/src/context/service/database/models/RelationModels.py b/src/context/service/database/models/RelationModels.py
index 89e8e05e082058f28f15421912a9bfbfcd294959..a57d85eb3a598b3909600cba9e36d8e07ef9a74f 100644
--- a/src/context/service/database/models/RelationModels.py
+++ b/src/context/service/database/models/RelationModels.py
@@ -31,33 +31,14 @@ class LinkEndPointModel(_Base):
     link     = relationship('LinkModel',     back_populates='link_endpoints', lazy='joined')
     endpoint = relationship('EndPointModel', lazy='joined') # back_populates='link_endpoints'
 
-#class ServiceEndPointModel(_Base):
-#    __tablename__ = 'service_endpoint'
-#
-#    context_uuid  = Column(UUID(as_uuid=False), primary_key=True)
-#    service_uuid  = Column(UUID(as_uuid=False), primary_key=True)
-#    topology_uuid = Column(UUID(as_uuid=False), primary_key=True)
-#    device_uuid   = Column(UUID(as_uuid=False), primary_key=True)
-#    endpoint_uuid = Column(UUID(as_uuid=False), primary_key=True)
-#
-#    service  = relationship('ServiceModel',  back_populates='service_endpoints', lazy='joined')
-#    endpoint = relationship('EndPointModel', back_populates='service_endpoints', lazy='joined')
-#    writer = relationship(
-#        "Writer",
-#        primaryjoin="and_(Writer.id == foreign(Article.writer_id), "
-#        "Writer.magazine_id == Article.magazine_id)",
-#    )
-#
-#    __table_args__ = (
-#        ForeignKeyConstraint(
-#            ['context_uuid', 'service_uuid'],
-#            ['service.context_uuid', 'service.service_uuid'],
-#            ondelete='CASCADE'),
-#        ForeignKeyConstraint(
-#            ['context_uuid', 'topology_uuid', 'device_uuid', 'endpoint_uuid'],
-#            ['endpoint.context_uuid', 'endpoint.topology_uuid', 'endpoint.device_uuid', 'endpoint.endpoint_uuid'],
-#            ondelete='CASCADE'),
-#    )
+class ServiceEndPointModel(_Base):
+    __tablename__ = 'service_endpoint'
+
+    service_uuid  = Column(ForeignKey('service.service_uuid',   ondelete='CASCADE' ), primary_key=True)
+    endpoint_uuid = Column(ForeignKey('endpoint.endpoint_uuid', ondelete='RESTRICT'), primary_key=True)
+
+    service  = relationship('ServiceModel',  back_populates='service_endpoints', lazy='joined')
+    endpoint = relationship('EndPointModel', lazy='joined') # back_populates='service_endpoints'
 
 # class SliceEndPointModel(Model):
 #     pk = PrimaryKeyField()
diff --git a/src/context/service/database/models/ServiceModel.py b/src/context/service/database/models/ServiceModel.py
index ea4e895264d3702b174e85c22b35229c6e95687d..b080438448a3fd89b359d5b412cdbdcd7aa0e042 100644
--- a/src/context/service/database/models/ServiceModel.py
+++ b/src/context/service/database/models/ServiceModel.py
@@ -13,8 +13,8 @@
 # limitations under the License.
 
 import operator
-from sqlalchemy import Column, Enum, Float, ForeignKey, String
 from typing import Dict
+from sqlalchemy import Column, Enum, ForeignKey, String
 from sqlalchemy.dialects.postgresql import UUID
 from sqlalchemy.orm import relationship
 from .enums.ServiceStatus import ORM_ServiceStatusEnum
@@ -24,17 +24,16 @@ from ._Base import _Base
 class ServiceModel(_Base):
     __tablename__ = 'service'
 
-    context_uuid   = Column(UUID(as_uuid=False), ForeignKey('context.context_uuid'), primary_key=True)
     service_uuid   = Column(UUID(as_uuid=False), primary_key=True)
+    context_uuid   = Column(ForeignKey('context.context_uuid'), nullable=False)
     service_name   = Column(String, nullable=False)
-    service_type   = Column(Enum(ORM_ServiceTypeEnum))
-    service_status = Column(Enum(ORM_ServiceStatusEnum))
-    created_at     = Column(Float)
+    service_type   = Column(Enum(ORM_ServiceTypeEnum), nullable=False)
+    service_status = Column(Enum(ORM_ServiceStatusEnum), nullable=False)
 
     context           = relationship('ContextModel', back_populates='services')
-    service_endpoints = relationship('ServiceEndPointModel', back_populates='service') #, lazy='joined')
-    #constraints       = relationship('ConstraintModel', passive_deletes=True, back_populates='service', lazy='joined')
-    config_rules      = relationship('ConfigRuleModel', passive_deletes=True, back_populates='service', lazy='joined')
+    service_endpoints = relationship('ServiceEndPointModel') # lazy='joined', back_populates='service'
+    constraints       = relationship('ConstraintModel', passive_deletes=True) # lazy='joined', back_populates='service'
+    config_rules      = relationship('ConfigRuleModel', passive_deletes=True) # lazy='joined', back_populates='service'
 
     def dump_id(self) -> Dict:
         return {
@@ -53,8 +52,8 @@ class ServiceModel(_Base):
                 for service_endpoint in self.service_endpoints
             ],
             'service_constraints' : [
-                #constraint.dump()
-                #for constraint in sorted(self.constraints, key=operator.attrgetter('position'))
+                constraint.dump()
+                for constraint in sorted(self.constraints, key=operator.attrgetter('position'))
             ],
             'service_config'      : {'config_rules': [
                 config_rule.dump()
diff --git a/src/context/service/database/models/TopologyModel.py b/src/context/service/database/models/TopologyModel.py
index e0119beadf631cfca0297d011e03448ce93b0efe..8c59bf58a01d64306ad0e6138ed7d561a1aae8c5 100644
--- a/src/context/service/database/models/TopologyModel.py
+++ b/src/context/service/database/models/TopologyModel.py
@@ -22,7 +22,7 @@ class TopologyModel(_Base):
     __tablename__ = 'topology'
 
     topology_uuid = Column(UUID(as_uuid=False), primary_key=True)
-    context_uuid  = Column(UUID(as_uuid=False), ForeignKey('context.context_uuid'))
+    context_uuid  = Column(ForeignKey('context.context_uuid'), nullable=False)
     topology_name = Column(String, nullable=False)
 
     context          = relationship('ContextModel', back_populates='topologies')
diff --git a/src/context/service/database/uuids/Service.py b/src/context/service/database/uuids/Service.py
new file mode 100644
index 0000000000000000000000000000000000000000..56a5d12a0965b0ac26cd9027ad39ecb3546a426b
--- /dev/null
+++ b/src/context/service/database/uuids/Service.py
@@ -0,0 +1,37 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from typing import Tuple
+from common.proto.context_pb2 import ServiceId
+from common.rpc_method_wrapper.ServiceExceptions import InvalidArgumentsException
+from ._Builder import get_uuid_from_string, get_uuid_random
+from .Context import context_get_uuid
+
+def service_get_uuid(
+    service_id : ServiceId, service_name : str = '', allow_random : bool = False
+) -> Tuple[str, str]:
+    context_uuid = context_get_uuid(service_id.context_id, allow_random=False)
+    raw_service_uuid = service_id.service_uuid.uuid
+
+    if len(raw_service_uuid) > 0:
+        return context_uuid, get_uuid_from_string(raw_service_uuid, prefix_for_name=context_uuid)
+    if len(service_name) > 0:
+        return context_uuid, get_uuid_from_string(service_name, prefix_for_name=context_uuid)
+    if allow_random:
+        return context_uuid, get_uuid_random()
+
+    raise InvalidArgumentsException([
+        ('service_id.service_uuid.uuid', raw_service_uuid),
+        ('name', service_name),
+    ], extra_details=['At least one is required to produce a Service UUID'])
diff --git a/src/context/tests/_test_service.py b/src/context/tests/test_service.py
similarity index 58%
rename from src/context/tests/_test_service.py
rename to src/context/tests/test_service.py
index 8bd6570de876cd71b09c55849090f4f84a68e282..ca81bbfa33d2a8e61b56201833acba0e7af29b8e 100644
--- a/src/context/tests/_test_service.py
+++ b/src/context/tests/test_service.py
@@ -13,108 +13,105 @@
 # limitations under the License.
 
 import copy, grpc, pytest
-from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID
 from common.proto.context_pb2 import (
     Context, ContextId, Device, DeviceId, Service, ServiceId, ServiceStatusEnum, ServiceTypeEnum, Topology, TopologyId)
 from context.client.ContextClient import ContextClient
+from context.service.database.uuids.Service import service_get_uuid
 #from context.client.EventsCollector import EventsCollector
 from .Objects import (
-    CONTEXT, CONTEXT_ID, DEVICE_R1, DEVICE_R1_ID, DEVICE_R1_UUID, DEVICE_R2, DEVICE_R2_ID, DEVICE_R2_UUID,
-    SERVICE_R1_R2, SERVICE_R1_R2_ID, SERVICE_R1_R2_UUID, TOPOLOGY, TOPOLOGY_ID)
+    CONTEXT, CONTEXT_ID, CONTEXT_NAME, DEVICE_R1, DEVICE_R1_ID, SERVICE_R1_R2_NAME, DEVICE_R2, DEVICE_R2_ID,
+    SERVICE_R1_R2, SERVICE_R1_R2_ID, TOPOLOGY, TOPOLOGY_ID)
 
-def grpc_service(context_client_grpc : ContextClient) -> None:
+@pytest.mark.depends(on=['context/tests/test_link.py::test_link'])
+def test_service(context_client : ContextClient) -> None:
 
     # ----- Initialize the EventsCollector -----------------------------------------------------------------------------
     #events_collector = EventsCollector(
-    #    context_client_grpc, log_events_received=True,
+    #    context_client, log_events_received=True,
     #    activate_context_collector = False, activate_topology_collector = False, activate_device_collector = False,
     #    activate_link_collector = False, activate_service_collector = True, activate_slice_collector = False,
     #    activate_connection_collector = False)
     #events_collector.start()
 
     # ----- Prepare dependencies for the test and capture related events -----------------------------------------------
-    response = context_client_grpc.SetContext(Context(**CONTEXT))
-    assert response.context_uuid.uuid == DEFAULT_CONTEXT_UUID
-
-    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_grpc.SetDevice(Device(**DEVICE_R1))
-    assert response.device_uuid.uuid == DEVICE_R1_UUID
-
-    response = context_client_grpc.SetDevice(Device(**DEVICE_R2))
-    assert response.device_uuid.uuid == DEVICE_R2_UUID
+    context_client.SetContext(Context(**CONTEXT))
+    context_client.SetTopology(Topology(**TOPOLOGY))
+    context_client.SetDevice(Device(**DEVICE_R1))
+    context_client.SetDevice(Device(**DEVICE_R2))
 
     # events = events_collector.get_events(block=True, count=4)
     # assert isinstance(events[0], ContextEvent)
     # assert events[0].event.event_type == EventTypeEnum.EVENTTYPE_CREATE
-    # assert events[0].context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
+    # assert events[0].context_id.context_uuid.uuid == context_uuid
     # assert isinstance(events[1], TopologyEvent)
     # assert events[1].event.event_type == EventTypeEnum.EVENTTYPE_CREATE
-    # assert events[1].topology_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
-    # assert events[1].topology_id.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
+    # assert events[1].topology_id.context_id.context_uuid.uuid == context_uuid
+    # assert events[1].topology_id.topology_uuid.uuid == topology_uuid
     # assert isinstance(events[2], DeviceEvent)
     # assert events[2].event.event_type == EventTypeEnum.EVENTTYPE_CREATE
-    # assert events[2].device_id.device_uuid.uuid == DEVICE_R1_UUID
+    # assert events[2].device_id.device_uuid.uuid == device_r1_uuid
     # assert isinstance(events[3], DeviceEvent)
     # assert events[3].event.event_type == EventTypeEnum.EVENTTYPE_CREATE
-    # assert events[3].device_id.device_uuid.uuid == DEVICE_R2_UUID
+    # assert events[3].device_id.device_uuid.uuid == device_r2_uuid
 
     # ----- Get when the object does not exist -------------------------------------------------------------------------
+    service_id = ServiceId(**SERVICE_R1_R2_ID)
+    context_uuid,service_uuid = service_get_uuid(service_id, allow_random=False)
     with pytest.raises(grpc.RpcError) as e:
-        context_client_grpc.GetService(ServiceId(**SERVICE_R1_R2_ID))
+        context_client.GetService(service_id)
     assert e.value.code() == grpc.StatusCode.NOT_FOUND
-    assert e.value.details() == 'Service({:s}) not found'.format(SERVICE_R1_R2_UUID)
+    MSG = 'Service({:s}/{:s}) not found; context_uuid generated was: {:s}; service_uuid generated was: {:s}'
+    assert e.value.details() == MSG.format(CONTEXT_NAME, SERVICE_R1_R2_NAME, context_uuid, service_uuid)
 
     # ----- List when the object does not exist ------------------------------------------------------------------------
-    response = context_client_grpc.GetContext(ContextId(**CONTEXT_ID))
+    response = context_client.GetContext(ContextId(**CONTEXT_ID))
     assert len(response.topology_ids) == 1
     assert len(response.service_ids) == 0
     assert len(response.slice_ids) == 0
 
-    response = context_client_grpc.ListServiceIds(ContextId(**CONTEXT_ID))
+    response = context_client.ListServiceIds(ContextId(**CONTEXT_ID))
     assert len(response.service_ids) == 0
 
-    response = context_client_grpc.ListServices(ContextId(**CONTEXT_ID))
+    response = context_client.ListServices(ContextId(**CONTEXT_ID))
     assert len(response.services) == 0
 
     # ----- Create the object ------------------------------------------------------------------------------------------
     with pytest.raises(grpc.RpcError) as e:
+        WRONG_UUID = 'ffffffff-ffff-ffff-ffff-ffffffffffff'
         WRONG_SERVICE = copy.deepcopy(SERVICE_R1_R2)
-        WRONG_SERVICE['service_endpoint_ids'][0]\
-            ['topology_id']['context_id']['context_uuid']['uuid'] = 'ca1ea172-728f-441d-972c-feeae8c9bffc'
-        context_client_grpc.SetService(Service(**WRONG_SERVICE))
+        WRONG_SERVICE['service_endpoint_ids'][0]['topology_id']['context_id']['context_uuid']['uuid'] = WRONG_UUID
+        context_client.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(ca1ea172-728f-441d-972c-feeae8c9bffc) is invalid; '\
-          'should be == request.service_id.context_id.context_uuid.uuid({:s})'.format(DEFAULT_CONTEXT_UUID)
-    assert e.value.details() == msg
+    MSG = 'request.service_endpoint_ids[0].topology_id.context_id.context_uuid.uuid({}) is invalid; '\
+          'should be == request.service_id.context_id.context_uuid.uuid({})'
+    raw_context_uuid = service_id.context_id.context_uuid.uuid # pylint: disable=no-member
+    assert e.value.details() == MSG.format(WRONG_UUID, raw_context_uuid)
 
-    response = context_client_grpc.SetService(Service(**SERVICE_R1_R2))
-    assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
-    assert response.service_uuid.uuid == SERVICE_R1_R2_UUID
+    response = context_client.SetService(Service(**SERVICE_R1_R2))
+    assert response.context_id.context_uuid.uuid == context_uuid
+    assert response.service_uuid.uuid == service_uuid
 
     # ----- Check create event -----------------------------------------------------------------------------------------
     #event = events_collector.get_event(block=True)
     #assert isinstance(event, ServiceEvent)
     #assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE
-    #assert event.service_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
-    #assert event.service_id.service_uuid.uuid == SERVICE_R1_R2_UUID
+    #assert event.service_id.context_id.context_uuid.uuid == context_uuid
+    #assert event.service_id.service_uuid.uuid == service_uuid
 
     # ----- Get when the object exists ---------------------------------------------------------------------------------
-    response = context_client_grpc.GetContext(ContextId(**CONTEXT_ID))
-    assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
-    assert response.name == ''
+    response = context_client.GetContext(ContextId(**CONTEXT_ID))
+    assert response.context_id.context_uuid.uuid == context_uuid
+    assert response.name == CONTEXT_NAME
     assert len(response.topology_ids) == 1
     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_R1_R2_UUID
+    assert response.service_ids[0].context_id.context_uuid.uuid == context_uuid
+    assert response.service_ids[0].service_uuid.uuid == service_uuid
     assert len(response.slice_ids) == 0
 
-    response = context_client_grpc.GetService(ServiceId(**SERVICE_R1_R2_ID))
-    assert response.service_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
-    assert response.service_id.service_uuid.uuid == SERVICE_R1_R2_UUID
-    assert response.name == ''
+    response = context_client.GetService(ServiceId(**SERVICE_R1_R2_ID))
+    assert response.service_id.context_id.context_uuid.uuid == context_uuid
+    assert response.service_id.service_uuid.uuid == service_uuid
+    assert response.name == SERVICE_R1_R2_NAME
     assert response.service_type == ServiceTypeEnum.SERVICETYPE_L3NM
     assert len(response.service_endpoint_ids) == 2
     assert len(response.service_constraints) == 2
@@ -122,106 +119,108 @@ def grpc_service(context_client_grpc : ContextClient) -> None:
     assert len(response.service_config.config_rules) == 3
 
     # ----- List when the object exists --------------------------------------------------------------------------------
-    response = context_client_grpc.ListServiceIds(ContextId(**CONTEXT_ID))
+    response = context_client.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_R1_R2_UUID
+    assert response.service_ids[0].context_id.context_uuid.uuid == context_uuid
+    assert response.service_ids[0].service_uuid.uuid == service_uuid
 
-    response = context_client_grpc.ListServices(ContextId(**CONTEXT_ID))
+    response = context_client.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_R1_R2_UUID
-    assert response.services[0].name == ''
-    assert response.service_type == ServiceTypeEnum.SERVICETYPE_L3NM
-    assert len(response.service_endpoint_ids) == 2
-    assert len(response.service_constraints) == 2
-    assert response.service_status.service_status == ServiceStatusEnum.SERVICESTATUS_PLANNED
-    assert len(response.service_config.config_rules) == 3
+    assert response.services[0].service_id.context_id.context_uuid.uuid == context_uuid
+    assert response.services[0].service_id.service_uuid.uuid == service_uuid
+    assert response.services[0].name == SERVICE_R1_R2_NAME
+    assert response.services[0].service_type == ServiceTypeEnum.SERVICETYPE_L3NM
+    assert len(response.services[0].service_endpoint_ids) == 2
+    assert len(response.services[0].service_constraints) == 2
+    assert response.services[0].service_status.service_status == ServiceStatusEnum.SERVICESTATUS_PLANNED
+    assert len(response.services[0].service_config.config_rules) == 3
 
     # ----- Update the object ------------------------------------------------------------------------------------------
-    new_service_name = 'svc:r1-r2'
+    new_service_name = 'new'
     SERVICE_UPDATED = copy.deepcopy(SERVICE_R1_R2)
     SERVICE_UPDATED['name'] = new_service_name
-    response = context_client_grpc.SetService(Service(**SERVICE_UPDATED))
-    assert response.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
-    assert response.service_uuid.uuid == SERVICE_R1_R2_UUID
+    SERVICE_UPDATED['service_status']['service_status'] = ServiceStatusEnum.SERVICESTATUS_ACTIVE
+    response = context_client.SetService(Service(**SERVICE_UPDATED))
+    assert response.context_id.context_uuid.uuid == context_uuid
+    assert response.service_uuid.uuid == service_uuid
 
     # ----- Check update event -----------------------------------------------------------------------------------------
     #event = events_collector.get_event(block=True)
     #assert isinstance(event, ServiceEvent)
     #assert event.event.event_type == EventTypeEnum.EVENTTYPE_UPDATE
-    #assert event.service_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
-    #assert event.service_id.service_uuid.uuid == SERVICE_R1_R2_UUID
+    #assert event.service_id.context_id.context_uuid.uuid == context_uuid
+    #assert event.service_id.service_uuid.uuid == service_uuid
 
     # ----- Get when the object is modified ----------------------------------------------------------------------------
-    response = context_client_grpc.GetService(ServiceId(**SERVICE_R1_R2_ID))
-    assert response.service_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
-    assert response.service_id.service_uuid.uuid == SERVICE_R1_R2_UUID
+    response = context_client.GetService(ServiceId(**SERVICE_R1_R2_ID))
+    assert response.service_id.context_id.context_uuid.uuid == context_uuid
+    assert response.service_id.service_uuid.uuid == service_uuid
     assert response.name == new_service_name
     assert response.service_type == ServiceTypeEnum.SERVICETYPE_L3NM
     assert len(response.service_endpoint_ids) == 2
     assert len(response.service_constraints) == 2
-    assert response.service_status.service_status == ServiceStatusEnum.SERVICESTATUS_PLANNED
+    assert response.service_status.service_status == ServiceStatusEnum.SERVICESTATUS_ACTIVE
     assert len(response.service_config.config_rules) == 3
 
     # ----- List when the object is modified ---------------------------------------------------------------------------
-    response = context_client_grpc.ListServiceIds(ContextId(**CONTEXT_ID))
+    response = context_client.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_R1_R2_UUID
+    assert response.service_ids[0].context_id.context_uuid.uuid == context_uuid
+    assert response.service_ids[0].service_uuid.uuid == service_uuid
 
-    response = context_client_grpc.ListServices(ContextId(**CONTEXT_ID))
+    response = context_client.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_R1_R2_UUID
+    assert response.services[0].service_id.context_id.context_uuid.uuid == context_uuid
+    assert response.services[0].service_id.service_uuid.uuid == service_uuid
     assert response.services[0].name == new_service_name
     assert response.services[0].service_type == ServiceTypeEnum.SERVICETYPE_L3NM
     assert len(response.services[0].service_endpoint_ids) == 2
     assert len(response.services[0].service_constraints) == 2
-    assert response.services[0].service_status.service_status == ServiceStatusEnum.SERVICESTATUS_PLANNED
+    assert response.services[0].service_status.service_status == ServiceStatusEnum.SERVICESTATUS_ACTIVE
     assert len(response.services[0].service_config.config_rules) == 3
 
     # ----- Remove the object ------------------------------------------------------------------------------------------
-    context_client_grpc.RemoveService(ServiceId(**SERVICE_R1_R2_ID))
+    context_client.RemoveService(ServiceId(**SERVICE_R1_R2_ID))
 
     # ----- Check remove event -----------------------------------------------------------------------------------------
     #event = events_collector.get_event(block=True)
     #assert isinstance(event, ServiceEvent)
-    #assert event.service_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
-    #assert event.service_id.service_uuid.uuid == SERVICE_R1_R2_UUID
+    #assert event.event.event_type == EventTypeEnum.EVENTTYPE_REMOVE
+    #assert event.service_id.context_id.context_uuid.uuid == context_uuid
+    #assert event.service_id.service_uuid.uuid == service_uuid
 
     # ----- List after deleting the object -----------------------------------------------------------------------------
-    response = context_client_grpc.GetContext(ContextId(**CONTEXT_ID))
+    response = context_client.GetContext(ContextId(**CONTEXT_ID))
     assert len(response.topology_ids) == 1
     assert len(response.service_ids) == 0
     assert len(response.slice_ids) == 0
 
-    response = context_client_grpc.ListServiceIds(ContextId(**CONTEXT_ID))
+    response = context_client.ListServiceIds(ContextId(**CONTEXT_ID))
     assert len(response.service_ids) == 0
 
-    response = context_client_grpc.ListServices(ContextId(**CONTEXT_ID))
+    response = context_client.ListServices(ContextId(**CONTEXT_ID))
     assert len(response.services) == 0
 
     # ----- Clean dependencies used in the test and capture related events ---------------------------------------------
-    context_client_grpc.RemoveDevice(DeviceId(**DEVICE_R1_ID))
-    context_client_grpc.RemoveDevice(DeviceId(**DEVICE_R2_ID))
-    context_client_grpc.RemoveTopology(TopologyId(**TOPOLOGY_ID))
-    context_client_grpc.RemoveContext(ContextId(**CONTEXT_ID))
+    context_client.RemoveDevice(DeviceId(**DEVICE_R1_ID))
+    context_client.RemoveDevice(DeviceId(**DEVICE_R2_ID))
+    context_client.RemoveTopology(TopologyId(**TOPOLOGY_ID))
+    context_client.RemoveContext(ContextId(**CONTEXT_ID))
 
     #events = events_collector.get_events(block=True, count=4)
     #assert isinstance(events[0], DeviceEvent)
     #assert events[0].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE
-    #assert events[0].device_id.device_uuid.uuid == DEVICE_R1_UUID
+    #assert events[0].device_id.device_uuid.uuid == device_r1_uuid
     #assert isinstance(events[1], DeviceEvent)
     #assert events[1].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE
-    #assert events[1].device_id.device_uuid.uuid == DEVICE_R2_UUID
+    #assert events[1].device_id.device_uuid.uuid == device_r2_uuid
     #assert isinstance(events[2], TopologyEvent)
     #assert events[2].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE
-    #assert events[2].topology_id.context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
-    #assert events[2].topology_id.topology_uuid.uuid == DEFAULT_TOPOLOGY_UUID
+    #assert events[2].topology_id.context_id.context_uuid.uuid == context_uuid
+    #assert events[2].topology_id.topology_uuid.uuid == topology_uuid
     #assert isinstance(events[3], ContextEvent)
     #assert events[3].event.event_type == EventTypeEnum.EVENTTYPE_REMOVE
-    #assert events[3].context_id.context_uuid.uuid == DEFAULT_CONTEXT_UUID
+    #assert events[3].context_id.context_uuid.uuid == context_uuid
 
     # ----- Stop the EventsCollector -----------------------------------------------------------------------------------
     #events_collector.stop()
diff --git a/src/context/tests/test_topology.py b/src/context/tests/test_topology.py
index 51b224007d7a60f4db6b4f015360e197dea4ec7f..23e73edc83e7f1cb16370c4325f93be277d3298a 100644
--- a/src/context/tests/test_topology.py
+++ b/src/context/tests/test_topology.py
@@ -31,8 +31,7 @@ def test_topology(context_client : ContextClient) -> None:
     #events_collector.start()
 
     # ----- Prepare dependencies for the test and capture related events -----------------------------------------------
-    response = context_client.SetContext(Context(**CONTEXT))
-    context_uuid = response.context_uuid.uuid
+    context_client.SetContext(Context(**CONTEXT))
 
     # event = events_collector.get_event(block=True)
     # assert isinstance(event, ContextEvent)
diff --git a/test-context.sh b/test-context.sh
index 79a9d5653621db615030a09e5b362438bfae637e..47d81817bd80bd771fa647449a6c49bcfaee9870 100755
--- a/test-context.sh
+++ b/test-context.sh
@@ -41,11 +41,12 @@ export PYTHONPATH=/home/tfs/tfs-ctrl/src
 # Run unitary tests and analyze coverage of code at same time
 # helpful pytest flags: --log-level=INFO -o log_cli=true --verbose --maxfail=1 --durations=0
 coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose --maxfail=1 \
-    context/tests/test_hasher.py \
-    context/tests/test_context.py \
+    context/tests/test_hasher.py   \
+    context/tests/test_context.py  \
     context/tests/test_topology.py \
-    context/tests/test_device.py \
-    context/tests/test_link.py
+    context/tests/test_device.py   \
+    context/tests/test_link.py     \
+    context/tests/test_service.py
 
 echo
 echo "Coverage report:"