- If a port is already under OF control and then hw LLDP transmit is enabled on it... 40/140/1
authorJason Ye <yisye@cisco.com>
Thu, 11 Apr 2013 21:53:07 +0000 (14:53 -0700)
committerJason Ye <yisye@cisco.com>
Thu, 11 Apr 2013 21:53:07 +0000 (14:53 -0700)
- When we change the name of the Production switch, stale entries should be removed.
- Added Backend APIs to add/delete/get user link configs
- Northbound REST APIs to GET/POST/DELETE user link configs
- Endpoint connected as Production Switch to OF port. If the system-name TLV exists in the hw LLDP packet, it should be used for display.
- Some misc osgi debugging commands.

Signed-off-by: Jason Ye <yisye@cisco.com>
12 files changed:
opendaylight/northbound/topology/pom.xml
opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/TopologyNorthboundJAXRS.java
opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/TopologyUserLinks.java [new file with mode: 0644]
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/core/internal/SecureMessageReadWriteService.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/core/internal/SwitchHandler.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/DiscoveryService.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/TopologyServiceShim.java
opendaylight/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManagerImpl.java
opendaylight/topologymanager/pom.xml
opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/TopologyUserLinkConfig.java
opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImpl.java
opendaylight/topologymanager/src/test/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImplTest.java

index 82eaf4e..803fe40 100644 (file)
@@ -49,6 +49,7 @@
               com.sun.jersey.spi.container.servlet,
               javax.ws.rs,
               javax.ws.rs.core,
+              javax.xml.bind,
               javax.xml.bind.annotation,
               org.slf4j,
               com.sun.jersey.spi.spring.container.servlet,
index 00b27b0..5f1933b 100644 (file)
@@ -13,22 +13,31 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
 
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
+import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.xml.bind.JAXBElement;
 
 import org.codehaus.enunciate.jaxrs.ResponseCode;
 import org.codehaus.enunciate.jaxrs.StatusCodes;
 import org.codehaus.enunciate.jaxrs.TypeHint;
 import org.opendaylight.controller.northbound.commons.RestMessages;
+import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
 import org.opendaylight.controller.sal.core.Edge;
 import org.opendaylight.controller.sal.core.Property;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
