Add LISP mapping entry aging mechanism

Change-Id: I9a2a75f64ff4fb580dcc4b2e789af020c5decd8d
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 2303f85..16e8662 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
@@ -44,13 +44,11 @@
         try {
             // first we need to check whether this is an ECM
             if (msg instanceof LispEncapsulatedControl) {
-                LispMessage innerMsg =
-                        extractLispMessage((LispEncapsulatedControl) msg);
+                LispMessage innerMsg = extractLispMessage((LispEncapsulatedControl) msg);
                 if (innerMsg instanceof LispMapRequest) {
-                    LispMapResolver mapResolver = new LispMapResolver();
+                    LispMapResolver mapResolver = LispMapResolver.getInstance();
                     LispMessage lispMessage =
-                            mapResolver.processMapRequest(
-                                    (LispEncapsulatedControl) msg);
+                            mapResolver.processMapRequest((LispEncapsulatedControl) msg);
 
                     ctx.writeAndFlush(lispMessage);
                 }
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 285b397..3e4a21d 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
@@ -33,14 +33,18 @@
  * LISP map resolver class.
  * Handles map-request message and acknowledges with map-reply message.
  */
-public class LispMapResolver {
+public final class LispMapResolver {
 
     private static final Logger log = LoggerFactory.getLogger(LispMapResolver.class);
 
-    private LispEidRlocMap eidRlocMap;
+    private LispMappingDatabase mapDb = LispMappingDatabase.getInstance();
 
-    LispMapResolver() {
-        eidRlocMap = LispEidRlocMap.getInstance();
+    // non-instantiable (except for our Singleton)
+    private LispMapResolver() {
+    }
+
+    public static LispMapResolver getInstance() {
+        return SingletonHelper.INSTANCE;
     }
 
     /**
@@ -54,9 +58,6 @@
         LispEncapsulatedControl ecm = (LispEncapsulatedControl) message;
         LispMapRequest request = (LispMapRequest) ecm.getControlMessage();
 
-        // TODO: for now we always generate map-reply message and send to ITR
-        // no matter proxy bit is set or not
-
         // build map-reply message
         LispMapReply.ReplyBuilder replyBuilder = new DefaultReplyBuilder();
         replyBuilder.withNonce(request.getNonce());
@@ -64,7 +65,7 @@
         replyBuilder.withIsSecurity(false);
         replyBuilder.withIsProbe(request.isProbe());
 
-        List<LispMapRecord> mapRecords = eidRlocMap.getMapRecordByEidRecords(request.getEids());
+        List<LispMapRecord> mapRecords = mapDb.getMapRecordByEidRecords(request.getEids());
 
         if (mapRecords.size() == 0) {
             log.warn("Map information is not found.");
@@ -85,4 +86,16 @@
 
         return reply;
     }
+
+    /**
+     * 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 LispMapResolver INSTANCE = new LispMapResolver();
+
+        private SingletonHelper() {
+            throw new IllegalAccessError(ILLEGAL_ACCESS_MSG);
+        }
+    }
 }
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 8c2a7b7..e69cd41 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
@@ -57,17 +57,17 @@
 
     private static final Logger log = LoggerFactory.getLogger(LispMapServer.class);
 
-    private LispEidRlocMap eidRlocMap = LispEidRlocMap.getInstance();
+    private LispMappingDatabase mapDb = LispMappingDatabase.getInstance();
     private LispAuthenticationConfig authConfig = LispAuthenticationConfig.getInstance();
 
-    public static LispMapServer getInstance() {
-        return SingletonHelper.INSTANCE;
-    }
-
     // non-instantiable (except for our Singleton)
     private LispMapServer() {
     }
 
+    public static LispMapServer getInstance() {
+        return SingletonHelper.INSTANCE;
+    }
+
     /**
      * Handles map-register message and replies with map-notify message.
      *
@@ -83,6 +83,14 @@
             return null;
         }
 
+        register.getMapRecords().forEach(mapRecord -> {
+            LispEidRecord eidRecord =
+                    new LispEidRecord(mapRecord.getMaskLength(),
+                                      mapRecord.getEidPrefixAfi());
+
+            mapDb.putMapRecord(eidRecord, mapRecord);
+        });
+
         // we only acknowledge back to ETR when want-map-notify bit is set to true
         // otherwise, we do not acknowledge back to ETR
         if (register.isWantMapNotify()) {
@@ -99,12 +107,6 @@
                     new InetSocketAddress(register.getSender().getAddress(), MAP_NOTIFY_PORT);
             notify.configSender(address);
 
-            register.getMapRecords().forEach(record -> {
-                LispEidRecord eidRecord =
-                        new LispEidRecord(record.getMaskLength(), record.getEidPrefixAfi());
-                eidRlocMap.insertMapRecord(eidRecord, record);
-            });
-
             return notify;
         }
 
@@ -213,7 +215,12 @@
     /**
      * Prevents object instantiation from external.
      */
-    private static class SingletonHelper {
+    private static final class SingletonHelper {
+        private static final String ILLEGAL_ACCESS_MSG = "Should not instantiate this class.";
         private static final LispMapServer INSTANCE = new LispMapServer();
+
+        private SingletonHelper() {
+            throw new IllegalAccessError(ILLEGAL_ACCESS_MSG);
+        }
     }
 }
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispEidRlocMap.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMappingDatabase.java
similarity index 75%
rename from protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispEidRlocMap.java
rename to protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMappingDatabase.java
index 81437bd..d95ddaa 100644
--- a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispEidRlocMap.java
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/LispMappingDatabase.java
@@ -17,29 +17,37 @@
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
 import org.onlab.packet.IpPrefix;
+import org.onosproject.lisp.ctl.map.ExpireHashMap;
+import org.onosproject.lisp.ctl.map.ExpireMap;
 import org.onosproject.lisp.msg.protocols.LispEidRecord;
 import org.onosproject.lisp.msg.protocols.LispMapRecord;
 import org.onosproject.lisp.msg.types.LispAfiAddress;
 
 import java.util.List;
 import java.util.Optional;
-import java.util.concurrent.ConcurrentMap;
 
 /**
  * A singleton class that stores EID-RLOC mapping information.
  */
-public final class LispEidRlocMap {
+public final class LispMappingDatabase {
 
-    private ConcurrentMap<LispEidRecord, LispMapRecord> map = Maps.newConcurrentMap();
+    private static final long MINUTE_TO_MS_UNIT = 60 * 1000;
+
+    private ExpireMap<LispEidRecord, LispMapRecord> map = new ExpireHashMap<>();
+
+    /**
+     * Prevents object instantiation from external.
+     */
+    private LispMappingDatabase() {
+    }
 
     /**
      * Obtains a singleton instance.
      *
      * @return singleton instance
      */
-    public static LispEidRlocMap getInstance() {
+    public static LispMappingDatabase getInstance() {
         return SingletonHelper.INSTANCE;
     }
 
@@ -49,8 +57,18 @@
      * @param eid  endpoint identifier
      * @param rloc route locator record
      */
-    public void insertMapRecord(LispEidRecord eid, LispMapRecord rloc) {
-        map.putIfAbsent(eid, rloc);
+    public void putMapRecord(LispEidRecord eid, LispMapRecord rloc) {
+        map.put(eid, rloc, rloc.getRecordTtl() * MINUTE_TO_MS_UNIT);
+    }
+
+    /**
+     * Returns the results whether a given EidRecord is contained in the map.
+     *
+     * @param eid endpoint identifier
+     * @return the results whether a given EidRecord is contained in the map
+     */
+    public boolean hasEidRecord(LispEidRecord eid) {
+        return map.containsKey(eid);
     }
 
     /**
@@ -105,21 +123,7 @@
     public LispMapRecord getMapRecordByEidAddress(LispAfiAddress address) {
         Optional<LispEidRecord> eidRecord =
                 map.keySet().stream().filter(k -> k.getPrefix().equals(address)).findFirst();
-        if (eidRecord.isPresent()) {
-            return map.get(eidRecord);
-        }
-
-        return null;
-    }
-
-    /**
-     * Prevents object instantiation from external.
-     */
-    private LispEidRlocMap() {
-    }
-
-    private static class SingletonHelper {
-        private static final LispEidRlocMap INSTANCE = new LispEidRlocMap();
+        return eidRecord.map(lispEidRecord -> map.get(lispEidRecord)).orElse(null);
     }
 
     /**
@@ -150,4 +154,16 @@
 
         return originIpPrefix.contains(compareIpPrefix);
     }
+
+    /**
+     * 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 LispMappingDatabase INSTANCE = new LispMappingDatabase();
+
+        private SingletonHelper() {
+            throw new IllegalAccessError(ILLEGAL_ACCESS_MSG);
+        }
+    }
 }
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/map/ExpireHashMap.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/map/ExpireHashMap.java
new file mode 100644
index 0000000..d0aca9a
--- /dev/null
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/map/ExpireHashMap.java
@@ -0,0 +1,183 @@
+/*
+ * 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.map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Set;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * Default implementation of ExpireMap.
+ */
+public class ExpireHashMap<K, V> implements ExpireMap<K, V> {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private static final long DEFAULT_TTL = 60000L;
+    private final ConcurrentMap<K, ExpiredObject<K, V>> map = new ConcurrentHashMap<>();
+    private final Lock writeLock = new ReentrantLock();
+    private final Timer timer = new Timer("ExpireMapTimer", true);
+
+    /**
+     * An expired object that associates with a TimerTask instance.
+     *
+     * @param <K1> key type K1
+     * @param <V1> value type V1
+     */
+    class ExpiredObject<K1, V1> {
+        private final V1 value;
+        private final ExpiryTask<K1> task;
+        private final long ttl;
+
+        public ExpiredObject(K1 key, V1 value) {
+            this(key, value, DEFAULT_TTL);
+        }
+
+        ExpiredObject(K1 key, V1 value, long ttl) {
+            this.value = value;
+            this.task = new ExpiryTask<>(key);
+            this.ttl = ttl;
+            timer.schedule(this.task, ttl);
+        }
+
+        ExpiryTask<K1> getTask() {
+            return task;
+        }
+
+        V1 getValue() {
+            return value;
+        }
+
+        long getTtl() {
+            return ttl;
+        }
+    }
+
+    /**
+     * A TimerTask that removes its associated map entry from the internal map.
+     *
+     * @param <K2> object key
+     */
+    class ExpiryTask<K2> extends TimerTask {
+        private final K2 key;
+
+        ExpiryTask(K2 key) {
+            this.key = key;
+        }
+
+        K2 getKey() {
+            return key;
+        }
+
+        @Override
+        public void run() {
+            log.info("Removing element with key [{}]", key);
+            try {
+                writeLock.lock();
+                if (map.containsKey(key)) {
+                    map.remove(getKey());
+                }
+            } finally {
+                writeLock.unlock();
+            }
+        }
+    }
+
+    @Override
+    public void put(K key, V value, long expireMs) {
+        try {
+            writeLock.lock();
+
+            // if we have a value which is previously associated with the given
+            // key, we simply replace it with new value, and invalidate the
+            // previously associated value
+            final ExpiredObject<K, V> object =
+                    map.putIfAbsent(key, new ExpiredObject<>(key, value, expireMs));
+
+            if (object != null) {
+                object.getTask().cancel();
+            }
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    @Override
+    public void put(K key, V value) {
+        put(key, value, DEFAULT_TTL);
+    }
+
+    @Override
+    public V get(K key) {
+        return map.containsKey(key) ? map.get(key).getValue() : null;
+    }
+
+    @Override
+    public void clear() {
+        try {
+            writeLock.lock();
+            for (ExpiredObject<K, V> object : map.values()) {
+                object.getTask().cancel();
+            }
+            map.clear();
+            timer.purge();
+        } finally {
+            writeLock.unlock();
+        }
+    }
+
+    @Override
+    public boolean containsKey(K key) {
+        return map.containsKey(key);
+    }
+
+    @Override
+    public Set<K> keySet() {
+        return map.keySet();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return map.isEmpty();
+    }
+
+    @Override
+    public V remove(K key) {
+        final ExpiredObject<K, V> object;
+        try {
+            writeLock.lock();
+            object = map.remove(key);
+            if (object != null) {
+                object.getTask().cancel();
+            }
+        } finally {
+            writeLock.unlock();
+        }
+        return (object == null ? null : object.getValue());
+    }
+
+    @Override
+    public int size() {
+        return map.size();
+    }
+}
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/map/ExpireMap.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/map/ExpireMap.java
new file mode 100644
index 0000000..0d75104
--- /dev/null
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/map/ExpireMap.java
@@ -0,0 +1,161 @@
+/*
+ * 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.map;
+
+import java.util.Set;
+
+/**
+ * A {@link java.util.concurrent.ConcurrentMap} that supports timed entry
+ * eviction.
+ */
+public interface ExpireMap<K, V> {
+
+    /**
+     * Associates the specified value with the specified key in this map for the
+     * specified duration (optional operation). If the map previously contained
+     * a mapping for the key, the old value is replaced by the specified value.
+     *
+     * @param key      key with which the specified value is to be associated
+     * @param value    value to be associated with the specified key
+     * @param expireMs the maximum amount of time in ms during which the map
+     *                 entry should remain in the map, this can also be
+     *                 considered as (time-to-live: TTL) value. Note that when
+     *                 we assign a value of 0, the map entry will be immediately
+     *                 remove from the map.
+     *
+     * @throws UnsupportedOperationException if the <tt>put</tt> operation
+     *         is not supported by this map
+     * @throws ClassCastException if the class of the specified key or value
+     *         prevents it from being stored in this map
+     * @throws NullPointerException if the specified key or value is null
+     *         and this map does not permit null keys or values
+     * @throws IllegalArgumentException if some property of the specified key
+     *         or value prevents it from being stored in this map
+     */
+    void put(K key, V value, long expireMs);
+
+    /**
+     * Associates the specified value with the specified key in this map for the
+     * specified duration (optional operation). If the map previously contained
+     * a mapping for the key, the old value is replaced by the specified value.
+     * With this method, we can specify the expireMs with default value.
+     *
+     * @param key   key with which the specified value is to be associated
+     * @param value value to be associated with the specified key
+     *
+     * @throws UnsupportedOperationException if the <tt>put</tt> operation
+     *         is not supported by this map
+     * @throws ClassCastException if the class of the specified key or value
+     *         prevents it from being stored in this map
+     * @throws NullPointerException if the specified key or value is null
+     *         and this map does not permit null keys or values
+     * @throws IllegalArgumentException if some property of the specified key
+     *         or value prevents it from being stored in this map
+     */
+    void put(K key, V value);
+
+    /**
+     * Returns the value to which the specified key is mapped,
+     * or {@code null} if this map contains no mapping for the key.
+     *
+     * @param key the key whose associated value is to be returned
+     * @return the value to which the specified key is mapped, or
+     *         {@code null} if this map contains no mapping for the key
+     * @throws ClassCastException if the key is of an inappropriate type for
+     *         this map
+     * @throws NullPointerException if the specified key is null and this map
+     *         does not permit null keys
+     */
+    V get(K key);
+
+    /**
+     * Removes all of the mappings from this map (optional operation).
+     * The map will be empty after this call returns.
+     *
+     * @throws UnsupportedOperationException if the <tt>clear</tt> operation
+     *         is not supported by this map
+     */
+    void clear();
+
+    /**
+     * Returns <tt>true</tt> if this map contains a mapping for the specified
+     * key.  More formally, returns <tt>true</tt> if and only if
+     * this map contains a mapping for a key <tt>k</tt> such that
+     * <tt>(key==null ? k==null : key.equals(k))</tt>.  (There can be
+     * at most one such mapping.)
+     *
+     * @param key key whose presence in this map is to be tested
+     * @return <tt>true</tt> if this map contains a mapping for the specified
+     *         key
+     * @throws ClassCastException if the key is of an inappropriate type for
+     *         this map
+     * @throws NullPointerException if the specified key is null and this map
+     *         does not permit null keys
+     */
+    boolean containsKey(K key);
+
+    /**
+     * Returns a {@link Set} view of the keys contained in this map.
+     * The set is backed by the map, so changes to the map are
+     * reflected in the set, and vice-versa.  If the map is modified
+     * while an iteration over the set is in progress (except through
+     * the iterator's own <tt>remove</tt> operation), the results of
+     * the iteration are undefined.  The set supports element removal,
+     * which removes the corresponding mapping from the map, via the
+     * <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
+     * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt>
+     * operations.  It does not support the <tt>add</tt> or <tt>addAll</tt>
+     * operations.
+     *
+     * @return a set view of the keys contained in this map
+     */
+    Set<K> keySet();
+
+    /**
+     * Returns <tt>true</tt> if this map contains no key-value mappings.
+     *
+     * @return <tt>true</tt> if this map contains no key-value mappings
+     */
+    boolean isEmpty();
+
+    /**
+     * Removes the mapping for a key from this map if it is present
+     * (optional operation).   More formally, if this map contains a mapping
+     * from key <tt>k</tt> to value <tt>v</tt> such that
+     * <code>(key==null ?  k==null : key.equals(k))</code>, that mapping
+     * is removed.  (The map can contain at most one such mapping.)
+     *
+     * @param key key whose mapping is to be removed from the map
+     * @return the previous value associated with <tt>key</tt>, or
+     *         <tt>null</tt> if there was no mapping for <tt>key</tt>.
+     * @throws UnsupportedOperationException if the <tt>remove</tt> operation
+     *         is not supported by this map
+     * @throws ClassCastException if the key is of an inappropriate type for
+     *         this map
+     * @throws NullPointerException if the specified key is null and this
+     *         map does not permit null keys
+     */
+    V remove(K key);
+
+    /**
+     * Returns the number of key-value mappings in this map.  If the
+     * map contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
+     * <tt>Integer.MAX_VALUE</tt>.
+     *
+     * @return the number of key-value mappings in this map
+     */
+    int size();
+}
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/map/package-info.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/map/package-info.java
new file mode 100644
index 0000000..e5a33bf
--- /dev/null
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/map/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * A package that contains ExpireMap interface and implementation classes.
+ */
+package org.onosproject.lisp.ctl.map;
\ No newline at end of file
diff --git a/protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/LispEidRlocMapTest.java b/protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/LispMappingDatabaseTest.java
similarity index 88%
rename from protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/LispEidRlocMapTest.java
rename to protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/LispMappingDatabaseTest.java
index c8c112b..8b60e2e 100644
--- a/protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/LispEidRlocMapTest.java
+++ b/protocols/lisp/ctl/src/test/java/org/onosproject/lisp/ctl/LispMappingDatabaseTest.java
@@ -35,9 +35,9 @@
 /**
  * Tests for LISP EID RLOC Map class.
  */
-public class LispEidRlocMapTest {
+public class LispMappingDatabaseTest {
 
-    final LispEidRlocMap eidRlocMap = LispEidRlocMap.getInstance();
+    final LispMappingDatabase mapDb = LispMappingDatabase.getInstance();
 
     @Before
     public void setup() {
@@ -89,23 +89,26 @@
         builder1.withMaskLength(cidr1);
         builder1.withEidPrefixAfi(eid1);
         builder1.withLocators(locatorRecords1);
+        builder1.withRecordTtl(60);
         LispMapRecord mapRecord1 = builder1.build();
 
         MapRecordBuilder builder2 = new DefaultMapRecordBuilder();
         builder2.withMaskLength(cidr2);
         builder2.withEidPrefixAfi(eid2);
         builder2.withLocators(locatorRecords2);
+        builder2.withRecordTtl(60);
         LispMapRecord mapRecord2 = builder2.build();
 
         MapRecordBuilder builder3 = new DefaultMapRecordBuilder();
         builder3.withMaskLength(cidr3);
         builder3.withEidPrefixAfi(eid3);
         builder3.withLocators(locatorRecords3);
+        builder3.withRecordTtl(60);
         LispMapRecord mapRecord3 = builder3.build();
 
-        eidRlocMap.insertMapRecord(eidRecord1, mapRecord1);
-        eidRlocMap.insertMapRecord(eidRecord2, mapRecord2);
-        eidRlocMap.insertMapRecord(eidRecord3, mapRecord3);
+        mapDb.putMapRecord(eidRecord1, mapRecord1);
+        mapDb.putMapRecord(eidRecord2, mapRecord2);
+        mapDb.putMapRecord(eidRecord3, mapRecord3);
     }
 
     @Test
@@ -113,7 +116,7 @@
         byte cidr32 = (byte) 32;
         LispIpv4Address eid = new LispIpv4Address(IpAddress.valueOf("10.1.1.1"));
         LispEidRecord record = new LispEidRecord(cidr32, eid);
-        LispMapRecord mapRecord = eidRlocMap.getMapRecordByEidRecord(record);
+        LispMapRecord mapRecord = mapDb.getMapRecordByEidRecord(record);
 
         assertThat("Failed to fetch the RLOCs with /32 EID record",
                     mapRecord.getLocatorCount(), is(3));
@@ -124,12 +127,12 @@
         byte cidr32 = (byte) 32;
         LispIpv4Address eid = new LispIpv4Address(IpAddress.valueOf("10.1.2.1"));
         LispEidRecord record32 = new LispEidRecord(cidr32, eid);
-        LispMapRecord mapRecord32 = eidRlocMap.getMapRecordByEidRecord(record32);
+        LispMapRecord mapRecord32 = mapDb.getMapRecordByEidRecord(record32);
 
         byte cidr24 = (byte) 24;
         LispIpv4Address eid24 = new LispIpv4Address(IpAddress.valueOf("10.1.2.0"));
         LispEidRecord record24 = new LispEidRecord(cidr24, eid24);
-        LispMapRecord mapRecord24 = eidRlocMap.getMapRecordByEidRecord(record24);
+        LispMapRecord mapRecord24 = mapDb.getMapRecordByEidRecord(record24);
 
         assertThat("Failed to fetch the RLOCs with /32 EID record",
                     mapRecord32.getLocatorCount(), is(2));
@@ -142,17 +145,17 @@
         byte cidr32 = (byte) 32;
         LispIpv4Address eid = new LispIpv4Address(IpAddress.valueOf("10.2.1.1"));
         LispEidRecord record32 = new LispEidRecord(cidr32, eid);
-        LispMapRecord mapRecord32 = eidRlocMap.getMapRecordByEidRecord(record32);
+        LispMapRecord mapRecord32 = mapDb.getMapRecordByEidRecord(record32);
 
         byte cidr24 = (byte) 24;
         LispIpv4Address eid24 = new LispIpv4Address(IpAddress.valueOf("10.2.1.0"));
         LispEidRecord record24 = new LispEidRecord(cidr24, eid24);
-        LispMapRecord mapRecord24 = eidRlocMap.getMapRecordByEidRecord(record24);
+        LispMapRecord mapRecord24 = mapDb.getMapRecordByEidRecord(record24);
 
         byte cidr16 = (byte) 16;
         LispIpv4Address eid16 = new LispIpv4Address(IpAddress.valueOf("10.2.0.0"));
         LispEidRecord record16 = new LispEidRecord(cidr16, eid16);
-        LispMapRecord mapRecord16 = eidRlocMap.getMapRecordByEidRecord(record16);
+        LispMapRecord mapRecord16 = mapDb.getMapRecordByEidRecord(record16);
 
         assertThat("Failed to fetch the RLOCs with /32 EID record",
                     mapRecord32.getLocatorCount(), is(1));