[CORD-1324-1328-1330-1331] Models for refactored Global ECORD service

Change-Id: Ib9c02d25bd65729c7faaa48d40b54a2ce6ffffac
diff --git a/xos/synchronizer/Dockerfile.synchronizer b/xos/synchronizer/Dockerfile.synchronizer
index 9440751..3ff2ebc 100644
--- a/xos/synchronizer/Dockerfile.synchronizer
+++ b/xos/synchronizer/Dockerfile.synchronizer
@@ -6,4 +6,4 @@
 
 WORKDIR "/opt/xos/synchronizers/metro-net"
 
-CMD bash -c "cd /opt/xos/synchronizers/metro-net; ./run-from-api.sh
\ No newline at end of file
+CMD bash -c "cd /opt/xos/synchronizers/metro-net; ./run-from-api.sh"
\ No newline at end of file
diff --git a/xos/synchronizer/invokers/invoker.py b/xos/synchronizer/invokers/invoker.py
deleted file mode 100644
index e645285..0000000
--- a/xos/synchronizer/invokers/invoker.py
+++ /dev/null
@@ -1,25 +0,0 @@
-class Invoker(object):
-
-    def __init__(self, **args):
-        pass
-
-    # Method for handline pre save semantics
-    #      content here would be model specific but could include handling Many-to-Many relationship
-    #      creation - which must occur post save
-    #
-    # obj     - Whatever obj was just saved
-    # returns - None - this is a pure invoke() call, return type is None
-    #
-    def presave(self, obj):
-        return None
-
-
-    # Method for handline post save semantics
-    #      content here would be model specific but could include handling Many-to-Many relationship
-    #      creation - which must occur post save
-    #
-    # obj     - Whatever obj was just saved
-    # returns - None - this is a pure invoke() call, return type is None
-    #
-    def postsave(self, obj):
-        return None
\ No newline at end of file
diff --git a/xos/synchronizer/invokers/invokerfactory.py b/xos/synchronizer/invokers/invokerfactory.py
deleted file mode 100644
index b3628fe..0000000
--- a/xos/synchronizer/invokers/invokerfactory.py
+++ /dev/null
@@ -1,29 +0,0 @@
-from services.metronetwork.models import *
-from synchronizers.metronetwork.invokers.networkmultipointtomultipointinvoker import NetworkMultipointToMultipointInvoker
-from synchronizers.metronetwork.invokers.networkedgetoedgepointinvoker import NetworkEdgeToEdgePointInvoker
-from synchronizers.metronetwork.invokers.networkedgetomultipointinvoker import NetworkEdgeToMultipointInvoker
-from synchronizers.metronetwork.invokers.servicespokeinvoker import ServiceSpokeInvoker
-from synchronizers.metronetwork.invokers.vnodglobalserviceinvoker import VnodGlobalServiceInvoker
-from synchronizers.metronetwork.invokers.remoteportinvoker import RemotePortInvoker
-
-
-class InvokerFactory(object):
-    @staticmethod
-    def getinvoker(obj):
-        #
-        # Here is where we build various invokers
-        #
-        if isinstance(obj, NetworkMultipointToMultipointConnection):
-            return NetworkMultipointToMultipointInvoker()
-        elif isinstance(obj, NetworkEdgeToEdgePointConnection):
-            return NetworkEdgeToEdgePointInvoker()
-        elif isinstance(obj, NetworkEdgeToMultipointConnection):
-            return NetworkEdgeToMultipointInvoker()
-        elif isinstance(obj, ServiceSpoke):
-            return ServiceSpokeInvoker()
-        elif isinstance(obj, VnodGlobalService):
-            return VnodGlobalServiceInvoker()
-        elif isinstance(obj, RemotePort):
-            return RemotePortInvoker()
-        else:
-            return None
diff --git a/xos/synchronizer/invokers/networkedgetoedgepointinvoker.py b/xos/synchronizer/invokers/networkedgetoedgepointinvoker.py
deleted file mode 100644
index 2c30d79..0000000
--- a/xos/synchronizer/invokers/networkedgetoedgepointinvoker.py
+++ /dev/null
@@ -1,34 +0,0 @@
-import json
-from synchronizers.metronetwork.invokers.invoker import Invoker
-from services.metronetwork.models import NetworkEdgePort
-
-
-class NetworkEdgeToEdgePointInvoker(Invoker):
-    def __init__(self, **args):
-        pass
-
-    # Method for handline pre save semantics
-    #      content here would be model specific but could include handling Many-to-Many relationship
-    #      creation - which must occur post save
-    #
-    # obj     - Whatever obj was just saved
-    # returns - None - this is a pure invoke() call, return type is None
-    #
-    def presave(self, obj):
-        # Now that the Ports are created - get a proper reference to them and update the
-        # src and dst fields
-        if hasattr(obj, 'uni1_createbuffer'):
-            uni1port = NetworkEdgePort.objects.get(pid=obj.uni1_createbuffer)
-            uni2port = NetworkEdgePort.objects.get(pid=obj.uni2_createbuffer)
-            obj.uni1 = uni1port
-            obj.uni2 = uni2port
-
-    # Method for handline post save semantics
-    #      content here would be model specific but could include handling Many-to-Many relationship
-    #      creation - which must occur post save
-    #
-    # obj     - Whatever obj was just saved
-    # returns - N/A - this is a pure invoke() call
-    #
-    def postsave(self, obj):
-        pass
diff --git a/xos/synchronizer/invokers/networkedgetomultipointinvoker.py b/xos/synchronizer/invokers/networkedgetomultipointinvoker.py
deleted file mode 100644
index 9b8e88b..0000000
--- a/xos/synchronizer/invokers/networkedgetomultipointinvoker.py
+++ /dev/null
@@ -1,47 +0,0 @@
-import json
-from synchronizers.metronetwork.invokers.invoker import Invoker
-from services.metronetwork.models import NetworkEdgeToMultipointConnection, NetworkEdgePort
-
-class NetworkEdgeToMultipointInvoker(Invoker):
-
-    def __init__(self, **args):
-        pass
-
-    # Method for handline pre save semantics
-    #      content here would be model specific but could include handling Many-to-Many relationship
-    #      creation - which must occur post save
-    #
-    # obj     - Whatever obj was just saved
-    # returns - None - this is a pure invoke() call, return type is None
-    #
-    def presave(self, obj):
-        # Now that the Ports are created - get a proper reference to them and update the
-        # root field
-        if hasattr(obj, 'root_createbuffer'):
-            rootEdgePort = NetworkEdgePort.objects.get(pid=obj.root_createbuffer)
-            obj.root = rootEdgePort
-
-
-    # Method for handline post save semantics
-    #      content here would be model specific but could include handling Many-to-Many relationship
-    #      creation - which must occur post save
-    #
-    # obj     - Whatever obj was just saved
-    # returns - N/A - this is a pure invoke() call
-    #
-    def postsave(self, obj):
-        #
-        # Ok - we need to handle the multipoint many-to-many relationships in here
-        #
-        # By design convnetion we will look for them in the 'backend_register' object field
-        # this is a json field that is general purpose - we will expect to find a JSON array
-        # called 'eps' that just containts a reference to a bunch of NetworkEdgePorts
-        #
-        #
-        if hasattr(obj, 'eps_createbuffer'):
-            scratchpad = json.loads(obj.eps_createbuffer)
-            eps = scratchpad['eps']
-
-            for ep in eps:
-                port = NetworkEdgePort.objects.get(pid=ep)
-                obj.eps.add(port)
diff --git a/xos/synchronizer/invokers/networkmultipointtomultipointinvoker.py b/xos/synchronizer/invokers/networkmultipointtomultipointinvoker.py
deleted file mode 100644
index 6b2ab42..0000000
--- a/xos/synchronizer/invokers/networkmultipointtomultipointinvoker.py
+++ /dev/null
@@ -1,43 +0,0 @@
-import json
-from synchronizers.metronetwork.invokers.invoker import Invoker
-from services.metronetwork.models import NetworkMultipointToMultipointConnection, NetworkEdgePort
-
-class NetworkMultipointToMultipointInvoker(Invoker):
-
-    def __init__(self, **args):
-        pass
-
-    # Method for handline pre save semantics
-    #      content here would be model specific but could include handling Many-to-Many relationship
-    #      creation - which must occur post save
-    #
-    # obj     - Whatever obj was just saved
-    # returns - None - this is a pure invoke() call, return type is None
-    #
-    def presave(self, obj):
-        pass
-
-
-    # Method for handline post save semantics
-    #      content here would be model specific but could include handling Many-to-Many relationship
-    #      creation - which must occur post save
-    #
-    # obj     - Whatever obj was just saved
-    # returns - N/A - this is a pure invoke() call
-    #
-    def postsave(self, obj):
-        #
-        # Ok - we need to handle the multipoint many-to-many relationships in here
-        #
-        # By design convnetion we will look for them in the 'backend_register' object field
-        # this is a json field that is general purpose - we will expect to find a JSON array
-        # called 'eps' that just containts a reference to a bunch of NetworkEdgePorts
-        #
-        #
-        if hasattr(obj, 'eps_createbuffer'):
-            scratchpad = json.loads(obj.eps_createbuffer)
-            eps = scratchpad['eps']
-
-            for ep in eps:
-                port = NetworkEdgePort.objects.get(pid=ep)
-                obj.eps.add(port)
diff --git a/xos/synchronizer/invokers/remoteportinvoker.py b/xos/synchronizer/invokers/remoteportinvoker.py
deleted file mode 100644
index 1061dc4..0000000
--- a/xos/synchronizer/invokers/remoteportinvoker.py
+++ /dev/null
@@ -1,35 +0,0 @@
-import json
-from synchronizers.metronetwork.invokers.invoker import Invoker
-from core.models import Site
-from services.metronetwork.models import NetworkEdgePort
-
-class RemotePortInvoker(Invoker):
-    def __init__(self, **args):
-        pass
-
-    # Method for handline pre save semantics
-    #      content here would be model specific but could include handling Many-to-Many relationship
-    #      creation - which must occur post save
-    #
-    # obj     - Whatever obj was just saved
-    # returns - None - this is a pure invoke() call, return type is None
-    #
-    def presave(self, obj):
-        # Now that the Site and EdgePorts are created set the foreign keys
-        if hasattr(obj, 'sitename'):
-            site = Site.objects.get(login_base=obj.sitename)
-            obj.remoteportsite = site
-
-        if hasattr(obj, 'edgeportname'):
-            edgeport = NetworkEdgePort.objects.get(pid=obj.edgeportname)
-            obj.edgeport = edgeport
-
-    # Method for handline post save semantics
-    #      content here would be model specific but could include handling Many-to-Many relationship
-    #      creation - which must occur post save
-    #
-    # obj     - Whatever obj was just saved
-    # returns - N/A - this is a pure invoke() call
-    #
-    def postsave(self, obj):
-        pass
\ No newline at end of file
diff --git a/xos/synchronizer/invokers/servicespokeinvoker.py b/xos/synchronizer/invokers/servicespokeinvoker.py
deleted file mode 100644
index 8470cf5..0000000
--- a/xos/synchronizer/invokers/servicespokeinvoker.py
+++ /dev/null
@@ -1,37 +0,0 @@
-import json
-from synchronizers.metronetwork.invokers.invoker import Invoker
-from core.models import Site
-from services.metronetwork.models import RemotePort
-
-
-class ServiceSpokeInvoker(Invoker):
-    def __init__(self, **args):
-        pass
-
-    # Method for handline pre save semantics
-    #      content here would be model specific but could include handling Many-to-Many relationship
-    #      creation - which must occur post save
-    #
-    # obj     - Whatever obj was just saved
-    # returns - None - this is a pure invoke() call, return type is None
-    #
-    def presave(self, obj):
-        # Now that the Ports are created - get a proper reference to them and update the
-        # src and dst fields
-        if hasattr(obj, 'sitename'):
-            site = Site.objects.get(login_base=obj.sitename)
-            obj.vnodlocalsite = site
-
-        if hasattr(obj, 'remoteportname'):
-            remoteport = RemotePort.objects.get(name=obj.remoteportname)
-            obj.vnodlocalport = remoteport
-
-    # Method for handline post save semantics
-    #      content here would be model specific but could include handling Many-to-Many relationship
-    #      creation - which must occur post save
-    #
-    # obj     - Whatever obj was just saved
-    # returns - N/A - this is a pure invoke() call
-    #
-    def postsave(self, obj):
-        pass
\ No newline at end of file
diff --git a/xos/synchronizer/invokers/vnodglobalserviceinvoker.py b/xos/synchronizer/invokers/vnodglobalserviceinvoker.py
deleted file mode 100644
index a313171..0000000
--- a/xos/synchronizer/invokers/vnodglobalserviceinvoker.py
+++ /dev/null
@@ -1,50 +0,0 @@
-import json
-from synchronizers.metronetwork.invokers.invoker import Invoker
-from services.metronetwork.models import ServiceSpoke
-from services.metronetwork.models import BandwidthProfile
-from services.metronetwork.models import NetworkEdgeToEdgePointConnection
-
-class VnodGlobalServiceInvoker(Invoker):
-
-    def __init__(self, **args):
-        pass
-
-    # Method for handline pre save semantics
-    #      content here would be model specific but could include handling Many-to-Many relationship
-    #      creation - which must occur post save
-    #
-    # obj     - Whatever obj was just saved
-    # returns - None - this is a pure invoke() call, return type is None
-    #
-    def presave(self, obj):
-
-        if hasattr(obj, 'bwpname'):
-            bwprofile = BandwidthProfile.objects.get(name=obj.bwpname)
-            obj.bandwidthProfile = bwprofile
-
-        if hasattr(obj, 'pointtopointsid'):
-            connection = NetworkEdgeToEdgePointConnection.objects.get(sid=obj.pointtopointsid)
-            obj.metronetworkpointtopoint = connection
-
-    # Method for handline post save semantics
-    #      content here would be model specific but could include handling Many-to-Many relationship
-    #      creation - which must occur post save
-    #
-    # obj     - Whatever obj was just saved
-    # returns - N/A - this is a pure invoke() call
-    #
-    def postsave(self, obj):
-        #
-        # Ok - we need to handle the multipoint many-to-many relationships in here
-        #
-        # By design convnetion we will look for them in the 'backend_register' object field
-        # this is a json field that is general purpose - we will expect to find a JSON array
-        # called 'eps' that just containts a reference to a bunch of NetworkEdgePorts
-        #
-        if hasattr(obj, 'spokes_createbuffer'):
-            scratchpad = json.loads(obj.spokes_createbuffer)
-            spokes = scratchpad['spokes']
-
-            for spokeid in spokes:
-                spoke = ServiceSpoke.objects.get(name=spokeid)
-                obj.spokes.add(spoke)
diff --git a/xos/synchronizer/manifest b/xos/synchronizer/manifest
index 03f1088..4a4ccfe 100644
--- a/xos/synchronizer/manifest
+++ b/xos/synchronizer/manifest
@@ -1,23 +1,7 @@
 metronetwork-synchronizer.py
 __init__.py
 model-deps
