AbstractCacheImpl.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.utils.cache;

  21. import java.io.ByteArrayOutputStream;
  22. import java.io.IOException;
  23. import java.io.ObjectOutputStream;
  24. import java.io.OutputStream;

  25. import org.apache.commons.jcs3.admin.CountingOnlyOutputStream;
  26. import org.apache.commons.jcs3.engine.CacheStatus;
  27. import org.openspcoop2.utils.Utilities;
  28. import org.openspcoop2.utils.UtilsException;

  29. /**
  30.  * AbstractCacheImpl
  31.  *
  32.  * @author Poli Andrea (apoli@link.it)
  33.  * @author $Author$
  34.  * @version $Rev$, $Date$
  35.  */
  36. public abstract class AbstractCacheImpl implements ICacheImpl {

  37.     protected String cacheName = null;
  38.     protected CacheType cacheType = null;
  39.    
  40.     public AbstractCacheImpl() {
  41.        
  42.     }
  43.     public AbstractCacheImpl(CacheType cacheType, String cacheName) {
  44.         this.cacheType = cacheType;
  45.         this.cacheName = cacheName;
  46.     }
  47.    
  48.     @Override
  49.     public CacheType getType() {
  50.         return this.cacheType;
  51.     }
  52.     @Override
  53.     public String getName() {
  54.         return this.cacheName;
  55.     }
  56.    
  57.     @Override
  58.     public boolean isEternal() throws UtilsException{
  59.         return true;
  60.     }
  61.    
  62.     @Override
  63.     public String toString(){
  64.        
  65.         StringBuilder bf = new StringBuilder();
  66.        
  67.         try {
  68.             bf.append("CACHE SIZE["+this.getCacheSize()
  69.                     +"] ITEM_COUNT["+this.getItemCount()+"] ITEM_IDLE_TIME["+this.getItemIdleTime()+"] ITEM_IDLE_LIFE["+this.getItemLifeTime()
  70.                     +"] IS_ETERNAL["+this.isEternal()
  71.                     +"] CACHE_ALGO["+this.getCacheAlgoritm()+"] STATS{"+this.printStats("")+"}");
  72.             return bf.toString();
  73.         } catch (UtilsException e) {
  74.             return "NonDisponibile";
  75.         }
  76.     }
  77.     @Override
  78.     public String printKeys(String separator) throws UtilsException{
  79.         StringBuilder bf = new StringBuilder();
  80.         java.util.List<String> keys = this.keys();
  81.         for (int i = 0; i < keys.size(); i++) {
  82.             String key = (String) keys.get(i);
  83.             if(i>0){
  84.                 bf.append(separator);
  85.             }
  86.             bf.append("Cache["+i+"]=["+key+"]");
  87.         }
  88.         return bf.toString();
  89.     }
  90.    
  91.     @Override
  92.     public String printStats(String separator) throws UtilsException{
  93.         try{
  94.             ByteArrayOutputStream bout = new ByteArrayOutputStream();
  95.             this.printStats(bout,separator);
  96.             bout.flush();
  97.             bout.close();
  98.             return bout.toString();
  99.         }catch(Exception e){
  100.             throw new UtilsException(e.getMessage(),e);
  101.         }
  102.     }
  103.    
  104.     protected String _printStats(String separator, boolean thisCache) throws UtilsException {
  105.        
  106.         try{
  107.        
  108.             int tentativi = 0;
  109.             long sizeAttuale = -1;
  110.             while (tentativi<10) {
  111.                 sizeAttuale = this.getByteCount();
  112.                 if(this.errorOccursCountingBytes==false){
  113.                     break;
  114.                 }
  115.                 if(thisCache){
  116.                     //System.err.println("PROVO ALTRO TENTATIVO");
  117.                     tentativi++;
  118.                 }
  119.                 else{
  120.                     break;
  121.                 }
  122.             }
  123.            
  124.            
  125.             StringBuilder bf = new StringBuilder();
  126.                        
  127.             bf.append("Nome:");
  128.             bf.append(this.cacheName);
  129.             bf.append(" ");
  130.            
  131.             bf.append(separator);
  132.            
  133.             bf.append("Tipo:");
  134.             bf.append(this.cacheType);
  135.             bf.append(" ");
  136.            
  137.             bf.append(separator);
  138.            
  139.             bf.append("Stato:");
  140.             bf.append(CacheStatus.ALIVE); // uso terminologia JCS
  141.             bf.append(" ");
  142.            
  143.             bf.append(separator);
  144.            
  145.             // Dalla versione 3.0 non è più presente la gestione del synchronized
  146. //          bf.append("GetSyncDisabled:");
  147. //          bf.append(cache.isSyncDisabled());
  148. //          bf.append(" ");
  149. //          
  150. //          bf.append(separator);
  151.            
  152.             bf.append("Algoritmo:");
  153.             CacheAlgorithm cacheEnum = this.getCacheAlgoritm();
  154.             if(cacheEnum!=null){
  155.                 bf.append(cacheEnum.name());
  156.             }else{
  157.                 bf.append("-");
  158.             }
  159.             bf.append(" ");
  160.            
  161.             bf.append(separator);
  162.            
  163.             bf.append("Dimensione:");
  164.             bf.append(this.getCacheSize());
  165.             bf.append(" ");
  166.            
  167.             bf.append(separator);
  168.            
  169.            
  170.             bf.append("ElementiInCache:");
  171.             bf.append(this.getItemCount());
  172.             bf.append(" ");
  173.            
  174.             bf.append(separator);
  175.            
  176.             bf.append("MemoriaOccupata:");
  177.             bf.append(Utilities.convertBytesToFormatString(sizeAttuale));
  178.             bf.append(" ");
  179.            
  180.             bf.append(separator);
  181.            
  182.            
  183.             bf.append("IdleTime:");
  184.             long idleTime = this.getItemIdleTime();
  185.             if(idleTime>0){
  186.                 bf.append(Utilities.convertSystemTimeIntoStringMillisecondi(idleTime*1000,false));
  187.             }
  188.             else if(idleTime==0){
  189.                 bf.append("0");
  190.             }
  191.             else if(idleTime<0){
  192.                 bf.append("Infinito");
  193.             }
  194.             bf.append(" ");
  195.            
  196.             bf.append(separator);
  197.                
  198.             bf.append("LifeTime:");
  199.             long lifeTime = this.getItemLifeTime();
  200.             if(lifeTime>0){
  201.                 bf.append(Utilities.convertSystemTimeIntoStringMillisecondi(lifeTime*1000,false));
  202.             }
  203.             else if(lifeTime==0){
  204.                 bf.append("0");
  205.             }
  206.             else if(lifeTime<0){
  207.                 if(this.isEternal()) {
  208.                     bf.append("Infinito");
  209.                 }
  210.                 else {
  211.                     bf.append("Infinito (NoEternal?)");
  212.                 }
  213.             }
  214.             bf.append(" ");
  215.            
  216.             bf.append(separator);
  217.            
  218.             return bf.toString();
  219.            
  220.         }catch(Throwable e){
  221.             throw new UtilsException(e.getMessage(),e);
  222.         }
  223.     }

  224.     protected void _printStats(OutputStream out, String separator, boolean thisCache) throws UtilsException {
  225.         try{
  226.             out.write(_printStats(separator, thisCache).getBytes());
  227.         }catch(Exception e){
  228.             throw new UtilsException(e.getMessage(),e);
  229.         }
  230.     }
  231.    
  232.     private boolean errorOccursCountingBytes_debug = false;
  233.     private boolean errorOccursCountingBytes = false;
  234.     protected long getByteCount() {
  235.        
  236.         this.errorOccursCountingBytes = false;
  237.         long size = 0;
  238.         try {
  239.             for (String key : this.keys())
  240.             {
  241.                
  242.                 Object element = null;
  243.                 try
  244.                 {
  245.                     element = this.get(key);
  246.                 }
  247.                 catch (Throwable e)
  248.                 {
  249.                     if(this.errorOccursCountingBytes_debug) {
  250.                         System.err.println("["+this.cacheName+"] Element cache get");
  251.                         e.printStackTrace(System.err);
  252.                     }
  253.                     this.errorOccursCountingBytes = true;
  254.                     continue;
  255.                     //throw new RuntimeException("IOException while trying to get a cached element", e);
  256.                 }

  257.                 if (element == null)
  258.                 {
  259.                     continue;
  260.                 }

  261.                 //CountingOnlyOutputStream: Keeps track of the number of bytes written to it, but doesn't write them anywhere.
  262.                 CountingOnlyOutputStream counter = new CountingOnlyOutputStream();
  263.                 try (ObjectOutputStream out = new ObjectOutputStream(counter);)
  264.                 {
  265.                     out.writeObject(element);
  266.                 }
  267.                 catch (Throwable e)
  268.                 {
  269.                     if(this.errorOccursCountingBytes_debug) {
  270.                         System.err.println("["+this.cacheName+"] Element cache writeObject ("+element.getClass().getName()+")");
  271.                         e.printStackTrace(System.err);
  272.                     }
  273.                     this.errorOccursCountingBytes = true;
  274.                     continue;
  275.                     //throw new RuntimeException("IOException while trying to measure the size of the cached element", e);
  276.                 }
  277.                 finally
  278.                 {
  279.                     try
  280.                     {
  281.                         counter.close();
  282.                     }
  283.                     catch (IOException e)
  284.                     {
  285.                         // ignore
  286.                     }
  287.                 }

  288.                 // 4 bytes lost for the serialization header
  289.                 size += counter.getCount() - 4;
  290.                
  291.             }
  292.         }
  293.         catch ( Exception e )
  294.         {
  295.             System.err.println( "Problem getting byte count (Modified by GovWay).  Likley cause is a non serilizable object." + e.getMessage() );
  296.             e.printStackTrace(System.err);  
  297.         }
  298.        
  299.         return size;
  300.     }
  301. }