diff --git a/src/interdomain/service/topology_abstractor/AbstractDevice.py b/src/interdomain/service/topology_abstractor/AbstractDevice.py
index c3b1b89eee18a47cd61f075e2421d37eaddbf7ad..2e62f6215f0da174ef72ad22163d502d3c3ab106 100644
--- a/src/interdomain/service/topology_abstractor/AbstractDevice.py
+++ b/src/interdomain/service/topology_abstractor/AbstractDevice.py
@@ -14,13 +14,14 @@
 
 import copy, logging
 from typing import Dict, Optional
-from common.Constants import DEFAULT_CONTEXT_NAME, INTERDOMAIN_TOPOLOGY_NAME
+from common.Constants import DEFAULT_CONTEXT_NAME, DEFAULT_TOPOLOGY_NAME, INTERDOMAIN_TOPOLOGY_NAME
 from common.DeviceTypes import DeviceTypeEnum
-from common.proto.context_pb2 import Device, DeviceDriverEnum, DeviceOperationalStatusEnum, EndPoint
+from common.proto.context_pb2 import ContextId, Device, DeviceDriverEnum, DeviceOperationalStatusEnum, EndPoint
 from common.tools.context_queries.CheckType import (
     device_type_is_datacenter, device_type_is_network, endpoint_type_is_border)
-from common.tools.context_queries.Device import get_device
+from common.tools.context_queries.Device import add_device_to_topology, get_device
 from common.tools.grpc.Tools import grpc_message_to_json
+from common.tools.object_factory.Context import json_context_id
 from common.tools.object_factory.Device import json_device
 from context.client.ContextClient import ContextClient
 from .Tools import replace_device_uuids_by_names
@@ -55,7 +56,13 @@ class AbstractDevice:
             'device_name' : self.__device_name,
             'device_type' : self.__device_type,
             'device' : grpc_message_to_json(self.__device),
-            'device_endpoint_to_abstract' : self.__device_endpoint_to_abstract,
+            'device_endpoint_to_abstract' : {
+                device_name : {
+                    endpoint_name : grpc_message_to_json(endpoint)
+                    for endpoint_name, endpoint in endpoints.items()
+                }
+                for device_name, endpoints in self.__device_endpoint_to_abstract.items()
+            },
             'abstract_endpoint_to_device' : self.__abstract_endpoint_to_device,
         }
 
@@ -81,16 +88,13 @@ class AbstractDevice:
         else:
             self._load_existing(local_interdomain_device)
 
-        #is_datacenter = device_type_is_datacenter(self.__device_type)
-        #is_network = device_type_is_network(self.__device_type)
-        #if is_datacenter or is_network:
-        #    # Add abstract device to topologies [INTERDOMAIN_TOPOLOGY_NAME]
-        #    admin_context_id = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME))
-        #    topology_uuids = [INTERDOMAIN_TOPOLOGY_NAME]
-        #    for topology_uuid in topology_uuids:
-        #        # This action is done automatically; commented out by now.
-        #        add_device_to_topology(
-        #            self.__context_client, admin_context_id, topology_uuid, self.__device_name)
+        is_datacenter = device_type_is_datacenter(self.__device_type)
+        is_network = device_type_is_network(self.__device_type)
+        if is_datacenter or is_network:
+            # Add abstract device to INTERDOMAIN_TOPOLOGY_NAME topology
+            admin_context_id = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME))
+            topology_name = INTERDOMAIN_TOPOLOGY_NAME
+            add_device_to_topology(self.__context_client, admin_context_id, topology_name, self.__device_name)
 
         # seems not needed; to be removed in future releases
         #if is_datacenter and create_abstract_device:
@@ -164,7 +168,7 @@ class AbstractDevice:
 
     def _add_endpoint(self, device_name : str, endpoint_name : str, endpoint_type : str) -> EndPoint:
         interdomain_endpoint = self.__device.device_endpoints.add()