-providers/metronetworktestprovider.py
-providers/metronetworkrestprovider.py
-providers/providerfactory.py
-providers/__init__.py
-providers/metronetworkprovider.py
-run_devel.sh
-metronetwork-synchronizer-devel.py
 manifest
-steps/sync_metronetworkservice.py
-invokers/servicespokeinvoker.py
-invokers/networkedgetoedgepointinvoker.py
-invokers/vnodglobalserviceinvoker.py
-invokers/networkmultipointtomultipointinvoker.py
-invokers/__init__.py
-invokers/invoker.py
-invokers/networkedgetomultipointinvoker.py
-invokers/invokerfactory.py
-invokers/remoteportinvoker.py
-run.sh
+steps/sync_metroneteline.py
+run-from-api.sh
 metronetwork_synchronizer_config
diff --git a/xos/synchronizer/metronetwork-synchronizer-devel.py b/xos/synchronizer/metronetwork-synchronizer-devel.py
deleted file mode 100755
index df697ec..0000000
--- a/xos/synchronizer/metronetwork-synchronizer-devel.py
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/usr/bin/env python
-
-# This imports and runs ../../xos-observer.py
-
-import importlib
-import os
-import sys
-
-#observer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../../synchronizers/base")
-sys.path.append("/opt/xos/synchronizers/base")
-print sys.path
-mod = importlib.import_module("xos-synchronizer")
-mod.main()
diff --git a/xos/synchronizer/providers/__init__.py b/xos/synchronizer/providers/__init__.py
deleted file mode 100644
index 8b13789..0000000
--- a/xos/synchronizer/providers/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/xos/synchronizer/providers/metronetworkprovider.py b/xos/synchronizer/providers/metronetworkprovider.py
deleted file mode 100644
index c316815..0000000
--- a/xos/synchronizer/providers/metronetworkprovider.py
+++ /dev/null
@@ -1,90 +0,0 @@
-from xos.logger import Logger, logging
-from services.metronetwork.models import *
-
-logger = Logger(level=logging.INFO)
-
-
-class MetroNetworkProvider(object):
-    networkdevice = None
-
-    def __init__(self, networkdevice, **args):
-        self.networkdevice = networkdevice
-        pass
-
-    # Methods to support for Synchronization - effectively list all interfaces
-    #
-    # Method for retrieving all network ports from the backend system
-    # Intended for use when doing a re-sync
-    def get_network_ports(self):
-        # Default method needs to be overriden
-        logger.debug("get_network_ports default called - should be overriden")
-
-    # Method for getting a list of network ports to delete
-    # The default imnplementation just gets a list from the local DB
-    # Intended for use when doing a re-sync
-    def get_network_ports_for_deletion(self):
-        # Default method needs to be overriden
-        logger.debug("get_network_ports for deletion called - default is all ports in the db related to this id")
-        objs = []
-        return objs
-
-    # Method for retrieving all network links from the backend system
-    # Includes Connectivity Objects
-    # Intended for use when doing a re-sync
-    def get_network_links(self):
-        # Default method needs to be overriden
-        logger.debug("get_network_links default called - should be overriden")
-        objs = []
-        return objs
-
-    # Method for getting a list of network links to delete
-    # Includes Connectivity Objects
-    # Intended for use when doing a re-sync
-    def get_network_links_for_deletion(self):
-        # Default method needs to be overriden
-        logger.debug("get_network_links for deletion called - should be overidden")
-        objs = []
-        return objs
-
-    # Methods to support Event Management - movement of changes from the Domain to XOS
-    #
-    # Method for Create and Update - Create and Update are together given the base design
-    def get_updated_or_created_objects(self):
-        # Default method needs to be overriden
-        logger.debug("get_updated_or_created_objects default called - should be overriden")
-        objs = []
-        return objs
-
-    # Method for Delete - Create and Update are together given the base design
-    def get_deleted_objects(self):
-        # Default method needs to be overriden
-        logger.debug("get_deleted_objects default called - should be overriden")
-        objs = []
-        return objs
-
-    # Methods to support Movement of changes from XOS into the Domain
-    #
-    # Method for creating point to point connectivity object
-    #
-    # obj     - Connection object - with all configuration variables set
-    # returns - Boolean - indicating whether or not the request succeeded - in either case the Admin/Oper
-    #                     states are assigned - if False the backend_status field
-    #                     should be assigned with the appropriate error code - in the case of True the
-    #                     backend_status will be assigned by the system and should be unassigned
-
-    def create_point_to_point_connectivity(self, obj):
-        # Default method needs to be overriden
-        logger.debug("create_point_to_point_connectivity called - should be overriden")
-        return False
-
-    # Method for deleting point to point connectivity object
-    #
-    # obj     - Connection object
-    # returns - Boolean - indicating whether or not the request succeeded - in either case the Admin/Oper
-    #                     states are assigned - if False the backend_status field
-    #                     should be assigned with the appropriate error code - in the case of True the
-    #                     backend_status will be assigned by the system and should be unassigned
-    def delete_point_to_point_connectivity(self, obj):
-        # Default method needs to be overriden
-        logger.debug("delete_point_to_point_connectivity called - should be overriden")
-        return False
diff --git a/xos/synchronizer/providers/metronetworkrestprovider.py b/xos/synchronizer/providers/metronetworkrestprovider.py
deleted file mode 100644
index 2cb03ab..0000000
--- a/xos/synchronizer/providers/metronetworkrestprovider.py
+++ /dev/null
@@ -1,472 +0,0 @@
-from xos.logger import Logger, logging

