GestoreCacheResponseCaching.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */
  20. package org.openspcoop2.pdd.core.response_caching;

  21. import java.text.SimpleDateFormat;
  22. import java.util.Date;

  23. import org.openspcoop2.core.commons.CoreException;
  24. import org.openspcoop2.core.config.constants.CostantiConfigurazione;
  25. import org.openspcoop2.pdd.logger.OpenSPCoop2Logger;
  26. import org.openspcoop2.utils.SemaphoreLock;
  27. import org.openspcoop2.utils.UtilsException;
  28. import org.openspcoop2.utils.cache.Cache;
  29. import org.openspcoop2.utils.cache.CacheAlgorithm;
  30. import org.openspcoop2.utils.cache.CacheType;
  31. import org.openspcoop2.utils.date.DateManager;
  32. import org.openspcoop2.utils.date.DateUtils;
  33. import org.openspcoop2.utils.id.UniqueIdentifierManager;
  34. import org.slf4j.Logger;

  35. /**    
  36.  * GestoreCacheResponseCaching
  37.  *
  38.  * @author Poli Andrea (poli@link.it)
  39.  * @author $Author$
  40.  * @version $Rev$, $Date$
  41.  */
  42. public class GestoreCacheResponseCaching {

  43.     /** Chiave della cache per l'autenticazione Buste  */
  44.     private static final String RESPONSE_CACHING_CACHE_NAME = "responseCaching";
  45.     /** Cache */
  46.     private static Cache cache = null;
  47.     private static final org.openspcoop2.utils.Semaphore lock_cache = new org.openspcoop2.utils.Semaphore("GestoreCacheResponseCaching");
  48.    

  49.     /* --------------- Cache --------------------*/
  50.     public static boolean isCacheAbilitata() {
  51.         return cache!=null;
  52.     }
  53.     public static void resetCache() throws Exception{
  54.         try{
  55.             if(cache!=null){
  56.                 cache.clear();
  57.             }
  58.         }catch(Exception e){
  59.             throw new Exception("Reset della cache per i dati contenenti le risposte salvate non riuscita: "+e.getMessage(),e);
  60.         }
  61.     }
  62.     public static String printStatsCache(String separator) throws Exception{
  63.         try{
  64.             if(cache!=null){
  65.                 try{
  66.                     return cache.printStats(separator);
  67.                 }catch(Exception e){
  68.                     throw new Exception(e.getMessage(),e);
  69.                 }
  70.             }else{
  71.                 throw new Exception("Cache non abilitata");
  72.             }
  73.         }catch(Exception e){
  74.             throw new Exception("Visualizzazione Statistiche riguardante la cache per i dati contenenti le risposte salvate non riuscita: "+e.getMessage(),e);
  75.         }
  76.     }
  77.     public static void abilitaCache() throws Exception{
  78.         try{
  79.             if(cache!=null)
  80.                 throw new Exception("Cache gia' abilitata");
  81.             else{
  82.                 _abilitaCache();
  83.             }
  84.         }catch(Exception e){
  85.             throw new Exception("Abilitazione cache per i dati contenenti le risposte salvate non riuscita: "+e.getMessage(),e);
  86.         }
  87.     }
  88.     private static synchronized void _abilitaCache() throws Exception{
  89.         try{
  90.             if(cache==null) {
  91.                 cache = new Cache(CacheType.JCS, RESPONSE_CACHING_CACHE_NAME);  // lascio JCS come default abilitato via jmx
  92.                 cache.build();
  93.             }
  94.         }catch(Exception e){
  95.             throw new Exception("Abilitazione cache per i dati contenenti le risposte salvate non riuscita: "+e.getMessage(),e);
  96.         }
  97.     }
  98.     public static void abilitaCache(Long dimensioneCache,Boolean algoritmoCacheLRU,Long itemIdleTime,Long itemLifeSecond, Logger log) throws Exception{
  99.         try{
  100.             if(cache!=null)
  101.                 throw new Exception("Cache gia' abilitata");
  102.             else{
  103.                 int dimensione = -1;
  104.                 if(dimensioneCache!=null){
  105.                     dimensione = dimensioneCache.intValue();
  106.                 }
  107.                 initCache(CacheType.JCS, dimensione, algoritmoCacheLRU, itemIdleTime, itemLifeSecond, log);  // lascio JCS come default abilitato via jmx
  108.             }
  109.         }catch(Exception e){
  110.             throw new Exception("Abilitazione cache per i dati contenenti le risposte salvate non riuscita: "+e.getMessage(),e);
  111.         }
  112.     }
  113.     public static void disabilitaCache() throws Exception{
  114.         try{
  115.             if(cache==null)
  116.                 throw new Exception("Cache gia' disabilitata");
  117.             else{
  118.                 _disabilitaCache();
  119.             }
  120.         }catch(Exception e){
  121.             throw new Exception("Disabilitazione cache per i dati contenenti le risposte salvate non riuscita: "+e.getMessage(),e);
  122.         }
  123.     }  
  124.     private static synchronized void _disabilitaCache() throws Exception{
  125.         try{
  126.             if(cache!=null) {
  127.                 cache.clear();
  128.                 cache = null;
  129.             }
  130.         }catch(Exception e){
  131.             throw new Exception("Disabilitazione cache per i dati contenenti le risposte salvate non riuscita: "+e.getMessage(),e);
  132.         }
  133.     }  
  134.     public static String listKeysCache(String separator) throws Exception{
  135.         try{
  136.             if(cache!=null){
  137.                 try{
  138.                     return cache.printKeys(separator);
  139.                 }catch(Exception e){
  140.                     throw new Exception(e.getMessage(),e);
  141.                 }
  142.             }else{
  143.                 throw new Exception("Cache non abilitata");
  144.             }
  145.         }catch(Exception e){
  146.             throw new Exception("Visualizzazione chiavi presenti nella cache per i dati contenenti le risposte salvate non riuscita: "+e.getMessage(),e);
  147.         }
  148.     }
  149.    
  150.     public static String getObjectCache(String key) throws Exception{
  151.         try{
  152.             if(cache!=null){
  153.                 try{
  154.                     Object o = cache.get(key);
  155.                     if(o!=null){
  156.                         return o.toString();
  157.                     }else{
  158.                         return "oggetto con chiave ["+key+"] non presente";
  159.                     }
  160.                 }catch(Exception e){
  161.                     throw new Exception(e.getMessage(),e);
  162.                 }
  163.             }else{
  164.                 throw new Exception("Cache non abilitata");
  165.             }
  166.         }catch(Exception e){
  167.             throw new Exception("Visualizzazione oggetto presente nella cache per i dati contenenti le risposte salvate non riuscita: "+e.getMessage(),e);
  168.         }
  169.     }
  170.    
  171.     public static void removeObjectCache(String key) throws Exception{
  172.         try{
  173.             if(cache!=null){
  174.                 try{
  175.                     cache.remove(key);
  176.                 }catch(Exception e){
  177.                     throw new Exception(e.getMessage(),e);
  178.                 }
  179.             }else{
  180.                 throw new Exception("Cache non abilitata");
  181.             }
  182.         }catch(Exception e){
  183.             throw new Exception("Rimozione oggetto presente nella cache per i dati contenenti le risposte salvate non riuscita: "+e.getMessage(),e);
  184.         }
  185.     }
  186.    

  187.     /*----------------- INIZIALIZZAZIONE --------------------*/

  188.     public static void initialize(Logger log) throws Exception{
  189.         GestoreCacheResponseCaching.initialize(null, false, -1,null,-1l,-1l, log);
  190.     }
  191.     public static void initialize(CacheType cacheType, int dimensioneCache,String algoritmoCache,
  192.             long idleTime, long itemLifeSecond, Logger log) throws Exception{
  193.         GestoreCacheResponseCaching.initialize(cacheType, true, dimensioneCache,algoritmoCache,idleTime,itemLifeSecond, log);
  194.     }

  195.     private static void initialize(CacheType cacheType, boolean cacheAbilitata,int dimensioneCache,String algoritmoCache,
  196.             long idleTime, long itemLifeSecond, Logger log) throws Exception{

  197.         // Inizializzazione Cache
  198.         if(cacheAbilitata){
  199.             GestoreCacheResponseCaching.initCache(cacheType, dimensioneCache, algoritmoCache, idleTime, itemLifeSecond, log);
  200.         }

  201.     }
  202.     private static void initCache(CacheType cacheType, Integer dimensioneCache,String algoritmoCache,Long itemIdleTime,Long itemLifeSecond,Logger alog) throws Exception{
  203.         initCache(cacheType, dimensioneCache, CostantiConfigurazione.CACHE_LRU.toString().equalsIgnoreCase(algoritmoCache), itemIdleTime, itemLifeSecond, alog);
  204.     }
  205.    
  206.     private static void initCache(CacheType cacheType, Integer dimensioneCache,boolean algoritmoCacheLRU,Long itemIdleTime,Long itemLifeSecond,Logger alog) throws Exception{
  207.        
  208.         cache = new Cache(cacheType, RESPONSE_CACHING_CACHE_NAME);
  209.    
  210.         // dimensione
  211.         if(dimensioneCache!=null && dimensioneCache>0){
  212.             try{
  213.                 String msg = "Dimensione della cache (ResponseCaching) impostata al valore: "+dimensioneCache;
  214.                 alog.info(msg);
  215.                 cache.setCacheSize(dimensioneCache);
  216.             }catch(Exception error){
  217.                 String msg = "Parametro errato per la dimensione della cache (ResponseCaching): "+error.getMessage();
  218.                 alog.error(msg);
  219.                 throw new Exception(msg,error);
  220.             }
  221.         }
  222.        
  223.         // algoritno
  224.         String msg = "Algoritmo di cache (ResponseCaching) impostato al valore: LRU";
  225.         if(!algoritmoCacheLRU){
  226.             msg = "Algoritmo di cache (ResponseCaching) impostato al valore: MRU";
  227.         }
  228.         alog.info(msg);
  229.         if(!algoritmoCacheLRU)
  230.             cache.setCacheAlgoritm(CacheAlgorithm.MRU);
  231.         else
  232.             cache.setCacheAlgoritm(CacheAlgorithm.LRU);
  233.        
  234.        
  235.         // idle time
  236.         if(itemIdleTime!=null && itemIdleTime>0){
  237.             try{
  238.                 msg = "Attributo 'IdleTime' (ResponseCaching) impostato al valore: "+itemIdleTime;
  239.                 alog.info(msg);
  240.                 cache.setItemIdleTime(itemIdleTime);
  241.             }catch(Exception error){
  242.                 msg = "Parametro errato per l'attributo 'IdleTime' (ResponseCaching): "+error.getMessage();
  243.                 alog.error(msg);
  244.                 throw new Exception(msg,error);
  245.             }
  246.         }
  247.        
  248.         // LifeSecond
  249.         long longItemLife = -1;
  250.         if(itemLifeSecond!=null && itemLifeSecond>0){
  251.             longItemLife = itemLifeSecond.longValue();
  252.         }
  253.         try{
  254.             msg = "Attributo 'MaxLifeSecond' (ResponseCaching) impostato al valore: "+longItemLife;
  255.             alog.info(msg);
  256.             cache.setItemLifeTime(longItemLife);
  257.         }catch(Exception error){
  258.             msg = "Parametro errato per l'attributo 'MaxLifeSecond' (ResponseCaching): "+error.getMessage();
  259.             alog.error(msg);
  260.             throw new Exception(msg,error);
  261.         }
  262.        
  263.         cache.build();
  264.     }
  265.    
  266.    
  267.     @SuppressWarnings("deprecation")
  268.     @Deprecated
  269.     public static void disableSyncronizedGet() throws UtilsException {
  270.         if(cache==null) {
  271.             throw new UtilsException("Cache disabled");
  272.         }
  273.         cache.disableSyncronizedGet();
  274.     }
  275.     @SuppressWarnings("deprecation")
  276.     @Deprecated
  277.     public static boolean isDisableSyncronizedGet() throws UtilsException {
  278.         if(cache==null) {
  279.             throw new UtilsException("Cache disabled");
  280.         }
  281.         return cache.isDisableSyncronizedGet();
  282.     }
  283.    
  284.    
  285.    
  286.     private static GestoreCacheResponseCaching staticInstance = null;
  287.     public static synchronized void initialize() {
  288.         if(staticInstance==null){
  289.             staticInstance = new GestoreCacheResponseCaching();
  290.         }
  291.     }
  292.     public static GestoreCacheResponseCaching getInstance() throws CoreException{
  293.         if(staticInstance==null){
  294.             // spotbugs warning 'SING_SINGLETON_GETTER_NOT_SYNCHRONIZED': l'istanza viene creata allo startup
  295.             synchronized (GestoreCacheResponseCaching.class) {
  296.                 throw new CoreException("GestoreCacheResponseCaching non inizializzato");
  297.             }
  298.         }
  299.         return staticInstance;
  300.     }
  301.    
  302.     private Logger log;
  303.    
  304.     private GestoreCacheResponseCaching() {
  305.         this.log = OpenSPCoop2Logger.getLoggerOpenSPCoopCore();
  306.     }
  307.    

  308.    
  309.    
  310.    
  311.    
  312.    
  313.    
  314.    
  315.     /* ********************** ENGINE ************************** */
  316.    
  317.     public String save(String digest, ResponseCached response) throws Exception{
  318.        
  319.         String uuid = null;
  320.         try{

  321.             if(cache==null) {
  322.                 throw new Exception("Cache per il salvataggio delle risposte non abilitata");
  323.             }
  324.            
  325.             if(digest == null)
  326.                 throw new Exception("Digest non definito");
  327.             if(response == null)
  328.                 throw new Exception("Risposta non definita");
  329.            
  330.             String digestKey = formatKeyDigest(digest);
  331.            
  332.             // Fix: devo prima verificare se ho la chiave in cache prima di mettermi in sincronizzazione.
  333.             Object o = cache.get(digestKey);
  334.             if(o!=null) {
  335.                 org.openspcoop2.utils.cache.CacheResponse responseCache =
  336.                         (org.openspcoop2.utils.cache.CacheResponse)  o;
  337.                 return ((ResponseCached)responseCache.getObject()).getUuid(); // already saved concurrent thread
  338.             }
  339.            
  340.             //synchronized (cache) {
  341.             SemaphoreLock lock = lock_cache.acquire("save");
  342.             try {
  343.                
  344.                 o = cache.get(digestKey);
  345.                 if(o!=null) {
  346.                     org.openspcoop2.utils.cache.CacheResponse responseCache =
  347.                             (org.openspcoop2.utils.cache.CacheResponse)  o;
  348.                     return ((ResponseCached)responseCache.getObject()).getUuid(); // already saved concurrent thread
  349.                 }
  350.                
  351.                 uuid = UniqueIdentifierManager.newUniqueIdentifier().getAsString();
  352.                 String uuidKey = formatKeyUUID(uuid);
  353.                
  354.                 try{    
  355.                     cache.put(uuidKey,digestKey);
  356.                 }catch(UtilsException e){
  357.                     this.log.error("Errore durante l'inserimento in cache con chiave ["+uuidKey+"] valore["+digestKey+"]: "+e.getMessage());
  358.                 }
  359.                
  360.                 try{    
  361.                     org.openspcoop2.utils.cache.CacheResponse responseCache = new org.openspcoop2.utils.cache.CacheResponse();
  362.                     response.setUuid(uuid);
  363.                     response.setDigest(digest);
  364.                     responseCache.setObject((java.io.Serializable)response);
  365.                     cache.put(digestKey,responseCache);
  366.                 }catch(UtilsException e){
  367.                     this.log.error("Errore durante l'inserimento in cache con chiave ["+digestKey+"] della risposta: "+e.getMessage());
  368.                     try {
  369.                         cache.remove(uuidKey); // precedentemente aggiunto
  370.                     }catch(Throwable tIgnore) {}
  371.                 }
  372.                
  373.             }finally {
  374.                 lock_cache.release(lock, "save");
  375.             }

  376.         }
  377.         catch(Exception e){
  378.             this.log.error(e.getMessage(),e);
  379.             throw new Exception("Salvataggio in Cache fallito: "+e.getMessage(),e);
  380.         }

  381.         return uuid;
  382.        
  383.     }
  384.    
  385.    
  386.    
  387.     public ResponseCached readByUUID(String uuid) throws Exception{
  388.        
  389.         try{

  390.             if(cache==null) {
  391.                 throw new Exception("Cache per il salvataggio delle risposte non abilitata");
  392.             }
  393.            
  394.             if(uuid == null)
  395.                 throw new Exception("UUID non definito");

  396.             String uuidKey = formatKeyUUID(uuid);
  397.            
  398.             // Fix: devo prima verificare se ho la chiave in cache prima di mettermi in sincronizzazione.
  399.            
  400.             Object oDigest = cache.get(uuidKey);
  401.             if(oDigest==null) {
  402.                 return null; // messaggio non precedentemente salvato
  403.             }
  404.            
  405.             String digest = (String) oDigest;
  406.             String digestKey = formatKeyDigest(digest);
  407.            
  408.             org.openspcoop2.utils.cache.CacheResponse response =
  409.                     (org.openspcoop2.utils.cache.CacheResponse) cache.get(digestKey);
  410.             if(response == null || response.getObject()==null){
  411.                 // la rimozione la faccio in modalita' sincronizzata
  412.             }
  413.             else {
  414.                 ResponseCached responseCached = (ResponseCached) response.getObject();
  415.                 Date now = DateManager.getDate();
  416.                 if(now.after(responseCached.getScadenza())) {
  417.                     // la rimozione la faccio in modalita' sincronizzata
  418.                 }
  419.                 else {
  420.                     return responseCached;
  421.                 }
  422.             }
  423.            
  424.             //synchronized (cache) {
  425.             SemaphoreLock lock = lock_cache.acquire("readByUUID");
  426.             try {
  427.                
  428.                 oDigest = cache.get(uuidKey);
  429.                 if(oDigest==null) {
  430.                     return null; // messaggio non precedentemente salvato
  431.                 }
  432.                 digest = (String) oDigest;
  433.                 digestKey = formatKeyDigest(digest);
  434.            
  435.                 response =
  436.                         (org.openspcoop2.utils.cache.CacheResponse) cache.get(digestKey);
  437.                 if(response == null || response.getObject()==null){
  438.                     this.log.error("In cache non è presente il mapping uuid ("+uuidKey+") - digest ("+digestKey+") ma poi non esiste l'oggetto??");
  439.                     cache.remove(uuidKey);
  440.                     return null;
  441.                 }
  442.                
  443.                 ResponseCached responseCached = (ResponseCached) response.getObject();
  444.                 Date now = DateManager.getDate();
  445.                 if(now.after(responseCached.getScadenza())) {
  446.                     SimpleDateFormat dateformat = DateUtils.getSimpleDateFormatMs();
  447.                     String scadenza = dateformat.format(responseCached.getScadenza());
  448.                     String nowS = dateformat.format(now);
  449.                     this.log.debug("In cache è presente un messaggio [uuid ("+uuidKey+") - digest ("+digestKey+")] scaduto (scadenza:"+scadenza+") (now:"+nowS+")");
  450.                     cache.remove(uuidKey);
  451.                     cache.remove(digestKey);
  452.                     return null;
  453.                 }
  454.                
  455.                 return responseCached;
  456.                
  457.             }finally {
  458.                 lock_cache.release(lock, "readByUUID");
  459.             }

  460.         }
  461.         catch(Exception e){
  462.             this.log.error(e.getMessage(),e);
  463.             throw new Exception("Lettura messaggio in Cache fallito: "+e.getMessage(),e);
  464.         }
  465.        
  466.     }
  467.    
  468.     public void removeByUUID(String uuid) throws Exception{
  469.        
  470.         try{

  471.             if(cache==null) {
  472.                 throw new Exception("Cache per il salvataggio delle risposte non abilitata");
  473.             }
  474.            
  475.             if(uuid == null)
  476.                 throw new Exception("UUID non definito");

  477.             String uuidKey = formatKeyUUID(uuid);
  478.            
  479.             // Fix: devo prima verificare se ho la chiave in cache prima di mettermi in sincronizzazione.
  480.            
  481.             Object oDigest = cache.get(uuidKey);
  482.             if(oDigest==null) {
  483.                 return; // messaggio non precedentemente salvato
  484.             }
  485.                        
  486.             //synchronized (cache) {
  487.             SemaphoreLock lock = lock_cache.acquire("removeByUUID");
  488.             try {
  489.                
  490.                 oDigest = cache.get(uuidKey);
  491.                 if(oDigest==null) {
  492.                     return; // messaggio non precedentemente salvato
  493.                 }
  494.                 String digest = (String) oDigest;
  495.                 String digestKey = formatKeyDigest(digest);
  496.            
  497.                 org.openspcoop2.utils.cache.CacheResponse response =
  498.                         (org.openspcoop2.utils.cache.CacheResponse) cache.get(digestKey);
  499.                 if(response == null || response.getObject()==null){
  500.                     this.log.error("In cache non è presente il mapping uuid ("+uuidKey+") - digest ("+digestKey+") ma poi non esiste l'oggetto??");
  501.                     cache.remove(uuidKey);
  502.                     return;
  503.                 }
  504.                
  505.                 cache.remove(uuidKey);
  506.                 cache.remove(digestKey);
  507.                
  508.             }finally{
  509.                 lock_cache.release(lock, "removeByUUID");
  510.             }

  511.         }
  512.         catch(Exception e){
  513.             this.log.error(e.getMessage(),e);
  514.             throw new Exception("Rimozione messaggio in Cache fallito: "+e.getMessage(),e);
  515.         }
  516.        
  517.     }
  518.    
  519.     public ResponseCached readByDigest(String digest) throws Exception{
  520.        
  521.         try{

  522.             if(cache==null) {
  523.                 throw new Exception("Cache per il salvataggio delle risposte non abilitata");
  524.             }
  525.            
  526.             if(digest == null)
  527.                 throw new Exception("Digest non definito");

  528.             String digestKey = formatKeyDigest(digest);
  529.                
  530.            
  531.             // Fix: devo prima verificare se ho la chiave in cache prima di mettermi in sincronizzazione.
  532.            
  533.             org.openspcoop2.utils.cache.CacheResponse response =
  534.                     (org.openspcoop2.utils.cache.CacheResponse) cache.get(digestKey);
  535.             if(response == null || response.getObject()==null){
  536.                 return null;
  537.             }
  538.            
  539.             ResponseCached responseCached = (ResponseCached) response.getObject();
  540.             Date now = DateManager.getDate();
  541.             if(now.after(responseCached.getScadenza())) {
  542.                 // effettuo il controllo in modalita' sincronizzazione per fare le rimozioni
  543.             }
  544.             else {
  545.                 return responseCached;
  546.             }
  547.                        
  548.             //synchronized (cache) {
  549.             SemaphoreLock lock = lock_cache.acquire("readByDigest");
  550.             try {
  551.                
  552.                 response =
  553.                         (org.openspcoop2.utils.cache.CacheResponse) cache.get(digestKey);
  554.                 if(response == null || response.getObject()==null){
  555.                     return null;
  556.                 }
  557.                
  558.                 responseCached = (ResponseCached) response.getObject();
  559.                 now = DateManager.getDate();
  560.                 if(now.after(responseCached.getScadenza())) {
  561.                     String uuidKey = formatKeyUUID(responseCached.getUuid());
  562.                     SimpleDateFormat dateformat = DateUtils.getSimpleDateFormatMs();
  563.                     String scadenza = dateformat.format(responseCached.getScadenza());
  564.                     String nowS = dateformat.format(now);
  565.                     this.log.debug("In cache è presente un messaggio [uuid ("+uuidKey+") - digest ("+digestKey+")] scaduto (scadenza:"+scadenza+") (now:"+nowS+")");
  566.                     cache.remove(uuidKey);
  567.                     cache.remove(digestKey);
  568.                     return null;
  569.                 }

  570.                 return responseCached;
  571.                
  572.             }finally {
  573.                 lock_cache.release(lock, "readByDigest");
  574.             }

  575.         }
  576.         catch(Exception e){
  577.             this.log.error(e.getMessage(),e);
  578.             throw new Exception("Lettura messaggio in Cache fallito: "+e.getMessage(),e);
  579.         }
  580.        
  581.     }
  582.    
  583.    
  584.     public static String formatKeyUUID(String uuid) {
  585.         String prefix = "uuid:";
  586.         if(uuid.startsWith(prefix)==false) {
  587.             return prefix+uuid;
  588.         }
  589.         else {
  590.             return uuid;
  591.         }
  592.     }
  593.    
  594.     public static String formatKeyDigest(String digest) {
  595.         String prefix = "digest:";
  596.         if(digest.startsWith(prefix)==false) {
  597.             return prefix+digest;
  598.         }
  599.         else {
  600.             return digest;
  601.         }
  602.     }
  603. }