[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);