DatiCollezionatiDistributedPNCounter.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.controllo_traffico.policy.driver.hazelcast.counters;

  21. import java.util.ArrayList;
  22. import java.util.Date;
  23. import java.util.List;

  24. import org.openspcoop2.core.controllo_traffico.beans.ActivePolicy;
  25. import org.openspcoop2.core.controllo_traffico.beans.DatiCollezionati;
  26. import org.openspcoop2.core.controllo_traffico.beans.IDUnivocoGroupByPolicyMapId;
  27. import org.openspcoop2.core.controllo_traffico.beans.IDatiCollezionatiDistributed;
  28. import org.openspcoop2.core.controllo_traffico.constants.TipoControlloPeriodo;
  29. import org.openspcoop2.pdd.core.controllo_traffico.policy.driver.BuilderDatiCollezionatiDistributed;
  30. import org.openspcoop2.utils.SemaphoreLock;
  31. import org.slf4j.Logger;

  32. import com.hazelcast.core.HazelcastInstance;
  33. /**
  34.  *  Con il PNCounter accettiamo qualche tipo di inconsistenza ovvero:
  35.  *  
  36.  *  I valori dei contatori su di un nodo possono differire da quelle di un altro nodo perchè le notifiche sui contatori giunte ai due nodi fino al tempo T sono state diverse.
  37.  *  Dunque capita che lo stato locale non rifletta lo stato globale.
  38.  *  I PNCounter garantiscono comunque che dopo un certo lasso di tempo il valore locale dei contatori converge al valore esatto per tutti i nodi, dalla documentazione infatti:
  39.  *
  40.  *  The counter guarantees that whenever two members have received the same set of updates, possibly in a different order, their state is identical, and any conflicting updates are merged automatically.
  41.  *  If no new updates are made to the shared state, all members that can communicate will eventually have the same data.
  42.  *
  43.  *  The updates to the counter are applied locally when invoked on a CRDT replica.
  44.  *
  45.  *  https://docs.hazelcast.com/hazelcast/5.3/data-structures/pn-counter
  46.  *
  47.  * Attenzione:  Nel caso si diminuisse il numero delle repliche per il PNCounter, che di default è a INTEGER.MAX_VALUE per cui ogni membro ha la sua replica,
  48.  *  gli aggiornamenti potrebbero non raggiungere il membro che ha fatto partire la modifica, sollevando una ConsistencyLostException.
  49.  *  
  50.  * @author Francesco Scarlato (scarlato@link.it)
  51.  * @author $Author$
  52.  * @version $Rev$, $Date$
  53.  */
  54. public class DatiCollezionatiDistributedPNCounter extends DatiCollezionati implements IDatiCollezionatiDistributed {

  55.     private static final long serialVersionUID = 1L;
  56.    
  57.     private final transient org.openspcoop2.utils.Semaphore lock = new org.openspcoop2.utils.Semaphore("DatiCollezionatiDistributedPNCounter");
  58.    
  59.     private final transient HazelcastInstance hazelcast;
  60.     private final IDUnivocoGroupByPolicyMapId groupByPolicyMapId;
  61.     private final int groupByPolicyMapIdHashCode;

  62.     // data di registrazione/aggiornamento policy
  63.    
  64.     // final: sono i contatori che non dipendono da una finestra temporale
  65.    
  66.     // sono rimasti AtomicLong le date
  67.    
  68.     private final transient DatoAtomicLong distributedUpdatePolicyDate; // data di ultima modifica della policy
  69.     private final transient DatoAtomicLong distributedPolicyDate; // intervallo corrente su cui vengono costruiti gli altri contatori
  70.    
  71.     private transient DatoPNCounter distributedPolicyRequestCounter; // numero di richieste effettuato nell'intervallo
  72.     private transient DatoPNCounter distributedPolicyCounter; // utilizzato per tempi o banda
  73.        
  74.     private final transient DatoAtomicLong distributedPolicyDegradoPrestazionaleDate; // intervallo corrente su cui vengono costruiti gli altri contatori
  75.     private transient DatoPNCounter distributedPolicyDegradoPrestazionaleRequestCounter; // numero di richieste effettuato nell'intervallo
  76.     private transient DatoPNCounter distributedPolicyDegradoPrestazionaleCounter; // contatore del degrado
  77.    
  78.     private final boolean distribuitedActiveRequestCounterPolicyRichiesteSimultanee;
  79.     private final transient DatoPNCounter distributedActiveRequestCounterForStats; // numero di richieste simultanee
  80.     private transient DatoPNCounter distributedActiveRequestCounterForCheck; // numero di richieste simultanee
  81.    
  82.     private transient DatoPNCounter distributedPolicyDenyRequestCounter; // policy bloccate
  83.    
  84.     // I contatori da eliminare
  85.     // Se si effettua il drop di un contatore quando si rileva il cambio di intervallo, potrebbe succedere che in un altro nodo del cluster che sta effettuando la fase di 'end'
  86.     // non rilevi più il contatore e di fatto quindi lo riprende partenzo da 0. Poi a sua volta capisce il cambio di intervallo e lo rielimina.
  87.     // per questo motivo, il drop viene effettuato al secondo cambio di intervallo, e ad ogni cambio i contatori vengono collezionati nel cestino
  88.     private transient List<DatoPNCounter> cestinoPolicyCounters = new ArrayList<>();
  89.     private transient List<DatoPNCounter> cestinoPolicyCountersDegradoPrestazionale = new ArrayList<>();
  90.    
  91.     private boolean initialized = false;

  92.     private String getPNCounterName(String name, Long date) {
  93.         String t = "";
  94.         if(date!=null) {
  95.             t = date + "";
  96.         }
  97.        
  98.         String configDate = BuilderDatiCollezionatiDistributed.DISTRUBUITED_SUFFIX_CONFIG_DATE+
  99.                 (this.gestorePolicyConfigDate!=null ? this.gestorePolicyConfigDate.getTime() : -1);
  100.        
  101.         return "pncounter-"+this.groupByPolicyMapIdHashCode+"-"+name+t+configDate+"-rl"; // non modificare inizio e fine poichè configurato in hazelcast config
  102.     }
  103.    
  104.     public DatiCollezionatiDistributedPNCounter(Logger log, Date updatePolicyDate, Date gestorePolicyConfigDate, HazelcastInstance hazelcast, IDUnivocoGroupByPolicyMapId groupByPolicyMapId, ActivePolicy activePolicy) {
  105.         super(updatePolicyDate, gestorePolicyConfigDate);
  106.    
  107.         this.hazelcast = hazelcast;
  108.         this.groupByPolicyMapId = groupByPolicyMapId;
  109.         this.groupByPolicyMapIdHashCode = this.groupByPolicyMapId.hashCode();
  110.        
  111.         this.initDatiIniziali(activePolicy);
  112.         this.checkDate(log, activePolicy); // inizializza le date se ci sono
  113.        
  114.         this.distributedPolicyDate = this.initPolicyDate();
  115.         this.distributedUpdatePolicyDate = this.initUpdatePolicyDate();
  116.        
  117.         this.distributedPolicyDegradoPrestazionaleDate = this.initPolicyDegradoPrestazionaleDate();

  118.         this.distribuitedActiveRequestCounterPolicyRichiesteSimultanee = activePolicy.getConfigurazionePolicy().isSimultanee() &&
  119.                 TipoControlloPeriodo.REALTIME.equals(activePolicy.getConfigurazionePolicy().getModalitaControllo());
  120.         if(this.distribuitedActiveRequestCounterPolicyRichiesteSimultanee){
  121.             this.distributedActiveRequestCounterForCheck = this.initActiveRequestCounters();
  122.             this.distributedActiveRequestCounterForStats = null;
  123.         }
  124.         else {
  125.             this.distributedActiveRequestCounterForStats = this.initActiveRequestCounters();
  126.         }
  127.        
  128.         if(this.policyRealtime!=null && this.policyRealtime){
  129.             initPolicyCounters(super.getPolicyDate().getTime());
  130.         }
  131.         if(this.policyDegradoPrestazionaleRealtime!=null && this.policyDegradoPrestazionaleRealtime){
  132.             initPolicyCountersDegradoPrestazionale(super.getPolicyDegradoPrestazionaleDate().getTime());
  133.         }
  134.        
  135.         // Gestisco la updatePolicyDate qui.
  136.         // se updatePolicyDate è > this.distributedUpdatePolicyDate.get() allora resetto i contatori del cluster e setto la nuova data distribuita.
  137.         // Questo per via di come funziona l'aggiornamento delle policy: i datiCollezionati correnti per una map<IDUnivoco..., DatiCollezionati> vengono cancellati e reinizializzati.
  138.         // Per gli altri nodi in esecuzione, la updatePolicyDate locale resta sempre la stessa, ma non viene usata.
  139.         if(this.policyRealtime!=null && this.policyRealtime &&
  140.             updatePolicyDate != null && this.distributedUpdatePolicyDate!=null && this.distributedUpdatePolicyDate.get() < updatePolicyDate.getTime()) {
  141.             this.resetCounters(updatePolicyDate);
  142.         }
  143.        
  144.         this.initialized = true;
  145.     }
  146.        
  147.     public DatiCollezionatiDistributedPNCounter(Logger log, DatiCollezionati dati, HazelcastInstance hazelcast, IDUnivocoGroupByPolicyMapId groupByPolicyMapId, ActivePolicy activePolicy) {
  148.         super(dati.getUpdatePolicyDate(), dati.getGestorePolicyConfigDate());
  149.        
  150.         if(log!=null) {
  151.             // nop
  152.         }
  153.        
  154.         // Inizializzo il padre
  155.         dati.setValuesIn(this, false);
  156.        
  157.         this.hazelcast = hazelcast;
  158.         this.groupByPolicyMapId = groupByPolicyMapId;
  159.         this.groupByPolicyMapIdHashCode = this.groupByPolicyMapId.hashCode();
  160.        
  161.         this.distributedPolicyDate = this.initPolicyDate();
  162.         this.distributedUpdatePolicyDate = this.initUpdatePolicyDate();
  163.        
  164.         this.distributedPolicyDegradoPrestazionaleDate = this.initPolicyDegradoPrestazionaleDate();
  165.        
  166.         this.distribuitedActiveRequestCounterPolicyRichiesteSimultanee = activePolicy.getConfigurazionePolicy().isSimultanee() &&
  167.                 TipoControlloPeriodo.REALTIME.equals(activePolicy.getConfigurazionePolicy().getModalitaControllo());
  168.         if(this.distribuitedActiveRequestCounterPolicyRichiesteSimultanee){
  169.             this.distributedActiveRequestCounterForCheck = this.initActiveRequestCounters();
  170.             this.distributedActiveRequestCounterForStats = null;
  171.         }
  172.         else {
  173.             this.distributedActiveRequestCounterForStats = this.initActiveRequestCounters();
  174.         }
  175.        
  176.        
  177.         // Se non ho la policyDate, non considero il resto delle informazioni, che senza di essa non hanno senso.
  178.         if (super.getPolicyDate() != null) {

  179.             // Se ci sono altri nodi che stanno andando, la distributedPolicyDate DEVE essere != 0
  180.             // Se la policyDate è a zero vuol dire che questo è il primo nodo del cluster che sta inizializzando la policy per mezzo di un backup e che su tutto il cluster
  181.             // non sono ancora transitate richieste.
  182.             if (this.distributedPolicyDate!=null && this.distributedPolicyDate.compareAndSet(0, super.getPolicyDate().getTime())) {
  183.                 // Se la data distribuita non era inizializzata e questo nodo l'ha settata, imposto i contatori come da immagine bin.
  184.                 //  Faccio la addAndGet, in quanto tutti valori positivi, non entriamo in conflitto con gli altri nodi che stanno effettuando lo startup nello stesso momento
  185.                
  186.                 Long polDate = super.getPolicyDate().getTime();
  187.                 initPolicyCounters(polDate);
  188.                
  189.                 Long getPolicyRequestCounter = super.getPolicyRequestCounter(true);
  190.                 if (getPolicyRequestCounter != null) {
  191.                     this.distributedPolicyRequestCounter.addAndGet(getPolicyRequestCounter);
  192.                 }
  193.                
  194.                 Long getPolicyDenyRequestCounter = super.getPolicyDenyRequestCounter(true);
  195.                 if (getPolicyDenyRequestCounter != null) {
  196.                     this.distributedPolicyDenyRequestCounter.addAndGet(getPolicyDenyRequestCounter);
  197.                 }
  198.                
  199.                 if(this.tipoRisorsa==null || !isRisorsaContaNumeroRichieste(this.tipoRisorsa)){
  200.                     Long getPolicyCounter = super.getPolicyCounter(true);
  201.                     if (getPolicyCounter != null) {
  202.                         this.distributedPolicyCounter.addAndGet(getPolicyCounter);
  203.                     }
  204.                 }
  205.                
  206.                 Long getActiveRequestCounter = super.getActiveRequestCounter(true);
  207.                 if (getActiveRequestCounter!=null && getActiveRequestCounter != 0) {
  208.                     if(this.distribuitedActiveRequestCounterPolicyRichiesteSimultanee){
  209.                         this.distributedActiveRequestCounterForCheck.addAndGet(getActiveRequestCounter);
  210.                     }
  211.                     else {
  212.                         if(this.distributedActiveRequestCounterForStats!=null) {
  213.                             this.distributedActiveRequestCounterForStats.addAndGet(getActiveRequestCounter);
  214.                         }
  215.                     }
  216.                 }
  217.                                                
  218.             } else {
  219.                
  220.                 Long polDate = this.distributedPolicyDate!=null ? this.distributedPolicyDate.get() : null;
  221.                 initPolicyCounters(polDate);
  222.                
  223.             }
  224.         }
  225.        
  226.         // Se non ho la policyDegradoPrestazionaleDate, non considero il resto delle informazioni, che senza di essa non hanno senso.
  227.         if(this.policyDegradoPrestazionaleRealtime!=null && this.policyDegradoPrestazionaleRealtime &&
  228.             super.getPolicyDegradoPrestazionaleDate() != null) {
  229.                
  230.             // Imposto i contatori distribuiti solo se nel frattempo non l'ha fatto un altro thread del cluster.
  231.             if (this.distributedPolicyDegradoPrestazionaleDate!=null && this.distributedPolicyDegradoPrestazionaleDate.compareAndSet(0, super.getPolicyDegradoPrestazionaleDate().getTime())) {
  232.                
  233.                 Long degradoPrestazionaleTime = super.getPolicyDegradoPrestazionaleDate().getTime();
  234.                 initPolicyCountersDegradoPrestazionale(degradoPrestazionaleTime);
  235.                
  236.                 Long getPolicyDegradoPrestazionaleRequestCounter = super.getPolicyDegradoPrestazionaleRequestCounter(true);
  237.                 if (getPolicyDegradoPrestazionaleRequestCounter != null) {
  238.                     this.distributedPolicyDegradoPrestazionaleRequestCounter.addAndGet(getPolicyDegradoPrestazionaleRequestCounter);
  239.                 }
  240.                
  241.                 Long getPolicyDegradoPrestazionaleCounter = super.getPolicyDegradoPrestazionaleCounter(true);
  242.                 if (getPolicyDegradoPrestazionaleCounter != null) {
  243.                     this.distributedPolicyDegradoPrestazionaleCounter.addAndGet(getPolicyDegradoPrestazionaleCounter);
  244.                 }
  245.             }  else {
  246.                
  247.                 Long degradoPrestazionaleTime = this.distributedPolicyDegradoPrestazionaleDate!=null ? this.distributedPolicyDegradoPrestazionaleDate.get() : null;
  248.                 initPolicyCountersDegradoPrestazionale(degradoPrestazionaleTime);
  249.                
  250.             }
  251.         }
  252.        
  253.         this.initialized = true;
  254.     }
  255.    
  256.     private DatoAtomicLong initPolicyDate() {
  257.         if(this.policyRealtime!=null && this.policyRealtime){
  258.             return new DatoAtomicLong(this.hazelcast,
  259.                     this.groupByPolicyMapIdHashCode+
  260.                     BuilderDatiCollezionatiDistributed.DISTRUBUITED_POLICY_DATE+
  261.                     (this.gestorePolicyConfigDate!=null ? this.gestorePolicyConfigDate.getTime() : -1));
  262.         }
  263.         return null;
  264.     }
  265.     private DatoAtomicLong initUpdatePolicyDate() {
  266.         if(this.policyRealtime!=null && this.policyRealtime){
  267.             return new DatoAtomicLong(this.hazelcast,
  268.                     this.groupByPolicyMapIdHashCode+
  269.                     BuilderDatiCollezionatiDistributed.DISTRUBUITED_UPDATE_POLICY_DATE+
  270.                     (this.gestorePolicyConfigDate!=null ? this.gestorePolicyConfigDate.getTime() : -1));
  271.         }
  272.         return null;
  273.     }
  274.     private DatoAtomicLong initPolicyDegradoPrestazionaleDate() {
  275.         if(this.policyDegradoPrestazionaleRealtime!=null && this.policyDegradoPrestazionaleRealtime){
  276.             return new DatoAtomicLong(this.hazelcast,
  277.                     this.groupByPolicyMapIdHashCode+
  278.                     BuilderDatiCollezionatiDistributed.DISTRUBUITED_POLICY_DEGRADO_PRESTAZIONALE_DATE+
  279.                     (this.gestorePolicyConfigDate!=null ? this.gestorePolicyConfigDate.getTime() : -1));
  280.         }
  281.         return null;
  282.     }
  283.    
  284.     private DatoPNCounter initActiveRequestCounters() {
  285.         return new DatoPNCounter(this.hazelcast,
  286.                 getPNCounterName(BuilderDatiCollezionatiDistributed.DISTRUBUITED_ACTIVE_REQUEST_COUNTER,
  287.                         (this.gestorePolicyConfigDate!=null ? this.gestorePolicyConfigDate.getTime() : -1)));
  288.     }
  289.    
  290.     private void initPolicyCounters(Long policyDate) {

  291.         if(this.policyRealtime!=null && this.policyRealtime){
  292.                        
  293.             this.distributedPolicyRequestCounter = new DatoPNCounter(this.hazelcast,
  294.                     this.getPNCounterName(BuilderDatiCollezionatiDistributed.DISTRUBUITED_INTERVAL_POLICY_REQUEST_COUNTER,policyDate));
  295.            
  296.             this.distributedPolicyDenyRequestCounter = new DatoPNCounter(this.hazelcast,
  297.                     this.getPNCounterName(BuilderDatiCollezionatiDistributed.DISTRUBUITED_INTERVAL_POLICY_DENY_REQUEST_COUNTER,policyDate));
  298.            
  299.             if(this.tipoRisorsa==null || !isRisorsaContaNumeroRichieste(this.tipoRisorsa)){
  300.                 this.distributedPolicyCounter = new DatoPNCounter(this.hazelcast,
  301.                         this.getPNCounterName(BuilderDatiCollezionatiDistributed.DISTRUBUITED_INTERVAL_POLICY_COUNTER,policyDate));
  302.             }
  303.         }
  304.     }
  305.    
  306.     private void initPolicyCountersDegradoPrestazionale(Long policyDate) {
  307.        
  308.         if(this.policyDegradoPrestazionaleRealtime!=null && this.policyDegradoPrestazionaleRealtime){
  309.             this.distributedPolicyDegradoPrestazionaleCounter = new DatoPNCounter(this.hazelcast,
  310.                     this.getPNCounterName(BuilderDatiCollezionatiDistributed.DISTRUBUITED_INTERVAL_POLICY_DEGRADO_PRESTAZIONALE_COUNTER,policyDate));

  311.             this.distributedPolicyDegradoPrestazionaleRequestCounter = new DatoPNCounter(this.hazelcast,
  312.                     this.getPNCounterName(BuilderDatiCollezionatiDistributed.DISTRUBUITED_INTERVAL_POLICY_DEGRADO_PRESTAZIONALE_REQUEST_COUNTER,policyDate));

  313.         }  
  314.     }
  315.    

  316.     @Override
  317.     protected void resetPolicyCounterForDate(Date date) {
  318.         if(this.initialized) {
  319.             SemaphoreLock slock = this.lock.acquireThrowRuntime("resetPolicyCounterForDate");
  320.             try {
  321.                 long policyDate = date.getTime();
  322.                 long actual = this.distributedPolicyDate.get();
  323.                 long actualSuper = super.policyDate!=null ? super.policyDate.getTime() : -1;
  324.                 if(actualSuper!=policyDate && actual<policyDate && this.distributedPolicyDate.compareAndSet(actual, policyDate)) {                  
  325.                
  326.                     // Solo 1 nodo del cluster deve entrare in questo codice, altrimenti vengono fatti destroy più volte sullo stesso contatore
  327.                     // Potrà capitare che il cestino di un nodo non venga svuotato se si entra sempre sull'altro, cmq sia rimarrà 1 cestino con dei contatori di 1 intervallo.
  328.                     // Non appena ci entra poi li distruggerà.
  329.    
  330.                     // effettuo il drop creati due intervalli indietro
  331.                     if(!this.cestinoPolicyCounters.isEmpty()) {
  332.                         for (DatoPNCounter pnCounter : this.cestinoPolicyCounters) {
  333.                             pnCounter.destroy();
  334.                         }
  335.                         this.cestinoPolicyCounters.clear();
  336.                     }
  337.                    
  338.                     if(this.distributedPolicyRequestCounter!=null || this.distributedPolicyDenyRequestCounter!=null || this.distributedPolicyCounter!=null) {
  339.                         // conservo precedenti contatori
  340.                         if(this.distributedPolicyRequestCounter!=null) {
  341.                             this.cestinoPolicyCounters.add(this.distributedPolicyRequestCounter);
  342.                         }
  343.                         if(this.distributedPolicyDenyRequestCounter!=null) {
  344.                             this.cestinoPolicyCounters.add(this.distributedPolicyDenyRequestCounter);
  345.                         }
  346.                         if(this.distributedPolicyCounter!=null) {
  347.                             this.cestinoPolicyCounters.add(this.distributedPolicyCounter);
  348.                         }
  349.                     }
  350.                                                        
  351.                 }
  352.                
  353.                 if(actualSuper!=policyDate) {
  354.                    
  355.                     // Serve per inizializzare i nuovi riferimenti ai contatori
  356.                     initPolicyCounters(policyDate);
  357.                    
  358.                     // Serve per aggiornare la copia in ram del nodo in cui non si e' entrati nell'if precedente
  359.                     super.resetPolicyCounterForDate(date);
  360.                 }
  361.                
  362.             }finally {
  363.                 this.lock.release(slock, "resetPolicyCounterForDate");
  364.             }
  365.         }
  366.         else {
  367.             super.resetPolicyCounterForDate(date);
  368.         }
  369.     }
  370.    
  371.    
  372.     @Override
  373.     protected void resetPolicyCounterForDateDegradoPrestazionale(Date date) {
  374.        
  375.         if(this.initialized) {
  376.            
  377.             SemaphoreLock slock = this.lock.acquireThrowRuntime("resetPolicyCounterForDateDegradoPrestazionale");
  378.             try {
  379.                 long policyDate = date.getTime();
  380.                 long actual = this.distributedPolicyDate.get();
  381.                 long actualSuper = super.policyDegradoPrestazionaleDate!=null ? super.policyDegradoPrestazionaleDate.getTime() : -1;
  382.                 if(actualSuper!=policyDate && actual<policyDate && this.distributedPolicyDegradoPrestazionaleDate.compareAndSet(actual, policyDate)) {  
  383.                
  384.                     // Solo 1 nodo del cluster deve entrare in questo codice, altrimenti vengono fatti destroy più volte sullo stesso contatore
  385.                     // Potrà capitare che il cestino di un nodo non venga svuotato se si entra sempre sull'altro, cmq sia rimarrà 1 cestino con dei contatori di 1 intervallo.
  386.                     // Non appena ci entra poi li distruggerà.
  387.                    
  388.                     // effettuo il drop creati due intervalli indietro
  389.                     if(!this.cestinoPolicyCountersDegradoPrestazionale.isEmpty()) {
  390.                         for (DatoPNCounter pnCounter : this.cestinoPolicyCountersDegradoPrestazionale) {
  391.                             pnCounter.destroy();
  392.                         }
  393.                         this.cestinoPolicyCountersDegradoPrestazionale.clear();
  394.                     }
  395.                    
  396.                     if(this.distributedPolicyRequestCounter!=null || this.distributedPolicyDenyRequestCounter!=null || this.distributedPolicyCounter!=null) {
  397.                         // conservo precedenti contatori
  398.                         if(this.distributedPolicyDegradoPrestazionaleCounter!=null) {
  399.                             this.cestinoPolicyCountersDegradoPrestazionale.add(this.distributedPolicyDegradoPrestazionaleCounter);
  400.                         }
  401.                         if(this.distributedPolicyDegradoPrestazionaleRequestCounter!=null) {
  402.                             this.cestinoPolicyCountersDegradoPrestazionale.add(this.distributedPolicyDegradoPrestazionaleRequestCounter);
  403.                         }
  404.                     }
  405.                                        
  406.                 }
  407.                
  408.                 if(actualSuper!=policyDate) {
  409.                    
  410.                     // Serve per inizializzare i nuovi riferimenti ai contatori
  411.                     initPolicyCountersDegradoPrestazionale(policyDate);
  412.                    
  413.                     // Serve per aggiornare la copia in ram del nodo in cui non si e' entrati nell'if precedente
  414.                     super.resetPolicyCounterForDateDegradoPrestazionale(date);
  415.                 }
  416.                
  417.             }finally {
  418.                 this.lock.release(slock, "resetPolicyCounterForDateDegradoPrestazionale");
  419.             }
  420.         }
  421.         else {
  422.             super.resetPolicyCounterForDateDegradoPrestazionale(date);
  423.         }
  424.     }
  425.    
  426.     @Override
  427.     public void resetCounters(Date updatePolicyDate) {
  428.         super.resetCounters(updatePolicyDate);
  429.        
  430.         if(updatePolicyDate!=null) {
  431.             this.distributedUpdatePolicyDate.set(updatePolicyDate.getTime());
  432.         }
  433.        
  434.         if (this.distributedPolicyDenyRequestCounter != null) {
  435.             this.distributedPolicyDenyRequestCounter.subtractAndGet(this.distributedPolicyDenyRequestCounter.get());
  436.         }
  437.        
  438.         if (this.distributedPolicyRequestCounter != null)  {
  439.             this.distributedPolicyRequestCounter.subtractAndGet(this.distributedPolicyRequestCounter.get());
  440.         }
  441.        
  442.         if (this.distributedPolicyCounter != null) {
  443.             this.distributedPolicyCounter.subtractAndGet(this.distributedPolicyCounter.get());
  444.         }
  445.        
  446.         if (this.distributedPolicyDegradoPrestazionaleRequestCounter != null) {
  447.                 this.distributedPolicyDegradoPrestazionaleRequestCounter.subtractAndGet(this.distributedPolicyDegradoPrestazionaleRequestCounter.get());
  448.         }
  449.        
  450.         if (this.distributedPolicyDegradoPrestazionaleCounter != null) {
  451.             this.distributedPolicyDegradoPrestazionaleCounter.subtractAndGet(this.distributedPolicyDegradoPrestazionaleCounter.get());
  452.         }
  453.        
  454.     }
  455.    
  456.    
  457.    
  458.     @Override
  459.     protected void internalRegisterStartRequestIncrementActiveRequestCounter(DatiCollezionati datiCollezionatiPerPolicyVerifier) {
  460.         if(this.distribuitedActiveRequestCounterPolicyRichiesteSimultanee){
  461.             if(datiCollezionatiPerPolicyVerifier!=null) {
  462.                 super.activeRequestCounter = datiCollezionatiPerPolicyVerifier.setAndGetActiveRequestCounter(this.distributedActiveRequestCounterForCheck.incrementAndGet());
  463.             }
  464.             else {
  465.                 super.activeRequestCounter = this.distributedActiveRequestCounterForCheck.incrementAndGet();
  466.             }
  467.         }
  468.         else {
  469.             super.activeRequestCounter = this.distributedActiveRequestCounterForStats.incrementAndGet();
  470.         }
  471.     }
  472.    
  473.    
  474.     @Override
  475.     protected void internalUpdateDatiStartRequestApplicabileIncrementRequestCounter(DatiCollezionati datiCollezionatiPerPolicyVerifier) {
  476.         if(datiCollezionatiPerPolicyVerifier!=null) {
  477.             super.policyRequestCounter = datiCollezionatiPerPolicyVerifier.setAndGetPolicyRequestCounter(this.distributedPolicyRequestCounter.incrementAndGet());
  478.         }
  479.         else {
  480.             super.policyRequestCounter = this.distributedPolicyRequestCounter.incrementAndGet();
  481.         }
  482.     }
  483.    
  484.    
  485.    
  486.     @Override
  487.     protected void internalRegisterEndRequestDecrementActiveRequestCounter() {
  488.         if(this.distribuitedActiveRequestCounterPolicyRichiesteSimultanee){
  489.             super.activeRequestCounter = this.distributedActiveRequestCounterForCheck.decrementAndGet();
  490.         }
  491.         else {
  492.             super.activeRequestCounter = this.distributedActiveRequestCounterForStats.decrementAndGet();
  493.         }
  494.     }
  495.     @Override
  496.     protected void internalRegisterEndRequestIncrementDegradoPrestazionaleRequestCounter() {
  497.         super.policyDegradoPrestazionaleRequestCounter = this.distributedPolicyDegradoPrestazionaleRequestCounter.incrementAndGet();
  498.     }
  499.     @Override
  500.     protected void internalRegisterEndRequestIncrementDegradoPrestazionaleCounter(long latenza) {
  501.         super.policyDegradoPrestazionaleCounter = this.distributedPolicyDegradoPrestazionaleCounter.addAndGet(latenza);
  502.     }
  503.    
  504.    
  505.     @Override
  506.     protected void internalUpdateDatiEndRequestApplicabileIncrementRequestCounter() {
  507.         super.policyRequestCounter = this.distributedPolicyRequestCounter.incrementAndGet();
  508.     }
  509.     @Override
  510.     protected void internalUpdateDatiEndRequestApplicabileDecrementRequestCounter() {
  511.         super.policyRequestCounter = this.distributedPolicyRequestCounter.decrementAndGet();
  512.     }
  513.     @Override
  514.     protected void internalUpdateDatiEndRequestApplicabileIncrementDenyRequestCounter() {
  515.         super.policyDenyRequestCounter = this.distributedPolicyDenyRequestCounter.incrementAndGet();
  516.     }
  517.     @Override
  518.     protected void internalUpdateDatiEndRequestApplicabileIncrementCounter(long v) {
  519.         super.policyCounter = this.distributedPolicyCounter.addAndGet(v);
  520.     }
  521.    
  522.    
  523.    
  524.     @Override
  525.     public void destroyDatiDistribuiti() {
  526.         if(this.distributedPolicyDate!=null) {
  527.             this.distributedPolicyDate.destroy();
  528.         }
  529.         if(this.distributedUpdatePolicyDate!=null) {
  530.             this.distributedUpdatePolicyDate.destroy();
  531.         }
  532.        
  533.         if(this.distributedPolicyRequestCounter!=null) {
  534.             this.distributedPolicyRequestCounter.destroy();
  535.         }
  536.         if(this.distributedPolicyCounter!=null) {
  537.             this.distributedPolicyCounter.destroy();
  538.         }
  539.        
  540.         if(this.distributedPolicyDegradoPrestazionaleDate!=null) {
  541.             this.distributedPolicyDegradoPrestazionaleDate.destroy();
  542.         }
  543.         if(this.distributedPolicyDegradoPrestazionaleRequestCounter!=null) {
  544.             this.distributedPolicyDegradoPrestazionaleRequestCounter.destroy();
  545.         }
  546.         if(this.distributedPolicyDegradoPrestazionaleCounter!=null) {
  547.             this.distributedPolicyDegradoPrestazionaleCounter.destroy();
  548.         }
  549.        
  550.         if(this.distributedActiveRequestCounterForStats!=null) {
  551.             this.distributedActiveRequestCounterForStats.destroy();
  552.         }
  553.         if(this.distributedActiveRequestCounterForCheck!=null) {
  554.             this.distributedActiveRequestCounterForCheck.destroy();
  555.         }
  556.        
  557.         if(this.distributedPolicyDenyRequestCounter!=null) {
  558.             this.distributedPolicyDenyRequestCounter.destroy();
  559.         }
  560.     }
  561.    
  562.    
  563.    
  564.     // Getters non necessari, sono utili solo se viene richiesta una lettura del dato remoto
  565.    
  566.     @Override
  567.     public Long getActiveRequestCounter(boolean readRemoteInfo) {
  568.         if(readRemoteInfo) {
  569.             if(this.distribuitedActiveRequestCounterPolicyRichiesteSimultanee){
  570.                 return this.distributedActiveRequestCounterForCheck.get();  
  571.             }
  572.             else {
  573.                 return this.distributedActiveRequestCounterForStats.get();
  574.             }
  575.         }
  576.         else {
  577.             return super.getActiveRequestCounter(readRemoteInfo);
  578.         }
  579.     }
  580.        
  581.     @Override
  582.     public Long getPolicyDenyRequestCounter(boolean readRemoteInfo) {
  583.         if(readRemoteInfo) {
  584.             if(this.distributedPolicyDenyRequestCounter!=null) {
  585.                 return this.distributedPolicyDenyRequestCounter.get();
  586.             }
  587.             else {
  588.                 return null;
  589.             }
  590.         }
  591.         else {
  592.             return super.getPolicyDenyRequestCounter(readRemoteInfo);
  593.         }
  594.     }
  595.    
  596.     @Override
  597.     public Long getPolicyRequestCounter(boolean readRemoteInfo) {
  598.         if(readRemoteInfo) {
  599.             if(this.distributedPolicyRequestCounter!=null) {
  600.                 return this.distributedPolicyRequestCounter.get();
  601.             }
  602.             else {
  603.                 return null;
  604.             }
  605.         }
  606.         else {
  607.             return super.getPolicyRequestCounter(readRemoteInfo);
  608.         }
  609.     }
  610.     @Override
  611.     public Long getPolicyCounter(boolean readRemoteInfo) {
  612.         if(readRemoteInfo) {
  613.             if(this.distributedPolicyCounter!=null) {
  614.                 return this.distributedPolicyCounter.get();
  615.             }
  616.             else {
  617.                 return null;
  618.             }
  619.         }
  620.         else {
  621.             return super.getPolicyCounter(readRemoteInfo);
  622.         }
  623.     }  
  624.    
  625.     @Override
  626.     public Long getPolicyDegradoPrestazionaleRequestCounter(boolean readRemoteInfo) {
  627.         if(readRemoteInfo) {
  628.             if(this.distributedPolicyDegradoPrestazionaleRequestCounter!=null) {
  629.                 return this.distributedPolicyDegradoPrestazionaleRequestCounter.get();
  630.             }
  631.             else {
  632.                 return null;
  633.             }
  634.         }
  635.         else {
  636.             return super.getPolicyDegradoPrestazionaleRequestCounter(readRemoteInfo);
  637.         }
  638.     }
  639.     @Override
  640.     public Long getPolicyDegradoPrestazionaleCounter(boolean readRemoteInfo) {
  641.         if(readRemoteInfo) {
  642.             if(this.distributedPolicyDegradoPrestazionaleCounter!=null) {
  643.                 return this.distributedPolicyDegradoPrestazionaleCounter.get();
  644.             }
  645.             else {
  646.                 return null;
  647.             }
  648.         }
  649.         else {
  650.             return super.getPolicyDegradoPrestazionaleCounter(readRemoteInfo);
  651.         }
  652.     }
  653. }