[ONOS-5267] Rewrite LISP bootstrap class to use UDP rather than TCP

- Try to use MessageToMessageDecoder to decode DatagramPacket
- Use Bootstrap instead of ServerBootstrap in a way to use UDP
- Add a dummy LispController interface
- Remove unnecessary handlers from LispChannelInitializer
- Rename LispController to LispControllerBootstrap

Change-Id: I7d930f46ffb87d88b3449ba78e066d8b1c065093
diff --git a/protocols/lisp/api/src/main/java/org/onosproject/lisp/PlaceHolder.java b/protocols/lisp/api/src/main/java/org/onosproject/lisp/LispController.java
similarity index 79%
rename from protocols/lisp/api/src/main/java/org/onosproject/lisp/PlaceHolder.java
rename to protocols/lisp/api/src/main/java/org/onosproject/lisp/LispController.java
index db06167..d36eae8 100644
--- a/protocols/lisp/api/src/main/java/org/onosproject/lisp/PlaceHolder.java
+++ b/protocols/lisp/api/src/main/java/org/onosproject/lisp/LispController.java
@@ -16,9 +16,9 @@
 package org.onosproject.lisp;
 
 /**
- * Remove me.
+ * Abstraction of a LISP controller. Serves as a one stop shop for obtaining
+ * LISP devices and (un)register listeners on LISP events.
  */