-from services.metronetwork.models import *

-from synchronizers.metronetwork.providers.metronetworkprovider import MetroNetworkProvider

-

-import requests, json

-from requests.auth import HTTPBasicAuth

-

-logger = Logger(level=logging.INFO)

-

-

-class MetroNetworkRestProvider(MetroNetworkProvider):

-    def __init__(self, networkdevice, **args):

-        MetroNetworkProvider.__init__(self, networkdevice, **args)

-

-    def get_network_ports(self):

-

-        objs = []

-

-        restCtrlUrl = self.networkdevice.restCtrlUrl

-        username = self.networkdevice.username

-        password = self.networkdevice.password

-

-        resp = requests.get("{}/mef-sca-api/SCA_ETH_FPP_UNI_N".format(restCtrlUrl),

-                            auth=HTTPBasicAuth(username, password))

-

-        if resp.status_code == 200:

-            for uni in resp.json():

-                hostname = uni['transportPort']['Hostname']

-                port = uni['transportPort']['Port']

-

-                # Default values

-                bwpCfgCbs = 0

-                bwpCfgEbs = 0

-                bwpCfgCir = 0

-                bwpCfgEir = 0

-

-                if 'interfaceCfgIngressBwp' in uni:

-                    bwpCfgCbs = uni['interfaceCfgIngressBwp']['bwpCfgCbs']

-                    bwpCfgEbs = uni['interfaceCfgIngressBwp']['bwpCfgEbs']

-                    bwpCfgCir = uni['interfaceCfgIngressBwp']['bwpCfgCir']

-                    bwpCfgEir = uni['interfaceCfgIngressBwp']['bwpCfgEir']

-

-                uniPort = NetworkEdgePort()

-                uniPort.element = self.networkdevice

-                uniPort.pid = "{}.{}/{}".format(self.networkdevice.id, hostname, port)

-                uniPort.bwpCfgCbs = bwpCfgCbs

-                uniPort.bwpCfgEbs = bwpCfgEbs

-                uniPort.bwpCfgCir = bwpCfgCir

-                uniPort.bwpCfgEir = bwpCfgEir

-

-                objs.append(uniPort)

-

-            return objs

-

-        else:

-            raise Exception("OnosApiError: get_network_ports()")

-

-    def get_network_ports(self):

-

-        objs = []

-

-        restCtrlUrl = self.networkdevice.restCtrlUrl

-        username = self.networkdevice.username

-        password = self.networkdevice.password

-

-        resp = requests.get("{}/mef-sca-api/SCA_ETH_FPP_UNI_N".format(restCtrlUrl),

-                            auth=HTTPBasicAuth(username, password))

-

-        if resp.status_code == 200:

-            for uni in resp.json():

-                hostname = uni['transportPort']['Hostname']

-                port = uni['transportPort']['Port']

-

-                # Default values

-                bwpCfgCbs = 0

-                bwpCfgEbs = 0

-                bwpCfgCir = 0

-                bwpCfgEir = 0

-

-                if 'interfaceCfgIngressBwp' in uni:

-                    bwpCfgCbs = uni['interfaceCfgIngressBwp']['bwpCfgCbs']

-                    bwpCfgEbs = uni['interfaceCfgIngressBwp']['bwpCfgEbs']

-                    bwpCfgCir = uni['interfaceCfgIngressBwp']['bwpCfgCir']

-                    bwpCfgEir = uni['interfaceCfgIngressBwp']['bwpCfgEir']

-

-                uniPort = NetworkEdgePort()

-                uniPort.element = self.networkdevice

-                uniPort.pid = "{}.{}/{}".format(self.networkdevice.id, hostname, port)

-                uniPort.bwpCfgCbs = bwpCfgCbs

-                uniPort.bwpCfgEbs = bwpCfgEbs

-                uniPort.bwpCfgCir = bwpCfgCir

-                uniPort.bwpCfgEir = bwpCfgEir

-

-                objs.append(uniPort)

-

-            return objs

-

-        else:

-            raise Exception("OnosApiError: get_network_ports()")

-

-    def get_network_eline_link(self, networkDevice, evc):

-

-        sid = evc['id']

-        uni1 = evc['SCA_ETH_Flow_Points'][0]

-        hostname = uni1['scaEthFppUniN']['transportPort']['Hostname']

-        port = uni1['scaEthFppUniN']['transportPort']['Port']

-

-        edgePort1 = NetworkEdgePort()

-        edgePort1.element = networkDevice

-        edgePort1.pid = "{}.{}/{}".format(networkDevice.id, hostname, port)

-

-        if 'interfaceCfgIngressBwp' in uni1['scaEthFppUniN']:

-            edgePort1.bwpCfgCbs = uni1['scaEthFppUniN']['interfaceCfgIngressBwp']['bwpCfgCbs']

-            edgePort1.bwpCfgEbs = uni1['scaEthFppUniN']['interfaceCfgIngressBwp']['bwpCfgEbs']

-            edgePort1.bwpCfgCir = uni1['scaEthFppUniN']['interfaceCfgIngressBwp']['bwpCfgCir']

-            edgePort1.bwpCfgEir = uni1['scaEthFppUniN']['interfaceCfgIngressBwp']['bwpCfgEir']

-

-        uni2 = evc['SCA_ETH_Flow_Points'][1]

-        hostname = uni2['scaEthFppUniN']['transportPort']['Hostname']

-        port = uni2['scaEthFppUniN']['transportPort']['Port']

-

-        edgePort2 = NetworkEdgePort()

-        edgePort2.element = networkDevice

-        edgePort2.pid = "{}.{}/{}".format(networkDevice.id, hostname, port)

-

-        if 'interfaceCfgIngressBwp' in uni1['scaEthFppUniN']:

-            edgePort2.bwpCfgCbs = uni2['scaEthFppUniN']['interfaceCfgIngressBwp']['bwpCfgCbs']

-            edgePort2.bwpCfgEbs = uni2['scaEthFppUniN']['interfaceCfgIngressBwp']['bwpCfgEbs']

-            edgePort2.bwpCfgCir = uni2['scaEthFppUniN']['interfaceCfgIngressBwp']['bwpCfgCir']

-            edgePort2.bwpCfgEir = uni2['scaEthFppUniN']['interfaceCfgIngressBwp']['bwpCfgEir']

-

-        edgeToEdgeConnectivity = NetworkEdgeToEdgePointConnection()

-        edgeToEdgeConnectivity.sid = sid

-        edgeToEdgeConnectivity.type = "Point_To_Point"

-        edgeToEdgeConnectivity.uni1 = edgePort1

-        edgeToEdgeConnectivity.uni2 = edgePort2

-        edgeToEdgeConnectivity.operstate = "active"

-        edgeToEdgeConnectivity.adminstate = "enabled"

-

-        return(edgeToEdgeConnectivity)

-

-    def get_network_elan_link(self, networkDevice, evc):

-

-        sid = evc['id']

-        eps = []

-

-        for ep in evc['SCA_ETH_Flow_Points']:

-            hostname = ep['scaEthFppUniN']['transportPort']['Hostname']

-            port = ep['scaEthFppUniN']['transportPort']['Port']

-

-            edgePort = NetworkEdgePort()

-            edgePort.element = networkDevice

-            edgePort.pid = "{}.{}/{}".format(networkDevice.id, hostname, port)

-

-            if 'interfaceCfgIngressBwp' in ep['scaEthFppUniN']:

-                edgePort.bwpCfgCbs = ep['scaEthFppUniN']['interfaceCfgIngressBwp']['bwpCfgCbs']

