diff --git a/README.md b/README.md
index 142aacf6f32c6ee28f219f19618b3e77bdb31972..7f849d0d42dfde718dcb559a9aea4a0f9190de87 100644
--- a/README.md
+++ b/README.md
@@ -256,3 +256,17 @@ Any non-empty responses are JSON formatted messages.
 
   This resource updates data that should only be refreshed
   in case of system restart.
+
+* /classifier/infinera-dna-addresses, /classifier/juniper-server-addresses
+
+  Both of these resources return lists of source addresses
+  of known senders of snmp traps.  Responses will be
+  formatted as follows:
+
+    ```json
+    {
+        "$schema": "http://json-schema.org/draft-07/schema#",
+        "type": "array",
+        "items": {"type": "string"}
+    }
+    ```
\ No newline at end of file
diff --git a/changelog b/changelog
index 73a599d671ad205bf199e5b7a6cb2257f87fe409..c2891b4f8c49c97607dea1713160f957295e5f44 100644
--- a/changelog
+++ b/changelog
@@ -17,3 +17,5 @@
 0.14: added sample route for startup-only tasks
       added method for caching selected alarmsdb tables
       added caching of last known interface status from alarmsdb
+0.15: added some routes for initial classifier support
+      added basic replacement for findAffectedCircuits
\ No newline at end of file
diff --git a/inventory_provider/__init__.py b/inventory_provider/__init__.py
index a8e55e8edb0d75ffbbbcae07669b9d63450a064f..a8adb17fc82ed6aca7c697d723990e18c98cb710 100644
--- a/inventory_provider/__init__.py
+++ b/inventory_provider/__init__.py
@@ -26,8 +26,8 @@ def create_app():
     from inventory_provider.routes import opsdb
     app.register_blueprint(opsdb.routes, url_prefix='/opsdb')
 
-    from inventory_provider.routes import alarmsdb
-    app.register_blueprint(alarmsdb.routes, url_prefix='/alarmsdb')
+    from inventory_provider.routes import classifier
+    app.register_blueprint(classifier.routes, url_prefix='/classifier')
 
     if "SETTINGS_FILENAME" not in os.environ:
         assert False, \
diff --git a/inventory_provider/config.py b/inventory_provider/config.py
index 5dd0019a9ac2770e785be3e6b8d2671ba3d7d579..0f6bc1b320d17da8e4b328cd0957c9f23424eb45 100644
--- a/inventory_provider/config.py
+++ b/inventory_provider/config.py
@@ -46,6 +46,30 @@ CONFIG_SCHEMA = {
             },
             "required": ["hostname", "port"],
             "additionalProperties": False
+        },
+        "infinera-dna": {
+            "type": "array",
+            "items": {
+                "type": "object",
+                "properties": {
+                    "name": {"type": "string"},
+                    "address": {"type": "string"}
+                },
+                "required": ["name", "address"],
+                "additionalProperties": False
+            }
+        },
+        "coriant-tnms": {
+            "type": "array",
+            "items": {
+                "type": "object",
+                "properties": {
+                    "name": {"type": "string"},
+                    "address": {"type": "string"}
+                },
+                "required": ["name", "address"],
+                "additionalProperties": False
+            }
         }
     },
     "required": [
@@ -54,7 +78,9 @@ CONFIG_SCHEMA = {
         "oid_list.conf",
         "routers_community.conf",
         "ssh",
-        "redis"],
+        "redis",
+        "infinera-dna",
+        "coriant-tnms"],
     "additionalProperties": False
 }
 
diff --git a/inventory_provider/opsdb.py b/inventory_provider/opsdb.py
index c0a6417abbc10b803ba4ee39053d8e1498f64533..7848f09de3407fd5c77a56f18b3ae0833e1bd6c1 100644
--- a/inventory_provider/opsdb.py
+++ b/inventory_provider/opsdb.py
@@ -18,7 +18,14 @@ equipment_location_query = """SELECT
                           ON g.absid = p.PTR_geocoding
                         WHERE
                           e.status != 'terminated'
-                          AND e.status != 'disposed'"""
+                          AND e.status != 'disposed'
+                        ORDER BY
+                         FIELD(e.status,
+                          'spare',
+                          'planned',
+                          'ordered',
+                          'installed',
+                          'operational')"""
 
 
 circuit_hierarchy_query = """SELECT
