diff --git a/src/context/service/Database.py b/src/context/service/Database.py
index 8fae9f652eab73f577bd383def6d88bbd19418ed..bf970b356a61df10474d024554839b94b57cc610 100644
--- a/src/context/service/Database.py
+++ b/src/context/service/Database.py
@@ -1,7 +1,7 @@
 from typing import Tuple, List
 
 from sqlalchemy import MetaData
-from sqlalchemy.orm import Session
+from sqlalchemy.orm import Session, joinedload
 from context.service.database.Base import Base
 import logging
 from common.orm.backend.Tools import key_to_str
@@ -27,8 +27,11 @@ class Database(Session):
     def create_or_update(self, model):
         with self.session() as session:
             att = getattr(model, model.main_pk_name())
+            obj = self.get_object(type(model), att)
+
             filt = {model.main_pk_name(): att}
-            found = session.query(type(model)).filter_by(**filt).one_or_none()
+            t_model = type(model)
+            found = session.query(t_model).filter_by(**filt).one_or_none()
             if found:
                 found = True
             else:
@@ -36,6 +39,9 @@ class Database(Session):
 
             session.merge(model)
             session.commit()
+
+            obj = self.get_object(t_model, att)
+
         return model, found
 
     def create(self, model):
@@ -93,11 +99,11 @@ class Database(Session):
                     raise NotFoundException(model_class.__name__.replace('Model', ''), main_key)
 
             return get
-    def get_or_create(self, model_class: Base, key_parts: List[str]
-                      ) -> Tuple[Base, bool]:
 
+    def get_or_create(self, model_class: Base, key_parts: List[str], filt=None) -> Tuple[Base, bool]:
         str_key = key_to_str(key_parts)
-        filt = {model_class.main_pk_name(): key_parts}
+        if not filt:
+            filt = {model_class.main_pk_name(): key_parts}
         with self.session() as session:
             get = session.query(model_class).filter_by(**filt).one_or_none()
             if get:
@@ -105,7 +111,6 @@ class Database(Session):
             else:
                 obj = model_class()
                 setattr(obj, model_class.main_pk_name(), str_key)
-                LOGGER.info(obj.dump())
                 session.add(obj)
                 session.commit()
                 return obj, True
diff --git a/src/context/service/database/ConfigModel.py b/src/context/service/database/ConfigModel.py
index 4dcd50c2cc6d010af1f2a745ad4e22c96eb226ed..40069185fc2c7ce43d584fe8b1b0704a22d88e84 100644
--- a/src/context/service/database/ConfigModel.py
+++ b/src/context/service/database/ConfigModel.py
@@ -40,7 +40,7 @@ class ConfigModel(Base): # pylint: disable=abstract-method
     config_uuid = Column(UUID(as_uuid=False), primary_key=True)
 
     # Relationships
-    config_rule = relationship("ConfigRuleModel", back_populates="config", lazy="dynamic")
+    config_rule = relationship("ConfigRuleModel", back_populates="config", lazy='joined')
 
 
     def delete(self) -> None:
@@ -48,7 +48,7 @@ class ConfigModel(Base): # pylint: disable=abstract-method
         for pk,_ in db_config_rule_pks: ConfigRuleModel(self.database, pk).delete()
         super().delete()
 
-    def dump(self): # -> List[Dict]:
+    def dump(self) -> List[Dict]:
         config_rules = []
         for a in self.config_rule:
             asdf = a.dump()
@@ -62,7 +62,7 @@ class ConfigModel(Base): # pylint: disable=abstract-method
 class ConfigRuleModel(Base): # pylint: disable=abstract-method
     __tablename__ = 'ConfigRule'
     config_rule_uuid = Column(UUID(as_uuid=False), primary_key=True)
-    config_uuid = Column(UUID(as_uuid=False), ForeignKey("Config.config_uuid"), primary_key=True)
+    config_uuid = Column(UUID(as_uuid=False), ForeignKey("Config.config_uuid", ondelete='CASCADE'), primary_key=True)
 
     action = Column(Enum(ORM_ConfigActionEnum, create_constraint=True, native_enum=True), nullable=False)
     position = Column(INTEGER, nullable=False)
