[Falcon][ONOS-3537] Implement control message collecting logic w/ unit test

Change-Id: Ic21d476a5ad92d7ef739fa3c13dcc06e5cbf7c56
diff --git a/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java b/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java
index b410158..f9a6059 100644
--- a/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java
+++ b/protocols/openflow/ctl/src/main/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImpl.java
@@ -272,10 +272,13 @@
             for (PacketListener p : ofPacketListener.values()) {
                 p.handlePacket(pktCtx);
             }
+            executorMsgs.submit(new OFMessageHandler(dpid, msg));
             break;
         // TODO: Consider using separate threadpool for sensitive messages.
         //    ie. Back to back error could cause us to starve.
         case FLOW_REMOVED:
+            executorMsgs.submit(new OFMessageHandler(dpid, msg));
+            break;
         case ERROR:
             executorMsgs.submit(new OFMessageHandler(dpid, msg));
             break;
@@ -625,6 +628,9 @@
         }
     }
 
+    /**
+     * OpenFlow message handler for incoming control messages.
+     */
     protected final class OFMessageHandler implements Runnable {
 
         protected final OFMessage msg;
@@ -641,7 +647,5 @@
                 listener.handleMessage(dpid, msg);
             }
         }
-
     }
-
 }
diff --git a/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OpenflowSwitchDriverAdapter.java b/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OpenflowSwitchDriverAdapter.java
index 9b899a6..b1b77d8 100644
--- a/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OpenflowSwitchDriverAdapter.java
+++ b/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/OpenflowSwitchDriverAdapter.java
@@ -22,6 +22,7 @@
 import org.onosproject.net.driver.DriverData;
 import org.onosproject.net.driver.DriverHandler;
 import org.onosproject.openflow.controller.Dpid;
+import org.onosproject.openflow.controller.OpenFlowEventListener;
 import org.onosproject.openflow.controller.RoleState;
 import org.onosproject.openflow.controller.driver.OpenFlowAgent;
 import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver;
@@ -299,4 +300,12 @@
     public String channelId() {
         return null;
     }
+
+    @Override
+    public void addEventListener(OpenFlowEventListener listener) {
+    }
+
+    @Override
+    public void removeEventListener(OpenFlowEventListener listener) {
+    }
 }
diff --git a/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/MockOfFlowRemoved.java b/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/MockOfFlowRemoved.java
new file mode 100644
index 0000000..94158ae
--- /dev/null
+++ b/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/MockOfFlowRemoved.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.openflow.controller.impl;
+
+import org.onosproject.openflow.OfMessageAdapter;
+import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
+import org.projectfloodlight.openflow.protocol.OFType;
+import org.projectfloodlight.openflow.protocol.match.Match;
+import org.projectfloodlight.openflow.types.TableId;
+import org.projectfloodlight.openflow.types.U64;
+
+/**
+ * Mock of the Open Flow packet removed message.
+ */
+public class MockOfFlowRemoved extends OfMessageAdapter implements OFFlowRemoved {
+
+    public MockOfFlowRemoved() {
+        super(OFType.FLOW_REMOVED);
+    }
+
+    @Override
+    public U64 getCookie() {
+        return null;
+    }
+
+    @Override
+    public int getPriority() {
+        return 0;
+    }
+
+    @Override
+    public short getReason() {
+        return 0;
+    }
+
+    @Override
+    public TableId getTableId() throws UnsupportedOperationException {
+        return null;
+    }
+
+    @Override
+    public long getDurationSec() {
+        return 0;
+    }
+
+    @Override
+    public long getDurationNsec() {
+        return 0;
+    }
+
+    @Override
+    public int getIdleTimeout() {
+        return 0;
+    }
+
+    @Override
+    public int getHardTimeout() throws UnsupportedOperationException {
+        return 0;
+    }
+
+    @Override
+    public U64 getPacketCount() {
+        return null;
+    }
+
+    @Override
+    public U64 getByteCount() {
+        return null;
+    }
+
+    @Override
+    public Match getMatch() {
+        return null;
+    }
+
+    @Override
+    public OFFlowRemoved.Builder createBuilder() {
+        return null;
+    }
+}
diff --git a/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImplPacketsTest.java b/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImplPacketsTest.java
index 13086ca..bd417bb 100644
--- a/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImplPacketsTest.java
+++ b/protocols/openflow/ctl/src/test/java/org/onosproject/openflow/controller/impl/OpenFlowControllerImplPacketsTest.java
@@ -24,12 +24,12 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.onosproject.openflow.ExecutorServiceAdapter;
-import org.onosproject.openflow.MockOfFeaturesReply;
-import org.onosproject.openflow.MockOfPacketIn;
 import org.onosproject.openflow.MockOfPortStatus;
-import org.onosproject.openflow.OfMessageAdapter;
 import org.onosproject.openflow.OpenFlowSwitchListenerAdapter;
 import org.onosproject.openflow.OpenflowSwitchDriverAdapter;
+import org.onosproject.openflow.MockOfFeaturesReply;
+import org.onosproject.openflow.MockOfPacketIn;
+import org.onosproject.openflow.OfMessageAdapter;
 import org.onosproject.openflow.controller.Dpid;
 import org.onosproject.openflow.controller.OpenFlowPacketContext;
 import org.onosproject.openflow.controller.OpenFlowSwitch;
@@ -143,14 +143,16 @@
     }
 
     /**
-     * Tests a packet in operation.
+     * Tests a packet in listen operation.
      */
     @Test
-    public void testPacketIn() {
+    public void testPacketInListen() {
         agent.addConnectedSwitch(dpid1, switch1);
         OFMessage packetInPacket = new MockOfPacketIn();
         controller.processPacket(dpid1, packetInPacket);
         assertThat(packetListener.contexts(), hasSize(1));
+        assertThat(executorService.submittedMessages(), hasSize(1));
+        assertThat(executorService.submittedMessages().get(0), is(packetInPacket));
     }
 
     /**
@@ -164,4 +166,16 @@
         assertThat(executorService.submittedMessages(), hasSize(1));
         assertThat(executorService.submittedMessages().get(0), is(errorPacket));
     }
+
+    /**
+     * Tests a packet in operation.
+     */
+    @Test
+    public void testFlowRemoved() {
+        agent.addConnectedSwitch(dpid1, switch1);
+        OFMessage flowRemovedPacket = new MockOfFlowRemoved();
+        controller.processPacket(dpid1, flowRemovedPacket);
+        assertThat(executorService.submittedMessages(), hasSize(1));
+        assertThat(executorService.submittedMessages().get(0), is(flowRemovedPacket));
+    }
 }