@@ -159,6 +166,7 @@ retrieve_services_query = """SELECT *
                      c.status != 'terminated'
                       AND is_circuit = 1)
                     AS inner_query
+                    WHERE circuit_type IN ('path', 'service', 'l2circuit')
                     ORDER BY
                      FIELD(status,
                       'spare',
@@ -204,6 +212,14 @@ def _juniper_field_update(record):
     return record
 
 
+def _coriant_field_update(record):
+    record["interface_name"] = record["card_id"]
+    if record["port"] is not None and record["port"] != "":
+        separator = "/" if "-" in record["interface_name"] else ""
+        record["interface_name"] += separator + str(record["port"])
+    return record
+
+
 def _update_fields(r):
     func = globals().get("_" + r["manufacturer"] + "_field_update")
     return func(r) if func else r
diff --git a/inventory_provider/routes/alarmsdb.py b/inventory_provider/routes/alarmsdb.py
deleted file mode 100644
index ee1fda69bdeed171f78e2bdea561903562c7dfc0..0000000000000000000000000000000000000000
--- a/inventory_provider/routes/alarmsdb.py
+++ /dev/null
@@ -1,43 +0,0 @@
-import functools
-import json
-
-from flask import Blueprint, request, Response, current_app
-from inventory_provider import alarmsdb, db
-
-routes = Blueprint("inventory-alarmsdb-query-routes", __name__)
-
-
-def require_accepts_json(f):
-    """
-    used as a route handler decorator to return an error
-    unless the request allows responses with type "application/json"
-    :param f: the function to be decorated
-    :return: the decorated function
-    """
-    @functools.wraps(f)
-    def decorated_function(*args, **kwargs):
-        # TODO: use best_match to disallow */* ...?
-        if not request.accept_mimetypes.accept_json:
-            return Response(
-                response="response will be json",
-                status=406,
-                mimetype="text/html")
-        return f(*args, **kwargs)
-    return decorated_function
-
-
-@routes.route("/interface-status", methods=['GET', 'POST'])
-@require_accepts_json
-def get_interface_status():
-    config = current_app.config['INVENTORY_PROVIDER_CONFIG']
-
-    equipment = request.args.get("equipment")
-    interface = request.args.get("interface")
-
-    with db.connection(config['alarms-db']) as connection:
-        result = {"status": alarmsdb.get_last_known_interface_status(
-            connection, equipment, interface)}
-
-    return Response(
-        json.dumps(result),
-        mimetype="application/json")
diff --git a/inventory_provider/routes/classifier.py b/inventory_provider/routes/classifier.py
new file mode 100644
index 0000000000000000000000000000000000000000..85dcbd779d3d419b12625f402b9b17c16ca8a55f
--- /dev/null
+++ b/inventory_provider/routes/classifier.py
@@ -0,0 +1,71 @@
+import functools
+
+from flask import Blueprint, request, Response, current_app, jsonify
+import json
+import jsonschema
+
+from inventory_provider import db
+
+routes = Blueprint("inventory-data-classifier-support-routes", __name__)
+
+
+def require_accepts_json(f):
+    """
+    used as a route handler decorator to return an error
+    unless the request allows responses with type "application/json"
+    :param f: the function to be decorated
+    :return: the decorated function
+    """
+    @functools.wraps(f)
+    def decorated_function(*args, **kwargs):
+        # TODO: use best_match to disallow */* ...?
+        if not request.accept_mimetypes.accept_json:
+            return Response(
+                response="response will be json",
+                status=406,
+                mimetype="text/html")
+        return f(*args, **kwargs)
+    return decorated_function
+
+
+@routes.route("/infinera-dna-addresses", methods=['GET', 'POST'])
+@require_accepts_json
+def infinera_addresses():
+    infinera_config = current_app.config[
+        "INVENTORY_PROVIDER_CONFIG"]["infinera-dna"]
+    return jsonify([dna['address'] for dna in infinera_config])
+
+
+@routes.route("/coriant-tnms-addresses", methods=['GET', 'POST'])
+@require_accepts_json
+def coriant_addresses():
+    coriant_config = current_app.config[
+        "INVENTORY_PROVIDER_CONFIG"]["coriant-tnms"]
+    return jsonify([tnms['address'] for tnms in coriant_config])
+
+
+@routes.route("/juniper-server-addresses", methods=['GET', 'POST'])
+@require_accepts_json
+def juniper_addresses():
+    backend_data_schema = {
+        "$schema": "http://json-schema.org/draft-07/schema#",
+        "type": "array",
+        "items": {
+            "type": "object",
+            "properties": {
+                "ip_address": {"type": "string"}
+            },
+            "required": ["ip_address"]
+        }
+    }
+
+    servers = db.get_redis().get('alarmsdb:juniper_servers')
+    if not servers:
+        return Response(
+            response="no juniper server data found",
+            status=404,
+            mimetype="text/html")
+
+    servers = json.loads(servers.decode('utf-8'))
+    jsonschema.validate(servers, backend_data_schema)
+    return jsonify([s['ip_address'] for s in servers])
diff --git a/inventory_provider/routes/data.py b/inventory_provider/routes/data.py
index 30810e45b074fbf599e5d26ace622675e7e7ca53..7b819151faf1a9ca1527cbe140f56072b8fd2ab8 100644
--- a/inventory_provider/routes/data.py
+++ b/inventory_provider/routes/data.py
@@ -7,7 +7,6 @@ from lxml import etree
 import redis
 
 from inventory_provider import db, juniper
-from inventory_provider.storage import external_inventory
 
 routes = Blueprint("inventory-data-query-routes", __name__)
 
@@ -170,7 +169,7 @@ def bgp_configs(hostname):
 @require_accepts_json
 def interface_statuses(hostname, interface):
     r = db.get_redis()
-    result = r.hget(external_inventory.interface_status_key,
+    result = r.hget("interface_statuses",
                     "{}::{}".format(hostname, interface))
     if not result:
         return Response(
@@ -178,3 +177,17 @@ def interface_statuses(hostname, interface):
             status=404,
             mimetype="text/html")
     return jsonify({"status": result.decode('utf-8')})
+
+
+@routes.route("/services/<hostname>/<path:interface>",
+              methods=['GET', 'POST'])
+def services_for_interface(hostname, interface):
+    r = db.get_redis()
+    result = r.hget("interface_services",
+                    "{}::{}".format(hostname, interface))
+    if not result:
+        return Response(
+            response="no available info for {} {}".format(hostname, interface),
+            status=404,
+            mimetype="text/html")
+    return jsonify(json.loads(result.decode('utf-8')))
diff --git a/inventory_provider/routes/jobs.py b/inventory_provider/routes/jobs.py
index 315c3e8d7c960228304a6a5020497cde0bbe1f42..25954f2b93df1eef33bb70e53c72649f81ec400b 100644
--- a/inventory_provider/routes/jobs.py
+++ b/inventory_provider/routes/jobs.py
@@ -1,8 +1,7 @@
 import logging
+
 from flask import Blueprint, Response, current_app
 
-import inventory_provider.storage.external_inventory as external_inventory
-from inventory_provider import db, opsdb
 from inventory_provider.tasks.app import app
 from inventory_provider.constants import TASK_LOGGER_NAME
 
@@ -49,56 +48,38 @@ def startup_update():
     return Response("OK")
 
 
-@routes.route("update-services", methods=['GET'])
-def update_service():
-    config = current_app.config['INVENTORY_PROVIDER_CONFIG']
-
-    with db.connection(config['ops-db']) as connection:
-        result = opsdb.get_circuits(connection)
-    external_inventory.update_services_to_monitor(result)
-    return Response("OK")
-
-
-@routes.route("update-interfaces", methods=['GET'])
-def update_interfaces():
-    config = current_app.config['INVENTORY_PROVIDER_CONFIG']
-
-    with db.connection(config['ops-db']) as connection:
-        result = opsdb.get_circuits(connection)
-    external_inventory.update_interfaces_to_services(result)
+@routes.route("update-interfaces-to-services", methods=['GET'])
+def update_interfaces_to_services():
+    app.send_task(
+        'inventory_provider.tasks.worker.update_interfaces_to_services')
     return Response("OK")
 
 
 @routes.route("update-service-hierarchy", methods=['GET'])
 def update_service_hierarchy():
-    config = current_app.config['INVENTORY_PROVIDER_CONFIG']
-
-    with db.connection(config['ops-db']) as connection:
-        result = opsdb.get_circuit_hierarchy(connection)
-    external_inventory.update_service_hierarchy(result)
+    app.send_task('inventory_provider.tasks.worker.update_circuit_hierarchy')
     return Response("OK")
 
 
 @routes.route("update-equipment-locations", methods=['GET'])
 def update_equipment_locations():
-    config = current_app.config['INVENTORY_PROVIDER_CONFIG']
-
-    with db.connection(config['ops-db']) as connection:
-        result = opsdb.get_equipment_location_data(connection)
-    external_inventory.update_equipment_locations(result)
+    app.send_task('inventory_provider.tasks.worker.update_equipment_locations')
     return Response("OK")
 
 
 @routes.route("update-from-inventory-system", methods=['GET'])
 def update_from_inventory_system():
-    config = current_app.config['INVENTORY_PROVIDER_CONFIG']
-
-    with db.connection(config['ops-db']) as connection:
-        circuits = opsdb.get_circuits(connection)
-        hierarchy = opsdb.get_circuit_hierarchy(connection)
-        equipment_locations = opsdb.get_equipment_location_data(connection)
-    external_inventory.update_services_to_monitor(circuits)
-    external_inventory.update_interfaces_to_services(circuits)
-    external_inventory.update_service_hierarchy(hierarchy)
-    external_inventory.update_equipment_locations(equipment_locations)
+    app.send_task(
+        'inventory_provider.tasks.worker.update_service_to_monitor')
+    app.send_task(
+        'inventory_provider.tasks.worker.update_interfaces_to_services')
+    app.send_task('inventory_provider.tasks.worker.update_circuit_hierarchy')
+    app.send_task('inventory_provider.tasks.worker.update_equipment_locations')
+    return Response("OK")
+
+
+@routes.route("update-interface-statuses")
+def update_interface_statuses():
+    app.send_task(
+        'inventory_provider.tasks.worker.update_interface_statuses')
     return Response("OK")
diff --git a/inventory_provider/routes/opsdb.py b/inventory_provider/routes/opsdb.py
index 9d176e6825704b1ddfe7d645a23bab021606f79e..c49fe1f269e04944aca61cb69e5cb158648185a7 100644
--- a/inventory_provider/routes/opsdb.py
+++ b/inventory_provider/routes/opsdb.py
@@ -3,13 +3,14 @@ import json
 
 from flask import Blueprint, request, Response
 from inventory_provider import db
-from inventory_provider.storage import external_inventory
 
 routes = Blueprint("inventory-opsdb-query-routes", __name__)
 
-services_key = "inv_services"
-interfaces_key = "inv_interfaces"
-equipment_locations_key = "inv_eq_locations"
+interfaces_key = "interface_services"
+equipment_locations_key = "equipment_locations"
+service_child_to_parents_key = "child_to_parent_circuit_relations"
+service_parent_to_children_key = "parent_to_children_circuit_relations"
+interface_status_key = "interface_statuses"
 
 
 def require_accepts_json(f):
@@ -93,7 +94,7 @@ def get_children(parent_id):
     r = db.get_redis()
     return Response(
         r.hget(
-            external_inventory.service_parent_to_children_key,
+            service_parent_to_children_key,
             parent_id),
         mimetype="application/json")
 
@@ -103,6 +104,6 @@ def get_parents(child_id):
     r = db.get_redis()
     return Response(
         r.hget(
-            external_inventory.service_child_to_parents_key,
+            service_child_to_parents_key,
             child_id),
         mimetype="application/json")
diff --git a/inventory_provider/storage/__init__.py b/inventory_provider/storage/__init__.py
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/inventory_provider/storage/external_inventory.py b/inventory_provider/storage/external_inventory.py
deleted file mode 100644
index e721a348d52a83ca82121dd299f674f630d38392..0000000000000000000000000000000000000000
--- a/inventory_provider/storage/external_inventory.py
+++ /dev/null
@@ -1,72 +0,0 @@
-import json
-from collections import defaultdict
-from flask import current_app
-from inventory_provider import alarmsdb, db
-
-
-services_key = "inv_services"
-interfaces_key = "inv_interfaces"
-equipment_locations_key = "inv_eq_locations"
-service_child_to_parents_key = "inv_service_child_to_parents"
-service_parent_to_children_key = "inv_service_parent_to_children"
-interface_status_key = "service_status"
-
-
-def update_services_to_monitor(services):
-    r = db.get_redis()
-    relevant_types = ("path", "service", "l2circuit")
-    r.delete(services_key)
-    for service in services:
-        if service["circuit_type"].lower() in relevant_types:
-            r.hset(services_key, service["id"], json.dumps(service))
-
-
-def update_interfaces_to_services(services):
-    r = db.get_redis()
-    config = current_app.config["INVENTORY_PROVIDER_CONFIG"]
-    with db.connection(config["alarms-db"]) as cnx:
-        with db.cursor(cnx) as csr:
-            mapped_interfaces = defaultdict(list)
-            r.delete(interfaces_key)
-            for service in services:
-                key = "{}::{}".format(
-                    service["equipment"],
-                    service["interface_name"]
-                )
-                mapped_interfaces[key].append(service)
-                if not r.hexists(interface_status_key, key):
-                    r.hset(interface_status_key, key,
-                           alarmsdb.get_last_known_interface_status(
-                               csr,
-                               service["equipment"],
-                               service["interface_name"]
-                           ))
-
-    for key, value in mapped_interfaces.items():
-        r.hset(interfaces_key, key, json.dumps(value))
-
-
-def update_service_hierarchy(records):
-    r = db.get_redis()
-    children_to_parents = defaultdict(list)
-    parents_to_children = defaultdict(list)
-    for relation in records:
-        parent_id = relation["parent_circuit_id"]
-        child_id = relation["child_circuit_id"]
-        parents_to_children[parent_id].append(relation)
-        children_to_parents[child_id].append(relation)
-
-    r.delete(service_child_to_parents_key)
-    for child, parents in children_to_parents.items():
-        r.hset(service_child_to_parents_key, child, json.dumps(parents))
-
-    r.delete(service_parent_to_children_key)
-    for parent, children in parents_to_children.items():
-        r.hset(service_parent_to_children_key, parent, json.dumps(children))
-
-
-def update_equipment_locations(equipment_location_data):
-    r = db.get_redis()
-    r.delete(equipment_locations_key)
-    for ld in equipment_location_data:
-        r.hset(equipment_locations_key, ld["equipment_name"], json.dumps(ld))
diff --git a/inventory_provider/tasks/worker.py b/inventory_provider/tasks/worker.py
index 8f2efb84f0badfac81a87851d541f9297c6a1bd0..2f48358a17bc2b5480ace087e8ab60391a4ea6af 100644
--- a/inventory_provider/tasks/worker.py
+++ b/inventory_provider/tasks/worker.py
@@ -2,6 +2,7 @@ import json
 import logging
 
 from celery import bootsteps, Task
+from collections import defaultdict
 import redis
 from lxml import etree
 
@@ -11,6 +12,7 @@ from inventory_provider import config
 from inventory_provider import constants
 from inventory_provider import db
 from inventory_provider import environment
+from inventory_provider import opsdb
 from inventory_provider import snmp
 from inventory_provider import juniper
 
@@ -81,6 +83,13 @@ class WorkerArgs(bootsteps.Step):
         InventoryTask.logger = logging.getLogger(constants.TASK_LOGGER_NAME)
 
 
+interfaces_key = "interface_services"
+equipment_locations_key = "equipment_locations"
+service_child_to_parents_key = "child_to_parent_circuit_relations"
+service_parent_to_children_key = "parent_to_children_circuit_relations"
+interface_status_key = "interface_statuses"
+
+
 def worker_args(parser):
     parser.add_argument(
         "--config_filename",
@@ -135,3 +144,98 @@ def update_alarmsdb_cache(self):
             InventoryTask.save_value_json('alarmsdb:%s' % table_name, data)
 
     logger.debug('FINISHED: update_alarmsdb_cache')
+
+
+@app.task()
+def update_interfaces_to_services():
+    # todo - factor this connection stuff out
+    r = redis.StrictRedis(
+        host=InventoryTask.config["redis"]["hostname"],
+        port=InventoryTask.config["redis"]["port"])
+    with db.connection(InventoryTask.config["ops-db"]) as cx:
+        services = opsdb.get_circuits(cx)
+
+    mapped_interfaces = defaultdict(list)
+    for service in services:
+        key = "{}::{}".format(
+            service["equipment"],
+            service["interface_name"]
+        )
+        mapped_interfaces[key].append(service)
+        # Puts lu services under the parent ae as well as their own interface
+        # eg. services on ae15.12 would be found under ae15 as well as ae15.12
+        if "." in service["interface_name"]:
+            key = "{}::{}".format(
+                service["equipment"],
+                service["interface_name"].split(".")[0]
+            )
+            mapped_interfaces[key].append(service)
+
+    r.delete(interfaces_key)
+    for key, value in mapped_interfaces.items():
+        r.hset(interfaces_key, key, json.dumps(value))
+
+
+@app.task()
+def update_equipment_locations():
+    # todo - factor this connection stuff out
+    r = redis.StrictRedis(
+        host=InventoryTask.config["redis"]["hostname"],
+        port=InventoryTask.config["redis"]["port"])
+    r.delete(equipment_locations_key)
+
+    with db.connection(InventoryTask.config["ops-db"]) as cx:
+        for ld in opsdb.get_equipment_location_data(cx):
+            r.hset(
+                equipment_locations_key, ld["equipment_name"], json.dumps(ld))
+
+
+@app.task()
+def update_circuit_hierarchy():
+    # todo - factor this connection stuff out
+    r = redis.StrictRedis(
+        host=InventoryTask.config["redis"]["hostname"],
+        port=InventoryTask.config["redis"]["port"])
+    children_to_parents = defaultdict(list)
+    parents_to_children = defaultdict(list)
+    with db.connection(InventoryTask.config["ops-db"]) as cx:
+        records = opsdb.get_circuit_hierarchy(cx)
+        for relation in records:
+            parent_id = relation["parent_circuit_id"]
+            child_id = relation["child_circuit_id"]
+            parents_to_children[parent_id].append(relation)
+            children_to_parents[child_id].append(relation)
+
+        r.delete(service_child_to_parents_key)
+        for child, parents in children_to_parents.items():
+            r.hset(service_child_to_parents_key, child, json.dumps(parents))
+
+        r.delete(service_parent_to_children_key)
+        for parent, children in parents_to_children.items():
+            r.hset(
+                service_parent_to_children_key, parent, json.dumps(children))
+
+
+@app.task()
+def update_interface_statuses():
+    # todo - factor this connection stuff out
+    r = redis.StrictRedis(
+        host=InventoryTask.config["redis"]["hostname"],
+        port=InventoryTask.config["redis"]["port"])
+    with db.connection(InventoryTask.config["ops-db"]) as cx:
+            services = opsdb.get_circuits(cx)
+    with db.connection(InventoryTask.config["alarms-db"]) as cx:
+        with db.cursor(cx) as csr:
+            for service in services:
+                key = "{}::{}".format(
+                    service["equipment"],
+                    service["interface_name"]
+                )
+                if not r.hexists(interface_status_key, key):
+                    r.hset(interface_status_key,
+                           key,
+                           alarmsdb.get_last_known_interface_status(
+                               csr,
+                               service["equipment"],
+                               service["interface_name"]
+                           ))
diff --git a/setup.py b/setup.py
index d48ac903b5b8d269c01cbe3d2f8b600d35383380..fd7d16bf8508369e6fc9cce9803c83911e6a5b51 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
 
 setup(
     name='inventory-provider',
-    version="0.14",
+    version="0.15",
     author='GEANT',
     author_email='swd@geant.org',
     description='Dashboard inventory provider',
diff --git a/test/conftest.py b/test/conftest.py
index 1b8bf386dfaf2bf9055449ed04710a531bc161a7..26186461066c26a4c6654a6b021f975831544cf7 100644
--- a/test/conftest.py
+++ b/test/conftest.py
@@ -42,7 +42,17 @@ def data_config_filename(tmp_dir_name):
         "redis": {
             "hostname": "xxxxxx",
             "port": 6379
-        }
+        },
+        "infinera-dna": [
+            {"name": "name1", "address": "123.456.789.0"},
+            {"name": "name2", "address": "012.345.678.9"},
+            {"name": "name3", "address": "111.222.333.000"}
+        ],
+        "coriant-tnms": [
+            {"name": "name1", "address": "123.456.789.0"},
+            {"name": "name2", "address": "012.345.678.9"},
+            {"name": "name3", "address": "111.222.333.000"}
+        ]
     }
 
     shutil.copyfile(
diff --git a/test/storage/test_external_inventory.py b/test/storage/test_external_inventory.py
deleted file mode 100644
index b0caf9684824c9a701e67a05f25ceca5468723ea..0000000000000000000000000000000000000000
--- a/test/storage/test_external_inventory.py
+++ /dev/null
@@ -1,156 +0,0 @@
-from inventory_provider.storage import external_inventory
-
-
-def test_update_services_to_monitor(mocker):
-    mocked_redis = mocker.patch(
-        "inventory_provider.storage.external_inventory.db.get_redis")
-    mocked_hset = mocked_redis.return_value.hset
-
-    services = [
-        {"circuit_type": "path", "id": "test_id_0", "other": "stuff"},
-        {"circuit_type": "service", "id": "test_id_1", "other": "stuff"},
-        {"circuit_type": "l2circuit", "id": "test_id_2", "other": "stuff"},
-        {"circuit_type": "spam", "id": "test_id_4", "other": "stuff"}
-    ]
-    external_inventory.update_services_to_monitor(services)
-    mocked_hset.assert_any_call(
-        external_inventory.services_key, "test_id_0",
-        "{\"circuit_type\": \"path\","
-        " \"id\": \"test_id_0\","
-        " \"other\": \"stuff\"}")
-    mocked_hset.assert_any_call(
-        external_inventory.services_key, "test_id_1",
-        "{\"circuit_type\": \"service\","
-        " \"id\": \"test_id_1\","
-        " \"other\": \"stuff\"}")
-    mocked_hset.assert_any_call(
-        external_inventory.services_key, "test_id_2",
-        "{\"circuit_type\": \"l2circuit\","
-        " \"id\": \"test_id_2\","
-        " \"other\": \"stuff\"}")
-    assert mocked_hset.call_count == 3
-
-
-def test_update_interfaces_to_services(mocker):
-    mocked_redis = mocker.patch(
-        "inventory_provider.storage.external_inventory.db.get_redis")
-    mocker.patch(
-        "inventory_provider.storage.external_inventory.current_app")
-    mocker.patch(
-        "inventory_provider.storage.external_inventory.db.connection")
-    mocker.patch(
-        "inventory_provider.storage.external_inventory.db.cursor")
-    mocked_hset = mocked_redis.return_value.hset
-    services = [
-        {"equipment": "eq_0", "interface_name": "if_0"},
-        {"equipment": "eq_1", "interface_name": "if_1"},
-        {"equipment": "eq_2", "interface_name": "if_2"},
-        {"equipment": "eq_3", "interface_name": "if_3"},
-        {"equipment": "eq_3", "interface_name": "if_3", "extra": "stuff"},
-        {"equipment": "eq_4", "interface_name": "if_4"}
-    ]
-    unique_keys = set(s["equipment"] + "::" + s["interface_name"]
-                      for s in services)
-
-    external_inventory.update_interfaces_to_services(services)
-    assert mocked_hset.call_count == len(unique_keys)
-    mocked_hset.assert_any_call(external_inventory.interfaces_key,
-                                "eq_2::if_2",
-                                "[{\"equipment\": \"eq_2\","
-                                " \"interface_name\": \"if_2\"}]")
-    mocked_hset.assert_any_call(external_inventory.interfaces_key,
-                                "eq_3::if_3",
-                                "[{\"equipment\": \"eq_3\","
-                                " \"interface_name\": \"if_3\"},"
-                                " {\"equipment\": \"eq_3\","
-                                " \"interface_name\": \"if_3\","
-                                " \"extra\": \"stuff\"}]")
-
-
-def test_update_service_hierarchy(mocker):
-    mocked_redis = mocker.patch(
-        "inventory_provider.storage.external_inventory.db.get_redis")
-    mocked_hset = mocked_redis.return_value.hset
-    data = [
-        {"parent_circuit": "PC_1",
-         "parent_circuit_id": "1001",
-         "parent_circuit_status": "operational",
-         "child_circuit": "CC_1",
-         "child_circuit_id": "2001",
-         "segment_group": 1},
-        {"parent_circuit": "PC_2",
-         "parent_circuit_id": "1002",
-         "parent_circuit_status": "operational",
-         "child_circuit": "CC_1",
-         "child_circuit_id": "2001",
-         "segment_group": 1},
-        {"parent_circuit": "PC_3",
-         "parent_circuit_id": "1003",
-         "parent_circuit_status": "operational",
-         "child_circuit": "CC_2",
-         "child_circuit_id": "2002",
-         "segment_group": 1},
-        {"parent_circuit": "PC_3",
-         "parent_circuit_id": "1003",
-         "parent_circuit_status": "operational",
-         "child_circuit": "CC_3",
-         "child_circuit_id": "2003",
-         "segment_group": 1}
-    ]
-    external_inventory.update_service_hierarchy(data)
-    u_parent_keys = set([d["parent_circuit_id"] for d in data])
-    u_child_keys = set([d["child_circuit_id"] for d in data])
-    assert mocked_hset.call_count == len(u_parent_keys) + len(u_child_keys)
-    mocked_hset.assert_any_call(
-        external_inventory.service_child_to_parents_key,
-        "2001",
-        "[{\"parent_circuit\": \"PC_1\","
-        " \"parent_circuit_id\": \"1001\","
-        " \"parent_circuit_status\": \"operational\","
-        " \"child_circuit\": \"CC_1\","
-        " \"child_circuit_id\": \"2001\","
-        " \"segment_group\": 1},"
-        " {\"parent_circuit\": \"PC_2\","
-        " \"parent_circuit_id\": \"1002\","
-        " \"parent_circuit_status\": \"operational\","
-        " \"child_circuit\": \"CC_1\","
-        " \"child_circuit_id\": \"2001\","
-        " \"segment_group\": 1}]"
-    )
-    mocked_hset.assert_any_call(
-        external_inventory.service_child_to_parents_key,
-        "2002",
-        "[{\"parent_circuit\": \"PC_3\","
-        " \"parent_circuit_id\": \"1003\","
-        " \"parent_circuit_status\": \"operational\","
-        " \"child_circuit\": \"CC_2\","
-        " \"child_circuit_id\": \"2002\","
-        " \"segment_group\": 1}]"
-    )
-
-    mocked_hset.assert_any_call(
-        external_inventory.service_parent_to_children_key,
-        "1003",
-        "[{\"parent_circuit\": \"PC_3\","
-        " \"parent_circuit_id\": \"1003\","
-        " \"parent_circuit_status\": \"operational\","
-        " \"child_circuit\": \"CC_2\","
-        " \"child_circuit_id\": \"2002\","
-        " \"segment_group\": 1},"
-        " {\"parent_circuit\": \"PC_3\","
-        " \"parent_circuit_id\": \"1003\","
-        " \"parent_circuit_status\": \"operational\","
-        " \"child_circuit\": \"CC_3\","
-        " \"child_circuit_id\": \"2003\","
-        " \"segment_group\": 1}]"
-    )
-    mocked_hset.assert_any_call(
-        external_inventory.service_parent_to_children_key,
-        "1002",
-        "[{\"parent_circuit\": \"PC_2\","
-        " \"parent_circuit_id\": \"1002\","
-        " \"parent_circuit_status\": \"operational\","
-        " \"child_circuit\": \"CC_1\","
-        " \"child_circuit_id\": \"2001\","
-        " \"segment_group\": 1}]"
-    )
diff --git a/test/test_alarmdb_routes.py b/test/test_alarmdb_routes.py
deleted file mode 100644
index 82522455868b48bdda22a82131c606dcdd8f0d72..0000000000000000000000000000000000000000
--- a/test/test_alarmdb_routes.py
+++ /dev/null
@@ -1,37 +0,0 @@
-import json
-import jsonschema
-
-DEFAULT_REQUEST_HEADERS = {
-    "Content-type": "application/json",
-    "Accept": ["application/json"]
-}
-
-
-def test_get_interface_status(mocker, client):
-    mocked_conn = mocker.patch('inventory_provider.routes.alarmsdb'
-                               '.db.connection')
-    mocked_conn.return_value.__enter__.return_value = None
-
-    mocked_inteface_status = mocker.patch(
-        'inventory_provider.routes.alarmsdb.'
-        'alarmsdb.get_last_known_interface_status')
-    mocked_inteface_status.return_value = "up"
-
-    rv = client.get(
-        '/alarmsdb/interface-status?'
-        'equipment=mx1.lon.uk.geant.net&interface=xe-1/2/2',
-        headers=DEFAULT_REQUEST_HEADERS)
-
-    interfaces_list_schema = {
-        "$schema": "http://json-schema.org/draft-07/schema#",
-        "type": "object",
-        "properties": {
-            "status": {
-                "type": "string",
-            }
-        }
-    }
-
-    response = json.loads(rv.data.decode("utf-8"))
-    jsonschema.validate(response, interfaces_list_schema)
-    assert response == {"status": "up"}
diff --git a/test/test_classifier_routes.py b/test/test_classifier_routes.py
new file mode 100644
index 0000000000000000000000000000000000000000..114112d1a6cd3789e38211547a03eb14497cfbe8
--- /dev/null
+++ b/test/test_classifier_routes.py
@@ -0,0 +1,75 @@
+import json
+import jsonschema
+
+DEFAULT_REQUEST_HEADERS = {
+    "Content-type": "application/json",
+    "Accept": ["application/json"]
+}
+
+
+def test_infinera_addresses(client):
+    response_schema = {
+        "$schema": "http://json-schema.org/draft-07/schema#",
+        "type": "array",
+        "items": {"type": "string"}
+    }
+
+    rv = client.post(
+        "/classifier/infinera-dna-addresses",
+        headers=DEFAULT_REQUEST_HEADERS)
+    assert rv.status_code == 200
+    jsonschema.validate(
+        json.loads(rv.data.decode("utf-8")),
+        response_schema)
+
+
+def test_coriant_addresses(client):
+    response_schema = {
+        "$schema": "http://json-schema.org/draft-07/schema#",
+        "type": "array",
+        "items": {"type": "string"}
+    }
+
+    rv = client.post(
+        "/classifier/coriant-tnms-addresses",
+        headers=DEFAULT_REQUEST_HEADERS)
+    assert rv.status_code == 200
+    jsonschema.validate(
+        json.loads(rv.data.decode("utf-8")),
+        response_schema)
+
+
+def test_juniper_addresses(mocker, client):
+
+    test_data = [
+        {"ip_address": "a.b.c.d", "project_name": "AAABBB"},
+        {"ip_address": "b.c.d.e", "project_name": "CCCCDDDDD"},
+        {"ip_address": "c.d.e.f", "project_name": "EFEFEFEF"},
+        {"ip_address": "::1", "project_name": "GGHHGGHH"}
+    ]
+
+    class MockedRedis():
+        def __init__(self):
+            pass
+
+        def get(self, ignored):
+            return json.dumps(test_data).encode('utf-8')
+
+    mocker.patch(
+        'inventory_provider.routes.classifier.db.get_redis',
+        return_value=MockedRedis())
+
+    response_schema = {
+            "$schema": "http://json-schema.org/draft-07/schema#",
+            "type": "array",
+            "items": {"type": "string"}
+        }
+
+    rv = client.post(
+        "/classifier/juniper-server-addresses",
+        headers=DEFAULT_REQUEST_HEADERS)
+    assert rv.status_code == 200
+    response_data = json.loads(rv.data.decode('utf-8'))
+    jsonschema.validate(response_data, response_schema)
+    assert len(response_data) == len(test_data)
+    assert set([x['ip_address'] for x in test_data]) == set(response_data)
diff --git a/test/test_external_inventory_routes.py b/test/test_external_inventory_routes.py
index 4adc7d5890795740626e7a696fe51f6c1a89a6fc..32c72c8a1787bfddfd6530f4b272fed485753aeb 100644
--- a/test/test_external_inventory_routes.py
+++ b/test/test_external_inventory_routes.py
@@ -1,5 +1,5 @@
 import json
-from inventory_provider.storage import external_inventory
+from inventory_provider.tasks import worker
 
 DEFAULT_REQUEST_HEADERS = {
     "Content-type": "application/json",
@@ -31,7 +31,7 @@ def test_get_one_equipment_location(mocker, client):
     assert dummy_data == json.loads(rv.data.decode("utf-8"))
 
     mocked_hget.assert_called_with(
-        external_inventory.equipment_locations_key,
+        worker.equipment_locations_key,
         "dummy-equipment"
     )
 
@@ -48,7 +48,7 @@ def test_get_equipment_location(mocker, client):
     assert rv.is_json
 
     mocked_hgetall.assert_called_with(
-        external_inventory.equipment_locations_key
+        worker.equipment_locations_key
     )
 
 
@@ -64,7 +64,7 @@ def test_get_interface_info(mocker, client):
     assert rv.is_json
 
     mocked_hgetall.assert_called_with(
-        external_inventory.interfaces_key
+        worker.interfaces_key
     )
 
 
@@ -80,7 +80,7 @@ def test_get_interface_info_for_equipment(mocker, client):
     assert rv.is_json
 
     mocked_hscan_iter.assert_called_with(
-        external_inventory.interfaces_key, "dummy-equipment::*"
+        worker.interfaces_key, "dummy-equipment::*"
     )
 
 
@@ -96,7 +96,7 @@ def test_get_interface_info_for_equipment_and_interface(mocker, client):
     assert rv.is_json
 
     mocked_hget.assert_called_with(
-        external_inventory.interfaces_key, "dummy-equipment::xe-2/3/1"
+        worker.interfaces_key, "dummy-equipment::xe-2/3/1"
     )
 
 
@@ -112,7 +112,7 @@ def test_get_children(mocker, client):
     assert rv.is_json
 
     mocked_hget.assert_called_with(
-        external_inventory.service_parent_to_children_key,
+        worker.service_parent_to_children_key,
         "22987"
     )
 
@@ -129,6 +129,6 @@ def test_get_parents(mocker, client):
     assert rv.is_json
 
     mocked_hget.assert_called_with(
-        external_inventory.service_parent_to_children_key,
+        worker.service_parent_to_children_key,
         "22987"
     )
diff --git a/test/test_opsdb.py b/test/test_opsdb.py
index 3507bdc0bcb80e341586cd2d8d966a5591da94fc..7e6c1848378c14f31ea6ede92b04a1bc2a65f2e2 100644
--- a/test/test_opsdb.py
+++ b/test/test_opsdb.py
@@ -97,6 +97,24 @@ def test_juniper_field_update():
     assert r["interface_name"] == "xe-2/0/0.123"
 
 
+def test_coriant_update_fields():
+    i = {
+        "equipment": "groove-1",
+        "card_id": "2-3",
+        "port": None
+         }
+    r = inventory_provider.opsdb._coriant_field_update(i)
+    assert r["interface_name"] == "2-3"
+
+    i = {
+        "equipment": "groove-1",
+        "card_id": "2-3",
+        "port": "4"
+         }
+    r = inventory_provider.opsdb._coriant_field_update(i)
+    assert r["interface_name"] == "2-3/4"
+
+
 def test_get_circuits(mocker):
     mocker.patch("inventory_provider.opsdb.db.cursor")
     mocked_convert_to_dict = mocker.patch(