Revert "Checkstyle enforcer"
[controller.git] / opendaylight / sal / implementation / src / main / java / org / opendaylight / controller / sal / implementation / internal / FlowProgrammerService.java
index d2a49b9208fac68118ca27e70086ef9b0f59738a..6bea30666925ddaf4991f819597fde625766026f 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
@@ -11,10 +10,13 @@ package org.opendaylight.controller.sal.implementation.internal;
 
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.eclipse.osgi.framework.console.CommandInterpreter;
 import org.eclipse.osgi.framework.console.CommandProvider;
@@ -26,53 +28,64 @@ import org.opendaylight.controller.sal.action.PopVlan;
 import org.opendaylight.controller.sal.action.SetNwDst;
 import org.opendaylight.controller.sal.core.ConstructionException;
 import org.opendaylight.controller.sal.core.Node;
-import org.opendaylight.controller.sal.core.NodeConnector;
 import org.opendaylight.controller.sal.core.Node.NodeIDType;
+import org.opendaylight.controller.sal.core.NodeConnector;
 import org.opendaylight.controller.sal.flowprogrammer.Flow;
+import org.opendaylight.controller.sal.flowprogrammer.IFlowProgrammerListener;
 import org.opendaylight.controller.sal.flowprogrammer.IFlowProgrammerService;
 import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService;
+import org.opendaylight.controller.sal.flowprogrammer.IPluginOutFlowProgrammerService;
 import org.opendaylight.controller.sal.match.Match;
 import org.opendaylight.controller.sal.match.MatchType;
-import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.controller.sal.utils.EtherTypes;
 import org.opendaylight.controller.sal.utils.IPProtocols;
 import org.opendaylight.controller.sal.utils.NodeConnectorCreator;
 import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * The SAL Flow Programmer Service. It dispatches the flow programming
- * requests to the proper SDN protocol plugin
- *
- *
- *
+ * The SAL Flow Programmer Service. It dispatches the flow programming requests
+ * to the proper SDN protocol plugin and it notifies about asynchronous messages
+ * received from the network node related to flow programming.
  */
 public class FlowProgrammerService implements IFlowProgrammerService,