-                edgePort.bwpCfgEbs = ep['scaEthFppUniN']['interfaceCfgIngressBwp']['bwpCfgEbs']

-                edgePort.bwpCfgCir = ep['scaEthFppUniN']['interfaceCfgIngressBwp']['bwpCfgCir']

-                edgePort.bwpCfgEir = ep['scaEthFppUniN']['interfaceCfgIngressBwp']['bwpCfgEir']

-

-            eps.append(edgePort)

-

-        multipointToMultipointConnectivity = NetworkMultipointToMultipointConnection()

-        multipointToMultipointConnectivity.sid = sid

-        multipointToMultipointConnectivity.type = "Multipoint_To_Multipoint"

-        multipointToMultipointConnectivity.eps = eps

-        multipointToMultipointConnectivity.operstate = "active"

-        multipointToMultipointConnectivity.adminstate = "enabled"

-

-        return(multipointToMultipointConnectivity)

-

-    def get_network_etree_link(self, networkDevice, evc):

-

-        sid = evc['id']

-        eps = []

-

-        root = evc['SCA_ETH_Flow_Points'][0]

-        hostname = root['scaEthFppUniN']['transportPort']['Hostname']

-        port = root['scaEthFppUniN']['transportPort']['Port']

-

-        edgePort = NetworkEdgePort()

-        edgePort.element = networkDevice

-        edgePort.pid = "{}.{}/{}".format(networkDevice.id, hostname, port)

-

-        if 'interfaceCfgIngressBwp' in root['scaEthFppUniN']:

-            edgePort.bwpCfgCbs = root['scaEthFppUniN']['interfaceCfgIngressBwp']['bwpCfgCbs']

-            edgePort.bwpCfgEbs = root['scaEthFppUniN']['interfaceCfgIngressBwp']['bwpCfgEbs']

-            edgePort.bwpCfgCir = root['scaEthFppUniN']['interfaceCfgIngressBwp']['bwpCfgCir']

-            edgePort.bwpCfgEir = root['scaEthFppUniN']['interfaceCfgIngressBwp']['bwpCfgEir']

-

-        edgeToMultipointConnectivity = NetworkEdgeToMultipointConnection()

-        edgeToMultipointConnectivity.sid = sid

-        edgeToMultipointConnectivity.type = "Root_Multipoint"

-        edgeToMultipointConnectivity.root = edgePort

-

-        for ep in evc['SCA_ETH_Flow_Points'][1:]:

-            hostname = ep['scaEthFppUniN']['transportPort']['Hostname']

-            port = ep['scaEthFppUniN']['transportPort']['Port']

-

-            edgePort = NetworkEdgePort()

-            edgePort.element = networkDevice

-            edgePort.pid = "{}.{}/{}".format(networkDevice.id, hostname, port)

-

-            if 'interfaceCfgIngressBwp' in ep['scaEthFppUniN']:

-                edgePort.bwpCfgCbs = ep['scaEthFppUniN']['interfaceCfgIngressBwp']['bwpCfgCbs']

-                edgePort.bwpCfgEbs = ep['scaEthFppUniN']['interfaceCfgIngressBwp']['bwpCfgEbs']

-                edgePort.bwpCfgCir = ep['scaEthFppUniN']['interfaceCfgIngressBwp']['bwpCfgCir']

-                edgePort.bwpCfgEir = ep['scaEthFppUniN']['interfaceCfgIngressBwp']['bwpCfgEir']

-

-            eps.append(edgePort)

-

-        edgeToMultipointConnectivity.eps = eps

-        edgeToMultipointConnectivity.operstate = "active"

-        edgeToMultipointConnectivity.adminstate = "enabled"

-

-        return(edgeToMultipointConnectivity)

-

-    def get_network_links(self):

-

-        objs = []

-

-        networkDevice = self.networkdevice

-        restCtrlUrl = self.networkdevice.restCtrlUrl

-        username = self.networkdevice.username

-        password = self.networkdevice.password

-

-        resp = requests.get("{}/mef-sca-api/SCA_ETH_FDFr_EC/findByState?state=Active".format(restCtrlUrl),

-                            auth=HTTPBasicAuth(username, password))

-

-        if resp.status_code == 200:

-            for evc in resp.json():

-                evcServiceType = evc['evcServiceType']

-                if (evcServiceType == "Point_To_Point"):

-                    objs.append(self.get_network_eline_link(networkDevice, evc))

-                elif (evcServiceType == "Multipoint_To_Multipoint"):

-                    objs.append(self.get_network_elan_link(networkDevice, evc))

-                elif (evcServiceType == "Root_Multipoint"):

-                    objs.append(self.get_network_etree_link(networkDevice, evc))

-                else:

-                    raise Exception("OnosApiError: get_network_links() - unknown link type")

-        else:

-            raise Exception("OnosApiError: get_network_links()")

-

-        return objs

-

-    def create_point_to_point_connectivity_json_data(self, obj):

-

-        p2p_json_data = {}

-        p2p_json_data["evcServiceType"] = "Point_To_Point"

-

-        uni1 = obj.uni1

-        uni1Id = uni1.pid

-        uni1IdToken = (uni1Id.split('.', 1))[1].split('/', 1)

-        uni1Hostname = uni1IdToken[0]

-        uni1Port = uni1IdToken[1]

-        uni1BwpCfgCbs = uni1.bwpCfgCbs

-        uni1BwpCfgEbs = uni1.bwpCfgEbs

-        uni1BwpCfgCir = uni1.bwpCfgCir

-        uni1BwpCfgEir = uni1.bwpCfgEir

-

-        uni1_json_data = {}

-        uni1_json_data['scaEthFppUniN'] = {}

-        uni1_json_data['scaEthFppUniN']['ceVlanId'] = obj.vlanid

-        uni1_json_data['scaEthFppUniN']["transportPort"] = {}

-        uni1_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"] = {}

-

-        uni1_json_data['scaEthFppUniN']["transportPort"]["Hostname"] = uni1Hostname

-        uni1_json_data['scaEthFppUniN']["transportPort"]["Port"] = uni1Port

-        uni1_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"]["bwpCfgCbs"] = uni1BwpCfgCbs

-        uni1_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"]["bwpCfgEbs"] = uni1BwpCfgEbs

-        uni1_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"]["bwpCfgCir"] = uni1BwpCfgCir

-        uni1_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"]["bwpCfgEir"] = uni1BwpCfgEir

-

-        uni2 = obj.uni2

-        uni2Id = uni2.pid

-        uni2IdToken = (uni2Id.split('.', 1))[1].split('/', 1)

-        uni2Hostname = uni2IdToken[0]

-        uni2Port = uni2IdToken[1]

-        uni2BwpCfgCbs = uni2.bwpCfgCbs

-        uni2BwpCfgEbs = uni2.bwpCfgEbs

-        uni2BwpCfgCir = uni2.bwpCfgCir

-        uni2BwpCfgEir = uni2.bwpCfgEir

-

-        uni2_json_data = {}

-        uni2_json_data['scaEthFppUniN'] = {}

-        uni2_json_data['scaEthFppUniN']['ceVlanId'] = obj.vlanid

-        uni2_json_data['scaEthFppUniN']["transportPort"] = {}

-        uni2_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"] = {}

-

-        uni2_json_data['scaEthFppUniN']["transportPort"]["Hostname"] = uni2Hostname

-        uni2_json_data['scaEthFppUniN']["transportPort"]["Port"] = uni2Port

-        uni2_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"]["bwpCfgCbs"] = uni2BwpCfgCbs

-        uni2_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"]["bwpCfgEbs"] = uni2BwpCfgEbs

-        uni2_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"]["bwpCfgCir"] = uni2BwpCfgCir

-        uni2_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"]["bwpCfgEir"] = uni2BwpCfgEir

-

-        p2p_json_data["SCA_ETH_Flow_Points"] = []

-        p2p_json_data["SCA_ETH_Flow_Points"].append(uni1_json_data)

-        p2p_json_data["SCA_ETH_Flow_Points"].append(uni2_json_data)

-

-        return p2p_json_data

-

-    # nchoi: create elan service json data

-    def create_multipoint_to_multipoint_connectivity_json_data(self, obj):

-

-        mp2mp_json_data = {}

-        mp2mp_json_data["evcServiceType"] = "Multipoint_To_Multipoint"

-        mp2mp_json_data["SCA_ETH_Flow_Points"] = []

-

-        for ep in obj.eps.all():

-            uniId = ep.pid

-            uniIdToken = (uniId.split('.', 1))[1].split('/', 1)

-            uniHostname = uniIdToken[0]

-            uniPort = uniIdToken[1]

-            uniBwpCfgCbs = ep.bwpCfgCbs

-            uniBwpCfgEbs = ep.bwpCfgEbs

-            uniBwpCfgCir = ep.bwpCfgCir

-            uniBwpCfgEir = ep.bwpCfgEir

-

-            uni_json_data = {}

-            uni_json_data['scaEthFppUniN'] = {}

-            uni_json_data['scaEthFppUniN']['ceVlanId'] = obj.vlanid

-            uni_json_data['scaEthFppUniN']["transportPort"] = {}

-            uni_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"] = {}

-

-            uni_json_data['scaEthFppUniN']["transportPort"]["Hostname"] = uniHostname

-            uni_json_data['scaEthFppUniN']["transportPort"]["Port"] = uniPort

-            uni_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"]["bwpCfgCbs"] = uniBwpCfgCbs

