Moved default flows logic into the PacketManager.

This prevents us duplicating code in each of the apps and allows us to manage
packet requests better in the future.

Change-Id: I5656b2f0f3cecd3e42fe7b4a0a5ab7cb6582bb25
diff --git a/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LLDPLinkProvider.java b/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LLDPLinkProvider.java
index 0169e02..6aefaed 100644
--- a/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LLDPLinkProvider.java
+++ b/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LLDPLinkProvider.java
@@ -15,6 +15,18 @@
  */
 package org.onosproject.provider.lldp.impl;
 
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static org.onlab.util.Tools.namedThreads;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.EnumSet;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
@@ -35,17 +47,13 @@
 import org.onosproject.net.device.DeviceEvent;
 import org.onosproject.net.device.DeviceListener;
 import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.flow.DefaultFlowRule;
 import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleService;
 import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.link.LinkProvider;
 import org.onosproject.net.link.LinkProviderRegistry;
 import org.onosproject.net.link.LinkProviderService;
 import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketPriority;
 import org.onosproject.net.packet.PacketProcessor;
 import org.onosproject.net.packet.PacketService;
 import org.onosproject.net.provider.AbstractProvider;
@@ -57,18 +65,6 @@
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 
-import java.io.IOException;
-import java.util.Dictionary;
-import java.util.EnumSet;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
-import static org.onlab.util.Tools.namedThreads;
-import static org.slf4j.LoggerFactory.getLogger;
-
 
 /**
  * Provider which uses an OpenFlow controller to detect network
@@ -85,15 +81,10 @@
 
     private final Logger log = getLogger(getClass());
 
-    private static final int FLOW_RULE_PRIORITY = 40000;
-
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected CoreService coreService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected FlowRuleService flowRuleService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected LinkProviderRegistry providerRegistry;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -174,7 +165,7 @@
         executor.scheduleAtFixedRate(new SyncDeviceInfoTask(), INIT_DELAY,
                 DELAY, TimeUnit.SECONDS);
 
-        pushRules();
+        requestPackets();
 
         log.info("Started");
     }
@@ -233,48 +224,20 @@
         // should refresh discoverers when we need dynamic reconfiguration
     }
 
-    /**
-     * Pushes flow rules to all devices.
-     */
-    private void pushRules() {
-        for (Device device : deviceService.getDevices()) {
-            pushRules(device);
+    private void requestPackets() {
+        TrafficSelector.Builder lldpSelector = DefaultTrafficSelector.builder();
+        lldpSelector.matchEthType(Ethernet.TYPE_LLDP);
+        packetSevice.requestPackets(lldpSelector.build(),
+                                    PacketPriority.CONTROL, appId);
+
+        if (useBDDP) {
+            TrafficSelector.Builder bddpSelector = DefaultTrafficSelector.builder();
+            bddpSelector.matchEthType(Ethernet.TYPE_BSN);
+            packetSevice.requestPackets(bddpSelector.build(),
+                                        PacketPriority.CONTROL, appId);
         }
     }
 
-    /**
-     * Pushes flow rules to the device to receive control packets that need
-     * to be processed.
-     *
-     * @param device the device to push the rules to
-     */
-    private synchronized void pushRules(Device device) {
-        TrafficSelector.Builder sbuilder;
-        TrafficTreatment.Builder tbuilder;
-
-        // Get all LLDP packets
-        sbuilder = DefaultTrafficSelector.builder();
-        tbuilder = DefaultTrafficTreatment.builder();
-        sbuilder.matchEthType(Ethernet.TYPE_LLDP);
-        tbuilder.punt();
-        FlowRule flowLldp =
-            new DefaultFlowRule(device.id(),
-                                sbuilder.build(), tbuilder.build(),
-                                FLOW_RULE_PRIORITY, appId, 0, true);
-
-        // Get all BDDP packets
-        sbuilder = DefaultTrafficSelector.builder();
-        tbuilder = DefaultTrafficTreatment.builder();
-        sbuilder.matchEthType(Ethernet.TYPE_BSN);
-        tbuilder.punt();
-        FlowRule flowBddp =
-            new DefaultFlowRule(device.id(),
-                                sbuilder.build(), tbuilder.build(),
-                                FLOW_RULE_PRIORITY, appId, 0, true);
-
-        flowRuleService.applyFlowRules(flowLldp, flowBddp);
-    }
-
     private class InternalRoleListener implements MastershipListener {
 
         @Override
@@ -323,8 +286,6 @@
             final DeviceId deviceId = device.id();
             switch (event.type()) {
                 case DEVICE_ADDED:
-                    pushRules(device);
-                    // FALLTHROUGH
                 case DEVICE_UPDATED:
                     synchronized (discoverers) {
                         ld = discoverers.get(deviceId);
diff --git a/providers/lldp/src/test/java/org/onosproject/provider/lldp/impl/LLDPLinkProviderTest.java b/providers/lldp/src/test/java/org/onosproject/provider/lldp/impl/LLDPLinkProviderTest.java
index 6da1716..ce5e048 100644
--- a/providers/lldp/src/test/java/org/onosproject/provider/lldp/impl/LLDPLinkProviderTest.java
+++ b/providers/lldp/src/test/java/org/onosproject/provider/lldp/impl/LLDPLinkProviderTest.java
@@ -15,19 +15,28 @@
  */
 package org.onosproject.provider.lldp.impl;
 
-import static org.easymock.EasyMock.anyObject;
 import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
 import static org.easymock.EasyMock.replay;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
+import java.nio.ByteBuffer;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.onlab.packet.ChassisId;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.ONOSLLDP;
 import org.onosproject.cluster.NodeId;
 import org.onosproject.cluster.RoleInfo;
 import org.onosproject.core.ApplicationId;
@@ -46,8 +55,7 @@
 import org.onosproject.net.device.DeviceEvent;
 import org.onosproject.net.device.DeviceListener;
 import org.onosproject.net.device.DeviceServiceAdapter;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.link.LinkDescription;
 import org.onosproject.net.link.LinkProvider;
@@ -57,22 +65,15 @@
 import org.onosproject.net.packet.InboundPacket;
 import org.onosproject.net.packet.OutboundPacket;
 import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketPriority;
 import org.onosproject.net.packet.PacketProcessor;
 import org.onosproject.net.packet.PacketService;
 import org.onosproject.net.provider.AbstractProviderService;
 import org.onosproject.net.provider.ProviderId;
-import org.onlab.packet.ChassisId;
-import org.onlab.packet.Ethernet;
-import org.onlab.packet.ONOSLLDP;
 
-import java.nio.ByteBuffer;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static org.junit.Assert.*;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 
 public class LLDPLinkProviderTest {
 
@@ -91,7 +92,6 @@
     private final TestMasterShipService masterService = new TestMasterShipService();
 
     private CoreService coreService;
-    private FlowRuleService flowRuleService;
     private TestLinkProviderService providerService;
 
     private PacketProcessor testProcessor;
@@ -108,14 +108,7 @@
             .andReturn(appId).anyTimes();
         replay(coreService);
 
-        flowRuleService = createMock(FlowRuleService.class);
-        flowRuleService.applyFlowRules(anyObject(FlowRule.class),
-                                       anyObject(FlowRule.class));
-        expectLastCall().anyTimes();
-        replay(flowRuleService);
-
         provider.coreService = coreService;
-        provider.flowRuleService = flowRuleService;
 
         provider.deviceService = deviceService;
         provider.packetSevice = packetService;
@@ -208,7 +201,6 @@
     public void tearDown() {
         provider.deactivate();
         provider.coreService = null;
-        provider.flowRuleService = null;
         provider.providerRegistry = null;
         provider.deviceService = null;
         provider.packetSevice = null;
@@ -403,6 +395,11 @@
         public void emit(OutboundPacket packet) {
 
         }
+
+        @Override
+        public void requestPackets(TrafficSelector selector,
+                                   PacketPriority priority, ApplicationId appId) {
+        }
     }
 
     private class TestDeviceService extends DeviceServiceAdapter {