AbstractKeystoreCache.java
- /*
- * GovWay - A customizable API Gateway
- * https://govway.org
- *
- * Copyright (c) 2005-2025 Link.it srl (https://link.it).
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 3, as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- package org.openspcoop2.security.keystore.cache;
- import java.io.Serializable;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Date;
- import java.util.List;
- import java.util.Map;
- import java.util.concurrent.ConcurrentHashMap;
- import org.apache.commons.codec.digest.DigestUtils;
- import org.openspcoop2.security.SecurityException;
- import org.openspcoop2.utils.SemaphoreLock;
- import org.openspcoop2.utils.cache.Cache;
- import org.openspcoop2.utils.date.DateManager;
- import org.openspcoop2.utils.date.DateUtils;
- /**
- * AbstractKeystoreCache
- *
- * @author Andrea Poli (apoli@link.it)
- * @author $Author$
- * @version $Rev$, $Date$
- */
- public abstract class AbstractKeystoreCache<T extends Serializable> {
- private int cacheLifeSecond = -1;
- private int cacheSize = -1;
-
- private Map<String, KeystoreCacheEntry<T>> cacheMap = new ConcurrentHashMap<>();
- private Cache cacheJCS = null;
- private final org.openspcoop2.utils.Semaphore lockCache = new org.openspcoop2.utils.Semaphore(this.getClass().getSimpleName());
- public void setKeystoreCacheParameters(int cacheLifeSecond,int cacheSize){
- this.cacheLifeSecond = cacheLifeSecond;
- this.cacheSize = cacheSize;
- }
- public void setCacheJCS(int cacheLifeSecond,Cache cacheJCS) {
- this.cacheLifeSecond = cacheLifeSecond;
- this.cacheJCS = cacheJCS;
- }
- public void updateCacheLifeSecond(int cacheLifeSecond) {
- this.cacheLifeSecond = cacheLifeSecond;
- }
-
-
-
- public T getKeystore(String keyParam) throws SecurityException{
- KeystoreCacheEntry<T> o = this.getObjectFromCache(keyParam);
- if(o==null){
- throw new SecurityException("Keystore with key ["+keyParam+"] not found");
- }
- else {
- return estraiKeystore(o);
- }
- }
- public T getKeystoreAndCreateIfNotExists(String keyParam,Object ... params) throws SecurityException{
- KeystoreCacheEntry<T> o = this.getObjectFromCache(keyParam);
- if(o==null){
- /**System.out.println("NON trovato ["+key+"], creo...");*/
- return initKeystore(keyParam, params);
- }
- else {
- /**System.out.println("GIA PRESENTE ["+key+"] ESTRAGGO");*/
- return estraiKeystore(o);
- }
- }
-
- public T getKeystore(byte[] keystore) throws SecurityException{
- String keyParam = buildKeyCacheFromBytes(keystore);
- return getKeystore(keyParam);
- }
- public T getKeystoreAndCreateIfNotExists(byte[] keystore,Object ... params) throws SecurityException{
- String keyParam = buildKeyCacheFromBytes(keystore);
- List<Object> lArgs = new ArrayList<>();
- lArgs.add(keystore);
- if(params!=null && params.length>0) {
- lArgs.addAll(Arrays.asList(params));
- }
- return getKeystoreAndCreateIfNotExists(keyParam, lArgs.toArray());
- }
-
- public abstract T createKeystore(String key,Object ... params) throws SecurityException;
- public abstract String getPrefixKey();
-
-
- /* UTILITY */
-
- public static String buildKeyCacheFromBytes(byte[] keystore) throws SecurityException {
- if(keystore==null) {
- throw new SecurityException("Keystore undefined");
- }
- return DigestUtils.sha256Hex(keystore);
- }
-
- @SuppressWarnings("unchecked")
- private KeystoreCacheEntry<T> getObjectFromCache(String keyParam) {
- String keyCache = this.getPrefixKey() + keyParam;
- KeystoreCacheEntry<T> o = null;
- if(this.cacheJCS!=null) {
- Object object = this.cacheJCS.get(keyCache);
- if(object!=null) {
- o = (KeystoreCacheEntry<T>) object;
- }
- }
- else {
- o = this.cacheMap.get(keyCache);
- }
- return o;
- }
-
- private T initKeystore(String keyParam,Object ... params) throws SecurityException{
-
- SemaphoreLock lock = this.lockCache.acquireThrowRuntime("initKeystore");
- try {
- String keyCache = this.getPrefixKey() + keyParam;
- KeystoreCacheEntry<T> o = this.getObjectFromCache(keyCache);
- if(o==null) {
- T keystore = createKeystore(keyParam, params);
- KeystoreCacheEntry<T> cacheEntry = new KeystoreCacheEntry<>();
- cacheEntry.setKey(keyCache);
- cacheEntry.setKeystore(keystore);
- cacheEntry.setDate(DateManager.getDate());
- if(this.cacheJCS!=null) {
- try {
- this.cacheJCS.put(keyCache, cacheEntry);
- }catch(Exception e) {
- throw new SecurityException(e.getMessage(),e);
- }
- }
- else {
- this.cacheMap.put(keyCache, cacheEntry);
- }
- /**System.out.println("CREATO ["+key+"] !!!! DATA["+cacheEntry.getDate()+"]"); */
- return keystore;
- }
- else {
- return estraiKeystore(o);
- }
- }finally {
- this.lockCache.release(lock, "initKeystore");
- }
-
- }
-
- private void removeKeystore(String key) throws SecurityException{
-
- SemaphoreLock lock = this.lockCache.acquireThrowRuntime("removeKeystore");
- try {
- if(this.cacheJCS!=null) {
- try {
- this.cacheJCS.remove(key);
- }catch(Exception e) {
- throw new SecurityException(e.getMessage(),e);
- }
- }
- else {
- this.cacheMap.remove(key);
- }
- }finally {
- this.lockCache.release(lock, "removeKeystore");
- }
-
- }
- public void removeObjectFromCache(String keyParam) throws SecurityException {
- String keyCache = this.getPrefixKey() + keyParam;
- removeKeystore(keyCache);
- }
-
- public List<String> keys() throws SecurityException{
- List<String> keys = new ArrayList<>();
- SemaphoreLock lock = this.lockCache.acquireThrowRuntime("keys");
- try {
- if(this.cacheJCS!=null) {
- try {
- List<String> l = this.cacheJCS.keys();
- if(l!=null && !l.isEmpty()) {
- keys.addAll(l);
- }
- }catch(Exception e) {
- throw new SecurityException(e.getMessage(),e);
- }
- }
- else {
- if(!this.cacheMap.isEmpty()) {
- keys.addAll(this.cacheMap.keySet());
- }
- }
- }finally {
- this.lockCache.release(lock, "keys");
- }
- return keys;
- }
-
- private T estraiKeystore(KeystoreCacheEntry<T> entry) throws SecurityException{
-
- T keystore = entry.getKeystore();
- if(this.cacheLifeSecond>-1){
- long scadenza = entry.getDate().getTime()+this.cacheLifeSecond*1000;
- long now = DateManager.getTimeMillis();
- if(scadenza<now){
- /**System.out.println("SCADUTO PER DATA ["+entry.getKey()+"] ["+scadenza+"] ["+now+"]");*/
- removeKeystore(entry.getKey());
- }
- }
- if(this.cacheJCS==null &&
- this.cacheSize>-1 &&
- this.cacheMap.size()>this.cacheSize){
- /**System.out.println("ECCEDUTA DIMENSIONE ["+entry.getKey()+"]");*/
- clearCacheMap();
- }
- return keystore;
- }
- private void clearCacheMap(){
- SemaphoreLock lock = this.lockCache.acquireThrowRuntime("clearCacheMap");
- try {
- this.cacheMap.clear();
- }finally {
- this.lockCache.release(lock, "clearCacheMap");
- }
- }
-
-
-
-
- }
- class KeystoreCacheEntry<T extends Serializable> implements Serializable {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
- @Override
- public String toString() {
- StringBuilder bf = new StringBuilder();
- bf.append("Data ").append(DateUtils.getSimpleDateFormatMs().format(this.date)).append("\n");
- bf.append(this.keystore.toString());
- return bf.toString();
- }
-
- private String key;
- private T keystore;
- private Date date;
-
- public T getKeystore() {
- return this.keystore;
- }
- public void setKeystore(T keystore) {
- this.keystore = keystore;
- }
- public Date getDate() {
- return this.date;
- }
- public void setDate(Date date) {
- this.date = date;
- }
- public String getKey() {
- return this.key;
- }
- public void setKey(String key) {
- this.key = key;
- }
-
- }