/* * Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you 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.wso2.carbon.identity.application.common.cache; import org.wso2.carbon.caching.impl.CacheImpl; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.identity.application.common.listener.AbstractCacheListener; import org.wso2.carbon.identity.core.model.IdentityCacheConfig; import org.wso2.carbon.identity.core.util.IdentityUtil; import org.wso2.carbon.utils.multitenancy.MultitenantConstants; import javax.cache.Cache; import javax.cache.CacheBuilder; import javax.cache.CacheConfiguration; import javax.cache.CacheManager; import javax.cache.Caching; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; /** * A base class for all cache implementations in Identity Application Management modules. */ public class BaseCache<K extends Serializable, V extends Serializable> { private static final String CACHE_MANAGER_NAME = "IdentityApplicationManagementCacheManager"; private CacheBuilder<K, V> cacheBuilder; private String cacheName; private List<AbstractCacheListener> cacheListeners = new ArrayList<AbstractCacheListener>(); public BaseCache(String cacheName) { this.cacheName = cacheName; } private Cache<K, V> getBaseCache() { Cache<K, V> cache = null; try { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext(); carbonContext.setTenantId(MultitenantConstants.SUPER_TENANT_ID); carbonContext.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); CacheManager cacheManager = Caching.getCacheManagerFactory() .getCacheManager(CACHE_MANAGER_NAME); if (getCacheTimeout() > 0 && cacheBuilder == null) { synchronized (cacheName.intern()) { if (cacheBuilder == null) { cacheManager.removeCache(cacheName); cacheBuilder = cacheManager.<K, V>createCacheBuilder(cacheName). setExpiry(CacheConfiguration.ExpiryType.ACCESSED, new CacheConfiguration .Duration(TimeUnit.SECONDS, getCacheTimeout())). setExpiry(CacheConfiguration.ExpiryType.MODIFIED, new CacheConfiguration .Duration(TimeUnit.SECONDS, getCacheTimeout())). setStoreByValue(false); cache = cacheBuilder.build(); for (AbstractCacheListener cacheListener : cacheListeners) { if (cacheListener.isEnable()) { this.cacheBuilder.registerCacheEntryListener(cacheListener); } } setCapacity((CacheImpl) cache); } else { cache = cacheManager.getCache(cacheName); setCapacity((CacheImpl) cache); } } } else { cache = cacheManager.getCache(cacheName); setCapacity((CacheImpl) cache); } } finally { PrivilegedCarbonContext.endTenantFlow(); } return cache; } /** * Add a cache entry. * * @param key Key which cache entry is indexed. * @param entry Actual object where cache entry is placed. */ public void addToCache(K key, V entry) { if (!isEnabled()) { return; } try { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext .getThreadLocalCarbonContext(); carbonContext.setTenantId(MultitenantConstants.SUPER_TENANT_ID); carbonContext.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); // Element already in the cache. Remove it first Cache<K, V> cache = getBaseCache(); if (cache != null) { cache.put(key, entry); } } finally { PrivilegedCarbonContext.endTenantFlow(); } } /** * Retrieves a cache entry. * * @param key CacheKey * @return Cached entry. */ public V getValueFromCache(K key) { if (!isEnabled()) { return null; } if(key == null) { return null; } try { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext .getThreadLocalCarbonContext(); carbonContext.setTenantId(MultitenantConstants.SUPER_TENANT_ID); carbonContext.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); Cache<K, V> cache = getBaseCache(); if (cache != null && cache.get(key) != null) { return (V) cache.get(key); } return null; } finally { PrivilegedCarbonContext.endTenantFlow(); } } /** * Clears a cache entry. * * @param key Key to clear cache. */ public void clearCacheEntry(K key) { if (!isEnabled()) { return; } try { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext .getThreadLocalCarbonContext(); carbonContext.setTenantId(MultitenantConstants.SUPER_TENANT_ID); carbonContext.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); Cache<K, V> cache = getBaseCache(); if (cache != null) { cache.remove(key); } } finally { PrivilegedCarbonContext.endTenantFlow(); } } /** * Remove everything in the cache. */ public void clear() { if (!isEnabled()) { return; } try { PrivilegedCarbonContext.startTenantFlow(); PrivilegedCarbonContext carbonContext = PrivilegedCarbonContext .getThreadLocalCarbonContext(); carbonContext.setTenantId(MultitenantConstants.SUPER_TENANT_ID); carbonContext.setTenantDomain(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); Cache<K, V> cache = getBaseCache(); if (cache != null) { cache.removeAll(); } } finally { PrivilegedCarbonContext.endTenantFlow(); } } public void addListener(AbstractCacheListener listener){ cacheListeners.add(listener); } public boolean isEnabled() { IdentityCacheConfig identityCacheConfig = IdentityUtil.getIdentityCacheConfig(CACHE_MANAGER_NAME, cacheName); if (identityCacheConfig != null) { return identityCacheConfig.isEnabled(); } return true; } public int getCacheTimeout() { IdentityCacheConfig identityCacheConfig = IdentityUtil.getIdentityCacheConfig(CACHE_MANAGER_NAME, cacheName); if (identityCacheConfig != null && identityCacheConfig.getTimeout() > 0) { return identityCacheConfig.getTimeout(); } return -1; } public int getCapacity() { IdentityCacheConfig identityCacheConfig = IdentityUtil.getIdentityCacheConfig(CACHE_MANAGER_NAME, cacheName); if (identityCacheConfig != null && identityCacheConfig.getCapacity() > 0) { return identityCacheConfig.getCapacity(); } return -1; } public void setCapacity(CacheImpl cache) { if (getCapacity() > 0) { cache.setCapacity(getCapacity()); } } }