From 3192eba4c145930a1f54950966b9b451ebb12b51 Mon Sep 17 00:00:00 2001
From: Shigeru Yasuda
Date: Wed, 19 Nov 2014 19:44:23 +0900
Subject: [PATCH] Bug 2158: Handle out-of-order inventory notification.
MD-SAL notifications are delivered on multiple threads.
So VTN Manager should not expect order of inventory notifications.
Change-Id: I9a23203b085ab114b8de11c6584903ab3850755e
Signed-off-by: Shigeru Yasuda
---
.../vtn/manager/internal/VTNManagerImpl.java | 201 +++++++++++-------
.../internal/VTNManagerImplWithNodesTest.java | 149 ++++++++-----
2 files changed, 223 insertions(+), 127 deletions(-)
diff --git a/manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/VTNManagerImpl.java b/manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/VTNManagerImpl.java
index d2bfd5ef..670e0ba5 100644
--- a/manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/VTNManagerImpl.java
+++ b/manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/VTNManagerImpl.java
@@ -290,12 +290,11 @@ public class VTNManagerImpl
* Keeps internal ports as map key.
*
*
- * This map is used as {@code Set}. So we use
- * {@code VNodeState} enum as value in order to reduce memory footprint
- * and traffic between cluster nodes.
+ * This map keeps pairs of {@link NodeConnector} instances corresponding
+ * to switch ports connected each other.
*
*/
- private ConcurrentMap islDB;
+ private ConcurrentMap islDB;
/**
* Keeps flow conditions configured in this container.
@@ -861,7 +860,7 @@ public class VTNManagerImpl
stateDB = new ConcurrentHashMap();
nodeDB = new ConcurrentHashMap();
portDB = new ConcurrentHashMap();
- islDB = new ConcurrentHashMap();
+ islDB = new ConcurrentHashMap();
clusterEvent =
new ConcurrentHashMap();
flowDB = new ConcurrentHashMap();
@@ -893,7 +892,7 @@ public class VTNManagerImpl
getCache(cluster, CACHE_NODES);
portDB = (ConcurrentMap)
getCache(cluster, CACHE_PORTS);
- islDB = (ConcurrentMap)
+ islDB = (ConcurrentMap)
getCache(cluster, CACHE_ISL);
flowCondDB = (ConcurrentMap)
getCache(cluster, CACHE_FLOWCOND);
@@ -1246,7 +1245,6 @@ public class VTNManagerImpl
PortProperty pp = new PortProperty(propMap);
PortProperty old = portDB.putIfAbsent(nc, pp);
if (old == null) {
- addNode(nc.getNode(), false);
LOG.info("{}: addPort: New port: port={}, prop={}",
containerName, nc, pp);
return UpdateType.ADDED;
@@ -1348,18 +1346,25 @@ public class VTNManagerImpl
* {@code -1} is returned if the given edge is invalid.
*/
private int addISL(Edge edge, Map islMap) {
+ // Ensure both ports are valid.
NodeConnector head = edge.getHeadNodeConnector();
NodeConnector tail = edge.getTailNodeConnector();
- if (portDB.containsKey(head) && portDB.containsKey(tail)) {
- boolean h = addISLPort(head, islMap);
- boolean t = addISLPort(tail, islMap);
- return (h || t) ? 1 : 0;
- } else if (LOG.isDebugEnabled()) {
- LOG.debug("{}: addISL: Ignore invalid edge: {}",
- containerName, edge);
+
+ try {
+ NodeUtils.checkNodeConnector(head);
+ NodeUtils.checkNodeConnector(tail);
+ } catch (VTNException e) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("{}: addISL: Ignore invalid edge {}: {}",
+ containerName, edge, e);
+ }
+
+ return -1;
}
- return -1;
+ boolean h = addISLPort(head, tail, islMap);
+ boolean t = addISLPort(tail, head, islMap);
+ return (h || t) ? 1 : 0;
}
/**
@@ -1396,7 +1401,10 @@ public class VTNManagerImpl
* {@link #rwLock}.
*
*
- * @param nc A node connector.
+ * @param nc A {@link NodeConnector} instance corresponding to the
+ * target switch port.
+ * @param peer A {@link NodeConnector} instance corresponding to the
+ * switch port connected to {@link nc}.
* @param islMap If a non-{@code null} value is specified, the specified
* port is put to the given map only if the port was
* actually added to the ISL map.
@@ -1404,19 +1412,19 @@ public class VTNManagerImpl
* actually added. {@code false} is returned if the given node
* connector exists in the inter switch link map.
*/
- private boolean addISLPort(NodeConnector nc,
+ private boolean addISLPort(NodeConnector nc, NodeConnector peer,
Map islMap) {
- if (islDB.putIfAbsent(nc, VNodeState.UP) == null) {
+ if (islDB.putIfAbsent(nc, peer) == null) {
if (islMap != null) {
islMap.put(nc, Boolean.TRUE);
}
- LOG.info("{}: addISLPort: New ISL port {}",
- containerName, nc);
+ LOG.info("{}: addISLPort: New ISL port {} <-> {}",
+ containerName, nc, peer);
return true;
}
- if (LOG.isDebugEnabled()) {
- LOG.debug("{}: addISLPort: Ignore existing port {}",
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("{}: addISLPort: Ignore existing port {}",
containerName, nc);
}
return false;
@@ -1440,19 +1448,47 @@ public class VTNManagerImpl
*/
private boolean removeISLPort(NodeConnector nc,
Map islMap) {
- if (islDB.remove(nc) != null) {
+ NodeConnector port = nc;
+ boolean removed = false;
+ while (true) {
+ NodeConnector peer = islDB.remove(port);
+ if (peer == null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("{}: removeISLPort: Ignore unknown port {}",
+ containerName, port);
+ }
+ break;
+ }
+
+ removed = true;
if (islMap != null) {
- islMap.put(nc, Boolean.FALSE);
+ islMap.put(port, Boolean.FALSE);
}
- LOG.info("{}: removeISLPort: Removed {}", containerName, nc);
- return true;
+ LOG.info("{}: removeISLPort: Removed {} <-> {}",
+ containerName, port, peer);
+ port = peer;
}
- if (LOG.isDebugEnabled()) {
- LOG.debug("{}: removeISLPort: Ignore unknown port {}",
- containerName, nc);
- }
- return false;
+ return removed;
+ }
+
+ /**
+ * Determine whether the given node connector is associated with the
+ * physical switch port at the edge of the SDN network.
+ *
+ *
+ * Note that this method does not check whether the given switch port
+ * is managed by the controller or not.
+ *
+ *
+ * @param nc A node connector.
+ * @return {@code true} is returned only if the given node connector
+ * is associated with the physical switch port at the edge of
+ * the SDN network.
+ */
+ private boolean isEdgePortImpl(NodeConnector nc) {
+ NodeConnector peer = islDB.get(nc);
+ return (peer == null || !exists(peer));
}
/**
@@ -2286,7 +2322,7 @@ public class VTNManagerImpl
* the SDN network.
*/
public boolean isEdgePort(NodeConnector nc) {
- return (portDB.containsKey(nc) && !islDB.containsKey(nc));
+ return (exists(nc) && isEdgePortImpl(nc));
}
/**
@@ -2318,7 +2354,8 @@ public class VTNManagerImpl
* Otherwise {@code false} is returned.
*/
public boolean exists(NodeConnector port) {
- return portDB.containsKey(port);
+ return (nodeDB.containsKey(port.getNode()) &&
+ portDB.containsKey(port));
}
/**
@@ -2333,9 +2370,11 @@ public class VTNManagerImpl
public void collectUpEdgePorts(Set portSet) {
for (Map.Entry entry: portDB.entrySet()) {
NodeConnector port = entry.getKey();
- PortProperty pp = entry.getValue();
- if (pp.isEnabled() && !islDB.containsKey(port)) {
- portSet.add(port);
+ if (nodeDB.containsKey(port.getNode())) {
+ PortProperty pp = entry.getValue();
+ if (pp.isEnabled() && isEdgePortImpl(port)) {
+ portSet.add(port);
+ }
}
}
}
@@ -2369,10 +2408,12 @@ public class VTNManagerImpl
for (Map.Entry entry: portDB.entrySet()) {
NodeConnector port = entry.getKey();
- PortProperty pp = entry.getValue();
- if (pp.isEnabled() && !islDB.containsKey(port) &&
- filter.accept(port, pp)) {
- portSet.add(port);
+ if (nodeDB.containsKey(port.getNode())) {
+ PortProperty pp = entry.getValue();
+ if (pp.isEnabled() && isEdgePortImpl(port) &&
+ filter.accept(port, pp)) {
+ portSet.add(port);
+ }
}
}
}
@@ -2392,9 +2433,9 @@ public class VTNManagerImpl
public boolean hasEdgePort(Node node) {
for (Map.Entry entry: portDB.entrySet()) {
NodeConnector port = entry.getKey();
- if (port.getNode().equals(node)) {
+ if (nodeDB.containsKey(node) && port.getNode().equals(node)) {
PortProperty pp = entry.getValue();
- if (pp.isEnabled() && !islDB.containsKey(port)) {
+ if (pp.isEnabled() && isEdgePortImpl(port)) {
return true;
}
}
@@ -2411,8 +2452,12 @@ public class VTNManagerImpl
* is enabled. Otherwise {@code false} is returned.
*/
public boolean isEnabled(NodeConnector port) {
- PortProperty pp = portDB.get(port);
- return (pp != null && pp.isEnabled());
+ if (nodeDB.containsKey(port.getNode())) {
+ PortProperty pp = portDB.get(port);
+ return (pp != null && pp.isEnabled());
+ }
+
+ return false;
}
/**
@@ -2423,7 +2468,7 @@ public class VTNManagerImpl
* property is returned. {@code null} is returned if not found.
*/
public PortProperty getPortProperty(NodeConnector nc) {
- return portDB.get(nc);
+ return (nodeDB.containsKey(nc.getNode())) ? portDB.get(nc) : null;
}
/**
@@ -2436,8 +2481,12 @@ public class VTNManagerImpl
* determined.
*/
public String getPortName(NodeConnector nc) {
- PortProperty prop = portDB.get(nc);
- return (prop == null) ? null : prop.getName();
+ if (nodeDB.containsKey(nc.getNode())) {
+ PortProperty prop = portDB.get(nc);
+ return (prop == null) ? null : prop.getName();
+ }
+
+ return null;
}
/**
@@ -5783,6 +5832,12 @@ public class VTNManagerImpl
return false;
}
+ if (!exists(nc)) {
+ LOG.debug("{}: probeHost: Ignore request for {}: Unknown port {}",
+ containerName, host, nc);
+ return false;
+ }
+
// Create an unicast ARP request.
InetAddress target = host.getNetworkAddress();
byte[] dst = host.getDataLayerAddressBytes();
@@ -5804,7 +5859,7 @@ public class VTNManagerImpl
Lock rdlock = rwLock.readLock();
rdlock.lock();
try {
- if (islDB.containsKey(nc)) {
+ if (!isEdgePortImpl(nc)) {
LOG.debug("{}: probeHost: Ignore request for {}: " +
"Internal port", containerName, host);
return false;
@@ -7377,33 +7432,14 @@ public class VTNManagerImpl
@Override
public void notifyNode(Node node, UpdateType type,
Map propMap) {
- if (type == UpdateType.CHANGED) {
- // Nothing to do.
- return;
- }
-
// Acquire writer lock because this operation may change existing
// virtual network mapping.
Lock wrlock = rwLock.writeLock();
+ UpdateType utype = type;
wrlock.lock();
try {
// Maintain the node DB.
- if (type == UpdateType.ADDED) {
- if (connectionManager.getLocalityStatus(node) ==
- ConnectionLocality.LOCAL) {
- // Remove all VTN flows related to this node because
- // all flow entries in this node should be removed by
- // protocol plugin.
- for (VTNFlowDatabase fdb: vtnFlowMap.values()) {
- fdb.removeFlows(this, node);
- }
- }
-
- if (!addNode(node)) {
- return;
- }
- } else {
- assert type == UpdateType.REMOVED;
+ if (type == UpdateType.REMOVED) {
if (!removeNode(node)) {
return;
}
@@ -7418,10 +7454,25 @@ public class VTNManagerImpl
for (MacAddressTable table: macTableMap.values()) {
table.flush(node);
}
+ } else {
+ if (connectionManager.getLocalityStatus(node) ==
+ ConnectionLocality.LOCAL) {
+ // Remove all VTN flows related to this node because
+ // all flow entries in this node should be removed by
+ // protocol plugin.
+ for (VTNFlowDatabase fdb: vtnFlowMap.values()) {
+ fdb.removeFlows(this, node);
+ }
+ }
+
+ if (!addNode(node)) {
+ return;
+ }
+ utype = UpdateType.ADDED;
}
for (VTenantImpl vtn: tenantDB.values()) {
- vtn.notifyNode(this, node, type);
+ vtn.notifyNode(this, node, utype);
}
} finally {
unlock(wrlock);
@@ -7446,21 +7497,19 @@ public class VTNManagerImpl
wrlock.lock();
try {
// Maintain the port DB.
+ VNodeState pstate;
if (type == UpdateType.REMOVED) {
if (!removePort(nc)) {
return;
}
+
+ pstate = VNodeState.UNKNOWN;
} else {
utype = addPort(nc, propMap);
if (utype == null) {
return;
}
- }
- VNodeState pstate;
- if (type == UpdateType.REMOVED) {
- pstate = VNodeState.UNKNOWN;
- } else {
// Determine whether the port is up or not.
pstate = (isEnabled(nc)) ? VNodeState.UP : VNodeState.DOWN;
}
@@ -7719,7 +7768,7 @@ public class VTNManagerImpl
NodeUtils.checkNodeType(node.getType());
NodeUtils.checkNodeConnectorType(nc.getType());
- if (islDB.containsKey(nc)) {
+ if (!isEdgePortImpl(nc)) {
LOG.debug("{}: Ignore packet from internal node connector: {}",
containerName, nc);
if (connectionManager.getLocalityStatus(node) ==
diff --git a/manager/implementation/src/test/java/org/opendaylight/vtn/manager/internal/VTNManagerImplWithNodesTest.java b/manager/implementation/src/test/java/org/opendaylight/vtn/manager/internal/VTNManagerImplWithNodesTest.java
index 607a9338..9432d861 100644
--- a/manager/implementation/src/test/java/org/opendaylight/vtn/manager/internal/VTNManagerImplWithNodesTest.java
+++ b/manager/implementation/src/test/java/org/opendaylight/vtn/manager/internal/VTNManagerImplWithNodesTest.java
@@ -951,7 +951,8 @@ public class VTNManagerImplWithNodesTest extends VTNManagerImplTestCommon {
mgr.initISL();
Set existNodeConnector = new HashSet();
- Set existISL = new HashSet();
+ Map existISL =
+ new HashMap();
List addTopoList = new ArrayList();
getInventoryNodeAndPortData(mgr, existNodeConnector, existISL,
addTopoList);
@@ -964,10 +965,12 @@ public class VTNManagerImplWithNodesTest extends VTNManagerImplTestCommon {
Map propMap = swMgr.getNodeConnectorProps(nc);
mgr.notifyNodeConnector(nc, UpdateType.REMOVED, propMap);
- int expectedNumISL = existISL.contains(nc)
- ? existISL.size() - 1 : existISL.size();
+ int expectedNumISL =
+ existISL.size() - getRemovedLinkSize(existISL, nc);
checkNodeDBAndPortDBAndIslDB(cs, swMgr.getNodes().size(),
existNodeConnector.size() - 1, expectedNumISL);
+ assertTrue(mgr.exists(nc.getNode()));
+ assertFalse(mgr.exists(nc));
// remove same port again. status is not changed.
mgr.notifyNodeConnector(nc, UpdateType.REMOVED, propMap);
@@ -977,8 +980,10 @@ public class VTNManagerImplWithNodesTest extends VTNManagerImplTestCommon {
mgr.notifyNodeConnector(nc, UpdateType.ADDED, propMap);
checkNodeDBAndPortDBAndIslDB(cs, swMgr.getNodes().size(),
existNodeConnector.size(), expectedNumISL);
+ assertTrue(mgr.exists(nc.getNode()));
+ assertTrue(mgr.exists(nc));
- if (existISL.contains(nc)) {
+ if (existISL.containsKey(nc)) {
// edge information isn't updated by invoking notifyNodeConnector()
// until edgeUpdate() is invoked.
mgr.edgeUpdate(addTopoList);
@@ -996,39 +1001,44 @@ public class VTNManagerImplWithNodesTest extends VTNManagerImplTestCommon {
existNodeConnector.size(), existISL.size());
}
- // add and remove not existing node connector.
- // If added existing node connector , it is added to DB.
+ // When a node connector in unknown node is added, node connector
+ // should be added but node.
Node node10 = NodeCreator.createOFNode(Long.valueOf("10"));
NodeConnector nc = NodeConnectorCreator
.createOFNodeConnector(Short.valueOf("99"), node10);
Map propMap = new HashMap();
mgr.notifyNodeConnector(nc, UpdateType.ADDED, propMap);
- checkNodeDBAndPortDBAndIslDB(cs, swMgr.getNodes().size() + 1,
+ checkNodeDBAndPortDBAndIslDB(cs, swMgr.getNodes().size(),
existNodeConnector.size() + 1, existISL.size());
+ // exists(NodeConnector) should return false if the node is not added.
+ assertFalse(mgr.exists(node10));
+ assertFalse(mgr.exists(nc));
+
mgr.notifyNodeConnector(nc, UpdateType.CHANGED, propMap);
- checkNodeDBAndPortDBAndIslDB(cs, swMgr.getNodes().size() + 1,
+ checkNodeDBAndPortDBAndIslDB(cs, swMgr.getNodes().size(),
existNodeConnector.size() + 1, existISL.size());
+ assertFalse(mgr.exists(node10));
+ assertFalse(mgr.exists(nc));
// nodeDB isn't updated when notifyNodeConnector() invoked with
// UpdateType.REMOVED.
mgr.notifyNodeConnector(nc, UpdateType.REMOVED, propMap);
- checkNodeDBAndPortDBAndIslDB(cs, swMgr.getNodes().size() + 1,
+ checkNodeDBAndPortDBAndIslDB(cs, swMgr.getNodes().size(),
existNodeConnector.size(), existISL.size());
- // nodeDB isn't updated until notifyNode() received().
mgr.notifyNode(node10, UpdateType.REMOVED, propMap);
checkNodeDBAndPortDBAndIslDB(cs, swMgr.getNodes().size(),
existNodeConnector.size(), existISL.size());
// in case propMap == null
mgr.notifyNodeConnector(nc, UpdateType.ADDED, null);
- checkNodeDBAndPortDBAndIslDB(cs, swMgr.getNodes().size() + 1,
+ checkNodeDBAndPortDBAndIslDB(cs, swMgr.getNodes().size(),
existNodeConnector.size() + 1, existISL.size());
mgr.notifyNodeConnector(nc, UpdateType.REMOVED, null);
- checkNodeDBAndPortDBAndIslDB(cs, swMgr.getNodes().size() + 1,
+ checkNodeDBAndPortDBAndIslDB(cs, swMgr.getNodes().size(),
existNodeConnector.size(), existISL.size());
mgr.notifyNode(node10, UpdateType.REMOVED, null);
@@ -1136,7 +1146,8 @@ public class VTNManagerImplWithNodesTest extends VTNManagerImplTestCommon {
mgr.initISL();
Set existNodeConnector = new HashSet();
- Set existISL = new HashSet();
+ Map existISL =
+ new HashMap();
List addTopoList = new ArrayList();
getInventoryNodeAndPortData(mgr, existNodeConnector, existISL,
addTopoList);
@@ -1159,13 +1170,19 @@ public class VTNManagerImplWithNodesTest extends VTNManagerImplTestCommon {
getInventoryNodeAndPortData(mgr, existNodeConnector, existISL,
addTopoList);
+ int removed = 0;
for (Node node : swMgr.getNodes()) {
mgr.initInventory();
mgr.initISL();
- int expectedNumISL = 1;
- if (mode == 3) {
- expectedNumISL = (node.equals(node0)) ? 2 : 3;
+ // If test mode is 3, node0 is linked with both node1 and
+ // node2. So all inter-switch links will be removed when node0
+ // is removed.
+ int expectedNumISL;
+ if (mode == 2 || node.equals(node0)) {
+ expectedNumISL = 0;
+ } else {
+ expectedNumISL = 2;
}
Map propMap = swMgr.getNodeProps(node);
@@ -1180,11 +1197,6 @@ public class VTNManagerImplWithNodesTest extends VTNManagerImplTestCommon {
existNodeConnector.size() - swMgr.getNodeConnectors(node).size(),
expectedNumISL);
- mgr.notifyNode(node, UpdateType.CHANGED, propMap);
- checkNodeDBAndPortDBAndIslDB(cs, swMgr.getNodes().size() - 1,
- existNodeConnector.size() - swMgr.getNodeConnectors(node).size(),
- expectedNumISL);
-
// node connectors associated with specified node
// are removed by invoking notifyNode().
// But these aren't added by invoking notifyNode().
@@ -1272,7 +1284,8 @@ public class VTNManagerImplWithNodesTest extends VTNManagerImplTestCommon {
mgr.initISL();
Set existNodeConnector = new HashSet();
- Set existISL = new HashSet();
+ Map existISL =
+ new HashMap();
getInventoryNodeAndPortData(mgr, existNodeConnector, existISL, null);
checkNodeDBAndPortDBAndIslDB(cs, swMgr.getNodes().size(), existNodeConnector.size(),
@@ -1371,6 +1384,13 @@ public class VTNManagerImplWithNodesTest extends VTNManagerImplTestCommon {
NodeConnector head = NodeConnectorCreator
.createOFNodeConnector(Short.valueOf(portHead),
nodeHead);
+ boolean tailExists = !(nodeTail.equals(node100) ||
+ portTail == 99);
+ boolean headExists = !(nodeHead.equals(node100) ||
+ portHead == 99);
+ assertEquals(tailExists, mgr.exists(tail));
+ assertEquals(headExists, mgr.exists(head));
+
Edge newEdge = null;
try {
newEdge = new Edge(tail, head);
@@ -1384,20 +1404,16 @@ public class VTNManagerImplWithNodesTest extends VTNManagerImplTestCommon {
addTopoList.add(update);
mgr.edgeUpdate(addTopoList);
- if (nodeTail.equals(node100) || nodeHead.equals(node100)
- || portTail == 99 || portHead == 99) {
- // if tail or head is not existing NodeConnector
- // islDB isn't updated.
- checkNodeDBAndPortDBAndIslDB(cs,
- swMgr.getNodes().size(),
- existNodeConnector.size(),
- existISL.size());
- } else {
- checkNodeDBAndPortDBAndIslDB(cs,
- swMgr.getNodes().size(),
- existNodeConnector.size(),
- existISL.size() + 2);
- }
+
+ // ISL DB should be updated even if edge contains
+ // unknown port.
+ checkNodeDBAndPortDBAndIslDB(
+ cs, swMgr.getNodes().size(),
+ existNodeConnector.size(), existISL.size() + 2);
+ boolean tailEdge = (tailExists && !headExists);
+ boolean headEdge = (headExists && !tailExists);
+ assertEquals(tailEdge, mgr.isEdgePort(tail));
+ assertEquals(headEdge, mgr.isEdgePort(head));
update = new TopoEdgeUpdate(newEdge, null,
UpdateType.REMOVED);
@@ -1407,6 +1423,9 @@ public class VTNManagerImplWithNodesTest extends VTNManagerImplTestCommon {
mgr.edgeUpdate(removeTopoList);
checkNodeDBAndPortDBAndIslDB(cs, swMgr.getNodes().size(),
existNodeConnector.size(), existISL.size());
+
+ assertEquals(tailEdge, mgr.isEdgePort(tail));
+ assertEquals(headEdge, mgr.isEdgePort(head));
}
}
}
@@ -1430,7 +1449,9 @@ public class VTNManagerImplWithNodesTest extends VTNManagerImplTestCommon {
mgr.edgeUpdate(addTopoList);
checkNodeDBAndPortDBAndIslDB(cs, swMgr.getNodes().size(),
existNodeConnector.size(),
- existISL.size());
+ existISL.size() + 2);
+ assertFalse(mgr.isEdgePort(tail));
+ assertFalse(mgr.isEdgePort(head));
update = new TopoEdgeUpdate(newEdge, null, UpdateType.REMOVED);
removeTopoList.clear();
@@ -1440,6 +1461,8 @@ public class VTNManagerImplWithNodesTest extends VTNManagerImplTestCommon {
checkNodeDBAndPortDBAndIslDB(cs, swMgr.getNodes().size(),
existNodeConnector.size(),
existISL.size());
+ assertFalse(mgr.isEdgePort(tail));
+ assertFalse(mgr.isEdgePort(head));
// start with invalid topology.
// (topologyManager has edges associated with not existing Node.)
@@ -1454,7 +1477,7 @@ public class VTNManagerImplWithNodesTest extends VTNManagerImplTestCommon {
vtnMgr.setSwitchManager(stubObj);
vtnMgr.setTopologyManager(stubNew);
startVTNManager(c);
- assertEquals(2, cs.getCache(CACHE_ISL).size());
+ assertEquals(4, cs.getCache(CACHE_ISL).size());
}
/**
@@ -1465,15 +1488,15 @@ public class VTNManagerImplWithNodesTest extends VTNManagerImplTestCommon {
* @param mgr VTNManager service.
* @param existNodeConnector A List of {@link NodeConnector} which is set
* existing Nodeconnectors.
- * @param existISL A List of {@link NodeConnector} which is set
- * existing ISLs.
+ * @param existISL A map of {@link NodeConnector} which
+ * contains internal links.
* @param addTopoList A List of {@link TopoEdgeUpdate} which is set
* {@link TopoEdgeUpdate} of existing Edges.
*/
- private void getInventoryNodeAndPortData(VTNManagerImpl mgr,
- Set existNodeConnector,
- Set existISL,
- List addTopoList) {
+ private void getInventoryNodeAndPortData(
+ VTNManagerImpl mgr, Set existNodeConnector,
+ Map existISL,
+ List addTopoList) {
ISwitchManager swMgr = mgr.getSwitchManager();
ITopologyManager topoMgr = mgr.getTopologyManager();
for (Node node : swMgr.getNodes()) {
@@ -1481,8 +1504,10 @@ public class VTNManagerImplWithNodesTest extends VTNManagerImplTestCommon {
}
for (Edge edge : topoMgr.getEdges().keySet()) {
- existISL.add(edge.getHeadNodeConnector());
- existISL.add(edge.getTailNodeConnector());
+ NodeConnector head = edge.getHeadNodeConnector();
+ NodeConnector tail = edge.getTailNodeConnector();
+ existISL.put(head, tail);
+ existISL.put(tail, head);
if (addTopoList != null) {
TopoEdgeUpdate update = new TopoEdgeUpdate(edge, null,
@@ -1512,10 +1537,8 @@ public class VTNManagerImplWithNodesTest extends VTNManagerImplTestCommon {
cs.getCache(CACHE_PORTS);
List portMapList
= new ArrayList(portMap.keySet());
- ConcurrentMap islMap =
- (ConcurrentMap)cs.getCache(CACHE_ISL);
- List islMapList =
- new ArrayList(islMap.keySet());
+ ConcurrentMap islMap =
+ (ConcurrentMap)cs.getCache(CACHE_ISL);
if (nodeDBSize >= 0) {
assertEquals(nodeDBSize, nodeMapList.size());
@@ -1524,7 +1547,7 @@ public class VTNManagerImplWithNodesTest extends VTNManagerImplTestCommon {
assertEquals(portDBSize, portMapList.size());
}
if (islDBSize >= 0) {
- assertEquals(islDBSize, islMapList.size());
+ assertEquals(islDBSize, islMap.size());
}
}
@@ -5055,4 +5078,28 @@ public class VTNManagerImplWithNodesTest extends VTNManagerImplTestCommon {
assertEquals(StatusCode.SUCCESS, st.getCode());
}
}
+
+ /**
+ * Return the number of inter-switch links to be removed when the given
+ * node is removed.
+ *
+ * @param map A map that contains inter-switch links.
+ * @param nc A node connector to be removed.
+ * @return The number of inter-switch links to be removed.
+ */
+ private int getRemovedLinkSize(Map map,
+ NodeConnector nc) {
+ Set removed = new HashSet();
+ NodeConnector port = nc;
+ do {
+ NodeConnector peer = map.get(port);
+ if (peer == null || !removed.add(port)) {
+ break;
+ }
+
+ port = peer;
+ } while (true);
+
+ return removed.size();
+ }
}
--
2.36.6