diff --git a/src/context/service/database/ContextModel.py b/src/context/service/database/ContextModel.py
index ef1d485bed9937929160ca700d08ed191bc8e7b1..cde774fe49430bf9d4c347533747315562dcdccc 100644
--- a/src/context/service/database/ContextModel.py
+++ b/src/context/service/database/ContextModel.py
@@ -33,7 +33,8 @@ class ContextModel(Base):
     def dump_id(self) -> Dict:
         return {'context_uuid': {'uuid': self.context_uuid}}
 
-    def main_pk_name(self):
+    @staticmethod
+    def main_pk_name():
         return 'context_uuid'
 
     """    
diff --git a/src/context/service/database/DeviceModel.py b/src/context/service/database/DeviceModel.py
index bf8f73c79a6c595eb427e108e0ca610e1f966f76..122da50afbad1f894b03d9caeac8c096ed822cac 100644
--- a/src/context/service/database/DeviceModel.py
+++ b/src/context/service/database/DeviceModel.py
@@ -49,14 +49,16 @@ class DeviceModel(Base):
     __tablename__ = 'Device'
     device_uuid = Column(UUID(as_uuid=False), primary_key=True)
     device_type = Column(String)
-    device_config_uuid = Column(UUID(as_uuid=False), ForeignKey("Config.config_uuid"))
+    device_config_uuid = Column(UUID(as_uuid=False), ForeignKey("Config.config_uuid", ondelete='CASCADE'))
     device_operational_status = Column(Enum(ORM_DeviceOperationalStatusEnum, create_constraint=False,
                                             native_enum=False))
 
     # Relationships
-    device_config = relationship("ConfigModel", lazy="joined")
-    driver = relationship("DriverModel", lazy="joined")
-    endpoints = relationship("EndPointModel", lazy="joined")
+    device_config = relationship("ConfigModel", passive_deletes="all, delete", lazy="joined")
+    driver = relationship("DriverModel", passive_deletes=True, back_populates="device")
+    endpoints = relationship("EndPointModel", passive_deletes=True, back_populates="device")
+
+    # topology = relationship("TopologyModel", lazy="joined")
 
     # def delete(self) -> None:
     #     # pylint: disable=import-outside-toplevel
@@ -83,13 +85,25 @@ class DeviceModel(Base):
         return self.device_config.dump()
 
     def dump_drivers(self) -> List[int]:
-        return self.driver.dump()
+        response = []
+
+        for a in self.driver:
+            LOGGER.info('DUMPPPPPPPPPPPPPPPPPPPPPIIIIIIIIIIIIIIIIIIIIIIINNNNNNNNNNNNNNNGGGGGGGGGGGGGGGGGGg')
+            LOGGER.info('aasdfadsf: {}'.format(a.dump()))
+            response.append(a.dump())
+
+        return response
 
     def dump_endpoints(self) -> List[Dict]:
-        return self.endpoints.dump()
+        response = []
+
+        for a in self.endpoints:
+            response.append(a.dump())
+
+        return response
 
     def dump(   # pylint: disable=arguments-differ
-            self, include_config_rules=True, include_drivers=False, include_endpoints=False
+            self, include_config_rules=True, include_drivers=True, include_endpoints=True
         ) -> Dict:
         result = {
             'device_id': self.dump_id(),
@@ -101,24 +115,26 @@ class DeviceModel(Base):
         if include_endpoints: result['device_endpoints'] = self.dump_endpoints()
         return result
 
-    def main_pk_name(self):
+    @staticmethod
+    def main_pk_name():
         return 'device_uuid'
 
 class DriverModel(Base): # pylint: disable=abstract-method
     __tablename__ = 'Driver'
-    driver_uuid = Column(UUID(as_uuid=False), primary_key=True)
-    device_uuid = Column(UUID(as_uuid=False), ForeignKey("Device.device_uuid"), primary_key=True)
+    # driver_uuid = Column(UUID(as_uuid=False), primary_key=True)
+    device_uuid = Column(UUID(as_uuid=False), ForeignKey("Device.device_uuid", ondelete='CASCADE'), primary_key=True)
     driver = Column(Enum(ORM_DeviceDriverEnum, create_constraint=False, native_enum=False))
 
     # Relationships
-    device = relationship("DeviceModel")
+    device = relationship("DeviceModel", back_populates="driver")
 
 
     def dump(self) -> Dict:
         return self.driver.value
 
-    def main_pk_name(self):
-        return 'driver_uuid'
+    @staticmethod
+    def main_pk_name():
+        return 'device_uuid'
 
 def set_drivers(database : Database, db_device : DeviceModel, grpc_device_drivers):
     db_device_pk = db_device.device_uuid
diff --git a/src/context/service/database/EndPointModel.py b/src/context/service/database/EndPointModel.py
index 669b590e3a8e2b56d8b8efcdf8deb9e99ead23ab..a4381a2e307127dacfb27136c67ab5baa7f2101b 100644
--- a/src/context/service/database/EndPointModel.py
+++ b/src/context/service/database/EndPointModel.py
@@ -27,14 +27,17 @@ LOGGER = logging.getLogger(__name__)
 
 class EndPointModel(Base):
     __tablename__ = 'EndPoint'
-    endpoint_uuid = Column(UUID(as_uuid=False), primary_key=True, unique=True)
     topology_uuid = Column(UUID(as_uuid=False), ForeignKey("Topology.topology_uuid"), primary_key=True)
-    device_uuid = Column(UUID(as_uuid=False), ForeignKey("Device.device_uuid"), primary_key=True)
+    device_uuid = Column(UUID(as_uuid=False), ForeignKey("Device.device_uuid", ondelete='CASCADE'), primary_key=True)
+    endpoint_uuid = Column(UUID(as_uuid=False), primary_key=True, unique=True)
     endpoint_type = Column(String)
 
     # Relationships
+    kpi_sample_types = relationship("KpiSampleTypeModel", passive_deletes=True, back_populates="EndPoint")
+    device = relationship("DeviceModel", back_populates="endpoints")
 
-    def main_pk_name(self):
+    @staticmethod
+    def main_pk_name():
         return 'endpoint_uuid'
 
     def delete(self) -> None:
@@ -44,32 +47,41 @@ class EndPointModel(Base):
 
     def dump_id(self) -> Dict:
         result = {
-            'device_uuid': self.device_uuid,
+            'device_id': self.device.dump_id(),
             'endpoint_uuid': {'uuid': self.endpoint_uuid},
         }
         return result
 
     def dump_kpi_sample_types(self) -> List[int]:
-        db_kpi_sample_type_pks = self.references(KpiSampleTypeModel)
-        return [KpiSampleTypeModel(self.database, pk).dump() for pk,_ in db_kpi_sample_type_pks]
+        # db_kpi_sample_type_pks = self.references(KpiSampleTypeModel)
+        # return [KpiSampleTypeModel(self.database, pk).dump() for pk,_ in db_kpi_sample_type_pks]
+        response = []
+        for a in self.kpi_sample_types:
+            response.append(a.dump())
+        return response
 
     def dump(   # pylint: disable=arguments-differ
             self, include_kpi_sample_types=True
         ) -> Dict:
         result = {
-            'endpoint_uuid': self.dump_id(),
+            'endpoint_id': self.dump_id(),
             'endpoint_type': self.endpoint_type,
         }
         if include_kpi_sample_types: result['kpi_sample_types'] = self.dump_kpi_sample_types()
         return result
 
+
 class KpiSampleTypeModel(Base): # pylint: disable=abstract-method
     __tablename__ = 'KpiSampleType'
     kpi_uuid = Column(UUID(as_uuid=False), primary_key=True)
-    endpoint_uuid = Column(UUID(as_uuid=False), ForeignKey("EndPoint.endpoint_uuid"))
+    endpoint_uuid = Column(UUID(as_uuid=False), ForeignKey("EndPoint.endpoint_uuid",  ondelete='CASCADE'))
     kpi_sample_type = Column(Enum(ORM_KpiSampleTypeEnum, create_constraint=False,
                                                   native_enum=False))
     # __table_args__ = (ForeignKeyConstraint([endpoint_uuid], [EndPointModel.endpoint_uuid]), {})
+
+    # Relationships
+    EndPoint = relationship("EndPointModel", passive_deletes=True, back_populates="kpi_sample_types")
+
     def dump(self) -> Dict:
         return self.kpi_sample_type.value
 
diff --git a/src/context/service/grpc_server/ContextServiceServicerImpl.py b/src/context/service/grpc_server/ContextServiceServicerImpl.py
index d104d556772f8691ea001673d1b7133ce7161282..108ab9950e494cc5069de3140c4a5ed29c731161 100644
--- a/src/context/service/grpc_server/ContextServiceServicerImpl.py
+++ b/src/context/service/grpc_server/ContextServiceServicerImpl.py
@@ -46,7 +46,6 @@ from context.service.database.ConnectionModel import ConnectionModel, set_path
 from context.service.database.ConstraintModel import set_constraints
 from context.service.database.EndPointModel import EndPointModel, set_kpi_sample_types
 from context.service.database.Events import notify_event
-from context.service.database.LinkModel import LinkModel
 from context.service.database.RelationModels import (
     ConnectionSubServiceModel, LinkEndPointModel, ServiceEndPointModel, SliceEndPointModel, SliceServiceModel,
     SliceSubSliceModel, TopologyDeviceModel, TopologyLinkModel)
@@ -60,6 +59,7 @@ from context.service.database.TopologyModel import TopologyModel
 from context.service.database.Events import notify_event
 from context.service.database.EndPointModel import EndPointModel
 from context.service.database.EndPointModel import KpiSampleTypeModel
+from context.service.database.LinkModel import LinkModel
 
 from .Constants import (
     CONSUME_TIMEOUT, TOPIC_CONNECTION, TOPIC_CONTEXT, TOPIC_DEVICE, TOPIC_LINK, TOPIC_SERVICE, TOPIC_SLICE,
@@ -268,7 +268,7 @@ class ContextServiceServicerImpl(ContextServiceServicer):
     def ListDevices(self, request: Empty, context : grpc.ServicerContext) -> DeviceList:
         with self.session() as session:
             result = session.query(DeviceModel).all()
-            return DeviceList(devices=[device.dump_id() for device in result])
+            return DeviceList(devices=[device.dump() for device in result])
 
     @safe_and_metered_rpc_method(METRICS, LOGGER)
     def GetDevice(self, request: DeviceId, context : grpc.ServicerContext) -> Device:
@@ -278,72 +278,76 @@ class ContextServiceServicerImpl(ContextServiceServicer):
             if not result:
                 raise NotFoundException(DeviceModel.__name__.replace('Model', ''), device_uuid)
 
-            rd = result.dump()
+            rd = result.dump(include_config_rules=True, include_drivers=True, include_endpoints=True)
+
             rt = Device(**rd)
 
             return rt
 
     @safe_and_metered_rpc_method(METRICS, LOGGER)
     def SetDevice(self, request: Device, context : grpc.ServicerContext) -> DeviceId:
-        device_uuid = request.device_id.device_uuid.uuid
+        with self.session() as session:
+            device_uuid = request.device_id.device_uuid.uuid
 
-        for i,endpoint in enumerate(request.device_endpoints):
-            endpoint_device_uuid = endpoint.endpoint_id.device_id.device_uuid.uuid
-            if len(endpoint_device_uuid) == 0: endpoint_device_uuid = device_uuid
-            if device_uuid != endpoint_device_uuid:
-                raise InvalidArgumentException(
-                    'request.device_endpoints[{:d}].device_id.device_uuid.uuid'.format(i), endpoint_device_uuid,
-                    ['should be == {:s}({:s})'.format('request.device_id.device_uuid.uuid', device_uuid)])
-
-        config_rules = grpc_config_rules_to_raw(request.device_config.config_rules)
-        running_config_result = self.update_config(device_uuid, 'running', config_rules)
-        db_running_config = running_config_result[0][0]
-        config_uuid = db_running_config.config_uuid
-
-        new_obj = DeviceModel(**{
-            'device_uuid'               : device_uuid,
-            'device_type'               : request.device_type,
-            'device_operational_status' : grpc_to_enum__device_operational_status(request.device_operational_status),
-            'device_config_uuid'        : config_uuid,
-        })
-        result: Tuple[DeviceModel, bool] = self.database.create_or_update(new_obj)
-        db_device, updated = result
+            for i,endpoint in enumerate(request.device_endpoints):
+                endpoint_device_uuid = endpoint.endpoint_id.device_id.device_uuid.uuid
+                if len(endpoint_device_uuid) == 0: endpoint_device_uuid = device_uuid
+                if device_uuid != endpoint_device_uuid:
+                    raise InvalidArgumentException(
+                        'request.device_endpoints[{:d}].device_id.device_uuid.uuid'.format(i), endpoint_device_uuid,
+                        ['should be == {:s}({:s})'.format('request.device_id.device_uuid.uuid', device_uuid)])
 
-        self.set_drivers(db_device, request.device_drivers)
+            config_rules = grpc_config_rules_to_raw(request.device_config.config_rules)
+            running_config_result = self.update_config(session, device_uuid, 'running', config_rules)
+            db_running_config = running_config_result[0][0]
+            config_uuid = db_running_config.config_uuid
 
-        for i,endpoint in enumerate(request.device_endpoints):
-            endpoint_uuid = endpoint.endpoint_id.endpoint_uuid.uuid
-            endpoint_device_uuid = endpoint.endpoint_id.device_id.device_uuid.uuid
-            if len(endpoint_device_uuid) == 0: endpoint_device_uuid = device_uuid
+            new_obj = DeviceModel(**{
+                'device_uuid'               : device_uuid,
+                'device_type'               : request.device_type,
+                'device_operational_status' : grpc_to_enum__device_operational_status(request.device_operational_status),
+                'device_config_uuid'        : config_uuid,
+            })
+            result: Tuple[DeviceModel, bool] = self.database.create_or_update(new_obj)
+            db_device, updated = result
 
-            str_endpoint_key = key_to_str([device_uuid, endpoint_uuid])
-            endpoint_attributes = {
-                'device_uuid'    : db_device.device_uuid,
-                'endpoint_uuid': endpoint_uuid,
-                'endpoint_type': endpoint.endpoint_type,
-            }
+            self.set_drivers(db_device, request.device_drivers)
 
-            endpoint_topology_context_uuid = endpoint.endpoint_id.topology_id.context_id.context_uuid.uuid
-            endpoint_topology_uuid = endpoint.endpoint_id.topology_id.topology_uuid.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])
+            for i,endpoint in enumerate(request.device_endpoints):
+                endpoint_uuid = endpoint.endpoint_id.endpoint_uuid.uuid
+                endpoint_device_uuid = endpoint.endpoint_id.device_id.device_uuid.uuid
+                if len(endpoint_device_uuid) == 0: endpoint_device_uuid = device_uuid
+
+                str_endpoint_key = key_to_str([device_uuid, endpoint_uuid])
+                endpoint_attributes = {
+                    'device_uuid'  : db_device.device_uuid,
+                    'endpoint_uuid': endpoint_uuid,
+                    'endpoint_type': endpoint.endpoint_type,
+                }
+
+                endpoint_topology_context_uuid = endpoint.endpoint_id.topology_id.context_id.context_uuid.uuid
+                endpoint_topology_uuid = endpoint.endpoint_id.topology_id.topology_uuid.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])
 
-                db_topology : TopologyModel = self.database.get_object(TopologyModel, endpoint_topology_uuid)
+                    db_topology: TopologyModel = self.database.get_object(TopologyModel, endpoint_topology_uuid)
+                    new_topo = TopologyModel(context_uuid=db_topology.context_uuid, topology_uuid=db_topology.topology_uuid, device_uuids=db_device.device_uuid)
 
-                str_endpoint_key = key_to_str([str_endpoint_key, str_topology_key], separator=':')
-                endpoint_attributes['topology_uuid'] = db_topology.topology_uuid
+                    self.database.create_or_update(new_topo)
 
-            new_endpoint = EndPointModel(**endpoint_attributes)
-            result : Tuple[EndPointModel, bool] = self.database.create_or_update(new_endpoint)
-            db_endpoint, updated = result
+                    endpoint_attributes['topology_uuid'] = db_topology.topology_uuid
 
-            self.set_kpi_sample_types(db_endpoint, endpoint.kpi_sample_types)
+                new_endpoint = EndPointModel(**endpoint_attributes)
+                result : Tuple[EndPointModel, bool] = self.database.create_or_update(new_endpoint)
+                db_endpoint, updated = result
 
-        # event_type = EventTypeEnum.EVENTTYPE_UPDATE if updated else EventTypeEnum.EVENTTYPE_CREATE
-        dict_device_id = db_device.dump_id()
-        # notify_event(self.messagebroker, TOPIC_DEVICE, event_type, {'device_id': dict_device_id})
+                self.set_kpi_sample_types(db_endpoint, endpoint.kpi_sample_types)
 
-        return DeviceId(**dict_device_id)
+            # event_type = EventTypeEnum.EVENTTYPE_UPDATE if updated else EventTypeEnum.EVENTTYPE_CREATE
+            dict_device_id = db_device.dump_id()
+            # notify_event(self.messagebroker, TOPIC_DEVICE, event_type, {'device_id': dict_device_id})
+
+            return DeviceId(**dict_device_id)
 
     def set_kpi_sample_types(self, db_endpoint: EndPointModel, grpc_endpoint_kpi_sample_types):
         db_endpoint_pk = db_endpoint.endpoint_uuid
@@ -362,7 +366,7 @@ class ContextServiceServicerImpl(ContextServiceServicer):
             orm_driver = grpc_to_enum__device_driver(driver)
             str_device_driver_key = key_to_str([db_device_pk, orm_driver.name])
             driver_config = {
-                "driver_uuid": str(uuid.uuid4()),
+                # "driver_uuid": str(uuid.uuid4()),
                 "device_uuid": db_device_pk,
                 "driver": orm_driver.name
             }
@@ -373,13 +377,19 @@ class ContextServiceServicerImpl(ContextServiceServicer):
             self.database.create_or_update(db_device_driver)
 
     def update_config(
-            self, db_parent_pk: str, config_name: str,
+            self, session, db_parent_pk: str, config_name: str,
             raw_config_rules: List[Tuple[ORM_ConfigActionEnum, str, str]]
     ) -> List[Tuple[Union[ConfigModel, ConfigRuleModel], bool]]:
 
-        str_config_key = key_to_str([db_parent_pk, config_name], separator=':')
-        result = self.database.get_or_create(ConfigModel, db_parent_pk)
-        db_config, created = result
+        created = False
+
+        db_config = session.query(ConfigModel).filter_by(**{ConfigModel.main_pk_name(): db_parent_pk}).one_or_none()
+        if not db_config:
+            db_config = ConfigModel()
+            setattr(db_config, ConfigModel.main_pk_name(), db_parent_pk)
+            session.add(db_config)
+            session.commit()
+            created = True
 
         LOGGER.info('UPDATED-CONFIG: {}'.format(db_config.dump()))
 
@@ -452,15 +462,16 @@ class ContextServiceServicerImpl(ContextServiceServicer):
 
     @safe_and_metered_rpc_method(METRICS, LOGGER)
     def RemoveDevice(self, request: DeviceId, context : grpc.ServicerContext) -> Empty:
-        with self.lock:
-            device_uuid = request.device_uuid.uuid
-            db_device = DeviceModel(self.database, device_uuid, auto_load=False)
-            found = db_device.load()
-            if not found: return Empty()
+        device_uuid = request.device_uuid.uuid
 
-            dict_device_id = db_device.dump_id()
-            db_device.delete()
+        with self.session() as session:
+            result = session.query(DeviceModel).filter_by(device_uuid=device_uuid).one_or_none()
+            if not result:
+                return Empty()
+            dict_device_id = result.dump_id()
 
+            session.query(DeviceModel).filter_by(device_uuid=device_uuid).delete()
+            session.commit()
             event_type = EventTypeEnum.EVENTTYPE_REMOVE
             notify_event(self.messagebroker, TOPIC_DEVICE, event_type, {'device_id': dict_device_id})
             return Empty()
@@ -472,75 +483,86 @@ class ContextServiceServicerImpl(ContextServiceServicer):
 
 
 
-    """
 
     # ----- Link -------------------------------------------------------------------------------------------------------
 
     @safe_and_metered_rpc_method(METRICS, LOGGER)
     def ListLinkIds(self, request: Empty, context : grpc.ServicerContext) -> LinkIdList:
