X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fforwardingrulesmanager%2Fimplementation%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fforwardingrulesmanager%2Finternal%2FForwardingRulesManager.java;h=bce7dd30ba59de6c9707062f3fdeaf9f23a8141d;hp=45fb11a83eda110b96b1588dd43b0c8fd6c7b164;hb=9255eb1b0531be05266f52175044464fee30a969;hpb=81754b97dad4d38ee9a38516664f6b1b8c99d48c diff --git a/opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java b/opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java index 45fb11a83e..bce7dd30ba 100644 --- a/opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java +++ b/opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java @@ -33,7 +33,9 @@ import org.opendaylight.controller.clustering.services.CacheExistException; import org.opendaylight.controller.clustering.services.ICacheUpdateAware; import org.opendaylight.controller.clustering.services.IClusterContainerServices; import org.opendaylight.controller.clustering.services.IClusterServices; +import org.opendaylight.controller.configuration.ConfigurationObject; import org.opendaylight.controller.configuration.IConfigurationContainerAware; +import org.opendaylight.controller.configuration.IConfigurationContainerService; import org.opendaylight.controller.connectionmanager.IConnectionManager; import org.opendaylight.controller.containermanager.IContainerManager; import org.opendaylight.controller.forwardingrulesmanager.FlowConfig; @@ -66,8 +68,6 @@ import org.opendaylight.controller.sal.match.MatchType; import org.opendaylight.controller.sal.utils.EtherTypes; import org.opendaylight.controller.sal.utils.GlobalConstants; import org.opendaylight.controller.sal.utils.IObjectReader; -import org.opendaylight.controller.sal.utils.ObjectReader; -import org.opendaylight.controller.sal.utils.ObjectWriter; import org.opendaylight.controller.sal.utils.Status; import org.opendaylight.controller.sal.utils.StatusCode; import org.opendaylight.controller.switchmanager.IInventoryListener; @@ -98,14 +98,15 @@ public class ForwardingRulesManager implements private static final String PORT_REMOVED = "Port removed"; private static final String NODE_DOWN = "Node is Down"; private static final String INVALID_FLOW_ENTRY = "Invalid FlowEntry"; - private String frmFileName; - private String portGroupFileName; + private static final String STATIC_FLOWS_FILE_NAME = "frm_staticflows.conf"; + private static final String PORT_GROUP_FILE_NAME = "portgroup.conf"; private ConcurrentMap staticFlows; private ConcurrentMap staticFlowsOrdinal; private ConcurrentMap portGroupConfigs; private ConcurrentMap> portGroupData; private ConcurrentMap TSPolicies; private IContainerManager containerManager; + private IConfigurationContainerService configurationService; private boolean inContainerMode; // being used by global instance only protected boolean stopping; @@ -467,7 +468,7 @@ public class ForwardingRulesManager implements Status succeeded = null; boolean decouple = false; if (installedList.size() != toInstallList.size()) { - log.info("Modify: New flow entry does not satisfy the same " + log.trace("Modify: New flow entry does not satisfy the same " + "number of container flows as the original entry does"); decouple = true; } @@ -479,7 +480,7 @@ public class ForwardingRulesManager implements */ FlowEntryInstall sameMatchEntry = installedSwView.get(installEntry); if (sameMatchEntry != null && !sameMatchEntry.getOriginal().equals(currentFlowEntry)) { - log.info("Modify: new container flow merged flow entry clashes with existing flow"); + log.trace("Modify: new container flow merged flow entry clashes with existing flow"); decouple = true; } else { toInstallSafe.add(installEntry); @@ -1263,7 +1264,7 @@ public class ForwardingRulesManager implements } Status error = modifyEntry(currentFlowEntry, newFlowEntry, false); if (error.isSuccess()) { - log.info("Ports {} added to FlowEntry {}", portList, flowName); + log.trace("Ports {} added to FlowEntry {}", portList, flowName); } else { log.warn("Failed to add ports {} to Flow entry {}. The failure is: {}", portList, currentFlowEntry.toString(), error.getDescription()); @@ -1287,7 +1288,7 @@ public class ForwardingRulesManager implements } Status status = modifyEntry(currentFlowEntry, newFlowEntry, false); if (status.isSuccess()) { - log.info("Ports {} removed from FlowEntry {}", portList, flowName); + log.trace("Ports {} removed from FlowEntry {}", portList, flowName); } else { log.warn("Failed to remove ports {} from Flow entry {}. The failure is: {}", portList, currentFlowEntry.toString(), status.getDescription()); @@ -1335,7 +1336,7 @@ public class ForwardingRulesManager implements Status status = modifyEntry(currentFlowEntry, newFlowEntry, false); if (status.isSuccess()) { - log.info("Output port replaced with {} for flow {} on node {}", outPort, flowName, node); + log.trace("Output port replaced with {} for flow {} on node {}", outPort, flowName, node); } else { log.warn("Failed to replace output port for flow {} on node {}. The failure is: {}", flowName, node, status.getDescription()); @@ -1793,7 +1794,7 @@ public class ForwardingRulesManager implements // Do not attempt to reinstall the flow, warn user if (newFlowConfig.equals(oldFlowConfig)) { String msg = "No modification detected"; - log.info("Static flow modification skipped. New flow and old flow are the same: {}", newFlowConfig); + log.trace("Static flow modification skipped. New flow and old flow are the same: {}", newFlowConfig); return new Status(StatusCode.SUCCESS, msg); } @@ -1895,7 +1896,7 @@ public class ForwardingRulesManager implements * inactive list */ private void uninstallAllFlowEntries(boolean preserveFlowEntries) { - log.info("Uninstalling all non-internal flows"); + log.trace("Uninstalling all non-internal flows"); List toRemove = new ArrayList(); @@ -1933,7 +1934,7 @@ public class ForwardingRulesManager implements * default container instance of FRM only when the last container is deleted */ private void reinstallAllFlowEntries() { - log.info("Reinstalling all inactive flows"); + log.trace("Reinstalling all inactive flows"); for (FlowEntry flowEntry : this.inactiveFlows.keySet()) { this.addEntry(flowEntry, false); @@ -1945,22 +1946,7 @@ public class ForwardingRulesManager implements @Override public List getStaticFlows() { - return getStaticFlowsOrderedList(staticFlows, staticFlowsOrdinal.get(0).intValue()); - } - - // TODO: need to come out with a better algorithm for maintaining the order - // of the configuration entries - // with actual one, index associated to deleted entries cannot be reused and - // map grows... - private List getStaticFlowsOrderedList(ConcurrentMap flowMap, int maxKey) { - List orderedList = new ArrayList(); - for (int i = 0; i <= maxKey; i++) { - FlowConfig entry = flowMap.get(i); - if (entry != null) { - orderedList.add(entry); - } - } - return orderedList; + return new ArrayList(staticFlows.values()); } @Override @@ -2003,34 +1989,13 @@ public class ForwardingRulesManager implements return new ArrayList(set); } - @SuppressWarnings("unchecked") private void loadFlowConfiguration() { - ObjectReader objReader = new ObjectReader(); - ConcurrentMap confList = (ConcurrentMap) objReader.read(this, - frmFileName); - - ConcurrentMap pgConfig = (ConcurrentMap) objReader.read(this, - portGroupFileName); - - if (pgConfig != null) { - for (ConcurrentMap.Entry entry : pgConfig.entrySet()) { - addPortGroupConfig(entry.getKey(), entry.getValue().getMatchString(), true); - } - } - - if (confList == null) { - return; + for (ConfigurationObject conf : configurationService.retrieveConfiguration(this, PORT_GROUP_FILE_NAME)) { + addPortGroupConfig(((PortGroupConfig) conf).getName(), ((PortGroupConfig) conf).getMatchString(), true); } - int maxKey = 0; - for (Integer key : confList.keySet()) { - if (key.intValue() > maxKey) { - maxKey = key.intValue(); - } - } - - for (FlowConfig conf : getStaticFlowsOrderedList(confList, maxKey)) { - addStaticFlowInternal(conf, true); + for (ConfigurationObject conf : configurationService.retrieveConfiguration(this, STATIC_FLOWS_FILE_NAME)) { + addStaticFlowInternal((FlowConfig) conf, true); } } @@ -2045,25 +2010,44 @@ public class ForwardingRulesManager implements } private Status saveConfigInternal() { - ObjectWriter objWriter = new ObjectWriter(); - ConcurrentMap nonDynamicFlows = new ConcurrentHashMap(); + List nonDynamicFlows = new ArrayList(); + for (Integer ordinal : staticFlows.keySet()) { FlowConfig config = staticFlows.get(ordinal); // Do not save dynamic and controller generated static flows if (config.isDynamic() || config.isInternalFlow()) { continue; } - nonDynamicFlows.put(ordinal, config); + nonDynamicFlows.add(config); } - objWriter.write(nonDynamicFlows, frmFileName); - objWriter.write(new ConcurrentHashMap(portGroupConfigs), portGroupFileName); - return new Status(StatusCode.SUCCESS, null); + + configurationService.persistConfiguration(nonDynamicFlows, STATIC_FLOWS_FILE_NAME); + configurationService.persistConfiguration(new ArrayList(portGroupConfigs.values()), + PORT_GROUP_FILE_NAME); + + return new Status(StatusCode.SUCCESS); } @Override public void subnetNotify(Subnet sub, boolean add) { } + private boolean programInternalFlow(boolean proactive, FlowConfig fc) { + boolean retVal = true; // program flows unless determined otherwise + if(proactive) { + // if the flow already exists do not program + if(flowConfigExists(fc)) { + retVal = false; + } + } else { + // if the flow does not exist do not program + if(!flowConfigExists(fc)) { + retVal = false; + } + } + return retVal; + } + /** * (non-Javadoc) * @@ -2118,14 +2102,20 @@ public class ForwardingRulesManager implements dropAllConfig.setActions(dropAction); defaultConfigs.add(dropAllConfig); - log.info("Forwarding mode for node {} set to {}", node, (proactive ? "proactive" : "reactive")); + log.trace("Forwarding mode for node {} set to {}", node, (proactive ? "proactive" : "reactive")); for (FlowConfig fc : defaultConfigs) { - Status status = (proactive) ? addStaticFlowInternal(fc, false) : removeStaticFlow(fc); - if (status.isSuccess()) { - log.info("{} Proactive Static flow: {}", (proactive ? "Installed" : "Removed"), fc.getName()); + // check if the frm really needs to act on the notification. + // this is to check against duplicate notifications + if(programInternalFlow(proactive, fc)) { + Status status = (proactive) ? addStaticFlowInternal(fc, false) : removeStaticFlow(fc); + if (status.isSuccess()) { + log.trace("{} Proactive Static flow: {}", (proactive ? "Installed" : "Removed"), fc.getName()); + } else { + log.warn("Failed to {} Proactive Static flow: {}", (proactive ? "install" : "remove"), + fc.getName()); + } } else { - log.warn("Failed to {} Proactive Static flow: {}", (proactive ? "install" : "remove"), - fc.getName()); + log.debug("Got redundant install request for internal flow: {} on node: {}. Request not sent to FRM.", fc.getName(), node); } } return new Status(StatusCode.SUCCESS); @@ -2145,7 +2135,7 @@ public class ForwardingRulesManager implements * @param node */ private void cleanDatabaseForNode(Node node) { - log.info("Cleaning Flow database for Node {}", node); + log.trace("Cleaning Flow database for Node {}", node); if (nodeFlows.containsKey(node)) { List toRemove = new ArrayList(nodeFlows.get(node)); @@ -2322,7 +2312,7 @@ public class ForwardingRulesManager implements @Override public void portGroupChanged(PortGroupConfig config, Map data, boolean add) { - log.info("PortGroup Changed for: {} Data: {}", config, portGroupData); + log.trace("PortGroup Changed for: {} Data: {}", config, portGroupData); Map existingData = portGroupData.get(config); if (existingData != null) { for (Map.Entry entry : data.entrySet()) { @@ -2410,6 +2400,16 @@ public class ForwardingRulesManager implements } } + public void setConfigurationContainerService(IConfigurationContainerService service) { + log.trace("Got configuration service set request {}", service); + this.configurationService = service; + } + + public void unsetConfigurationContainerService(IConfigurationContainerService service) { + log.trace("Got configuration service UNset request"); + this.configurationService = null; + } + @Override public PortGroupProvider getPortGroupProvider() { return portGroupProvider; @@ -2460,8 +2460,6 @@ public class ForwardingRulesManager implements * */ void init() { - frmFileName = GlobalConstants.STARTUPHOME.toString() + "frm_staticflows_" + this.getContainerName() + ".conf"; - portGroupFileName = GlobalConstants.STARTUPHOME.toString() + "portgroup_" + this.getContainerName() + ".conf"; inContainerMode = false; @@ -2631,12 +2629,16 @@ public class ForwardingRulesManager implements } /* - * Read startup and build database if we have not already gotten the - * configurations synced from another node + * Read startup and build database if we are the coordinator */ - if (staticFlows.isEmpty()) { - loadFlowConfiguration(); - } + loadFlowConfiguration(); + } + + /** + * Function called by the dependency manager before Container is Stopped and Destroyed. + */ + public void containerStop() { + uninstallAllFlowEntries(false); } /** @@ -2646,7 +2648,6 @@ public class ForwardingRulesManager implements */ void stop() { stopping = true; - uninstallAllFlowEntries(false); // Shutdown executor this.executor.shutdownNow(); // Now walk all the workMonitor and wake up the one sleeping because @@ -2930,8 +2931,16 @@ public class ForwardingRulesManager implements } if (target != null) { // Update Configuration database - target.toggleInstallation(); - target.setStatus(StatusCode.SUCCESS.toString()); + if (target.getHardTimeout() != null || target.getIdleTimeout() != null) { + /* + * No need for checking if actual values: these strings were + * validated at configuration creation. Also, after a switch + * down scenario, no use to reinstall a timed flow. Mark it as + * "do not install". User can manually toggle it. + */ + target.toggleInstallation(); + } + target.setStatus(StatusCode.GONE.toString()); staticFlows.put(key, target); } @@ -2980,7 +2989,11 @@ public class ForwardingRulesManager implements // staticFlowEntry should never be null. // the null check is just an extra defensive check. if(staticFlowEntry != null) { - staticFlows.remove(staticFlowEntry.getKey()); + // Modify status and update cluster cache + log.debug("Updating static flow configuration on async error event"); + String status = String.format("Cannot be installed on node. reason: %s", errorString); + staticFlowEntry.getValue().setStatus(status); + refreshClusterStaticFlowsStatus(node); } } }