-        CommandProvider {
+        IPluginOutFlowProgrammerService, CommandProvider {
 
     protected static final Logger logger = LoggerFactory
             .getLogger(FlowProgrammerService.class);
-    private ConcurrentHashMap<String, IPluginInFlowProgrammerService>
-        pluginFlowProgrammer =
-        new ConcurrentHashMap<String, IPluginInFlowProgrammerService>();
+    private ConcurrentHashMap<String, IPluginInFlowProgrammerService> pluginFlowProgrammer;
+    private Set<IFlowProgrammerListener> listener;
+    private AtomicLong seq;
+
+    public FlowProgrammerService() {
+        pluginFlowProgrammer = new ConcurrentHashMap<String, IPluginInFlowProgrammerService>();
+        listener = new HashSet<IFlowProgrammerListener>();
+        seq = new AtomicLong();
+        /*
+         * This Request ID generator starts with 1. Each aysnc message is
+         * associated with an unique Request ID (!= 0).
+         */
+        seq.lazySet(1);
+    }
 
     /**
      * Function called by the dependency manager when all the required
      * dependencies are satisfied
-     *
+     * 
      */
     void init() {
         logger.debug("INIT called!");
     }
 
     /**
-     * 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.
-     *
+     * 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() {
         // Clear previous registration to avoid they are left hanging
@@ -81,10 +94,9 @@ public class FlowProgrammerService implements IFlowProgrammerService,
     }
 
     /**
-     * Function called by dependency manager after "init ()" is called
-     * and after the services provided by the class are registered in
-     * the service registry
-     *
+     * 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() {
         logger.debug("START called!");
@@ -93,10 +105,10 @@ public class FlowProgrammerService implements IFlowProgrammerService,
     }
 
     /**
-     * Function called by the dependency manager before the services
-     * exported by the component are unregistered, this will be
-     * followed by a "destroy ()" calls
-     *
+     * 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() {
         logger.debug("STOP called!");
@@ -113,8 +125,8 @@ public class FlowProgrammerService implements IFlowProgrammerService,
         String type = null;
         for (Object e : props.entrySet()) {
             Map.Entry entry = (Map.Entry) e;
-            logger.trace("Prop key:({}) value:({})",entry.getKey(),
-                         entry.getValue());
+            logger.trace("Prop key:({}) value:({})", entry.getKey(),
+                    entry.getValue());
         }
 
         Object value = props.get("protocolPluginType");
@@ -126,12 +138,11 @@ public class FlowProgrammerService implements IFlowProgrammerService,
                     + "protocolPluginType provided");
         } else {
             this.pluginFlowProgrammer.put(type, s);
-            logger.debug("Stored the pluginFlowProgrammer for type: {}",type);
+            logger.debug("Stored the pluginFlowProgrammer for type: {}", type);
         }
     }
 
-    public void unsetService(Map props,
-                             IPluginInFlowProgrammerService s) {
+    public void unsetService(Map props, IPluginInFlowProgrammerService s) {
         if (this.pluginFlowProgrammer == null) {
             logger.error("pluginFlowProgrammer store null");
             return;
@@ -141,8 +152,8 @@ public class FlowProgrammerService implements IFlowProgrammerService,
         logger.debug("Received unsetpluginFlowProgrammer request");
         for (Object e : props.entrySet()) {
             Map.Entry entry = (Map.Entry) e;
-            logger.trace("Prop key:({}) value:({})",entry.getKey(),
-                       entry.getValue());
+            logger.trace("Prop key:({}) value:({})", entry.getKey(),
+                    entry.getValue());
         }
 
         Object value = props.get("protocoloPluginType");
@@ -158,12 +169,20 @@ public class FlowProgrammerService implements IFlowProgrammerService,
         }
     }
 
+    public void setListener(IFlowProgrammerListener s) {
+        this.listener.add(s);
+    }
+
+    public void unsetListener(IFlowProgrammerListener s) {
+        this.listener.remove(s);
+    }
+
     @Override
     public Status addFlow(Node node, Flow flow) {
         if (pluginFlowProgrammer != null) {
             if (this.pluginFlowProgrammer.get(node.getType()) != null) {
-                return this.pluginFlowProgrammer.get(node.getType())
-                    .addFlow(node, flow);
+                return this.pluginFlowProgrammer.get(node.getType()).addFlow(
+                        node, flow);
             }
         }
         return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
@@ -174,7 +193,7 @@ public class FlowProgrammerService implements IFlowProgrammerService,
         if (pluginFlowProgrammer != null) {
             if (this.pluginFlowProgrammer.get(node.getType()) != null) {
                 return this.pluginFlowProgrammer.get(node.getType())
-                    .removeFlow(node, flow);
+                        .removeFlow(node, flow);
             }
         }
         return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
@@ -185,7 +204,7 @@ public class FlowProgrammerService implements IFlowProgrammerService,
         if (pluginFlowProgrammer != null) {
             if (this.pluginFlowProgrammer.get(node.getType()) != null) {
                 return this.pluginFlowProgrammer.get(node.getType())
-                    .removeAllFlows(node);
+                        .removeAllFlows(node);
             }
         }
         return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
@@ -196,12 +215,62 @@ public class FlowProgrammerService implements IFlowProgrammerService,
         if (pluginFlowProgrammer != null) {
             if (this.pluginFlowProgrammer.get(node.getType()) != null) {
                 return this.pluginFlowProgrammer.get(node.getType())
-                    .modifyFlow(node, oldFlow, newFlow);
+                        .modifyFlow(node, oldFlow, newFlow);
+            }
+        }
+        return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
+    }
+
+    @Override
+    public Status addFlowAsync(Node node, Flow flow) {
+        if (pluginFlowProgrammer != null) {
+            if (this.pluginFlowProgrammer.get(node.getType()) != null) {
+                return this.pluginFlowProgrammer.get(node.getType()).addFlowAsync(
+                        node, flow, getNextRid());
+            }
+        }
+        return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
+    }
+
+    @Override
+    public Status removeFlowAsync(Node node, Flow flow) {
+        if (pluginFlowProgrammer != null) {
+            if (this.pluginFlowProgrammer.get(node.getType()) != null) {
+                return this.pluginFlowProgrammer.get(node.getType())
+                        .removeFlowAsync(node, flow, getNextRid());
+            }
+        }
+        return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
+    }
+
+    @Override
+    public Status modifyFlowAsync(Node node, Flow oldFlow, Flow newFlow) {
+        if (pluginFlowProgrammer != null) {
+            if (this.pluginFlowProgrammer.get(node.getType()) != null) {
+                return this.pluginFlowProgrammer.get(node.getType())
+                        .modifyFlowAsync(node, oldFlow, newFlow, getNextRid());
             }
         }
         return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
     }
 
+    @Override
+    public void flowRemoved(Node node, Flow flow) {
+        for (IFlowProgrammerListener l : listener) {
+            l.flowRemoved(node, flow);
+        }
+    }
+
+    @Override
+    public void flowErrorReported(Node node, long rid, Object err) {
+        logger.error("Got error {} for message rid {} from node {}",
+                new Object[] { err, rid, node });
+
+        for (IFlowProgrammerListener l : listener) {
+            l.flowErrorReported(node, rid, err);
+        }
+    }
+
     // ---------------- OSGI TEST CODE ------------------------------//
 
     private void registerWithOSGIConsole() {
@@ -215,10 +284,8 @@ public class FlowProgrammerService implements IFlowProgrammerService,
     public String getHelp() {
         StringBuffer help = new StringBuffer();
         help.append("---SAL Flow Programmer testing commands---\n");
-        help
-                .append("\t addflow <sid> - Add a sample flow to the openflow switch <sid>\n");
-        help
-                .append("\t removeflow <sid> - Remove the sample flow from the openflow switch <sid>\n");
+        help.append("\t addflow <sid> - Add a sample flow to the openflow switch <sid>\n");
+        help.append("\t removeflow <sid> - Remove the sample flow from the openflow switch <sid>\n");
         return help.toString();
     }
 
@@ -232,13 +299,13 @@ public class FlowProgrammerService implements IFlowProgrammerService,
         try {
             node = new Node(NodeIDType.OPENFLOW, Long.valueOf(nodeId));
         } catch (NumberFormatException e) {
-            e.printStackTrace();
+            logger.error("",e);
         } catch (ConstructionException e) {
-            e.printStackTrace();
+            logger.error("",e);
         }
         ci.println(this.addFlow(node, getSampleFlow(node)));
     }
-
+    
     public void _modifyflow(CommandInterpreter ci) throws UnknownHostException {
         Node node = null;
         String nodeId = ci.nextArgument();
@@ -249,15 +316,15 @@ public class FlowProgrammerService implements IFlowProgrammerService,
         try {
             node = new Node(NodeIDType.OPENFLOW, Long.valueOf(nodeId));
         } catch (NumberFormatException e) {
-            e.printStackTrace();
+            logger.error("",e);
         } catch (ConstructionException e) {
-            e.printStackTrace();
+            logger.error("",e);
         }
         Flow flowA = getSampleFlow(node);
         Flow flowB = getSampleFlow(node);
         Match matchB = flowB.getMatch();
-        matchB.setField(MatchType.NW_DST, InetAddress
-                .getByName("190.190.190.190"));
+        matchB.setField(MatchType.NW_DST,
+                InetAddress.getByName("190.190.190.190"));
         flowB.setMatch(matchB);
         ci.println(this.modifyFlow(node, flowA, flowB));
     }
@@ -272,9 +339,9 @@ public class FlowProgrammerService implements IFlowProgrammerService,
         try {
             node = new Node(NodeIDType.OPENFLOW, Long.valueOf(nodeId));
         } catch (NumberFormatException e) {
-            e.printStackTrace();
+            logger.error("",e);
         } catch (ConstructionException e) {
-            e.printStackTrace();
+            logger.error("",e);
         }
         ci.println(this.removeFlow(node, getSampleFlow(node)));
     }
@@ -289,9 +356,9 @@ public class FlowProgrammerService implements IFlowProgrammerService,
         try {
             node = new Node(NodeIDType.OPENFLOW, Long.valueOf(nodeId));
         } catch (NumberFormatException e) {
-            e.printStackTrace();
+            logger.error("",e);
         } catch (ConstructionException e) {
-            e.printStackTrace();
+            logger.error("",e);
         }
         ci.println(this.addFlow(node, getSampleFlowV6(node)));
     }
@@ -307,9 +374,9 @@ public class FlowProgrammerService implements IFlowProgrammerService,
         try {
             node = new Node(NodeIDType.OPENFLOW, Long.valueOf(nodeId));
         } catch (NumberFormatException e) {
-            e.printStackTrace();
+            logger.error("",e);
         } catch (ConstructionException e) {
-            e.printStackTrace();
+            logger.error("",e);
         }
         ci.println(this.removeFlow(node, getSampleFlowV6(node)));
     }
@@ -380,15 +447,17 @@ public class FlowProgrammerService implements IFlowProgrammerService,
                 .getByName("2001:420:281:1004:407a:57f4:4d15:c355");
         InetAddress dstIP = InetAddress
                 .getByName("2001:420:281:1004:e123:e688:d655:a1b0");
-        InetAddress ipMask = null; //InetAddress.getByName("ffff:ffff:ffff:ffff:0:0:0:0"); V6Match implementation assumes no mask is specified
-        InetAddress ipMask2 = null; //InetAddress.getByName("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0");
+        InetAddress ipMask = null; // InetAddress.getByName("ffff:ffff:ffff:ffff:0:0:0:0");
+                                   // V6Match implementation assumes no mask is
+                                   // specified
+        InetAddress ipMask2 = null; // InetAddress.getByName("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0");
         short ethertype = EtherTypes.IPv6.shortValue();
         short vlan = (short) 27;
         byte vlanPr = (byte) 3;
         Byte tos = 4;
         byte proto = IPProtocols.UDP.byteValue();
         short src = (short) 5500;
-        //short dst = 80;
+        // short dst = 80;
 
         /*
          * Create a SAL Flow aFlow
@@ -399,13 +468,16 @@ public class FlowProgrammerService implements IFlowProgrammerService,
         match.setField(MatchType.DL_DST, dstMac);
         match.setField(MatchType.DL_TYPE, ethertype);
         match.setField(MatchType.DL_VLAN, vlan);
-        match.setField(MatchType.DL_VLAN_PR, vlanPr); //V6Match does not handle this properly...
+        match.setField(MatchType.DL_VLAN_PR, vlanPr); // V6Match does not handle
+                                                      // this properly...
         match.setField(MatchType.NW_SRC, srcIP, ipMask);
         match.setField(MatchType.NW_DST, dstIP, ipMask2);
         match.setField(MatchType.NW_TOS, tos);
         match.setField(MatchType.NW_PROTO, proto);
-        match.setField(MatchType.TP_SRC, src); //V6Match does not handle this properly...
-        //match.setField(MatchType.TP_DST, dst); V6Match does not handle this properly...
+        match.setField(MatchType.TP_SRC, src); // V6Match does not handle this
+                                               // properly...
+        // match.setField(MatchType.TP_DST, dst); V6Match does not handle this
+        // properly...
 
         List<Action> actions = new ArrayList<Action>();
         actions.add(new Output(oport));
@@ -418,4 +490,36 @@ public class FlowProgrammerService implements IFlowProgrammerService,
 
         return flow;
     }
+
+    /**
+     * This Request ID generator starts with 1. Each aysnc message is
+     * associated with an unique Request ID (!= 0).
+     * 
+     * @return Request ID
+     */
+    private long getNextRid() {
+        return seq.getAndIncrement();
+    }
+
+    @Override
+    public Status syncSendBarrierMessage(Node node) {
+        if (this.pluginFlowProgrammer != null) {
+            if (this.pluginFlowProgrammer.get(node.getType()) != null) {
+                return this.pluginFlowProgrammer.get(node.getType())
+                        .syncSendBarrierMessage(node);
+            }
+        }
+        return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
+    }
+
+    @Override
+    public Status asyncSendBarrierMessage(Node node) {
+        if (this.pluginFlowProgrammer != null) {
+            if (this.pluginFlowProgrammer.get(node.getType()) != null) {
+                return this.pluginFlowProgrammer.get(node.getType())
+                        .asyncSendBarrierMessage(node);
+            }
+        }
+        return new Status(StatusCode.NOSERVICE, "Plugin unuvailable");
+    }
 }