ONOS-3422 inter-domain cross connect

- Add network configuration about cross connect port for CO-ONOS
- revised metro.py requires ecord.co app after
  (Change-Id: I3892e780bc6550f8a8d8be622b9fee5322c1dab5)
  to be loaded.
- stop using onos-topo-cfg to send netcfg

Change-Id: Ie90e69c4134d1f71893bf43ee6c290bdbd273aeb
diff --git a/tools/test/topos/opticalUtils.py b/tools/test/topos/opticalUtils.py
index 9a908ef..19b898b 100644
--- a/tools/test/topos/opticalUtils.py
+++ b/tools/test/topos/opticalUtils.py
@@ -3,7 +3,7 @@
 '''
 Notes:
 
-This file contains classes and methods useful for integrating LincOE with Mininet, 
+This file contains classes and methods useful for integrating LincOE with Mininet,
 such as startOE, stopOE, LINCLink, and OpticalSwitch
 
 - $ONOS_ROOT ust be set
@@ -24,7 +24,7 @@
         ------------
     - import LINCLink and OpticalSwitch from this module
     - import startOE and stopOE from this module
-    - create topology as you would a normal topology. when 
+    - create topology as you would a normal topology. when
       to an optical switch with topo.addLink, always specify cls=LINCLink
     - when creating an optical switch, use cls=OpticalSwitch in topo.addSwitch
     - for annotations on links and switches, a dictionary must be passed in as
@@ -41,13 +41,13 @@
 information for each switch. We would still subclass switch and link, but these
 classes would basically be dummy classes that store their own json information
 in the Mininet class object. We may also change the default switch class to add
-it's tap interfaces from lincOE during startup. The start() method for mininet would 
+it's tap interfaces from lincOE during startup. The start() method for mininet would
 grab all of the information from these switches and links, write configuration files
 for lincOE using the json module, start lincOE, then run the start methodfor each
 switch. The new start() method for each switch would parse through the sys.config
-file that was created and find the tap interface it needs to connect to, similar 
-to the findTap function that I currently use. After all of the controllers and 
-switches have been started, the new Mininet start() method should also push the 
+file that was created and find the tap interface it needs to connect to, similar
+to the findTap function that I currently use. After all of the controllers and
+switches have been started, the new Mininet start() method should also push the
 Topology configuration file to ONOS.
 
 '''
@@ -119,7 +119,7 @@
                     if dpid:
                         dpids_to_ids[dpid.group().replace(':', '')] = switch_id
                         switch_id += 1
-            return dpids_to_ids     
+            return dpids_to_ids
         except:
             print "Error working with {}\nError: {}\n".format(sysConfig, sys.exc_info())
             fd.close()
@@ -287,8 +287,8 @@
         with open("crossConnect.json", 'w') as fd:
             json.dump(crossConnectJSON, fd, indent=4, separators=(',', ': '))
         info('*** Pushing crossConnect.json to ONOS\n')
-        output = quietRun('%s/tools/test/bin/onos-topo-cfg %s\
-         Topology.json network/configuration/' % (self.onosDir, self.controllers[ 0 ].ip), shell=True)
+        output = quietRun('%s/tools/test/bin/onos-netcfg %s\
+         Topology.json' % (self.onosDir, self.controllers[ 0 ].ip), shell=True)
 
     def stop_oe(self):
         '''
@@ -388,7 +388,7 @@
             json.dump(topoJSON, outfile, indent=4, separators=(',', ': '))
 
         info('*** Converting Topology.json to linc-oe format (TopoConfig.json) file (no oecfg) \n')
-        
+
         topoConfigJson = {}
 
         topoConfigJson["switchConfig"] = LINCSwitch.getSwitchConfig(net.switches)
@@ -455,21 +455,20 @@
         opener.open(url)
         urllib2.install_opener(opener)
         # focus on just checking the state of devices we're interested in
-        devlist =  map( lambda x: x['uri'], devices )
+        # expected devices availability map
+        devMap =  dict.fromkeys(map( lambda x: x['uri'], devices ), False)
         while True:
             response = json.load(urllib2.urlopen(url))
             devs = response.get('devices')
 
-            # Wait for all devices to be registered. There is a chance that this is only a subgraph.
-            if (len(devices) == len(devs)):
+            # update availability map
+            for d in devs:
+                if devMap.has_key(d['id']):
+                    devMap[d['id']] = d['available']
 
-                # Wait for all devices to available
-                available = True
-                for d in devs:
-                    if d['id'] in devlist:
-                        available &= d['available']
-                if available:
-                    break
+            # Check if all devices we're interested became available
+            if all(devMap.viewvalues()):
+                break;
 
             if (time >= TIMEOUT):
                 error('***ERROR: ONOS did not register devices within %s seconds\n' % TIMEOUT)
@@ -480,7 +479,7 @@
 
         info('*** Pushing Topology.json to ONOS\n')
         for index in range(len(LINCSwitch.controllers)):
-            output = quietRun('%s/tools/test/bin/onos-topo-cfg %s Topology.json network/configuration/ &'\
+            output = quietRun('%s/tools/test/bin/onos-netcfg %s Topology.json &'\
                                % (LINCSwitch.onosDir, LINCSwitch.controllers[ index ].ip), shell=True)
             # successful output contains the two characters '{}'
             # if there is more output than this, there is an issue
@@ -539,7 +538,7 @@
     @staticmethod
     def getSwitchConfig(switches):
         switchConfig = []
-        
+
         # Iterate through all switches and convert the ROADM switches to linc-oe format
         for switch in switches:
             if isinstance(switch, LINCSwitch):
@@ -566,7 +565,7 @@
     @staticmethod
     def getLinkConfig(links):
         linkConfig = []
-        
+
         # Iterate through all non-edge links and convert them to linc-oe format
         for link in links:
             if isinstance(link, LINCLink):
@@ -581,7 +580,7 @@
                 params = {}
                 params["nodeName1"] = link.intf1.node.name
                 params["nodeName2"] = link.intf2.node.name
-                
+
                 params["port1"] = link.port1
                 params["port2"]  = link.port2
 
@@ -609,7 +608,7 @@
         for link in net.links:
             if isinstance(link, LINCLink) and link.isCrossConnect():
                 tapCount += 1
-                    
+
         while True:
             # tapCount can be less than the actual number of taps if the optical network
             # is a subgraph of a larger multidomain network.
@@ -722,7 +721,7 @@
                 node1.crossConnects.append(self)
         else:
             cls1 = Intf
-            # bad hack to stop error message from appearing when we try to set up intf in a packet switch, 
+            # bad hack to stop error message from appearing when we try to set up intf in a packet switch,
             # and there is no interface there( because we do not run makeIntfPair ). This way, we just set lo up
             intfName1 = 'lo'
         if isinstance(node2, LINCSwitch):