DiagnosticInputStream.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.logger;

  21. import java.io.FilterInputStream;
  22. import java.io.IOException;
  23. import java.io.InputStream;
  24. import java.util.Date;

  25. import org.apache.commons.lang.StringUtils;
  26. import org.openspcoop2.pdd.core.CostantiPdD;
  27. import org.openspcoop2.utils.Map;
  28. import org.openspcoop2.utils.MapKey;
  29. import org.openspcoop2.utils.Utilities;
  30. import org.openspcoop2.utils.date.DateManager;
  31. import org.slf4j.Logger;

  32. /**
  33.  * DiagnosticInputStream
  34.  *
  35.  *
  36.  * @author Poli Andrea (apoli@link.it)
  37.  * @author $Author$
  38.  * @version $Rev$, $Date$
  39.  */
  40. public class DiagnosticInputStream extends FilterInputStream {

  41.     private static final String COMPLETATA = "completata";
  42.     private static final String FALLITA = "fallita";
  43.    
  44.     public static final MapKey<String> DIAGNOSTIC_INPUT_STREAM_REQUEST_COMPLETE_DATE = Map.newMapKey("DiagnosticInputStreamRequestCompleteDate");
  45.     public static final MapKey<String> DIAGNOSTIC_INPUT_STREAM_REQUEST_ERROR_DATE = Map.newMapKey("DiagnosticInputStreamRequestErrorDate");
  46.     public static final MapKey<String> DIAGNOSTIC_INPUT_STREAM_REQUEST_START_DATE = Map.newMapKey("DiagnosticInputStreamRequestStartDate");
  47.    
  48.     public static final MapKey<String> DIAGNOSTIC_INPUT_STREAM_RESPONSE_COMPLETE_DATE = Map.newMapKey("DiagnosticInputStreamResponseCompleteDate");
  49.     public static final MapKey<String> DIAGNOSTIC_INPUT_STREAM_RESPONSE_ERROR_DATE = Map.newMapKey("DiagnosticInputStreamResponseErrorDate");
  50.     public static final MapKey<String> DIAGNOSTIC_INPUT_STREAM_RESPONSE_START_DATE = Map.newMapKey("DiagnosticInputStreamResponseStartDate");
  51.    
  52.     private InputStream isWrapped = null;
  53.     private String idModuloFunzionale;
  54.     private String identificativo;
  55.     private boolean request;
  56.     private MsgDiagnostico msgDiagnostico;
  57.     private Logger log;
  58.     private Map<Object> ctx;
  59.     private boolean readSomeBytes = false;
  60.    
  61.     private static boolean setDateEmptyStream = true;
  62.     public static boolean isSetDateEmptyStream() {
  63.         return setDateEmptyStream;
  64.     }
  65.     public static void setSetDateEmptyStream(boolean setDateEmptyStream) {
  66.         DiagnosticInputStream.setDateEmptyStream = setDateEmptyStream;
  67.     }

  68.     public DiagnosticInputStream(InputStream inputStream, String idModuloFunzionale, String identificativo, boolean request,
  69.             MsgDiagnostico msgDiagnostico, Logger log, Map<Object> ctx) {
  70.         super(inputStream);
  71.         this.idModuloFunzionale = idModuloFunzionale;
  72.         this.identificativo = identificativo;
  73.         this.request = request;
  74.         this.msgDiagnostico = msgDiagnostico;
  75.         this.log = log;
  76.         this.ctx = ctx;
  77.        
  78.         this.isWrapped = inputStream;
  79.        
  80.         registerStartDate();
  81.     }
  82.    
  83.     public InputStream getIsWrapped() {
  84.         return this.isWrapped;
  85.     }

  86.     @Override
  87.     public int read() throws IOException {
  88.         try {
  89.             int res = super.read();
  90.             if (res == -1) {
  91.                 registerDate(null);
  92.                 emitLog(null);
  93.                 emitDiagnostic(null);
  94.             }
  95.             else {
  96.                 if(!this.readSomeBytes) {
  97.                     this.readSomeBytes=true;
  98.                 }
  99.             }
  100.             return res;
  101.         }catch(IOException io) {
  102.             registerDate(io);
  103.             emitLog(io);
  104.             emitDiagnostic(io);
  105.             throw io;
  106.         }catch(Throwable t) {
  107.             registerDate(t);
  108.             emitLog(t);
  109.             emitDiagnostic(t);
  110.             throw t;
  111.         }
  112.     }

  113.     @Override
  114.     public int read(byte[] b, int off, int len) throws IOException {
  115.         try {
  116.             int res = super.read(b, off, len);
  117.             if (res == -1) {
  118.                 registerDate(null);
  119.                 emitLog(null);
  120.                 emitDiagnostic(null);
  121.             }
  122.             else {
  123.                 if(!this.readSomeBytes) {
  124.                     this.readSomeBytes=true;
  125.                 }
  126.             }
  127.             return res;
  128.         }catch(IOException io) {
  129.             registerDate(io);
  130.             emitLog(io);
  131.             emitDiagnostic(io);
  132.             throw io;
  133.         }catch(Throwable t) {
  134.             registerDate(t);
  135.             emitLog(t);
  136.             emitDiagnostic(t);
  137.             throw t;
  138.         }
  139.     }

  140.     private void registerStartDate() {
  141.         if(this.ctx!=null && this.isWrapped!=null) {
  142.             Date d = DateManager.getDate();
  143.             this.ctx.put(this.request ? DIAGNOSTIC_INPUT_STREAM_REQUEST_START_DATE : DIAGNOSTIC_INPUT_STREAM_RESPONSE_START_DATE, d);
  144.         }
  145.     }
  146.    
  147.     private void registerDate(Throwable t) {
  148.         if(this.ctx!=null &&
  149.                 (this.readSomeBytes
  150.                         ||
  151.                 DiagnosticInputStream.setDateEmptyStream) // per far si che le due date siano le stesse
  152.             ) {
  153.             Date d = DateManager.getDate();
  154.             if(t!=null) {
  155.                 this.ctx.put(this.request ? DIAGNOSTIC_INPUT_STREAM_REQUEST_ERROR_DATE : DIAGNOSTIC_INPUT_STREAM_RESPONSE_ERROR_DATE, d);
  156.             }
  157.             else {
  158.                 this.ctx.put(this.request ? DIAGNOSTIC_INPUT_STREAM_REQUEST_COMPLETE_DATE : DIAGNOSTIC_INPUT_STREAM_RESPONSE_COMPLETE_DATE, d);
  159.             }
  160.         }
  161.     }
  162.    
  163.     private void emitLog(Throwable t) {
  164.         if(this.log!=null) {
  165.             StringBuilder sb = new StringBuilder();
  166.             sb.append("Lettura payload '").append(this.identificativo).append("' ");
  167.             if(t!=null) {
  168.                 sb.append("fallita: ").append(t.getMessage());
  169.             }
  170.             else {
  171.                 sb.append("completata con successo");
  172.             }
  173.             String msg = sb.toString();
  174.             if(t!=null) {
  175.                 this.log.error(msg, t);
  176.             }else{
  177.                 this.log.debug(msg);
  178.             }
  179.         }
  180.     }
  181.     private void emitDiagnostic(Throwable t) {
  182.         if(this.msgDiagnostico!=null &&
  183.                 this.idModuloFunzionale!=null && StringUtils.isNotEmpty(this.idModuloFunzionale) &&
  184.                 this.identificativo!=null && StringUtils.isNotEmpty(this.identificativo)) {
  185.             try {
  186.                 if(t!=null) {
  187.                     String msg = Utilities.readFirstErrorValidMessageFromException(t);
  188.                     this.msgDiagnostico.addKeyword(CostantiPdD.KEY_ERRORE_PROCESSAMENTO, msg);
  189.                     this.msgDiagnostico.logPersonalizzato(this.idModuloFunzionale, this.identificativo+"."+FALLITA);
  190.                 }
  191.                 else {
  192.                     this.msgDiagnostico.logPersonalizzato(this.idModuloFunzionale, this.identificativo+"."+COMPLETATA);
  193.                 }
  194.             }catch(Throwable tLog) {
  195.                 if(this.log!=null) {
  196.                     this.log.error("Emissione diagnostico per lettura payload '"+this.identificativo+"' fallita: "+tLog.getMessage(),tLog);
  197.                 }
  198.             }
  199.         }
  200.     }
  201. }