- 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>
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,
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;
/**
*
- * Retrieve the Topology for the
+ * Retrieve the Topology
*
* @param containerName The container for which we want to retrieve the topology
*
@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
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());
+ }
}
--- /dev/null
+/*
+ * 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);
+ }
+}
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");
bytesRead = socket.read(peerNetData);
if (bytesRead < 0) {
+ logger.debug("Message read operation failed");
throw new AsynchronousCloseException();
}
}
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);
}
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
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);
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;
}
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;
}
}
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);
}
}
edge = new Edge(srcNodeConnector, dstNodeConnector);
props = getProps(dstNodeConnector);
} catch (ConstructionException e) {
- logger.error(e.getMessage());
+ logger.error("Caught exception ", e);
}
addEdge(edge, props);
removeSet = getRemoveSet(prodMap.keySet(), node);
for (NodeConnector nodeConnector : removeSet) {
- removeProd(nodeConnector);
+ removeProdEdge(nodeConnector);
}
}
waitingList.remove(nodeConnector);
pendingMap.remove(nodeConnector);
removeEdge(nodeConnector, false);
- removeProd(nodeConnector);
+ removeProdEdge(nodeConnector);
}
private void checkTimeout() {
}
for (NodeConnector nodeConnector : removeSet) {
- removeProd(nodeConnector);
+ removeProdEdge(nodeConnector);
}
}
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);
}
/*
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");
}
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;
}
}
ci.println("\n");
- ci.println(" NodeConnector Edge ");
+ ci.println(" NodeConnector Edge ");
Set<NodeConnector> keySet = prodMap.keySet();
if (keySet == null) {
return;
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) {
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) {
}
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;
bw = ((Bandwidth) prop).getValue();
}
}
-
+ count++;
ci.println(edgeProps.getLeft() + " " + bw);
}
+ ci.println("Total number of Edges: " + count);
}
public void _bwfactor(CommandInterpreter ci) {
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;
}
ci.println(node + " " + node.getType()
+ " " + nodeName + " " + tierNum);
}
+ ci.println("Total number of Nodes: " + nodeSet.size());
}
public void _pencs(CommandInterpreter ci) {
}
ci.println(nodeConnector);
}
+ ci.println("Total number of NodeConnectors: " + nodeConnectorSet.size());
}
public void _pncs(CommandInterpreter ci) {
out += (state != null) ? state.getValue() : " ";
ci.println(out);
}
+ ci.println("Total number of NodeConnectors: " + nodeConnectorSet.size());
}
public void _pdm(CommandInterpreter ci) {
Object id = Long.decode(st);
Switch sw = getSwitchByNode(NodeCreator.createOFNode((Long) id));
- ci
- .println(" NodeConnector Name");
+ ci.println(" NodeConnector Name");
if (sw == null) {
return;
}
}
}
- ci
- .println(nodeConnector
- + " "
- + ((nodeConnectorName == null) ? ""
- : nodeConnectorName) + "("
- + nodeConnector.getID() + ")");
+ ci.println(nodeConnector
+ + " "
+ + ((nodeConnectorName == null) ? ""
+ : nodeConnectorName) + "("
+ + nodeConnector.getID() + ")");
}
+ ci.println("Total number of NodeConnectors: " + nodeConnectorSet.size());
}
}
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,
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
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}$";
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(
}
}
+ @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() {
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;
}
.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";
}
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() {
@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,
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;
}
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) &&
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;
}
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 : " +
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));
}
}
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));
}
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 {
@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();
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);
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]);
}