Merge "Added support to generate types from Choices and Cases added by augmentation."
authorAlessandro Boch <aboch@cisco.com>
Wed, 3 Jul 2013 20:31:38 +0000 (20:31 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 3 Jul 2013 20:31:38 +0000 (20:31 +0000)
17 files changed:
opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowEntryInstall.java
opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/Activator.java
opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManagerImpl.java
opendaylight/hosttracker/implementation/src/main/java/org/opendaylight/controller/hosttracker/internal/HostTracker.java
opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Latency.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/NetUtils.java
opendaylight/samples/simpleforwarding/pom.xml
opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/HostNodePair.java [moved from opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/HostNodePair.java with 97% similarity]
opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/SimpleForwardingImpl.java
opendaylight/samples/simpleforwarding/src/test/java/org/opendaylight/controller/samples/simpleforwarding/internal/HostSwitchTest.java
opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/SpanConfig.java
opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/SubnetConfig.java
opendaylight/switchmanager/api/src/main/java/org/opendaylight/controller/switchmanager/SwitchConfig.java
opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManagerImpl.java
opendaylight/web/root/src/main/resources/WEB-INF/jsp/main.jsp
opendaylight/web/root/src/main/resources/css/one.less

index ebb5a7bb2457125d8c3c27ea795a820377354eef..ee2113db8287066f7337a147ade4e7d9048bf2ea 100644 (file)
@@ -34,7 +34,7 @@ public class FlowEntryInstall implements Serializable {
     public FlowEntryInstall(FlowEntry original, ContainerFlow cFlow) {
         this.original = original;
         this.cFlow = cFlow;
-        this.install = (cFlow == null) ? original.clone() : original.mergeWith(cFlow);
+        this.install = (cFlow == null) ? original.clone() : original.clone().mergeWith(cFlow);
         deletePending = false;
         requestId = 0;
     }
index 2b161e9be7018365f6fee3ca7dcdb989e6257da4..f6fc0012ad4219f368373cb10284e1c401e96a0f 100644 (file)
@@ -22,7 +22,6 @@ import org.opendaylight.controller.sal.core.IContainer;
 import org.opendaylight.controller.sal.core.IContainerListener;
 import org.opendaylight.controller.sal.flowprogrammer.IFlowProgrammerListener;
 import org.opendaylight.controller.sal.flowprogrammer.IFlowProgrammerService;
-import org.opendaylight.controller.sal.utils.GlobalConstants;
 import org.opendaylight.controller.switchmanager.IInventoryListener;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
 import org.opendaylight.controller.switchmanager.ISwitchManagerAware;
@@ -41,6 +40,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      * are done by the ComponentActivatorAbstractBase.
      *
      */
+    @Override
     public void init() {
 
     }
@@ -50,6 +50,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      * ComponentActivatorAbstractBase
      *
      */
+    @Override
     public void destroy() {
 
     }
@@ -63,6 +64,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      *         instantiated in order to get an fully working implementation
      *         Object
      */
+    @Override
     public Object[] getImplementations() {
         Object[] res = { ForwardingRulesManagerImpl.class };
         return res;
@@ -83,26 +85,20 @@ public class Activator extends ComponentActivatorAbstractBase {
      *            per-container different behavior if needed, usually should not
      *            be the case though.
      */
+    @Override
     public void configureInstance(Component c, Object imp, String containerName) {
         if (imp.equals(ForwardingRulesManagerImpl.class)) {
             String interfaces[] = null;
             Dictionary<String, Set<String>> props = new Hashtable<String, Set<String>>();
             Set<String> propSet = new HashSet<String>();
-            propSet.add("staticFlows");
+            propSet.add("frm.flowsSaveEvent");
             props.put("cachenames", propSet);
 
             // export the service
-            if (containerName.equals(GlobalConstants.DEFAULT.toString())) {
-                interfaces = new String[] { IContainerListener.class.getName(), ISwitchManagerAware.class.getName(),
-                        IForwardingRulesManager.class.getName(), IInventoryListener.class.getName(),
-                        ICacheUpdateAware.class.getName(), IConfigurationContainerAware.class.getName(),
-                        IFlowProgrammerListener.class.getName() };
-            } else {
-                interfaces = new String[] { ISwitchManagerAware.class.getName(),
-                        IForwardingRulesManager.class.getName(), IInventoryListener.class.getName(),
-                        ICacheUpdateAware.class.getName(), IConfigurationContainerAware.class.getName(),
-                        IFlowProgrammerListener.class.getName() };
-            }
+            interfaces = new String[] { IContainerListener.class.getName(), ISwitchManagerAware.class.getName(),
+                    IForwardingRulesManager.class.getName(), IInventoryListener.class.getName(),
+                    ICacheUpdateAware.class.getName(), IConfigurationContainerAware.class.getName(),
+                    IFlowProgrammerListener.class.getName() };
 
             c.setInterface(interfaces, props);
 
index 2c5144f284b908f46d2a114da4acf2f2c3a14a58..7fae181ba632c0aa51a26d96dccd93698d313eab 100644 (file)
@@ -929,16 +929,21 @@ public class ForwardingRulesManagerImpl implements IForwardingRulesManager, Port
      * on the network node
      */
     private void updateFlowsContainerFlow() {
+        Set<FlowEntry> toReInstall = new HashSet<FlowEntry>();
+        // First remove all installed entries
         for (ConcurrentMap.Entry<FlowEntryInstall, FlowEntryInstall> entry : installedSwView.entrySet()) {
             FlowEntryInstall current = entry.getValue();
-            FlowEntry reInstall = current.getOriginal();
+            // Store the original entry
+            toReInstall.add(current.getOriginal());
             // Remove the old couples. No validity checks to be run, use the
             // internal remove
             this.removeEntryInternal(current, false);
-
+        }
+        // Then reinstall the original entries
+        for (FlowEntry entry : toReInstall) {
             // Reinstall the original flow entries, via the regular path: new
             // cFlow merge + validations
-            this.installFlowEntry(reInstall);
+            this.installFlowEntry(entry);
         }
     }
 
@@ -1131,7 +1136,7 @@ public class ForwardingRulesManagerImpl implements IForwardingRulesManager, Port
             return;
         }
 
-        log.debug("FRM allocateCaches for Container {}", container);
+        log.debug("Allocating caches for Container {}", container.getName());
 
         try {
             clusterContainerService.createCache("frm.originalSwView",
@@ -1165,9 +1170,9 @@ public class ForwardingRulesManagerImpl implements IForwardingRulesManager, Port
                     EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
 
         } catch (CacheConfigException cce) {
-            log.error("FRM CacheConfigException");
+            log.error("CacheConfigException");
         } catch (CacheExistException cce) {
-            log.error("FRM CacheExistException");
+            log.error("CacheExistException");
         }
     }
 
@@ -1180,76 +1185,76 @@ public class ForwardingRulesManagerImpl implements IForwardingRulesManager, Port
             return;
         }
 
-        log.debug("FRM retrieveCaches for Container {}", container);
+        log.debug("Retrieving Caches for Container {}", container.getName());
 
         map = clusterContainerService.getCache("frm.originalSwView");
         if (map != null) {
             originalSwView = (ConcurrentMap<FlowEntry, FlowEntry>) map;
         } else {
-            log.error("FRM Cache frm.originalSwView allocation failed for Container {}", container.getName());
+            log.error("Retrieval of frm.originalSwView cache failed for Container {}", container.getName());
         }
 
         map = clusterContainerService.getCache("frm.installedSwView");
         if (map != null) {
             installedSwView = (ConcurrentMap<FlowEntryInstall, FlowEntryInstall>) map;
         } else {
-            log.error("FRM Cache frm.installedSwView allocation failed for Container {}", container.getName());
+            log.error("Retrieval of frm.installedSwView cache failed for Container {}", container.getName());
         }
 
         map = clusterContainerService.getCache("frm.nodeFlows");
         if (map != null) {
             nodeFlows = (ConcurrentMap<Node, List<FlowEntryInstall>>) map;
         } else {
-            log.error("FRM Cache frm.nodeFlows allocation failed for Container {}", container.getName());
+            log.error("Retrieval of cache failed for Container {}", container.getName());
         }
 
         map = clusterContainerService.getCache("frm.groupFlows");
         if (map != null) {
             groupFlows = (ConcurrentMap<String, List<FlowEntryInstall>>) map;
         } else {
-            log.error("FRM Cache frm.groupFlows allocation failed for Container {}", container.getName());
+            log.error("Retrieval of frm.groupFlows cache failed for Container {}", container.getName());
         }
 
         map = clusterContainerService.getCache("frm.staticFlows");
         if (map != null) {
             staticFlows = (ConcurrentMap<Integer, FlowConfig>) map;
         } else {
-            log.error("FRM Cache frm.staticFlows allocation failed for Container {}", container.getName());
+            log.error("Retrieval of frm.staticFlows cache failed for Container {}", container.getName());
         }
 
         map = clusterContainerService.getCache("frm.flowsSaveEvent");
         if (map != null) {
             flowsSaveEvent = (ConcurrentMap<Long, String>) map;
         } else {
-            log.error("FRM Cache frm.flowsSaveEvent allocation failed for Container {}", container.getName());
+            log.error("Retrieval of frm.flowsSaveEvent cache failed for Container {}", container.getName());
         }
 
         map = clusterContainerService.getCache("frm.staticFlowsOrdinal");
         if (map != null) {
             staticFlowsOrdinal = (ConcurrentMap<Integer, Integer>) map;
         } else {
-            log.error("FRM Cache frm.staticFlowsOrdinal allocation failed for Container {}", container.getName());
+            log.error("Retrieval of frm.staticFlowsOrdinal cache failed for Container {}", container.getName());
         }
 
         map = clusterContainerService.getCache("frm.portGroupConfigs");
         if (map != null) {
             portGroupConfigs = (ConcurrentMap<String, PortGroupConfig>) map;
         } else {
-            log.error("FRM Cache frm.portGroupConfigs allocation failed for Container {}", container.getName());
+            log.error("Retrieval of frm.portGroupConfigs cache failed for Container {}", container.getName());
         }
 
         map = clusterContainerService.getCache("frm.portGroupData");
         if (map != null) {
             portGroupData = (ConcurrentMap<PortGroupConfig, Map<Node, PortGroup>>) map;
         } else {
-            log.error("FRM Cache frm.portGroupData allocation failed for Container {}", container.getName());
+            log.error("Retrieval of frm.portGroupData allocation failed for Container {}", container.getName());
         }
 
         map = clusterContainerService.getCache("frm.TSPolicies");
         if (map != null) {
             TSPolicies = (ConcurrentMap<String, Object>) map;
         } else {
-            log.error("FRM Cache frm.TSPolicies allocation failed for Container {}", container.getName());
+            log.error("Retrieval of frm.TSPolicies cache failed for Container {}", container.getName());
         }
 
     }
@@ -2217,12 +2222,19 @@ public class ForwardingRulesManagerImpl implements IForwardingRulesManager, Port
 
     @Override
     public void tagUpdated(String containerName, Node n, short oldTag, short newTag, UpdateType t) {
-
+        if (!container.getName().equals(containerName)) {
+            return;
+        }
     }
 
     @Override
-    public void containerFlowUpdated(String containerName, ContainerFlow previousFlow, ContainerFlow currentFlow,
+    public void containerFlowUpdated(String containerName, ContainerFlow previous, ContainerFlow current,
             UpdateType t) {
+        if (!container.getName().equals(containerName)) {
+            return;
+        }
+        log.trace("Container {}: Updating installed flows because of container flow change: {} {}",
+                container.getName(), t, current);
         /*
          * Whether it is an addition or removal, we have to recompute the merged
          * flows entries taking into account all the current container flows
@@ -2233,11 +2245,17 @@ public class ForwardingRulesManagerImpl implements IForwardingRulesManager, Port
 
     @Override
     public void nodeConnectorUpdated(String containerName, NodeConnector p, UpdateType t) {
-        // No action
+        if (!container.getName().equals(containerName)) {
+            return;
+        }
     }
 
     @Override
     public void containerModeUpdated(UpdateType update) {
+        // Only default container instance reacts on this event
+        if (!container.getName().equals(GlobalConstants.DEFAULT.toString())) {
+            return;
+        }
         switch (update) {
         case ADDED:
             this.inContainerMode = true;
index 707a7761389c1b0dcf3d6c6cc4706c95c944f96f..446f51eb04c81bd3be6f38038e1d6b33cb5fe964 100644 (file)
@@ -52,6 +52,7 @@ import org.opendaylight.controller.sal.packet.address.EthernetAddress;
 import org.opendaylight.controller.sal.topology.TopoEdgeUpdate;
 import org.opendaylight.controller.sal.utils.GlobalConstants;
 import org.opendaylight.controller.sal.utils.HexEncode;
+import org.opendaylight.controller.sal.utils.NetUtils;
 import org.opendaylight.controller.sal.utils.NodeCreator;
 import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.sal.utils.StatusCode;
@@ -77,10 +78,9 @@ import org.slf4j.LoggerFactory;
  *       removed the database
  */
 
-public class HostTracker implements IfIptoHost, IfHostListener,
-        ISwitchManagerAware, IInventoryListener, ITopologyManagerAware {
-    private static final Logger logger = LoggerFactory
-            .getLogger(HostTracker.class);
+public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAware, IInventoryListener,
+        ITopologyManagerAware {
+    private static final Logger logger = LoggerFactory.getLogger(HostTracker.class);
     private IHostFinder hostFinder;
     private ConcurrentMap<InetAddress, HostNodeConnector> hostsDB;
     /*
@@ -89,8 +89,7 @@ public class HostTracker implements IfIptoHost, IfHostListener,
      * added here until both come up
      */
     private ConcurrentMap<NodeConnector, HostNodeConnector> inactiveStaticHosts;
-    private Set<IfNewHostNotify> newHostNotify = Collections
-            .synchronizedSet(new HashSet<IfNewHostNotify>());
+    private final Set<IfNewHostNotify> newHostNotify = Collections.synchronizedSet(new HashSet<IfNewHostNotify>());
 
     private ITopologyManager topologyManager;
     private IClusterContainerServices clusterContainerService = null;
@@ -131,7 +130,7 @@ public class HostTracker implements IfIptoHost, IfHostListener,
 
     // This list contains the hosts for which ARP requests are being sent
     // periodically
-    private List<ARPPending> ARPPendingList = new ArrayList<HostTracker.ARPPending>();
+    private final List<ARPPending> ARPPendingList = new ArrayList<HostTracker.ARPPending>();
     /*
      * This list below contains the hosts which were initially in ARPPendingList
      * above, but ARP response didn't come from there hosts after multiple
@@ -148,7 +147,7 @@ public class HostTracker implements IfIptoHost, IfHostListener,
      *
      * We can't recover from condition 3 above
      */
-    private ArrayList<ARPPending> failedARPReqList = new ArrayList<HostTracker.ARPPending>();
+    private final ArrayList<ARPPending> failedARPReqList = new ArrayList<HostTracker.ARPPending>();
 
     public HostTracker() {
     }
@@ -267,27 +266,20 @@ public class HostTracker implements IfIptoHost, IfHostListener,
         return hostsDB.get(networkAddress);
     }
 
-    private Entry<NodeConnector, HostNodeConnector> getHostFromInactiveDB(
-            InetAddress networkAddress) {
-        for (Entry<NodeConnector, HostNodeConnector> entry : inactiveStaticHosts
-                .entrySet()) {
+    private Entry<NodeConnector, HostNodeConnector> getHostFromInactiveDB(InetAddress networkAddress) {
+        for (Entry<NodeConnector, HostNodeConnector> entry : inactiveStaticHosts.entrySet()) {
             if (entry.getValue().equalsByIP(networkAddress)) {
-                logger.debug(
-                        "getHostFromInactiveDB(): Inactive Host found for IP:{} ",
-                        networkAddress.getHostAddress());
+                logger.debug("getHostFromInactiveDB(): Inactive Host found for IP:{} ", networkAddress.getHostAddress());
                 return entry;
             }
         }
-        logger.debug(
-                "getHostFromInactiveDB() Inactive Host Not found for IP: {}",
-                networkAddress.getHostAddress());
+        logger.debug("getHostFromInactiveDB() Inactive Host Not found for IP: {}", networkAddress.getHostAddress());
         return null;
     }
 
     private void removeHostFromInactiveDB(InetAddress networkAddress) {
         NodeConnector nodeConnector = null;
-        for (Entry<NodeConnector, HostNodeConnector> entry : inactiveStaticHosts
-                .entrySet()) {
+        for (Entry<NodeConnector, HostNodeConnector> entry : inactiveStaticHosts.entrySet()) {
             if (entry.getValue().equalsByIP(networkAddress)) {
                 nodeConnector = entry.getKey();
                 break;
@@ -295,12 +287,10 @@ public class HostTracker implements IfIptoHost, IfHostListener,
         }
         if (nodeConnector != null) {
             inactiveStaticHosts.remove(nodeConnector);
-            logger.debug("removeHostFromInactiveDB(): Host Removed for IP: {}",
-                    networkAddress.getHostAddress());
+            logger.debug("removeHostFromInactiveDB(): Host Removed for IP: {}", networkAddress.getHostAddress());
             return;
         }
-        logger.debug("removeHostFromInactiveDB(): Host Not found for IP: {}",
-                networkAddress.getHostAddress());
+        logger.debug("removeHostFromInactiveDB(): Host Not found for IP: {}", networkAddress.getHostAddress());
     }
 
     protected boolean hostMoved(HostNodeConnector host) {
@@ -310,22 +300,24 @@ public class HostTracker implements IfIptoHost, IfHostListener,
         return false;
     }
 
+    @Override
     public HostNodeConnector hostQuery(InetAddress networkAddress) {
         return hostsDB.get(networkAddress);
     }
 
+    @Override
     public Future<HostNodeConnector> discoverHost(InetAddress networkAddress) {
         ExecutorService executor = Executors.newFixedThreadPool(1);
         if (executor == null) {
             logger.error("discoverHost: Null executor");
             return null;
         }
-        Callable<HostNodeConnector> worker = new HostTrackerCallable(this,
-                networkAddress);
+        Callable<HostNodeConnector> worker = new HostTrackerCallable(this, networkAddress);
         Future<HostNodeConnector> submit = executor.submit(worker);
         return submit;
     }
 
+    @Override
     public HostNodeConnector hostFind(InetAddress networkAddress) {
         /*
          * Sometimes at boot with containers configured in the startup we hit
@@ -340,20 +332,19 @@ public class HostTracker implements IfIptoHost, IfHostListener,
 
         HostNodeConnector host = hostQuery(networkAddress);
         if (host != null) {
-            logger.debug("hostFind(): Host found for IP: {}",
-                    networkAddress.getHostAddress());
+            logger.debug("hostFind(): Host found for IP: {}", networkAddress.getHostAddress());
             return host;
         }
         /* host is not found, initiate a discovery */
         hostFinder.find(networkAddress);
         /* Also add this host to ARPPending List for any potential retries */
         AddtoARPPendingList(networkAddress);
-        logger.debug(
-                "hostFind(): Host Not Found for IP: {}, Inititated Host Discovery ...",
+        logger.debug("hostFind(): Host Not Found for IP: {}, Inititated Host Discovery ...",
                 networkAddress.getHostAddress());
         return null;
     }
 
+    @Override
     public Set<HostNodeConnector> getAllHosts() {
         Set<HostNodeConnector> allHosts = new HashSet<HostNodeConnector>();
         for (Entry<InetAddress, HostNodeConnector> entry : hostsDB.entrySet()) {
@@ -380,8 +371,7 @@ public class HostTracker implements IfIptoHost, IfHostListener,
     @Override
     public Set<HostNodeConnector> getInactiveStaticHosts() {
         Set<HostNodeConnector> list = new HashSet<HostNodeConnector>();
-        for (Entry<NodeConnector, HostNodeConnector> entry : inactiveStaticHosts
-                .entrySet()) {
+        for (Entry<NodeConnector, HostNodeConnector> entry : inactiveStaticHosts.entrySet()) {
             list.add(entry.getValue());
         }
         logger.debug("getInactiveStaticHosts(): Found {} Hosts", list.size());
@@ -399,8 +389,7 @@ public class HostTracker implements IfIptoHost, IfHostListener,
 
     private void removePendingARPFromList(int index) {
         if (index >= ARPPendingList.size()) {
-            logger.warn(
-                    "removePendingARPFromList(): index greater than the List. Size:{}, Index:{}",
+            logger.warn("removePendingARPFromList(): index greater than the List. Size:{}, Index:{}",
                     ARPPendingList.size(), index);
             return;
         }
@@ -410,8 +399,7 @@ public class HostTracker implements IfIptoHost, IfHostListener,
             htCallable.wakeup();
     }
 
-    public void setCallableOnPendingARP(InetAddress networkAddr,
-            HostTrackerCallable callable) {
+    public void setCallableOnPendingARP(InetAddress networkAddr, HostTrackerCallable callable) {
         ARPPending arphost;
         for (int i = 0; i < ARPPendingList.size(); i++) {
             arphost = ARPPendingList.get(i);
@@ -432,8 +420,7 @@ public class HostTracker implements IfIptoHost, IfHostListener,
                  * the request
                  */
                 removePendingARPFromList(i);
-                logger.debug("Host Removed from ARPPending List, IP: {}",
-                        networkAddr);
+                logger.debug("Host Removed from ARPPending List, IP: {}", networkAddr);
                 return;
             }
         }
@@ -450,8 +437,7 @@ public class HostTracker implements IfIptoHost, IfHostListener,
                  * the request
                  */
                 failedARPReqList.remove(i);
-                logger.debug("Host Removed from FailedARPReqList List, IP: {}",
-                        networkAddr);
+                logger.debug("Host Removed from FailedARPReqList List, IP: {}", networkAddr);
                 return;
             }
         }
@@ -460,73 +446,93 @@ public class HostTracker implements IfIptoHost, IfHostListener,
     // Learn a new Host
     private void learnNewHost(HostNodeConnector host) {
         host.initArpSendCountDown();
-        hostsDB.put(host.getNetworkAddress(), host);
-        logger.debug("New Host Learned: MAC: {}  IP: {}",
-                HexEncode.bytesToHexString(host.getDataLayerAddressBytes()),
-                host.getNetworkAddress().getHostAddress());
+        HostNodeConnector rHost = hostsDB.putIfAbsent(host.getNetworkAddress(), host);
+        if (rHost != null) {
+            // Another host is already learned for this IP address, replace it
+            replaceHost(host.getNetworkAddress(), rHost, host);
+        } else {
+            logger.debug("New Host Learned: MAC: {}  IP: {}", HexEncode.bytesToHexString(host
+                    .getDataLayerAddressBytes()), host.getNetworkAddress().getHostAddress());
+        }
+    }
+
+    private void replaceHost(InetAddress networkAddr, HostNodeConnector removedHost, HostNodeConnector newHost) {
+        newHost.initArpSendCountDown();
+        if (hostsDB.replace(networkAddr, removedHost, newHost)) {
+            logger.debug("Host move occurred. Old Host:{}, New Host: {}", removedHost, newHost);
+        } else {
+            /*
+             * Host replacement has failed, do the recovery
+             */
+            hostsDB.put(networkAddr, newHost);
+            logger.error("Host replacement failed. Overwrite the host. Repalced Host: {}, New Host: {}", removedHost,
+                    newHost);
+        }
+        notifyHostLearnedOrRemoved(removedHost, false);
+        notifyHostLearnedOrRemoved(newHost, true);
+        if (!newHost.isStaticHost()) {
+            ProcPendingARPReqs(networkAddr);
+        }
     }
 
     // Remove known Host
     private void removeKnownHost(InetAddress key) {
         HostNodeConnector host = hostsDB.get(key);
         if (host != null) {
-            logger.debug("Removing Host: IP:{}", host.getNetworkAddress()
-                    .getHostAddress());
+            logger.debug("Removing Host: IP:{}", host.getNetworkAddress().getHostAddress());
             hostsDB.remove(key);
         } else {
-            logger.error(
-                    "removeKnownHost(): Host for IP address {} not found in hostsDB",
-                    key.getHostAddress());
+            logger.error("removeKnownHost(): Host for IP address {} not found in hostsDB", key.getHostAddress());
         }
     }
 
     private class NotifyHostThread extends Thread {
 
-        private HostNodeConnector host;
+        private final HostNodeConnector host;
 
         public NotifyHostThread(HostNodeConnector h) {
             this.host = h;
         }
 
+        @Override
         public void run() {
+            HostNodeConnector removedHost = null;
+            InetAddress networkAddr = host.getNetworkAddress();
+
             /* Check for Host Move case */
             if (hostMoved(host)) {
                 /*
                  * Host has been moved from one location (switch,port, MAC, or
-                 * VLAN). Remove the existing host with its previous location
-                 * parameters, inform the applications, and add it as a new Host
+                 * VLAN) to another. Replace the existing host and its previous
+                 * location parameters with new information, and notify the
+                 * applications listening to host move.
                  */
-                HostNodeConnector removedHost = hostsDB.get(host
-                        .getNetworkAddress());
-                removeKnownHost(host.getNetworkAddress());
+                removedHost = hostsDB.get(networkAddr);
                 if (removedHost != null) {
-                    notifyHostLearnedOrRemoved(removedHost, false);
-                    logger.debug(
-                            "Host move occurred. Old Host:{}, New Host: {}",
-                            removedHost, host);
+                    replaceHost(networkAddr, removedHost, host);
+                    return;
                 } else {
-                    logger.error(
-                            "Host to be removed not found in hostsDB. Host {}",
-                            removedHost);
+                    logger.error("Host to be removed not found in hostsDB. Host {}", removedHost);
                 }
             }
 
-            /* check if there is an outstanding request for this host */
-            InetAddress networkAddr = host.getNetworkAddress();
+            if (removedHost == null) {
+                // It is a new host
+                learnNewHost(host);
+            }
 
-            // add and notify
-            learnNewHost(host);
+            /* check if there is an outstanding request for this host */
             ProcPendingARPReqs(networkAddr);
             notifyHostLearnedOrRemoved(host, true);
         }
     }
 
+    @Override
     public void hostListener(HostNodeConnector host) {
 
         if (hostExists(host)) {
             logger.debug("ARP received for Host: {}", host);
-            HostNodeConnector existinghost = hostsDB.get(host
-                    .getNetworkAddress());
+            HostNodeConnector existinghost = hostsDB.get(host.getNetworkAddress());
             existinghost.initArpSendCountDown();
             return;
         }
@@ -561,10 +567,8 @@ public class HostTracker implements IfIptoHost, IfHostListener,
         Host h = null;
         NodeConnector p = host.getnodeConnector();
         try {
-            DataLinkAddress dla = new EthernetAddress(
-                    host.getDataLayerAddressBytes());
-            h = new org.opendaylight.controller.sal.core.Host(dla,
-                    host.getNetworkAddress());
+            DataLinkAddress dla = new EthernetAddress(host.getDataLayerAddressBytes());
+            h = new Host(dla, host.getNetworkAddress());
         } catch (ConstructionException ce) {
             p = null;
             h = null;
@@ -603,21 +607,17 @@ public class HostTracker implements IfIptoHost, IfHostListener,
     private void updateSwitchTiers(Node n, int currentTier) {
         Map<Node, Set<Edge>> ndlinks = topologyManager.getNodeEdges();
         if (ndlinks == null) {
-            logger.debug(
-                    "updateSwitchTiers(): ndlinks null for Node: {}, Tier:{}",
-                    n, currentTier);
+            logger.debug("updateSwitchTiers(): ndlinks null for Node: {}, Tier:{}", n, currentTier);
             return;
         }
         Set<Edge> links = ndlinks.get(n);
         if (links == null) {
-            logger.debug("updateSwitchTiers(): links null for ndlinks:{}",
-                    ndlinks);
+            logger.debug("updateSwitchTiers(): links null for ndlinks:{}", ndlinks);
             return;
         }
         ArrayList<Node> needsVisiting = new ArrayList<Node>();
         for (Edge lt : links) {
-            if (!lt.getHeadNodeConnector().getType()
-                    .equals(NodeConnector.NodeConnectorIDType.OPENFLOW)) {
+            if (!lt.getHeadNodeConnector().getType().equals(NodeConnector.NodeConnectorIDType.OPENFLOW)) {
                 // We don't want to work on Node that are not openflow
                 // for now
                 continue;
@@ -654,8 +654,7 @@ public class HostTracker implements IfIptoHost, IfHostListener,
 
     private boolean switchNeedsTieringUpdate(Node n, int tier) {
         if (n == null) {
-            logger.error("switchNeedsTieringUpdate(): Null node for tier: {}",
-                    tier);
+            logger.error("switchNeedsTieringUpdate(): Null node for tier: {}", tier);
             return false;
         }
         /*
@@ -723,6 +722,7 @@ public class HostTracker implements IfIptoHost, IfHostListener,
      * @return Network Hierarchies represented by an Array of Array (of
      *         Switch-Ids as String).
      */
+    @Override
     public List<List<String>> getHostNetworkHierarchy(InetAddress hostAddress) {
         HostNodeConnector host = hostQuery(hostAddress);
         if (host == null)
@@ -775,18 +775,17 @@ public class HostTracker implements IfIptoHost, IfHostListener,
      *            Array of multiple Hierarchies that represent a given host.
      */
     @SuppressWarnings("unchecked")
-    private void updateCurrentHierarchy(Node node,
-            ArrayList<String> currHierarchy, List<List<String>> fullHierarchy) {
+    private void updateCurrentHierarchy(Node node, ArrayList<String> currHierarchy, List<List<String>> fullHierarchy) {
         // currHierarchy.add(String.format("%x", currSw.getId()));
         currHierarchy.add(dpidToHostNameHack((Long) node.getID()));
-        ArrayList<String> currHierarchyClone = (ArrayList<String>) currHierarchy
-                .clone(); // Shallow copy as required
+        ArrayList<String> currHierarchyClone = (ArrayList<String>) currHierarchy.clone(); // Shallow
+                                                                                          // copy
+                                                                                          // as
+                                                                                          // required
 
         Map<Node, Set<Edge>> ndlinks = topologyManager.getNodeEdges();
         if (ndlinks == null) {
-            logger.debug(
-                    "updateCurrentHierarchy(): topologyManager returned null ndlinks for node: {}",
-                    node);
+            logger.debug("updateCurrentHierarchy(): topologyManager returned null ndlinks for node: {}", node);
             return;
         }
         Node n = NodeCreator.createOFNode((Long) node.getID());
@@ -796,23 +795,22 @@ public class HostTracker implements IfIptoHost, IfHostListener,
             return;
         }
         for (Edge lt : links) {
-            if (!lt.getHeadNodeConnector().getType()
-                    .equals(NodeConnector.NodeConnectorIDType.OPENFLOW)) {
+            if (!lt.getHeadNodeConnector().getType().equals(NodeConnector.NodeConnectorIDType.OPENFLOW)) {
                 // We don't want to work on Node that are not openflow
                 // for now
                 continue;
             }
             Node dstNode = lt.getHeadNodeConnector().getNode();
 
-            Tier nodeTier = (Tier) switchManager.getNodeProp(node,
-                    Tier.TierPropName);
-            Tier dstNodeTier = (Tier) switchManager.getNodeProp(dstNode,
-                    Tier.TierPropName);
+            Tier nodeTier = (Tier) switchManager.getNodeProp(node, Tier.TierPropName);
+            Tier dstNodeTier = (Tier) switchManager.getNodeProp(dstNode, Tier.TierPropName);
             if (dstNodeTier.getValue() > nodeTier.getValue()) {
                 ArrayList<String> buildHierarchy = currHierarchy;
                 if (currHierarchy.size() > currHierarchyClone.size()) {
-                    buildHierarchy = (ArrayList<String>) currHierarchyClone
-                            .clone(); // Shallow copy as required
+                    buildHierarchy = (ArrayList<String>) currHierarchyClone.clone(); // Shallow
+                                                                                     // copy
+                                                                                     // as
+                                                                                     // required
                     fullHierarchy.add(buildHierarchy);
                 }
                 updateCurrentHierarchy(dstNode, buildHierarchy, fullHierarchy);
@@ -842,8 +840,7 @@ public class HostTracker implements IfIptoHost, IfHostListener,
             }
 
             if (!srcType.equals(NodeConnector.NodeConnectorIDType.OPENFLOW)) {
-                logger.error("For now we cannot handle updates for "
-                        + "non-openflow nodes");
+                logger.error("For now we cannot handle updates for " + "non-openflow nodes");
                 return;
             }
 
@@ -853,8 +850,7 @@ public class HostTracker implements IfIptoHost, IfHostListener,
             }
 
             if (!dstType.equals(NodeConnector.NodeConnectorIDType.OPENFLOW)) {
-                logger.error("For now we cannot handle updates for "
-                        + "non-openflow nodes");
+                logger.error("For now we cannot handle updates for " + "non-openflow nodes");
                 return;
             }
 
@@ -876,8 +872,7 @@ public class HostTracker implements IfIptoHost, IfHostListener,
             }
         }
 
-        logger.debug(
-                "HostTracker Topology linkUpdate handling src:{}[port {}] dst:{}[port {}] added: {}",
+        logger.debug("HostTracker Topology linkUpdate handling src:{}[port {}] dst:{}[port {}] added: {}",
                 new Object[] { srcNid, srcPort, dstNid, dstPort, added });
     }
 
@@ -891,21 +886,21 @@ public class HostTracker implements IfIptoHost, IfHostListener,
         }
     }
 
+    @Override
     public void subnetNotify(Subnet sub, boolean add) {
         logger.debug("Received subnet notification: {}  add={}", sub, add);
         if (add) {
             for (int i = 0; i < failedARPReqList.size(); i++) {
                 ARPPending arphost;
                 arphost = failedARPReqList.get(i);
-                logger.debug(
-                        "Sending the ARP from FailedARPReqList fors IP: {}",
-                        arphost.getHostIP().getHostAddress());
+                logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostIP().getHostAddress());
                 hostFinder.find(arphost.getHostIP());
             }
         }
     }
 
     class OutStandingARPHandler extends TimerTask {
+        @Override
         public void run() {
             ARPPending arphost;
             /* This routine runs every 4 seconds */
@@ -919,43 +914,37 @@ public class HostTracker implements IfIptoHost, IfHostListener,
                      */
                     hostFinder.find(arphost.getHostIP());
                     arphost.sent_count++;
-                    logger.debug("ARP Sent from ARPPending List, IP: {}",
-                            arphost.getHostIP().getHostAddress());
-                } else if (arphost.getSent_count() >= switchManager
-                        .getHostRetryCount()) {
+                    logger.debug("ARP Sent from ARPPending List, IP: {}", arphost.getHostIP().getHostAddress());
+                } else if (arphost.getSent_count() >= switchManager.getHostRetryCount()) {
                     /*
                      * Two ARP requests have been sent without receiving a
                      * reply, remove this from the pending list
                      */
                     removePendingARPFromList(i);
-                    logger.debug(
-                            "ARP reply not received after two attempts, removing from Pending List IP: {}",
+                    logger.debug("ARP reply not received after two attempts, removing from Pending List IP: {}",
                             arphost.getHostIP().getHostAddress());
                     /*
                      * Add this host to a different list which will be processed
                      * on link up events
                      */
-                    logger.debug("Adding the host to FailedARPReqList IP: {}",
-                            arphost.getHostIP().getHostAddress());
+                    logger.debug("Adding the host to FailedARPReqList IP: {}", arphost.getHostIP().getHostAddress());
                     failedARPReqList.add(arphost);
 
                 } else {
-                    logger.error(
-                            "Inavlid arp_sent count for entery at index: {}", i);
+                    logger.error("Inavlid arp_sent count for entery at index: {}", i);
                 }
             }
         }
     }
 
     private class ARPRefreshHandler extends TimerTask {
+        @Override
         @SuppressWarnings("deprecation")
         public void run() {
-            if ((clusterContainerService != null)
-                    && !clusterContainerService.amICoordinator()) {
+            if ((clusterContainerService != null) && !clusterContainerService.amICoordinator()) {
                 return;
             }
-            if ((switchManager != null)
-                    && !switchManager.isHostRefreshEnabled()) {
+            if ((switchManager != null) && !switchManager.isHostRefreshEnabled()) {
                 /*
                  * The host probe procedure was disabled by CLI
                  */
@@ -966,8 +955,7 @@ public class HostTracker implements IfIptoHost, IfHostListener,
                 logger.error("ARPRefreshHandler(): hostsDB is not allocated yet:");
                 return;
             }
-            for (Entry<InetAddress, HostNodeConnector> entry : hostsDB
-                    .entrySet()) {
+            for (Entry<InetAddress, HostNodeConnector> entry : hostsDB.entrySet()) {
                 HostNodeConnector host = entry.getValue();
                 if (host.isStaticHost()) {
                     /* this host was learned via API3, don't age it out */
@@ -993,12 +981,8 @@ public class HostTracker implements IfIptoHost, IfHostListener,
                     if (logger.isTraceEnabled()) {
                         logger.trace(
                                 "ARP Probing ({}) for {}({})",
-                                new Object[] {
-                                        arp_cntdown,
-                                        host.getNetworkAddress()
-                                                .getHostAddress(),
-                                        HexEncode.bytesToHexString(host
-                                                .getDataLayerAddressBytes()) });
+                                new Object[] { arp_cntdown, host.getNetworkAddress().getHostAddress(),
+                                        HexEncode.bytesToHexString(host.getDataLayerAddressBytes()) });
                     }
                     host.setArpSendCountDown(arp_cntdown);
                     hostFinder.probe(host);
@@ -1026,16 +1010,18 @@ public class HostTracker implements IfIptoHost, IfHostListener,
      *         indicating the result of this action.
      */
 
-    public Status addStaticHostReq(InetAddress networkAddr,
-            byte[] dataLayerAddress, NodeConnector nc, short vlan) {
-        if (dataLayerAddress.length != 6) {
+    public Status addStaticHostReq(InetAddress networkAddr, byte[] dataLayerAddress, NodeConnector nc, short vlan) {
+        if (dataLayerAddress.length != NetUtils.MACAddrLengthInBytes) {
             return new Status(StatusCode.BADREQUEST, "Invalid MAC address");
         }
 
+        if (nc == null) {
+            return new Status(StatusCode.BADREQUEST, "Invalid NodeConnector");
+        }
+
         HostNodeConnector host = null;
         try {
-            host = new HostNodeConnector(dataLayerAddress, networkAddr, nc,
-                    vlan);
+            host = new HostNodeConnector(dataLayerAddress, networkAddr, nc, vlan);
             if (hostExists(host)) {
                 // This host is already learned either via ARP or through a
                 // northbound request
@@ -1043,6 +1029,12 @@ public class HostTracker implements IfIptoHost, IfHostListener,
                 transHost.setStaticHost(true);
                 return new Status(StatusCode.SUCCESS, null);
             }
+
+            if (hostsDB.get(networkAddr) != null) {
+                // There is already a host with this IP address (but behind
+                // a different (switch, port, vlan) tuple. Return an error
+                return new Status(StatusCode.CONFLICT, "Existing IP, Use PUT to update");
+            }
             host.setStaticHost(true);
             /*
              * Before adding host, Check if the switch and the port have already
@@ -1053,14 +1045,13 @@ public class HostTracker implements IfIptoHost, IfHostListener,
                 notifyHostLearnedOrRemoved(host, true);
             } else {
                 inactiveStaticHosts.put(nc, host);
-                logger.debug(
-                        "Switch or switchport is not up, adding host {} to inactive list",
+                logger.debug("Switch or switchport is not up, adding host {} to inactive list",
                         networkAddr.getHostName());
             }
             return new Status(StatusCode.SUCCESS, null);
         } catch (ConstructionException e) {
-            return new Status(StatusCode.INTERNALERROR,
-                    "Host could not be created");
+            logger.error("", e);
+            return new Status(StatusCode.INTERNALERROR, "Host could not be created");
         }
 
     }
@@ -1080,29 +1071,61 @@ public class HostTracker implements IfIptoHost, IfHostListener,
      * @param vlan
      *            Vlan of which this host is member of
      *
-     * @return boolean true if the host was added successfully, false otherwise
+     * @return Status The status object as described in {@code Status}
+     *         indicating the result of this action.
      */
-    public boolean updateHostReq(InetAddress networkAddr,
-            byte[] dataLayerAddress, NodeConnector nc, short vlan) {
+    public Status updateHostReq(InetAddress networkAddr, byte[] dataLayerAddress, NodeConnector nc, short vlan) {
+        HostNodeConnector tobeUpdatedHost;
+        HostNodeConnector host = null;
+
+        if (dataLayerAddress.length != NetUtils.MACAddrLengthInBytes) {
+            return new Status(StatusCode.BADREQUEST, "Invalid MAC address");
+        }
+
         if (nc == null) {
-            return false;
+            return new Status(StatusCode.BADREQUEST, "Invalid NodeConnector");
         }
-        HostNodeConnector host = null;
+
         try {
-            host = new HostNodeConnector(dataLayerAddress, networkAddr, nc,
-                    vlan);
-            if (!hostExists(host)) {
-                if ((inactiveStaticHosts.get(nc)) != null) {
-                    inactiveStaticHosts.replace(nc, host);
-                    return true;
+            host = new HostNodeConnector(dataLayerAddress, networkAddr, nc, vlan);
+            if (hostExists(host)) {
+                return new Status(StatusCode.BADREQUEST, "Host already exists");
+            }
+
+            if ((tobeUpdatedHost = hostsDB.get(networkAddr)) != null) {
+                if (hostsDB.replace(networkAddr, tobeUpdatedHost, host)) {
+                    logger.debug("Host replaced from hostsDB. Old host: {} New Host: {}", tobeUpdatedHost, host);
+                    notifyHostLearnedOrRemoved(tobeUpdatedHost, false);
+                    notifyHostLearnedOrRemoved(host, true);
+                    return new Status(StatusCode.SUCCESS);
+                } else {
+                    logger.error("Static host replacement failed from hostsDB, Replaced Host: {}, New Host: {}",
+                            tobeUpdatedHost, host);
+                    return new Status(StatusCode.INTERNALERROR,
+                            "Host Replacement Failed due to presence of another host with same IP");
                 }
-                return false;
             }
-            hostsDB.replace(networkAddr, host);
-            return true;
+
+            // Check if the host exists in inactive hosts database
+            if ((tobeUpdatedHost = inactiveStaticHosts.get(nc)) != null) {
+                if (inactiveStaticHosts.replace(nc, tobeUpdatedHost, host)) {
+                    logger.debug("Host replaced from inactive hostsDB. Old host: {} New Host: {}", tobeUpdatedHost,
+                            host);
+                    return new Status(StatusCode.SUCCESS);
+                } else {
+                    logger.error("Static host replacement failed, Replaced Host: {}, New Host: {}", tobeUpdatedHost,
+                            host);
+                    return new Status(StatusCode.INTERNALERROR,
+                            "Host Replacement Failed due to presence of another host with same IP");
+                }
+            }
+
+            // Host doesn't exist
+            return new Status(StatusCode.BADREQUEST, "Host doesn't exists, can't update");
         } catch (ConstructionException e) {
+            logger.error("", e);
+            return new Status(StatusCode.INTERNALERROR, "host object creation failure");
         }
-        return false;
     }
 
     /**
@@ -1122,8 +1145,7 @@ public class HostTracker implements IfIptoHost, IfHostListener,
         if (host != null) {
             // Validation check
             if (!host.isStaticHost()) {
-                return new Status(StatusCode.FORBIDDEN, "Host "
-                        + networkAddress.getHostName() + " is not static");
+                return new Status(StatusCode.FORBIDDEN, "Host " + networkAddress.getHostName() + " is not static");
             }
             // Remove and notify
             notifyHostLearnedOrRemoved(host, false);
@@ -1137,8 +1159,7 @@ public class HostTracker implements IfIptoHost, IfHostListener,
             host = entry.getValue();
             // Validation check
             if (!host.isStaticHost()) {
-                return new Status(StatusCode.FORBIDDEN, "Host "
-                        + networkAddress.getHostName() + " is not static");
+                return new Status(StatusCode.FORBIDDEN, "Host " + networkAddress.getHostName() + " is not static");
             }
             this.removeHostFromInactiveDB(networkAddress);
             return new Status(StatusCode.SUCCESS, null);
@@ -1154,16 +1175,14 @@ public class HostTracker implements IfIptoHost, IfHostListener,
     }
 
     @Override
-    public void notifyNode(Node node, UpdateType type,
-            Map<String, Property> propMap) {
+    public void notifyNode(Node node, UpdateType type, Map<String, Property> propMap) {
         if (node == null)
             return;
 
         switch (type) {
         case REMOVED:
             logger.debug("Received removed node {}", node);
-            for (Entry<InetAddress, HostNodeConnector> entry : hostsDB
-                    .entrySet()) {
+            for (Entry<InetAddress, HostNodeConnector> entry : hostsDB.entrySet()) {
                 HostNodeConnector host = entry.getValue();
                 if (host.getnodeconnectorNode().equals(node)) {
                     logger.debug("Node: {} is down, remove from Hosts_DB", node);
@@ -1178,8 +1197,7 @@ public class HostTracker implements IfIptoHost, IfHostListener,
     }
 
     @Override
-    public void notifyNodeConnector(NodeConnector nodeConnector,
-            UpdateType type, Map<String, Property> propMap) {
+    public void notifyNodeConnector(NodeConnector nodeConnector, UpdateType type, Map<String, Property> propMap) {
         if (nodeConnector == null)
             return;
 
@@ -1208,16 +1226,13 @@ public class HostTracker implements IfIptoHost, IfHostListener,
     }
 
     @Override
-    public Status addStaticHost(String networkAddress, String dataLayerAddress,
-            NodeConnector nc, String vlan) {
+    public Status addStaticHost(String networkAddress, String dataLayerAddress, NodeConnector nc, String vlan) {
         try {
             InetAddress ip = InetAddress.getByName(networkAddress);
             if (nc == null) {
                 return new Status(StatusCode.BADREQUEST, "Invalid NodeId");
             }
-            return addStaticHostReq(ip,
-                    HexEncode.bytesFromHexString(dataLayerAddress), nc,
-                    Short.valueOf(vlan));
+            return addStaticHostReq(ip, HexEncode.bytesFromHexString(dataLayerAddress), nc, Short.valueOf(vlan));
         } catch (UnknownHostException e) {
             logger.error("", e);
             return new Status(StatusCode.BADREQUEST, "Invalid Address");
@@ -1243,8 +1258,7 @@ public class HostTracker implements IfIptoHost, IfHostListener,
 
         for (int i = 0; i < failedARPReqList.size(); i++) {
             arphost = failedARPReqList.get(i);
-            logger.debug("Sending the ARP from FailedARPReqList fors IP: {}",
-                    arphost.getHostIP().getHostAddress());
+            logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostIP().getHostAddress());
             hostFinder.find(arphost.getHostIP());
         }
         HostNodeConnector host = inactiveStaticHosts.get(nodeConnector);
@@ -1261,9 +1275,7 @@ public class HostTracker implements IfIptoHost, IfHostListener,
         for (Entry<InetAddress, HostNodeConnector> entry : hostsDB.entrySet()) {
             HostNodeConnector host = entry.getValue();
             if (host.getnodeConnector().equals(nodeConnector)) {
-                logger.debug(
-                        " NodeConnector: {} is down, remove from Hosts_DB",
-                        nodeConnector);
+                logger.debug(" NodeConnector: {} is down, remove from Hosts_DB", nodeConnector);
                 removeKnownHost(entry.getKey());
                 notifyHostLearnedOrRemoved(host, false);
             }
index 103a515607a49b043475ca59925c545d6d439586..797bca798f7d811c491e318bc4fddda1d9710899 100644 (file)
@@ -24,7 +24,11 @@ import java.io.OutputStreamWriter;
 import java.net.HttpURLConnection;
 import java.net.URL;
 import java.nio.charset.Charset;
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 import org.apache.commons.codec.binary.Base64;
 
@@ -34,10 +38,17 @@ import org.codehaus.jettison.json.JSONObject;
 import org.codehaus.jettison.json.JSONTokener;
 
 import org.opendaylight.controller.hosttracker.IfIptoHost;
+import org.opendaylight.controller.sal.core.Bandwidth;
 import org.opendaylight.controller.sal.core.ConstructionException;
+import org.opendaylight.controller.sal.core.Edge;
+import org.opendaylight.controller.sal.core.Latency;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.core.State;
 import org.opendaylight.controller.sal.core.UpdateType;
+import org.opendaylight.controller.sal.topology.IListenTopoUpdates;
+import org.opendaylight.controller.sal.topology.TopoEdgeUpdate;
 import org.opendaylight.controller.switchmanager.IInventoryListener;
 import org.opendaylight.controller.usermanager.IUserManager;
 
@@ -49,6 +60,9 @@ public class NorthboundIT {
     private BundleContext bc;
     private IUserManager users = null;
     private IInventoryListener invtoryListener = null;
+    private IListenTopoUpdates topoUpdates = null;
+
+    private Boolean debugMsg = false;
 
     private String stateToString(int state) {
         switch (state) {
@@ -73,20 +87,17 @@ public class NorthboundIT {
         for (int i = 0; i < b.length; i++) {
             int state = b[i].getState();
             if (state != Bundle.ACTIVE && state != Bundle.RESOLVED) {
-                log.debug("Bundle:" + b[i].getSymbolicName() + " state:"
-                        + stateToString(state));
+                log.debug("Bundle:" + b[i].getSymbolicName() + " state:" + stateToString(state));
                 debugit = true;
             }
         }
         if (debugit) {
-            log.debug("Do some debugging because some bundle is "
-                    + "unresolved");
+            log.debug("Do some debugging because some bundle is " + "unresolved");
         }
         // Assert if true, if false we are good to go!
         assertFalse(debugit);
 
-        ServiceReference r = bc.getServiceReference(IUserManager.class
-                .getName());
+        ServiceReference r = bc.getServiceReference(IUserManager.class.getName());
         if (r != null) {
             this.users = (IUserManager) bc.getService(r);
         }
@@ -101,6 +112,14 @@ public class NorthboundIT {
         // If inventoryListener is null, cannot run hosttracker tests.
         assertNotNull(this.invtoryListener);
 
+        r = bc.getServiceReference(IListenTopoUpdates.class.getName());
+        if (r != null) {
+            this.topoUpdates = (IListenTopoUpdates) bc.getService(r);
+        }
+
+        // If topologyManager is null, cannot run topology North tests.
+        assertNotNull(this.topoUpdates);
+
     }
 
     // static variable to pass response code from getJsonResult()
@@ -118,6 +137,12 @@ public class NorthboundIT {
         // initialize response code to indicate error
         httpResponseCode = 400;
 
+        if (debugMsg) {
+            System.out.println("HTTP method: " + method + " url: " + restUrl.toString());
+            if (body != null)
+                System.out.println("body: " + body);
+        }
+
         try {
             URL url = new URL(restUrl);
             this.users.getAuthorizationList();
@@ -126,18 +151,15 @@ public class NorthboundIT {
             byte[] authEncBytes = Base64.encodeBase64(authString.getBytes());
             String authStringEnc = new String(authEncBytes);
 
-            HttpURLConnection connection = (HttpURLConnection) url
-                    .openConnection();
+            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
             connection.setRequestMethod(method);
-            connection.setRequestProperty("Authorization", "Basic "
-                    + authStringEnc);
+            connection.setRequestProperty("Authorization", "Basic " + authStringEnc);
             connection.setRequestProperty("Content-Type", "application/json");
             connection.setRequestProperty("Accept", "application/json");
 
             if (body != null) {
                 connection.setDoOutput(true);
-                OutputStreamWriter wr = new OutputStreamWriter(
-                        connection.getOutputStream());
+                OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream());
                 wr.write(body);
                 wr.flush();
             }
@@ -149,9 +171,13 @@ public class NorthboundIT {
             if (httpResponseCode > 299)
                 return httpResponseCode.toString();
 
+            if (debugMsg) {
+                System.out.println("HTTP response code: " + connection.getResponseCode());
+                System.out.println("HTTP response message: " + connection.getResponseMessage());
+            }
+
             InputStream is = connection.getInputStream();
-            BufferedReader rd = new BufferedReader(new InputStreamReader(is,
-                    Charset.forName("UTF-8")));
+            BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
             StringBuilder sb = new StringBuilder();
             int cp;
             while ((cp = rd.read()) != -1) {
@@ -165,10 +191,9 @@ public class NorthboundIT {
         }
     }
 
-    private void testNodeProperties(JSONObject node, Integer nodeId,
-            String nodeType, Integer timestamp, String timestampName,
-            Integer actionsValue, Integer capabilitiesValue,
-            Integer tablesValue, Integer buffersValue) throws JSONException {
+    private void testNodeProperties(JSONObject node, Integer nodeId, String nodeType, Integer timestamp,
+            String timestampName, Integer actionsValue, Integer capabilitiesValue, Integer tablesValue,
+            Integer buffersValue) throws JSONException {
 
         JSONObject nodeInfo = node.getJSONObject("node");
         Assert.assertEquals(nodeId, (Integer) nodeInfo.getInt("@id"));
@@ -179,51 +204,39 @@ public class NorthboundIT {
         if (timestamp == null || timestampName == null) {
             Assert.assertFalse(properties.has("timeStamp"));
         } else {
-            Assert.assertEquals(
-                    timestamp,
-                    (Integer) properties.getJSONObject("timeStamp").getInt(
-                            "timestamp"));
-            Assert.assertEquals(
-                    timestampName,
-                    properties.getJSONObject("timeStamp").getString(
-                            "timestampName"));
+            Assert.assertEquals(timestamp, (Integer) properties.getJSONObject("timeStamp").getInt("timestamp"));
+            Assert.assertEquals(timestampName, properties.getJSONObject("timeStamp").getString("timestampName"));
         }
         if (actionsValue == null) {
             Assert.assertFalse(properties.has("actions"));
         } else {
-            Assert.assertEquals(actionsValue, (Integer) properties
-                    .getJSONObject("actions").getInt("actionsValue"));
+            Assert.assertEquals(actionsValue, (Integer) properties.getJSONObject("actions").getInt("actionsValue"));
         }
         if (capabilitiesValue == null) {
             Assert.assertFalse(properties.has("capabilities"));
         } else {
-            Assert.assertEquals(capabilitiesValue, (Integer) properties
-                    .getJSONObject("capabilities").getInt("capabilitiesValue"));
+            Assert.assertEquals(capabilitiesValue,
+                    (Integer) properties.getJSONObject("capabilities").getInt("capabilitiesValue"));
         }
         if (tablesValue == null) {
             Assert.assertFalse(properties.has("tables"));
         } else {
-            Assert.assertEquals(tablesValue, (Integer) properties
-                    .getJSONObject("tables").getInt("tablesValue"));
+            Assert.assertEquals(tablesValue, (Integer) properties.getJSONObject("tables").getInt("tablesValue"));
         }
         if (buffersValue == null) {
             Assert.assertFalse(properties.has("buffers"));
         } else {
-            Assert.assertEquals(buffersValue, (Integer) properties
-                    .getJSONObject("buffers").getInt("buffersValue"));
+            Assert.assertEquals(buffersValue, (Integer) properties.getJSONObject("buffers").getInt("buffersValue"));
         }
     }
 
-    private void testNodeConnectorProperties(
-            JSONObject nodeConnectorProperties, Integer ncId, String ncType,
-            Integer nodeId, String nodeType, Integer state,
-            Integer capabilities, Integer bandwidth) throws JSONException {
+    private void testNodeConnectorProperties(JSONObject nodeConnectorProperties, Integer ncId, String ncType,
+            Integer nodeId, String nodeType, Integer state, Integer capabilities, Integer bandwidth)
+            throws JSONException {
 
-        JSONObject nodeConnector = nodeConnectorProperties
-                .getJSONObject("nodeconnector");
+        JSONObject nodeConnector = nodeConnectorProperties.getJSONObject("nodeconnector");
         JSONObject node = nodeConnector.getJSONObject("node");
-        JSONObject properties = nodeConnectorProperties
-                .getJSONObject("properties");
+        JSONObject properties = nodeConnectorProperties.getJSONObject("properties");
 
         Assert.assertEquals(ncId, (Integer) nodeConnector.getInt("@id"));
         Assert.assertEquals(ncType, nodeConnector.getString("@type"));
@@ -232,30 +245,25 @@ public class NorthboundIT {
         if (state == null) {
             Assert.assertFalse(properties.has("state"));
         } else {
-            Assert.assertEquals(
-                    state,
-                    (Integer) properties.getJSONObject("state").getInt(
-                            "stateValue"));
+            Assert.assertEquals(state, (Integer) properties.getJSONObject("state").getInt("stateValue"));
         }
         if (capabilities == null) {
             Assert.assertFalse(properties.has("capabilities"));
         } else {
-            Assert.assertEquals(capabilities, (Integer) properties
-                    .getJSONObject("capabilities").getInt("capabilitiesValue"));
+            Assert.assertEquals(capabilities,
+                    (Integer) properties.getJSONObject("capabilities").getInt("capabilitiesValue"));
         }
         if (bandwidth == null) {
             Assert.assertFalse(properties.has("bandwidth"));
         } else {
-            Assert.assertEquals(
-                    bandwidth,
-                    (Integer) properties.getJSONObject("bandwidth").getInt(
-                            "bandwidthValue"));
+            Assert.assertEquals(bandwidth, (Integer) properties.getJSONObject("bandwidth").getInt("bandwidthValue"));
         }
 
     }
 
     @Test
     public void testSubnetsNorthbound() throws JSONException {
+        System.out.println("Starting Subnets JAXB client.");
         String baseURL = "http://127.0.0.1:8080/controller/nb/v2/subnet/";
 
         String name1 = "testSubnet1";
@@ -274,10 +282,8 @@ public class NorthboundIT {
         Assert.assertEquals(404, httpResponseCode.intValue());
 
         // Test POST subnet1
-        String queryParameter = new QueryParameter("subnetName", name1).add(
-                "subnet", subnet1).getString();
-        result = getJsonResult(baseURL + "default/" + name1 + queryParameter,
-                "POST");
+        String queryParameter = new QueryParameter("subnetName", name1).add("subnet", subnet1).getString();
+        result = getJsonResult(baseURL + "default/" + name1 + queryParameter, "POST");
         Assert.assertEquals(201, httpResponseCode.intValue());
 
         // Test GET subnet1
@@ -289,10 +295,8 @@ public class NorthboundIT {
         Assert.assertEquals(subnet1, json.getString("@subnet"));
 
         // Test POST subnet2
-        queryParameter = new QueryParameter("subnetName", name2).add("subnet",
-                subnet2).getString();
-        result = getJsonResult(baseURL + "default/" + name2 + queryParameter,
-                "POST");
+        queryParameter = new QueryParameter("subnetName", name2).add("subnet", subnet2).getString();
+        result = getJsonResult(baseURL + "default/" + name2 + queryParameter, "POST");
         Assert.assertEquals(201, httpResponseCode.intValue());
 
         // Test GET all subnets in default container
@@ -326,6 +330,7 @@ public class NorthboundIT {
 
     @Test
     public void testStaticRoutingNorthbound() throws JSONException {
+        System.out.println("Starting StaticRouting JAXB client.");
         String baseURL = "http://127.0.0.1:8080/controller/nb/v2/staticroute/";
 
         String name1 = "testRoute1";
@@ -342,16 +347,13 @@ public class NorthboundIT {
         Assert.assertEquals("{}", result);
 
         // Test insert static route
-        String requestBody = "{\"name\":\"" + name1 + "\", \"prefix\":\""
-                + prefix1 + "\", \"nextHop\":\"" + nextHop1 + "\"}";
-        result = getJsonResult(baseURL + "default/" + name1, "POST",
-                requestBody);
+        String requestBody = "{\"name\":\"" + name1 + "\", \"prefix\":\"" + prefix1 + "\", \"nextHop\":\"" + nextHop1
+                + "\"}";
+        result = getJsonResult(baseURL + "default/" + name1, "POST", requestBody);
         Assert.assertEquals(201, httpResponseCode.intValue());
 
-        requestBody = "{\"name\":\"" + name2 + "\", \"prefix\":\"" + prefix2
-                + "\", \"nextHop\":\"" + nextHop2 + "\"}";
-        result = getJsonResult(baseURL + "default/" + name2, "POST",
-                requestBody);
+        requestBody = "{\"name\":\"" + name2 + "\", \"prefix\":\"" + prefix2 + "\", \"nextHop\":\"" + nextHop2 + "\"}";
+        result = getJsonResult(baseURL + "default/" + name2, "POST", requestBody);
         Assert.assertEquals(201, httpResponseCode.intValue());
 
         // Test Get all static routes
@@ -406,6 +408,7 @@ public class NorthboundIT {
 
     @Test
     public void testSwitchManager() throws JSONException {
+        System.out.println("Starting SwitchManager JAXB client.");
         String baseURL = "http://127.0.0.1:8080/controller/nb/v2/switch/default/";
 
         // define Node/NodeConnector attributes for test
@@ -436,22 +439,19 @@ public class NorthboundIT {
         // Test for first node
         JSONObject node = getJsonInstance(json, "nodeProperties", nodeId_1);
         Assert.assertNotNull(node);
-        testNodeProperties(node, nodeId_1, nodeType, timestamp_1,
-                timestampName_1, actionsValue_1, capabilitiesValue_1,
+        testNodeProperties(node, nodeId_1, nodeType, timestamp_1, timestampName_1, actionsValue_1, capabilitiesValue_1,
                 tablesValue_1, buffersValue_1);
 
         // Test 2nd node, properties of 2nd node same as first node
         node = getJsonInstance(json, "nodeProperties", nodeId_2);
         Assert.assertNotNull(node);
-        testNodeProperties(node, nodeId_2, nodeType, timestamp_1,
-                timestampName_1, actionsValue_1, capabilitiesValue_1,
+        testNodeProperties(node, nodeId_2, nodeType, timestamp_1, timestampName_1, actionsValue_1, capabilitiesValue_1,
                 tablesValue_1, buffersValue_1);
 
         // Test 3rd node, properties of 3rd node same as first node
         node = getJsonInstance(json, "nodeProperties", nodeId_3);
         Assert.assertNotNull(node);
-        testNodeProperties(node, nodeId_3, nodeType, timestamp_1,
-                timestampName_1, actionsValue_1, capabilitiesValue_1,
+        testNodeProperties(node, nodeId_3, nodeType, timestamp_1, timestampName_1, actionsValue_1, capabilitiesValue_1,
                 tablesValue_1, buffersValue_1);
 
         // Test GET nodeConnectors of a node
@@ -459,12 +459,10 @@ public class NorthboundIT {
         result = getJsonResult(baseURL + "node/STUB/" + nodeId_1);
         jt = new JSONTokener(result);
         json = new JSONObject(jt);
-        JSONObject nodeConnectorProperties = json
-                .getJSONObject("nodeConnectorProperties");
+        JSONObject nodeConnectorProperties = json.getJSONObject("nodeConnectorProperties");
 
-        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_1,
-                ncType, nodeId_1, nodeType, ncState, ncCapabilities,
-                ncBandwidth);
+        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_1, ncType, nodeId_1, nodeType, ncState,
+                ncCapabilities, ncBandwidth);
 
         // Test second node
         result = getJsonResult(baseURL + "node/STUB/" + nodeId_2);
@@ -472,9 +470,8 @@ public class NorthboundIT {
         json = new JSONObject(jt);
         nodeConnectorProperties = json.getJSONObject("nodeConnectorProperties");
 
-        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_2,
-                ncType, nodeId_2, nodeType, ncState, ncCapabilities,
-                ncBandwidth);
+        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_2, ncType, nodeId_2, nodeType, ncState,
+                ncCapabilities, ncBandwidth);
 
         // Test third node
         result = getJsonResult(baseURL + "node/STUB/" + nodeId_3);
@@ -482,14 +479,12 @@ public class NorthboundIT {
         json = new JSONObject(jt);
 
         nodeConnectorProperties = json.getJSONObject("nodeConnectorProperties");
-        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_3,
-                ncType, nodeId_3, nodeType, ncState, ncCapabilities,
-                ncBandwidth);
+        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_3, ncType, nodeId_3, nodeType, ncState,
+                ncCapabilities, ncBandwidth);
 
         // Test delete node property
         // Delete timestamp property from node1
-        result = getJsonResult(baseURL + "node/STUB/" + nodeId_1
-                + "/property/timeStamp", "DELETE");
+        result = getJsonResult(baseURL + "node/STUB/" + nodeId_1 + "/property/timeStamp", "DELETE");
         Assert.assertEquals(200, httpResponseCode.intValue());
 
         // Check node1
@@ -498,13 +493,11 @@ public class NorthboundIT {
         json = new JSONObject(jt);
         node = getJsonInstance(json, "nodeProperties", nodeId_1);
         Assert.assertNotNull(node);
-        testNodeProperties(node, nodeId_1, nodeType, null, null,
-                actionsValue_1, capabilitiesValue_1, tablesValue_1,
+        testNodeProperties(node, nodeId_1, nodeType, null, null, actionsValue_1, capabilitiesValue_1, tablesValue_1,
                 buffersValue_1);
 
         // Delete actions property from node2
-        result = getJsonResult(baseURL + "node/STUB/" + nodeId_2
-                + "/property/actions", "DELETE");
+        result = getJsonResult(baseURL + "node/STUB/" + nodeId_2 + "/property/actions", "DELETE");
         Assert.assertEquals(200, httpResponseCode.intValue());
 
         // Check node2
@@ -513,17 +506,14 @@ public class NorthboundIT {
         json = new JSONObject(jt);
         node = getJsonInstance(json, "nodeProperties", nodeId_2);
         Assert.assertNotNull(node);
-        testNodeProperties(node, nodeId_2, nodeType, timestamp_1,
-                timestampName_1, null, capabilitiesValue_1, tablesValue_1,
-                buffersValue_1);
+        testNodeProperties(node, nodeId_2, nodeType, timestamp_1, timestampName_1, null, capabilitiesValue_1,
+                tablesValue_1, buffersValue_1);
 
         // Test add property to node
         // Add Tier and Bandwidth property to node1
-        result = getJsonResult(baseURL + "node/STUB/" + nodeId_1
-                + "/property/tier/1001", "PUT");
+        result = getJsonResult(baseURL + "node/STUB/" + nodeId_1 + "/property/tier/1001", "PUT");
         Assert.assertEquals(201, httpResponseCode.intValue());
-        result = getJsonResult(baseURL + "node/STUB/" + nodeId_1
-                + "/property/bandwidth/1002", "PUT");
+        result = getJsonResult(baseURL + "node/STUB/" + nodeId_1 + "/property/bandwidth/1002", "PUT");
         Assert.assertEquals(201, httpResponseCode.intValue());
 
         // Test for first node
@@ -532,15 +522,13 @@ public class NorthboundIT {
         json = new JSONObject(jt);
         node = getJsonInstance(json, "nodeProperties", nodeId_1);
         Assert.assertNotNull(node);
-        Assert.assertEquals(1001, node.getJSONObject("properties")
-                .getJSONObject("tier").getInt("tierValue"));
-        Assert.assertEquals(1002, node.getJSONObject("properties")
-                .getJSONObject("bandwidth").getInt("bandwidthValue"));
+        Assert.assertEquals(1001, node.getJSONObject("properties").getJSONObject("tier").getInt("tierValue"));
+        Assert.assertEquals(1002, node.getJSONObject("properties").getJSONObject("bandwidth").getInt("bandwidthValue"));
 
         // Test delete nodeConnector property
         // Delete state property of nodeconnector1
-        result = getJsonResult(baseURL + "nodeconnector/STUB/" + nodeId_1
-                + "/STUB/" + nodeConnectorId_1 + "/property/state", "DELETE");
+        result = getJsonResult(baseURL + "nodeconnector/STUB/" + nodeId_1 + "/STUB/" + nodeConnectorId_1
+                + "/property/state", "DELETE");
         Assert.assertEquals(200, httpResponseCode.intValue());
 
         result = getJsonResult(baseURL + "node/STUB/" + nodeId_1);
@@ -548,13 +536,12 @@ public class NorthboundIT {
         json = new JSONObject(jt);
         nodeConnectorProperties = json.getJSONObject("nodeConnectorProperties");
 
-        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_1,
-                ncType, nodeId_1, nodeType, null, ncCapabilities, ncBandwidth);
+        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_1, ncType, nodeId_1, nodeType, null,
+                ncCapabilities, ncBandwidth);
 
         // Delete capabilities property of nodeconnector2
-        result = getJsonResult(baseURL + "nodeconnector/STUB/" + nodeId_2
-                + "/STUB/" + nodeConnectorId_2 + "/property/capabilities",
-                "DELETE");
+        result = getJsonResult(baseURL + "nodeconnector/STUB/" + nodeId_2 + "/STUB/" + nodeConnectorId_2
+                + "/property/capabilities", "DELETE");
         Assert.assertEquals(200, httpResponseCode.intValue());
 
         result = getJsonResult(baseURL + "node/STUB/" + nodeId_2);
@@ -562,16 +549,15 @@ public class NorthboundIT {
         json = new JSONObject(jt);
         nodeConnectorProperties = json.getJSONObject("nodeConnectorProperties");
 
-        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_2,
-                ncType, nodeId_2, nodeType, ncState, null, ncBandwidth);
+        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_2, ncType, nodeId_2, nodeType, ncState,
+                null, ncBandwidth);
 
         // Test PUT nodeConnector property
         int newBandwidth = 1001;
 
         // Add Name/Bandwidth property to nodeConnector1
-        result = getJsonResult(baseURL + "nodeconnector/STUB/" + nodeId_1
-                + "/STUB/" + nodeConnectorId_1 + "/property/bandwidth/"
-                + newBandwidth, "PUT");
+        result = getJsonResult(baseURL + "nodeconnector/STUB/" + nodeId_1 + "/STUB/" + nodeConnectorId_1
+                + "/property/bandwidth/" + newBandwidth, "PUT");
         Assert.assertEquals(201, httpResponseCode.intValue());
 
         result = getJsonResult(baseURL + "node/STUB/" + nodeId_1);
@@ -581,18 +567,16 @@ public class NorthboundIT {
 
         // Check for new bandwidth value, state value removed from previous
         // test
-        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_1,
-                ncType, nodeId_1, nodeType, null, ncCapabilities, newBandwidth);
+        testNodeConnectorProperties(nodeConnectorProperties, nodeConnectorId_1, ncType, nodeId_1, nodeType, null,
+                ncCapabilities, newBandwidth);
 
     }
 
     @Test
     public void testStatistics() throws JSONException {
-        String actionTypes[] = { "drop", "loopback", "flood", "floodAll",
-                "controller", "swPath", "hwPath", "output", "setDlSrc",
-                "setDlDst", "setDlType", "setVlanId", "setVlanPcp",
-                "setVlanCfi", "popVlan", "pushVlan", "setNwSrc", "setNwDst",
-                "setNwTos", "setTpSrc", "setTpDst" };
+        String actionTypes[] = { "drop", "loopback", "flood", "floodAll", "controller", "swPath", "hwPath", "output",
+                "setDlSrc", "setDlDst", "setDlType", "setVlanId", "setVlanPcp", "setVlanCfi", "popVlan", "pushVlan",
+                "setNwSrc", "setNwDst", "setNwTos", "setTpSrc", "setTpDst" };
         System.out.println("Starting Statistics JAXB client.");
 
         String baseURL = "http://127.0.0.1:8080/controller/nb/v2/statistics/default/";
@@ -600,12 +584,11 @@ public class NorthboundIT {
         String result = getJsonResult(baseURL + "flowstats");
         JSONTokener jt = new JSONTokener(result);
         JSONObject json = new JSONObject(jt);
-        JSONObject flowStatistics = getJsonInstance(json, "flowStatistics",
-                0xCAFE);
+        JSONObject flowStatistics = getJsonInstance(json, "flowStatistics", 0xCAFE);
         JSONObject node = flowStatistics.getJSONObject("node");
         // test that node was returned properly
         Assert.assertTrue(node.getInt("@id") == 0xCAFE);
-        Assert.assertTrue(node.getString("@type").equals("STUB"));
+        Assert.assertEquals(node.getString("@type"), "STUB");
 
         // test that flow statistics results are correct
         JSONArray flowStats = flowStatistics.getJSONArray("flowStat");
@@ -620,12 +603,11 @@ public class NorthboundIT {
         result = getJsonResult(baseURL + "portstats");
         jt = new JSONTokener(result);
         json = new JSONObject(jt);
-        JSONObject portStatistics = getJsonInstance(json, "portStatistics",
-                0xCAFE);
+        JSONObject portStatistics = getJsonInstance(json, "portStatistics", 0xCAFE);
         JSONObject node2 = portStatistics.getJSONObject("node");
         // test that node was returned properly
         Assert.assertTrue(node2.getInt("@id") == 0xCAFE);
-        Assert.assertTrue(node2.getString("@type").equals("STUB"));
+        Assert.assertEquals(node2.getString("@type"), "STUB");
 
         // test that port statistic results are correct
         JSONObject portStat = portStatistics.getJSONObject("portStat");
@@ -649,7 +631,7 @@ public class NorthboundIT {
         node = json.getJSONObject("node");
         // test that node was returned properly
         Assert.assertTrue(node.getInt("@id") == 0xCAFE);
-        Assert.assertTrue(node.getString("@type").equals("STUB"));
+        Assert.assertEquals(node.getString("@type"), "STUB");
 
         // test that flow statistics results are correct
         flowStats = json.getJSONArray("flowStat");
@@ -664,7 +646,7 @@ public class NorthboundIT {
         node2 = json.getJSONObject("node");
         // test that node was returned properly
         Assert.assertTrue(node2.getInt("@id") == 0xCAFE);
-        Assert.assertTrue(node2.getString("@type").equals("STUB"));
+        Assert.assertEquals(node2.getString("@type"), "STUB");
 
         // test that port statistic results are correct
         portStat = json.getJSONObject("portStat");
@@ -682,8 +664,7 @@ public class NorthboundIT {
         Assert.assertTrue(portStat.getInt("collisionCount") == 4);
     }
 
-    private void testFlowStat(JSONObject flowStat, String actionType)
-            throws JSONException {
+    private void testFlowStat(JSONObject flowStat, String actionType) throws JSONException {
         Assert.assertTrue(flowStat.getInt("tableId") == 1);
         Assert.assertTrue(flowStat.getInt("durationSeconds") == 40);
         Assert.assertTrue(flowStat.getInt("durationNanoseconds") == 400);
@@ -697,8 +678,7 @@ public class NorthboundIT {
         Assert.assertTrue(flow.getInt("hardTimeout") == 2000);
         Assert.assertTrue(flow.getInt("id") == 12345);
 
-        JSONObject match = (flow.getJSONObject("match")
-                .getJSONObject("matchField"));
+        JSONObject match = (flow.getJSONObject("match").getJSONObject("matchField"));
         Assert.assertTrue(match.getString("type").equals("NW_DST"));
         Assert.assertTrue(match.getString("value").equals("1.1.1.1"));
 
@@ -715,8 +695,7 @@ public class NorthboundIT {
         }
 
         if (act.getString("@type").equals("setDlSrc")) {
-            byte srcMatch[] = { (byte) 5, (byte) 4, (byte) 3, (byte) 2,
-                    (byte) 1 };
+            byte srcMatch[] = { (byte) 5, (byte) 4, (byte) 3, (byte) 2, (byte) 1 };
             String src = act.getString("address");
             byte srcBytes[] = new byte[5];
             srcBytes[0] = Byte.parseByte(src.substring(0, 2));
@@ -728,8 +707,7 @@ public class NorthboundIT {
         }
 
         if (act.getString("@type").equals("setDlDst")) {
-            byte dstMatch[] = { (byte) 1, (byte) 2, (byte) 3, (byte) 4,
-                    (byte) 5 };
+            byte dstMatch[] = { (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5 };
             String dst = act.getString("address");
             byte dstBytes[] = new byte[5];
             dstBytes[0] = Byte.parseByte(dst.substring(0, 2));
@@ -775,6 +753,7 @@ public class NorthboundIT {
 
     @Test
     public void testFlowProgrammer() throws JSONException {
+        System.out.println("Starting FlowProgrammer JAXB client.");
         String baseURL = "http://127.0.0.1:8080/controller/nb/v2/flow/default/";
         // Attempt to get a flow that doesn't exit. Should return 404
         // status.
@@ -792,12 +771,12 @@ public class NorthboundIT {
         Assert.assertTrue(httpResponseCode == 200);
         JSONTokener jt = new JSONTokener(result);
         JSONObject json = new JSONObject(jt);
-        Assert.assertTrue(json.getString("name").equals("test1"));
-        Assert.assertTrue(json.getString("actions").equals("DROP"));
-        Assert.assertTrue(json.getString("installInHw").equals("true"));
+        Assert.assertEquals(json.getString("name"), "test1");
+        Assert.assertEquals(json.getString("actions"), "DROP");
+        Assert.assertEquals(json.getString("installInHw"), "true");
         JSONObject node = json.getJSONObject("node");
-        Assert.assertTrue(node.getString("@type").equals("STUB"));
-        Assert.assertTrue(node.getString("@id").equals("51966"));
+        Assert.assertEquals(node.getString("@type"), "STUB");
+        Assert.assertEquals(node.getString("@id"), "51966");
         // test adding same flow again fails due to repeat name..return 409
         // code
         result = getJsonResult(baseURL + "STUB/51966/test1", "POST", fc);
@@ -844,8 +823,7 @@ public class NorthboundIT {
     // This is specifically written for statistics manager northbound REST
     // interface
     // array_name should be either "flowStatistics" or "portStatistics"
-    private JSONObject getJsonInstance(JSONObject json, String array_name,
-            Integer nodeId) throws JSONException {
+    private JSONObject getJsonInstance(JSONObject json, String array_name, Integer nodeId) throws JSONException {
         JSONObject result = null;
         if (json.get(array_name) instanceof JSONArray) {
             JSONArray json_array = json.getJSONArray(array_name);
@@ -914,29 +892,21 @@ public class NorthboundIT {
         String baseURL = "http://127.0.0.1:8080/controller/nb/v2/host/default";
 
         // test POST method: addHost()
-        String queryParameter = new QueryParameter("dataLayerAddress",
-                dataLayerAddress_1).add("nodeType", nodeType_1)
-                .add("nodeId", nodeId_1.toString())
-                .add("nodeConnectorType", nodeConnectorType_1)
-                .add("nodeConnectorId", nodeConnectorId_1.toString())
-                .add("vlan", vlan_1).getString();
+        String queryParameter = new QueryParameter("dataLayerAddress", dataLayerAddress_1).add("nodeType", nodeType_1)
+                .add("nodeId", nodeId_1.toString()).add("nodeConnectorType", nodeConnectorType_1)
+                .add("nodeConnectorId", nodeConnectorId_1.toString()).add("vlan", vlan_1).getString();
 
-        String result = getJsonResult(baseURL + "/" + networkAddress_1
-                + queryParameter, "POST");
-        Assert.assertTrue(httpResponseCode.intValue() == (Integer) 201);
+        String result = getJsonResult(baseURL + "/" + networkAddress_1 + queryParameter, "POST");
+        Assert.assertTrue(httpResponseCode == 201);
 
         // vlan is not passed through query parameter but should be
         // defaulted to "0"
-        queryParameter = new QueryParameter("dataLayerAddress",
-                dataLayerAddress_2).add("nodeType", nodeType_2)
-                .add("nodeId", nodeId_2.toString())
-                .add("nodeConnectorType", nodeConnectorType_2)
-                .add("nodeConnectorId", nodeConnectorId_2.toString())
-                .getString();
+        queryParameter = new QueryParameter("dataLayerAddress", dataLayerAddress_2).add("nodeType", nodeType_2)
+                .add("nodeId", nodeId_2.toString()).add("nodeConnectorType", nodeConnectorType_2)
+                .add("nodeConnectorId", nodeConnectorId_2.toString()).getString();
 
-        result = getJsonResult(baseURL + "/" + networkAddress_2
-                + queryParameter, "POST");
-        Assert.assertTrue(httpResponseCode.intValue() == (Integer) 201);
+        result = getJsonResult(baseURL + "/" + networkAddress_2 + queryParameter, "POST");
+        Assert.assertTrue(httpResponseCode == 201);
 
         // define variables for decoding returned strings
         String networkAddress;
@@ -945,7 +915,7 @@ public class NorthboundIT {
         // the two hosts should be in inactive host DB
         // test GET method: getInactiveHosts()
         result = getJsonResult(baseURL + "/inactive", "GET");
-        Assert.assertTrue(httpResponseCode.intValue() == (Integer) 200);
+        Assert.assertTrue(httpResponseCode == 200);
 
         JSONTokener jt = new JSONTokener(result);
         JSONObject json = new JSONObject(jt);
@@ -963,27 +933,19 @@ public class NorthboundIT {
 
             networkAddress = host_jo.getString("networkAddress");
             if (networkAddress.equalsIgnoreCase(networkAddress_1)) {
-                Assert.assertTrue(dl_jo.getString("macAddress")
-                        .equalsIgnoreCase(dataLayerAddress_1));
-                Assert.assertTrue(nc_jo.getString("@type").equalsIgnoreCase(
-                        nodeConnectorType_1));
-                Assert.assertTrue(Integer.parseInt(nc_jo.getString("@id")) == nodeConnectorId_1);
-                Assert.assertTrue(node_jo.getString("@type").equalsIgnoreCase(
-                        nodeType_1));
-                Assert.assertTrue(Integer.parseInt(node_jo.getString("@id")) == nodeId_1);
-                Assert.assertTrue(host_jo.getString("vlan").equalsIgnoreCase(
-                        vlan_1));
+                Assert.assertTrue(dl_jo.getString("macAddress").equalsIgnoreCase(dataLayerAddress_1));
+                Assert.assertTrue(nc_jo.getString("@type").equalsIgnoreCase(nodeConnectorType_1));
+                Assert.assertTrue(nc_jo.getInt("@id") == nodeConnectorId_1);
+                Assert.assertTrue(node_jo.getString("@type").equalsIgnoreCase(nodeType_1));
+                Assert.assertTrue(node_jo.getInt("@id") == nodeId_1);
+                Assert.assertTrue(host_jo.getString("vlan").equalsIgnoreCase(vlan_1));
             } else if (networkAddress.equalsIgnoreCase(networkAddress_2)) {
-                Assert.assertTrue(dl_jo.getString("macAddress")
-                        .equalsIgnoreCase(dataLayerAddress_2));
-                Assert.assertTrue(nc_jo.getString("@type").equalsIgnoreCase(
-                        nodeConnectorType_2));
-                Assert.assertTrue(Integer.parseInt(nc_jo.getString("@id")) == nodeConnectorId_2);
-                Assert.assertTrue(node_jo.getString("@type").equalsIgnoreCase(
-                        nodeType_2));
-                Assert.assertTrue(Integer.parseInt(node_jo.getString("@id")) == nodeId_2);
-                Assert.assertTrue(host_jo.getString("vlan").equalsIgnoreCase(
-                        vlan_2));
+                Assert.assertTrue(dl_jo.getString("macAddress").equalsIgnoreCase(dataLayerAddress_2));
+                Assert.assertTrue(nc_jo.getString("@type").equalsIgnoreCase(nodeConnectorType_2));
+                Assert.assertTrue(nc_jo.getInt("@id") == nodeConnectorId_2);
+                Assert.assertTrue(node_jo.getString("@type").equalsIgnoreCase(nodeType_2));
+                Assert.assertTrue(node_jo.getInt("@id") == nodeId_2);
+                Assert.assertTrue(host_jo.getString("vlan").equalsIgnoreCase(vlan_2));
             } else {
                 Assert.assertTrue(false);
             }
@@ -991,7 +953,7 @@ public class NorthboundIT {
 
         // test GET method: getActiveHosts() - no host expected
         result = getJsonResult(baseURL, "GET");
-        Assert.assertTrue(httpResponseCode.intValue() == (Integer) 200);
+        Assert.assertTrue(httpResponseCode == 200);
 
         jt = new JSONTokener(result);
         json = new JSONObject(jt);
@@ -1004,8 +966,7 @@ public class NorthboundIT {
         try {
             nd = new Node(nodeType_1, nodeId_1);
             ndc = new NodeConnector(nodeConnectorType_1, nodeConnectorId_1, nd);
-            this.invtoryListener.notifyNodeConnector(ndc, UpdateType.ADDED,
-                    null);
+            this.invtoryListener.notifyNodeConnector(ndc, UpdateType.ADDED, null);
         } catch (ConstructionException e) {
             ndc = null;
             nd = null;
@@ -1014,7 +975,7 @@ public class NorthboundIT {
         // verify the host shows up in active host DB
 
         result = getJsonResult(baseURL, "GET");
-        Assert.assertTrue(httpResponseCode.intValue() == (Integer) 200);
+        Assert.assertTrue(httpResponseCode == 200);
 
         jt = new JSONTokener(result);
         json = new JSONObject(jt);
@@ -1024,7 +985,7 @@ public class NorthboundIT {
         // test GET method for getHostDetails()
 
         result = getJsonResult(baseURL + "/" + networkAddress_1, "GET");
-        Assert.assertTrue(httpResponseCode.intValue() == (Integer) 200);
+        Assert.assertTrue(httpResponseCode == 200);
 
         jt = new JSONTokener(result);
         json = new JSONObject(jt);
@@ -1035,28 +996,24 @@ public class NorthboundIT {
         nc_jo = json.getJSONObject("nodeConnector");
         node_jo = nc_jo.getJSONObject("node");
 
-        Assert.assertTrue(json.getString("networkAddress").equalsIgnoreCase(
-                networkAddress_1));
-        Assert.assertTrue(dl_jo.getString("macAddress").equalsIgnoreCase(
-                dataLayerAddress_1));
-        Assert.assertTrue(nc_jo.getString("@type").equalsIgnoreCase(
-                nodeConnectorType_1));
+        Assert.assertTrue(json.getString("networkAddress").equalsIgnoreCase(networkAddress_1));
+        Assert.assertTrue(dl_jo.getString("macAddress").equalsIgnoreCase(dataLayerAddress_1));
+        Assert.assertTrue(nc_jo.getString("@type").equalsIgnoreCase(nodeConnectorType_1));
         Assert.assertTrue(Integer.parseInt(nc_jo.getString("@id")) == nodeConnectorId_1);
-        Assert.assertTrue(node_jo.getString("@type").equalsIgnoreCase(
-                nodeType_1));
+        Assert.assertTrue(node_jo.getString("@type").equalsIgnoreCase(nodeType_1));
         Assert.assertTrue(Integer.parseInt(node_jo.getString("@id")) == nodeId_1);
         Assert.assertTrue(json.getString("vlan").equalsIgnoreCase(vlan_1));
 
         // test DELETE method for deleteFlow()
 
         result = getJsonResult(baseURL + "/" + networkAddress_1, "DELETE");
-        Assert.assertTrue(httpResponseCode.intValue() == (Integer) 200);
+        Assert.assertTrue(httpResponseCode == 200);
 
         // verify host_1 removed from active host DB
         // test GET method: getActiveHosts() - no host expected
 
         result = getJsonResult(baseURL, "GET");
-        Assert.assertTrue(httpResponseCode.intValue() == (Integer) 200);
+        Assert.assertTrue(httpResponseCode == 200);
 
         jt = new JSONTokener(result);
         json = new JSONObject(jt);
@@ -1065,8 +1022,7 @@ public class NorthboundIT {
 
     }
 
-    private Boolean hostInJson(JSONObject json, String hostIp)
-            throws JSONException {
+    private Boolean hostInJson(JSONObject json, String hostIp) throws JSONException {
         // input JSONObject may be empty
         if (json.length() == 0) {
             return false;
@@ -1085,19 +1041,202 @@ public class NorthboundIT {
         }
     }
 
+    @Test
+    public void testTopology() throws JSONException, ConstructionException {
+        System.out.println("Starting Topology JAXB client.");
+        String baseURL = "http://127.0.0.1:8080/controller/nb/v2/topology/default";
+
+        // === test GET method for getTopology()
+        short state_1 = State.EDGE_UP, state_2 = State.EDGE_DOWN;
+        long bw_1 = Bandwidth.BW10Gbps, bw_2 = Bandwidth.BW100Mbps;
+        long lat_1 = Latency.LATENCY100ns, lat_2 = Latency.LATENCY1ms;
+        String nodeType = "STUB";
+        String nodeConnType = "STUB";
+        int headNC1_nodeId = 1, headNC1_nodeConnId = 11;
+        int tailNC1_nodeId = 2, tailNC1_nodeConnId = 22;
+        int headNC2_nodeId = 2, headNC2_nodeConnId = 21;
+        int tailNC2_nodeId = 1, tailNC2_nodeConnId = 12;
+
+        List<TopoEdgeUpdate> topoedgeupdateList = new ArrayList<TopoEdgeUpdate>();
+        NodeConnector headnc1 = new NodeConnector(nodeConnType, headNC1_nodeConnId, new Node(nodeType, headNC1_nodeId));
+        NodeConnector tailnc1 = new NodeConnector(nodeConnType, tailNC1_nodeConnId, new Node(nodeType, tailNC1_nodeId));
+        Edge e1 = new Edge(tailnc1, headnc1);
+        Set<Property> props_1 = new HashSet<Property>();
+        props_1.add(new State(state_1));
+        props_1.add(new Bandwidth(bw_1));
+        props_1.add(new Latency(lat_1));
+        TopoEdgeUpdate teu1 = new TopoEdgeUpdate(e1, props_1, UpdateType.ADDED);
+        topoedgeupdateList.add(teu1);
+
+        NodeConnector headnc2 = new NodeConnector(nodeConnType, headNC2_nodeConnId, new Node(nodeType, headNC2_nodeId));
+        NodeConnector tailnc2 = new NodeConnector(nodeConnType, tailNC2_nodeConnId, new Node(nodeType, tailNC2_nodeId));
+        Edge e2 = new Edge(tailnc2, headnc2);
+        Set<Property> props_2 = new HashSet<Property>();
+        props_2.add(new State(state_2));
+        props_2.add(new Bandwidth(bw_2));
+        props_2.add(new Latency(lat_2));
+
+        TopoEdgeUpdate teu2 = new TopoEdgeUpdate(e2, props_2, UpdateType.ADDED);
+        topoedgeupdateList.add(teu2);
+
+        topoUpdates.edgeUpdate(topoedgeupdateList);
+
+        // HTTP request
+        String result = getJsonResult(baseURL, "GET");
+        Assert.assertTrue(httpResponseCode == 200);
+        if (debugMsg) {
+            System.out.println("Get Topology: " + result);
+        }
+
+        // returned data must be an array of edges
+        JSONTokener jt = new JSONTokener(result);
+        JSONObject json = new JSONObject(jt);
+        Assert.assertTrue(json.get("edgeProperties") instanceof JSONArray);
+        JSONArray ja = json.getJSONArray("edgeProperties");
+
+        for (int i = 0; i < ja.length(); i++) {
+            JSONObject edgeProp = ja.getJSONObject(i);
+            JSONObject edge = edgeProp.getJSONObject("edge");
+            JSONObject tailNC = edge.getJSONObject("tailNodeConnector");
+            JSONObject tailNode = tailNC.getJSONObject("node");
+
+            JSONObject headNC = edge.getJSONObject("headNodeConnector");
+            JSONObject headNode = headNC.getJSONObject("node");
+            JSONObject Props = edgeProp.getJSONObject("properties");
+            JSONObject bandw = Props.getJSONObject("bandwidth");
+            JSONObject stt = Props.getJSONObject("state");
+            JSONObject ltc = Props.getJSONObject("latency");
+
+            if (headNC.getInt("@id") == headNC1_nodeConnId) {
+                Assert.assertEquals(headNode.getString("@type"), nodeType);
+                Assert.assertEquals(headNode.getLong("@id"), headNC1_nodeId);
+                Assert.assertEquals(headNC.getString("@type"), nodeConnType);
+                Assert.assertEquals(tailNode.getString("@type"),nodeType);
+                Assert.assertEquals(tailNode.getString("@type"), nodeConnType);
+                Assert.assertEquals(tailNC.getLong("@id"), tailNC1_nodeConnId);
+                Assert.assertEquals(bandw.getLong("bandwidthValue"), bw_1);
+                Assert.assertTrue((short) stt.getInt("stateValue") == state_1);
+                Assert.assertEquals(ltc.getLong("latencyValue"), lat_1);
+            } else if (headNC.getInt("@id") == headNC2_nodeConnId) {
+                Assert.assertEquals(headNode.getString("@type"),nodeType);
+                Assert.assertEquals(headNode.getLong("@id"), headNC2_nodeId);
+                Assert.assertEquals(headNC.getString("@type"), nodeConnType);
+                Assert.assertEquals(tailNode.getString("@type"), nodeType);
+                Assert.assertTrue(tailNode.getInt("@id") == tailNC2_nodeId);
+                Assert.assertEquals(tailNC.getString("@type"), nodeConnType);
+                Assert.assertEquals(tailNC.getLong("@id"), tailNC2_nodeConnId);
+                Assert.assertEquals(bandw.getLong("bandwidthValue"), bw_2);
+                Assert.assertTrue((short) stt.getInt("stateValue") == state_2);
+                Assert.assertEquals(ltc.getLong("latencyValue"), lat_2);
+            }
+        }
+
+        // === test POST method for addUserLink()
+        // define 2 sample nodeConnectors for user link configuration tests
+        String nodeType_1 = "STUB";
+        Integer nodeId_1 = 3366;
+        String nodeConnectorType_1 = "STUB";
+        Integer nodeConnectorId_1 = 12;
+
+        String nodeType_2 = "STUB";
+        Integer nodeId_2 = 4477;
+        String nodeConnectorType_2 = "STUB";
+        Integer nodeConnectorId_2 = 34;
+
+        JSONObject jo = new JSONObject()
+                .append("name", "userLink_1")
+                .append("srcNodeConnector",
+                        nodeConnectorType_1 + "|" + nodeConnectorId_1 + "@" + nodeType_1 + "|" + nodeId_1)
+                .append("dstNodeConnector",
+                        nodeConnectorType_2 + "|" + nodeConnectorId_2 + "@" + nodeType_2 + "|" + nodeId_2);
+        // execute HTTP request and verify response code
+        result = getJsonResult(baseURL + "/userLink", "POST", jo.toString());
+        Assert.assertTrue(httpResponseCode == 201);
+
+        // === test GET method for getUserLinks()
+        result = getJsonResult(baseURL + "/userLink", "GET");
+        Assert.assertTrue(httpResponseCode == 200);
+        if (debugMsg) {
+            System.out.println("result:" + result);
+        }
+
+        jt = new JSONTokener(result);
+        json = new JSONObject(jt);
+
+        // should have at least one object returned
+        Assert.assertFalse(json.length() == 0);
+        JSONObject userlink = new JSONObject();
+
+        if (json.get("userLinks") instanceof JSONArray) {
+            ja = json.getJSONArray("userLinks");
+            int i;
+            for (i = 0; i < ja.length(); i++) {
+                userlink = ja.getJSONObject(i);
+                if (userlink.getString("name").equalsIgnoreCase("userLink_1"))
+                    break;
+            }
+            Assert.assertFalse(i == ja.length());
+        } else {
+            userlink = json.getJSONObject("userLinks");
+            Assert.assertTrue(userlink.getString("name").equalsIgnoreCase("userLink_1"));
+        }
+
+        String[] level_1, level_2;
+        level_1 = userlink.getString("srcNodeConnector").split("\\@");
+        level_2 = level_1[0].split("\\|");
+        Assert.assertTrue(level_2[0].equalsIgnoreCase(nodeConnectorType_1));
+        Assert.assertTrue(Integer.parseInt(level_2[1]) == nodeConnectorId_1);
+        level_2 = level_1[1].split("\\|");
+        Assert.assertTrue(level_2[0].equalsIgnoreCase(nodeType_1));
+        Assert.assertTrue(Integer.parseInt(level_2[1]) == nodeId_1);
+        level_1 = userlink.getString("dstNodeConnector").split("\\@");
+        level_2 = level_1[0].split("\\|");
+        Assert.assertTrue(level_2[0].equalsIgnoreCase(nodeConnectorType_2));
+        Assert.assertTrue(Integer.parseInt(level_2[1]) == nodeConnectorId_2);
+        level_2 = level_1[1].split("\\|");
+        Assert.assertTrue(level_2[0].equalsIgnoreCase(nodeType_2));
+        Assert.assertTrue(Integer.parseInt(level_2[1]) == nodeId_2);
+
+        // === test DELETE method for deleteUserLink()
+        String userName = "userLink_1";
+        result = getJsonResult(baseURL + "/userLink/" + userName, "DELETE");
+        Assert.assertTrue(httpResponseCode == 200);
+
+        // execute another getUserLinks() request to verify that userLink_1 is
+        // removed
+        result = getJsonResult(baseURL + "/userLink", "GET");
+        Assert.assertTrue(httpResponseCode == 200);
+        if (debugMsg) {
+            System.out.println("result:" + result);
+        }
+        jt = new JSONTokener(result);
+        json = new JSONObject(jt);
+
+        if (json.length() != 0) {
+            if (json.get("userLinks") instanceof JSONArray) {
+                ja = json.getJSONArray("userLinks");
+                for (int i = 0; i < ja.length(); i++) {
+                    userlink = ja.getJSONObject(i);
+                    Assert.assertFalse(userlink.getString("name").equalsIgnoreCase("userLink_1"));
+                }
+            } else {
+                userlink = json.getJSONObject("userLinks");
+                Assert.assertFalse(userlink.getString("name").equalsIgnoreCase("userLink_1"));
+            }
+        }
+    }
+
     // Configure the OSGi container
     @Configuration
     public Option[] config() {
         return options(
                 //
                 systemProperty("logback.configurationFile").value(
-                        "file:" + PathUtils.getBaseDir()
-                                + "/src/test/resources/logback.xml"),
+                        "file:" + PathUtils.getBaseDir() + "/src/test/resources/logback.xml"),
                 // To start OSGi console for inspection remotely
                 systemProperty("osgi.console").value("2401"),
-                systemProperty("org.eclipse.gemini.web.tomcat.config.path")
-                        .value(PathUtils.getBaseDir()
-                                + "/src/test/resources/tomcat-server.xml"),
+                systemProperty("org.eclipse.gemini.web.tomcat.config.path").value(
+                        PathUtils.getBaseDir() + "/src/test/resources/tomcat-server.xml"),
 
                 // setting default level. Jersey bundles will need to be started
                 // earlier.
@@ -1113,90 +1252,52 @@ public class NorthboundIT {
                 mavenBundle("ch.qos.logback", "logback-core", "1.0.9"),
                 mavenBundle("ch.qos.logback", "logback-classic", "1.0.9"),
                 mavenBundle("org.apache.commons", "commons-lang3", "3.1"),
-                mavenBundle("org.apache.felix",
-                        "org.apache.felix.dependencymanager", "3.1.0"),
+                mavenBundle("org.apache.felix", "org.apache.felix.dependencymanager", "3.1.0"),
 
                 // the plugin stub to get data for the tests
-                mavenBundle("org.opendaylight.controller",
-                        "protocol_plugins.stub", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "protocol_plugins.stub", "0.4.0-SNAPSHOT"),
 
                 // List all the opendaylight modules
-                mavenBundle("org.opendaylight.controller", "security",
-                        "0.4.0-SNAPSHOT").noStart(),
-                mavenBundle("org.opendaylight.controller", "sal",
-                        "0.5.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "sal.implementation", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller", "statisticsmanager",
-                        "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "statisticsmanager.implementation", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller", "containermanager",
-                        "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "containermanager.implementation", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "forwardingrulesmanager", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "forwardingrulesmanager.implementation",
-                        "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller", "arphandler",
-                        "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "clustering.services", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "clustering.services-implementation", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller", "switchmanager",
-                        "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "switchmanager.implementation", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller", "configuration",
-                        "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "configuration.implementation", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller", "hosttracker",
-                        "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "hosttracker.implementation", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller", "arphandler",
-                        "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "routing.dijkstra_implementation", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller", "topologymanager",
-                        "0.4.0-SNAPSHOT"),
-
-                mavenBundle("org.opendaylight.controller", "usermanager",
-                        "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "usermanager.implementation", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller", "logging.bridge",
-                        "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller", "clustering.test",
-                        "0.4.0-SNAPSHOT"),
-
-                mavenBundle("org.opendaylight.controller",
-                        "forwarding.staticrouting", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "security", "0.4.0-SNAPSHOT").noStart(),
+                mavenBundle("org.opendaylight.controller", "sal", "0.5.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "sal.implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "statisticsmanager", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "statisticsmanager.implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "containermanager", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "containermanager.implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "forwardingrulesmanager", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "forwardingrulesmanager.implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "arphandler", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "clustering.services", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "clustering.services-implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "switchmanager", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "switchmanager.implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "configuration", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "configuration.implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "hosttracker", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "hosttracker.implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "arphandler", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "routing.dijkstra_implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "topologymanager", "0.4.0-SNAPSHOT"),
+
+                mavenBundle("org.opendaylight.controller", "usermanager", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "usermanager.implementation", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "logging.bridge", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "clustering.test", "0.4.0-SNAPSHOT"),
+
+                mavenBundle("org.opendaylight.controller", "forwarding.staticrouting", "0.4.0-SNAPSHOT"),
 
                 // Northbound bundles
-                mavenBundle("org.opendaylight.controller",
-                        "commons.northbound", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "forwarding.staticrouting.northbound", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "statistics.northbound", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "topology.northbound", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "hosttracker.northbound", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "switchmanager.northbound", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "flowprogrammer.northbound", "0.4.0-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller",
-                        "subnets.northbound", "0.4.0-SNAPSHOT"),
-
-                mavenBundle("org.codehaus.jackson", "jackson-mapper-asl",
-                        "1.9.8"),
+                mavenBundle("org.opendaylight.controller", "commons.northbound", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "forwarding.staticrouting.northbound", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "statistics.northbound", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "topology.northbound", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "hosttracker.northbound", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "switchmanager.northbound", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "flowprogrammer.northbound", "0.4.0-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller", "subnets.northbound", "0.4.0-SNAPSHOT"),
+
+                mavenBundle("org.codehaus.jackson", "jackson-mapper-asl", "1.9.8"),
                 mavenBundle("org.codehaus.jackson", "jackson-core-asl", "1.9.8"),
                 mavenBundle("org.codehaus.jackson", "jackson-jaxrs", "1.9.8"),
                 mavenBundle("org.codehaus.jettison", "jettison", "1.3.3"),
@@ -1205,154 +1306,93 @@ public class NorthboundIT {
 
                 mavenBundle("commons-fileupload", "commons-fileupload", "1.2.2"),
 
-                mavenBundle("equinoxSDK381", "javax.servlet",
-                        "3.0.0.v201112011016"),
-                mavenBundle("equinoxSDK381", "javax.servlet.jsp",
-                        "2.2.0.v201112011158"),
-                mavenBundle("equinoxSDK381", "org.eclipse.equinox.ds",
-                        "1.4.0.v20120522-1841"),
+                mavenBundle("equinoxSDK381", "javax.servlet", "3.0.0.v201112011016"),
+                mavenBundle("equinoxSDK381", "javax.servlet.jsp", "2.2.0.v201112011158"),
+                mavenBundle("equinoxSDK381", "org.eclipse.equinox.ds", "1.4.0.v20120522-1841"),
                 mavenBundle("orbit", "javax.xml.rpc", "1.1.0.v201005080400"),
-                mavenBundle("equinoxSDK381", "org.eclipse.equinox.util",
-                        "1.0.400.v20120522-2049"),
-                mavenBundle("equinoxSDK381", "org.eclipse.osgi.services",
-                        "3.3.100.v20120522-1822"),
-                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.command",
-                        "0.8.0.v201108120515"),
-                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.runtime",
-                        "0.8.0.v201108120515"),
-                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.shell",
-                        "0.8.0.v201110170705"),
-                mavenBundle("equinoxSDK381", "org.eclipse.equinox.cm",
-                        "1.0.400.v20120522-1841"),
-                mavenBundle("equinoxSDK381", "org.eclipse.equinox.console",
-                        "1.0.0.v20120522-1841"),
-                mavenBundle("equinoxSDK381", "org.eclipse.equinox.launcher",
-                        "1.3.0.v20120522-1813"),
-
-                mavenBundle("geminiweb", "org.eclipse.gemini.web.core",
-                        "2.2.0.RELEASE"),
-                mavenBundle("geminiweb", "org.eclipse.gemini.web.extender",
-                        "2.2.0.RELEASE"),
-                mavenBundle("geminiweb", "org.eclipse.gemini.web.tomcat",
-                        "2.2.0.RELEASE"),
-                mavenBundle("geminiweb",
-                        "org.eclipse.virgo.kernel.equinox.extensions",
-                        "3.6.0.RELEASE").noStart(),
-                mavenBundle("geminiweb", "org.eclipse.virgo.util.common",
-                        "3.6.0.RELEASE"),
-                mavenBundle("geminiweb", "org.eclipse.virgo.util.io",
-                        "3.6.0.RELEASE"),
-                mavenBundle("geminiweb", "org.eclipse.virgo.util.math",
-                        "3.6.0.RELEASE"),
-                mavenBundle("geminiweb", "org.eclipse.virgo.util.osgi",
-                        "3.6.0.RELEASE"),
-                mavenBundle("geminiweb",
-                        "org.eclipse.virgo.util.osgi.manifest", "3.6.0.RELEASE"),
-                mavenBundle("geminiweb",
-                        "org.eclipse.virgo.util.parser.manifest",
-                        "3.6.0.RELEASE"),
-
-                mavenBundle("org.apache.felix",
-                        "org.apache.felix.dependencymanager", "3.1.0"),
-                mavenBundle("org.apache.felix",
-                        "org.apache.felix.dependencymanager.shell", "3.0.1"),
+                mavenBundle("equinoxSDK381", "org.eclipse.equinox.util", "1.0.400.v20120522-2049"),
+                mavenBundle("equinoxSDK381", "org.eclipse.osgi.services", "3.3.100.v20120522-1822"),
+                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.command", "0.8.0.v201108120515"),
+                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.runtime", "0.8.0.v201108120515"),
+                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.shell", "0.8.0.v201110170705"),
+                mavenBundle("equinoxSDK381", "org.eclipse.equinox.cm", "1.0.400.v20120522-1841"),
+                mavenBundle("equinoxSDK381", "org.eclipse.equinox.console", "1.0.0.v20120522-1841"),
+                mavenBundle("equinoxSDK381", "org.eclipse.equinox.launcher", "1.3.0.v20120522-1813"),
+
+                mavenBundle("geminiweb", "org.eclipse.gemini.web.core", "2.2.0.RELEASE"),
+                mavenBundle("geminiweb", "org.eclipse.gemini.web.extender", "2.2.0.RELEASE"),
+                mavenBundle("geminiweb", "org.eclipse.gemini.web.tomcat", "2.2.0.RELEASE"),
+                mavenBundle("geminiweb", "org.eclipse.virgo.kernel.equinox.extensions", "3.6.0.RELEASE").noStart(),
+                mavenBundle("geminiweb", "org.eclipse.virgo.util.common", "3.6.0.RELEASE"),
+                mavenBundle("geminiweb", "org.eclipse.virgo.util.io", "3.6.0.RELEASE"),
+                mavenBundle("geminiweb", "org.eclipse.virgo.util.math", "3.6.0.RELEASE"),
+                mavenBundle("geminiweb", "org.eclipse.virgo.util.osgi", "3.6.0.RELEASE"),
+                mavenBundle("geminiweb", "org.eclipse.virgo.util.osgi.manifest", "3.6.0.RELEASE"),
+                mavenBundle("geminiweb", "org.eclipse.virgo.util.parser.manifest", "3.6.0.RELEASE"),
+
+                mavenBundle("org.apache.felix", "org.apache.felix.dependencymanager", "3.1.0"),
+                mavenBundle("org.apache.felix", "org.apache.felix.dependencymanager.shell", "3.0.1"),
 
                 mavenBundle("com.google.code.gson", "gson", "2.1"),
-                mavenBundle("org.jboss.spec.javax.transaction",
-                        "jboss-transaction-api_1.1_spec", "1.0.1.Final"),
-                mavenBundle("org.apache.felix", "org.apache.felix.fileinstall",
-                        "3.1.6"),
+                mavenBundle("org.jboss.spec.javax.transaction", "jboss-transaction-api_1.1_spec", "1.0.1.Final"),
+                mavenBundle("org.apache.felix", "org.apache.felix.fileinstall", "3.1.6"),
                 mavenBundle("org.apache.commons", "commons-lang3", "3.1"),
                 mavenBundle("commons-codec", "commons-codec"),
-                mavenBundle("virgomirror",
-                        "org.eclipse.jdt.core.compiler.batch",
-                        "3.8.0.I20120518-2145"),
-                mavenBundle("eclipselink", "javax.persistence",
-                        "2.0.4.v201112161009"),
+                mavenBundle("virgomirror", "org.eclipse.jdt.core.compiler.batch", "3.8.0.I20120518-2145"),
+                mavenBundle("eclipselink", "javax.persistence", "2.0.4.v201112161009"),
 
                 mavenBundle("orbit", "javax.activation", "1.1.0.v201211130549"),
                 mavenBundle("orbit", "javax.annotation", "1.1.0.v201209060031"),
                 mavenBundle("orbit", "javax.ejb", "3.1.1.v201204261316"),
                 mavenBundle("orbit", "javax.el", "2.2.0.v201108011116"),
-                mavenBundle("orbit", "javax.mail.glassfish",
-                        "1.4.1.v201108011116"),
+                mavenBundle("orbit", "javax.mail.glassfish", "1.4.1.v201108011116"),
                 mavenBundle("orbit", "javax.xml.rpc", "1.1.0.v201005080400"),
-                mavenBundle("orbit", "org.apache.catalina",
-                        "7.0.32.v201211201336"),
+                mavenBundle("orbit", "org.apache.catalina", "7.0.32.v201211201336"),
                 // these are bundle fragments that can't be started on its own
-                mavenBundle("orbit", "org.apache.catalina.ha",
-                        "7.0.32.v201211201952").noStart(),
-                mavenBundle("orbit", "org.apache.catalina.tribes",
-                        "7.0.32.v201211201952").noStart(),
-                mavenBundle("orbit", "org.apache.coyote",
-                        "7.0.32.v201211201952").noStart(),
-                mavenBundle("orbit", "org.apache.jasper",
-                        "7.0.32.v201211201952").noStart(),
+                mavenBundle("orbit", "org.apache.catalina.ha", "7.0.32.v201211201952").noStart(),
+                mavenBundle("orbit", "org.apache.catalina.tribes", "7.0.32.v201211201952").noStart(),
+                mavenBundle("orbit", "org.apache.coyote", "7.0.32.v201211201952").noStart(),
+                mavenBundle("orbit", "org.apache.jasper", "7.0.32.v201211201952").noStart(),
 
                 mavenBundle("orbit", "org.apache.el", "7.0.32.v201211081135"),
-                mavenBundle("orbit", "org.apache.juli.extras",
-                        "7.0.32.v201211081135"),
-                mavenBundle("orbit", "org.apache.tomcat.api",
-                        "7.0.32.v201211081135"),
-                mavenBundle("orbit", "org.apache.tomcat.util",
-                        "7.0.32.v201211201952").noStart(),
-                mavenBundle("orbit", "javax.servlet.jsp.jstl",
-                        "1.2.0.v201105211821"),
-                mavenBundle("orbit", "javax.servlet.jsp.jstl.impl",
-                        "1.2.0.v201210211230"),
+                mavenBundle("orbit", "org.apache.juli.extras", "7.0.32.v201211081135"),
+                mavenBundle("orbit", "org.apache.tomcat.api", "7.0.32.v201211081135"),
+                mavenBundle("orbit", "org.apache.tomcat.util", "7.0.32.v201211201952").noStart(),
+                mavenBundle("orbit", "javax.servlet.jsp.jstl", "1.2.0.v201105211821"),
+                mavenBundle("orbit", "javax.servlet.jsp.jstl.impl", "1.2.0.v201210211230"),
 
                 mavenBundle("org.ops4j.pax.exam", "pax-exam-container-native"),
                 mavenBundle("org.ops4j.pax.exam", "pax-exam-junit4"),
                 mavenBundle("org.ops4j.pax.exam", "pax-exam-link-mvn"),
                 mavenBundle("org.ops4j.pax.url", "pax-url-aether"),
 
-                mavenBundle("org.springframework", "org.springframework.asm",
-                        "3.1.3.RELEASE"),
-                mavenBundle("org.springframework", "org.springframework.aop",
-                        "3.1.3.RELEASE"),
-                mavenBundle("org.springframework",
-                        "org.springframework.context", "3.1.3.RELEASE"),
-                mavenBundle("org.springframework",
-                        "org.springframework.context.support", "3.1.3.RELEASE"),
-                mavenBundle("org.springframework", "org.springframework.core",
-                        "3.1.3.RELEASE"),
-                mavenBundle("org.springframework", "org.springframework.beans",
-                        "3.1.3.RELEASE"),
-                mavenBundle("org.springframework",
-                        "org.springframework.expression", "3.1.3.RELEASE"),
-                mavenBundle("org.springframework", "org.springframework.web",
-                        "3.1.3.RELEASE"),
-
-                mavenBundle("org.aopalliance",
-                        "com.springsource.org.aopalliance", "1.0.0"),
-                mavenBundle("org.springframework",
-                        "org.springframework.web.servlet", "3.1.3.RELEASE"),
-                mavenBundle("org.springframework.security",
-                        "spring-security-config", "3.1.3.RELEASE"),
-                mavenBundle("org.springframework.security",
-                        "spring-security-core", "3.1.3.RELEASE"),
-                mavenBundle("org.springframework.security",
-                        "spring-security-web", "3.1.3.RELEASE"),
-                mavenBundle("org.springframework.security",
-                        "spring-security-taglibs", "3.1.3.RELEASE"),
-                mavenBundle("org.springframework",
-                        "org.springframework.transaction", "3.1.3.RELEASE"),
-
-                mavenBundle("org.ow2.chameleon.management", "chameleon-mbeans",
-                        "1.0.0"),
-                mavenBundle("org.opendaylight.controller.thirdparty",
-                        "net.sf.jung2", "2.0.1-SNAPSHOT"),
-                mavenBundle("org.opendaylight.controller.thirdparty",
-                        "com.sun.jersey.jersey-servlet", "1.17-SNAPSHOT"),
+                mavenBundle("org.springframework", "org.springframework.asm", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework", "org.springframework.aop", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework", "org.springframework.context", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework", "org.springframework.context.support", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework", "org.springframework.core", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework", "org.springframework.beans", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework", "org.springframework.expression", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework", "org.springframework.web", "3.1.3.RELEASE"),
+
+                mavenBundle("org.aopalliance", "com.springsource.org.aopalliance", "1.0.0"),
+                mavenBundle("org.springframework", "org.springframework.web.servlet", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework.security", "spring-security-config", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework.security", "spring-security-core", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework.security", "spring-security-web", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework.security", "spring-security-taglibs", "3.1.3.RELEASE"),
+                mavenBundle("org.springframework", "org.springframework.transaction", "3.1.3.RELEASE"),
+
+                mavenBundle("org.ow2.chameleon.management", "chameleon-mbeans", "1.0.0"),
+                mavenBundle("org.opendaylight.controller.thirdparty", "net.sf.jung2", "2.0.1-SNAPSHOT"),
+                mavenBundle("org.opendaylight.controller.thirdparty", "com.sun.jersey.jersey-servlet", "1.17-SNAPSHOT"),
 
                 // Jersey needs to be started before the northbound application
                 // bundles, using a lower start level
                 mavenBundle("com.sun.jersey", "jersey-client", "1.17"),
-                mavenBundle("com.sun.jersey", "jersey-server", "1.17")
-                        .startLevel(2),
-                mavenBundle("com.sun.jersey", "jersey-core", "1.17")
-                        .startLevel(2),
-                mavenBundle("com.sun.jersey", "jersey-json", "1.17")
-                        .startLevel(2), junitBundles());
+                mavenBundle("com.sun.jersey", "jersey-server", "1.17").startLevel(2),
+                mavenBundle("com.sun.jersey", "jersey-core", "1.17").startLevel(2),
+                mavenBundle("com.sun.jersey", "jersey-json", "1.17").startLevel(2), junitBundles());
     }
+
 }
index 61e3872669b67f6a01f955bf2d15780635e0c84a..818002a21e042f87da32f5e14573e1b502ffc328 100644 (file)
@@ -9,6 +9,7 @@
 
 package org.opendaylight.controller.sal.core;
 
+import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
 /**
@@ -21,7 +22,9 @@ import javax.xml.bind.annotation.XmlRootElement;
 @XmlRootElement
 public class Latency extends Property {
     private static final long serialVersionUID = 1L;
-    private long latency;
+
+    @XmlElement
+    private long latencyValue;
 
     public static final long LATENCYUNK = 0;
     public static final long LATENCY1ns = (long) Math.pow(10, 3);
@@ -40,37 +43,37 @@ public class Latency extends Property {
      */
     private Latency() {
         super(LatencyPropName);
-        this.latency = LATENCYUNK;
+        this.latencyValue = LATENCYUNK;
     }
 
     public Latency(long latency) {
         super(LatencyPropName);
-        this.latency = latency;
+        this.latencyValue = latency;
     }
 
     public Latency(int latency) {
         super(LatencyPropName);
-        this.latency = (long) latency;
+        this.latencyValue = (long) latency;
     }
 
     public Latency(short latency) {
         super(LatencyPropName);
-        this.latency = (long) latency;
+        this.latencyValue = (long) latency;
     }
 
     public Latency clone() {
-        return new Latency(this.latency);
+        return new Latency(this.latencyValue);
     }
 
     public long getValue() {
-        return this.latency;
+        return this.latencyValue;
     }
 
     @Override
     public int hashCode() {
         final int prime = 31;
         int result = super.hashCode();
-        result = prime * result + (int) (latency ^ (latency >>> 32));
+        result = prime * result + (int) (latencyValue ^ (latencyValue >>> 32));
         return result;
     }
 
@@ -83,7 +86,7 @@ public class Latency extends Property {
         if (getClass() != obj.getClass())
             return false;
         Latency other = (Latency) obj;
-        if (latency != other.latency)
+        if (latencyValue != other.latencyValue)
             return false;
         return true;
     }
@@ -93,16 +96,16 @@ public class Latency extends Property {
         StringBuffer sb = new StringBuffer();
 
         sb.append("Latency[");
-        if (this.latency == 0) {
+        if (this.latencyValue == 0) {
             sb.append("UnKnown");
-        } else if (this.latency < LATENCY1ns) {
-            sb.append(this.latency + "psec");
-        } else if (this.latency < LATENCY1us) {
-            sb.append(Long.toString(this.latency / LATENCY1ns) + "nsec");
-        } else if (this.latency < LATENCY1ms) {
-            sb.append(Long.toString(this.latency / LATENCY1us) + "usec");
-        } else if (this.latency < LATENCY1s) {
-            sb.append(Long.toString(this.latency / LATENCY1ms) + "msec");
+        } else if (this.latencyValue < LATENCY1ns) {
+            sb.append(this.latencyValue + "psec");
+        } else if (this.latencyValue < LATENCY1us) {
+            sb.append(Long.toString(this.latencyValue / LATENCY1ns) + "nsec");
+        } else if (this.latencyValue < LATENCY1ms) {
+            sb.append(Long.toString(this.latencyValue / LATENCY1us) + "usec");
+        } else if (this.latencyValue < LATENCY1s) {
+            sb.append(Long.toString(this.latencyValue / LATENCY1ms) + "msec");
         }
 
         sb.append("]");
index 8e76c3fc60d81e35b552bd8bb54edf73d997bf6e..8aee1cc37f474492916894d4b121dced2066e106 100644 (file)
@@ -28,6 +28,16 @@ public abstract class NetUtils {
      */
     public static final int NumBitsInAByte = 8;
 
+    /**
+     * Constant holding the number of bytes in MAC Address
+     */
+    public static final int MACAddrLengthInBytes = 6;
+
+    /**
+     * Constant holding the number of words in MAC Address
+     */
+    public static final int MACAddrLengthInWords = 3;
+
     /**
      * Converts a 4 bytes array into an integer number
      *
index fd288c71276e3669ea30adffb12c5f89248aa9a5..14e440df029f1bb71b901a647d12c2cf548b617e 100644 (file)
@@ -40,6 +40,9 @@
               org.slf4j,
               org.apache.felix.dm
             </Import-Package>
+            <Export-Package>
+              org.opendaylight.controller.sample.simpleforwarding
+            </Export-Package>
             <Bundle-Activator>
               org.opendaylight.controller.samples.simpleforwarding.internal.Activator
             </Bundle-Activator>
index 11056478dbf1742ec48e5cc6bbf9ec3bf01ad56a..7f4c98a6483969fabfd14f6bc54219873ae00cd8 100644 (file)
@@ -50,12 +50,15 @@ import org.opendaylight.controller.sal.routing.IRouting;
 import org.opendaylight.controller.sal.utils.EtherTypes;
 import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
 import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.samples.simpleforwarding.HostNodePair;
 import org.opendaylight.controller.switchmanager.IInventoryListener;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
 import org.opendaylight.controller.topologymanager.ITopologyManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+
+
 public class SimpleForwardingImpl implements IfNewHostNotify,
         IListenRoutingUpdates, IInventoryListener {
     private static Logger log = LoggerFactory
index afa4c42d36095072371dafc09c171fd9b6ebb587..7897c398909a48a02cd0221279cf51d054bbaa6c 100644 (file)
@@ -18,7 +18,8 @@ import org.junit.Assert;
 import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
 import org.opendaylight.controller.sal.core.ConstructionException;
 import org.opendaylight.controller.sal.utils.NodeCreator;
-import org.opendaylight.controller.samples.simpleforwarding.internal.HostNodePair;
+import org.opendaylight.controller.samples.simpleforwarding.HostNodePair;
+
 
 public class HostSwitchTest {
     @Test
index 80ed20981961b56e21d397575ea09c2712190cdd..83cb8b1cc9786f42757e1f609dedf724943c0f19 100644 (file)
@@ -150,4 +150,9 @@ public class SpanConfig implements Serializable {
     public boolean matchNode(String nodeId) {
         return this.nodeId.equals(nodeId);
     }
+
+    @Override
+    public String toString() {
+        return ("Span Config [nodeId=" + nodeId + " spanPort=" + spanPort + "]");
+    }
 }
index 87dd99da7f80736c76fc2e31765e84d46667fd35..895f117321a6c61645742e425bcf0ad2d0af6cbd 100644 (file)
@@ -231,6 +231,7 @@ public class SubnetConfig implements Serializable {
         nodePorts.remove(sp);
     }
 
+    @Override
     public String toString() {
         return ("Subnet Config [Description=" + name + " Subnet=" + subnet
                 + " NodeConnectors=" + nodePorts + "]");
index 253096edc34116ed4cc9474624f9711f90efa13a..61b2f0a3a8edf0a00a7a783d088b4751e379859a 100644 (file)
@@ -97,4 +97,10 @@ public class SwitchConfig implements Serializable {
             return false;
         return true;
     }
+
+    @Override
+    public String toString() {
+        return ("Switch Config [Node=" + nodeId + " Description=" + description +
+                " Tier=" + tier + " Mode=" + mode + "]");
+    }
 }
index ab3149610309b08f314b9cee1ca85a6998063a5c..d32f98650b8b549ce8235fd3c14d22c55205ac56 100644 (file)
@@ -52,14 +52,14 @@ import org.opendaylight.controller.sal.core.Tier;
 import org.opendaylight.controller.sal.core.UpdateType;
 import org.opendaylight.controller.sal.inventory.IInventoryService;
 import org.opendaylight.controller.sal.inventory.IListenInventoryUpdates;
-import org.opendaylight.controller.sal.utils.HexEncode;
-import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.HexEncode;
 import org.opendaylight.controller.sal.utils.IObjectReader;
 import org.opendaylight.controller.sal.utils.ObjectReader;
 import org.opendaylight.controller.sal.utils.ObjectWriter;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
 import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.controller.switchmanager.IInventoryListener;
 import org.opendaylight.controller.switchmanager.ISpanAware;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
@@ -174,7 +174,7 @@ CommandProvider {
 
     public void startUp() {
         // Initialize configuration file names
-        subnetFileName = ROOT + "subnets" + this.getContainerName() + ".conf";
+        subnetFileName = ROOT + "subnets_" + this.getContainerName() + ".conf";
         spanFileName = ROOT + "spanPorts_" + this.getContainerName() + ".conf";
         switchConfigFileName = ROOT + "switchConfig_" + this.getContainerName()
                 + ".conf";
@@ -201,7 +201,6 @@ CommandProvider {
     }
 
     public void shutDown() {
-        destroyCaches(this.getContainerName());
     }
 
     @SuppressWarnings("deprecation")
@@ -499,11 +498,13 @@ CommandProvider {
         }
 
         conf.addNodeConnectors(switchPorts);
+        subnetsConfigList.put(name, conf);
 
         // Update Database
         Subnet sub = subnets.get(conf.getIPnum());
         Set<NodeConnector> sp = conf.getNodeConnectors(switchPorts);
         sub.addNodeConnectors(sp);
+        subnets.put(conf.getIPnum(), sub);
         return new Status(StatusCode.SUCCESS, null);
     }
 
@@ -515,11 +516,13 @@ CommandProvider {
             return new Status(StatusCode.NOTFOUND, "Subnet does not exist");
         }
         conf.removeNodeConnectors(switchPorts);
+        subnetsConfigList.put(name, conf);
 
         // Update Database
         Subnet sub = subnets.get(conf.getIPnum());
         Set<NodeConnector> sp = conf.getNodeConnectors(switchPorts);
         sub.deleteNodeConnectors(sp);
+        subnets.put(conf.getIPnum(), sub);
         return new Status(StatusCode.SUCCESS, null);
     }
 
@@ -554,7 +557,7 @@ CommandProvider {
     @SuppressWarnings("unchecked")
     private void loadSubnetConfiguration() {
         ObjectReader objReader = new ObjectReader();
-        ConcurrentMap<Integer, SubnetConfig> confList = (ConcurrentMap<Integer, SubnetConfig>) objReader
+        ConcurrentMap<String, SubnetConfig> confList = (ConcurrentMap<String, SubnetConfig>) objReader
                 .read(this, subnetFileName);
 
         if (confList == null) {
@@ -598,6 +601,11 @@ CommandProvider {
 
     @Override
     public void updateSwitchConfig(SwitchConfig cfgObject) {
+        // update default container only
+        if (!isDefaultContainer) {
+            return;
+        }
+
         boolean modeChange = false;
 
         SwitchConfig sc = nodeConfigList.get(cfgObject.getNodeId());
@@ -607,28 +615,25 @@ CommandProvider {
 
         nodeConfigList.put(cfgObject.getNodeId(), cfgObject);
         try {
-            // update default container only
-            if (isDefaultContainer) {
-                String nodeId = cfgObject.getNodeId();
-                Node node = Node.fromString(nodeId);
-                Map<String, Property> propMap;
-                if (nodeProps.get(node) != null) {
-                    propMap = nodeProps.get(node);
-                } else {
-                    propMap = new HashMap<String, Property>();
-                }
-                Property desc = new Description(cfgObject.getNodeDescription());
-                propMap.put(desc.getName(), desc);
-                Property tier = new Tier(Integer.parseInt(cfgObject.getTier()));
-                propMap.put(tier.getName(), tier);
-                addNodeProps(node, propMap);
+            String nodeId = cfgObject.getNodeId();
+            Node node = Node.fromString(nodeId);
+            Map<String, Property> propMap;
+            if (nodeProps.get(node) != null) {
+                propMap = nodeProps.get(node);
+            } else {
+                propMap = new HashMap<String, Property>();
+            }
+            Property desc = new Description(cfgObject.getNodeDescription());
+            propMap.put(desc.getName(), desc);
+            Property tier = new Tier(Integer.parseInt(cfgObject.getTier()));
+            propMap.put(tier.getName(), tier);
+            addNodeProps(node, propMap);
 
-                log.info("Set Node {}'s Mode to {}", nodeId,
-                        cfgObject.getMode());
+            log.info("Set Node {}'s Mode to {}", nodeId,
+                    cfgObject.getMode());
 
-                if (modeChange) {
-                    notifyModeChange(node, cfgObject.isProactive());
-                }
+            if (modeChange) {
+                notifyModeChange(node, cfgObject.isProactive());
             }
         } catch (Exception e) {
             log.debug("updateSwitchConfig: {}", e.getMessage());
@@ -1333,17 +1338,26 @@ CommandProvider {
             return;
         }
 
-        nodeProps = this.inventoryService.getNodeProps();
-        Set<Node> nodeSet = nodeProps.keySet();
-        if (nodeSet != null) {
-            for (Node node : nodeSet) {
-                log.debug("getInventories: {} added for container {}",
-                        new Object[] { node, containerName });
-                addNode(node, null);
+        Map<Node, Map<String, Property>> nodeProp = this.inventoryService.getNodeProps();
+        for(Map.Entry<Node, Map<String, Property>> entry : nodeProp.entrySet()) {
+            Node node = entry.getKey();
+            log.debug("getInventories: {} added for container {}",
+                    new Object[] { node, containerName });
+            Map<String, Property> propMap = entry.getValue();
+            Set<Property> props = new HashSet<Property>();
+            for(Property property : propMap.values()) {
+                props.add(property);
             }
+            addNode(node, props);
         }
 
-        nodeConnectorProps = inventoryService.getNodeConnectorProps();
+        Map<NodeConnector, Map<String, Property>> nodeConnectorProp = this.inventoryService.getNodeConnectorProps();
+        for(Map.Entry<NodeConnector, Map<String, Property>> entry : nodeConnectorProp.entrySet()) {
+            Map<String, Property> propMap = entry.getValue();
+            for(Property property : propMap.values()) {
+                addNodeConnectorProp(entry.getKey(), property);
+            }
+        }
     }
 
     private void clearInventories() {
index 863b0a64a04b6e2f32abfaf50bc78adf7965236b..a532560bcde4b3166cf42c7f7bc8e62fc83ef068 100644 (file)
   <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal"
     aria-hidden="true">&times;</button>
+   <button type="button" class="help" aria-hidden="true"
+    >?</button>
    <h3></h3>
   </div>
   <div class="modal-body"></div>
index cb6fbc54fce32f897c65c05512a785be7f018351..b5ab76f323a557278bdb4dd5fe70d7a040678f0b 100644 (file)
 .table-cursor tr:hover {
        cursor: pointer;
 }
+
+// hide
+.modal {
+       .help {
+               display: none;
+       }
+}
\ No newline at end of file