-            uni_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"]["bwpCfgEbs"] = uniBwpCfgEbs

-            uni_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"]["bwpCfgCir"] = uniBwpCfgCir

-            uni_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"]["bwpCfgEir"] = uniBwpCfgEir

-

-            mp2mp_json_data["SCA_ETH_Flow_Points"].append(uni_json_data)

-

-        return mp2mp_json_data

-

-    # nchoi: create etree service json data

-    def create_root_multipoint_connectivity_json_data(self, obj):

-

-        r2mp_json_data = {}

-        r2mp_json_data["evcServiceType"] = "Root_Multipoint"

-        r2mp_json_data["SCA_ETH_Flow_Points"] = []

-

-        root = obj.root

-        uniId = root.pid

-        uniIdToken = (uniId.split('.', 1))[1].split('/', 1)

-        uniHostname = uniIdToken[0]

-        uniPort = uniIdToken[1]

-        uniBwpCfgCbs = root.bwpCfgCbs

-        uniBwpCfgEbs = root.bwpCfgEbs

-        uniBwpCfgCir = root.bwpCfgCir

-        uniBwpCfgEir = root.bwpCfgEir

-

-        uni_json_data = {}

-        uni_json_data['scaEthFppUniN'] = {}

-        uni_json_data['scaEthFppUniN']['ceVlanId'] = obj.vlanid

-        uni_json_data['scaEthFppUniN']["transportPort"] = {}

-        uni_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"] = {}

-

-        uni_json_data['scaEthFppUniN']["transportPort"]["Hostname"] = uniHostname

-        uni_json_data['scaEthFppUniN']["transportPort"]["Port"] = uniPort

-        uni_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"]["bwpCfgCbs"] = uniBwpCfgCbs

-        uni_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"]["bwpCfgEbs"] = uniBwpCfgEbs

-        uni_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"]["bwpCfgCir"] = uniBwpCfgCir

-        uni_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"]["bwpCfgEir"] = uniBwpCfgEir

-

-        r2mp_json_data["SCA_ETH_Flow_Points"].append(uni_json_data)

-

-        for ep in obj.eps.all():

-            uniId = ep.pid

-            uniIdToken = (uniId.split('.', 1))[1].split('/', 1)

-            uniHostname = uniIdToken[0]

-            uniPort = uniIdToken[1]

-            uniBwpCfgCbs = ep.bwpCfgCbs

-            uniBwpCfgEbs = ep.bwpCfgEbs

-            uniBwpCfgCir = ep.bwpCfgCir

-            uniBwpCfgEir = ep.bwpCfgEir

-

-            uni_json_data = {}

-            uni_json_data['scaEthFppUniN'] = {}

-            uni_json_data['scaEthFppUniN']['ceVlanId'] = obj.vlanid

-            uni_json_data['scaEthFppUniN']["transportPort"] = {}

-            uni_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"] = {}

-

-            uni_json_data['scaEthFppUniN']["transportPort"]["Hostname"] = uniHostname

-            uni_json_data['scaEthFppUniN']["transportPort"]["Port"] = uniPort

-            uni_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"]["bwpCfgCbs"] = uniBwpCfgCbs

-            uni_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"]["bwpCfgEbs"] = uniBwpCfgEbs

-            uni_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"]["bwpCfgCir"] = uniBwpCfgCir

-            uni_json_data['scaEthFppUniN']["interfaceCfgIngressBwp"]["bwpCfgEir"] = uniBwpCfgEir

-

-            r2mp_json_data["SCA_ETH_Flow_Points"].append(uni_json_data)

-

-        return r2mp_json_data

-

-    def create_network_connectivity(self, obj):

-

-        restCtrlUrl = self.networkdevice.restCtrlUrl

-        username = self.networkdevice.username

-        password = self.networkdevice.password

-

-        evcServiceType = obj.type

-        if (evcServiceType == "Point_To_Point"):

-            network_connectivity_json_data = self.create_point_to_point_connectivity_json_data(obj)

-        elif (evcServiceType == "Multipoint_To_Multipoint"):

-            network_connectivity_json_data = self.create_multipoint_to_multipoint_connectivity_json_data(obj)

-        elif (evcServiceType == "Root_Multipoint"):

-            network_connectivity_json_data = self.create_root_multipoint_connectivity_json_data(obj)

-        else:

-            raise Exception("OnosApiError: get_network_links() - unknown link type")

-

-        headers = {'Content-Type': 'application/json'}

-        resp = requests.post('{}/mef-sca-api/SCA_ETH_FDFr_EC'.format(restCtrlUrl),

-                             data=json.dumps(network_connectivity_json_data), headers=headers, auth=HTTPBasicAuth(username, password))

-

-        if resp.status_code == 201:

-            result = resp.json()

-            message = result['message']

-

-            msg_token = message.split()

-            for i, token in enumerate(msg_token):

-                if token == 'id':

-                    service_id = msg_token[i + 1]

-                    obj.sid = service_id

-                    obj.adminstate = "enabled"

-                    obj.operstate = "active"

-

-                    return True

-

-        elif resp.status_code == 204:

-            obj.adminstate = "invalid"  # what's the meaning?

-            obj.operstate = "inactive"

-            obj.backend_status = '204 - No network resource'

-

-            return False

-

-        elif resp.status_code == 500:

-            obj.adminstate = "enabled"

-            obj.operstate = "inactive"

-            obj.backend_status = '500 - Internal Server Error'

-            return False

-

-        else:

-            raise Exception("OnosApiError: create_network_connectivity()")

-

-    def delete_network_connectivity(self, obj):

-

-        restCtrlUrl = self.networkdevice.restCtrlUrl

-        username = self.networkdevice.username

-        password = self.networkdevice.password

-        evcId = obj.sid

-

-        resp = requests.delete("{}/mef-sca-api/SCA_ETH_FDFr_EC/{}".format(restCtrlUrl, evcId),

-                               auth=HTTPBasicAuth(username, password))

-

-        if resp.status_code == 200:

-            obj.adminstate = 'disabled'

-            obj.operstate = 'inactive'

-            return True

-

-        elif resp.status_code == 204:

-            obj.adminstate = "invalid"  # what's the meaning?

-            obj.backend_status = '204 - No such network resource: {}'.format(evcId)

-            return False

-

-        elif resp.status_code == 500:

-            obj.adminstate = "disabled"

-            obj.backend_status = '500 - Internal Server Error'

-            return False

-

-        else:

-            raise Exception("OnosApiError: delete_network_connectivity()")

