/** * ============LICENSE_START======================================================= * org.onap.aaf * ================================================================================ * Copyright © 2018 European Software Marketing Ltd. * ================================================================================ * 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. * ============LICENSE_END========================================================= */ package org.onap.aaf.fproxy.cache; import java.lang.ref.SoftReference; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.DelayQueue; import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit; import org.onap.aaf.fproxy.data.CredentialCacheData; public class InMemoryCredentialCache implements CredentialCache { private final ConcurrentHashMap> cache = new ConcurrentHashMap<>(); private final DelayQueue cleaningUpQueue = new DelayQueue<>(); public InMemoryCredentialCache() { Thread cleanerThread = new Thread(() -> { while (!Thread.currentThread().isInterrupted()) { try { DelayedCacheObject delayedCacheObject = cleaningUpQueue.take(); cache.remove(delayedCacheObject.getKey(), delayedCacheObject.getReference()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } }); cleanerThread.setDaemon(true); cleanerThread.start(); } @Override public void add(String key, CredentialCacheData value, long periodInMillis) { if (key == null) { return; } if (value == null) { cache.remove(key); } else { long expiryTime = System.currentTimeMillis() + periodInMillis; SoftReference reference = new SoftReference<>(value); cache.put(key, reference); cleaningUpQueue.put(new DelayedCacheObject(key, reference, expiryTime)); } } @Override public void remove(String key) { cache.remove(key); } @Override public CredentialCacheData get(String key) { return Optional.ofNullable(cache.get(key)).map(SoftReference::get).orElse(null); } @Override public void clear() { cache.clear(); } @Override public long size() { return cache.size(); } private static class DelayedCacheObject implements Delayed { private final String key; private final SoftReference reference; private final long expiryTime; public DelayedCacheObject(String key, SoftReference reference, long expiryTime) { super(); this.key = key; this.reference = reference; this.expiryTime = expiryTime; } @Override public long getDelay(TimeUnit unit) { return unit.convert(expiryTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS); } @Override public int compareTo(Delayed o) { return Long.compare(expiryTime, ((DelayedCacheObject) o).expiryTime); } public String getKey() { return key; } public SoftReference getReference() { return reference; } } }