[ONOS-5607] Add a new LISP router when receiving MapRegisterMessage
Change-Id: I0cb11492def61b99f30b463304a3f152c5200b2f
diff --git a/protocols/lisp/api/src/main/java/org/onosproject/lisp/ctl/AbstractLispRouter.java b/protocols/lisp/api/src/main/java/org/onosproject/lisp/ctl/AbstractLispRouter.java
index d8e24c4..a2c6232 100644
--- a/protocols/lisp/api/src/main/java/org/onosproject/lisp/ctl/AbstractLispRouter.java
+++ b/protocols/lisp/api/src/main/java/org/onosproject/lisp/ctl/AbstractLispRouter.java
@@ -15,6 +15,7 @@
*/
package org.onosproject.lisp.ctl;
+import com.google.common.base.Objects;
import io.netty.channel.Channel;
import org.onlab.packet.IpAddress;
import org.onosproject.lisp.msg.protocols.LispMessage;
@@ -74,13 +75,7 @@
this.channel = channel;
final SocketAddress address = channel.remoteAddress();
if (address instanceof InetSocketAddress) {
- final InetSocketAddress inetAddress = (InetSocketAddress) address;
- final IpAddress ipAddress = IpAddress.valueOf(inetAddress.getAddress());
- if (ipAddress.isIp4()) {
- channelId = ipAddress.toString() + ':' + inetAddress.getPort();
- } else {
- channelId = '[' + ipAddress.toString() + "]:" + inetAddress.getPort();
- }
+ channelId = genChannelId((InetSocketAddress) address);
}
}
@@ -162,4 +157,50 @@
return sb.toString();
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ AbstractLispRouter that = (AbstractLispRouter) o;
+ return Objects.equal(channel, that.channel) &&
+ Objects.equal(channelId, that.channelId) &&
+ Objects.equal(connected, that.connected) &&
+ Objects.equal(subscribed, that.subscribed) &&
+ Objects.equal(routerId, that.routerId) &&
+ Objects.equal(agent, that.agent);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(channel, channelId, connected,
+ subscribed, routerId, agent);
+ }
+
+ /**
+ * Generates a string format of channel ID from the given InetSocketAddress.
+ *
+ * @param inetAddress InetAddress object
+ * @return string format of channel ID
+ */
+ private String genChannelId(InetSocketAddress inetAddress) {
+ StringBuilder sb = new StringBuilder();
+ final IpAddress ipAddress = IpAddress.valueOf(inetAddress.getAddress());
+ if (ipAddress.isIp4()) {
+ sb.append(ipAddress.toString());
+ sb.append(":");
+ sb.append(inetAddress.getPort());
+ } else {
+ sb.append("[");
+ sb.append(ipAddress.toString());
+ sb.append("]:");
+ sb.append(inetAddress.getPort());
+ }
+ return sb.toString();
+ }
}
diff --git a/protocols/lisp/api/src/main/java/org/onosproject/lisp/ctl/LispRouterFactory.java b/protocols/lisp/api/src/main/java/org/onosproject/lisp/ctl/LispRouterFactory.java
new file mode 100644
index 0000000..db7e583
--- /dev/null
+++ b/protocols/lisp/api/src/main/java/org/onosproject/lisp/ctl/LispRouterFactory.java
@@ -0,0 +1,97 @@
+/*
+ * 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.onlab.packet.IpAddress;
+import org.slf4j.Logger;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * LISP router factory which returns concrete router object for the physical
+ * LISP router in use.
+ */
+public final class LispRouterFactory {
+
+ private final Logger log = getLogger(getClass());
+
+ private LispRouterAgent agent;
+
+ // non-instantiable (except for our Singleton)
+ private LispRouterFactory() {
+ }
+
+ /**
+ * Configures LISP router agent only if it is not initialized.
+ *
+ * @param agent reference object of LISP router agent
+ */
+ public void setAgent(LispRouterAgent agent) {
+ synchronized (agent) {
+ if (this.agent == null) {
+ this.agent = agent;
+ } else {
+ log.warn("LISP Router Agent has already been set.");
+ }
+ }
+ }
+
+ /**
+ * Cleans up LISP router agent.
+ */
+ public void cleanAgent() {
+ synchronized (agent) {
+ if (this.agent != null) {
+ this.agent = null;
+ } else {
+ log.warn("LISP Router Agent is not configured.");
+ }
+ }
+ }
+
+ /**
+ * Returns a LISP router instance.
+ *
+ * @param routerId LISP router identifier
+ * @return LISP router instance
+ */
+ public LispRouter getRouterInstance(IpAddress routerId) {
+ LispRouter router = new DefaultLispRouter(new LispRouterId(routerId));
+ router.setAgent(agent);
+ return router;
+ }
+
+ /**
+ * Returns an instance of LISP router agent factory.
+ *
+ * @return instance of LISP router agent factory
+ */
+ public static LispRouterFactory getInstance() {
+ return SingletonHelper.INSTANCE;
+ }
+
+ /**
+ * Prevents object instantiation from external.
+ */
+ private static final class SingletonHelper {
+ private static final String ILLEGAL_ACCESS_MSG = "Should not instantiate this class.";
+ private static final LispRouterFactory INSTANCE = new LispRouterFactory();
+
+ private SingletonHelper() {
+ throw new IllegalAccessError(ILLEGAL_ACCESS_MSG);
+ }
+ }
+}
diff --git a/protocols/lisp/api/src/test/java/org/onosproject/lisp/ctl/LispRouterAgentAdapter.java b/protocols/lisp/api/src/test/java/org/onosproject/lisp/ctl/LispRouterAgentAdapter.java
new file mode 100644
index 0000000..88abadb
--- /dev/null
+++ b/protocols/lisp/api/src/test/java/org/onosproject/lisp/ctl/LispRouterAgentAdapter.java
@@ -0,0 +1,43 @@
+/*
+ * 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;
+
+/**
+ * Test adapter for the LISP router agent interface.
+ */
+public class LispRouterAgentAdapter implements LispRouterAgent {
+ @Override
+ public boolean addConnectedRouter(LispRouterId routerId, LispRouter router) {
+ return false;
+ }
+
+ @Override
+ public void removeConnectedRouter(LispRouterId routerId) {
+
+ }
+
+ @Override
+ public void processUpstreamMessage(LispRouterId routerId, LispMessage message) {
+
+ }
+
+ @Override
+ public void processDownstreamMessage(LispRouterId routerId, LispMessage message) {
+
+ }
+}
diff --git a/protocols/lisp/api/src/test/java/org/onosproject/lisp/ctl/LispRouterFactoryTest.java b/protocols/lisp/api/src/test/java/org/onosproject/lisp/ctl/LispRouterFactoryTest.java
new file mode 100644
index 0000000..097a44a
--- /dev/null
+++ b/protocols/lisp/api/src/test/java/org/onosproject/lisp/ctl/LispRouterFactoryTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+/**
+ * Unit test class for LispRouterFactory.
+ */
+public class LispRouterFactoryTest {
+
+ private LispRouterFactory routerFactory;
+ private LispRouterAgent agent = new LispRouterAgentAdapter();
+
+ @Before
+ public void setUp() throws Exception {
+ routerFactory = LispRouterFactory.getInstance();
+ routerFactory.setAgent(agent);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ routerFactory = null;
+ }
+
+ @Test
+ public void testSetAgent() throws Exception {
+ routerFactory.setAgent(agent);
+
+ assertThat(routerFactory, is(routerFactory));
+ }
+
+ @Test
+ public void testGetRouterInstance() throws Exception {
+ IpAddress ipAddress = IpAddress.valueOf("192.168.1.1");
+
+ LispRouter router1 = routerFactory.getRouterInstance(ipAddress);
+ LispRouter router2 = routerFactory.getRouterInstance(ipAddress);
+
+ assertThat(router1, is(router2));
+ }
+}
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispChannelHandler.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispChannelHandler.java
index b5e0105..8efbff9 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispChannelHandler.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispChannelHandler.java
@@ -20,11 +20,14 @@
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.ReferenceCountUtil;
+import org.onlab.packet.IpAddress;
+import org.onosproject.lisp.ctl.LispRouter;
+import org.onosproject.lisp.ctl.LispRouterFactory;
import org.onosproject.lisp.msg.protocols.LispEncapsulatedControl;
-import org.onosproject.lisp.msg.protocols.LispMapNotify;
-import org.onosproject.lisp.msg.protocols.LispMapRegister;
import org.onosproject.lisp.msg.protocols.LispInfoReply;
import org.onosproject.lisp.msg.protocols.LispInfoRequest;
+import org.onosproject.lisp.msg.protocols.LispMapNotify;
+import org.onosproject.lisp.msg.protocols.LispMapRegister;
import org.onosproject.lisp.msg.protocols.LispMapRequest;
import org.onosproject.lisp.msg.protocols.LispMessage;
import org.slf4j.Logger;
@@ -32,6 +35,8 @@
import java.util.List;
+import static org.onlab.packet.IpAddress.valueOf;
+
/**
* Channel handler deals with the xTR connection and dispatches xTR messages
* to the appropriate locations.
@@ -40,6 +45,10 @@
private final Logger log = LoggerFactory.getLogger(getClass());
+ private final LispRouterFactory routerFactory = LispRouterFactory.getInstance();
+
+ private LispRouter router;
+
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
@@ -61,9 +70,16 @@
// process map-register message
if (msg instanceof LispMapRegister) {
+
+ LispMapRegister register = (LispMapRegister) msg;
+ IpAddress xtrAddress = valueOf(register.getSender().getAddress());
+ router = routerFactory.getRouterInstance(xtrAddress);
+ router.setChannel(ctx.channel());
+ router.connectRouter();
+ router.handleMessage(register);
+
LispMapServer mapServer = LispMapServer.getInstance();
- LispMapNotify mapNotify =
- mapServer.processMapRegister((LispMapRegister) msg);
+ LispMapNotify mapNotify = mapServer.processMapRegister(register);
if (mapNotify != null) {
ctx.writeAndFlush(mapNotify);
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispControllerImpl.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispControllerImpl.java
index 560cf8e..7fa1e98 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispControllerImpl.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispControllerImpl.java
@@ -31,6 +31,7 @@
import org.onosproject.lisp.ctl.LispMessageListener;
import org.onosproject.lisp.ctl.LispRouter;
import org.onosproject.lisp.ctl.LispRouterAgent;
+import org.onosproject.lisp.ctl.LispRouterFactory;
import org.onosproject.lisp.ctl.LispRouterId;
import org.onosproject.lisp.ctl.LispRouterListener;
import org.onosproject.lisp.msg.authentication.LispAuthenticationConfig;
@@ -99,11 +100,14 @@
private Set<LispRouterListener> lispRouterListeners = new CopyOnWriteArraySet<>();
private Set<LispMessageListener> lispMessageListeners = new CopyOnWriteArraySet<>();
+ private LispRouterFactory routerFactory = LispRouterFactory.getInstance();
+
@Activate
public void activate(ComponentContext context) {
coreService.registerApplication(APP_ID, this::cleanup);
cfgService.registerProperties(getClass());
initAuthConfig(context.getProperties());
+ routerFactory.setAgent(agent);
bootstrap.start();
log.info("Started");
}
@@ -114,6 +118,7 @@
*/
private void cleanup() {
bootstrap.stop();
+ routerFactory.cleanAgent();
connectedRouters.values().forEach(LispRouter::disconnectRouter);
connectedRouters.clear();
}