-@Deprecated
-public abstract class PlaceHolder {
+public interface LispController {
 
 }
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispChannelHandler.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispChannelHandler.java
index 1cd8d0b..136831a 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispChannelHandler.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispChannelHandler.java
@@ -39,14 +39,16 @@
 
         if (msg instanceof LispMapRegister) {
             LispMapServer mapServer = new LispMapServer();
-            LispMapNotify mapNotify = (LispMapNotify) mapServer.process((LispMapRegister) msg);
+            LispMapNotify mapNotify =
+                    (LispMapNotify) mapServer.processMapRegister((LispMapRegister) msg);
 
             // TODO: deserialize mapNotify message and write to channel
         }
 
         if (msg instanceof LispMapRequest) {
             LispMapResolver mapResolver = new LispMapResolver();
-            LispMapReply mapReply = (LispMapReply) mapResolver.process((LispMapRequest) msg);
+            LispMapReply mapReply =
+                    (LispMapReply) mapResolver.processMapRequest((LispMapRequest) msg);
 
             // TODO: deserialize mapReply message and write to channel
         }
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispChannelInitializer.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispChannelInitializer.java
index e0b7ab6..c5c8867 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispChannelInitializer.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispChannelInitializer.java
@@ -15,43 +15,30 @@
  */
 package org.onosproject.lisp.ctl;
 
-import io.netty.channel.Channel;
 import io.netty.channel.ChannelInitializer;
 import io.netty.channel.ChannelPipeline;
-import io.netty.handler.timeout.IdleStateHandler;
-import io.netty.handler.timeout.ReadTimeoutHandler;
+import io.netty.channel.socket.nio.NioDatagramChannel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * Creates a ChannelInitializer for a server-side LISP channel.
  */
-public final class LispChannelInitializer extends ChannelInitializer<Channel> {
+public final class LispChannelInitializer extends ChannelInitializer<NioDatagramChannel> {
 
     private final Logger log = LoggerFactory.getLogger(getClass());
-
-    private IdleStateHandler idleHandler;
-    private ReadTimeoutHandler readTimeoutHandler;
-
-    private static final int READER_IDLE_TIME_SECOND = 20;
-    private static final int WRITER_IDLE_TIME_SECOND = 25;
-    private static final int ALL_IDLE_TIME_SECOND = 0;
-    private static final int READ_TIMEOUT_SECOND = 30;
+    private static final String LISP_MESSAGE_DECODER = "lispmessagedecoder";
+    private static final String LISP_MESSAGE_ENCODER = "lispmessageencoder";
+    private static final String LISP_CHANNEL_HANDLER = "handler";
 
     @Override
-    protected void initChannel(Channel channel) throws Exception {
+    protected void initChannel(NioDatagramChannel channel) throws Exception {
         ChannelPipeline pipeline = channel.pipeline();
 
         LispChannelHandler handler = new LispChannelHandler();
 
-        idleHandler = new IdleStateHandler(READER_IDLE_TIME_SECOND,
-                WRITER_IDLE_TIME_SECOND, ALL_IDLE_TIME_SECOND);
-        readTimeoutHandler = new ReadTimeoutHandler(READ_TIMEOUT_SECOND);
-
-        pipeline.addLast("lispmessagedecoder", new LispMessageDecoder());
-        pipeline.addLast("lispmessageencoder", new LispMessageEncoder());
-        pipeline.addLast("idle", idleHandler);
-        pipeline.addLast("readTimeout", readTimeoutHandler);
-        pipeline.addLast("handler", handler);
+        pipeline.addLast(LISP_MESSAGE_DECODER, new LispMessageDecoder());
+        pipeline.addLast(LISP_MESSAGE_ENCODER, new LispMessageEncoder());
+        pipeline.addLast(LISP_CHANNEL_HANDLER, handler);
     }
 }
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispController.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispControllerBootstrap.java
similarity index 74%
rename from protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispController.java
rename to protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispControllerBootstrap.java
index 01c87dbc..b7415c0 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispController.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispControllerBootstrap.java
@@ -17,12 +17,13 @@
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
-import io.netty.bootstrap.ServerBootstrap;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.buffer.PooledByteBufAllocator;
 import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelOption;
 import io.netty.channel.EventLoopGroup;
 import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.channel.socket.nio.NioDatagramChannel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -30,12 +31,11 @@
 import java.util.List;
 
 /**
- * The main LISP controller class.
  * Bootstraps LISP netty channel, handles all setup and network listeners.
  */
-public class LispController {
+public class LispControllerBootstrap {
 
-    protected static final Logger log = LoggerFactory.getLogger(LispController.class);
+    protected static final Logger log = LoggerFactory.getLogger(LispControllerBootstrap.class);
 
     private static final int LISP_DATA_PORT = 4341;
     private static final int LISP_CONTROL_PORT = 4342;
@@ -43,10 +43,7 @@
     // Configuration options
     protected List<Integer> lispPorts = ImmutableList.of(LISP_DATA_PORT, LISP_CONTROL_PORT);
 
-    protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
-
-    private EventLoopGroup bossGroup;
-    private EventLoopGroup workerGroup;
+    private EventLoopGroup eventLoopGroup;
 
     /**
      * Stitches all channel handlers into server bootstrap.
@@ -54,7 +51,7 @@
     public void run() {
 
         try {
-            final ServerBootstrap bootstrap = createServerBootstrap();
+            final Bootstrap bootstrap = createServerBootstrap();
 
             configBootstrapOptions(bootstrap);
 
@@ -80,13 +77,12 @@
      *
      * @return initialized server bootstrap
      */
-    private ServerBootstrap createServerBootstrap() {
-        ServerBootstrap bootstrap = new ServerBootstrap();
-        bossGroup = new NioEventLoopGroup();
-        workerGroup = new NioEventLoopGroup();
-        bootstrap.group(bossGroup, workerGroup)
-                .channel(NioServerSocketChannel.class)
-                .childHandler(new LispChannelInitializer());
+    private Bootstrap createServerBootstrap() {
+        Bootstrap bootstrap = new Bootstrap();
+        eventLoopGroup = new NioEventLoopGroup();
+        bootstrap.group(eventLoopGroup)
+                .channel(NioDatagramChannel.class)
+                .handler(new LispChannelInitializer());
 
         return bootstrap;
     }
@@ -96,10 +92,8 @@
      *
      * @param bootstrap LISP server bootstrap
      */
-    private void configBootstrapOptions(ServerBootstrap bootstrap) {
-        bootstrap.option(ChannelOption.SO_REUSEADDR, true);
-        bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
-        bootstrap.option(ChannelOption.SO_SNDBUF, SEND_BUFFER_SIZE);
+    private void configBootstrapOptions(Bootstrap bootstrap) {
+        bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
     }
 
     /**
@@ -134,8 +128,7 @@
 
         try {
             // try to shutdown all open event groups
-            bossGroup.shutdownGracefully().sync();
-            workerGroup.shutdownGracefully().sync();
+            eventLoopGroup.shutdownGracefully().sync();
         } catch (InterruptedException e) {
             e.printStackTrace();
         }
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispControllerImpl.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispControllerImpl.java
new file mode 100644
index 0000000..502a3b4
--- /dev/null
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispControllerImpl.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2016-present 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.lisp.ctl;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Deactivate;
+
+import org.onosproject.core.CoreService;
+import org.onosproject.lisp.LispController;
+import org.onosproject.net.device.DeviceService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * LISP controller initiation class.
+ */
+@Component(immediate = true)
+@Service
+public class LispControllerImpl implements LispController {
+
+    private static final String APP_ID = "org.onosproject.lisp-base";
+
+    private static final Logger log =
+            LoggerFactory.getLogger(LispControllerImpl.class);
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    private final LispControllerBootstrap bootstrap = new LispControllerBootstrap();
+
+    @Activate
+    public void activate() {
+        coreService.registerApplication(APP_ID);
+        bootstrap.start();
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        bootstrap.stop();
+        log.info("Stopped");
+    }
+}
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMapResolver.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMapResolver.java
index 01b654a..d021a8f 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMapResolver.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMapResolver.java
@@ -21,9 +21,9 @@
  * LISP map resolver class.
  * Handles map-request message and acknowledges with map-reply message.
  */
-public class LispMapResolver implements LispMapSystem {
-    @Override
-    public LispMessage process(LispMessage message) {
+public class LispMapResolver {
+
+    public LispMessage processMapRequest(LispMessage message) {
         // TODO: need to implement map-register message processing logic
         return null;
     }
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMapServer.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMapServer.java
index 145a4bb..409d360 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMapServer.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMapServer.java
@@ -21,9 +21,9 @@
  * LISP map server class.
  * Handles map-register message and acknowledges with map-notify message.
  */
-public class LispMapServer implements LispMapSystem {
-    @Override
-    public LispMessage process(LispMessage message) {
+public class LispMapServer {
+
+    public LispMessage processMapRegister(LispMessage message) {
         // TODO: need to implement map-request message processing logic
         return null;
     }
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMapSystem.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMapSystem.java
deleted file mode 100644
index f321a6d..0000000
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMapSystem.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2016-present 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.lisp.ctl;
-
-import org.onosproject.lisp.msg.protocols.LispMessage;
-
-/**
- * LISP map system interface.
- */
-public interface LispMapSystem {
-
-    /**
-     * Processes incoming LISP message, and results in corresponding LISP message.
-     *
-     * @param message input LISP message
-     * @return output LISP message
-     */
-    LispMessage process(LispMessage message);
-}
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMessageDecoder.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMessageDecoder.java
index 9cc8488..94668d3 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMessageDecoder.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMessageDecoder.java
@@ -17,7 +17,8 @@
 
 import io.netty.buffer.ByteBuf;
 import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.ByteToMessageDecoder;
+import io.netty.channel.socket.DatagramPacket;
+import io.netty.handler.codec.MessageToMessageDecoder;
 import org.onosproject.lisp.msg.protocols.LispMessage;
 import org.onosproject.lisp.msg.protocols.LispMessageReader;
 import org.onosproject.lisp.msg.protocols.LispMessageReaderFactory;
@@ -27,12 +28,12 @@
 /**
  * Decode a LISP message from a ByteBuffer, for use in a netty pipeline.
  */
-public class LispMessageDecoder extends ByteToMessageDecoder {
+public class LispMessageDecoder extends MessageToMessageDecoder<DatagramPacket> {
 
     @Override
-    protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuf,
+    protected void decode(ChannelHandlerContext ctx, DatagramPacket msg,
                           List<Object> list) throws Exception {
-
+        ByteBuf byteBuf = msg.content();
         LispMessageReader reader = LispMessageReaderFactory.getReader(byteBuf);
         LispMessage message = (LispMessage) reader.readFrom(byteBuf);
         list.add(message);
diff --git a/protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/LispMessageDecoderTest.java b/protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/LispMessageDecoderTest.java
index 025181e..5e9be94 100644
--- a/protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/LispMessageDecoderTest.java
+++ b/protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/LispMessageDecoderTest.java
@@ -18,12 +18,14 @@
 import com.google.common.collect.Lists;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
+import io.netty.channel.socket.DatagramPacket;
 import org.junit.Test;
 import org.onosproject.lisp.msg.protocols.LispMapNotify;
 import org.onosproject.lisp.msg.protocols.LispMapRegister;
 import org.onosproject.lisp.msg.protocols.LispMapReply;
 import org.onosproject.lisp.msg.protocols.LispMapRequest;
 
+import java.net.InetSocketAddress;
 import java.util.List;
 
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -114,21 +116,27 @@
         return buffer;
     }
 
+    private DatagramPacket convToDatagram(ByteBuf byteBuf) {
+        InetSocketAddress source = new InetSocketAddress(0);
+        return new DatagramPacket(byteBuf, source);
+    }
+
     @Test(expected = IllegalArgumentException.class)
     public void testDecodeNoChannel() throws Exception {
         LispMessageDecoder decoder = new LispMessageDecoder();
 
         List<Object> list = Lists.newArrayList();
-        decoder.decode(new ChannelHandlerContextAdapter(), Unpooled.buffer(), list);
+        decoder.decode(new ChannelHandlerContextAdapter(),
+                convToDatagram(Unpooled.buffer()), list);
     }
 
     @Test
     public void testDecode() throws Exception {
         LispMessageDecoder decoder = new LispMessageDecoder();
-        ByteBuf requestBuff = getLispMapRequestBuffer();
-        ByteBuf replyBuff = getLispMapReplyBuffer();
-        ByteBuf registerBuff = getLispMapRegisterBuffer();
-        ByteBuf notifyBuff = getLispMapNotifyBuffer();
+        DatagramPacket requestBuff = convToDatagram(getLispMapRequestBuffer());
+        DatagramPacket replyBuff = convToDatagram(getLispMapReplyBuffer());
+        DatagramPacket registerBuff = convToDatagram(getLispMapRegisterBuffer());
+        DatagramPacket notifyBuff = convToDatagram(getLispMapNotifyBuffer());
 
         List<Object> list = Lists.newArrayList();
         decoder.decode(new ChannelHandlerContextAdapter(), requestBuff, list);