Offload packet processing to another thread

Also update unit tests

Change-Id: Ib94c796083e2d75912f77667d3cfe4ed794694e9
diff --git a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java
index 90c58b7..08ba908 100644
--- a/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java
+++ b/apps/dhcprelay/app/src/main/java/org/onosproject/dhcprelay/DhcpRelayManager.java
@@ -109,8 +109,9 @@
 @Service
 public class DhcpRelayManager implements DhcpRelayService {
     public static final String DHCP_RELAY_APP = "org.onosproject.dhcprelay";
-    public static final String ROUTE_STORE_IMPL =
-            "org.onosproject.routeservice.store.RouteStoreImpl";
+    public static final String ROUTE_STORE_IMPL = "org.onosproject.routeservice.store.RouteStoreImpl";
+
+    private static final int DEFAULT_POOL_SIZE = 32;
 
     private static final TrafficSelector ARP_SELECTOR = DefaultTrafficSelector.builder()
             .matchEthType(Ethernet.TYPE_ARP)
@@ -207,6 +208,7 @@
 
     private ScheduledExecutorService timerExecutor;
     protected ExecutorService devEventExecutor;
+    private ExecutorService packetExecutor;
 
     protected DeviceListener deviceListener = new InternalDeviceListener();
     private DhcpRelayPacketProcessor dhcpRelayPacketProcessor = new DhcpRelayPacketProcessor();
@@ -236,12 +238,10 @@
         packetService.addProcessor(dhcpRelayPacketProcessor, PacketProcessor.director(0));
 
         timerExecutor = Executors.newScheduledThreadPool(1,
-                groupedThreads("dhcpRelay",
-                        "config-reloader-%d", log));
-        timerExecutor.scheduleAtFixedRate(new Dhcp6Timer(),
-                0,
-                dhcpPollInterval,
-                TimeUnit.SECONDS);
+                groupedThreads("onos/dhcprelay", "config-reloader-%d", log));
+        timerExecutor.scheduleAtFixedRate(new Dhcp6Timer(), 0, dhcpPollInterval, TimeUnit.SECONDS);
+        packetExecutor = Executors.newFixedThreadPool(DEFAULT_POOL_SIZE,
+                groupedThreads("onos/dhcprelay", "packet-%d", log));
 
         devEventExecutor = newSingleThreadScheduledExecutor(
                              groupedThreads("onos/dhcprelay-dev-events", "events-%d", log));
@@ -255,8 +255,6 @@
 
         deviceService.addListener(deviceListener);
 
-
-
         log.info("DHCP-RELAY Started");
     }
 
@@ -271,6 +269,9 @@
         timerExecutor.shutdown();
         devEventExecutor.shutdownNow();
         devEventExecutor = null;
+        packetExecutor.shutdown();
+        timerExecutor = null;
+        packetExecutor = null;
 
         log.info("DHCP-RELAY Stopped");
     }
@@ -497,9 +498,12 @@
 
 
     private class DhcpRelayPacketProcessor implements PacketProcessor {
-
         @Override
         public void process(PacketContext context) {
+            packetExecutor.execute(() -> processInternal(context));
+        }
+
+        private void processInternal(PacketContext context) {
             // process the packet and get the payload
             Ethernet packet = context.inPacket().parsed();
             if (packet == null) {