Refactor LISP package to separate ctrl interface and impl classes
Change-Id: I4e94ff54299e886cd0e8b3ce38591b0900290f54
diff --git a/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/map/ExpireHashMap.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/map/ExpireHashMap.java
new file mode 100644
index 0000000..08f7c88
--- /dev/null
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/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.impl.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/impl/map/ExpireMap.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/map/ExpireMap.java
new file mode 100644
index 0000000..7bb8fcd
--- /dev/null
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/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.impl.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/impl/map/package-info.java b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/map/package-info.java
new file mode 100644
index 0000000..f37bfe1
--- /dev/null
+++ b/protocols/lisp/ctl/src/main/java/org/onosproject/lisp/ctl/impl/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.impl.map;
\ No newline at end of file