+import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.topologymanager.ITopologyManager;
+import org.opendaylight.controller.topologymanager.TopologyUserLinkConfig;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -52,7 +61,7 @@ public class TopologyNorthboundJAXRS {
 
     /**
      *
-     * Retrieve the Topology for the
+     * Retrieve the Topology
      *
      * @param containerName The container for which we want to retrieve the topology
      *
@@ -63,7 +72,7 @@ public class TopologyNorthboundJAXRS {
     @GET
     @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
     @TypeHint(Topology.class)
-    @StatusCodes( { @ResponseCode(code = 404, condition = "The containerName passed was not found") })
+    @StatusCodes( { @ResponseCode(code = 404, condition = "The Container Name passed was not found") })
     public Topology getTopology(
             @PathParam("containerName") String containerName) {
         ITopologyManager topologyManager = (ITopologyManager) ServiceHelper
@@ -85,4 +94,102 @@ public class TopologyNorthboundJAXRS {
 
         return null;
     }
+
+    /**
+    * Retrieve the user configured links 
+    *
+    * @param containerName The container for which we want to retrieve the user links
+    *
+    * @return A List of user configured links
+    */
+   @Path("/{containerName}/userLink")
+   @GET
+   @Produces( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+   @TypeHint(TopologyUserLinks.class)
+   @StatusCodes( { @ResponseCode(code = 404, condition = "The Container Name passed was not found") })
+   public TopologyUserLinks getUserLinks(
+           @PathParam("containerName") String containerName) {
+       ITopologyManager topologyManager = (ITopologyManager) ServiceHelper
+               .getInstance(ITopologyManager.class, containerName, this);
+       if (topologyManager == null) {
+           throw new ResourceNotFoundException(RestMessages.NOCONTAINER
+                   .toString());
+       }
+
+       ConcurrentMap<String, TopologyUserLinkConfig> userLinks = topologyManager.getUserLinks();
+       if ((userLinks != null) && (userLinks.values() != null)) {
+          List<TopologyUserLinkConfig> res = new ArrayList<TopologyUserLinkConfig>(userLinks.values());
+           return new TopologyUserLinks(res);
+       }
+
+       return null;
+   }
+   
+   /**
+    * Add an User Link
+    *
+    * @param containerName Name of the Container. The base Container is "default".
+    * @param TopologyUserLinkConfig in JSON or XML format
+    * @return Response as dictated by the HTTP Response Status code
+    */
+
+   @Path("/{containerName}/userLink")
+   @POST
+   @Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+   @StatusCodes( {
+           @ResponseCode(code = 201, condition = "User Link added successfully"),
+           @ResponseCode(code = 404, condition = "The Container Name passed was not found"),
+           @ResponseCode(code = 409, condition = "Failed to add User Link due to Conflicting Name"),
+           @ResponseCode(code = 500, condition = "Failed to add User Link. Failure Reason included in HTTP Error response"),
+           @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
+   public Response addUserLink(
+           @PathParam(value = "containerName") String containerName,
+           @TypeHint(TopologyUserLinkConfig.class) JAXBElement<TopologyUserLinkConfig> userLinkConfig) {
+
+               ITopologyManager topologyManager = (ITopologyManager) ServiceHelper
+                               .getInstance(ITopologyManager.class, containerName, this);
+               if (topologyManager == null) {
+                       throw new ResourceNotFoundException(RestMessages.NOCONTAINER
+                                       .toString());
+               }
+
+               Status status = topologyManager.addUserLink(userLinkConfig.getValue());
+               if (status.isSuccess()) {
+                       return Response.status(Response.Status.CREATED).build();
+               }
+               throw new InternalServerErrorException(status.getDescription());
+   }
+
+   /**
+    * Delete an User Link
+    *
+    * @param containerName Name of the Container. The base Container is "default".
+    * @param name Name of the Link Configuration
+    * @return Response as dictated by the HTTP Response Status code
+    */
+
+   @Path("/{containerName}/userLink/{name}")
+   @DELETE
+   @Consumes( { MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+   @StatusCodes( {
+              @ResponseCode(code = 200, condition = "Operation successful"),
+           @ResponseCode(code = 404, condition = "The Container Name or Link Configuration Name was not found"),
+           @ResponseCode(code = 503, condition = "One or more of Controller services are unavailable") })
+   public Response deleteUserLink(
+                  @PathParam("containerName") String containerName,
+           @PathParam("name") String name) {
+
+               ITopologyManager topologyManager = (ITopologyManager) ServiceHelper
+                               .getInstance(ITopologyManager.class, containerName, this);
+          if (topologyManager == null) {
+                  throw new ResourceNotFoundException(RestMessages.NOCONTAINER
+                                  .toString());
+          }
+
+       Status ret = topologyManager.deleteUserLink(name);
+       if (ret.isSuccess()) {
+           return Response.ok().build();
+       }
+       throw new ResourceNotFoundException(ret.getDescription());
+   }
 }
diff --git a/opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/TopologyUserLinks.java b/opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/TopologyUserLinks.java
new file mode 100644 (file)
index 0000000..1b19edc
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.topology.northbound;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.controller.topologymanager.TopologyUserLinkConfig;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+
+public class TopologyUserLinks {
+       @XmlElement
+       List<TopologyUserLinkConfig> userLinks;
+       
+       //To satisfy JAXB
+       private TopologyUserLinks() {
+               
+       }
+       
+       public List<TopologyUserLinkConfig> getUserLinks() {
+               return userLinks;
+       }
+
+       public void setUserLinks(List<TopologyUserLinkConfig> userLinks) {
+               this.userLinks = userLinks;
+       }
+
+       public TopologyUserLinks(List<TopologyUserLinkConfig> userLinks) {
+               this.userLinks = new ArrayList<TopologyUserLinkConfig>(userLinks);
+       }
+}
index 627e223..b411561 100644 (file)
@@ -69,8 +69,8 @@ public class SecureMessageReadWriteService implements IMessageReadWrite {
     private void createSecureChannel(SocketChannel socket) throws Exception {
        String keyStoreFile = System.getProperty("controllerKeyStore");
        String keyStorePassword = System.getProperty("controllerKeyStorePassword");
-       String trustStoreFile = System.getProperty("controllerTrustStore");;
-       String trustStorePassword = System.getProperty("controllerTrustStorePassword");;
+       String trustStoreFile = System.getProperty("controllerTrustStore");
+       String trustStorePassword = System.getProperty("controllerTrustStorePassword");
 
         KeyStore ks = KeyStore.getInstance("JKS");
         KeyStore ts = KeyStore.getInstance("JKS");
@@ -204,6 +204,7 @@ public class SecureMessageReadWriteService implements IMessageReadWrite {
 
        bytesRead = socket.read(peerNetData);
        if (bytesRead < 0) {
+               logger.debug("Message read operation failed");
                        throw new AsynchronousCloseException();
        }
 
index 4520375..b87b785 100644 (file)
@@ -428,7 +428,11 @@ public class SwitchHandler implements ISwitch {
     }
 
     private void reportError(Exception e) {
-        logger.debug("Caught exception ", e);
+       if (e instanceof AsynchronousCloseException) {
+               logger.debug("Caught exception {}", e.getMessage());
+       } else {
+               logger.warn("Caught exception {}", e.getMessage());
+       }
         // notify core of this error event and disconnect the switch
         ((Controller) core).takeSwitchEventError(this);
     }
index aa8c517..26ed4f2 100644 (file)
@@ -85,8 +85,9 @@ public class DiscoveryService implements IInventoryShimExternalListener,
     private long discoveryTimerTick = 1L * 1000; // per tick in msec
     private int discoveryTimerTickCount = 0; // main tick counter
     private int discoveryBatchMaxPorts = 500; // max # of ports handled in one batch
-    private int discoveryBatchPauseTicks = 28; // pause a little bit after this point
     private int discoveryBatchRestartTicks = 30; // periodically restart batching process
+    private int discoveryBatchPausePeriod = 2; // pause for few secs
+    private int discoveryBatchPauseTicks = discoveryBatchRestartTicks - discoveryBatchPausePeriod; // pause after this point
     private int discoveryRetry = 1; // number of retry after initial timeout
     private int discoveryTimeoutTicks = 2; // timeout 2 sec
     private int discoveryAgeoutTicks = 120; // age out 2 min
@@ -183,7 +184,7 @@ public class DiscoveryService implements IInventoryShimExternalListener,
             rawPkt = new RawPacket(data);
             rawPkt.setOutgoingNodeConnector(nodeConnector);
         } catch (ConstructionException cex) {
-            logger.debug("RawPacket creation caught exception {}", cex
+            logger.warn("RawPacket creation caught exception {}", cex
                     .getMessage());
         } catch (Exception e) {
             logger.error("Failed to serialize the LLDP packet: " + e);
@@ -195,12 +196,12 @@ public class DiscoveryService implements IInventoryShimExternalListener,
     private void sendDiscoveryPacket(NodeConnector nodeConnector,
             RawPacket outPkt) {
         if (nodeConnector == null) {
-            logger.error("nodeConnector is null");
+            logger.debug("Can not send discovery packet out since nodeConnector is null");
             return;
         }
 
         if (outPkt == null) {
-            logger.error("outPkt is null");
+            logger.debug("Can not send discovery packet out since outPkt is null");
             return;
         }
 
@@ -208,17 +209,17 @@ public class DiscoveryService implements IInventoryShimExternalListener,
         ISwitch sw = controller.getSwitches().get(sid);
 
         if (sw == null) {
-            logger.error("Switch of swid {} is null", sid);
+            logger.debug("Can not send discovery packet out since switch {} is null", sid);
             return;
         }
 
         if (!sw.isOperational()) {
-            logger.error("Switch {} is not operational", sw);
+            logger.debug("Can not send discovery packet out since switch {} is not operational", sw);
             return;
         }
 
         if (this.iDataPacketMux == null) {
-            logger.error("Cannot send discover packets out");
+            logger.debug("Can not send discovery packet out since DataPacket service is not available");
             return;
         }
 
@@ -280,39 +281,37 @@ public class DiscoveryService implements IInventoryShimExternalListener,
         }
 
         if ((dstNodeConnector == null) || (ethPkt == null)) {
-            logger
-                    .trace("Ignoring processing of discovery packet: Null node connector or packet");
+            logger.trace("Quit spoofing discovery packet: Null node connector or packet");
             return;
         }
 
-        logger.trace("Handle discovery packet {} from {}", ethPkt,
-                dstNodeConnector);
-
         LLDP lldp = (LLDP) ethPkt.getPayload();
 
         try {
             String nodeId = LLDPTLV.getHexStringValue(lldp.getChassisId().getValue(), lldp.getChassisId().getLength());
             String portId = LLDPTLV.getStringValue(lldp.getPortId().getValue(), lldp.getPortId().getLength());
-            Node srcNode = new Node(Node.NodeIDType.PRODUCTION, nodeId);
-            NodeConnector srcNodeConnector = NodeConnectorCreator
-                    .createNodeConnector(
-                            NodeConnector.NodeConnectorIDType.PRODUCTION,
-                            portId, srcNode);
+                       byte[] systemNameBytes = null;
+               // get system name if present in the LLDP pkt 
+               for (LLDPTLV lldptlv : lldp.getOptionalTLVList()) {
+                       if (lldptlv.getType() == LLDPTLV.TLVType.SystemName.getValue()) {
+                               systemNameBytes = lldptlv.getValue();
+                               break;
+                       }
+               }
+                       String nodeName = (systemNameBytes == null) ? nodeId : new String(systemNameBytes);
+                       Node srcNode = new Node(Node.NodeIDType.PRODUCTION, nodeName);
+                       NodeConnector srcNodeConnector = NodeConnectorCreator
+                    .createNodeConnector(NodeConnector.NodeConnectorIDType.PRODUCTION,
+                               portId, srcNode);
 
-            // push it out to Topology
             Edge edge = null;
             Set<Property> props = null;
-            try {
-                edge = new Edge(srcNodeConnector, dstNodeConnector);
-                props = getProps(dstNodeConnector);
-            } catch (ConstructionException e) {
-                logger.error(e.getMessage());
-            }
-            addEdge(edge, props);
+            edge = new Edge(srcNodeConnector, dstNodeConnector);
+            props = getProps(dstNodeConnector);
 
-            logger.trace("Received discovery packet for Edge {}", edge);
+            updateProdEdge(edge, props);
         } catch (Exception e) {
-            e.printStackTrace();
+            logger.warn("Caught exception ", e);
         }
     }
 
@@ -374,7 +373,7 @@ public class DiscoveryService implements IInventoryShimExternalListener,
             edge = new Edge(srcNodeConnector, dstNodeConnector);
             props = getProps(dstNodeConnector);
         } catch (ConstructionException e) {
-            logger.error(e.getMessage());
+            logger.error("Caught exception ", e);
         }
         addEdge(edge, props);
 
@@ -558,7 +557,7 @@ public class DiscoveryService implements IInventoryShimExternalListener,
 
         removeSet = getRemoveSet(prodMap.keySet(), node);
         for (NodeConnector nodeConnector : removeSet) {
-            removeProd(nodeConnector);
+            removeProdEdge(nodeConnector);
         }
     }
 
@@ -568,7 +567,7 @@ public class DiscoveryService implements IInventoryShimExternalListener,
         waitingList.remove(nodeConnector);
         pendingMap.remove(nodeConnector);
         removeEdge(nodeConnector, false);
-        removeProd(nodeConnector);
+        removeProdEdge(nodeConnector);
     }
 
     private void checkTimeout() {
@@ -622,7 +621,7 @@ public class DiscoveryService implements IInventoryShimExternalListener,
         }
 
         for (NodeConnector nodeConnector : removeSet) {
-            removeProd(nodeConnector);
+            removeProdEdge(nodeConnector);
         }
     }
 
@@ -732,24 +731,60 @@ public class DiscoveryService implements IInventoryShimExternalListener,
         logger.trace("Add edge {}", edge);
     }
 
-    /*
-     * Remove Production edge
+    
+    /**
+     * Update Production Edge
+     * 
+     * @param edge The Production Edge
+     * @param props Properties associated with the edge
      */
-    private void removeProd(NodeConnector nodeConnector) {
-        agingMap.remove(nodeConnector);
+    private void updateProdEdge(Edge edge, Set<Property> props) {
+       NodeConnector edgePort = edge.getHeadNodeConnector();
+       
+       /* Do not update in case there is an existing OpenFlow link */
+       if (edgeMap.get(edgePort) != null) {
+               logger.trace("Discarded edge {} since there is an existing OF link {}",
+                               edge, edgeMap.get(edgePort));
+               return;
+       }
+       
+       /* Look for any existing Production Edge */
+       Edge oldEdge = prodMap.get(edgePort);           
+       if (oldEdge == null) {
+               /* Let's add a new one */
+               addEdge(edge, props);
+       } else if (!edge.equals(oldEdge)) {
+               /* Remove the old one first */
+               removeProdEdge(oldEdge.getHeadNodeConnector());
+               /* Then add the new one */
+               addEdge(edge, props);                   
+       } else {
+               /* o/w, just reset the aging timer */
+            NodeConnector dst = edge.getHeadNodeConnector();
+            agingMap.put(dst, 0);              
+       }
+    }
+
+    /**
+     * Remove Production Edge for a given edge port
+     * 
+     * @param edgePort The OF edge port
+     */
+    private void removeProdEdge(NodeConnector edgePort) {
+        agingMap.remove(edgePort);
 
         Edge edge = null;
         Set<NodeConnector> prodKeySet = prodMap.keySet();
-        if ((prodKeySet != null) && (prodKeySet.contains(nodeConnector))) {
-            edge = prodMap.get(nodeConnector);
-            prodMap.remove(nodeConnector);
+        if ((prodKeySet != null) && (prodKeySet.contains(edgePort))) {
+            edge = prodMap.get(edgePort);
+            prodMap.remove(edgePort);
         }
 
         // notify Topology
         if (this.discoveryService != null) {
             this.discoveryService.notifyEdge(edge, UpdateType.REMOVED, null);
         }
-        logger.trace("Remove {}", nodeConnector);
+        logger.trace("Remove edge {}", edge);
     }
 
     /*
@@ -851,17 +886,14 @@ public class DiscoveryService implements IInventoryShimExternalListener,
         help.append("\t ppl                    - Print pendingList entries\n");
         help.append("\t ptick                  - Print tick time in msec\n");
         help.append("\t pcc                    - Print CC info\n");
-        help
-                .append("\t psize                  - Print sizes of all the lists\n");
+        help.append("\t psize                  - Print sizes of all the lists\n");
         help.append("\t ptm                    - Print timeout info\n");
         help.append("\t ecc                       - Enable CC\n");
         help.append("\t dcc                       - Disable CC\n");
-        help
-                .append("\t scc [multiple]         - Set/show CC multiple and interval\n");
+        help.append("\t scc [multiple]         - Set/show CC multiple and interval\n");
         help.append("\t sports [ports]                    - Set/show max ports per batch\n");
-        help.append("\t spause [ticks]         - Set/show pause ticks\n");
-        help
-                .append("\t sdi [ticks]           - Set/show discovery interval in ticks\n");
+        help.append("\t spause [ticks]         - Set/show pause period\n");
+        help.append("\t sdi [ticks]               - Set/show discovery interval in ticks\n");
         help.append("\t stm [ticks]            - Set/show per timeout ticks\n");
         help.append("\t sretry [count]                    - Set/show num of retries\n");
         help.append("\t addsw <swid>              - Add a switch\n");
@@ -956,8 +988,7 @@ public class DiscoveryService implements IInventoryShimExternalListener,
         }
         ci.println("Current aging time limit " + this.discoveryAgeoutTicks);
         ci.println("\n");
-        ci
-                .println("                                Edge                                                       Aging ");
+        ci.println("                           Edge                                 Aging ");
         Collection<Edge> prodSet = prodMap.values();
         if (prodSet == null) {
             return;
@@ -969,7 +1000,7 @@ public class DiscoveryService implements IInventoryShimExternalListener,
             }
         }
         ci.println("\n");
-        ci.println("              NodeConnector                                                                        Edge ");
+        ci.println("              NodeConnector                                                Edge ");
         Set<NodeConnector> keySet = prodMap.keySet();
         if (keySet == null) {
             return;
@@ -1060,15 +1091,17 @@ public class DiscoveryService implements IInventoryShimExternalListener,
 
     public void _spause(CommandInterpreter ci) {
         String val = ci.nextArgument();
-        String out = "Please enter pause tick value less than "
-                + discoveryBatchRestartTicks + ". Current value is "
-                + discoveryBatchPauseTicks;
+        String out = "Please enter pause period less than "
+                               + discoveryBatchRestartTicks + ". Current pause period is "
+                               + discoveryBatchPausePeriod + " pause tick is "
+                               + discoveryBatchPauseTicks + ".";
 
         if (val != null) {
             try {
                 int pause = Integer.parseInt(val);
                 if (pause < discoveryBatchRestartTicks) {
-                    discoveryBatchPauseTicks = pause;
+                       discoveryBatchPausePeriod = pause;
+                    discoveryBatchPauseTicks = discoveryBatchRestartTicks - discoveryBatchPausePeriod;
                     return;
                 }
             } catch (Exception e) {
@@ -1080,18 +1113,22 @@ public class DiscoveryService implements IInventoryShimExternalListener,
 
     public void _sdi(CommandInterpreter ci) {
         String val = ci.nextArgument();
-        if (val == null) {
-            ci
-                    .println("Please enter discovery interval in ticks. Current value is "
-                            + discoveryBatchRestartTicks);
-            return;
-        }
-        try {
-            discoveryBatchRestartTicks = Integer.parseInt(val);
-        } catch (Exception e) {
-            ci.println("Please enter a valid number");
+        String out = "Please enter discovery interval greater than "
+                               + discoveryBatchPausePeriod + ". Current value is "
+                               + discoveryBatchRestartTicks + ".";
+
+        if (val != null) {
+               try {
+                       int restart = Integer.parseInt(val);        
+                   if (restart > discoveryBatchPausePeriod) {
+                       discoveryBatchRestartTicks = restart;
+                       discoveryBatchPauseTicks = discoveryBatchRestartTicks - discoveryBatchPausePeriod;
+                       return;
+                   }
+               } catch (Exception e) {
+               }
         }
-        return;
+        ci.println(out);
     }
 
     public void _sports(CommandInterpreter ci) {
index 5d0ee5d..ab7ab2e 100644 (file)
@@ -557,14 +557,14 @@ public class TopologyServiceShim implements IDiscoveryService,
         }
 
         ci.println("Container: " + container);
-        ci
-                .println("                             Edge                                          Bandwidth");
+        ci.println("                             Edge                                          Bandwidth");
 
         Map<NodeConnector, Pair<Edge, Set<Property>>> edgePropsMap = edgeMap
                 .get(container);
         if (edgePropsMap == null) {
             return;
         }
+        int count = 0;
         for (Pair<Edge, Set<Property>> edgeProps : edgePropsMap.values()) {
             if (edgeProps == null) {
                 continue;
@@ -576,9 +576,10 @@ public class TopologyServiceShim implements IDiscoveryService,
                     bw = ((Bandwidth) prop).getValue();
                 }
             }
-
+            count++;
             ci.println(edgeProps.getLeft() + "          " + bw);
         }
+        ci.println("Total number of Edges: " + count);
     }
 
     public void _bwfactor(CommandInterpreter ci) {
index c4f4b11..d3dcc65 100755 (executable)
@@ -1430,22 +1430,17 @@ public class SwitchManagerImpl implements ISwitchManager,
         StringBuffer help = new StringBuffer();
         help.append("---Switch Manager---\n");
         help.append("\t pns                    - Print connected nodes\n");
-        help
-                .append("\t pncs <node id>         - Print node connectors for a given node\n");
-        help
-                .append("\t pencs <node id>        - Print enabled node connectors for a given node\n");
-        help
-                .append("\t pdm <node id>          - Print switch ports in device map\n");
+        help.append("\t pncs <node id>         - Print node connectors for a given node\n");
+        help.append("\t pencs <node id>        - Print enabled node connectors for a given node\n");
+        help.append("\t pdm <node id>          - Print switch ports in device map\n");
         help.append("\t snt <node id> <tier>   - Set node tier number\n");
-        help
-                .append("\t hostRefresh <on/off/?> - Enable/Disable/Query host refresh\n");
+        help.append("\t hostRefresh <on/off/?> - Enable/Disable/Query host refresh\n");
         help.append("\t hostRetry <count>      - Set host retry count\n");
         return help.toString();
     }
 
     public void _pns(CommandInterpreter ci) {
-        ci
-                .println("           Node                       Type             Name             Tier");
+        ci.println("           Node                       Type             Name             Tier");
         if (nodeProps == null) {
             return;
         }
@@ -1461,6 +1456,7 @@ public class SwitchManagerImpl implements ISwitchManager,
             ci.println(node + "            " + node.getType()
                     + "            " + nodeName + "            " + tierNum);
         }
+        ci.println("Total number of Nodes: " + nodeSet.size());
     }
 
     public void _pencs(CommandInterpreter ci) {
@@ -1482,6 +1478,7 @@ public class SwitchManagerImpl implements ISwitchManager,
             }
             ci.println(nodeConnector);
         }
+        ci.println("Total number of NodeConnectors: " + nodeConnectorSet.size());
     }
 
     public void _pncs(CommandInterpreter ci) {
@@ -1514,6 +1511,7 @@ public class SwitchManagerImpl implements ISwitchManager,
             out += (state != null) ? state.getValue() : " ";
             ci.println(out);
         }
+        ci.println("Total number of NodeConnectors: " + nodeConnectorSet.size());
     }
 
     public void _pdm(CommandInterpreter ci) {
@@ -1525,8 +1523,7 @@ public class SwitchManagerImpl implements ISwitchManager,
         Object id = Long.decode(st);
         Switch sw = getSwitchByNode(NodeCreator.createOFNode((Long) id));
 
-        ci
-                .println("          NodeConnector                        Name");
+        ci.println("          NodeConnector                        Name");
         if (sw == null) {
             return;
         }
@@ -1557,13 +1554,13 @@ public class SwitchManagerImpl implements ISwitchManager,
                     }
                 }
 
-                ci
-                        .println(nodeConnector
-                                + "            "
-                                + ((nodeConnectorName == null) ? ""
-                                        : nodeConnectorName) + "("
-                                + nodeConnector.getID() + ")");
+                ci.println(nodeConnector
+                               + "            "
+                               + ((nodeConnectorName == null) ? ""
+                                               : nodeConnectorName) + "("
+                        + nodeConnector.getID() + ")");
             }
+            ci.println("Total number of NodeConnectors: " + nodeConnectorSet.size());
         }
     }
 
index aebaeca..dd7ad2d 100755 (executable)
@@ -27,6 +27,7 @@
              org.opendaylight.controller.topologymanager
            </Export-Package>
            <Import-Package>
+          javax.xml.bind.annotation,
              org.opendaylight.controller.sal.core,
              org.opendaylight.controller.sal.utils,
              org.opendaylight.controller.sal.packet,
@@ -36,6 +37,7 @@
           org.osgi.service.component,
              org.slf4j,
           org.apache.felix.dm,
+          org.apache.commons.lang3.builder,
           org.apache.commons.lang3.tuple,
                  org.eclipse.osgi.framework.console,
           org.osgi.framework
index 1bd9ac6..fafbd4b 100644 (file)
@@ -12,12 +12,25 @@ package org.opendaylight.controller.topologymanager;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
-
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.core.Node.NodeIDType;
+import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType;
+import org.opendaylight.controller.sal.core.NodeConnector;
 import org.opendaylight.controller.sal.utils.GUIField;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Interface class that provides methods to manipulate user configured link
  */
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
 public class TopologyUserLinkConfig implements Serializable {
     private static final long serialVersionUID = 1L;
     private static final String regexDatapathID = "^([0-9a-fA-F]{1,2}[:-]){7}[0-9a-fA-F]{1,2}$";
@@ -26,6 +39,8 @@ public class TopologyUserLinkConfig implements Serializable {
             GUIField.NAME.toString(), GUIField.SRCNODE.toString(),
             GUIField.SRCPORT.toString(), GUIField.DSTNODE.toString(),
             GUIField.DSTPORT.toString() };
+    private static final Logger logger = LoggerFactory
+    .getLogger(TopologyUserLinkConfig.class);
 
     public enum STATUS {
         SUCCESS("Success"), LINKDOWN("Link Down"), INCORRECT(
@@ -53,11 +68,25 @@ public class TopologyUserLinkConfig implements Serializable {
         }
     }
 
+    @XmlElement
     private String status;
+    @XmlElement
     private String name;
+    @XmlElement
+    private String srcNodeIDType;
+    @XmlElement
     private String srcSwitchId;
+    @XmlElement
+    private String srcNodeConnectorIDType;
+    @XmlElement
     private String srcPort;
+    @XmlElement
+    private String dstNodeIDType;
+    @XmlElement
     private String dstSwitchId;
+    @XmlElement
+    private String dstNodeConnectorIDType;
+    @XmlElement
     private String dstPort;
 
     public TopologyUserLinkConfig() {
@@ -65,17 +94,55 @@ public class TopologyUserLinkConfig implements Serializable {
         status = STATUS.LINKDOWN.toString();
     }
 
-    public TopologyUserLinkConfig(String name, String srcSwitchId,
-            String srcPort, String dstSwitchId, String dstPort) {
+       public TopologyUserLinkConfig(String name, String srcNodeIDType,
+                       String srcSwitchId, String srcNodeConnectorIDType, String srcPort,
+                       String dstNodeIDType, String dstSwitchId,
+                       String dstNodeConnectorIDType, String dstPort) {
         super();
         this.name = name;
+        this.srcNodeIDType = srcNodeIDType;
         this.srcSwitchId = srcSwitchId;
+        this.dstNodeIDType = dstNodeIDType;
         this.dstSwitchId = dstSwitchId;
+        this.srcNodeConnectorIDType = srcNodeConnectorIDType;
         this.srcPort = srcPort;
+        this.dstNodeConnectorIDType = dstNodeConnectorIDType;
         this.dstPort = dstPort;
     }
 
-    public String getName() {
+    public String getSrcNodeIDType() {
+               return srcNodeIDType;
+       }
+
+       public void setSrcNodeIDType(String srcNodeIDType) {
+               this.srcNodeIDType = srcNodeIDType;
+       }
+
+       public String getSrcNodeConnectorIDType() {
+               return srcNodeConnectorIDType;
+       }
+
+       public void setSrcNodeConnectorIDType(String srcNodeConnectorIDType) {
+               this.srcNodeConnectorIDType = srcNodeConnectorIDType;
+       }
+
+       public String getDstNodeIDType() {
+               return dstNodeIDType;
+       }
+
+       public void setDstNodeIDType(String dstNodeIDType) {
+               this.dstNodeIDType = dstNodeIDType;
+       }
+
+       public String getDstNodeConnectorIDType() {
+               return dstNodeConnectorIDType;
+       }
+
+       public void setDstNodeConnectorIDType(String dstNodeConnectorIDType) {
+               this.dstNodeConnectorIDType = dstNodeConnectorIDType;
+       }
+
+       public String getName() {
         return name;
     }
 
@@ -136,6 +203,28 @@ public class TopologyUserLinkConfig implements Serializable {
                 .matches(regexDatapathIDLong)));
     }
 
+    private boolean isValidSwitchId(String switchId, String typeStr) {
+        if (typeStr.equals(NodeIDType.OPENFLOW)) {
+            return isValidSwitchId(switchId);
+        } else if (typeStr.equals(NodeIDType.ONEPK) || 
+                          typeStr.equals(NodeIDType.PCEP) || 
+                          typeStr.equals(NodeIDType.PRODUCTION)) {
+            return true;
+        } else {
+                       logger.warn("Invalid node id type {}", typeStr);
+               return false;
+        }
+    }
+
+    private boolean isValidPortId(String portId, String nodeConnectorType) {
+               if (NodeConnectorIDType.getClassType(nodeConnectorType) == null) {
+                       logger.warn("Invalid node connector id type {}", nodeConnectorType);
+                       return false; 
+               }
+               
+               return true;
+       }
+
     private long getSwitchIDLong(String switchId) {
         int radix = 16;
         String switchString = "0";
@@ -156,12 +245,26 @@ public class TopologyUserLinkConfig implements Serializable {
     }
 
     public boolean isValid() {
-        if (name == null || srcSwitchId == null || dstSwitchId == null
-                || srcPort == null || dstPort == null)
+               if (name == null || srcSwitchId == null || dstSwitchId == null
+                               || srcPort == null || dstPort == null || srcNodeIDType == null
+                               || dstNodeIDType == null || srcNodeConnectorIDType == null
+                               || dstNodeConnectorIDType == null) {
             return false;
-        if (!isValidSwitchId(srcSwitchId) || !isValidSwitchId(dstSwitchId))
-            return false;
-        return true;
+               }
+               
+               if (!isValidSwitchId(srcSwitchId, srcNodeIDType) || 
+                       !isValidSwitchId(dstSwitchId, dstNodeIDType)) {
+                       logger.warn("Invalid switch id");
+                       return false;
+               }
+               
+               if (!isValidPortId(srcPort, srcNodeConnectorIDType) || 
+                       !isValidPortId(dstPort, dstNodeConnectorIDType)) {
+                       logger.warn("Invalid port id");
+                       return false;
+               }
+                       
+               return true;
     }
 
     public boolean isSrcPortByName() {
@@ -192,22 +295,18 @@ public class TopologyUserLinkConfig implements Serializable {
 
     @Override
     public String toString() {
-        return "ITopologyUserLinkConfig [status=" + status + ", name=" + name
-                + ", srcSwitchId=" + srcSwitchId + ", srcPort=" + srcPort
-                + ", dstSwitchId=" + dstSwitchId + ", dstPort=" + dstPort + "]";
+               return "ITopologyUserLinkConfig [status=" + status + ", name=" + name
+                               + ", srcNodeIDType=" + srcNodeIDType + ", srcSwitchId="
+                               + srcSwitchId + ", srcNodeConnectorIDType="
+                               + srcNodeConnectorIDType + ", srcPort=" + srcPort
+                               + ", dstNodeIDType=" + dstNodeIDType + ", dstId="
+                               + dstSwitchId + ", dstNodeConnectorIDType="
+                               + dstNodeConnectorIDType + ", dstPort=" + dstPort + "]";
     }
 
     @Override
     public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((dstPort == null) ? 0 : dstPort.hashCode());
-        result = prime * result
-                + ((dstSwitchId == null) ? 0 : dstSwitchId.hashCode());
-        result = prime * result + ((srcPort == null) ? 0 : srcPort.hashCode());
-        result = prime * result
-                + ((srcSwitchId == null) ? 0 : srcSwitchId.hashCode());
-        return result;
+        return HashCodeBuilder.reflectionHashCode(this);
     }
 
     public boolean equals(Long srcNid, String srcPortName, Long dstNid,
index 9d24cc6..25058a3 100644 (file)
@@ -37,14 +37,15 @@ import org.opendaylight.controller.sal.core.Edge;
 import org.opendaylight.controller.sal.core.Host;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType;
 import org.opendaylight.controller.sal.core.Property;
 import org.opendaylight.controller.sal.core.TimeStamp;
 import org.opendaylight.controller.sal.core.UpdateType;
+import org.opendaylight.controller.sal.core.Node.NodeIDType;
 import org.opendaylight.controller.sal.topology.IListenTopoUpdates;
 import org.opendaylight.controller.sal.topology.ITopologyService;
 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;
@@ -543,71 +544,22 @@ public class TopologyManagerImpl implements ITopologyManager,
     }
 
     private Edge getReverseLinkTuple(TopologyUserLinkConfig link) {
-        TopologyUserLinkConfig rLink = new TopologyUserLinkConfig(link
-                .getName(), link.getDstSwitchId(), link.getDstPort(), link
-                .getSrcSwitchId(), link.getSrcPort());
+               TopologyUserLinkConfig rLink = new TopologyUserLinkConfig(
+                               link.getName(), link.getDstNodeIDType(), link.getDstSwitchId(),
+                               link.getDstNodeConnectorIDType(), link.getDstPort(),
+                               link.getSrcNodeIDType(), link.getSrcSwitchId(),
+                               link.getSrcNodeConnectorIDType(), link.getSrcPort());
         return getLinkTuple(rLink);
     }
 
     private Edge getLinkTuple(TopologyUserLinkConfig link) {
         Edge linkTuple = null;
-        Long sID = link.getSrcSwitchIDLong();
-        Long dID = link.getDstSwitchIDLong();
-        Short srcPort = Short.valueOf((short) 0);
-        Short dstPort = Short.valueOf((short) 0);
-        if (link.isSrcPortByName()) {
-            // TODO find the inventory service to do this, for now 0
-            //srcPort = srcSw.getPortNumber(link.getSrcPort());
-        } else {
-            srcPort = Short.parseShort(link.getSrcPort());
-        }
-
-        if (link.isDstPortByName()) {
-            //dstPort = dstSw.getPortNumber(link.getDstPort());;
-        } else {
-            dstPort = Short.parseShort(link.getDstPort());
-        }
 
         // if atleast 1 link exists for the srcPort and atleast 1 link exists for the dstPort
         // that makes it ineligible for the Manual link addition
         // This is just an extra protection to avoid mis-programming.
         boolean srcLinkExists = false;
         boolean dstLinkExists = false;
-        /**
-         * Disabling this optimization for now to understand the real benefit of doing this.
-         * Since this is a Manual Link addition, the user knows what he is doing and it is
-         * not good to restrict such creativity...
-         */
-        /*
-          Set <Edge> links = oneTopology.getLinks().keySet();
-          if (links != null) {
-          for (Edge eLink : links) {
-          if (!eLink.isUserCreated() &&
-          eLink.getSrc().getSid().equals(link.getSrcSwitchIDLong()) &&
-          eLink.getSrc().getPort().equals(srcPort)) {
-          srcLinkExists = true;
-          }
-
-          if (!eLink.isUserCreated() &&
-          eLink.getSrc().getSid().equals(link.getSrcSwitchIDLong()) &&
-          eLink.getSrc().getPort().equals(srcPort)) {
-          dstLinkExists = true;
-          }
-
-          if (!eLink.isUserCreated() &&
-          eLink.getDst().getSid().equals(link.getSrcSwitchIDLong()) &&
-          eLink.getDst().getPort().equals(srcPort)) {
-          srcLinkExists = true;
-          }
-
-          if (!eLink.isUserCreated() &&
-          eLink.getDst().getSid().equals(link.getSrcSwitchIDLong()) &&
-          eLink.getDst().getPort().equals(srcPort)) {
-          dstLinkExists = true;
-          }
-          }
-          }
-         */
         //TODO check a way to validate the port with inventory services
         //if (srcSw.getPorts().contains(srcPort) &&
         //dstSw.getPorts().contains(srcPort) &&
@@ -617,17 +569,49 @@ public class TopologyManagerImpl implements ITopologyManager,
             NodeConnector sPort = null;
             NodeConnector dPort = null;
             linkTuple = null;
+            String srcNodeIDType = link.getSrcNodeIDType();
+            String srcNodeConnectorIDType = link.getSrcNodeConnectorIDType();
+            String dstNodeIDType = link.getDstNodeIDType();
+            String dstNodeConnectorIDType = link.getDstNodeConnectorIDType();
             try {
-                sNode = new Node(Node.NodeIDType.OPENFLOW, sID);
-                dNode = new Node(Node.NodeIDType.OPENFLOW, dID);
-                sPort = new NodeConnector(
-                        NodeConnector.NodeConnectorIDType.OPENFLOW, srcPort,
-                        sNode);
-                dPort = new NodeConnector(
-                        NodeConnector.NodeConnectorIDType.OPENFLOW, dstPort,
-                        dNode);
+               if (srcNodeIDType.equals(NodeIDType.OPENFLOW)) {
+                    sNode = new Node(srcNodeIDType, link.getSrcSwitchIDLong());
+               } else {
+                    sNode = new Node(srcNodeIDType, link.getSrcSwitchId());                            
+               }
+
+               if (dstNodeIDType.equals(NodeIDType.OPENFLOW)) {
+                    dNode = new Node(dstNodeIDType, link.getDstSwitchIDLong());
+               } else {
+                    dNode = new Node(dstNodeIDType, link.getDstSwitchId());                            
+               }
+       
+               if (srcNodeConnectorIDType.equals(NodeConnectorIDType.OPENFLOW)) {
+                    Short srcPort = Short.valueOf((short) 0);
+                               if (!link.isSrcPortByName()) {
+                                       srcPort = Short.parseShort(link.getSrcPort());
+                               }
+                                       sPort = new NodeConnector(srcNodeConnectorIDType, 
+                                                       srcPort, sNode);
+               } else {
+                               sPort = new NodeConnector(srcNodeConnectorIDType,
+                                               link.getSrcPort(), sNode);                      
+               }
+
+               if (dstNodeConnectorIDType.equals(NodeConnectorIDType.OPENFLOW)) {
+                    Short dstPort = Short.valueOf((short) 0);
+                               if (!link.isDstPortByName()) {
+                           dstPort = Short.parseShort(link.getDstPort());
+                       }
+                                       dPort = new NodeConnector(dstNodeConnectorIDType,
+                                                       dstPort, dNode);
+               } else {
+                                       dPort = new NodeConnector(dstNodeConnectorIDType,
+                                                       link.getDstPort(), dNode);
+               }
                 linkTuple = new Edge(sPort, dPort);
             } catch (ConstructionException cex) {
+               log.warn("Caught exception ", cex);
             }
             return linkTuple;
         }
@@ -664,14 +648,8 @@ public class TopologyManagerImpl implements ITopologyManager,
         Edge linkTuple = getLinkTuple(link);
         if (linkTuple != null) {
             try {
-                // TODO The onetopology will be gone too, topology
-                //manager is the master of the topology at this point
-                //if (oneTopology.addUserConfiguredLink(linkTuple)) {
                 linkTuple = getReverseLinkTuple(link);
-                //if (oneTopology.addUserConfiguredLink(linkTuple)) {
                 link.setStatus(TopologyUserLinkConfig.STATUS.SUCCESS);
-                //}
-                //}
             } catch (Exception e) {
                 return new Status(StatusCode.INTERNALERROR,
                                "Exception while adding custom link : " + 
@@ -723,16 +701,20 @@ public class TopologyManagerImpl implements ITopologyManager,
     public String getHelp() {
         StringBuffer help = new StringBuffer();
         help.append("---Topology Manager---\n");
-        help
-                .append("\t addTopo name <src-sw-id> <port-number> <dst-sw-id> <port-number>\n");
+               help.append("\t addTopo name <NodeIDType> <src-sw-id> <NodeConnectorIDType> <port-number> <NodeIDType> <dst-sw-id> <NodeConnectorIDType> <port-number>\n");
         help.append("\t delTopo name\n");
-        help.append("\t _printTopo\n");
+        help.append("\t printTopo\n");
+        help.append("\t printNodeEdges\n");
         return help.toString();
     }
 
     public void _printTopo(CommandInterpreter ci) {
         for (String name : this.userLinks.keySet()) {
-            ci.println(name + " : " + userLinks.get(name));
+               TopologyUserLinkConfig linkConfig = userLinks.get(name);
+            ci.println("Name : " + name);
+            ci.println(linkConfig);
+            ci.println("Edge " +  getLinkTuple(linkConfig));
+            ci.println("Reverse Edge " +  getReverseLinkTuple(linkConfig));
         }
     }
 
@@ -743,43 +725,56 @@ public class TopologyManagerImpl implements ITopologyManager,
             return;
         }
 
+        String srcNodeIDType = ci.nextArgument();
+        if (srcNodeIDType == null) {
+            ci.println("Null source node ID Type. Example: OF or PR");
+            return;
+        }
+
         String dpid = ci.nextArgument();
         if (dpid == null) {
-            ci.println("Invalid Switch ID. Format xx:xx:xx:xx:xx:xx:xx:xx");
+            ci.println("Null source ndoe id");
             return;
         }
-        try {
-            HexEncode.stringToLong(dpid);
-        } catch (Exception e) {
-            ci.println("Invalid Switch ID. Format xx:xx:xx:xx:xx:xx:xx:xx");
+
+        String srcNodeConnectorIDType = ci.nextArgument();
+        if (srcNodeConnectorIDType == null) {
+            ci.println("Null source node connector ID Type. Example: OF or PR");
             return;
         }
 
         String port = ci.nextArgument();
         if (port == null) {
-            ci.println("Invalid port number");
+            ci.println("Null source port number");
+            return;
+        }
+
+        String dstNodeIDType = ci.nextArgument();
+        if (dstNodeIDType == null) {
+            ci.println("Null destination node ID Type. Example: OF or PR");
             return;
         }
 
         String ddpid = ci.nextArgument();
         if (ddpid == null) {
-            ci.println("Invalid Switch ID. Format xx:xx:xx:xx:xx:xx:xx:xx");
+            ci.println("Null destination node ID");
             return;
         }
-        try {
-            HexEncode.stringToLong(ddpid);
-        } catch (Exception e) {
-            ci.println("Invalid Switch ID. Format xx:xx:xx:xx:xx:xx:xx:xx");
+
+        String dstNodeConnectorIDType = ci.nextArgument();
+        if (dstNodeConnectorIDType == null) {
+            ci.println("Null destination node connector ID Type. Example: OF or PR");
             return;
         }
 
         String dport = ci.nextArgument();
         if (dport == null) {
-            ci.println("Invalid port number");
+            ci.println("Null destination port number");
             return;
         }
-        TopologyUserLinkConfig config = new TopologyUserLinkConfig(name,
-                dpid, port, ddpid, dport);
+               TopologyUserLinkConfig config = new TopologyUserLinkConfig(name,
+                               srcNodeIDType, dpid, srcNodeConnectorIDType, port,
+                               dstNodeIDType, ddpid, dstNodeConnectorIDType, dport);
         ci.println(this.addUserLink(config));
     }
 
@@ -792,6 +787,27 @@ public class TopologyManagerImpl implements ITopologyManager,
         this.deleteUserLink(name);
     }
 
+    public void _printNodeEdges(CommandInterpreter ci) {
+       Map<Node, Set<Edge>> nodeEdges = getNodeEdges();        
+       if (nodeEdges == null) {
+               return;
+       }
+       Set<Node> nodeSet = nodeEdges.keySet();
+       if (nodeSet == null) {
+               return;
+       }
+        ci.println("        Node                                         Edge");
+       for (Node node : nodeSet) {
+               Set<Edge> edgeSet = nodeEdges.get(node);
+               if (edgeSet == null) {
+                       continue;
+               }
+               for (Edge edge : edgeSet) {
+                       ci.println(node + "             " + edge);
+               }
+        }
+    }
+
     @Override
     public Object readObject(ObjectInputStream ois)
             throws FileNotFoundException, IOException, ClassNotFoundException {
index f2cf236..c2e3df9 100644 (file)
@@ -173,10 +173,10 @@ public class TopologyManagerImplTest {
        
        @Test
        public void testAddDeleteUserLink () {
-               TopologyUserLinkConfig link1 = new TopologyUserLinkConfig("default1", "1", "2", "1", "2"); 
-               TopologyUserLinkConfig link2 = new TopologyUserLinkConfig("default1", "10", "20", "10", "20"); 
-               TopologyUserLinkConfig link3 = new TopologyUserLinkConfig("default2", "1", "2", "1", "2"); 
-               TopologyUserLinkConfig link4 = new TopologyUserLinkConfig("default20", "10", "20", "10", "20"); 
+               TopologyUserLinkConfig link1 = new TopologyUserLinkConfig("default1", "OF", "1", "OF", "2", "OF", "1", "OF", "2"); 
+               TopologyUserLinkConfig link2 = new TopologyUserLinkConfig("default1", "OF", "10", "OF", "20", "OF", "10", "OF", "20"); 
+               TopologyUserLinkConfig link3 = new TopologyUserLinkConfig("default2", "OF", "1", "OF", "2", "OF", "1", "OF", "2"); 
+               TopologyUserLinkConfig link4 = new TopologyUserLinkConfig("default20", "OF", "10", "OF", "20", "OF", "10", "OF", "20"); 
                
                TopologyManagerImpl topoManagerImpl = new TopologyManagerImpl();
                topoManagerImpl.nonClusterObjectCreate();
@@ -201,28 +201,40 @@ public class TopologyManagerImplTest {
                topoManagerImpl.nonClusterObjectCreate();
                
                String name = null;
+               String srcNodeIDType = null;
                String srcSwitchId = null;
+               String srcNodeConnectorIDType = null;
                String srcPort = null;
+               String dstNodeIDType = null;
                String dstSwitchId = null;
+               String dstNodeConnectorIDType = null;
                String dstPort = null;
                
                /*Creating userlinks and checking for their validity*/
-               link[0] = new TopologyUserLinkConfig(name, srcSwitchId, srcPort, dstSwitchId, dstPort);
+               link[0] = new TopologyUserLinkConfig(name, srcNodeIDType, srcSwitchId,
+                               srcNodeConnectorIDType, srcPort, dstNodeIDType, dstSwitchId,
+                               dstNodeConnectorIDType, dstPort);
                Assert.assertTrue(link[0].isValid() == false);
                
-               srcSwitchId = "Z";
-               link[0] = new TopologyUserLinkConfig(name, srcSwitchId, srcPort, dstSwitchId, dstPort); 
+               srcSwitchId = "1";
+               link[0] = new TopologyUserLinkConfig(name, srcNodeIDType, srcSwitchId,
+                               srcNodeConnectorIDType, srcPort, dstNodeIDType, dstSwitchId,
+                               dstNodeConnectorIDType, dstPort);
                Assert.assertTrue(link[0].isValid() == false);
                
-               dstSwitchId = null;
-               link[0] = new TopologyUserLinkConfig(name, srcSwitchId, srcPort, dstSwitchId, dstPort); 
+               dstSwitchId = "2";
+               link[0] = new TopologyUserLinkConfig(name, srcNodeIDType, srcSwitchId,
+                               srcNodeConnectorIDType, srcPort, dstNodeIDType, dstSwitchId,
+                               dstNodeConnectorIDType, dstPort);
                Assert.assertTrue(link[0].isValid() == false);
 
                
                Integer i;
                
                for (i = 0; i < 5; i++) {
-                       link[i] = new TopologyUserLinkConfig(name, srcSwitchId, srcPort, dstSwitchId, dstPort); 
+                       link[i] = new TopologyUserLinkConfig(name, srcNodeIDType,
+                                       srcSwitchId, srcNodeConnectorIDType, srcPort,
+                                       dstNodeIDType, dstSwitchId, dstNodeConnectorIDType, dstPort);
 
                        name = Integer.toString(i + 1);
                        srcSwitchId = Integer.toString(i + 1);
@@ -236,9 +248,21 @@ public class TopologyManagerImplTest {
                        link[i].setDstSwitchId(dstSwitchId);
                        link[i].setDstPort(dstPort);
                        
+                       Assert.assertTrue(link[i].isValid() == false);
+                       
+                       link[i].setSrcNodeIDType("OF");
+                       link[i].setSrcNodeConnectorIDType("OF");
+
+                       Assert.assertTrue(link[i].isValid() == false);
+
+                       link[i].setDstNodeIDType("OF");
+                       link[i].setDstNodeConnectorIDType("OF");
+                       
                        Assert.assertTrue(link[i].isValid() == true);
 
-                       reverseLink[i] = new TopologyUserLinkConfig(name, dstSwitchId, dstPort, srcSwitchId, srcPort); 
+                       reverseLink[i] = new TopologyUserLinkConfig(name, dstNodeIDType,
+                                       dstSwitchId, dstNodeConnectorIDType, dstPort,
+                                       srcNodeIDType, srcSwitchId, srcNodeConnectorIDType, srcPort);
 
                        topoManagerImpl.addUserLink(link[i]);
                }