X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fswitchmanager%2Fimplementation%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fswitchmanager%2Finternal%2FSwitchManagerImpl.java;h=5d10620c4403f8c00829bd02927d5da39fa07178;hp=4ef841643691bdb145c377c85199fa1635f49d29;hb=0b203f52cbe128efa17a6c400b6653c8e6a84ba8;hpb=a640c5c549376e5d72038e033d49ef6f0df96c92 diff --git a/opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManagerImpl.java b/opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManagerImpl.java index 4ef8416436..5d10620c44 100644 --- a/opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManagerImpl.java +++ b/opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManagerImpl.java @@ -40,7 +40,10 @@ import org.opendaylight.controller.clustering.services.IClusterServices; import org.opendaylight.controller.configuration.IConfigurationContainerAware; import org.opendaylight.controller.sal.core.Bandwidth; import org.opendaylight.controller.sal.core.Config; +import org.opendaylight.controller.sal.core.ConstructionException; import org.opendaylight.controller.sal.core.Description; +import org.opendaylight.controller.sal.core.ForwardingMode; +import org.opendaylight.controller.sal.core.MacAddress; import org.opendaylight.controller.sal.core.Name; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.NodeConnector; @@ -51,14 +54,13 @@ import org.opendaylight.controller.sal.core.Tier; import org.opendaylight.controller.sal.core.UpdateType; import org.opendaylight.controller.sal.inventory.IInventoryService; import org.opendaylight.controller.sal.inventory.IListenInventoryUpdates; -import org.opendaylight.controller.sal.utils.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.NodeCreator; import org.opendaylight.controller.sal.utils.ObjectReader; import org.opendaylight.controller.sal.utils.ObjectWriter; -import org.opendaylight.controller.sal.utils.ServiceHelper; import org.opendaylight.controller.sal.utils.Status; +import org.opendaylight.controller.sal.utils.StatusCode; import org.opendaylight.controller.switchmanager.IInventoryListener; import org.opendaylight.controller.switchmanager.ISpanAware; import org.opendaylight.controller.switchmanager.ISwitchManager; @@ -82,30 +84,32 @@ import org.slf4j.LoggerFactory; * are maintained in the default container only. */ public class SwitchManagerImpl implements ISwitchManager, - IConfigurationContainerAware, IObjectReader, - ICacheUpdateAware, IListenInventoryUpdates, - CommandProvider { +IConfigurationContainerAware, IObjectReader, +ICacheUpdateAware, IListenInventoryUpdates, +CommandProvider { private static Logger log = LoggerFactory .getLogger(SwitchManagerImpl.class); private static String ROOT = GlobalConstants.STARTUPHOME.toString(); private static final String SAVE = "Save"; private String subnetFileName = null, spanFileName = null, switchConfigFileName = null; - private List spanNodeConnectors = new CopyOnWriteArrayList(); - private ConcurrentMap subnets; // set of Subnets keyed by the InetAddress + private final List spanNodeConnectors = new CopyOnWriteArrayList(); + // set of Subnets keyed by the InetAddress + private ConcurrentMap subnets; private ConcurrentMap subnetsConfigList; - private ConcurrentMap spanConfigList; - private ConcurrentMap nodeConfigList; // manually configured parameters for the node like name and tier + private ConcurrentMap spanConfigList; + // manually configured parameters for the node such as name, tier, mode + private ConcurrentMap nodeConfigList; private ConcurrentMap configSaveEvent; - private ConcurrentMap> nodeProps; // properties are maintained in global container only - private ConcurrentMap> nodeConnectorProps; // properties are maintained in global container only + private ConcurrentMap> nodeProps; + private ConcurrentMap> nodeConnectorProps; private ConcurrentMap> nodeConnectorNames; private IInventoryService inventoryService; - private Set switchManagerAware = Collections + private final Set switchManagerAware = Collections .synchronizedSet(new HashSet()); - private Set inventoryListeners = Collections + private final Set inventoryListeners = Collections .synchronizedSet(new HashSet()); - private Set spanAware = Collections + private final Set spanAware = Collections .synchronizedSet(new HashSet()); private byte[] MAC; private static boolean hostRefresh = true; @@ -113,18 +117,20 @@ public class SwitchManagerImpl implements ISwitchManager, private IClusterContainerServices clusterContainerService = null; private String containerName = null; private boolean isDefaultContainer = true; + private static final int REPLACE_RETRY = 1; public enum ReasonCode { SUCCESS("Success"), FAILURE("Failure"), INVALID_CONF( "Invalid Configuration"), EXIST("Entry Already Exist"), CONFLICT( - "Configuration Conflict with Existing Entry"); + "Configuration Conflict with Existing Entry"); - private String name; + private final String name; private ReasonCode(String name) { this.name = name; } + @Override public String toString() { return name; } @@ -172,7 +178,7 @@ public class SwitchManagerImpl implements ISwitchManager, public void startUp() { // Initialize configuration file names - subnetFileName = ROOT + "subnets" + this.getContainerName() + ".conf"; + subnetFileName = ROOT + "subnets_" + this.getContainerName() + ".conf"; spanFileName = ROOT + "spanPorts_" + this.getContainerName() + ".conf"; switchConfigFileName = ROOT + "switchConfig_" + this.getContainerName() + ".conf"; @@ -185,23 +191,26 @@ public class SwitchManagerImpl implements ISwitchManager, * Read startup and build database if we have not already gotten the * configurations synced from another node */ - if (subnetsConfigList.isEmpty()) + if (subnetsConfigList.isEmpty()) { loadSubnetConfiguration(); - if (spanConfigList.isEmpty()) + } + if (spanConfigList.isEmpty()) { loadSpanConfiguration(); - if (nodeConfigList.isEmpty()) + } + if (nodeConfigList.isEmpty()) { loadSwitchConfiguration(); + } MAC = getHardwareMAC(); } public void shutDown() { - destroyCaches(this.getContainerName()); } @SuppressWarnings("deprecation") private void allocateCaches() { if (this.clusterContainerService == null) { + this.nonClusterObjectCreate(); log.warn("un-initialized clusterContainerService, can't create cache"); return; } @@ -247,7 +256,7 @@ public class SwitchManagerImpl implements ISwitchManager, log.error("\nFailed to get cache for subnetsConfigList"); } - spanConfigList = (ConcurrentMap) clusterContainerService + spanConfigList = (ConcurrentMap) clusterContainerService .getCache("switchmanager.spanConfigList"); if (spanConfigList == null) { log.error("\nFailed to get cache for spanConfigList"); @@ -290,9 +299,9 @@ public class SwitchManagerImpl implements ISwitchManager, } } - void nonClusterObjectCreate() { + private void nonClusterObjectCreate() { subnetsConfigList = new ConcurrentHashMap(); - spanConfigList = new ConcurrentHashMap(); + spanConfigList = new ConcurrentHashMap(); nodeConfigList = new ConcurrentHashMap(); subnets = new ConcurrentHashMap(); configSaveEvent = new ConcurrentHashMap(); @@ -301,26 +310,7 @@ public class SwitchManagerImpl implements ISwitchManager, nodeConnectorNames = new ConcurrentHashMap>(); } - @SuppressWarnings("deprecation") - private void destroyCaches(String container) { - if (this.clusterContainerService == null) { - log.info("un-initialized clusterContainerService, can't create cache"); - return; - } - - clusterContainerService.destroyCache("switchmanager.subnetsConfigList"); - clusterContainerService.destroyCache("switchmanager.spanConfigList"); - clusterContainerService.destroyCache("switchmanager.nodeConfigList"); - clusterContainerService.destroyCache("switchmanager.subnets"); - clusterContainerService.destroyCache("switchmanager.configSaveEvent"); - clusterContainerService.destroyCache("switchmanager.nodeProps"); - clusterContainerService - .destroyCache("switchmanager.nodeConnectorProps"); - clusterContainerService - .destroyCache("switchmanager.nodeConnectorNames"); - nonClusterObjectCreate(); - } - + @Override public List getSubnetsConfigList() { return new ArrayList(subnetsConfigList.values()); } @@ -345,6 +335,7 @@ public class SwitchManagerImpl implements ISwitchManager, return new ArrayList(nodeConfigList.values()); } + @Override public SwitchConfig getSwitchConfig(String switchId) { return nodeConfigList.get(switchId); } @@ -352,7 +343,11 @@ public class SwitchManagerImpl implements ISwitchManager, public Switch getSwitchByNode(Node node) { Switch sw = new Switch(node); sw.setNode(node); - + MacAddress mac = (MacAddress) this.getNodeProp(node, + MacAddress.name); + if (mac != null) { + sw.setDataLayerAddress(mac.getMacAddress()); + } Set ncSet = getPhysicalNodeConnectors(node); sw.setNodeConnectors(ncSet); @@ -367,6 +362,7 @@ public class SwitchManagerImpl implements ISwitchManager, return sw; } + @Override public List getNetworkDevices() { Set nodeSet = getNodes(); List swList = new ArrayList(); @@ -379,19 +375,26 @@ public class SwitchManagerImpl implements ISwitchManager, return swList; } - private void updateConfig(SubnetConfig conf, boolean add) { + private Status updateConfig(SubnetConfig conf, boolean add) { if (add) { - subnetsConfigList.put(conf.getName(), conf); + if(subnetsConfigList.putIfAbsent(conf.getName(), conf) != null) { + String msg = "Cluster conflict: Subnet with name " + conf.getName() + "already exists."; + return new Status(StatusCode.CONFLICT, msg); + } } else { subnetsConfigList.remove(conf.getName()); } + return new Status(StatusCode.SUCCESS); } - private void updateDatabase(SubnetConfig conf, boolean add) { - Subnet subnet = subnets.get(conf.getIPnum()); + private Status updateDatabase(SubnetConfig conf, boolean add) { if (add) { - if (subnet == null) { + Subnet subnetCurr = subnets.get(conf.getIPnum()); + Subnet subnet; + if (subnetCurr == null) { subnet = new Subnet(conf); + } else { + subnet = subnetCurr.clone(); } // In case of API3 call we may receive the ports along with the // subnet creation @@ -399,28 +402,38 @@ public class SwitchManagerImpl implements ISwitchManager, Set sp = conf.getSubnetNodeConnectors(); subnet.addNodeConnectors(sp); } - subnets.put(conf.getIPnum(), subnet); + boolean result = false; + if(subnetCurr == null) { + if(subnets.putIfAbsent(conf.getIPnum(), subnet) == null) { + result = true; + } + } else { + result = subnets.replace(conf.getIPnum(), subnetCurr, subnet); + } + if(!result) { + String msg = "Cluster conflict: Conflict while adding the subnet " + conf.getIPnum(); + return new Status(StatusCode.CONFLICT, msg); + } } else { // This is the deletion of the whole subnet - if (subnet == null) - return; subnets.remove(conf.getIPnum()); } + return new Status(StatusCode.SUCCESS); } private Status semanticCheck(SubnetConfig conf) { Subnet newSubnet = new Subnet(conf); Set IPs = subnets.keySet(); if (IPs == null) { - return new Status(StatusCode.SUCCESS, null); + return new Status(StatusCode.SUCCESS); } for (InetAddress i : IPs) { Subnet existingSubnet = subnets.get(i); if ((existingSubnet != null) && !existingSubnet.isMutualExclusive(newSubnet)) { - return new Status(StatusCode.CONFLICT, null); + return new Status(StatusCode.CONFLICT); } } - return new Status(StatusCode.SUCCESS, null); + return new Status(StatusCode.SUCCESS); } private Status addRemoveSubnet(SubnetConfig conf, boolean add) { @@ -443,18 +456,25 @@ public class SwitchManagerImpl implements ISwitchManager, return rc; } } - // Update Configuration - updateConfig(conf, add); // Update Database - updateDatabase(conf, add); + Status rc = updateDatabase(conf, add); + + if (rc.isSuccess()) { + // Update Configuration + rc = updateConfig(conf, add); + if(!rc.isSuccess()) { + updateDatabase(conf, (!add)); + } + } - return new Status(StatusCode.SUCCESS, null); + return rc; } /** * Adds Subnet configured in GUI or API3 */ + @Override public Status addSubnet(SubnetConfig conf) { return this.addRemoveSubnet(conf, true); } @@ -475,38 +495,77 @@ public class SwitchManagerImpl implements ISwitchManager, @Override public Status addPortsToSubnet(String name, String switchPorts) { - // Update Configuration - SubnetConfig conf = subnetsConfigList.get(name); - if (conf == null) { + SubnetConfig confCurr = subnetsConfigList.get(name); + if (confCurr == null) { return new Status(StatusCode.NOTFOUND, "Subnet does not exist"); } - if (!conf.isValidSwitchPort(switchPorts)) { + if (!confCurr.isValidSwitchPort(switchPorts)) { return new Status(StatusCode.BADREQUEST, "Invalid switchports"); } - conf.addNodeConnectors(switchPorts); + Subnet subCurr = subnets.get(confCurr.getIPnum()); + if (subCurr == null) { + log.debug("Cluster conflict: Subnet entry {} is not present in the subnets cache.", confCurr.getIPnum()); + return new Status(StatusCode.NOTFOUND, "Subnet does not exist"); + } // Update Database - Subnet sub = subnets.get(conf.getIPnum()); - Set sp = conf.getNodeConnectors(switchPorts); + Subnet sub = subCurr.clone(); + Set sp = confCurr.getNodeConnectors(switchPorts); sub.addNodeConnectors(sp); - return new Status(StatusCode.SUCCESS, null); + boolean subnetsReplace = subnets.replace(confCurr.getIPnum(), subCurr, sub); + if (!subnetsReplace) { + String msg = "Cluster conflict: Conflict while adding ports to the subnet " + name; + return new Status(StatusCode.CONFLICT, msg); + } + + // Update Configuration + SubnetConfig conf = confCurr.clone(); + conf.addNodeConnectors(switchPorts); + boolean result = subnetsConfigList.replace(name, confCurr, conf); + if (!result) { + // TODO: recovery using Transactionality + String msg = "Cluster conflict: Conflict while adding ports to the subnet " + name; + return new Status(StatusCode.CONFLICT, msg); + } + + return new Status(StatusCode.SUCCESS); } @Override public Status removePortsFromSubnet(String name, String switchPorts) { - // Update Configuration - SubnetConfig conf = subnetsConfigList.get(name); - if (conf == null) { + SubnetConfig confCurr = subnetsConfigList.get(name); + if (confCurr == null) { + return new Status(StatusCode.NOTFOUND, "Subnet does not exist"); + } + + Subnet subCurr = subnets.get(confCurr.getIPnum()); + if (subCurr == null) { + log.debug("Cluster conflict: Subnet entry {} is not present in the subnets cache.", confCurr.getIPnum()); return new Status(StatusCode.NOTFOUND, "Subnet does not exist"); } - conf.removeNodeConnectors(switchPorts); // Update Database - Subnet sub = subnets.get(conf.getIPnum()); - Set sp = conf.getNodeConnectors(switchPorts); + Subnet sub = subCurr.clone(); + Set sp = confCurr.getNodeConnectors(switchPorts); sub.deleteNodeConnectors(sp); - return new Status(StatusCode.SUCCESS, null); + boolean subnetsReplace = subnets.replace(confCurr.getIPnum(), subCurr, sub); + if (!subnetsReplace) { + String msg = "Cluster conflict: Conflict while removing ports from the subnet " + name; + return new Status(StatusCode.CONFLICT, msg); + } + + // Update Configuration + SubnetConfig conf = confCurr.clone(); + conf.removeNodeConnectors(switchPorts); + boolean result = subnetsConfigList.replace(name, confCurr, conf); + if (!result) { + // TODO: recovery using Transactionality + String msg = "Cluster conflict: Conflict while removing ports from " + conf; + return new Status(StatusCode.CONFLICT, msg); + } + + return new Status(StatusCode.SUCCESS); } public String getContainerName() { @@ -540,7 +599,7 @@ public class SwitchManagerImpl implements ISwitchManager, @SuppressWarnings("unchecked") private void loadSubnetConfiguration() { ObjectReader objReader = new ObjectReader(); - ConcurrentMap confList = (ConcurrentMap) objReader + ConcurrentMap confList = (ConcurrentMap) objReader .read(this, subnetFileName); if (confList == null) { @@ -584,41 +643,164 @@ public class SwitchManagerImpl implements ISwitchManager, @Override public void updateSwitchConfig(SwitchConfig cfgObject) { - boolean modeChange = false; + // update default container only + if (!isDefaultContainer) { + return; + } SwitchConfig sc = nodeConfigList.get(cfgObject.getNodeId()); + if (sc == null) { + if (nodeConfigList.putIfAbsent(cfgObject.getNodeId(), cfgObject) != null) { + return; + } + } else { + if (!nodeConfigList.replace(cfgObject.getNodeId(), sc, cfgObject)) { + return; + } + } + + boolean modeChange = false; + if ((sc == null) || !cfgObject.getMode().equals(sc.getMode())) { modeChange = true; } - nodeConfigList.put(cfgObject.getNodeId(), cfgObject); - try { - // update default container only + String nodeId = cfgObject.getNodeId(); + Node node = Node.fromString(nodeId); + Map propMapCurr = nodeProps.get(node); + if (propMapCurr == null) { + return; + } + Map propMap = new HashMap(propMapCurr); + Property desc = new Description(cfgObject.getNodeDescription()); + propMap.put(desc.getName(), desc); + Property tier = new Tier(Integer.parseInt(cfgObject.getTier())); + propMap.put(tier.getName(), tier); + + if (!nodeProps.replace(node, propMapCurr, propMap)) { + // TODO rollback using Transactionality + return; + } + + log.info("Set Node {}'s Mode to {}", nodeId, cfgObject.getMode()); + + if (modeChange) { + notifyModeChange(node, cfgObject.isProactive()); + } + } + + @Override + public Status updateNodeConfig(SwitchConfig switchConfig) { + Status status = switchConfig.validate(); + if (!status.isSuccess()) { + return status; + } + + Map updateProperties = switchConfig.getNodeProperties(); + String nodeId = switchConfig.getNodeId(); + ForwardingMode mode = (ForwardingMode) updateProperties.get(ForwardingMode.name); + if (mode != null) { if (isDefaultContainer) { - String nodeId = cfgObject.getNodeId(); - Node node = Node.fromString(nodeId); - Map propMap; - if (nodeProps.get(node) != null) { - propMap = nodeProps.get(node); - } else { - propMap = new HashMap(); + if (!mode.isValid()) { + return new Status(StatusCode.NOTACCEPTABLE, "Invalid Forwarding Mode Value."); } - Property desc = new Description(cfgObject.getNodeDescription()); - propMap.put(desc.getName(), desc); - Property tier = new Tier(Integer.parseInt(cfgObject.getTier())); - propMap.put(tier.getName(), tier); - addNodeProps(node, propMap); - - log.info("Set Node {}'s Mode to {}", nodeId, - cfgObject.getMode()); + } else { + return new Status(StatusCode.NOTACCEPTABLE, + "Forwarding Mode modification is allowed only in default container"); + } + } + boolean modeChange = false; + SwitchConfig sc = nodeConfigList.get(nodeId); + Map prevNodeProperties = new HashMap(); + if (sc == null) { + if ((mode != null) && mode.isProactive()) { + modeChange = true; + } + if (!updateProperties.isEmpty()) { + if (nodeConfigList.putIfAbsent(nodeId, switchConfig) != null) { + return new Status(StatusCode.CONFLICT, "Cluster conflict: Unable to update node configuration"); + } + } + } else { + prevNodeProperties = new HashMap(sc.getNodeProperties()); + ForwardingMode prevMode = (ForwardingMode) sc.getProperty(ForwardingMode.name); + if (mode == null) { + if ((prevMode != null) && (prevMode.isProactive())) { + modeChange = true; + } + } else { + if (((prevMode != null) && (prevMode.getValue() != mode.getValue())) + || (prevMode == null && mode.isProactive())) { + modeChange = true; + } + } + if (updateProperties.isEmpty()) { + nodeConfigList.remove(nodeId); + } else { + if (!nodeConfigList.replace(nodeId, sc, switchConfig)) { + return new Status(StatusCode.CONFLICT, "Cluster conflict: Unable to update node configuration"); + } + } + } + Node node = Node.fromString(nodeId); + Map propMapCurr = nodeProps.get(node); + Map propMap = new HashMap(propMapCurr); + if (propMapCurr == null) { + return new Status(StatusCode.SUCCESS); + } + if (!prevNodeProperties.isEmpty()) { + for (String prop : prevNodeProperties.keySet()) { + if (!updateProperties.containsKey(prop)) { + if (prop.equals(Description.propertyName)) { + Map> nodeProp = this.inventoryService.getNodeProps(); + if (nodeProp.get(node) != null) { + propMap.put(Description.propertyName, nodeProp.get(node).get(Description.propertyName)); + continue; + } + } + propMap.remove(prop); + } + } + } + propMap.putAll(updateProperties); + if (!nodeProps.replace(node, propMapCurr, propMap)) { + // TODO rollback using Transactionality + return new Status(StatusCode.CONFLICT, "Cluster conflict: Unable to update node configuration."); + } + if (modeChange) { + notifyModeChange(node, (mode == null) ? false : mode.isProactive()); + } + return new Status(StatusCode.SUCCESS); + } - if (modeChange) { - notifyModeChange(node, cfgObject.isProactive()); + @Override + public Status removeNodeConfig(String nodeId) { + if ((nodeId == null) || (nodeId.isEmpty())) { + return new Status(StatusCode.BADREQUEST, "nodeId cannot be empty."); + } + Map nodeProperties = getSwitchConfig(nodeId).getNodeProperties(); + Node node = Node.fromString(nodeId); + Map propMapCurr = nodeProps.get(node); + if ((propMapCurr != null) && (nodeProperties != null) && (!nodeProperties.isEmpty())) { + Map propMap = new HashMap(propMapCurr); + for (String prop : nodeProperties.keySet()) { + if (prop.equals(Description.propertyName)) { + Map> nodeProp = this.inventoryService.getNodeProps(); + if (nodeProp.get(node) != null) { + propMap.put(Description.propertyName, nodeProp.get(node).get(Description.propertyName)); + continue; + } } + propMap.remove(prop); } - } catch (Exception e) { - log.debug("updateSwitchConfig: {}", e.getMessage()); + if (!nodeProps.replace(node, propMapCurr, propMap)) { + return new Status(StatusCode.CONFLICT, "Cluster conflict: Unable to update node configuration."); + } + } + if (nodeConfigList != null) { + nodeConfigList.remove(nodeId); } + return new Status(StatusCode.SUCCESS); } @Override @@ -634,7 +816,7 @@ public class SwitchManagerImpl implements ISwitchManager, retS = objWriter.write(new ConcurrentHashMap( subnetsConfigList), subnetFileName); - retP = objWriter.write(new ConcurrentHashMap( + retP = objWriter.write(new ConcurrentHashMap( spanConfigList), spanFileName); retS = objWriter.write(new ConcurrentHashMap( nodeConfigList), switchConfigFileName); @@ -665,17 +847,17 @@ public class SwitchManagerImpl implements ISwitchManager, } // Presence check - if (spanConfigList.containsKey(conf.hashCode())) { + if (spanConfigList.containsKey(conf)) { return new Status(StatusCode.CONFLICT, "Same span config exists"); } - // Update database and notify clients - addSpanPorts(conf.getNode(), conf.getPortArrayList()); - // Update configuration - spanConfigList.put(conf.hashCode(), conf); + if (spanConfigList.putIfAbsent(conf, conf) == null) { + // Update database and notify clients + addSpanPorts(conf.getNode(), conf.getPortArrayList()); + } - return new Status(StatusCode.SUCCESS, null); + return new Status(StatusCode.SUCCESS); } @Override @@ -683,9 +865,9 @@ public class SwitchManagerImpl implements ISwitchManager, removeSpanPorts(conf.getNode(), conf.getPortArrayList()); // Update configuration - spanConfigList.remove(conf.hashCode()); + spanConfigList.remove(conf); - return new Status(StatusCode.SUCCESS, null); + return new Status(StatusCode.SUCCESS); } @Override @@ -720,12 +902,9 @@ public class SwitchManagerImpl implements ISwitchManager, return; } - Map propMap; - if (nodeProps.get(node) != null) { - propMap = nodeProps.get(node); - } else { - propMap = new HashMap(); - } + Map propMapCurr = nodeProps.get(node); + Map propMap = (propMapCurr == null) ? new HashMap() + : new HashMap(propMapCurr); // copy node properties from plugin if (props != null) { @@ -738,19 +917,31 @@ public class SwitchManagerImpl implements ISwitchManager, boolean proactiveForwarding = false; if (nodeConfigList != null) { String nodeId = node.toString(); - for (SwitchConfig conf : nodeConfigList.values()) { - if (conf.getNodeId().equals(nodeId)) { - Property description = new Description( - conf.getNodeDescription()); - propMap.put(description.getName(), description); - Property tier = new Tier(Integer.parseInt(conf.getTier())); - propMap.put(tier.getName(), tier); - proactiveForwarding = conf.isProactive(); - break; + SwitchConfig conf = nodeConfigList.get(nodeId); + if (conf != null && (conf.getNodeProperties() != null)) { + Map nodeProperties = conf.getNodeProperties(); + propMap.putAll(nodeProperties); + if (nodeProperties.get(ForwardingMode.name) != null) { + ForwardingMode mode = (ForwardingMode) nodeProperties.get(ForwardingMode.name); + proactiveForwarding = mode.isProactive(); } } } - addNodeProps(node, propMap); + + boolean result = false; + if (propMapCurr == null) { + if (nodeProps.putIfAbsent(node, propMap) == null) { + result = true; + } + } else { + result = nodeProps.replace(node, propMapCurr, propMap); + } + + if (!result) { + log.debug("Cluster conflict: Conflict while adding the node properties. Node: {} Properties: {}", + node.getID(), props); + addNodeProps(node, propMap); + } // check if span ports are configed addSpanPorts(node); @@ -785,20 +976,28 @@ public class SwitchManagerImpl implements ISwitchManager, return; } - Map propMap; - if (nodeProps.get(node) != null) { - propMap = nodeProps.get(node); - } else { - propMap = new HashMap(); - } + Map propMapCurr = nodeProps.get(node); + Map propMap = (propMapCurr == null) ? new HashMap() + : new HashMap(propMapCurr); // copy node properties from plugin - if (props != null) { - for (Property prop : props) { - propMap.put(prop.getName(), prop); + for (Property prop : props) { + propMap.put(prop.getName(), prop); + } + + if (propMapCurr == null) { + if (nodeProps.putIfAbsent(node, propMap) != null) { + log.debug("Cluster conflict: Conflict while updating the node. Node: {} Properties: {}", + node.getID(), props); + addNodeProps(node, propMap); + } + } else { + if (!nodeProps.replace(node, propMapCurr, propMap)) { + log.debug("Cluster conflict: Conflict while updating the node. Node: {} Properties: {}", + node.getID(), props); + addNodeProps(node, propMap); } } - addNodeProps(node, propMap); /* notify node listeners */ notifyNode(node, UpdateType.CHANGED, propMap); @@ -806,6 +1005,8 @@ public class SwitchManagerImpl implements ISwitchManager, @Override public void updateNode(Node node, UpdateType type, Set props) { + log.debug("updateNode: {} type {} props {} for container {}", + new Object[] { node, type, props, containerName }); switch (type) { case ADDED: addNode(node, props); @@ -824,10 +1025,10 @@ public class SwitchManagerImpl implements ISwitchManager, @Override public void updateNodeConnector(NodeConnector nodeConnector, UpdateType type, Set props) { - Node node = nodeConnector.getNode(); Map propMap = new HashMap(); - log.trace("{} {}", nodeConnector, type); + log.debug("updateNodeConnector: {} type {} props {} for container {}", + new Object[] { nodeConnector, type, props, containerName }); if (nodeConnectorProps == null) { return; @@ -843,15 +1044,12 @@ public class SwitchManagerImpl implements ISwitchManager, } } else { addNodeConnectorProp(nodeConnector, null); - addNodeProps(node, null); } - // check if span is configed addSpanPort(nodeConnector); break; case REMOVED: removeNodeConnectorAllProps(nodeConnector); - removeNodeProps(node); // clean up span config removeSpanPort(nodeConnector); @@ -869,49 +1067,26 @@ public class SwitchManagerImpl implements ISwitchManager, : null; } - /* - * test utility function which assumes all nodes are OF nodes - */ - private Node getNode(Long id) { - Set nodes = getNodes(); - if (nodes != null) { - for (Node node : nodes) { - if (id.equals((Long) node.getID())) { - return node; - } - } - } - return null; - } - /* * Returns a copy of a list of properties for a given node - * + * * (non-Javadoc) - * + * * @see * org.opendaylight.controller.switchmanager.ISwitchManager#getNodeProps * (org.opendaylight.controller.sal.core.Node) */ @Override public Map getNodeProps(Node node) { - if (isDefaultContainer) { - Map rv = null; - if (this.nodeProps != null) { - rv = this.nodeProps.get(node); - if (rv != null) { - /* make a copy of it */ - rv = new HashMap(rv); - } + Map rv = new HashMap(); + if (this.nodeProps != null) { + rv = this.nodeProps.get(node); + if (rv != null) { + /* make a copy of it */ + rv = new HashMap(rv); } - return rv; - } else { - // get it from default container - ISwitchManager defaultSwitchManager = (ISwitchManager) ServiceHelper - .getInstance(ISwitchManager.class, - GlobalConstants.DEFAULT.toString(), this); - return defaultSwitchManager.getNodeProps(node); } + return rv; } @Override @@ -922,43 +1097,75 @@ public class SwitchManagerImpl implements ISwitchManager, @Override public void setNodeProp(Node node, Property prop) { - /* Get a copy of the property map */ - Map propMap = getNodeProps(node); - if (propMap == null) - return; - propMap.put(prop.getName(), prop); - this.nodeProps.put(node, propMap); + for (int i = 0; i <= REPLACE_RETRY; i++) { + /* Get a copy of the property map */ + Map propMapCurr = getNodeProps(node); + if (propMapCurr == null) { + return; + } + + Map propMap = new HashMap(propMapCurr); + propMap.put(prop.getName(), prop); + + if (nodeProps.replace(node, propMapCurr, propMap)) { + return; + } + if (!propMapCurr.get(prop.getName()).equals(nodeProps.get(node).get(prop.getName()))) { + log.debug("Cluster conflict: Unable to add property {} to node {}.", prop.getName(), node.getID()); + return; + } + } + log.warn("Cluster conflict: Unable to add property {} to node {}.", prop.getName(), node.getID()); } @Override public Status removeNodeProp(Node node, String propName) { - Map propMap = getNodeProps(node); - if (propMap != null) { - propMap.remove(propName); - this.nodeProps.put(node, propMap); + for (int i = 0; i <= REPLACE_RETRY; i++) { + Map propMapCurr = getNodeProps(node); + if (propMapCurr != null) { + if (!propMapCurr.containsKey(propName)) { + return new Status(StatusCode.SUCCESS); + } + Map propMap = new HashMap(propMapCurr); + propMap.remove(propName); + if (nodeProps.replace(node, propMapCurr, propMap)) { + return new Status(StatusCode.SUCCESS); + } + if (!propMapCurr.get(propName).equals(nodeProps.get(node).get(propName))) { + String msg = "Cluster conflict: Unable to remove property " + propName + " for node " + + node.getID(); + return new Status(StatusCode.CONFLICT, msg); + } + + } else { + return new Status(StatusCode.SUCCESS); + } } - return new Status(StatusCode.SUCCESS, null); + String msg = "Cluster conflict: Unable to remove property " + propName + " for node " + node.getID(); + return new Status(StatusCode.CONFLICT, msg); } @Override public Status removeNodeAllProps(Node node) { this.nodeProps.remove(node); - return new Status(StatusCode.SUCCESS, null); + return new Status(StatusCode.SUCCESS); } @Override public Set getUpNodeConnectors(Node node) { - if (nodeConnectorProps == null) + if (nodeConnectorProps == null) { return null; + } Set nodeConnectorSet = new HashSet(); for (NodeConnector nodeConnector : nodeConnectorProps.keySet()) { - if (((Long) nodeConnector.getNode().getID()).longValue() != (Long) node - .getID()) + if (!nodeConnector.getNode().equals(node)) { continue; - if (isNodeConnectorEnabled(nodeConnector)) + } + if (isNodeConnectorEnabled(nodeConnector)) { nodeConnectorSet.add(nodeConnector); + } } return nodeConnectorSet; @@ -966,14 +1173,15 @@ public class SwitchManagerImpl implements ISwitchManager, @Override public Set getNodeConnectors(Node node) { - if (nodeConnectorProps == null) + if (nodeConnectorProps == null) { return null; + } Set nodeConnectorSet = new HashSet(); for (NodeConnector nodeConnector : nodeConnectorProps.keySet()) { - if (((Long) nodeConnector.getNode().getID()).longValue() != (Long) node - .getID()) + if (!nodeConnector.getNode().equals(node)) { continue; + } nodeConnectorSet.add(nodeConnector); } @@ -982,8 +1190,9 @@ public class SwitchManagerImpl implements ISwitchManager, @Override public Set getPhysicalNodeConnectors(Node node) { - if (nodeConnectorProps == null) + if (nodeConnectorProps == null) { return null; + } Set nodeConnectorSet = new HashSet(); for (NodeConnector nodeConnector : nodeConnectorProps.keySet()) { @@ -997,43 +1206,16 @@ public class SwitchManagerImpl implements ISwitchManager, return nodeConnectorSet; } - /* - * testing utility function which assumes we are dealing with OF Node - * nodeconnectors only - */ - @SuppressWarnings("unused") - private Set getEnabledNodeConnectorIds(Node node) { - Set ids = new HashSet(); - Set nodeConnectors = getUpNodeConnectors(node); - - if (nodeConnectors != null) { - for (NodeConnector nodeConnector : nodeConnectors) { - ids.add((Long) nodeConnector.getID()); - } - } - - return ids; - } - @Override - public Map getNodeConnectorProps( - NodeConnector nodeConnector) { - if (isDefaultContainer) { - Map rv = null; - if (this.nodeConnectorProps != null) { - rv = this.nodeConnectorProps.get(nodeConnector); - if (rv != null) { - rv = new HashMap(rv); - } + public Map getNodeConnectorProps(NodeConnector nodeConnector) { + Map rv = new HashMap(); + if (this.nodeConnectorProps != null) { + rv = this.nodeConnectorProps.get(nodeConnector); + if (rv != null) { + rv = new HashMap(rv); } - return rv; - } else { - // get it from default container - ISwitchManager defaultSwitchManager = (ISwitchManager) ServiceHelper - .getInstance(ISwitchManager.class, - GlobalConstants.DEFAULT.toString(), this); - return defaultSwitchManager.getNodeConnectorProps(nodeConnector); } + return rv; } @Override @@ -1083,19 +1265,21 @@ public class SwitchManagerImpl implements ISwitchManager, @Override public NodeConnector getNodeConnector(Node node, String nodeConnectorName) { - if (nodeConnectorNames == null) + if (nodeConnectorNames == null) { return null; + } Map map = nodeConnectorNames.get(node); - if (map == null) + if (map == null) { return null; + } return map.get(nodeConnectorName); } /** * Adds a node connector and its property if any - * + * * @param nodeConnector * {@link org.opendaylight.controller.sal.core.NodeConnector} * @param propName @@ -1105,41 +1289,73 @@ public class SwitchManagerImpl implements ISwitchManager, @Override public Status addNodeConnectorProp(NodeConnector nodeConnector, Property prop) { - Map propMap = getNodeConnectorProps(nodeConnector); - - if (propMap == null) { - propMap = new HashMap(); - } + Map propMapCurr = getNodeConnectorProps(nodeConnector); + Map propMap = (propMapCurr == null) ? new HashMap() + : new HashMap(propMapCurr); + String msg = "Cluster conflict: Unable to add NodeConnector Property."; // Just add the nodeConnector if prop is not available (in a non-default // container) if (prop == null) { - nodeConnectorProps.put(nodeConnector, propMap); - return new Status(StatusCode.SUCCESS, null); + if (propMapCurr == null) { + if (nodeConnectorProps.putIfAbsent(nodeConnector, propMap) != null) { + return new Status(StatusCode.CONFLICT, msg); + } + } else { + if (!nodeConnectorProps.replace(nodeConnector, propMapCurr, propMap)) { + return new Status(StatusCode.CONFLICT, msg); + } + } + return new Status(StatusCode.SUCCESS); } propMap.put(prop.getName(), prop); - nodeConnectorProps.put(nodeConnector, propMap); + if (propMapCurr == null) { + if (nodeConnectorProps.putIfAbsent(nodeConnector, propMap) != null) { + return new Status(StatusCode.CONFLICT, msg); + } + } else { + if (!nodeConnectorProps.replace(nodeConnector, propMapCurr, propMap)) { + return new Status(StatusCode.CONFLICT, msg); + } + } if (prop.getName().equals(Name.NamePropName)) { if (nodeConnectorNames != null) { Node node = nodeConnector.getNode(); - Map map = nodeConnectorNames.get(node); - if (map == null) { - map = new HashMap(); + Map mapCurr = nodeConnectorNames.get(node); + Map map = new HashMap(); + if (mapCurr != null) { + for (String s : mapCurr.keySet()) { + try { + map.put(s, new NodeConnector(mapCurr.get(s))); + } catch (ConstructionException e) { + e.printStackTrace(); + } + } } map.put(((Name) prop).getValue(), nodeConnector); - nodeConnectorNames.put(node, map); + if (mapCurr == null) { + if (nodeConnectorNames.putIfAbsent(node, map) != null) { + // TODO: recovery using Transactionality + return new Status(StatusCode.CONFLICT, msg); + } + } else { + if (!nodeConnectorNames.replace(node, mapCurr, map)) { + // TODO: recovery using Transactionality + return new Status(StatusCode.CONFLICT, msg); + } + } } } - return new Status(StatusCode.SUCCESS, null); + return new Status(StatusCode.SUCCESS); } /** * Removes one property of a node connector - * + * * @param nodeConnector * {@link org.opendaylight.controller.sal.core.NodeConnector} * @param propName @@ -1147,37 +1363,53 @@ public class SwitchManagerImpl implements ISwitchManager, * @return success or failed reason */ @Override - public Status removeNodeConnectorProp(NodeConnector nodeConnector, - String propName) { - Map propMap = getNodeConnectorProps(nodeConnector); + public Status removeNodeConnectorProp(NodeConnector nodeConnector, String propName) { + Map propMapCurr = getNodeConnectorProps(nodeConnector); - if (propMap == null) { + if (propMapCurr == null) { /* Nothing to remove */ - return new Status(StatusCode.SUCCESS, null); + return new Status(StatusCode.SUCCESS); } + Map propMap = new HashMap(propMapCurr); propMap.remove(propName); - nodeConnectorProps.put(nodeConnector, propMap); + boolean result = nodeConnectorProps.replace(nodeConnector, propMapCurr, propMap); + String msg = "Cluster conflict: Unable to remove NodeConnector property."; + if (!result) { + return new Status(StatusCode.CONFLICT, msg); + } - if (nodeConnectorNames != null) { - Name name = ((Name) getNodeConnectorProp(nodeConnector, - Name.NamePropName)); - if (name != null) { - Node node = nodeConnector.getNode(); - Map map = nodeConnectorNames.get(node); - if (map != null) { - map.remove(name.getValue()); - nodeConnectorNames.put(node, map); + if (propName.equals(Name.NamePropName)) { + if (nodeConnectorNames != null) { + Name name = ((Name) getNodeConnectorProp(nodeConnector, Name.NamePropName)); + if (name != null) { + Node node = nodeConnector.getNode(); + Map mapCurr = nodeConnectorNames.get(node); + if (mapCurr != null) { + Map map = new HashMap(); + for (String s : mapCurr.keySet()) { + try { + map.put(s, new NodeConnector(mapCurr.get(s))); + } catch (ConstructionException e) { + e.printStackTrace(); + } + } + map.remove(name.getValue()); + if (!nodeConnectorNames.replace(node, mapCurr, map)) { + // TODO: recovery using Transactionality + return new Status(StatusCode.CONFLICT, msg); + } + } } } } - return new Status(StatusCode.SUCCESS, null); + return new Status(StatusCode.SUCCESS); } /** * Removes all the properties of a node connector - * + * * @param nodeConnector * {@link org.opendaylight.controller.sal.core.NodeConnector} * @return success or failed reason @@ -1185,26 +1417,37 @@ public class SwitchManagerImpl implements ISwitchManager, @Override public Status removeNodeConnectorAllProps(NodeConnector nodeConnector) { if (nodeConnectorNames != null) { - Name name = ((Name) getNodeConnectorProp(nodeConnector, - Name.NamePropName)); + Name name = ((Name) getNodeConnectorProp(nodeConnector, Name.NamePropName)); if (name != null) { Node node = nodeConnector.getNode(); - Map map = nodeConnectorNames.get(node); - if (map != null) { + Map mapCurr = nodeConnectorNames.get(node); + if (mapCurr != null) { + Map map = new HashMap(); + for (String s : mapCurr.keySet()) { + try { + map.put(s, new NodeConnector(mapCurr.get(s))); + } catch (ConstructionException e) { + e.printStackTrace(); + } + } map.remove(name.getValue()); - nodeConnectorNames.put(node, map); + if (!nodeConnectorNames.replace(node, mapCurr, map)) { + log.warn("Cluster conflict: Unable remove Name property of nodeconnector {}, skip.", + nodeConnector.getID()); + } } + } } nodeConnectorProps.remove(nodeConnector); - return new Status(StatusCode.SUCCESS, null); + return new Status(StatusCode.SUCCESS); } /** * Function called by the dependency manager when all the required * dependencies are satisfied - * + * */ void init(Component c) { Dictionary props = c.getServiceProperties(); @@ -1225,7 +1468,7 @@ public class SwitchManagerImpl implements ISwitchManager, * Function called by the dependency manager when at least one dependency * become unsatisfied or when the component is shutting down because for * example bundle is being stopped. - * + * */ void destroy() { shutDown(); @@ -1234,7 +1477,7 @@ public class SwitchManagerImpl implements ISwitchManager, /** * Function called by dependency manager after "init ()" is called and after * the services provided by the class are registered in the service registry - * + * */ void start() { // OSGI console @@ -1253,7 +1496,7 @@ public class SwitchManagerImpl implements ISwitchManager, * Function called by the dependency manager before the services exported by * the component are unregistered, this will be followed by a "destroy ()" * calls - * + * */ void stop() { } @@ -1343,15 +1586,25 @@ public class SwitchManagerImpl implements ISwitchManager, return; } - nodeProps = this.inventoryService.getNodeProps(); - Set nodeSet = nodeProps.keySet(); - if (nodeSet != null) { - for (Node node : nodeSet) { - addNode(node, null); + Map> nodeProp = this.inventoryService.getNodeProps(); + for (Map.Entry> entry : nodeProp.entrySet()) { + Node node = entry.getKey(); + log.debug("getInventories: {} added for container {}", new Object[] { node, containerName }); + Map propMap = entry.getValue(); + Set props = new HashSet(); + for (Property property : propMap.values()) { + props.add(property); } + addNode(node, props); } - nodeConnectorProps = inventoryService.getNodeConnectorProps(); + Map> nodeConnectorProp = this.inventoryService.getNodeConnectorProps(); + for (Map.Entry> entry : nodeConnectorProp.entrySet()) { + Map propMap = entry.getValue(); + for (Property property : propMap.values()) { + addNodeConnectorProp(entry.getKey(), property); + } + } } private void clearInventories() { @@ -1390,23 +1643,24 @@ public class SwitchManagerImpl implements ISwitchManager, for (Node node : getNodes()) { SwitchConfig sc = getSwitchConfig(node.toString()); if ((sc != null) && isDefaultContainer) { - service.modeChangeNotify(node, sc.isProactive()); + ForwardingMode mode = (ForwardingMode) sc.getProperty(ForwardingMode.name); + service.modeChangeNotify(node, (mode == null) ? false : mode.isProactive()); } } } private void bulkUpdateService(IInventoryListener service) { + Map propMap; + UpdateType type = UpdateType.ADDED; + for (Node node : getNodes()) { - service.notifyNode(node, UpdateType.ADDED, null); + propMap = nodeProps.get(node); + service.notifyNode(node, type, propMap); } - Map propMap = new HashMap(); - propMap.put(State.StatePropName, new State(State.EDGE_UP)); for (NodeConnector nodeConnector : nodeConnectorProps.keySet()) { - if (isNodeConnectorEnabled(nodeConnector)) { - service.notifyNodeConnector(nodeConnector, UpdateType.ADDED, - propMap); - } + propMap = nodeConnectorProps.get(nodeConnector); + service.notifyNodeConnector(nodeConnector, type, propMap); } } @@ -1427,8 +1681,9 @@ public class SwitchManagerImpl implements ISwitchManager, @Override public Boolean isNodeConnectorEnabled(NodeConnector nodeConnector) { - if (nodeConnector == null) + if (nodeConnector == null) { return false; + } Config config = (Config) getNodeConnectorProp(nodeConnector, Config.ConfigPropName); @@ -1453,7 +1708,7 @@ public class SwitchManagerImpl implements ISwitchManager, } public void _pns(CommandInterpreter ci) { - ci.println(" Node Type Name Tier"); + ci.println(" Node Type MAC Name Tier"); if (nodeProps == null) { return; } @@ -1461,14 +1716,24 @@ public class SwitchManagerImpl implements ISwitchManager, if (nodeSet == null) { return; } + List nodeArray = new ArrayList(); for (Node node : nodeSet) { + nodeArray.add(node.toString()); + } + Collections.sort(nodeArray); + for (String str: nodeArray) { + Node node = Node.fromString(str); Description desc = ((Description) getNodeProp(node, Description.propertyName)); Tier tier = ((Tier) getNodeProp(node, Tier.TierPropName)); String nodeName = (desc == null) ? "" : desc.getValue(); + MacAddress mac = (MacAddress) getNodeProp(node, + MacAddress.name); + String macAddr = (mac == null) ? "" : HexEncode + .bytesToHexStringFormat(mac.getMacAddress()); int tierNum = (tier == null) ? 0 : tier.getValue(); - ci.println(node + " " + node.getType() + " " - + nodeName + " " + tierNum); + ci.println(node + " " + node.getType() + " " + macAddr + + " " + nodeName + " " + tierNum); } ci.println("Total number of Nodes: " + nodeSet.size()); } @@ -1620,17 +1885,19 @@ public class SwitchManagerImpl implements ISwitchManager, ci.println("expecting on/off/?"); return; } - if (mode.toLowerCase().equals("on")) + if (mode.toLowerCase().equals("on")) { hostRefresh = true; - else if (mode.toLowerCase().equals("off")) + } else if (mode.toLowerCase().equals("off")) { hostRefresh = false; - else if (mode.equals("?")) { - if (hostRefresh) + } else if (mode.equals("?")) { + if (hostRefresh) { ci.println("host refresh is ON"); - else + } else { ci.println("host refresh is OFF"); - } else + } + } else { ci.println("expecting on/off/?"); + } return; } @@ -1651,17 +1918,9 @@ public class SwitchManagerImpl implements ISwitchManager, @Override public byte[] getNodeMAC(Node node) { - if (node.getType().equals(Node.NodeIDType.OPENFLOW)) { - byte[] gmac = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - long dpid = (Long) node.getID(); - - for (short i = 0; i < 6; i++) { - gmac[5 - i] = (byte) dpid; - dpid >>= 8; - } - return gmac; - } - return null; + MacAddress mac = (MacAddress) this.getNodeProp(node, + MacAddress.name); + return (mac != null) ? mac.getMacAddress() : null; } @Override @@ -1678,10 +1937,10 @@ public class SwitchManagerImpl implements ISwitchManager, /* * Add span configuration to local cache and notify clients */ - private void addSpanPorts(Node node, List nodeConncetors) { + private void addSpanPorts(Node node, List nodeConnectors) { List ncLists = new ArrayList(); - for (NodeConnector nodeConnector : nodeConncetors) { + for (NodeConnector nodeConnector : nodeConnectors) { if (!spanNodeConnectors.contains(nodeConnector)) { ncLists.add(nodeConnector); } @@ -1699,20 +1958,26 @@ public class SwitchManagerImpl implements ISwitchManager, } } - private void addSpanPort(NodeConnector nodeConncetor) { - List ncLists = new ArrayList(); - ncLists.add(nodeConncetor); - addSpanPorts(nodeConncetor.getNode(), ncLists); + private void addSpanPort(NodeConnector nodeConnector) { + // only add if span is configured on this nodeConnector + for (SpanConfig conf : getSpanConfigList(nodeConnector.getNode())) { + if (conf.getPortArrayList().contains(nodeConnector)) { + List ncLists = new ArrayList(); + ncLists.add(nodeConnector); + addSpanPorts(nodeConnector.getNode(), ncLists); + return; + } + } } /* * Remove span configuration to local cache and notify clients */ - private void removeSpanPorts(Node node, List nodeConncetors) { + private void removeSpanPorts(Node node, List nodeConnectors) { List ncLists = new ArrayList(); - for (NodeConnector nodeConnector : nodeConncetors) { - if (!spanNodeConnectors.contains(nodeConnector)) { + for (NodeConnector nodeConnector : nodeConnectors) { + if (spanNodeConnectors.contains(nodeConnector)) { ncLists.add(nodeConnector); } } @@ -1729,10 +1994,12 @@ public class SwitchManagerImpl implements ISwitchManager, } } - private void removeSpanPort(NodeConnector nodeConncetor) { - List ncLists = new ArrayList(); - ncLists.add(nodeConncetor); - removeSpanPorts(nodeConncetor.getNode(), ncLists); + private void removeSpanPort(NodeConnector nodeConnector) { + if (spanNodeConnectors.contains(nodeConnector)) { + List ncLists = new ArrayList(); + ncLists.add(nodeConnector); + removeSpanPorts(nodeConnector.getNode(), ncLists); + } } private void addNodeProps(Node node, Map propMap) { @@ -1756,7 +2023,7 @@ public class SwitchManagerImpl implements ISwitchManager, /** * Creates a Name/Tier/Bandwidth Property object based on given property * name and value. Other property types are not supported yet. - * + * * @param propName * Name of the Property * @param propValue @@ -1783,6 +2050,9 @@ public class SwitchManagerImpl implements ISwitchManager, } else if (propName.equalsIgnoreCase(Bandwidth.BandwidthPropName)) { long bw = Long.parseLong(propValue); return new Bandwidth(bw); + } else if (propName.equalsIgnoreCase(ForwardingMode.name)) { + int mode = Integer.parseInt(propValue); + return new ForwardingMode(mode); } else { log.debug("Not able to create {} property", propName); }