-        with self.lock:
-            db_links : List[LinkModel] = get_all_objects(self.database, LinkModel)
-            db_links = sorted(db_links, key=operator.attrgetter('pk'))
-            return LinkIdList(link_ids=[db_link.dump_id() for db_link in db_links])
+        with self.session() as session:
+            result = session.query(LinkModel).all()
+            return LinkIdList(link_ids=[db_link.dump_id() for db_link in result])
+
 
     @safe_and_metered_rpc_method(METRICS, LOGGER)
     def ListLinks(self, request: Empty, context : grpc.ServicerContext) -> LinkList:
-        with self.lock:
-            db_links : List[LinkModel] = get_all_objects(self.database, LinkModel)
-            db_links = sorted(db_links, key=operator.attrgetter('pk'))
-            return LinkList(links=[db_link.dump() for db_link in db_links])
+        with self.session() as session:
+            result = session.query(DeviceModel).all()
+            return LinkList(links=[db_link.dump() for db_link in result])
 
     @safe_and_metered_rpc_method(METRICS, LOGGER)
     def GetLink(self, request: LinkId, context : grpc.ServicerContext) -> Link:
-        with self.lock:
-            link_uuid = request.link_uuid.uuid
-            db_link : LinkModel = get_object(self.database, LinkModel, link_uuid)
-            return Link(**db_link.dump())
+        link_uuid = request.link_uuid.uuid
+        with self.session() as session:
+            result = session.query(LinkModel).filter(LinkModel.device_uuid == link_uuid).one_or_none()
+            if not result:
+                raise NotFoundException(DeviceModel.__name__.replace('Model', ''), link_uuid)
 