diff --git a/xos/synchronizer/providers/metronetworktestprovider.py b/xos/synchronizer/providers/metronetworktestprovider.py
deleted file mode 100644
index 3bcbb92..0000000
--- a/xos/synchronizer/providers/metronetworktestprovider.py
+++ /dev/null
@@ -1,339 +0,0 @@
-import random
-import json
-
-from xos.logger import Logger, logging
-from services.metronetwork.models import *
-from core.models import Site
-from synchronizers.metronetwork.providers.metronetworkprovider import MetroNetworkProvider
-
-logger = Logger(level=logging.INFO)
-
-
-class MetroNetworkTestProvider(MetroNetworkProvider):
-    def __init__(self, networkdevice, **args):
-        MetroNetworkProvider.__init__(self, networkdevice, **args)
-
-    # Method for retrieving all network ports from the backend system
-    def get_network_ports(self):
-        #
-        # Our Test Network Consists of one NetworkDevice (which correspond to ONOS instance):
-        #
-        #  8 Ports
-        #  1 Eline (2 ports)
-        #  1 Etree (3 ports)
-        #  1 Elan (3 ports)
-        #
-        #  2 Sites - Representing Two R-CORD Pods
-        #  2 Ports, One-per-site
-        #  1 Bandwidth Profile
-        #  2 Service Spokes
-        #  1 VnodGlobalService
-
-        objs = []
-
-        # For The Test Provider we don't handle re-sync for anything but the Metro Test Network
-        if self.networkdevice.id != 'TestMetroNet':
-            return objs
-
-        # Set the parent device id to just be the Test NetworkDevice
-        device1 = NetworkDevice()
-        device1.id = self.networkdevice.id
-
-        port1 = NetworkEdgePort()
-        port1.element = device1
-        port1.pid = device1.id + "." + "of:000000001/1"
-        port1.bwpCfgCbs = 1000000
-        port1.bwpCfgEbs = 1000000
-        port1.bwpCfgEir = 1000000
-        port1.bwpCfgCir = 1000000
-        port1.location = "San Francisco"
-        port1.name = "Central Office 1"
-        port1.latlng = "[-122.419416, 37.774929]"
-        objs.append(port1)
-
-        port2 = NetworkEdgePort()
-        port2.element = device1
-        port2.pid = device1.id + "." + "of:000000001/2"
-        port2.bwpCfgCbs = 1000000
-        port2.bwpCfgEbs = 1000000
-        port2.bwpCfgEir = 1000000
-        port2.bwpCfgCir = 1000000
-        port2.location = "San Jose"
-        port2.name = "Central Office 2"
-        port2.latlng = "[-121.886329, 37.338208]"
-        objs.append(port2)
-
-        port3 = NetworkEdgePort()
-        port3.element = device1
-        port3.pid = device1.id + "." + "of:000000001/3"
-        port3.bwpCfgCbs = 1000000
-        port3.bwpCfgEbs = 1000000
-        port3.bwpCfgEir = 1000000
-        port3.bwpCfgCir = 1000000
-        port3.location = "Palo Alto"
-        port3.name = "Central Office 3"
-        port3.latlng = "[-122.143019, 37.441883]"
-        objs.append(port3)
-
-        port4 = NetworkEdgePort()
-        port4.element = device1
-        port4.pid = device1.id + "." + "of:000000001/4"
-        port4.bwpCfgCbs = 1000000
-        port4.bwpCfgEbs = 1000000
-        port4.bwpCfgEir = 1000000
-        port4.bwpCfgCir = 1000000
-        port4.location = "Oakland"
-        port4.name = "Central Office 4"
-        port4.latlng = "[-122.271114, 37.804364]"
-        objs.append(port4)
-
-        port5 = NetworkEdgePort()
-        port5.element = device1
-        port5.pid = device1.id + "." + "of:000000001/5"
-        port5.bwpCfgCbs = 1000000
-        port5.bwpCfgEbs = 1000000
-        port5.bwpCfgEir = 1000000
-        port5.bwpCfgCir = 1000000
-        port5.location = "San Rafael"
-        port5.name = "Central Office 5"
-        port5.latlng = "[-122.531087, 37.973535]"
-        objs.append(port5)
-
-        port6 = NetworkEdgePort()
-        port6.element = device1
-        port6.pid = device1.id + "." + "of:000000001/6"
-        port6.bwpCfgCbs = 1000000
-        port6.bwpCfgEbs = 1000000
-        port6.bwpCfgEir = 1000000
-        port6.bwpCfgCir = 1000000
-        port6.location = "San Mateo"
-        port6.name = "Central Office 6"
-        port6.latlng = "[-122.325525, 37.562992]"
-        objs.append(port6)
-
-        port7 = NetworkEdgePort()
-        port7.element = device1
-        port7.pid = device1.id + "." + "of:000000001/7"
-        port7.bwpCfgCbs = 1000000
-        port7.bwpCfgEbs = 1000000
-        port7.bwpCfgEir = 1000000
-        port7.bwpCfgCir = 1000000
-        port7.location = "Hayward"
-        port7.name = "Central Office 7"
-        port7.latlng = "[-122.080796, 37.668821]"
-        objs.append(port7)
-
-        port8 = NetworkEdgePort()
-        port8.element = device1
-        port8.pid = device1.id + "." + "of:000000001/8"
-        port8.bwpCfgCbs = 1000000
-        port8.bwpCfgEbs = 1000000
-        port8.bwpCfgEir = 1000000
-        port8.bwpCfgCir = 1000000
-        port8.location = "Fremont"
-        port8.name = "Central Office 8"
-        port8.latlng = "[-121.988572, 37.548270]"
-        objs.append(port8)
-
-        return objs
-
-    def get_network_ports_for_deletion(self):
-
-        objs = []
-
-        # For The Test Provider we don't handle re-sync for anything but the Metro Test Network
-        if self.networkdevice.id != 'TestMetroNet':
-            return objs
-
-        allports = MetroNetworkProvider.get_network_ports_for_deletion(self)
-
-        for port in allports:
-            objs.append(port)
-
-        return objs
-
-    def get_network_links(self):
-
-        objs = []
-
-        # Connectivity object - Point to Point
-        cordpod1device = NetworkDevice()
-        cordpod1device.id = self.networkdevice.id
-
-        # Edge to Edge Point Connectivity Objects
-        edgetoedgeconnectivity = NetworkEdgeToEdgePointConnection()
-        edgetoedgeconnectivity.uni1_createbuffer = cordpod1device.id + "." + "of:000000001/1"
-        edgetoedgeconnectivity.uni2_createbuffer = cordpod1device.id + "." + "of:000000001/2"
-        edgetoedgeconnectivity.type = 'direct'
-        edgetoedgeconnectivity.operstate = 'active'
-        edgetoedgeconnectivity.adminstate = 'enabled'
-        edgetoedgeconnectivity.sid = 'EdgeToEdgePointConnectivity_1'
-        objs.append(edgetoedgeconnectivity)
-
-
-        # Multipoint to Multipoint Connectivity Objects
-        multipoint2multipointconnectivity=NetworkMultipointToMultipointConnection()
-        multipoint2multipointconnectivity.operstate = 'active'
-        multipoint2multipointconnectivity.adminstate = 'enabled'
-        multipoint2multipointconnectivity.type = 'ethernet'
-        multipoint2multipointconnectivity.sid = 'MultipointToMultipointConnectivity_1'
-
-        #
-        # Create JSON array for post-save behaviour
-        #
-        eps = []
-        eps.append(cordpod1device.id + "." + "of:000000001/3")
-        eps.append(cordpod1device.id + "." + "of:000000001/4")
-        eps.append(cordpod1device.id + "." + "of:000000001/5")
-
-        myjsonstr = {'eps': eps, 'foo':0, 'bar':0}
-        multipoint2multipointconnectivity.eps_createbuffer = json.dumps(myjsonstr)
-        objs.append(multipoint2multipointconnectivity)
-
-        # Edge to Multipoint Connectivity Objects
-        edge2multipointconnectivity = NetworkEdgeToMultipointConnection()
-        edge2multipointconnectivity.operstate = 'active'
-        edge2multipointconnectivity.adminstate = 'enabled'
-        edge2multipointconnectivity.type = 'ethernet'
-        edge2multipointconnectivity.sid = 'EdgeToMultipointConnectivity_1'
-        edge2multipointconnectivity.root_createbuffer = cordpod1device.id + "." + "of:000000001/7"
-        #
-        # Create JSON array for post-save behaviour
-        #
-        eps = []
-        eps.append(cordpod1device.id + "." + "of:000000001/6")
-        eps.append(cordpod1device.id + "." + "of:000000001/8")
-
-        myjsonstr = {'eps': eps, 'foo': 0, 'bar': 0}
-        edge2multipointconnectivity.eps_createbuffer = json.dumps(myjsonstr)
-        objs.append(edge2multipointconnectivity)
-
-        # Create Objects for VnodGlobal Sort of Testing
-
-        # Bandwidth Profile
-
-        bwprofile = BandwidthProfile()
-        bwprofile.bwpcfgcbs  = 0
-        bwprofile.bwpcfgcir = 0
-        bwprofile.bwpcfgebs = 0
-        bwprofile.bwpcfgeir = 0
-        bwprofile.name = 'TestBWP'
-        objs.append(bwprofile)
-
-        # Two Sites
-        site1 = Site()
-        site1.name = 'CORDPod1'
-        site1.login_base = 'CordPod1'
-        site1.site_url = 'http://1.2.3.4:8080/VnodLocalApi'
-        objs.append(site1)
-
-        site2 = Site()
-        site2.name = 'CORDPod2'
-        site2.login_base = 'CordPod2'
-        site2.site_url = 'http://10.11.12.13:8080/VnodLocalApi'
-        objs.append(site2)
-
-        # Two Ports - one per Site
-
-        remoteport1 = RemotePort()
-        remoteport1.name = "CORDPOD1:Port1"
-        remoteport1.sitename = 'CordPod1'
-        remoteport1.edgeportname = cordpod1device.id + "." + "of:000000001/1"
-        objs.append(remoteport1)
-
-        remoteport2 = RemotePort()
-        remoteport2.name = "CORDPOD2:Port1"
-        remoteport2.sitename = 'CordPod2'
-        remoteport2.edgeportname = cordpod1device.id + "." + "of:000000001/2"
-        objs.append(remoteport2)
-
-        # One Spoke/Site
-        spoke1 = ServiceSpoke()
-        spoke1.name = 'TestSpoke1'
-        spoke1.remoteportname = "CORDPOD1:Port1"
-        spoke1.remotevnodid = 'CORDPod1:VnodLocal:1'
-        spoke1.operstate = 'inactive'
-        spoke1.adminstate = 'enabled'
-        spoke1.sitename = 'CordPod1'
-        objs.append(spoke1)
-
-        spoke2 = ServiceSpoke()
-        spoke2.name = 'TestSpoke2'
-        spoke2.remoteportname = "CORDPOD2:Port1"
-        spoke2.remotevnodid = 'CORDPod2:VnodLocal:1'
-        spoke2.operstate = 'active'
-        spoke2.adminstate = 'enabled'
-        spoke2.sitename = 'CordPod2'
-        objs.append(spoke2)
-
-        # One VnodGlobal Service
-        vnodglobal = VnodGlobalService()
-        vnodglobal.name = 'VnodGlobalPtToPtTest1'
-        vnodglobal.type = 'eline'
-        vnodglobal.vlanid = '100'
-        vnodglobal.operstate = 'active'
-        vnodglobal.adminstate = 'enabled'
-        vnodglobal.servicehandle = 'testhandle1'
-        vnodglobal.pointtopointsid = 'onos_eline_id'
-        vnodglobal.bwpname = 'TestBWP'
-
-        # Create JSON array for post-save behaviour
-        #
-        spokes = ['TestSpoke1', 'TestSpoke2']
-        myjsonstr = {'spokes': spokes}
-        vnodglobal.spokes_createbuffer = json.dumps(myjsonstr)
-        objs.append(vnodglobal)
-
-        return objs
-
-    def get_network_links_for_deletion(self):
-
-        # For now we'll rely on cascade deletes in the port area - so from the test provider nothing to do
-        objs = []
-        return objs
-
-    def create_point_to_point_connectivity(self, obj):
-
-        # Ok - here is what we'll do to simulate the 'real world' - get a random number between 1 and 10
-        # 1-7 is considered 'successful' 8 is considered a transient error - 9 is a configuration problem
-        # 10 is a - resource exhausted problem - there you go!!
-        scenario = random.randint(1, 10)
-
-        if (scenario >= 1 and scenario <= 7):
-            obj.adminstate = 'enabled'
-            obj.operstate = 'active'
-            return True
-        elif (scenario == 8):
-            obj.adminstate = 'enabled'
-            obj.operstate = 'inactive'
-            obj.backend_status = '8 - Transient Server Error'
-            return False
-        elif (scenario == 9):
-            obj.adminstate = 'invalid'
-            obj.operstate = 'inactive'
-            obj.backend_status = '9 - Configuration Error'
-            return False
-        else:
-            obj.adminstate = 'enabled'
-            obj.operstate = 'inactive'
-            obj.backend_status = '10 - Resource Exhaustion'
-            return False
-
-    def delete_point_to_point_connectivity(self, obj):
-
-        # Ok - here is what we'll do to simulate the 'real world' - get a random number between 1 and 10
-        # 1-8 is considered 'successful' 8 is considered a transient error - 9 is a configuration problem
-        scenario = random.randint(1, 10)
-
-        if (scenario >= 1 and scenario <= 8):
-            obj.adminstate = 'disabled'
-            obj.operstate = 'inactive'
-            return True
-        elif (scenario == 9):
-            obj.adminstate = 'disabled'
-            obj.backend_status = '8 - Transient Server Error'
-            return False
-        else:
-            obj.adminstate = 'invalid'
-            obj.backend_status = '9 - Configuration Error'
-            return False
diff --git a/xos/synchronizer/providers/providerfactory.py b/xos/synchronizer/providers/providerfactory.py
deleted file mode 100644
index 9ef6cb8..0000000
--- a/xos/synchronizer/providers/providerfactory.py
+++ /dev/null
@@ -1,21 +0,0 @@
-import sys
-
-from synchronizers.metronetwork.providers.metronetworktestprovider import MetroNetworkTestProvider
-from synchronizers.metronetwork.providers.metronetworkrestprovider import MetroNetworkRestProvider
-
-
-class ProviderFactory(object):
-    @staticmethod
-    def getprovider(networkdevice):
-
-        undertest = False
-
-        # We either return Test or Rest
-        # By convention a NetworkDevice with name TestDomain will use test objects
-        if networkdevice.id == 'TestMetroNet' or networkdevice.id == 'TestCORD1Net' or networkdevice.id == 'TestCORD2Net':
-            undertest = True
-
-        if undertest:
-            return MetroNetworkTestProvider(networkdevice)
-        else:
-            return MetroNetworkRestProvider(networkdevice)
diff --git a/xos/synchronizer/run-from-api.sh b/xos/synchronizer/run-from-api.sh
old mode 100644
new mode 100755
index 95ba5dd..73f5eec
--- a/xos/synchronizer/run-from-api.sh
+++ b/xos/synchronizer/run-from-api.sh
@@ -1,2 +1,3 @@
+#!/usr/bin/env bash
 export XOS_DIR=/opt/xos
 python metronetwork-synchronizer.py  -C $XOS_DIR/synchronizers/metro-net/metronetwork_from_api_config
