[ONOS-6537] Implement LispRadixTreeDatabase with unit tests
Change-Id: I0d3c016432ad90aeb8843ac3653ec5b54cf6e3bf
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispRadixTreeDatabase.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispRadixTreeDatabase.java
index 0cb9d9e..0826d24 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispRadixTreeDatabase.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/LispRadixTreeDatabase.java
@@ -15,43 +15,114 @@
*/
package org.onosproject.lisp.ctl.impl;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import org.onlab.packet.IpPrefix;
+import org.onosproject.lisp.ctl.impl.tree.IpConcurrentRadixTree;
+import org.onosproject.lisp.msg.protocols.DefaultLispProxyMapRecord.DefaultMapWithProxyBuilder;
import org.onosproject.lisp.msg.protocols.LispEidRecord;
import org.onosproject.lisp.msg.protocols.LispMapRecord;
+import org.onosproject.lisp.msg.protocols.LispProxyMapRecord;
+import org.slf4j.Logger;
import java.util.List;
+import static org.onosproject.lisp.ctl.impl.util.LispMapUtil.cidrfy;
+import static org.slf4j.LoggerFactory.getLogger;
+
/**
* A radix tree based LISP mapping database.
*/
-public class LispRadixTreeDatabase implements LispMappingDatabase {
+public final class LispRadixTreeDatabase implements LispMappingDatabase {
+
+ private static final Logger log = getLogger(LispRadixTreeDatabase.class);
+
+ private final IpConcurrentRadixTree<LispProxyMapRecord> radixTree =
+ new IpConcurrentRadixTree<>();
+
+ /**
+ * Prevents object instantiation from external.
+ */
+ private LispRadixTreeDatabase() {
+ }
+
+ /**
+ * Obtains a singleton instance.
+ *
+ * @return singleton instance
+ */
+ public static LispRadixTreeDatabase getInstance() {
+ return SingletonHelper.INSTANCE;
+ }
@Override
public void putMapRecord(LispEidRecord eid, LispMapRecord rloc,
boolean proxyMapReply) {
- //TODO: requires implementation
+ final LispProxyMapRecord mapWithProxy = new DefaultMapWithProxyBuilder()
+ .withMapRecord(rloc)
+ .withIsProxyMapReply(proxyMapReply)
+ .build();
+ radixTree.put(getIpPrefix(eid), mapWithProxy);
+ log.debug("Inserted a new map record for key {}", eid.toString());
}
@Override
public void removeMapRecordByEid(LispEidRecord eid) {
- //TODO: requires implementation
+ if (radixTree.remove(getIpPrefix(eid))) {
+ log.debug("Removed a map record with key {}", eid.toString());
+ }
}
@Override
public void removeAllMapRecords() {
- //TODO: requires implementation
+ radixTree.clear();
+ log.debug("Clear all map records");
}
@Override
public LispMapRecord getMapRecordByEidRecord(LispEidRecord eid,
boolean proxyMapReply) {
- //TODO: requires implementation
+ final LispProxyMapRecord record =
+ radixTree.getValueForClosestParentAddress(getIpPrefix(eid));
+ if (record != null && record.isProxyMapReply() == proxyMapReply) {
+ return record.getMapRecord();
+ }
return null;
}
@Override
public List<LispMapRecord> getMapRecordByEidRecords(List<LispEidRecord> eids,
boolean proxyMapReply) {
- //TODO: requires implementation
- return null;
+ final List<LispMapRecord> mapRecords = Lists.newArrayList();
+ eids.parallelStream().forEach(eidRecord -> {
+ final LispMapRecord mapRecord =
+ getMapRecordByEidRecord(eidRecord, proxyMapReply);
+ if (mapRecord != null) {
+ mapRecords.add(mapRecord);
+ }
+ });
+ return ImmutableList.copyOf(mapRecords);
+ }
+
+ /**
+ * 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 LispRadixTreeDatabase INSTANCE = new LispRadixTreeDatabase();
+
+ private SingletonHelper() {
+ throw new IllegalAccessError(ILLEGAL_ACCESS_MSG);
+ }
+ }
+
+ /**
+ * Obtains the IP prefix from LISP EID record.
+ *
+ * @param eidRecord LISP EID record
+ * @return IP prefix object
+ */
+ private IpPrefix getIpPrefix(LispEidRecord eidRecord) {
+ return IpPrefix.valueOf(cidrfy(eidRecord));
}
}
diff --git a/protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/impl/LispMappingDatabaseTest.java b/protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/impl/LispMappingDatabaseTest.java
index f8d795d..8eb888d 100644
--- a/protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/impl/LispMappingDatabaseTest.java
+++ b/protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/impl/LispMappingDatabaseTest.java
@@ -57,7 +57,8 @@
private static final String EID_IP_PREFIX_2_32 = "10.1.2.1";
private static final String EID_IP_PREFIX_2_24 = "10.1.2.0";
- final LispMappingDatabase mapDb = LispExpireMapDatabase.getInstance();
+ private final LispMappingDatabase expireMapDb = LispExpireMapDatabase.getInstance();
+ private final LispMappingDatabase radixTreeDb = LispRadixTreeDatabase.getInstance();
@Before
public void setup() {
@@ -126,9 +127,13 @@
builder3.withRecordTtl(60);
LispMapRecord mapRecord3 = builder3.build();
- mapDb.putMapRecord(eidRecord1, mapRecord1, true);
- mapDb.putMapRecord(eidRecord2, mapRecord2, true);
- mapDb.putMapRecord(eidRecord3, mapRecord3, true);
+ expireMapDb.putMapRecord(eidRecord1, mapRecord1, true);
+ expireMapDb.putMapRecord(eidRecord2, mapRecord2, true);
+ expireMapDb.putMapRecord(eidRecord3, mapRecord3, true);
+
+ radixTreeDb.putMapRecord(eidRecord1, mapRecord1, true);
+ radixTreeDb.putMapRecord(eidRecord2, mapRecord2, true);
+ radixTreeDb.putMapRecord(eidRecord3, mapRecord3, true);
}
@Test
@@ -136,10 +141,14 @@
byte cidr32 = (byte) 32;
LispIpv4Address eid = new LispIpv4Address(IpAddress.valueOf(EID_IP_1));
LispEidRecord record = new LispEidRecord(cidr32, eid);
- LispMapRecord mapRecord = mapDb.getMapRecordByEidRecord(record, true);
+ LispMapRecord mapRecord1 = expireMapDb.getMapRecordByEidRecord(record, true);
+ LispMapRecord mapRecord2 = radixTreeDb.getMapRecordByEidRecord(record, true);
assertThat("Failed to fetch the RLOCs with /32 EID record",
- mapRecord.getLocatorCount(), is(3));
+ mapRecord1.getLocatorCount(), is(3));
+
+ assertThat("Failed to fetch the RLOCs with /32 EID record",
+ mapRecord2.getLocatorCount(), is(3));
}
@Test
@@ -147,17 +156,24 @@
byte cidr32 = (byte) 32;
LispIpv4Address eid = new LispIpv4Address(IpAddress.valueOf(EID_IP_PREFIX_2_32));
LispEidRecord record32 = new LispEidRecord(cidr32, eid);
- LispMapRecord mapRecord32 = mapDb.getMapRecordByEidRecord(record32, true);
+ LispMapRecord mapRecordExpireMap32 = expireMapDb.getMapRecordByEidRecord(record32, true);
+ LispMapRecord mapRecordRadixTree32 = radixTreeDb.getMapRecordByEidRecord(record32, true);
byte cidr24 = (byte) 24;
LispIpv4Address eid24 = new LispIpv4Address(IpAddress.valueOf(EID_IP_PREFIX_2_24));
LispEidRecord record24 = new LispEidRecord(cidr24, eid24);
- LispMapRecord mapRecord24 = mapDb.getMapRecordByEidRecord(record24, true);
+ LispMapRecord mapRecordExpireMap24 = expireMapDb.getMapRecordByEidRecord(record24, true);
+ LispMapRecord mapRecordRadixTree24 = radixTreeDb.getMapRecordByEidRecord(record32, true);
assertThat("Failed to fetch the RLOCs with /32 EID record",
- mapRecord32.getLocatorCount(), is(2));
+ mapRecordExpireMap32.getLocatorCount(), is(2));
assertThat("Failed to fetch the RLOCs with /24 EID record",
- mapRecord24.getLocatorCount(), is(2));
+ mapRecordExpireMap24.getLocatorCount(), is(2));
+
+ assertThat("Failed to fetch the RLOCs with /32 EID record",
+ mapRecordRadixTree32.getLocatorCount(), is(2));
+ assertThat("Failed to fetch the RLOCs with /24 EID record",
+ mapRecordRadixTree24.getLocatorCount(), is(2));
}
@Test
@@ -165,23 +181,33 @@
byte cidr32 = (byte) 32;
LispIpv4Address eid = new LispIpv4Address(IpAddress.valueOf(EID_IP_PREFIX_1_32));
LispEidRecord record32 = new LispEidRecord(cidr32, eid);
- LispMapRecord mapRecord32 = mapDb.getMapRecordByEidRecord(record32, true);
+ LispMapRecord mapRecordExpireMap32 = expireMapDb.getMapRecordByEidRecord(record32, true);
+ LispMapRecord mapRecordRadixTree32 = radixTreeDb.getMapRecordByEidRecord(record32, true);
byte cidr24 = (byte) 24;
LispIpv4Address eid24 = new LispIpv4Address(IpAddress.valueOf(EID_IP_PREFIX_1_24));
LispEidRecord record24 = new LispEidRecord(cidr24, eid24);
- LispMapRecord mapRecord24 = mapDb.getMapRecordByEidRecord(record24, true);
+ LispMapRecord mapRecordExpireMap24 = expireMapDb.getMapRecordByEidRecord(record24, true);
+ LispMapRecord mapRecordRadixTree24 = radixTreeDb.getMapRecordByEidRecord(record32, true);
byte cidr16 = (byte) 16;
LispIpv4Address eid16 = new LispIpv4Address(IpAddress.valueOf(EID_IP_PREFIX_1_16));
LispEidRecord record16 = new LispEidRecord(cidr16, eid16);
- LispMapRecord mapRecord16 = mapDb.getMapRecordByEidRecord(record16, true);
+ LispMapRecord mapRecordExpireMap16 = expireMapDb.getMapRecordByEidRecord(record16, true);
+ LispMapRecord mapRecordRadixTree16 = radixTreeDb.getMapRecordByEidRecord(record16, true);
assertThat("Failed to fetch the RLOCs with /32 EID record",
- mapRecord32.getLocatorCount(), is(1));
+ mapRecordExpireMap32.getLocatorCount(), is(1));
assertThat("Failed to fetch the RLOCs with /24 EID record",
- mapRecord24.getLocatorCount(), is(1));
+ mapRecordExpireMap24.getLocatorCount(), is(1));
assertThat("Failed to fetch the RLOCs with /16 EID record",
- mapRecord16.getLocatorCount(), is(1));
+ mapRecordExpireMap16.getLocatorCount(), is(1));
+
+ assertThat("Failed to fetch the RLOCs with /32 EID record",
+ mapRecordRadixTree32.getLocatorCount(), is(1));
+ assertThat("Failed to fetch the RLOCs with /24 EID record",
+ mapRecordRadixTree24.getLocatorCount(), is(1));
+ assertThat("Failed to fetch the RLOCs with /16 EID record",
+ mapRecordRadixTree16.getLocatorCount(), is(1));
}
}