X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fforwardingrules-manager%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fforwardingrulesmanager%2Fconsumer%2Fimpl%2FFlowConsumerImpl.java;h=2710104fcfac524ea9cd71cb023f151b81f98c90;hb=3f83be2d86dfe0aea7d9f1392c75939ee678324e;hp=2ffe0ecd87eee775b08f6e5b51c1e0febcb66baf;hpb=a87db38d47967eae159c5be17ab334bb6a4edffc;p=controller.git diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FlowConsumerImpl.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FlowConsumerImpl.java index 2ffe0ecd87..2710104fcf 100644 --- a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FlowConsumerImpl.java +++ b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FlowConsumerImpl.java @@ -1,8 +1,10 @@ package org.opendaylight.controller.forwardingrulesmanager.consumer.impl; import java.util.ArrayList; +import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -20,31 +22,18 @@ import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.Data import org.opendaylight.controller.md.sal.common.api.data.DataModification; import org.opendaylight.controller.sal.common.util.Rpcs; import org.opendaylight.controller.sal.core.IContainer; -import org.opendaylight.controller.sal.utils.GlobalConstants; 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.ISwitchManager; -import org.opendaylight.controller.switchmanager.Switch; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.Flows; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.Flow; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.config.rev130819.flows.FlowKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowUpdated; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeErrorNotification; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeExperimenterErrorNotification; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlow; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowListener; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SwitchFlowRemoved; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlowBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; @@ -54,13 +43,15 @@ import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.NotificationListener; +import org.opendaylight.yangtools.yang.common.RpcError; import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class FlowConsumerImpl implements IForwardingRulesManager { protected static final Logger logger = LoggerFactory.getLogger(FlowConsumerImpl.class); - private final FlowEventListener flowEventListener = new FlowEventListener(); + // private final FlowEventListener flowEventListener = new + // FlowEventListener(); private Registration listener1Reg; private SalFlowService flowService; // private FlowDataListener listener; @@ -86,13 +77,11 @@ public class FlowConsumerImpl implements IForwardingRulesManager { private boolean inContainerMode; // being used by global instance only public FlowConsumerImpl() { - InstanceIdentifier path = InstanceIdentifier.builder(Flows.class).child(Flow.class) - .toInstance(); + InstanceIdentifier path = InstanceIdentifier.builder(Flows.class).toInstance(); flowService = FRMConsumerImpl.getProviderSession().getRpcService(SalFlowService.class); if (null == flowService) { logger.error("Consumer SAL Service is down or NULL. FRM may not function as intended"); - System.out.println("Consumer SAL Service is down or NULL."); return; } @@ -107,21 +96,19 @@ public class FlowConsumerImpl implements IForwardingRulesManager { // } // For switch events - listener1Reg = FRMConsumerImpl.getNotificationService().registerNotificationListener(flowEventListener); + // listener1Reg = + // FRMConsumerImpl.getNotificationService().registerNotificationListener(flowEventListener); if (null == listener1Reg) { logger.error("Listener to listen on flow data modifcation events"); - System.out.println("Consumer SAL Service is down or NULL."); return; } // addFlowTest(); - System.out.println("-------------------------------------------------------------------"); - allocateCaches(); commitHandler = new FlowDataCommitHandler(); FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, commitHandler); clusterContainerService = (IClusterContainerServices) ServiceHelper.getGlobalInstance( IClusterContainerServices.class, this); - container = (IContainer) ServiceHelper.getGlobalInstance(IContainer.class, this); + allocateCaches(); /* * If we are not the first cluster node to come up, do not initialize * the static flow entries ordinal @@ -167,9 +154,7 @@ public class FlowConsumerImpl implements IForwardingRulesManager { AddFlowInput firstMsg = input1.build(); if (null != flowService) { - System.out.println(flowService.toString()); - } else { - System.out.println("ConsumerFlowService is NULL"); + logger.error("ConsumerFlowService is NULL"); } @SuppressWarnings("unused") Future> result1 = flowService.addFlow(firstMsg); @@ -189,28 +174,42 @@ public class FlowConsumerImpl implements IForwardingRulesManager { private void addFlow(InstanceIdentifier path, Flow dataObject) { AddFlowInputBuilder input = new AddFlowInputBuilder(); - List inst = (dataObject).getInstructions().getInstruction(); + input.setNode((dataObject).getNode()); input.setPriority((dataObject).getPriority()); input.setMatch((dataObject).getMatch()); input.setCookie((dataObject).getCookie()); input.setInstructions((dataObject).getInstructions()); - dataObject.getMatch().getLayer3Match(); - for (int i = 0; i < inst.size(); i++) { - System.out.println("i = " + i + inst.get(i).getInstruction().toString()); - System.out.println("i = " + i + inst.get(i).toString()); - } - - System.out.println("Instruction list" + (dataObject).getInstructions().getInstruction().toString()); + input.setBufferId(dataObject.getBufferId()); + input.setTableId(dataObject.getTableId()); + input.setOutPort(dataObject.getOutPort()); + input.setOutGroup(dataObject.getOutGroup()); + input.setIdleTimeout(dataObject.getIdleTimeout()); + input.setHardTimeout(dataObject.getHardTimeout()); + input.setFlowName(dataObject.getFlowName()); + input.setFlags(dataObject.getFlags()); + input.setCookieMask(dataObject.getCookieMask()); + input.setContainerName(dataObject.getContainerName()); + input.setBarrier(dataObject.isBarrier()); + input.setInstallHw(dataObject.isInstallHw()); + input.setStrict(dataObject.isStrict()); // updating the staticflow cache - Integer ordinal = staticFlowsOrdinal.get(0); - staticFlowsOrdinal.put(0, ++ordinal); - staticFlows.put(ordinal, dataObject); + /* + * Commented out... as in many other places... use of ClusteringServices + * is breaking things insufficient time to debug Integer ordinal = + * staticFlowsOrdinal.get(0); staticFlowsOrdinal.put(0, ++ordinal); + * staticFlows.put(ordinal, dataObject); + */ // We send flow to the sounthbound plugin + flowService.addFlow(input.build()); - updateLocalDatabase((NodeFlow) dataObject, true); + + /* + * Commented out as this will also break due to improper use of + * ClusteringServices updateLocalDatabase((NodeFlow) dataObject, true); + */ } /** @@ -222,28 +221,39 @@ public class FlowConsumerImpl implements IForwardingRulesManager { private void removeFlow(InstanceIdentifier path, Flow dataObject) { RemoveFlowInputBuilder input = new RemoveFlowInputBuilder(); - List inst = (dataObject).getInstructions().getInstruction(); input.setNode((dataObject).getNode()); input.setPriority((dataObject).getPriority()); input.setMatch((dataObject).getMatch()); input.setCookie((dataObject).getCookie()); input.setInstructions((dataObject).getInstructions()); - dataObject.getMatch().getLayer3Match(); - for (int i = 0; i < inst.size(); i++) { - System.out.println("i = " + i + inst.get(i).getInstruction().toString()); - System.out.println("i = " + i + inst.get(i).toString()); - } - - System.out.println("Instruction list" + (dataObject).getInstructions().getInstruction().toString()); - + input.setBufferId(dataObject.getBufferId()); + input.setTableId(dataObject.getTableId()); + input.setOutPort(dataObject.getOutPort()); + input.setOutGroup(dataObject.getOutGroup()); + input.setIdleTimeout(dataObject.getIdleTimeout()); + input.setHardTimeout(dataObject.getHardTimeout()); + input.setFlowName(dataObject.getFlowName()); + input.setFlags(dataObject.getFlags()); + input.setCookieMask(dataObject.getCookieMask()); + input.setContainerName(dataObject.getContainerName()); + input.setBarrier(dataObject.isBarrier()); + input.setInstallHw(dataObject.isInstallHw()); + input.setStrict(dataObject.isStrict()); // updating the staticflow cache - Integer ordinal = staticFlowsOrdinal.get(0); - staticFlowsOrdinal.put(0, ++ordinal); - staticFlows.put(ordinal, dataObject); + /* + * Commented out due to problems caused by improper use of + * ClusteringServices Integer ordinal = staticFlowsOrdinal.get(0); + * staticFlowsOrdinal.put(0, ++ordinal); staticFlows.put(ordinal, + * dataObject); + */ // We send flow to the sounthbound plugin flowService.removeFlow(input.build()); - updateLocalDatabase((NodeFlow) dataObject, false); + + /* + * Commented out due to problems caused by improper use of + * ClusteringServices updateLocalDatabase((NodeFlow) dataObject, false); + */ } /** @@ -257,33 +267,79 @@ public class FlowConsumerImpl implements IForwardingRulesManager { UpdateFlowInputBuilder input = new UpdateFlowInputBuilder(); UpdatedFlowBuilder updatedflowbuilder = new UpdatedFlowBuilder(); updatedflowbuilder.fieldsFrom(dataObject); + input.setNode(dataObject.getNode()); input.setUpdatedFlow(updatedflowbuilder.build()); // updating the staticflow cache - Integer ordinal = staticFlowsOrdinal.get(0); - staticFlowsOrdinal.put(0, ++ordinal); - staticFlows.put(ordinal, dataObject); + /* + * Commented out due to problems caused by improper use of + * ClusteringServices. Integer ordinal = staticFlowsOrdinal.get(0); + * staticFlowsOrdinal.put(0, ++ordinal); staticFlows.put(ordinal, + * dataObject); + */ // We send flow to the sounthbound plugin flowService.updateFlow(input.build()); - updateLocalDatabase((NodeFlow) dataObject, true); + + /* + * Commented out due to problems caused by improper use of + * ClusteringServices. updateLocalDatabase((NodeFlow) dataObject, true); + */ } @SuppressWarnings("unchecked") private void commitToPlugin(internalTransaction transaction) { - for (Entry, Flow> entry : transaction.additions.entrySet()) { - System.out.println("Coming add cc in FlowDatacommitHandler"); - addFlow(entry.getKey(), entry.getValue()); + Set, DataObject>> createdEntries = transaction.getModification() + .getCreatedConfigurationData().entrySet(); + + /* + * This little dance is because updatedEntries contains both created and + * modified entries The reason I created a new HashSet is because the + * collections we are returned are immutable. + */ + Set, DataObject>> updatedEntries = new HashSet, DataObject>>(); + updatedEntries.addAll(transaction.getModification().getUpdatedConfigurationData().entrySet()); + updatedEntries.removeAll(createdEntries); + + Set> removeEntriesInstanceIdentifiers = transaction.getModification() + .getRemovedConfigurationData(); + transaction.getModification().getOriginalConfigurationData(); + for (Entry, DataObject> entry : createdEntries) { + if (entry.getValue() instanceof Flow) { + logger.debug("Coming add cc in FlowDatacommitHandler"); + Flow flow = (Flow) entry.getValue(); + boolean status = validate(flow); + if (!status) { + return; + } + addFlow(entry.getKey(), (Flow) entry.getValue()); + } } for (@SuppressWarnings("unused") - Entry, Flow> entry : transaction.updates.entrySet()) { - System.out.println("Coming update cc in FlowDatacommitHandler"); - updateFlow(entry.getKey(), entry.getValue()); + Entry, DataObject> entry : updatedEntries) { + if (entry.getValue() instanceof Flow) { + logger.debug("Coming update cc in FlowDatacommitHandler"); + Flow flow = (Flow) entry.getValue(); + boolean status = validate(flow); + if (!status) { + return; + } + updateFlow(entry.getKey(), (Flow) entry.getValue()); + } } - for (Entry, Flow> entry : transaction.removals.entrySet()) { - System.out.println("Coming remove cc in FlowDatacommitHandler"); - removeFlow(entry.getKey(), entry.getValue()); + for (InstanceIdentifier instanceId : removeEntriesInstanceIdentifiers) { + DataObject removeValue = transaction.getModification().getOriginalConfigurationData().get(instanceId); + if (removeValue instanceof Flow) { + logger.debug("Coming remove cc in FlowDatacommitHandler"); + Flow flow = (Flow) removeValue; + boolean status = validate(flow); + if (!status) { + return; + } + removeFlow(instanceId, (Flow) removeValue); + + } } } @@ -294,7 +350,7 @@ public class FlowConsumerImpl implements IForwardingRulesManager { @Override public DataCommitTransaction requestCommit(DataModification, DataObject> modification) { // We should verify transaction - System.out.println("Coming in FlowDatacommitHandler"); + logger.debug("Coming in FlowDatacommitHandler"); internalTransaction transaction = new internalTransaction(modification); transaction.prepareUpdate(); return transaction; @@ -327,41 +383,6 @@ public class FlowConsumerImpl implements IForwardingRulesManager { Set, DataObject>> puts = modification.getUpdatedConfigurationData().entrySet(); for (Entry, DataObject> entry : puts) { - - // validating the DataObject - - Status status = validate(container, (NodeFlow) entry); - if (!status.isSuccess()) { - logger.warn("Invalid Configuration for flow {}. The failure is {}", entry, status.getDescription()); - String error = "Invalid Configuration (" + status.getDescription() + ")"; - logger.error(error); - return; - } - // Presence check - if (flowEntryExists((NodeFlow) entry)) { - String error = "Entry with this name on specified table already exists"; - logger.warn("Entry with this name on specified table already exists: {}", entry); - logger.error(error); - return; - } - if (originalSwView.containsKey(entry)) { - logger.warn("Operation Rejected: A flow with same match and priority exists on the target node"); - logger.trace("Aborting to install {}", entry); - continue; - } - if (!FRMUtil.validateMatch((NodeFlow) entry)) { - logger.error("Not a valid Match"); - return; - } - if (!FRMUtil.validateInstructions((NodeFlow) entry)) { - logger.error("Not a valid Instruction"); - return; - } - if (entry.getValue() instanceof Flow) { - Flow flow = (Flow) entry.getValue(); - preparePutEntry(entry.getKey(), flow); - } - } // removals = modification.getRemovedConfigurationData(); @@ -379,11 +400,9 @@ public class FlowConsumerImpl implements IForwardingRulesManager { Flow original = originalSwView.get(key); if (original != null) { // It is update for us - System.out.println("Coming update in FlowDatacommitHandler"); updates.put(key, flow); } else { // It is addition for us - System.out.println("Coming add in FlowDatacommitHandler"); additions.put(key, flow); } } @@ -398,7 +417,7 @@ public class FlowConsumerImpl implements IForwardingRulesManager { commitToPlugin(this); // We return true if internal transaction is successful. // return Rpcs.getRpcResult(true, null, Collections.emptySet()); - return Rpcs.getRpcResult(true, null, null); + return Rpcs.getRpcResult(true, null, Collections. emptySet()); } /** @@ -411,58 +430,15 @@ public class FlowConsumerImpl implements IForwardingRulesManager { // NOOP - we did not modified any internal state during // requestCommit phase // return Rpcs.getRpcResult(true, null, Collections.emptySet()); - return Rpcs.getRpcResult(true, null, null); + return Rpcs.getRpcResult(true, null, Collections. emptySet()); } - public Status validate(IContainer container, NodeFlow dataObject) { - - // container validation - Switch sw = null; - Node node = null; - String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container.getName(); - ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, - containerName, this); - // flow Name validation - if (dataObject.getFlowName() == null || dataObject.getFlowName().trim().isEmpty() - || !dataObject.getFlowName().matches(NAMEREGEX)) { - return new Status(StatusCode.BADREQUEST, "Invalid Flow name"); - } - // Node Validation - if (dataObject.getNode() == null) { - return new Status(StatusCode.BADREQUEST, "Node is null"); - } - - if (switchManager != null) { - for (Switch device : switchManager.getNetworkDevices()) { - node = (Node) device.getNode(); - if (device.getNode().equals(dataObject.getNode())) { - sw = device; - break; - } - } - if (sw == null) { - return new Status(StatusCode.BADREQUEST, String.format("Node %s not found", node)); - } - } else { - logger.debug("switchmanager is not set yet"); - } - - if (dataObject.getPriority() != null) { - if (dataObject.getPriority() < 0 || dataObject.getPriority() > 65535) { - return new Status(StatusCode.BADREQUEST, String.format("priority %s is not in the range 0 - 65535", - dataObject.getPriority())); - } - } - - return new Status(StatusCode.SUCCESS); - } - - private boolean flowEntryExists(NodeFlow config) { + private boolean flowEntryExists(Flow flow) { // Flow name has to be unique on per table id basis for (ConcurrentMap.Entry entry : originalSwView.entrySet()) { - if (entry.getValue().getFlowName().equals(config.getFlowName()) - && entry.getValue().getTableId().equals(config.getTableId())) { + if (entry.getValue().getFlowName().equals(flow.getFlowName()) + && entry.getValue().getTableId().equals(flow.getTableId())) { return true; } } @@ -470,47 +446,6 @@ public class FlowConsumerImpl implements IForwardingRulesManager { } } - final class FlowEventListener implements SalFlowListener { - - List addedFlows = new ArrayList<>(); - List removedFlows = new ArrayList<>(); - List updatedFlows = new ArrayList<>(); - - @Override - public void onFlowAdded(FlowAdded notification) { - System.out.println("added flow.........................."); - addedFlows.add(notification); - } - - @Override - public void onFlowRemoved(FlowRemoved notification) { - removedFlows.add(notification); - }; - - @Override - public void onFlowUpdated(FlowUpdated notification) { - updatedFlows.add(notification); - } - - @Override - public void onSwitchFlowRemoved(SwitchFlowRemoved notification) { - // TODO - } - - @Override - public void onNodeErrorNotification(NodeErrorNotification notification) { - // TODO Auto-generated method stub - - } - - @Override - public void onNodeExperimenterErrorNotification(NodeExperimenterErrorNotification notification) { - // TODO Auto-generated method stub - - }; - - } - // Commented out DataChangeListene - to be used by Stats // final class FlowDataListener implements DataChangeListener { @@ -550,6 +485,60 @@ public class FlowConsumerImpl implements IForwardingRulesManager { // } // } + public boolean validate(Flow flow) { + + String msg = ""; // Specific part of warn/error log + + boolean result = true; + // flow Name validation + if (flow.getFlowName() == null || flow.getFlowName().trim().isEmpty() || !flow.getFlowName().matches(NAMEREGEX)) { + msg = "Invalid Flow name"; + result = false; + } + // Node Validation + if (result == true && flow.getNode() == null) { + msg = "Node is null"; + result = false; + } + + // TODO: Validate we are seeking to program a flow against a valid + // Node + + if (result == true && flow.getPriority() != null) { + if (flow.getPriority() < 0 || flow.getPriority() > 65535) { + msg = String.format("priority %s is not in the range 0 - 65535", flow.getPriority()); + result = false; + } + } + + // Presence check + /* + * This is breaking due to some improper use of caches... + * + * if (flowEntryExists(flow)) { String error = + * "Entry with this name on specified table already exists"; + * logger.warn( + * "Entry with this name on specified table already exists: {}" , + * entry); logger.error(error); return; } if + * (originalSwView.containsKey(entry)) { logger.warn( + * "Operation Rejected: A flow with same match and priority exists on the target node" + * ); logger.trace("Aborting to install {}", entry); continue; } + */ + if (!FRMUtil.validateMatch(flow)) { + logger.error("Not a valid Match"); + result = false; + } + if (!FRMUtil.validateInstructions(flow)) { + logger.error("Not a valid Instruction"); + result = false; + } + if (result == false) { + logger.warn("Invalid Configuration for flow {}. The failure is {}", flow, msg); + logger.error("Invalid Configuration ({})", msg); + } + return result; + } + private static void updateLocalDatabase(NodeFlow entry, boolean add) { updateSwViewes(entry, add);