-        interdomain_endpoint.endpoint_id.topology_id.topology_uuid.uuid = INTERDOMAIN_TOPOLOGY_NAME
+        interdomain_endpoint.endpoint_id.topology_id.topology_uuid.uuid = DEFAULT_TOPOLOGY_NAME
         interdomain_endpoint.endpoint_id.topology_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME
         interdomain_endpoint.endpoint_id.device_id.device_uuid.uuid = self.__device.name
         interdomain_endpoint.endpoint_id.endpoint_uuid.uuid = endpoint_name
diff --git a/src/interdomain/service/topology_abstractor/AbstractLink.py b/src/interdomain/service/topology_abstractor/AbstractLink.py
index baeb0f94dcba330ea4d815ba811bd6addad4e5d4..bb1a02334c45b0606c090ccd951f8d3cc8b9ba65 100644
--- a/src/interdomain/service/topology_abstractor/AbstractLink.py
+++ b/src/interdomain/service/topology_abstractor/AbstractLink.py
@@ -15,8 +15,10 @@
 import copy, logging
 from typing import Dict, List, Optional, Tuple
 from common.Constants import DEFAULT_CONTEXT_NAME, INTERDOMAIN_TOPOLOGY_NAME
-from common.proto.context_pb2 import EndPointId, Link
-from common.tools.context_queries.Link import get_link
+from common.proto.context_pb2 import ContextId, EndPointId, Link
+from common.tools.context_queries.Link import add_link_to_topology, get_link
+from common.tools.grpc.Tools import grpc_message_to_json
+from common.tools.object_factory.Context import json_context_id
 from common.tools.object_factory.Link import json_link
 from context.client.ContextClient import ContextClient
 from .Tools import replace_link_uuids_by_names
@@ -39,14 +41,20 @@ class AbstractLink:
         self.__link_name : str = link_name
         self.__link : Optional[Link] = None
 
-        # Dict[(device_name, endpoint_name), abstract EndPointId]
-        self.__device_endpoint_to_abstract : Dict[Tuple[str, str], EndPointId] = dict()
+        # Dict[device_name, Dict[endpoint_name, abstract EndPointId]]
+        self.__device_endpoint_to_abstract : Dict[str, Dict[str, EndPointId]] = dict()
 
     def to_json(self) -> Dict:
         return {
             'link_name' : self.__link_name,
-            'link' : self.__link,
-            'device_endpoint_to_abstract' : self.__device_endpoint_to_abstract,
+            'link' : grpc_message_to_json(self.__link),
+            'device_endpoint_to_abstract' : {
+                device_name : {
+                    endpoint_name : grpc_message_to_json(endpoint_id)
+                    for endpoint_name, endpoint_id in endpoint_ids.items()
+                }
+                for device_name, endpoint_ids in self.__device_endpoint_to_abstract.items()
+            },
         }
 
     @property
@@ -80,13 +88,10 @@ class AbstractLink:
         else:
             self._load_existing(local_interdomain_link)
 
-        ## Add abstract link to topologies [INTERDOMAIN_TOPOLOGY_NAME]
-        #admin_context_id = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME))
-        #topology_uuids = [INTERDOMAIN_TOPOLOGY_NAME]
-        #for topology_uuid in topology_uuids:
-        #    # This action is done automatically; commented out by now.
-        #    add_link_to_topology(
-        #        self.__context_client, admin_context_id, topology_uuid, self.__link_name)
+        # Add abstract link to INTERDOMAIN_TOPOLOGY_NAME topology
+        admin_context_id = ContextId(**json_context_id(DEFAULT_CONTEXT_NAME))
+        topology_name = INTERDOMAIN_TOPOLOGY_NAME
+        add_link_to_topology(self.__context_client, admin_context_id, topology_name, self.__link_name)
 
         return create_abstract_link
 
