ConnettoreBaseWithResponse.java
/*
* GovWay - A customizable API Gateway
* https://govway.org
*
* Copyright (c) 2005-2024 Link.it srl (https://link.it).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3, as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.openspcoop2.pdd.core.connettori;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.input.CountingInputStream;
import org.openspcoop2.core.config.driver.DriverConfigurazioneException;
import org.openspcoop2.core.transazioni.constants.TipoMessaggio;
import org.openspcoop2.message.OpenSPCoop2MessageParseResult;
import org.openspcoop2.message.constants.MessageRole;
import org.openspcoop2.message.constants.MessageType;
import org.openspcoop2.message.exception.ParseExceptionUtils;
import org.openspcoop2.message.soap.AbstractOpenSPCoop2Message_soap_impl;
import org.openspcoop2.message.soap.SoapUtils;
import org.openspcoop2.message.soap.TunnelSoapUtils;
import org.openspcoop2.pdd.core.CostantiPdD;
import org.openspcoop2.pdd.core.controllo_traffico.LimitExceededNotifier;
import org.openspcoop2.pdd.core.controllo_traffico.ReadTimeoutConfigurationUtils;
import org.openspcoop2.pdd.core.controllo_traffico.ReadTimeoutContextParam;
import org.openspcoop2.pdd.core.controllo_traffico.SogliaReadTimeout;
import org.openspcoop2.pdd.core.controllo_traffico.TimeoutNotifier;
import org.openspcoop2.pdd.core.controllo_traffico.TimeoutNotifierType;
import org.openspcoop2.pdd.logger.DiagnosticInputStream;
import org.openspcoop2.pdd.logger.MsgDiagnosticiProperties;
import org.openspcoop2.pdd.logger.OpenSPCoop2Logger;
import org.openspcoop2.pdd.mdb.ConsegnaContenutiApplicativi;
import org.openspcoop2.protocol.sdk.ProtocolException;
import org.openspcoop2.utils.CopyStream;
import org.openspcoop2.utils.LimitedInputStream;
import org.openspcoop2.utils.TimeoutInputStream;
import org.openspcoop2.utils.Utilities;
import org.openspcoop2.utils.dch.MailcapActivationReader;
import org.openspcoop2.utils.io.DumpByteArrayOutputStream;
import org.openspcoop2.utils.io.notifier.NotifierInputStreamParams;
import org.openspcoop2.utils.transport.TransportResponseContext;
import org.openspcoop2.utils.transport.http.ContentTypeUtilities;
/**
* ConnettoreBaseWithResponse
*
*
* @author Poli Andrea (apoli@link.it)
* @author $Author$
* @version $Rev$, $Date$
*/
public abstract class ConnettoreBaseWithResponse extends ConnettoreBase {
/** InputStream Risposta */
protected InputStream isResponse = null;
/** MessageType Risposta */
protected MessageType messageTypeResponse = null;
/** ContentType Risposta */
protected String tipoRisposta = null;
/** Check ContentType */
protected boolean checkContentType = true;
/** NotifierInputStreamParams */
protected NotifierInputStreamParams notifierInputStreamParams;
/** Imbustamento SOAP */
protected boolean imbustamentoConAttachment;
protected String mimeTypeAttachment;
/** acceptOnlyReturnCode_202_200 SOAP */
protected boolean acceptOnlyReturnCode_202_200 = true;
protected void normalizeInputStreamResponse(int timeout, boolean configurazioneGlobale) throws Exception{
//Se non e' null, controllo che non sia vuoto.
if(this.isResponse!=null){
this.isResponse = Utilities.normalizeStream(this.isResponse, false);
}
else{
this.logger.info("Stream di risposta (return-code:"+this.codice+") is null",true);
}
if(this.isResponse!=null && this.useLimitedInputStream) {
if(this.limitBytes!=null && this.limitBytes.getSogliaKb()>0) {
LimitExceededNotifier notifier = new LimitExceededNotifier(this.getPddContext(), this.limitBytes, this.logger.getLogger());
long limitBytes = this.limitBytes.getSogliaKb()*1024; // trasformo kb in bytes
this.isResponse = new LimitedInputStream(this.isResponse, limitBytes,
CostantiPdD.PREFIX_LIMITED_RESPONSE,
this.getPddContext(),
notifier);
}
}
if(this.isResponse!=null && this.useTimeoutInputStream) {
if(timeout>0) {
TimeoutNotifier notifier = getTimeoutNotifier(timeout, configurazioneGlobale, TimeoutNotifierType.RECEIVE_RESPONSE);
this.isResponse = new TimeoutInputStream(this.isResponse, timeout,
CostantiPdD.PREFIX_TIMEOUT_RESPONSE,
this.getPddContext(),
notifier);
}
}
if(this.isResponse!=null && this.useDiagnosticInputStream && this.msgDiagnostico!=null) {
String idModuloFunzionale =
ConsegnaContenutiApplicativi.ID_MODULO.equals(this.idModulo) ?
MsgDiagnosticiProperties.MSG_DIAG_CONSEGNA_CONTENUTI_APPLICATIVI : MsgDiagnosticiProperties.MSG_DIAG_INOLTRO_BUSTE;
this.isResponse = new DiagnosticInputStream(this.isResponse, idModuloFunzionale, "letturaPayloadRisposta", false, this.msgDiagnostico,
(this.logger!=null && this.logger.getLogger()!=null) ? this.logger.getLogger() : OpenSPCoop2Logger.getLoggerOpenSPCoopCore(),
this.getPddContext());
}
}
protected TimeoutNotifier getTimeoutNotifier(int timeout, boolean configurazioneGlobale, TimeoutNotifierType type) throws DriverConfigurazioneException, ProtocolException {
SogliaReadTimeout soglia = null;
if(ConsegnaContenutiApplicativi.ID_MODULO.equals(this.idModulo) || this.pa!=null) {
soglia = (this.pa!=null) ?
ReadTimeoutConfigurationUtils.buildSogliaResponseTimeout(timeout, configurazioneGlobale, this.pa, this.nomeConnettoreAsincrono, this.policyTimeoutConfig,
new ReadTimeoutContextParam(this.requestInfo, this.getProtocolFactory(), this.getPddContext(), this.state)) :
ReadTimeoutConfigurationUtils.buildSogliaResponseTimeout(timeout, false, this.getProtocolFactory());
}
else {
soglia = (this.pd!=null) ?
ReadTimeoutConfigurationUtils.buildSogliaResponseTimeout(timeout, configurazioneGlobale, this.pd, this.policyTimeoutConfig,
new ReadTimeoutContextParam(this.requestInfo, this.getProtocolFactory(), this.getPddContext(), this.state)) :
ReadTimeoutConfigurationUtils.buildSogliaResponseTimeout(timeout, true, this.getProtocolFactory());
}
boolean saveInContext = !(this.policyTimeoutConfig!=null &&
(this.policyTimeoutConfig.getAttributeAuthority()!=null || this.policyTimeoutConfig.getAttributeAuthorityResponseJwt()!=null)
);
return new TimeoutNotifier(this.getPddContext(), this.getProtocolFactory(),
soglia, type, this.logger.getLogger(), saveInContext);
}
public static boolean isReadTimeoutException(Exception e, String message){
return "Read timed out".equals(message) && (e instanceof java.net.SocketTimeoutException);
}
public static boolean containsReadTimeoutException(Exception e, String message){
return message!=null && message.contains("Read timed out") && (e instanceof java.net.SocketTimeoutException || Utilities.existsInnerException(e, java.net.SocketTimeoutException.class));
}
protected void processReadTimeoutException(int timeout, boolean configurazioneGlobale, Exception e, String message) {
try {
if(timeout>0 && isReadTimeoutException(e, message)) {
TimeoutNotifier notifier = getTimeoutNotifier(timeout, configurazioneGlobale, TimeoutNotifierType.WAIT_RESPONSE);
notifier.notify(timeout);
}
}catch(Exception error) {
if(this.logger!=null) {
this.logger.error("Errore avvenuto durante la registrazione dell'evento di read timeout: "+error.getMessage(),error);
}
}
}
public static boolean isConnectionTimeoutException(Exception e, String message){
return "connect timed out".equals(message) && (e instanceof java.net.SocketTimeoutException);
}
public static boolean containsConnectionTimeoutException(Exception e, String message){
return message!=null && message.contains("connect timed out") && (e instanceof java.net.SocketTimeoutException || Utilities.existsInnerException(e, java.net.SocketTimeoutException.class));
}
protected void processConnectionTimeoutException(int timeout, boolean configurazioneGlobale, Exception e, String message) {
try {
if(timeout>0 && isConnectionTimeoutException(e, message)) {
TimeoutNotifier notifier = getTimeoutNotifier(timeout, configurazioneGlobale, TimeoutNotifierType.CONNECTION);
notifier.notify(timeout);
}
}catch(Exception error) {
if(this.logger!=null) {
this.logger.error("Errore avvenuto durante la registrazione dell'evento di connection timeout: "+error.getMessage(),error);
}
}
}
protected void initCheckContentTypeConfiguration(){
this.checkContentType = true;
if(this.idModulo!=null){
if(ConsegnaContenutiApplicativi.ID_MODULO.equals(this.idModulo)){
this.checkContentType = this.openspcoopProperties.isControlloContentTypeAbilitatoRicezioneBuste();
}else{
this.checkContentType = this.openspcoopProperties.isControlloContentTypeAbilitatoRicezioneContenutiApplicativi();
}
}
}
protected void initConfigurationAcceptOnlyReturnCode_202_200(){
this.acceptOnlyReturnCode_202_200 = true;
if(this.isRest){
this.acceptOnlyReturnCode_202_200 = false;
}
else{
if(ConsegnaContenutiApplicativi.ID_MODULO.equals(this.idModulo)){
this.acceptOnlyReturnCode_202_200 = this.openspcoopProperties.isAcceptOnlyReturnCode_200_202_consegnaContenutiApplicativi();
}
else{
// InoltroBuste e InoltroRisposte
this.acceptOnlyReturnCode_202_200 = this.openspcoopProperties.isAcceptOnlyReturnCode_200_202_inoltroBuste();
}
}
}
protected boolean dumpResponse(Map<String, List<String>> trasporto) throws Exception{
Exception exceptionCheck = null;
try {
if(this.isRest){
checkRestResponseMessageType();
}
else {
checkSoapResponseMessageType();
}
}catch(Exception e) {
exceptionCheck = e;
}
boolean returnValue = false;
try {
returnValue = _dumpResponse(trasporto);
}
catch(Exception e) {
if(exceptionCheck!=null) {
throw exceptionCheck;
}
else {
throw e;
}
}
if(exceptionCheck!=null) {
throw exceptionCheck;
}
else {
return returnValue;
}
}
private DumpByteArrayOutputStream readResponseForDump() throws Exception{
DumpByteArrayOutputStream bout = null;
try {
bout = new DumpByteArrayOutputStream(this.dumpBinario_soglia, this.dumpBinario_repositoryFile, this.idTransazione,
TipoMessaggio.RISPOSTA_INGRESSO_DUMP_BINARIO.getValue());
this.emitDiagnosticStartDumpBinarioRispostaIngresso();
// byte [] readB = new byte[Utilities.DIMENSIONE_BUFFER];
// int readByte = 0;
// while((readByte = this.isResponse.read(readB))!= -1){
// bout.write(readB,0,readByte);
// }
//System.out.println("READ FROM ["+this.isResponse.getClass().getName()+"] ...");
CopyStream.copy(this.isResponse, bout);
//System.out.println("READ FROM ["+this.isResponse.getClass().getName()+"] complete");
this.isResponse.close();
}finally {
try {
if(bout!=null) {
bout.flush();
}
}catch(Throwable t) {
// ignore
}
try {
if(bout!=null) {
bout.close();
}
}catch(Throwable t) {
// ignore
}
}
return bout;
}
private boolean _dumpResponse(Map<String, List<String>> trasporto) throws Exception{
if(this.isResponse!=null){
this.emitDiagnosticResponseRead(this.isResponse);
// Registro Debug.
DumpByteArrayOutputStream bout = null;
try {
bout = readResponseForDump();
if(this.debug) {
this.logger.info("Messaggio ricevuto (ContentType:"+this.tipoRisposta+") :\n"+bout.toString(),false);
}
// Creo nuovo inputStream
if(bout.isSerializedOnFileSystem()) {
this.isResponse = new FileInputStream(bout.getSerializedFile());
}
else {
this.isResponse = new ByteArrayInputStream(bout.toByteArray());
}
this.dumpBinarioRispostaIngresso(bout, this.messageTypeResponse, trasporto);
}finally {
try {
if(bout!=null) {
bout.clearResources();
}
}catch(Throwable t) {
this.logger.error("Release resources failed: "+t.getMessage(),t);
}
}
}
else {
if(this.debug) {
if(this.tipoRisposta!=null) {
this.logger.info("Messaggio ricevuto (ContentType:"+this.tipoRisposta+") senza contenuto nell'http-reply",false);
}
else {
this.logger.info("Messaggio ricevuto senza contenuto nell'http-reply",false);
}
}
// devo registrare almeno gli header HTTP
this.emitDiagnosticStartDumpBinarioRispostaIngresso();
this.dumpBinarioRispostaIngresso(null, null, trasporto);
}
return true;
}
private void checkRestResponseMessageType() throws Exception{
if(this.messageTypeResponse!=null) {
return; // gia' calcolato
}
String msgErrore = null;
Exception exErrore = null;
String contentTypeString = "N.D.";
if(this.tipoRisposta!=null && !"".equals(this.tipoRisposta)){
contentTypeString = this.tipoRisposta;
// Verifico correttezza Content-Type
try {
ContentTypeUtilities.validateContentType(contentTypeString);
}catch(Exception error){
exErrore = error;
msgErrore = "Content-Type '"+contentTypeString+"' presente nella risposta non valido: "+error.getMessage();
}
}
if(msgErrore==null) {
try{
this.messageTypeResponse = this.requestInfo.getBindingConfig().getResponseMessageType(this.requestMsg.getServiceBinding(),
this.requestMsg.getTransportRequestContext(),
this.tipoRisposta,
this.codice>0?this.codice:null);
if(this.messageTypeResponse==null){
String ctConosciuti = this.requestInfo.getBindingConfig().getContentTypesSupportedAsString(this.requestMsg.getServiceBinding(), MessageRole.RESPONSE,
this.requestMsg.getTransportRequestContext());
if(this.tipoRisposta==null){
throw new Exception("Header Content-Type non risulta definito nell'http reply e non esiste una configurazione che supporti tale casistica. Content-Type conosciuti: "+ctConosciuti);
}
else {
throw new Exception("Header Content-Type definito nell'http reply non è tra quelli conosciuti: "+ctConosciuti);
}
}
}catch(Exception e){
exErrore = e;
msgErrore = "Non è stato possibile comprendere come trattare il messaggio ricevuto (Content-Type: "+contentTypeString+"): "+e.getMessage();
}
}
if(msgErrore!=null){
if(this.checkContentType){
//if(exErrore!=null){
this.logger.error(msgErrore,exErrore);
//}
//else{
// this.logger.error(msgErrore);
//}
Exception e = new Exception(msgErrore);
this.getPddContext().addObject(org.openspcoop2.core.constants.Costanti.CONTENUTO_RISPOSTA_NON_RICONOSCIUTO, true);
this.getPddContext().addObject(org.openspcoop2.core.constants.Costanti.CONTENUTO_RISPOSTA_NON_RICONOSCIUTO_PARSE_EXCEPTION,
ParseExceptionUtils.buildParseException(e, MessageRole.RESPONSE));
throw e;
}else{
msgErrore = msgErrore+"; viene utilizzata forzatamente la tipologia "+MessageType.BINARY.name() +" come modalità di gestione del messaggio";
//if(exErrore!=null){
this.logger.warn(msgErrore,exErrore);
//}
//else{
// this.logger.warn(msgErrore);
//}
this.messageTypeResponse = MessageType.BINARY;
}
}
}
protected boolean doRestResponse() throws Exception{
if(this.debug)
this.logger.debug("gestione REST in corso ...");
checkRestResponseMessageType();
InputStream isParam = null;
if(this.contentLength>=0){
isParam = this.isResponse;
if(this.contentLength==0){
isParam = null;
}
}
else{
//non ho trovato ContentLength. Devo scoprire se c'e' un payload.
isParam = this.isResponse; // è stato normalizzato, quindi se non c'è un contenuto è null
}
TransportResponseContext responseContext = new TransportResponseContext(this.logger.getLogger());
responseContext.setCodiceTrasporto(this.codice+"");
responseContext.setContentLength(this.contentLength);
responseContext.setHeaders(this.propertiesTrasportoRisposta);
if(isParam!=null) {
this.emitDiagnosticResponseRead(isParam);
}
OpenSPCoop2MessageParseResult pr = org.openspcoop2.pdd.core.Utilities.getOpenspcoop2MessageFactory(this.logger.getLogger(),this.requestMsg, this.requestInfo,MessageRole.RESPONSE).
createMessage(this.messageTypeResponse,responseContext,
isParam,this.notifierInputStreamParams,
this.openspcoopProperties.getAttachmentsProcessingMode());
if(pr.getParseException()!=null){
this.getPddContext().addObject(org.openspcoop2.core.constants.Costanti.CONTENUTO_RISPOSTA_NON_RICONOSCIUTO_PARSE_EXCEPTION, pr.getParseException());
}
try{
this.responseMsg = pr.getMessage_throwParseException();
}catch(Exception e){
this.responseMsg=null;
// L'errore 'premature end of file' consiste solo nel fatto che una risposta non e' stata ricevuta.
boolean result2XX = (this.codice>=200 && this.codice<=299);
boolean premature = Utilities.existsInnerMessageException(e, "Premature end of file", true) && result2XX;
// Se non ho un premature, ed un errore di lettura in 200, allora devo segnalare l'errore, altrimenti comunque
// il msg ritornato e' null e nel codiceStato vi e' l'errore.
if( premature == false ){
this.eccezioneProcessamento = e;
this.errore = "Errore avvenuto durante il parsing della risposta: " + this.readExceptionMessageFromException(e);
this.logger.error("Errore avvenuto durante il parsing della risposta: " + this.readExceptionMessageFromException(e),e);
if(result2XX){
return false;
}
}
}
return true;
}
private void checkSoapResponseMessageType() throws Exception{
if(this.messageTypeResponse!=null) {
return; // gia' calcolato
}
this.contentTypeMessaggioOriginale_tunnelSoap = this.tipoRisposta; // serve per funzionalità TunnelSOAP
if(this.isResponse!=null){
if(this.sbustamentoSoap==false){
String msgErrore = null;
Exception exErrore = null;
String contentTypeString = "N.D.";
if(this.tipoRisposta!=null && !"".equals(this.tipoRisposta)){
contentTypeString = this.tipoRisposta;
// Verifico correttezza Content-Type
try {
ContentTypeUtilities.validateContentType(contentTypeString);
}catch(Exception error){
exErrore = error;
msgErrore = "Content-Type '"+contentTypeString+"' presente nella risposta non valido: "+error.getMessage();
}
}
if(msgErrore==null) {
try{
if(this.tipoRisposta==null){
// obbligatorio in SOAP
msgErrore = "Header Content-Type non definito nell'http reply";
}
else{
if(this.requestInfo==null) {
throw new Exception("BindingConfig is null");
}
if(this.requestInfo.getBindingConfig()==null) {
throw new Exception("BindingConfig is null");
}
if(this.requestMsg==null) {
throw new Exception("RequestMsg is null");
}
this.messageTypeResponse = this.requestInfo.getBindingConfig().getResponseMessageType(this.requestMsg.getServiceBinding(),
this.requestMsg.getTransportRequestContext(),
this.tipoRisposta,
this.codice>0?this.codice:null);
}
if(this.messageTypeResponse==null){
String ctConosciuti = this.requestInfo.getBindingConfig().getContentTypesSupportedAsString(this.requestMsg.getServiceBinding(), MessageRole.RESPONSE,
this.requestMsg.getTransportRequestContext());
if(this.tipoRisposta==null){
throw new Exception("Header Content-Type non risulta definito nell'http reply e non esiste una configurazione che supporti tale casistica. Content-Type conosciuti: "+ctConosciuti);
}
else {
throw new Exception("Header Content-Type definito nell'http reply non è tra quelli conosciuti: "+ctConosciuti);
}
}
else{
if(this.requestMsg.getMessageType().equals(this.messageTypeResponse)==false){
msgErrore = "Header Content-Type definito nell'http reply associato ad un tipo ("+this.messageTypeResponse.name()
+") differente da quello associato al messaggio di richiesta ("+this.requestMsg.getMessageType().name()+")";
}
}
}catch(Exception e){
exErrore = e;
msgErrore = "Non è stato possibile comprendere come trattare il messaggio ricevuto (Content-Type: "+contentTypeString+"): "+e.getMessage();
}
}
if(msgErrore!=null){
if(this.checkContentType){
Exception e = null;
if(exErrore!=null){
this.logger.error(msgErrore,exErrore);
e = new Exception(msgErrore, exErrore);
}
else{
this.logger.error(msgErrore);
e = new Exception(msgErrore);
}
this.getPddContext().addObject(org.openspcoop2.core.constants.Costanti.CONTENUTO_RISPOSTA_NON_RICONOSCIUTO, true);
this.getPddContext().addObject(org.openspcoop2.core.constants.Costanti.CONTENUTO_RISPOSTA_NON_RICONOSCIUTO_PARSE_EXCEPTION,
ParseExceptionUtils.buildParseException(e, MessageRole.RESPONSE));
throw e;
}else{
this.messageTypeResponse = MessageType.SOAP_11;
this.tipoRisposta = SoapUtils.getSoapContentTypeForMessageWithoutAttachments(this.messageTypeResponse);
msgErrore = msgErrore+"; per trattare il messaggio viene utilizzato forzatamente il content-type "+this.tipoRisposta+" e la tipologia "+MessageType.SOAP_11.name();
if(exErrore!=null){
this.logger.warn(msgErrore,exErrore);
}
else{
this.logger.warn(msgErrore);
}
}
}
}
else{
this.messageTypeResponse = this.requestMsg.getMessageType();
this.tipoRisposta = SoapUtils.getSoapContentTypeForMessageWithoutAttachments(this.messageTypeResponse);
}
}
}
private String contentTypeMessaggioOriginale_tunnelSoap = null; // serve per funzionalità TunnelSOAP;
protected boolean doSoapResponse() throws Exception{
String tipoLetturaRisposta = null;
// gestione ordinaria via WS/SOAP
if(this.debug)
this.logger.debug("gestione WS/SOAP in corso ...");
checkSoapResponseMessageType();
if(this.isResponse!=null){
TransportResponseContext responseContext = new TransportResponseContext(this.logger.getLogger());
responseContext.setCodiceTrasporto(this.codice+"");
responseContext.setContentLength(this.contentLength);
responseContext.setHeaders(this.propertiesTrasportoRisposta);
this.emitDiagnosticResponseRead(this.isResponse);
try{
if(this.sbustamentoSoap==false){
if(this.debug)
this.logger.debug("Ricostruzione normale...");
// Ricostruzione messaggio soap: secondo parametro a false, indica che il messaggio e' gia un SOAPMessage
tipoLetturaRisposta = "Parsing Risposta SOAP";
if(this.contentLength>0){
OpenSPCoop2MessageParseResult pr = org.openspcoop2.pdd.core.Utilities.getOpenspcoop2MessageFactory(this.logger.getLogger(),this.requestMsg, this.requestInfo,MessageRole.RESPONSE).
createMessage(this.messageTypeResponse,responseContext,
this.isResponse,this.notifierInputStreamParams,
this.openspcoopProperties.getAttachmentsProcessingMode());
if(pr.getParseException()!=null){
this.getPddContext().addObject(org.openspcoop2.core.constants.Costanti.CONTENUTO_RISPOSTA_NON_RICONOSCIUTO_PARSE_EXCEPTION, pr.getParseException());
}
this.responseMsg = pr.getMessage_throwParseException();
}
else if(this.contentLength==0){
this.responseMsg = null;
}
else{
// non ho trovato ContentLength. Devo scoprire se c'e' un payload.
// L'inputstream è stato normalizzato, quindi se non c'è un contenuto è null
// Devo scoprire se c'e' un payload. Costruisco il messaggio e poi provo ad accedere all'envelope
try{
OpenSPCoop2MessageParseResult pr = org.openspcoop2.pdd.core.Utilities.getOpenspcoop2MessageFactory(this.logger.getLogger(),this.requestMsg, this.requestInfo,MessageRole.RESPONSE)
.createMessage(this.messageTypeResponse,responseContext,
this.isResponse,this.notifierInputStreamParams,
this.openspcoopProperties.getAttachmentsProcessingMode());
if(pr.getParseException()!=null){
this.getPddContext().addObject(org.openspcoop2.core.constants.Costanti.CONTENUTO_RISPOSTA_NON_RICONOSCIUTO_PARSE_EXCEPTION, pr.getParseException());
}
this.responseMsg = pr.getMessage_throwParseException();
}catch(Exception e){
this.responseMsg=null;
// L'errore 'premature end of file' consiste solo nel fatto che una risposta non e' stata ricevuta.
boolean result2XX = (this.codice>=200 && this.codice<=299);
boolean premature = Utilities.existsInnerMessageException(e, "Premature end of file", true) && result2XX;
// Se non ho un premature, ed un errore di lettura in 200, allora devo segnalare l'errore, altrimenti comunque
// il msg ritornato e' null e nel codiceStato vi e' l'errore.
if( premature == false ){
this.eccezioneProcessamento = e;
this.errore = "Errore avvenuto durante il parsing della risposta: " + this.readExceptionMessageFromException(e);
this.logger.error("Errore avvenuto durante il parsing della risposta: " + this.readExceptionMessageFromException(e),e);
if(result2XX){
return false;
}
}
}
}
}else{
InputStream isParam = null;
if(this.contentLength>=0){
isParam = this.isResponse;
if(this.contentLength==0){
isParam = null;
}
}
else{
//non ho trovato ContentLength. Devo scoprire se c'e' un payload.
isParam = this.isResponse; // è stato normalizzato, quindi se non c'è un contenuto è null
}
if(isParam!=null){
CountingInputStream cis = null;
try{
cis = new CountingInputStream(isParam);
if(this.imbustamentoConAttachment){
if(this.debug)
this.logger.debug("Imbustamento con attachments...");
// Imbustamento per Tunnel OpenSPCoop
tipoLetturaRisposta = "Costruzione messaggio SOAP per Tunnel con mimeType "+this.mimeTypeAttachment;
this.responseMsg = TunnelSoapUtils.imbustamentoMessaggioConAttachment(org.openspcoop2.pdd.core.Utilities.getOpenspcoop2MessageFactory(this.logger.getLogger(),this.requestMsg, this.requestInfo,MessageRole.RESPONSE),
this.messageTypeResponse,MessageRole.RESPONSE,
cis,this.mimeTypeAttachment,
MailcapActivationReader.existsDataContentHandler(this.mimeTypeAttachment),this.contentTypeMessaggioOriginale_tunnelSoap,
this.openspcoopProperties.getHeaderSoapActorIntegrazione());
}else{
if(this.debug)
this.logger.debug("Imbustamento messaggio...");
tipoLetturaRisposta = "Imbustamento messaggio in un messaggio SOAP";
// Per ottenere il corretto content length in questo caso devo leggere tutto il messaggio
// ALtrimenti dopo effettuando la close, nel caso di saaj instreaming otterrei un errore (o il msg non viene cmq costruito)
byte[] msg = Utilities.getAsByteArray(cis);
if(msg==null || msg.length<=0){
throw new Exception("Contenuto messaggio da imbustare non presente");
}
this.isResponse.close();
// Creo nuovo inputStream
this.isResponse = new ByteArrayInputStream(msg);
OpenSPCoop2MessageParseResult pr = org.openspcoop2.pdd.core.Utilities.getOpenspcoop2MessageFactory(this.logger.getLogger(),this.requestMsg, this.requestInfo,MessageRole.RESPONSE).
envelopingMessage(this.messageTypeResponse, this.tipoRisposta, this.soapAction, responseContext,
this.isResponse, this.notifierInputStreamParams,
this.openspcoopProperties.getAttachmentsProcessingMode(),
true,
this.openspcoopProperties.useSoapMessageReader(), this.openspcoopProperties.getSoapMessageReaderBufferThresholdKb());
if(pr.getParseException()!=null){
this.getPddContext().addObject(org.openspcoop2.core.constants.Costanti.CONTENUTO_RISPOSTA_NON_RICONOSCIUTO_PARSE_EXCEPTION, pr.getParseException());
}
this.responseMsg = pr.getMessage_throwParseException();
}
if(this.responseMsg!=null){
this.responseMsg.updateIncomingMessageContentLength(cis.getByteCount());
}
}finally{
try{
if(cis!=null){
cis.close();
}
}catch(Exception eClose){
// close
}
}
}
}
try{
if(this.responseMsg!=null){
if(this.responseMsg instanceof AbstractOpenSPCoop2Message_soap_impl) {
AbstractOpenSPCoop2Message_soap_impl<?> soap = (AbstractOpenSPCoop2Message_soap_impl<?>) this.responseMsg;
if(!soap.hasContent()) {
this.responseMsg = null;
}
}
else {
this.responseMsg.castAsSoap().getSOAPPart().getEnvelope();
}
}
}
catch(Exception e){
this.responseMsg=null;
// L'errore 'premature end of file' consiste solo nel fatto che una risposta non e' stata ricevuta.
boolean result2XX = (this.codice>=200 && this.codice<=299);
boolean premature = Utilities.existsInnerMessageException(e, "Premature end of file", true) && result2XX;
// Se non ho un premature, ed un errore di lettura in 200, allora devo segnalare l'errore, altrimenti comunque
// il msg ritornato e' null e nel codiceStato vi e' l'errore.
if( premature == false ){
this.eccezioneProcessamento = e;
this.errore = "Errore avvenuto durante il parsing della risposta: " + this.readExceptionMessageFromException(e);
this.logger.error("Errore avvenuto durante il parsing della risposta: " + this.readExceptionMessageFromException(e),e);
if(result2XX){
return false;
}
}
}
}catch(Exception e){
this.eccezioneProcessamento = e;
String msgErrore = this.readExceptionMessageFromException(e);
this.errore = "Errore avvenuto durante il processamento della risposta ("+tipoLetturaRisposta+"): " + msgErrore;
this.logger.error("Errore avvenuto durante il processamento della risposta ("+tipoLetturaRisposta+"): " + msgErrore,e);
return false;
}
// save Msg
if(this.debug)
this.logger.debug("Save messaggio...");
try{
if(this.responseMsg!=null){
// save changes.
// N.B. il countAttachments serve per il msg con attachments come saveMessage!
if(this.responseMsg.castAsSoap().hasAttachments()) {
if(this.responseMsg.castAsSoap().countAttachments()==0){
this.responseMsg.castAsSoap().getSOAPPart();
}
}
}
}catch(Exception e){
this.eccezioneProcessamento = e;
this.errore = "Errore avvenuto durante il salvataggio della risposta: " + this.readExceptionMessageFromException(e);
this.logger.error("Errore avvenuto durante il salvataggio della risposta: " + this.readExceptionMessageFromException(e),e);
return false;
}
}
return true;
}
}