AbstractFSRecovery.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.monitor.engine.fs_recovery;

  21. import java.io.File;
  22. import java.sql.Connection;

  23. import org.openspcoop2.utils.UtilsException;
  24. import org.openspcoop2.utils.UtilsMultiException;
  25. import org.openspcoop2.utils.resources.FileSystemUtilities;
  26. import org.slf4j.Logger;

  27. /**
  28.  * AbstractFSRecovery
  29.  *
  30.  * @author Poli Andrea (apoli@link.it)
  31.  * @author $Author$
  32.  * @version $Rev$, $Date$
  33.  */
  34. public abstract class AbstractFSRecovery {

  35.     protected Logger log;
  36.     protected boolean debug;
  37.     protected File directory;
  38.     protected File directoryDLQ;
  39.     protected int tentativi;
  40.     protected long msAttesaProcessingFile;
  41.    
  42.     protected AbstractFSRecovery(
  43.             Logger log,
  44.             boolean debug,
  45.             File directory, File directoryDLQ,
  46.             int tentativi,
  47.             long msAttesaProcessingFile) {
  48.         this.log = log;
  49.         this.debug = debug;
  50.         this.directory = directory;
  51.         this.directoryDLQ = directoryDLQ;
  52.         this.tentativi = tentativi;
  53.         this.msAttesaProcessingFile = msAttesaProcessingFile;
  54.     }
  55.    
  56.     public abstract void insertObject(File file, Connection connection) throws UtilsException, UtilsMultiException;
  57.    
  58.     protected void logDebug(String msg) {
  59.         if(this.log!=null) {
  60.             this.log.debug(msg);
  61.         }
  62.     }
  63.     protected void logInfo(String msg) {
  64.         if(this.log!=null) {
  65.             this.log.info(msg);
  66.         }
  67.     }
  68.     protected void logWarn(String msg) {
  69.         if(this.log!=null) {
  70.             this.log.warn(msg);
  71.         }
  72.     }
  73.     protected void logWarn(String msg, Exception e) {
  74.         if(this.log!=null) {
  75.             this.log.warn(msg, e);
  76.         }
  77.     }
  78.     protected void logError(String msg, Exception e) {
  79.         if(this.log!=null) {
  80.             this.log.error(msg, e);
  81.         }
  82.     }
  83.    
  84.     public void process(Connection connection){

  85.         // process file presenti nella directory.
  86.         // Per ogni file fare il marshall dell'oggetto 'it.link.pdd.core.plugins.eventi.utils.serializer.JaxbDeserializer'
  87.         try {
  88.             // NOTA: prima di processare un file verificare che la sua data di ultima modifica sia piu' vecchia almeno di X minuti (mettere X minuti in una costante)
  89.             //       in modo da evitare di processare i file che sono creati nello stesso momento in cui gira la procedura
  90.             File[] filesToProcess = this.directory.listFiles(new LastModifiedFileFilter(this.msAttesaProcessingFile));
  91.            
  92.             if(filesToProcess!=null && filesToProcess.length > 0) {
  93.                 this.logInfo("Processamento di ["+filesToProcess.length+"] file");
  94.                
  95.                 int countProcessatiCorrettamente = 0;
  96.                 int countProcessatiConErrore = 0;

  97.                 for(File file: filesToProcess) {
  98.                     if(process(connection, file)) {
  99.                         countProcessatiCorrettamente++;
  100.                     }
  101.                     else {
  102.                         countProcessatiConErrore++;
  103.                     }
  104.                 }
  105.                 this.logInfo("Processamento di ["+filesToProcess.length+"] file completato. ["+countProcessatiCorrettamente+"] file processati correttamente, ["+countProcessatiConErrore+"] con errore");
  106.             } else {
  107.                 this.logInfo("Nessun file da processare");
  108.             }
  109.            
  110.         }catch(Exception e) {
  111.             this.logError("Errore durante Il Recovery: "+e.getMessage(), e);
  112.         }
  113.     }
  114.     private boolean process(Connection connection, File file) throws UtilsException{
  115.         try {
  116.             if(this.debug)
  117.                 this.logInfo("Inserimento del file ["+file.getName()+"] ...");

  118.             // Implementare il salvataggio nella classe concreta
  119.             // Se il salvataggio su database va a buon fine si puo eliminare il file.
  120.             this.insertObject(file, connection);
  121.             FileSystemUtilities.deleteFile(file);
  122.             if(this.debug)
  123.                 this.logInfo("Inserimento del file ["+file.getName()+"] completato con successo");
  124.             return true;
  125.         } catch(Exception e) {
  126.             error(file, e);
  127.             return false;
  128.         }
  129.     }
  130.     private void error(File file, Exception e) throws UtilsException {
  131.         if(this.debug)
  132.             this.logWarn("Errore durante l'inserimento del file ["+file.getName()+"] rinomino il file:"+e.getMessage(), e);
  133.        
  134.         int tentativiPerFile = FSRecoveryFileUtils.getTentativiFromFilename(file.getName());
  135.         if(tentativiPerFile < this.tentativi) {
  136.             // Se avviene un errore sul marshal o se avviene un errore durante l'inserimento effettuare un rename del file file.renameTo(file2)
  137.             // aggiungendo un suffisso sul numero del tentativo: es.
  138.             // File originale: Evento_2015-04-27_09\:37\:34.323_1.xml
  139.             // Dopo primo tentativo: Evento_2015-04-27_09\:37\:34.323_1.xml_1.error
  140.             // Dopo secondo tentativo: Evento_2015-04-27_09\:37\:34.323_1.xml_2.error
  141.             // ...
  142.             // In modo da riconoscere gli originali *.xml da quelli che sono andati in errore almeno una volta *.error

  143.             File newFile = new File(this.directory, FSRecoveryFileUtils.getNewFileNameFromFilename(file.getName()));
  144.             if(!file.renameTo(newFile)) {
  145.                 // ignore
  146.             }
  147.             if(this.debug)
  148.                 this.logWarn("File ["+file.getName()+"] rinominato in ["+newFile.getName()+"]");
  149.         } else {
  150.             // Se per un file si raggiunge il massimo numero di tentativi, effettuare il rename del file file.renameTo(file2)
  151.             // Spostandolo nella directory DLQ.

  152.             // NOTA: in DLQ estrapolare la data (solo anno mese e giorno) dal nome del file e usarla come nome della directory all'interno di DLQ. Inserire
  153.             String newFileName = FSRecoveryFileUtils.renameToDLQ(this.directoryDLQ, file, e, this.log);
  154.             if(this.debug)
  155.                 this.logWarn("File ["+file.getName()+"] rinominato in ["+newFileName+"]");
  156.         }
  157.     }
  158.    
  159. }