@@ -106,7 +111,8 @@ class AbstractLink:
         for endpoint_id in self.__link.link_endpoint_ids:
             device_name = endpoint_id.device_id.device_uuid.uuid
             endpoint_name = endpoint_id.endpoint_uuid.uuid
-            self.__device_endpoint_to_abstract.setdefault((device_name, endpoint_name), endpoint_id)
+            endpoints = self.__device_endpoint_to_abstract.setdefault(device_name, dict())
+            endpoints.setdefault(endpoint_name, endpoint_id)
 
     def _add_endpoint(self, device_name : str, endpoint_name : str) -> None:
         endpoint_id = self.__link.link_endpoint_ids.add()
@@ -114,7 +120,8 @@ class AbstractLink:
         endpoint_id.topology_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_NAME
         endpoint_id.device_id.device_uuid.uuid = device_name
         endpoint_id.endpoint_uuid.uuid = endpoint_name
-        self.__device_endpoint_to_abstract.setdefault((device_name, endpoint_name), endpoint_id)
+        endpoints = self.__device_endpoint_to_abstract.setdefault(device_name, dict())
+        endpoints.setdefault(endpoint_name, endpoint_id)
 
     def _remove_endpoint(self, device_name : str, endpoint_name : str) -> None:
         device_endpoint_to_abstract = self.__device_endpoint_to_abstract.get(device_name, {})
@@ -126,16 +133,20 @@ class AbstractLink:
 
         # for each endpoint in abstract link that is not in link; remove from abstract link
         device_endpoint_to_abstract = copy.deepcopy(self.__device_endpoint_to_abstract)
-        for device_name, endpoint_name in device_endpoint_to_abstract.keys():
-            if (device_name, endpoint_name) in link_endpoint_names: continue
-            # remove endpoint_id that is not in link
-            self._remove_endpoint(device_name, endpoint_name)
-            updated = True
+        for device_name, endpoints in device_endpoint_to_abstract.items():
+            for endpoint_name in endpoints.keys():
+                if (device_name, endpoint_name) in link_endpoint_names: continue
+                # remove endpoint_id that is not in link
+                self._remove_endpoint(device_name, endpoint_name)
+                updated = True
 
         # for each endpoint in link that is not in abstract link; add to abstract link
         for device_name, endpoint_name in link_endpoint_names:
             # if already added; just check endpoint type is not modified
-            if (device_name, endpoint_name) in self.__device_endpoint_to_abstract: continue
+            endpoints = self.__device_endpoint_to_abstract.get(device_name, {})
+            endpoint = endpoints.get(endpoint_name)
+            if endpoint is not None: continue
+
             # otherwise, add it to the abstract device
             self._add_endpoint(device_name, endpoint_name)
             updated = True
diff --git a/src/interdomain/service/topology_abstractor/TopologyAbstractor.py b/src/interdomain/service/topology_abstractor/TopologyAbstractor.py
index 357b300a7ac9405ad81259e543f7179a86f8bd9d..c22c3ec2f6e3e5492625a75a4252e4982e73c19c 100644
--- a/src/interdomain/service/topology_abstractor/TopologyAbstractor.py
+++ b/src/interdomain/service/topology_abstractor/TopologyAbstractor.py
@@ -253,7 +253,7 @@ class TopologyAbstractor(threading.Thread):
         }
         str_interdomain_devices = {
             interdomain_device_name : grpc_message_to_json(interdomain_device)
-            for interdomain_device_name,interdomain_device in interdomain_devices
+            for interdomain_device_name,interdomain_device in interdomain_devices.items()
         }
         LOGGER.info('[_infer_abstract_links] interdomain_devices={:s}'.format(str(str_interdomain_devices)))
 