-    @safe_and_metered_rpc_method(METRICS, LOGGER)
-    def SetLink(self, request: Link, context : grpc.ServicerContext) -> LinkId:
-        with self.lock:
-            link_uuid = request.link_id.link_uuid.uuid
-            result : Tuple[LinkModel, bool] = update_or_create_object(
-                self.database, LinkModel, link_uuid, {'link_uuid': link_uuid})
-            db_link, updated = result
+            rd = result.dump()
 
-            for endpoint_id in request.link_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
+            rt = Link(**rd)
 
-                str_endpoint_key = key_to_str([endpoint_device_uuid, endpoint_uuid])
+            return rt
 
-                db_topology = None
-                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])
-                    db_topology : TopologyModel = get_object(self.database, TopologyModel, str_topology_key)
-                    str_topology_device_key = key_to_str([str_topology_key, endpoint_device_uuid], separator='--')
-                    # check device is in topology
-                    get_object(self.database, TopologyDeviceModel, str_topology_device_key)
-                    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_link_endpoint_key = key_to_str([link_uuid, endpoint_device_uuid], separator='--')
-                result : Tuple[LinkEndPointModel, bool] = get_or_create_object(
-                    self.database, LinkEndPointModel, str_link_endpoint_key, {
-                        'link_fk': db_link, 'endpoint_fk': db_endpoint})
-                #db_link_endpoint, link_endpoint_created = result
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def SetLink(self, request: Link, context : grpc.ServicerContext) -> LinkId:
+        link_uuid = request.link_id.link_uuid.uuid
 
