ConnettoreFILE.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.connettori;

  21. import java.io.ByteArrayOutputStream;
  22. import java.io.File;
  23. import java.io.FileInputStream;
  24. import java.io.FileOutputStream;
  25. import java.io.OutputStream;
  26. import java.util.ArrayList;
  27. import java.util.Enumeration;
  28. import java.util.HashMap;
  29. import java.util.Iterator;
  30. import java.util.List;
  31. import java.util.Map;
  32. import java.util.Properties;
  33. import java.util.Scanner;

  34. import org.apache.commons.lang.StringUtils;
  35. import org.openspcoop2.core.config.ResponseCachingConfigurazione;
  36. import org.openspcoop2.core.constants.CostantiConnettori;
  37. import org.openspcoop2.core.transazioni.constants.TipoMessaggio;
  38. import org.openspcoop2.message.OpenSPCoop2SoapMessage;
  39. import org.openspcoop2.message.constants.Costanti;
  40. import org.openspcoop2.message.constants.MessageType;
  41. import org.openspcoop2.message.soap.TunnelSoapUtils;
  42. import org.openspcoop2.pdd.core.dynamic.DynamicInfo;
  43. import org.openspcoop2.pdd.core.dynamic.DynamicUtils;
  44. import org.openspcoop2.pdd.mdb.ConsegnaContenutiApplicativi;
  45. import org.openspcoop2.utils.Utilities;
  46. import org.openspcoop2.utils.date.DateManager;
  47. import org.openspcoop2.utils.io.DumpByteArrayOutputStream;
  48. import org.openspcoop2.utils.resources.FileSystemUtilities;
  49. import org.openspcoop2.utils.transport.TransportUtils;
  50. import org.openspcoop2.utils.transport.http.HttpConstants;
  51. import org.openspcoop2.utils.transport.http.HttpUtilities;



  52. /**
  53.  * Classe utilizzata per effettuare consegne di messaggi su file system
  54.  *
  55.  *
  56.  * @author Poli Andrea (apoli@link.it)
  57.  * @author $Author$
  58.  * @version $Rev$, $Date$
  59.  */

  60. public class ConnettoreFILE extends ConnettoreBaseWithResponse {

  61.     @Override
  62.     public String getProtocollo() {
  63.         return "FILE";
  64.     }
  65.    
  66.     /* ********  F I E L D S  P R I V A T I  ******** */

  67.     public ByteArrayOutputStream outByte = new ByteArrayOutputStream();

  68.     /** File */
  69.     private ConnettoreFile_outputConfig outputFile = null;
  70.     private ConnettoreFile_outputConfig outputFileHeaders = null;
  71.     private boolean outputFileAutoCreateParentDirectory = false;
  72.     private boolean outputFileOverwriteIfExists = false;
  73.     private boolean generateResponse = false;
  74.     private File inputFile = null;
  75.     private File inputFileHeaders = null;
  76.     private boolean inputFileDeleteAfterRead = false;
  77.     private Integer inputFileWaitTimeIfNotExists;
  78.    
  79.     private ByteArrayOutputStream boutFileOutputHeaders;
  80.    
  81.    
  82.     /* Costruttori */
  83.     public ConnettoreFILE(){
  84.        
  85.     }

  86.    
  87.    
  88.     /* ********  METODI  ******** */

  89.     public String buildLocation(ConnettoreMsg request) throws ConnettoreException{
  90.        
  91.         this.properties = request.getConnectorProperties();
  92.        
  93.         // Costruisco Mappa per dynamic name
  94.         // NOTA: Lasciare la costruzione qua, poiche' altrimenti la classe File lancia eccezioni se trova i threshold
  95.         Map<String, Object> dynamicMap = this.buildDynamicMap(request);
  96.        
  97.         // OutputFile
  98.         String tmp = this.getDynamicProperty(request.getTipoConnettore(), true, CostantiConnettori.CONNETTORE_FILE_REQUEST_OUTPUT_FILE, dynamicMap);
  99.         File f = new File(tmp);
  100.         String l = f.getAbsolutePath();
  101.        
  102.         // OutputFile-Headers
  103.         tmp = this.getDynamicProperty(request.getTipoConnettore(), false, CostantiConnettori.CONNETTORE_FILE_REQUEST_OUTPUT_FILE_HEADERS, dynamicMap);
  104.         if(tmp!=null){
  105.             l = l + " [headers: "+(new File(tmp)).getAbsolutePath()+"]";
  106.         }
  107.        
  108.         return l;
  109.     }
  110.    

  111.     @Override
  112.     protected boolean initializePreSend(ResponseCachingConfigurazione responseCachingConfig, ConnettoreMsg request) {
  113.        
  114.         if(this.initialize(request, true, responseCachingConfig)==false){
  115.             return false;
  116.         }
  117.        
  118.         return true;
  119.        
  120.     }
  121.    
  122.     @Override
  123.     protected boolean send(ConnettoreMsg request) {

  124.         // Lettura Parametri
  125.         try{
  126.    
  127.             this.checkContentType = true;
  128.             if(this.idModulo!=null){
  129.                 if(ConsegnaContenutiApplicativi.ID_MODULO.equals(this.idModulo)){
  130.                     this.checkContentType = this.openspcoopProperties.isControlloContentTypeAbilitatoRicezioneBuste();
  131.                 }else{
  132.                     this.checkContentType = this.openspcoopProperties.isControlloContentTypeAbilitatoRicezioneContenutiApplicativi();
  133.                 }
  134.             }
  135.            
  136.            
  137.             // Costruisco Mappa per dynamic name
  138.             Map<String, Object> dynamicMap = new HashMap<>();
  139.             DynamicInfo dInfo = new DynamicInfo(request, this.getPddContext());
  140.             DynamicUtils.fillDynamicMap(this.logger.getLogger(),dynamicMap, dInfo);
  141.            
  142.            
  143.             // Identificativo modulo
  144.             this.idModulo = request.getIdModulo();
  145.                    
  146.             // Context per invocazioni handler
  147.             this.outRequestContext = request.getOutRequestContext();
  148.             this.msgDiagnostico = request.getMsgDiagnostico();
  149.            
  150.            
  151.             // analsi i parametri specifici per il connettore
  152.            
  153.             // OutputFile
  154.             this.outputFile = readOutputConfig(request.getTipoConnettore(), true,
  155.                     CostantiConnettori.CONNETTORE_FILE_REQUEST_OUTPUT_FILE,
  156.                     CostantiConnettori.CONNETTORE_FILE_REQUEST_OUTPUT_FILE_PERMISSIONS);
  157.             if(this.outputFile==null || this.outputFile.getOutputFile()==null){
  158.                 return false;
  159.             }
  160.            
  161.             // OutputFileHeader
  162.             this.outputFileHeaders = readOutputConfig(request.getTipoConnettore(), false,
  163.                     CostantiConnettori.CONNETTORE_FILE_REQUEST_OUTPUT_FILE_HEADERS,
  164.                     CostantiConnettori.CONNETTORE_FILE_REQUEST_OUTPUT_FILE_HEADERS_PERMISSIONS);

  165.             // Location
  166.             this.location = this.outputFile.getOutputFile().getAbsolutePath();
  167.             if(this.outputFileHeaders!=null){
  168.                 this.location = this.location + " [headers: "+this.outputFileHeaders.getOutputFile().getAbsolutePath()+"]";
  169.             }
  170.            
  171.             // AutoCreateDir
  172.             this.outputFileAutoCreateParentDirectory = this.isBooleanProperty(request.getTipoConnettore(), false, CostantiConnettori.CONNETTORE_FILE_REQUEST_OUTPUT_AUTO_CREATE_DIR);
  173.            
  174.             // OverwriteFileIfExists
  175.             this.outputFileOverwriteIfExists = this.isBooleanProperty(request.getTipoConnettore(), false, CostantiConnettori.CONNETTORE_FILE_REQUEST_OUTPUT_OVERWRITE_FILE);
  176.            
  177.             // GenerazioneRisposta
  178.             this.generateResponse = this.isBooleanProperty(request.getTipoConnettore(), false, CostantiConnettori.CONNETTORE_FILE_RESPONSE_INPUT_MODE);
  179.            
  180.             if(this.generateResponse){
  181.                
  182.                 // InputFile
  183.                 String tmp = this.getDynamicProperty(request.getTipoConnettore(), true, CostantiConnettori.CONNETTORE_FILE_RESPONSE_INPUT_FILE, dynamicMap);
  184.                 if(tmp==null){
  185.                     return false;
  186.                 }
  187.                 this.inputFile = new File(tmp);
  188.                
  189.                 // InputFileHeader
  190.                 tmp = this.getDynamicProperty(request.getTipoConnettore(), false, CostantiConnettori.CONNETTORE_FILE_RESPONSE_INPUT_FILE_HEADERS, dynamicMap);
  191.                 if(tmp!=null){
  192.                     this.inputFileHeaders = new File(tmp);
  193.                 }
  194.                
  195.                 // DeleteAfterRead
  196.                 this.inputFileDeleteAfterRead = this.isBooleanProperty(request.getTipoConnettore(), false, CostantiConnettori.CONNETTORE_FILE_RESPONSE_INPUT_FILE_DELETE_AFTER_READ);
  197.                
  198.                 // inputFileWaitTimeIfNotExists
  199.                 this.inputFileWaitTimeIfNotExists = this.getIntegerProperty(request.getTipoConnettore(), false, CostantiConnettori.CONNETTORE_FILE_RESPONSE_INPUT_WAIT_TIME);
  200.             }
  201.            
  202.         }  catch(Exception e){
  203.             this.eccezioneProcessamento = e;
  204.             this.errore = "Errore avvenuto durante la consegna su FileSystem: "+this.readExceptionMessageFromException(e);
  205.             this.logger.error("Errore avvenuto durante la consegna su FileSystem: "+this.readExceptionMessageFromException(e),e);
  206.             return false;
  207.         }
  208.            
  209.            
  210.            
  211.         // Gestione File
  212.         int readConnectionTimeout = -1;
  213.         boolean readConnectionTimeoutConfigurazioneGlobale = true;
  214.         try{

  215.             /* ------------  Request ------------- */
  216.            
  217.            
  218.             // OutputFile
  219.             this.checkOutputFile(this.outputFile, "Request");
  220.            
  221.             // OutputFile Headers
  222.             if(this.outputFileHeaders!=null){
  223.                 this.checkOutputFile(this.outputFileHeaders, "Request-Headers");
  224.             }
  225.            
  226.            
  227.             // Tipologia di servizio
  228.             MessageType requestMessageType = this.requestMsg.getMessageType();
  229.             OpenSPCoop2SoapMessage soapMessageRequest = null;
  230.             if(this.debug)
  231.                 this.logger.debug("Tipologia Servizio: "+this.requestMsg.getServiceBinding());
  232.             if(this.isSoap){
  233.                 soapMessageRequest = this.requestMsg.castAsSoap();
  234.             }
  235.            
  236.            
  237.            
  238.             // Alcune implementazioni richiedono di aggiornare il Content-Type
  239.             this.requestMsg.updateContentType();
  240.            
  241.            
  242.             // Properties per serializzazione header file
  243.             this.boutFileOutputHeaders = new ByteArrayOutputStream();
  244.            
  245.            
  246.             // Collezione header di trasporto per dump
  247.             Map<String, List<String>> propertiesTrasportoDebug = null;
  248.             if(this.isDumpBinarioRichiesta()) {
  249.                 propertiesTrasportoDebug = new HashMap<>();
  250.             }
  251.            
  252.            
  253.             // Impostazione Content-Type
  254.             String contentTypeRichiesta = null;
  255.             if(this.debug)
  256.                 this.logger.debug("Impostazione content type...");
  257.             if(this.isSoap){
  258.                 if(this.sbustamentoSoap && soapMessageRequest.countAttachments()>0 && TunnelSoapUtils.isTunnelOpenSPCoopSoap(soapMessageRequest)){
  259.                     contentTypeRichiesta = TunnelSoapUtils.getContentTypeTunnelOpenSPCoopSoap(soapMessageRequest.getSOAPBody());
  260.                 }else{
  261.                     contentTypeRichiesta = this.requestMsg.getContentType();
  262.                 }
  263.                 if(contentTypeRichiesta==null){
  264.                     throw new Exception("Content-Type del messaggio da spedire non definito");
  265.                 }
  266.             }
  267.             else{
  268.                 contentTypeRichiesta = this.requestMsg.getContentType();
  269.                 // Content-Type non obbligatorio in REST
  270.             }
  271.             if(this.debug)
  272.                 this.logger.info("Impostazione Content-Type ["+contentTypeRichiesta+"]",false);
  273.             if(contentTypeRichiesta!=null){
  274.                 setRequestHeader(HttpConstants.CONTENT_TYPE, contentTypeRichiesta, this.logger, propertiesTrasportoDebug);
  275.             }
  276.            
  277.            
  278.            
  279.             // Impostazione timeout
  280.             if(this.debug)
  281.                 this.logger.debug("Impostazione timeout...");
  282.             if(this.properties.get(CostantiConnettori.CONNETTORE_READ_CONNECTION_TIMEOUT)!=null){
  283.                 try{
  284.                     readConnectionTimeout = Integer.parseInt(this.properties.get(CostantiConnettori.CONNETTORE_READ_CONNECTION_TIMEOUT));
  285.                     readConnectionTimeoutConfigurazioneGlobale = this.properties.containsKey(CostantiConnettori.CONNETTORE_READ_CONNECTION_TIMEOUT_GLOBALE);
  286.                 }catch(Exception e){
  287.                     this.logger.error("Parametro "+CostantiConnettori.CONNETTORE_READ_CONNECTION_TIMEOUT+" errato",e);
  288.                 }
  289.             }
  290.             if(readConnectionTimeout==-1){
  291.                 readConnectionTimeout = HttpUtilities.HTTP_READ_CONNECTION_TIMEOUT;
  292.             }
  293.             if(this.debug)
  294.                 this.logger.info("Impostazione read timeout ["+readConnectionTimeout+"]",false);
  295.            
  296.            

  297.                
  298.             // Impostazione Proprieta del trasporto
  299.             if(this.debug)
  300.                 this.logger.debug("Impostazione header di trasporto...");
  301.             this.forwardHttpRequestHeader();
  302.             if(this.propertiesTrasporto != null){
  303.                 Iterator<String> keys = this.propertiesTrasporto.keySet().iterator();
  304.                 while (keys.hasNext()) {
  305.                     String key = (String) keys.next();
  306.                     List<String> values = this.propertiesTrasporto.get(key);
  307.                     if(this.debug) {
  308.                         if(values!=null && !values.isEmpty()) {
  309.                             for (String value : values) {
  310.                                 this.logger.info("Set Transport Header ["+key+"]=["+value+"]",false);
  311.                             }
  312.                         }
  313.                     }
  314.                    
  315.                     setRequestHeader(key, values, this.logger, propertiesTrasportoDebug);
  316.                 }
  317.             }
  318.            
  319.            
  320.            
  321.            
  322.            
  323.             // Aggiunta del SoapAction Header in caso di richiesta SOAP
  324.             // spostato sotto il forwardHeader per consentire alle trasformazioni di modificarla
  325.             if(this.isSoap && this.sbustamentoSoap == false){
  326.                 if(this.debug)
  327.                     this.logger.debug("Impostazione soap action...");
  328.                 boolean existsTransportProperties = false;
  329.                 if(TransportUtils.containsKey(this.propertiesTrasporto, Costanti.SOAP11_MANDATORY_HEADER_HTTP_SOAP_ACTION)){
  330.                     this.soapAction = TransportUtils.getFirstValue(this.propertiesTrasporto, Costanti.SOAP11_MANDATORY_HEADER_HTTP_SOAP_ACTION);
  331.                     existsTransportProperties = (this.soapAction!=null);
  332.                 }
  333.                 if(!existsTransportProperties) {
  334.                     this.soapAction = soapMessageRequest.getSoapAction();
  335.                 }
  336.                 if(this.soapAction==null){
  337.                     this.soapAction="\"OpenSPCoop\"";
  338.                 }
  339.                 if(MessageType.SOAP_11.equals(this.requestMsg.getMessageType()) && !existsTransportProperties){
  340.                     // NOTA non quotare la soap action, per mantenere la trasparenza della PdD
  341.                     setRequestHeader(Costanti.SOAP11_MANDATORY_HEADER_HTTP_SOAP_ACTION,this.soapAction, this.logger, propertiesTrasportoDebug);
  342.                 }
  343.                 if(this.debug)
  344.                     this.logger.info("SOAP Action inviata ["+this.soapAction+"]",false);
  345.             }
  346.            
  347.            
  348.            
  349.            
  350.                    
  351.             // Spedizione byte
  352.             boolean consumeRequestMessage = true;
  353.             if(this.debug)
  354.                 this.logger.debug("Serializzazione ["+this.outputFile.getOutputFile().getAbsolutePath()+"] (consume-request-message:"+consumeRequestMessage+")...");
  355.             OutputStream out = new FileOutputStream(this.outputFile.getOutputFile());
  356.             if(this.isDumpBinarioRichiesta()) {
  357.                 DumpByteArrayOutputStream bout = new DumpByteArrayOutputStream(this.dumpBinario_soglia, this.dumpBinario_repositoryFile, this.idTransazione,
  358.                         TipoMessaggio.RICHIESTA_USCITA_DUMP_BINARIO.getValue());
  359.                 try {
  360.                     this.emitDiagnosticStartDumpBinarioRichiestaUscita();
  361.                    
  362.                     if(this.isSoap && this.sbustamentoSoap){
  363.                         this.logger.debug("Sbustamento...");
  364.                         TunnelSoapUtils.sbustamentoMessaggio(soapMessageRequest,bout);
  365.                     }else{
  366.                         this.requestMsg.writeTo(bout, consumeRequestMessage);
  367.                     }
  368.                     bout.flush();
  369.                     bout.close();
  370.                    
  371.                     if(bout.isSerializedOnFileSystem()) {
  372.                         try(FileInputStream fin = new FileInputStream(bout.getSerializedFile())) {
  373.                             Utilities.copy(fin, out);
  374.                         }
  375.                     }
  376.                     else {
  377.                         out.write(bout.toByteArray());
  378.                     }
  379.                    
  380.                     out.flush();
  381.                     out.close();
  382.                    
  383.                     this.dataRichiestaInoltrata = DateManager.getDate();
  384.                    
  385.                     this.dumpBinarioRichiestaUscita(bout, requestMessageType, contentTypeRichiesta, this.location, propertiesTrasportoDebug);
  386.                 }finally {
  387.                     try {
  388.                         bout.clearResources();
  389.                     }catch(Throwable t) {
  390.                         this.logger.error("Release resources failed: "+t.getMessage(),t);
  391.                     }
  392.                 }
  393.             }else{
  394.                 if(this.isSoap && this.sbustamentoSoap){
  395.                     if(this.debug)
  396.                         this.logger.debug("Sbustamento...");
  397.                     TunnelSoapUtils.sbustamentoMessaggio(soapMessageRequest,out);
  398.                 }else{
  399.                     this.requestMsg.writeTo(out, consumeRequestMessage);
  400.                 }
  401.                
  402.                 out.flush();
  403.                 out.close();
  404.                
  405.                 this.dataRichiestaInoltrata = DateManager.getDate();
  406.             }

  407.             if(this.debug)
  408.                 this.logger.debug("Serializzazione ["+this.outputFile.getOutputFile().getAbsolutePath()+"] effettuata");
  409.            
  410.             if(this.outputFile.isPermission()) {
  411.                 if(this.debug)
  412.                     this.logger.debug("Modifica diritti del file ["+this.outputFile.getOutputFile().getAbsolutePath()+"] ("+this.outputFile.getPermissionAsString()+") ...");
  413.                 setPermission(this.outputFile);
  414.                 if(this.debug)
  415.                     this.logger.debug("Modifica diritti del file ["+this.outputFile.getOutputFile().getAbsolutePath()+"] ("+this.outputFile.getPermissionAsString()+") effettuata");
  416.             }
  417.            
  418.            
  419.             // Spedizione File Headers
  420.             this.boutFileOutputHeaders.flush();
  421.             this.boutFileOutputHeaders.close();
  422.             if(this.outputFileHeaders!=null){
  423.                 if(this.debug)
  424.                     this.logger.debug("Serializzazione File Output Headers ["+this.outputFileHeaders.getOutputFile().getAbsolutePath()+"]...");
  425.                 out = new FileOutputStream(this.outputFileHeaders.getOutputFile());
  426.                 if(this.debug){
  427.                     ByteArrayOutputStream bout = new ByteArrayOutputStream();
  428.                     bout.write(this.boutFileOutputHeaders.toByteArray());
  429.                     bout.flush();
  430.                     bout.close();
  431.                     out.write(bout.toByteArray());
  432.                     this.logger.info("File Header Serializzato:\n"+bout.toString(),false);
  433.                 }else{
  434.                     out.write(this.boutFileOutputHeaders.toByteArray());
  435.                 }
  436.                 out.flush();
  437.                 out.close();
  438.                 if(this.debug)
  439.                     this.logger.debug("Serializzazione File Output Headers ["+this.outputFileHeaders.getOutputFile().getAbsolutePath()+"] effettuata");
  440.                
  441.                 if(this.outputFileHeaders.isPermission()) {
  442.                     if(this.debug)
  443.                         this.logger.debug("Modifica diritti del file ["+this.outputFileHeaders.getOutputFile().getAbsolutePath()+"] ("+this.outputFileHeaders.getPermissionAsString()+") ...");
  444.                     setPermission(this.outputFileHeaders);
  445.                     if(this.debug)
  446.                         this.logger.debug("Modifica diritti del file ["+this.outputFileHeaders.getOutputFile().getAbsolutePath()+"] ("+this.outputFileHeaders.getPermissionAsString()+") effettuata");
  447.                 }
  448.             }
  449.            

  450.            
  451.            
  452.            
  453.             /* ------------  PostOutRequestHandler ------------- */
  454.             this.postOutRequest();
  455.            
  456.            
  457.            
  458.            
  459.             // return code
  460.             this.codice = 200; // codice deve essere impostato prima delle invocazioni dei successivi metodi nel caso di gestione response, altrimenti cmq ho finito
  461.            

  462.            
  463.             if(this.generateResponse){

  464.                
  465.                
  466.                 /* ------------  PreInResponseHandler ------------- */
  467.                 this.preInResponse();
  468.                
  469.                 // Lettura risposta parametri NotifierInputStream per la risposta
  470.                 this.notifierInputStreamParams = null;
  471.                 if(this.preInResponseContext!=null){
  472.                     this.notifierInputStreamParams = this.preInResponseContext.getNotifierInputStreamParams();
  473.                 }

  474.                
  475.                
  476.                
  477.                
  478.                
  479.                 /* ------------  Response ------------- */
  480.                
  481.                 // InputFile
  482.                 this.checkInputFile(this.inputFile, "Response");
  483.                
  484.                 // InputFile Header
  485.                 if(this.inputFileHeaders!=null){
  486.                     this.checkInputFile(this.inputFileHeaders, "Response-Headers");
  487.                     this.propertiesTrasportoRisposta = new HashMap<>();
  488.                     FileInputStream fin = new FileInputStream(this.inputFileHeaders);
  489.                     try{
  490.                         Properties pTmp = new Properties();
  491.                         pTmp.load(fin);
  492.                         if(pTmp.size()>0) {
  493.                             Enumeration<Object> en = pTmp.keys();
  494.                             while (en.hasMoreElements()) {
  495.                                 Object oKey = (Object) en.nextElement();
  496.                                 if(oKey instanceof String) {
  497.                                     String key = (String) oKey;
  498.                                     String value = pTmp.getProperty(key);
  499.                                     TransportUtils.addHeader(this.propertiesTrasportoRisposta, key, value);            
  500.                                 }
  501.                             }
  502.                            
  503.                         }
  504.                     }
  505.                     catch(Exception e){
  506.                         throw new Exception("Input File (Response-Headers) ["+this.inputFileHeaders.getAbsolutePath()+"] with wrong format: "+e.getMessage(),e);
  507.                     }
  508.                     finally{
  509.                         try{
  510.                             if(fin!=null){
  511.                                 fin.close();
  512.                             }
  513.                         }catch(Exception eClose){
  514.                             // close
  515.                         }
  516.                     }
  517.                 }
  518.        
  519.                
  520.                 // Dati Risposta
  521.                 if(this.debug)
  522.                     this.logger.debug("Analisi risposta...");
  523.                 if(this.propertiesTrasportoRisposta!=null && this.propertiesTrasportoRisposta.size()>0){            
  524.                     this.tipoRisposta = TransportUtils.getFirstValue(this.propertiesTrasportoRisposta, HttpConstants.CONTENT_TYPE);
  525.                 }
  526.                 if(this.tipoRisposta==null || "".equals(this.tipoRisposta)) {
  527.                     this.tipoRisposta = contentTypeRichiesta;
  528.                     if(this.propertiesTrasportoRisposta==null) {
  529.                         this.propertiesTrasportoRisposta = new HashMap<>();
  530.                     }
  531.                     TransportUtils.setHeader(this.propertiesTrasportoRisposta, HttpConstants.CONTENT_TYPE, this.tipoRisposta);
  532.                 }

  533.                                
  534.                 // Parametri di imbustamento
  535.                 if(this.isSoap){
  536.                     this.imbustamentoConAttachment = false;
  537.                     if(this.propertiesTrasportoRisposta!=null && this.propertiesTrasportoRisposta.size()>0){
  538.                         if("true".equals(TransportUtils.getObjectAsString(this.propertiesTrasportoRisposta, this.openspcoopProperties.getTunnelSOAPKeyWord_headerTrasporto()))){
  539.                             this.imbustamentoConAttachment = true;
  540.                         }
  541.                         this.mimeTypeAttachment = TransportUtils.getFirstValue(this.propertiesTrasportoRisposta, this.openspcoopProperties.getTunnelSOAPKeyWordMimeType_headerTrasporto());
  542.                         if(this.mimeTypeAttachment==null)
  543.                             this.mimeTypeAttachment = HttpConstants.CONTENT_TYPE_OPENSPCOOP2_TUNNEL_SOAP;
  544.                         //System.out.println("IMB["+imbustamentoConAttachment+"] MIME["+mimeTypeAttachment+"]");
  545.                     }
  546.                 }
  547.                
  548.                
  549.                 // Gestione risposta
  550.                
  551.                 this.isResponse = new FileInputStream(this.inputFile);
  552.                                
  553.                 this.normalizeInputStreamResponse(readConnectionTimeout, readConnectionTimeoutConfigurazioneGlobale);
  554.                
  555.                 this.initCheckContentTypeConfiguration();
  556.                
  557.                 if(this.isDumpBinarioRisposta()){
  558.                     this.dumpResponse(this.propertiesTrasportoRisposta);
  559.                 }
  560.                                
  561.                 if(this.isRest){
  562.                    
  563.                     if(this.doRestResponse()==false){
  564.                         return false;
  565.                     }
  566.                    
  567.                 }
  568.                 else{
  569.                
  570.                     if(this.doSoapResponse()==false){
  571.                         return false;
  572.                     }
  573.                    
  574.                 }
  575.                
  576.             }


  577.             if(this.debug)
  578.                 this.logger.info("Gestione consegna su file effettuata con successo",false);
  579.            
  580.             return true;

  581.         }  catch(Exception e){
  582.             this.eccezioneProcessamento = e;
  583.             String msgErrore = this.readExceptionMessageFromException(e);
  584.             if(this.generateErrorWithConnectorPrefix) {
  585.                 this.errore = "Errore avvenuto durante la consegna su FileSystem: "+msgErrore;
  586.             }
  587.             else {
  588.                 this.errore = msgErrore;
  589.             }
  590.             this.logger.error("Errore avvenuto durante la consegna su FileSystem: "+msgErrore,e);
  591.            
  592.             /**this.processConnectionTimeoutException(connectionTimeout, e, msgErrore);*/
  593.            
  594.             this.processReadTimeoutException(readConnectionTimeout, readConnectionTimeoutConfigurazioneGlobale, e, msgErrore);
  595.            
  596.             return false;
  597.         }
  598.     }
  599.    
  600.     /**
  601.      * Effettua la disconnessione
  602.      */
  603.     @Override
  604.     public void disconnect() throws ConnettoreException{
  605.         List<Throwable> listExceptionChiusura = new ArrayList<Throwable>();
  606.         try{
  607.        
  608.             // Gestione finale
  609.            
  610.             if(this.isResponse!=null){
  611.                 if(this.debug && this.logger!=null)
  612.                     this.logger.debug("Chiusura inputStream ["+this.inputFile.getAbsolutePath()+"] ...");
  613.                 try{
  614.                     this.isResponse.close();
  615.                     if(this.debug && this.logger!=null)
  616.                         this.logger.debug("Chiusura inputStream ["+this.inputFile.getAbsolutePath()+"] effettuata con successo");
  617.                 }catch(Throwable e){
  618.                     if(this.logger!=null)
  619.                         this.logger.error("Chiusura inputStream ["+this.inputFile.getAbsolutePath()+"] non riuscita");
  620.                     listExceptionChiusura.add(e);
  621.                 }
  622.             }
  623.            
  624.             if(this.inputFile!=null && this.inputFileDeleteAfterRead && this.inputFile.exists()){
  625.                 if(this.debug && this.logger!=null)
  626.                     this.logger.debug("Eliminazione File ["+this.inputFile.getAbsolutePath()+"] ...");
  627.                 if(this.inputFile.delete()){
  628.                     if(this.debug && this.logger!=null)
  629.                         this.logger.debug("Eliminazione File ["+this.inputFile.getAbsolutePath()+"] effettuata con successo");
  630.                 }
  631.                 else{
  632.                     if(this.logger!=null)
  633.                         this.logger.error("Eliminazione File ["+this.inputFile.getAbsolutePath()+"] non riuscita");
  634.                 }
  635.             }
  636.            
  637.             // Gestione finale della connessione
  638.             if(this.inputFileHeaders!=null && this.inputFileDeleteAfterRead && this.inputFileHeaders.exists()){
  639.                 if(this.debug && this.logger!=null)
  640.                     this.logger.debug("Eliminazione File ["+this.inputFileHeaders.getAbsolutePath()+"] ...");
  641.                 if(this.inputFileHeaders.delete()){
  642.                     if(this.debug && this.logger!=null)
  643.                         this.logger.debug("Eliminazione File ["+this.inputFileHeaders.getAbsolutePath()+"] effettuata con successo");
  644.                 }
  645.                 else{
  646.                     if(this.logger!=null)
  647.                         this.logger.error("Eliminazione File ["+this.inputFileHeaders.getAbsolutePath()+"] non riuscita");
  648.                 }
  649.             }
  650.    

  651.            
  652.             // super.disconnect (Per risorse base)
  653.             try {
  654.                 super.disconnect();
  655.             }catch(Throwable t) {
  656.                 this.logger.debug("Chiusura risorse fallita: "+t.getMessage(),t);
  657.                 listExceptionChiusura.add(t);
  658.             }
  659.            
  660.         }catch(Exception e){
  661.             throw new ConnettoreException("Chiusura non riuscita: "+e.getMessage(),e);
  662.         }
  663.        
  664.         if(listExceptionChiusura!=null && !listExceptionChiusura.isEmpty()) {
  665.             org.openspcoop2.utils.UtilsMultiException multiException = new org.openspcoop2.utils.UtilsMultiException(listExceptionChiusura.toArray(new Throwable[1]));
  666.             throw new ConnettoreException("Chiusura connessione non riuscita: "+multiException.getMessage(),multiException);
  667.         }
  668.     }

  669.    
  670.     /**
  671.      * Ritorna l'informazione su dove il connettore sta spedendo il messaggio
  672.      *
  673.      * @return location di inoltro del messaggio
  674.      */
  675.     @Override
  676.     public String getLocation(){
  677.         return this.location;
  678.     }


  679.     private void setRequestHeader(String key, String value, ConnettoreLogger logger, Map<String, List<String>> propertiesTrasportoDebug) throws Exception {
  680.         List<String> list = new ArrayList<>();
  681.         list.add(value);
  682.         this.setRequestHeader(key, list, logger, propertiesTrasportoDebug);
  683.     }
  684.     private void setRequestHeader(String key, List<String> values, ConnettoreLogger logger, Map<String, List<String>> propertiesTrasportoDebug) throws Exception {
  685.        
  686.         if(this.debug) {
  687.             if(values!=null && !values.isEmpty()) {
  688.                 for (String value : values) {
  689.                     this.logger.info("Set proprietà trasporto ["+key+"]=["+value+"]",false);        
  690.                 }
  691.             }
  692.         }
  693.         setRequestHeader(key, values, propertiesTrasportoDebug);
  694.        
  695.     }
  696.    
  697.     @Override
  698.     protected void setRequestHeader(String key,List<String> values) throws Exception{
  699.         if(values!=null && !values.isEmpty()) {
  700.             for (String value : values) {
  701.                 this.boutFileOutputHeaders.write((key+"="+value+"\n").getBytes());      
  702.             }
  703.         }
  704.     }
  705.    
  706.    
  707.     private void checkOutputFile(ConnettoreFile_outputConfig fileConfig, String tipo) throws Exception{
  708.         File file = fileConfig.getOutputFile();
  709.         if(this.debug){
  710.             this.logger.debug("Check file output ("+tipo+") ["+file.getAbsolutePath()+"]...");
  711.         }
  712.         if(file.exists()){
  713.             if(this.debug){
  714.                 this.logger.debug("File output ("+tipo+") ["+file.getAbsolutePath()+"] exists canRead["+file.canRead()+
  715.                     "] canWrite["+file.canWrite()+"] canExcute["+file.canExecute()+"] isDirectory["+
  716.                     file.isDirectory()+"] isFile["+file.isFile()+"] isHidden["+file.isHidden()+"]");    
  717.             }
  718.             if(this.outputFileOverwriteIfExists==false){
  719.                 throw new Exception("Output File ("+tipo+") ["+file.getAbsolutePath()+"] already exists (overwrite not permitted)");
  720.             }
  721.             if(file.isFile()==false){
  722.                 throw new Exception("Output File ("+tipo+") ["+file.getAbsolutePath()+"] already exists with uncorrect type (is Directory?)");
  723.             }
  724.             if(file.canWrite()==false){
  725.                 throw new Exception("Output File ("+tipo+") ["+file.getAbsolutePath()+"] already exists (cannot rewrite)");
  726.             }
  727.         }
  728.         if(this.debug){
  729.             this.logger.debug("("+tipo+") Check parent directory ...");
  730.         }
  731.         if(file.getParentFile()!=null){
  732.             if(this.debug){
  733.                 this.logger.debug("("+tipo+") Check parent directory ["+file.getParentFile().getAbsolutePath()+"] ...");
  734.             }
  735.             if(file.getParentFile().exists()==false){
  736.                 if(this.outputFileAutoCreateParentDirectory==false){
  737.                     throw new Exception("Parent Directory Output File ("+tipo+") ["+file.getParentFile().getAbsolutePath()+"] not exists (auto create not permitted)");
  738.                 }
  739.                 FileSystemUtilities.mkdirParentDirectory(file,
  740.                         fileConfig.getReadable(), fileConfig.getReadable_ownerOnly(),
  741.                         fileConfig.getWritable(), fileConfig.getWritable_ownerOnly(),
  742.                         fileConfig.getExecutable(), fileConfig.getExecutable_ownerOnly());
  743.             }
  744.             else{
  745.                 if(this.debug){
  746.                     this.logger.debug("Parent Directory Output File ("+tipo+") ["+file.getParentFile().getAbsolutePath()+"] exists canRead["+file.getParentFile().canRead()+
  747.                         "] canWrite["+file.getParentFile().canWrite()+"] canExcute["+file.getParentFile().canExecute()+"] isDirectory["+
  748.                         file.getParentFile().isDirectory()+"] isFile["+file.getParentFile().isFile()+"] isHidden["+file.getParentFile().isHidden()+"]");    
  749.                 }
  750.                 if(file.getParentFile().isDirectory()==false){
  751.                     throw new Exception("Parent Directory Output File ("+tipo+") ["+file.getParentFile().getAbsolutePath()+"] already exists with uncorrect type (is File?)");
  752.                 }
  753.                 if(file.getParentFile().canWrite()==false){
  754.                     throw new Exception("Parent Directory Output File ("+tipo+") ["+file.getParentFile().getAbsolutePath()+"] already exists (cannot rewrite)");
  755.                 }
  756.             }
  757.         }
  758.     }
  759.    
  760.     private void checkInputFile(File file, String tipo) throws Exception{
  761.         if(this.debug){
  762.             this.logger.debug("Check file input ("+tipo+") ["+file.getAbsolutePath()+"]...");
  763.         }
  764.         if(file.exists()){
  765.             this._checkInputFile(file, tipo);
  766.         }
  767.         else{
  768.            
  769.             if(this.inputFileWaitTimeIfNotExists!=null && this.inputFileWaitTimeIfNotExists>0){
  770.                
  771.                 int millisecond = this.inputFileWaitTimeIfNotExists;
  772.                 int tempoSingoloSleepMs = 250;
  773.                 if(millisecond>tempoSingoloSleepMs){
  774.                     int count = millisecond/tempoSingoloSleepMs;
  775.                     int resto = millisecond%tempoSingoloSleepMs;
  776.                     this.logger.info("Wait "+millisecond+"ms ...", false);
  777.                     for (int i = 0; i < count; i++) {
  778.                         Utilities.sleep(tempoSingoloSleepMs);
  779.                         if(file.exists()){
  780.                             break;
  781.                         }
  782.                     }
  783.                     if(!file.exists()){
  784.                         Utilities.sleep(resto);
  785.                     }
  786.                     this.logger.info("Wait "+millisecond+"ms terminated", false);
  787.                 }else{
  788.                     this.logger.info("Wait "+millisecond+"ms ...", false);
  789.                     Utilities.sleep(tempoSingoloSleepMs);
  790.                     this.logger.info("Wait "+millisecond+"ms terminated", false);
  791.                 }
  792.                
  793.                 if(file.exists()){
  794.                     this._checkInputFile(file, tipo);
  795.                 }
  796.                 else{
  797.                     throw new Exception("Input File ("+tipo+") ["+file.getAbsolutePath()+"] not exists (wait "+millisecond+"ms)");
  798.                 }
  799.             }
  800.             else{
  801.                 throw new Exception("Input File ("+tipo+") ["+file.getAbsolutePath()+"] not exists");
  802.             }
  803.         }
  804.     }
  805.     private void _checkInputFile(File file, String tipo) throws Exception{
  806.         if(this.debug){
  807.             this.logger.debug("File input ("+tipo+") ["+file.getAbsolutePath()+"] exists canRead["+file.canRead()+
  808.                 "] canWrite["+file.canWrite()+"] canExcute["+file.canExecute()+"] isDirectory["+
  809.                 file.isDirectory()+"] isFile["+file.isFile()+"] isHidden["+file.isHidden()+"] lenght["+file.length()+"]");  
  810.         }
  811.         if(file.isFile()==false){
  812.             throw new Exception("Input File ("+tipo+") ["+file.getAbsolutePath()+"] with uncorrect type (is Directory?)");
  813.         }
  814.         if(file.canRead()==false){
  815.             throw new Exception("Input File ("+tipo+") ["+file.getAbsolutePath()+"] cannot read");
  816.         }
  817.         if(file.length()<=0){
  818.             throw new Exception("Input File ("+tipo+") ["+file.getAbsolutePath()+"] empty");
  819.         }
  820.         if(this.inputFileDeleteAfterRead){
  821.             if(file.canWrite()==false){
  822.                 throw new Exception("Input File ("+tipo+") ["+file.getAbsolutePath()+"] cannot write (delete after read required)");
  823.             }
  824.         }
  825.     }

  826.     private ConnettoreFile_outputConfig readOutputConfig(String tipoConnettore,boolean required, String file, String permission) throws ConnettoreException {
  827.         String tmp = this.getDynamicProperty(tipoConnettore, required, file, this.dynamicMap);
  828.         if(tmp==null){
  829.             return null;
  830.         }
  831.         ConnettoreFile_outputConfig c = new ConnettoreFile_outputConfig();
  832.         c.setOutputFile(new File(tmp));
  833.        
  834.         String p = this.getDynamicProperty(tipoConnettore, false, permission, this.dynamicMap);
  835.         if(p!=null) {
  836.              validatePermission(p, c);
  837.         }
  838.         return c;
  839.     }
  840.    
  841.     public static void validatePermission(String p, ConnettoreFile_outputConfig c) throws ConnettoreException {
  842.         Scanner scanner = new Scanner(p);
  843.         try {
  844.             while (scanner.hasNextLine()) {
  845.                 String line = scanner.nextLine();
  846.                 if(line==null || line.trim().equals("") || line.trim().startsWith("#")) {
  847.                     continue;
  848.                 }
  849.                 _validateSinglePermission(line,c);
  850.             }
  851.         }finally {
  852.             scanner.close();
  853.         }
  854.     }
  855.    
  856.     public static int getNumPermission(String p) throws ConnettoreException {
  857.         Scanner scanner = new Scanner(p);
  858.         int num = 0;
  859.         try {
  860.             while (scanner.hasNextLine()) {
  861.                 String line = scanner.nextLine();
  862.                 if(line==null || line.trim().equals("") || line.trim().startsWith("#")) {
  863.                     continue;
  864.                 }
  865.                 num++;
  866.             }
  867.             return num;
  868.         }finally {
  869.             scanner.close();
  870.         }
  871.     }
  872.    
  873.     public static final String PERMESSI_FORMATO = "[o/a]+/-rwx";
  874.     private static void _validateSinglePermission(String p, ConnettoreFile_outputConfig config) throws ConnettoreException {
  875.         String errorMsg = "Wrong permission format ("+p+"); expected "+PERMESSI_FORMATO;
  876.         if(p==null || StringUtils.isEmpty(p) || (!p.contains("+") && !p.contains("-")) || p.length()<=1) {
  877.             throw new ConnettoreException(errorMsg);
  878.         }
  879.        
  880.         String permission = null;
  881.         boolean add = false;
  882.         Boolean owner = null;
  883.         if(p.startsWith("+")) {
  884.             permission = p.substring(1);
  885.             add = true;
  886.         }
  887.         else if(p.startsWith("-")) {
  888.             permission = p.substring(1);
  889.             add = false;
  890.         }
  891.         else if(p.contains("+")) {
  892.             add = true;
  893.             int indexOf = p.indexOf("+");
  894.             String ownerS = p.substring(0, indexOf);
  895.             if(!"o".equals(ownerS) && !"a".equals(ownerS)) {
  896.                 throw new ConnettoreException(errorMsg);
  897.             }
  898.             if("o".equals(ownerS)) {
  899.                 owner = true;
  900.             }
  901.             else if("a".equals(ownerS)) {
  902.                 owner = false;
  903.             }
  904.             if(indexOf == (p.length()-1)) {
  905.                 throw new ConnettoreException(errorMsg);
  906.             }
  907.             permission = p.substring(indexOf+1, p.length());
  908.         }
  909.         else if(p.contains("-")) {
  910.             add = false;
  911.             int indexOf = p.indexOf("-");
  912.             String ownerS = p.substring(0, indexOf);
  913.             if(!"o".equals(ownerS) && !"a".equals(ownerS)) {
  914.                 throw new ConnettoreException(errorMsg);
  915.             }
  916.             if("o".equals(ownerS)) {
  917.                 owner = true;
  918.             }
  919.             else if("a".equals(ownerS)) {
  920.                 owner = false;
  921.             }
  922.             if(indexOf == (p.length()-1)) {
  923.                 throw new ConnettoreException(errorMsg);
  924.             }
  925.             permission = p.substring(indexOf+1, p.length());
  926.         }
  927.        
  928.         if(permission!=null) {
  929.             for (int i = 0; i < permission.length(); i++) {
  930.                 char c = permission.charAt(i);
  931.                 if(c == 'r' || c == 'R') {
  932.                     config.setReadable(add);
  933.                     if(owner!=null) {
  934.                         config.setReadable_ownerOnly(owner);
  935.                     }
  936.                 }
  937.                 else if(c == 'w' || c == 'W') {
  938.                     config.setWritable(add);
  939.                     if(owner!=null) {
  940.                         config.setWritable_ownerOnly(owner);
  941.                     }
  942.                 }
  943.                 else if(c == 'x' || c == 'X') {
  944.                     config.setExecutable(add);
  945.                     if(owner!=null) {
  946.                         config.setExecutable_ownerOnly(owner);
  947.                     }
  948.                 }
  949.                 else {
  950.                     throw new ConnettoreException(errorMsg);
  951.                 }
  952.             }
  953.         }
  954.        
  955.     }
  956.    
  957.     private void setPermission(ConnettoreFile_outputConfig config) throws ConnettoreException {
  958.         if(config.getReadable()!=null) {
  959.             if(config.getReadable_ownerOnly()!=null) {
  960.                 if(!config.getOutputFile().setReadable(config.getReadable(), config.getReadable_ownerOnly())) {
  961.                     // ignore
  962.                 }
  963.             }
  964.             else {
  965.                 if(!config.getOutputFile().setReadable(config.getReadable())) {
  966.                     // ignore
  967.                 }
  968.             }
  969.         }
  970.         if(config.getWritable()!=null) {
  971.             if(config.getWritable_ownerOnly()!=null) {
  972.                 if(!config.getOutputFile().setWritable(config.getWritable(), config.getWritable_ownerOnly())) {
  973.                     // ignore
  974.                 }
  975.             }
  976.             else {
  977.                 if(!config.getOutputFile().setWritable(config.getWritable())) {
  978.                     // ignore
  979.                 }
  980.             }
  981.         }
  982.         if(config.getExecutable()!=null) {
  983.             if(config.getExecutable_ownerOnly()!=null) {
  984.                 if(!config.getOutputFile().setExecutable(config.getExecutable(), config.getExecutable_ownerOnly())) {
  985.                     // ignore
  986.                 }
  987.             }
  988.             else {
  989.                 if(!config.getOutputFile().setExecutable(config.getExecutable())) {
  990.                     // ignore
  991.                 }
  992.             }
  993.         }
  994.     }
  995. }