@@ -266,8 +266,7 @@ class TopologyAbstractor(threading.Thread):
             abstract_link_name = AbstractLink.compose_name(device_name, endpoint_name, endpoint_name, device_name)
             LOGGER.info('[_infer_abstract_links] abstract_link_name={:s}'.format(str(abstract_link_name)))
             LOGGER.info('[_infer_abstract_links] abstract_links={:s}'.format(str({
-                abstract_link_name : abstract_link_obj.to_json()
-                for abstract_link_name, abstract_link_obj in self.abstract_links.items()
+                al_name : al_obj.to_json() for al_name, al_obj in self.abstract_links.items()
             })))
             if abstract_link_name in self.abstract_links: continue
 
@@ -320,7 +319,7 @@ class TopologyAbstractor(threading.Thread):
         if dlt_connector_client is not None: dlt_connector_client.close()
 
     def _process_event_topology(self, event : TopologyEvent, dlt_record_sender : DltRecordSender) -> None:
-        LOGGER.debug('Processing TopologyEvent({:s})'.format(grpc_message_to_json_string(event)))
+        LOGGER.info('Processing TopologyEvent({:s})'.format(grpc_message_to_json_string(event)))
         topology_id = event.topology_id
         topology_uuid = topology_id.topology_uuid.uuid
         context_uuid = topology_id.context_id.context_uuid.uuid
@@ -359,7 +358,7 @@ class TopologyAbstractor(threading.Thread):
         LOGGER.info('  topology_name={:s}'.format(str(topology_name)))
         LOGGER.info('  topology_uuids={:s}'.format(str(topology_uuids)))
         if (topology_uuid in topology_uuids) or (topology_name in topology_uuids):
-            MSG = 'Ignoring ({:s}/{:s})({:s}/{:s}) TopologyEvent({:s})... Not a domain topology'
+            MSG = 'Ignoring ({:s}/{:s})({:s}/{:s}) TopologyEvent({:s})... Not a domain/interdomain topology'
             args = context_uuid, context_name, topology_uuid, topology_name, grpc_message_to_json_string(event)
             LOGGER.warning(MSG.format(*args))
             return
@@ -385,7 +384,7 @@ class TopologyAbstractor(threading.Thread):
             self._infer_abstract_links(device, dlt_record_sender)
 
     def _process_event_device(self, event : DeviceEvent, dlt_record_sender : DltRecordSender) -> None:
-        LOGGER.debug('Processing DeviceEvent({:s})'.format(grpc_message_to_json_string(event)))
+        LOGGER.info('Processing DeviceEvent({:s})'.format(grpc_message_to_json_string(event)))
 
         device_uuid = event.device_id.device_uuid.uuid
         device = get_device(
@@ -407,16 +406,16 @@ class TopologyAbstractor(threading.Thread):
         if abstract_device_name is None:
             MSG = 'Ignoring DeviceEvent({:s}). Abstract Device not found'
             LOGGER.warning(MSG.format(grpc_message_to_json_string(event)))
-            return
-
-        abstract_topology_id = self.abstract_device_to_topology_id[abstract_device_name]
-        self._update_abstract_device(
-            device, dlt_record_sender, abstract_topology_id, abstract_device_name=abstract_device_name)
+        else:
+            abstract_topology_id = self.abstract_device_to_topology_id[abstract_device_name]
+            self._update_abstract_device(
+                device, dlt_record_sender, abstract_topology_id, abstract_device_name=abstract_device_name)
 
-        self._infer_abstract_links(device, dlt_record_sender)
+        if abstract_device_name is not None or device_name in self.abstract_device_to_topology_id:
+            self._infer_abstract_links(device, dlt_record_sender)
 
     def _process_event_link(self, event : LinkEvent, dlt_record_sender : DltRecordSender) -> None:
-        LOGGER.debug('Processing LinkEvent({:s})'.format(grpc_message_to_json_string(event)))
+        LOGGER.info('Processing LinkEvent({:s})'.format(grpc_message_to_json_string(event)))
 
         link_uuid = event.link_id.link_uuid.uuid
         link = get_link(self.context_client, link_uuid, rw_copy=True)