-                if db_topology is not None:
-                    str_topology_link_key = key_to_str([str_topology_key, link_uuid], separator='--')
-                    result : Tuple[TopologyLinkModel, bool] = get_or_create_object(
-                        self.database, TopologyLinkModel, str_topology_link_key, {
-                            'topology_fk': db_topology, 'link_fk': db_link})
-                    #db_topology_link, topology_link_created = result
+        new_link = LinkModel(**{
+            'lin_uuid': link_uuid
+        })
+        result: Tuple[LinkModel, bool] = self.database.create_or_update(new_link)
+        db_link, updated = result
 
-            event_type = EventTypeEnum.EVENTTYPE_UPDATE if updated else EventTypeEnum.EVENTTYPE_CREATE
-            dict_link_id = db_link.dump_id()
-            notify_event(self.messagebroker, TOPIC_LINK, event_type, {'link_id': dict_link_id})
-            return LinkId(**dict_link_id)
+        for endpoint_id in request.link_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])
+                # db_topology : TopologyModel = get_object(self.database, TopologyModel, str_topology_key)
+                db_topology : TopologyModel = self.database.get_object(TopologyModel, str_topology_key)
+                str_topology_device_key = key_to_str([str_topology_key, endpoint_device_uuid], separator='--')
+                # check device is in topology
+                # get_object(self.database, TopologyDeviceModel, str_topology_device_key)
+                # str_endpoint_key = key_to_str([str_endpoint_key, str_topology_key], separator=':')
+
+            # db_endpoint : EndPointModel = get_object(self.database, EndPointModel, str_endpoint_key)
+            LOGGER.info('str_endpoint_key: {}'.format(str_endpoint_key))
+            db_endpoint: EndPointModel = self.database.get_object(EndPointModel, str_endpoint_key)
+
+            # str_link_endpoint_key = key_to_str([link_uuid, endpoint_device_uuid], separator='--')
+            # result : Tuple[LinkEndPointModel, bool] = get_or_create_object(
+            #     self.database, LinkEndPointModel, str_link_endpoint_key, {
+            #         'link_fk': db_link, 'endpoint_fk': db_endpoint})
+            #db_link_endpoint, link_endpoint_created = result
+
+            # if db_topology is not None:
+            #     str_topology_link_key = key_to_str([str_topology_key, link_uuid], separator='--')
+            #     result : Tuple[TopologyLinkModel, bool] = get_or_create_object(
+            #         self.database, TopologyLinkModel, str_topology_link_key, {
+            #             'topology_fk': db_topology, 'link_fk': db_link})
+            #     #db_topology_link, topology_link_created = result
+
+        event_type = EventTypeEnum.EVENTTYPE_UPDATE if updated else EventTypeEnum.EVENTTYPE_CREATE
+        dict_link_id = db_link.dump_id()
+        notify_event(self.messagebroker, TOPIC_LINK, event_type, {'link_id': dict_link_id})
+        return LinkId(**dict_link_id)
 
     @safe_and_metered_rpc_method(METRICS, LOGGER)
     def RemoveLink(self, request: LinkId, context : grpc.ServicerContext) -> Empty:
@@ -562,6 +584,7 @@ class ContextServiceServicerImpl(ContextServiceServicer):
         for message in self.messagebroker.consume({TOPIC_LINK}, consume_timeout=CONSUME_TIMEOUT):
             yield LinkEvent(**json.loads(message.content))
 
+    """
 
     # ----- Service ----------------------------------------------------------------------------------------------------