\ No newline at end of file
diff --git a/xos/synchronizer/invokers/__init__.py b/xos/synchronizer/steps/__init__.py
similarity index 100%
rename from xos/synchronizer/invokers/__init__.py
rename to xos/synchronizer/steps/__init__.py
diff --git a/xos/synchronizer/steps/sync_metroneteline.py b/xos/synchronizer/steps/sync_metroneteline.py
new file mode 100644
index 0000000..bd0bfef
--- /dev/null
+++ b/xos/synchronizer/steps/sync_metroneteline.py
@@ -0,0 +1,89 @@
+import os
+import sys
+import requests
+import json
+from synchronizers.new_base.syncstep import SyncStep
+from synchronizers.new_base.modelaccessor import *
+#from xos.logger import Logger, logging
+
+from requests.auth import HTTPBasicAuth
+#logger = Logger(level=logging.INFO)
+
+parentdir = os.path.join(os.path.dirname(__file__), "..")
+sys.path.insert(0, parentdir)
+
+
+class SyncMetroNetEline(SyncStep):
+    provides = [ELine]
+
+    observes = ELine
+
+    requested_interval = 0
+
+    def __init__(self, *args, **kwargs):
+        super(SyncMetroNetEline, self).__init__(*args, **kwargs)
+
+    def get_onos_global_addr(self, onos):
+        #Fetching ip and port from the Global ONOS, append the CE specif API
+
+        onos_url = "http://%s:%s/onos/" % (onos.onos_ip, onos.onos_port)
+        evc_endpoint = "carrierethernet/evc"
+        return onos_url + evc_endpoint
+
+    def get_onos_global_auth(self, onos):
+        #Fetching username and password from the Global ONOS
+
+        return HTTPBasicAuth(onos.onos_username, onos.onos_password)
+
+    def sync_record(self, evc):
+        print "POST %s " % (evc)
+        #logger.info("Syncing Edited EVC: %s" % evc.name)
+        # Fetch the bwp from the DB
+        bwp = BandwidthProfile.objects.get(name=evc.bwp)
+
+        # json to configure ONOS to start the EVC.
+        # {
+        #     "evcId": "evc1",
+        #     "evcCfgId": "evpl1",
+        #     "uniList": [
+        #         "netconf:192.168.56.10:830/0",
+        #         "netconf:192.168.56.20:830/0"
+        #     ],
+        #     "evcType": "POINT_TO_POINT",
+        #     "vlanId": 100,
+        #     "cir": "400",
+        #     "eir": "200",
+        #     "cbs": "3000",
+        #     "ebs": "2000"
+        # }
+
+        data = {}
+        data["evcId"] = evc.name
+        data["evcCfgId"] = evc.name
+        data["uniList"] = [evc.connect_point_1_id, evc.connect_point_2_id]
+        data["evcType"] = "POINT_TO_POINT"
+        data["vlanId"] = evc.vlanids.split(",")
+        data["cbs"] = bwp.cbs
+        data["ebs"] = bwp.ebs
+        data["cir"] = bwp.cir
+        data["eir"] = bwp.eir
+        print "data %s" % data
+        # assuming that the CPEs are controller by the fabric ONOS
+        onos = OnosModel.objects.get(onos_type="global")
+        onos_addr = self.get_onos_global_addr(onos)
+
+        # FIXME - hardcoded auth
+        auth = self.get_onos_global_auth(onos)
+
+        print "POST %s for app %s, data = %s" % (onos_addr, evc.name, data)
+
+        r = requests.post(onos_addr, data=json.dumps(data), auth=auth)
+        #TODO XOS might fail to connect to ONOS.
+        if (r.status_code != 200):
+            print r
+            raise Exception("Received error from EVC Installation update (%d)" % r.status_code)
+
+    def delete_record(self, evc):
+        # TODO evaluate what to in this case.
+        print "Syncing delete EVC: %s" % evc.name
+        #logger.info("Syncing delete EVC: %s" % evc.name)
diff --git a/xos/synchronizer/steps/sync_metronetworkservice.py b/xos/synchronizer/steps/sync_metronetworkservice.py
deleted file mode 100644
index 3468d2b..0000000
--- a/xos/synchronizer/steps/sync_metronetworkservice.py
+++ /dev/null
@@ -1,254 +0,0 @@
-import os, sys
-from itertools import chain
-
-from synchronizers.new_base.SyncInstanceUsingAnsible import SyncInstanceUsingAnsible #if needed
-from synchronizers.new_base.ansible_helper import run_template_ssh #if needed
-from synchronizers.new_base.modelaccessor import *
-from xos.logger import Logger, logging
-from synchronizers.metronetwork.providers.providerfactory import ProviderFactory
-from synchronizers.metronetwork.invokers.invokerfactory import InvokerFactory
-
-# metronetwork will be in steps/..
-parentdir = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, parentdir)
-
-logger = Logger(level=logging.INFO)
-
-
-class SyncMetroNetworkSystem(SyncStep):
-    provides = [MetroNetworkSystem]
-    observes = MetroNetworkSystem
-    requested_interval = 0
-    initialized = False
-
-    def __init__(self, **args):
-        SyncStep.__init__(self, **args)
-
-    def fetch_pending(self, deletion=False):
-
-        # The general idea:
-        # We do one of two things in here:
-        #    1. Full Synchronization of the DBS (XOS <-> MetroONOS)
-        #    2. Look for updates between the two stores
-        # The first thing is potentially a much bigger
-        # operation and should not happen as often
-        #
-        # The Sync operation must take into account the 'deletion' flag
-
-        objs = []
-
-        # Get the NetworkSystem object - if it exists it will test us
-        # whether we should do a full sync or not - it all has our config
-        # information about the REST interface
-
-        metronetworksystem = self.get_metronetwork_system()
-        if not metronetworksystem:
-            logger.debug("No Service configured")
-            return objs
-
-        # Check to make sure the Metro Network System is enabled
-        metronetworksystem = self.get_metronetwork_system()
-        if metronetworksystem.administrativeState == 'disabled':
-            # Nothing to do
-            logger.debug("MetroService configured - state is Disabled")
-            return objs
-
-        # The Main Loop - retrieve all the NetworkDevice objects - for each of these
-        # Apply synchronization aspects
-        networkdevices = NetworkDevice.objects.all()
-
-        for dev in networkdevices:
-
-            # Set up the provider
-            provider = ProviderFactory.getprovider(dev)
-
-            # First check is for the AdminState of Disabled - do nothing
-            if dev.administrativeState == 'disabled':
-                # Nothing to do with this device
-                logger.debug("NetworkDevice %s: administrativeState set to Disabled - continuing" % dev.id)
-
-            # Now to the main options - are we syncing - deletion portion
-            elif dev.administrativeState == 'syncrequested' and deletion is True:
-
-                logger.info("NetworkDevice %s: administrativeState set to SyncRequested" % dev.id)
-
-                # Kill Links
-                networklinks = provider.get_network_links_for_deletion()
-                for link in networklinks:
-                    objs.append(link)
-
-                # Kill Ports
-                allports = provider.get_network_ports_for_deletion()
-                for port in allports:
-                    objs.append(port)
-
-                logger.info("NetworkDevice %s: Deletion part of Sync completed" % dev.id)
-                dev.administrativeState = 'syncinprogress'
-                dev.save(update_fields=['administrativeState'])
-
-            # Now to the main options - are we syncing - creation portion
-            elif dev.administrativeState == 'syncinprogress' and deletion is False:
-
-                logger.info("NetworkDevice %s: administrativeState set to SyncRequested" % dev.id)
-                # Reload objects in the reverse order of deletion
-
-                # Add Ports
-                networkports = provider.get_network_ports()
-                for port in networkports:
-                    objs.append(port)
-
-                # Add Links
-                networklinks = provider.get_network_links()
-                for link in networklinks:
-                    objs.append(link)
-
-                logger.info("NetworkDevice %s: Creation part of Sync completed" % dev.id)
-                dev.administrativeState = 'enabled'
-                dev.save(update_fields=['administrativeState'])
-
-            # If we are enabled - then check for events - in either direction and sync
-            elif dev.administrativeState == 'enabled' and deletion is False:
-                logger.debug("NetworkDevice: administrativeState set to Enabled - non deletion phase")
-
-                # This should be the 'normal running state' when we are not deleting - a few things to do in here
-
-                # Get the changed objects from the provider - deletions are handled separately
-                eventobjs = provider.get_updated_or_created_objects()
-                for eventobj in eventobjs:
-                    # Simply put in the queue for update - this will handle both new and changed objects
-                    objs.append(eventobj)
-
-                # Handle changes XOS -> ONOS
-                # Check for ConnectivityObjects that are in acticationequested state - creates to the backend
-                p2pactivatereqs = NetworkEdgeToEdgePointConnection.objects.filter(adminstate='activationrequested')
-                mp2mpactivatereqs = NetworkMultipointToMultipointConnection.objects.filter(adminstate='activationrequested')
-                r2mpactivatereqs = NetworkEdgeToMultipointConnection.objects.filter(adminstate='activationrequested')
-                activatereqs = list(chain(p2pactivatereqs, mp2mpactivatereqs, r2mpactivatereqs))
-                for activatereq in activatereqs:
-
-                    # Call the XOS Interface to create the service
-                    logger.debug("Attempting to create EdgePointToEdgePointConnectivity: %s" % activatereq.id)
-                    if (provider.create_network_connectivity(activatereq)):
-                        # Everyting is OK, lets let the system handle the persist
-                        objs.append(activatereq)
-                    else:
-                        # In the case of an error we persist the state of the object directly to preserve
-                        # the error code - and because that is how the base synchronizer is designed
-                        activatereq.save()
-
-                # Check for ConnectivityObjects that are in deacticationequested state - deletes to the backend
-                p2pdeactivatereqs = NetworkEdgeToEdgePointConnection.objects.filter(adminstate='deactivationrequested')
-                mp2mpdeactivatereqs = NetworkMultipointToMultipointConnection.objects.filter(adminstate='deactivationrequested')
-                r2mpdeactivatereqs = NetworkEdgeToMultipointConnection.objects.filter(adminstate='deactivationrequested')
-                deactivatereqs = list(chain(p2pdeactivatereqs, mp2mpdeactivatereqs, r2mpdeactivatereqs))
-                for deactivatereq in deactivatereqs:
-
-                    # Call the XOS Interface to delete the service
-                    logger.debug("Attempting to delete EdgePointToEdgePointConnectivity: %s" % deactivatereq.id)
-                    if provider.delete_network_connectivity(deactivatereq):
-                        # Everyting is OK, lets let the system handle the persist
-                        objs.append(deactivatereq)
-                    else:
-                        # In the case of an error we persist the state of the object directly to preserve
-                        # the error code - and because that is how the base synchronizer is designed
-                        deactivatereq.save()
-
-            # If we are enabled - and in our deletion pass then look for objects waiting for deletion
-            elif dev.administrativeState == 'enabled' and deletion is True:
-                logger.debug("NetworkDevice: administrativeState set to Enabled - deletion phase")
-
-                # Any object that is simply deleted in the model gets removed automatically - the synchronizer
-                # doesn't get involved - we just need to check for deleted objects in the domain and reflect that
-                # in the model
-                #
-                # Get the deleted objects from the provider
-                eventobjs = provider.get_deleted_objects()
-                for eventobj in eventobjs:
-                    # Simply put in the queue for update - this will handle both new and changed objects
-                    objs.append(eventobj)
-
-                # Handle the case where we have deleted Eline Services from our side - if the Service is in
-                # enabled state then we call the provider, otherwise just queue it for deletion
-                elinedeletedobjs = NetworkEdgeToEdgePointConnection.deleted_objects.all()
-                for elinedeletedobj in elinedeletedobjs:
-                    if elinedeletedobj.adminstate == 'enabled':
-                        provider.delete_network_connectivity(elinedeletedobj)
-                    # Either way queue it for deletion
-                    objs.append(elinedeletedobj)
-
-                # Handle the case where we have deleted Etree Services from our side - if the Service is in
-                # enabled state then we call the provider, otherwise just queue it for deletion
-                etreedeletedobjs = NetworkEdgeToMultipointConnection.deleted_objects.all()
-                for etreedeletedobj in etreedeletedobjs:
-                    # TODO: Handle the case where its connected, we need to disconnect first
-                    if etreedeletedobj.adminstate == 'enabled':
-                        provider.delete_network_connectivity(etreedeletedobj)
-                    # Either way queue it for deletion
-                    objs.append(etreedeletedobj)
-
-                # Handle the case where we have deleted Elan Services from our side - if the Service is in
-                # enabled state then we call the provider, otherwise just queue it for deletion
-                elandeletedobjs = NetworkMultipointToMultipointConnection.deleted_objects.all()
-                for elandeletedobj in elandeletedobjs:
-                    # TODO: Handle the case where its connected, we need to disconnect first
-                    if elandeletedobj.adminstate == 'enabled':
-                        provider.delete_network_connectivity(elandeletedobj)
-                    # Either way queue it for deletion
-                    objs.append(elandeletedobj)
-
-                # Handle the case where we have deleted VnodGlobal Services from our side - if there is
-                # an attached Eline/Etree/Elan we set that to deleted
-                vnodbloaldeletedobjs = VnodGlobalService.deleted_objects.all()
-                for vnodbloaldeletedobj in vnodbloaldeletedobjs:
-                    # Check for dependent eline service
-                    if vnodbloaldeletedobj.metronetworkpointtopoint is not None:
-                        elineobj = vnodbloaldeletedobj.metronetworkpointtopoint
-                        elineobj.deleted = True
-                        objs.append(elineobj)
-                    # Check for dependent elan service
-                    if vnodbloaldeletedobj.metronetworkmultipoint is not None:
-                        elanobj = vnodbloaldeletedobj.metronetworkmultipoint
-                        elanobj.deleted = True
-                        objs.append(elanobj)
-                    # Check for dependent etree service
-                    if vnodbloaldeletedobj.metronetworkroottomultipoint is not None:
-                        etreeobj = vnodbloaldeletedobj.metronetworkroottomultipoint
-                        etreeobj.deleted = True
-                        objs.append(etreeobj)
-
-                    objs.append(vnodbloaldeletedobj)
-
-        # In add cases return the objects we are interested in
-        return objs
-
-    def sync_record(self, o):
-
-        # First we call and see if there is an invoker for this object - the idea of the invoker
-        # is to wrap the save with a pre/post paradigm to handle special cases
-        # It will only exist for a subset of ojbects
-        invoker = InvokerFactory.getinvoker(o)
-
-        # Call Pre-save on the inovker (if it exists)
-        if invoker is not None:
-            invoker.presave(o)
-
-        # Simply save the record to the DB - both updates and adds are handled the same way
-        o.save()
-
-        # Call Post-save on the inovker (if it exists)
-        if invoker is not None:
-            invoker.postsave(o)
-
-    def delete_record(self, o):
-        # Overriden to customize our behaviour - the core sync step for will remove the record directly
-        # We just log and return
-        logger.debug("deleting Object %s" % str(o), extra=o.tologdict())
-
-    def get_metronetwork_system(self):
-        # We only expect to have one of these objects in the system in the curent design
-        # So get the first element from the query
-        metronetworksystem = MetroNetworkSystem.objects.all()
-        if not metronetworksystem:
-            return None
-
-        return metronetworksystem[0]