TimerConsegnaContenutiApplicativiSender.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.timers;

import java.sql.Timestamp;
import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.openspcoop2.core.config.GestioneErrore;
import org.openspcoop2.core.config.PortaApplicativa;
import org.openspcoop2.core.config.PortaApplicativaServizioApplicativo;
import org.openspcoop2.core.config.ServizioApplicativo;
import org.openspcoop2.core.id.IDAccordo;
import org.openspcoop2.core.id.IDPortaApplicativa;
import org.openspcoop2.core.id.IDServizio;
import org.openspcoop2.core.id.IDServizioApplicativo;
import org.openspcoop2.core.id.IDSoggetto;
import org.openspcoop2.core.registry.AccordoServizioParteSpecifica;
import org.openspcoop2.core.registry.PortaDominio;
import org.openspcoop2.core.registry.driver.IDAccordoFactory;
import org.openspcoop2.core.registry.driver.IDServizioFactory;
import org.openspcoop2.core.transazioni.IdTransazioneApplicativoServer;
import org.openspcoop2.pdd.config.ConfigurazioneCoda;
import org.openspcoop2.pdd.config.ConfigurazionePdDManager;
import org.openspcoop2.pdd.config.OpenSPCoop2Properties;
import org.openspcoop2.pdd.config.RichiestaApplicativa;
import org.openspcoop2.pdd.core.CostantiPdD;
import org.openspcoop2.pdd.core.GestoreMessaggi;
import org.openspcoop2.pdd.core.MessaggioServizioApplicativo;
import org.openspcoop2.pdd.core.PdDContext;
import org.openspcoop2.pdd.core.behaviour.BehaviourForwardToConfiguration;
import org.openspcoop2.pdd.core.behaviour.StatoFunzionalita;
import org.openspcoop2.pdd.core.behaviour.built_in.multi_deliver.ConfigurazioneGestioneConsegnaNotifiche;
import org.openspcoop2.pdd.core.behaviour.built_in.multi_deliver.GestioneConsegnaNotificheUtils;
import org.openspcoop2.pdd.core.behaviour.built_in.multi_deliver.MultiDeliverUtils;
import org.openspcoop2.pdd.core.state.OpenSPCoopStateDBManager;
import org.openspcoop2.pdd.core.state.OpenSPCoopStateful;
import org.openspcoop2.pdd.logger.MsgDiagnosticiProperties;
import org.openspcoop2.pdd.logger.MsgDiagnostico;
import org.openspcoop2.pdd.logger.OpenSPCoop2Logger;
import org.openspcoop2.pdd.mdb.ConsegnaContenutiApplicativi;
import org.openspcoop2.pdd.mdb.ConsegnaContenutiApplicativiBehaviourMessage;
import org.openspcoop2.pdd.mdb.ConsegnaContenutiApplicativiMessage;
import org.openspcoop2.pdd.mdb.EsitoLib;
import org.openspcoop2.protocol.engine.ProtocolFactoryManager;
import org.openspcoop2.protocol.engine.constants.Costanti;
import org.openspcoop2.protocol.engine.driver.RepositoryBuste;
import org.openspcoop2.protocol.registry.RegistroServiziManager;
import org.openspcoop2.protocol.sdk.Busta;
import org.openspcoop2.protocol.sdk.IProtocolFactory;
import org.openspcoop2.protocol.sdk.state.RequestConfig;
import org.openspcoop2.protocol.sdk.state.RequestInfo;
import org.openspcoop2.utils.UtilsException;
import org.openspcoop2.utils.date.DateManager;
import org.openspcoop2.utils.threads.IRunnableInstance;
import org.openspcoop2.utils.threads.RunnableLogger;

/**
 * Timer che si occupa di re-inoltrare i messaggi in riconsegna
 * 
 *  
 * @author Poli Andrea (apoli@link.it)
 * @author $Author$
 * @version $Rev$, $Date$
 */
public class TimerConsegnaContenutiApplicativiSender implements IRunnableInstance{

	private OpenSPCoop2Properties propertiesReader = null;
	private RegistroServiziManager registroServiziReader;
	private ConfigurazionePdDManager configurazionePdDReader;
	
	private MessaggioServizioApplicativo messaggioServizioApplicativo;
	
	private RunnableLogger log;
	private RunnableLogger logSql;
	private boolean debug;
	
	private String clusterId;
	
	private int minTimeoutResend;
	
	public TimerConsegnaContenutiApplicativiSender(MessaggioServizioApplicativo messaggioServizioApplicativo,
			RegistroServiziManager registroServiziReader,
			ConfigurazionePdDManager configurazionePdDReader,
			String clusterId, ConfigurazioneCoda configurazioneCoda) {
		this.messaggioServizioApplicativo = messaggioServizioApplicativo;
		this.propertiesReader = OpenSPCoop2Properties.getInstance();
		this.registroServiziReader = registroServiziReader;
		this.configurazionePdDReader = configurazionePdDReader;
		this.debug = configurazioneCoda.isDebug();
		this.clusterId = clusterId;
		this.minTimeoutResend = configurazioneCoda.getConsegnaFallita_intervalloMinimoRiconsegna();
	}
	
	@Override
	public String getIdentifier() {
		return "("+this.messaggioServizioApplicativo.getIdTransazione()+"_"+this.messaggioServizioApplicativo.getServizioApplicativo()+"_"+this.messaggioServizioApplicativo.getIdMessaggio()+")";
	}
	
	@Override
	public boolean isContinuousRunning() {
		return false; // deve effettuare solamente una consegna
	}
	
	@Override
	public void initialize(RunnableLogger log) throws UtilsException{
		this.log = log;
		this.logSql = new RunnableLogger(log.getThreadName(),  
				OpenSPCoop2Logger.getLoggerOpenSPCoopConsegnaContenutiSql(this.debug));
	}
	
	
	@Override
	public void check() throws UtilsException {
		
		String idTransazione = this.messaggioServizioApplicativo.getIdTransazione();
		String servizioApplicativo = this.messaggioServizioApplicativo.getServizioApplicativo();
		String idMsgDaInoltrare = this.messaggioServizioApplicativo.getIdMessaggio();
		String identificativo = "redelivery_"+idTransazione+"_"+servizioApplicativo+"_"+idMsgDaInoltrare;
		Date oraRegistrazione = this.messaggioServizioApplicativo.getOraRegistrazione();
		
		MsgDiagnostico msgDiag = MsgDiagnostico.newInstance(TimerConsegnaContenutiApplicativiThread.ID_MODULO);
		PdDContext pddContext = new PdDContext();
		pddContext.addObject(org.openspcoop2.core.constants.Costanti.ID_TRANSAZIONE, idTransazione);
		msgDiag.setPrefixMsgPersonalizzati(MsgDiagnosticiProperties.MSG_DIAG_TIMER_CONSEGNA_CONTENUTI_APPLICATIVI);
		msgDiag.addKeyword(CostantiPdD.KEY_TIPO_MESSAGGIO,Costanti.INBOX);
		msgDiag.addKeyword(CostantiPdD.KEY_ID_MESSAGGIO_DA_INOLTRARE,idMsgDaInoltrare);
		msgDiag.addKeyword(CostantiPdD.KEY_SA_EROGATORE,servizioApplicativo);
		
		OpenSPCoopStateful openspcoopstateGestore = new OpenSPCoopStateful();
		try {

			this.log.debug("Riconsegna in corso del messaggio '"+idMsgDaInoltrare+"' per l'applicativo '"+servizioApplicativo+"' ...");
			
			openspcoopstateGestore.initResource(this.propertiesReader.getIdentitaPortaDefaultWithoutProtocol(),TimerConsegnaContenutiApplicativiThread.ID_MODULO, identificativo,
					OpenSPCoopStateDBManager.consegnePreseInCarico);
				
			GestoreMessaggi messaggioDaInviare = null;
			try{
	
				// FASE 1 PREPARAZIONE
				
				RepositoryBuste repositoryBuste = new RepositoryBuste(openspcoopstateGestore.getStatoRichiesta(), true,null);
				Busta bustaToSend = repositoryBuste.getBustaFromInBox(idMsgDaInoltrare, true);
				msgDiag.addKeywords(bustaToSend, true);
	
				IProtocolFactory<?> protocolFactory = ProtocolFactoryManager.getInstance().getProtocolFactoryByName(bustaToSend.getProtocollo());
	
				// Per ottimizzare le chiamate
				RequestInfo requestInfoForMemoryOptimization = new RequestInfo();
				requestInfoForMemoryOptimization.setProtocolFactory(protocolFactory);
				msgDiag.updateRequestInfo(requestInfoForMemoryOptimization);
				
				messaggioDaInviare = new GestoreMessaggi(openspcoopstateGestore,true,idMsgDaInoltrare,Costanti.INBOX,
						this.logSql.getLog(),msgDiag,null);
				pddContext = messaggioDaInviare.getPdDContext(true); // aggiorno anche l'istanza dentro l'oggetto messaggioDaInviare stesso.
	
				pddContext.addObject(org.openspcoop2.core.constants.Costanti.REQUEST_INFO, requestInfoForMemoryOptimization);
				pddContext.addObject(org.openspcoop2.core.constants.Costanti.REQUEST_INFO_IN_MEMORY, true);
				
				IDSoggetto soggettoFruitore = null;
				if(bustaToSend.getMittente()!=null) {
					soggettoFruitore = new IDSoggetto(bustaToSend.getTipoMittente(),
							bustaToSend.getMittente());
				}
	
				IDServizio servizioBusta = IDServizioFactory.getInstance().getIDServizioFromValues(bustaToSend.getTipoServizio(),
						bustaToSend.getServizio(),
						bustaToSend.getTipoDestinatario(), 
						bustaToSend.getDestinatario(), 
						bustaToSend.getVersioneServizio()); 
				if(servizioBusta!=null) {
					servizioBusta.setAzione(bustaToSend.getAzione());
				}
				
				// Set identità soggetti erogatori usati poi successivamente
				requestInfoForMemoryOptimization.setRequestConfig(new RequestConfig());
				if(servizioBusta!=null && servizioBusta.getSoggettoErogatore()!=null) {
					requestInfoForMemoryOptimization.getRequestConfig().setIdServizio(servizioBusta);
					try{
						org.openspcoop2.core.registry.Soggetto soggettoRegistry = this.registroServiziReader.getSoggetto(servizioBusta.getSoggettoErogatore(), null, null); // passo null volutamente, per accedere alla configurazione
						requestInfoForMemoryOptimization.getRequestConfig().setSoggettoErogatoreRegistry(soggettoRegistry);
					}catch(Exception e){
						this.log.getLog().debug("Recupero soggetto erogatore dal registro fallito: "+e.getMessage(),e);
					}
					try{
						org.openspcoop2.core.config.Soggetto soggettoConfig = this.configurazionePdDReader.getSoggetto(servizioBusta.getSoggettoErogatore(), null); // passo null volutamente, per accedere alla configurazione
						requestInfoForMemoryOptimization.getRequestConfig().setSoggettoErogatoreConfig(soggettoConfig);
					}catch(Exception e){
						this.log.getLog().debug("Recupero soggetto erogatore dal registro fallito: "+e.getMessage(),e);
					}
					try{
						String idPorta = this.configurazionePdDReader.getIdentificativoPorta(servizioBusta.getSoggettoErogatore(), protocolFactory, null); // passo null volutamente, per accedere alla configurazione
						requestInfoForMemoryOptimization.getRequestConfig().setSoggettoErogatoreIdentificativoPorta(idPorta);
					}catch(Exception e){
						this.log.getLog().debug("Recupero dati soggetto erogatore (identificativoPorta) dal registro fallito: "+e.getMessage(),e);
					}
					try{
						if(requestInfoForMemoryOptimization.getRequestConfig().getSoggettoErogatoreRegistry()!=null) {
							if(requestInfoForMemoryOptimization.getRequestConfig().getSoggettoErogatoreRegistry().getPortaDominio()!=null &&
									StringUtils.isNotEmpty(requestInfoForMemoryOptimization.getRequestConfig().getSoggettoErogatoreRegistry().getPortaDominio())) {
								PortaDominio pdd = this.registroServiziReader.getPortaDominio(requestInfoForMemoryOptimization.getRequestConfig().getSoggettoErogatoreRegistry().getPortaDominio(), null, null); // passo null volutamente, per accedere alla configurazione
								requestInfoForMemoryOptimization.getRequestConfig().setSoggettoErogatorePddReaded(true);
								requestInfoForMemoryOptimization.getRequestConfig().setSoggettoErogatorePdd(pdd);
							}
							else {
								requestInfoForMemoryOptimization.getRequestConfig().setSoggettoErogatorePddReaded(true);
							}
						}
					}catch(Exception e){
						this.log.getLog().debug("Recupero dati soggetto erogatore (pdd) dal registro fallito: "+e.getMessage(),e);
					}
				}
	
				String implementazioneDestinatario = this.registroServiziReader.getImplementazionePdD(new IDSoggetto(bustaToSend.getTipoDestinatario(),bustaToSend.getDestinatario()), null, requestInfoForMemoryOptimization);
				requestInfoForMemoryOptimization.getRequestConfig().setSoggettoErogatoreImplementazionePdd(implementazioneDestinatario);
				
				String implementazioneMittente = null;
				if(bustaToSend.getTipoMittente()!=null && bustaToSend.getMittente()!=null) {
					implementazioneMittente = this.registroServiziReader.getImplementazionePdD(new IDSoggetto(bustaToSend.getTipoMittente(),bustaToSend.getMittente()), null, requestInfoForMemoryOptimization);
					requestInfoForMemoryOptimization.getRequestConfig().setSoggettoFruitoreImplementazionePdd(implementazioneMittente);
				}
				
				IDAccordo idAccordo = null;
				AccordoServizioParteSpecifica asps = null;
				try{
					asps = this.registroServiziReader.getAccordoServizioParteSpecifica(servizioBusta, null, false, requestInfoForMemoryOptimization);
					idAccordo = IDAccordoFactory.getInstance().getIDAccordoFromUri(asps.getAccordoServizioParteComune());
					requestInfoForMemoryOptimization.getRequestConfig().setAsps(asps);
				}catch(Exception e){
					msgDiag.logErroreGenerico(e,"ConsegnaAsincrona getAccordoServizioParteSpecifica("+servizioBusta+")");
				}
					
				IDSoggetto identitaPdD = null;
				String dominioRD = null;
				try{
					if(servizioBusta!=null) {
						dominioRD = this.configurazionePdDReader.getIdentificativoPorta(servizioBusta.getSoggettoErogatore(),protocolFactory, requestInfoForMemoryOptimization);
					}
					if(dominioRD==null){
						throw new Exception("Dominio is null");
					}
				}catch(Exception e){
					msgDiag.logErroreGenerico(e,"ConsegnaAsincrona getDominio("+servizioBusta.getSoggettoErogatore()+")");
				}
				if(dominioRD==null){
					identitaPdD = this.propertiesReader.getIdentitaPortaDefault(null, requestInfoForMemoryOptimization);
				}else{
					identitaPdD = new IDSoggetto(bustaToSend.getTipoDestinatario(),
							bustaToSend.getDestinatario(),dominioRD);
				}
				requestInfoForMemoryOptimization.setIdentitaPdD(identitaPdD);
				requestInfoForMemoryOptimization.setIdServizio(servizioBusta);
				requestInfoForMemoryOptimization.setFruitore(soggettoFruitore);
					
				IDPortaApplicativa idPA = this.configurazionePdDReader.getIDPortaApplicativa(this.messaggioServizioApplicativo.getNomePorta(), requestInfoForMemoryOptimization, protocolFactory);
				requestInfoForMemoryOptimization.getRequestConfig().setIdPortaApplicativa(idPA);
				RichiestaApplicativa richiestaApplicativa = new RichiestaApplicativa(soggettoFruitore, identitaPdD, idPA);
				richiestaApplicativa.setServizioApplicativo(servizioApplicativo);
				richiestaApplicativa.setIdentitaServizioApplicativoFruitore(bustaToSend.getServizioApplicativoFruitore());
				richiestaApplicativa.setIdAccordo(idAccordo);
	
				if(servizioBusta!=null) {
					IDServizioApplicativo idSA = new IDServizioApplicativo();
					idSA.setNome(richiestaApplicativa.getServizioApplicativo());
					idSA.setIdSoggettoProprietario(servizioBusta.getSoggettoErogatore());
					try {
						ServizioApplicativo sa = this.configurazionePdDReader.getServizioApplicativo(idSA, requestInfoForMemoryOptimization);
						requestInfoForMemoryOptimization.getRequestConfig().addServizioApplicativoErogatore(sa, idTransazione);
					}catch(Exception e){
						this.log.getLog().debug("Recupero dati soggetto erogatore (pdd) dal registro fallito: "+e.getMessage(),e);
					}
				}
				
				ConsegnaContenutiApplicativiMessage consegnaMSG = new ConsegnaContenutiApplicativiMessage();
				consegnaMSG.setBusta(bustaToSend);
				consegnaMSG.setOneWayVersione11(false);
				consegnaMSG.setStateless(true);
				consegnaMSG.setImplementazionePdDSoggettoMittente(implementazioneMittente);
				consegnaMSG.setImplementazionePdDSoggettoDestinatario(implementazioneDestinatario);
				consegnaMSG.setPddContext(pddContext);
				consegnaMSG.setRichiestaApplicativa(richiestaApplicativa);
				
				BehaviourForwardToConfiguration behaviourForwardToConfiguration = new BehaviourForwardToConfiguration();
				if(this.messaggioServizioApplicativo.isSbustamentoSoap())
					behaviourForwardToConfiguration.setSbustamentoSoap(StatoFunzionalita.ABILITATA);
				else 
					behaviourForwardToConfiguration.setSbustamentoSoap(StatoFunzionalita.DISABILITATA);
				if(this.messaggioServizioApplicativo.isSbustamentoInformazioniProtocollo())
					behaviourForwardToConfiguration.setSbustamentoInformazioniProtocollo(StatoFunzionalita.ABILITATA);
				else 
					behaviourForwardToConfiguration.setSbustamentoInformazioniProtocollo(StatoFunzionalita.DISABILITATA);
				
				ConsegnaContenutiApplicativiBehaviourMessage behaviourMsg = new ConsegnaContenutiApplicativiBehaviourMessage();
				behaviourMsg.setIdMessaggioPreBehaviour(bustaToSend.getRiferimentoMessaggio());
				behaviourMsg.setBehaviourForwardToConfiguration(behaviourForwardToConfiguration);
				IdTransazioneApplicativoServer idTransazioneApplicativoServer = new IdTransazioneApplicativoServer();
				idTransazioneApplicativoServer.setIdTransazione(PdDContext.getValue(org.openspcoop2.core.constants.Costanti.ID_TRANSAZIONE, pddContext));
				idTransazioneApplicativoServer.setServizioApplicativoErogatore(servizioApplicativo);
				PortaApplicativa pa = this.configurazionePdDReader.getPortaApplicativaSafeMethod(idPA, requestInfoForMemoryOptimization);
				requestInfoForMemoryOptimization.getRequestConfig().setPortaApplicativa(pa);
				if(pa!=null && pa.getServizioApplicativoList()!=null) {
					for (PortaApplicativaServizioApplicativo pasa : pa.getServizioApplicativoList()) {
						if(pasa.getNome().equals(servizioApplicativo)) {
							if(pasa.getDatiConnettore()!=null) {
								idTransazioneApplicativoServer.setConnettoreNome(pasa.getDatiConnettore().getNome());
							}
							ConfigurazioneGestioneConsegnaNotifiche configGestioneConsegna = MultiDeliverUtils.read(pasa); 
							GestioneErrore gestioneErroreBehaviour = GestioneConsegnaNotificheUtils.toGestioneErrore(configGestioneConsegna);		
							behaviourMsg.setGestioneErrore(gestioneErroreBehaviour);
							break;
						}
					}
				}
				behaviourMsg.setIdTransazioneApplicativoServer(idTransazioneApplicativoServer);
				behaviourMsg.setOraRegistrazioneTransazioneApplicativoServer(oraRegistrazione);
				consegnaMSG.setBehaviour(behaviourMsg);
				
				
				// FASE 2 SPEDIZIONE
				
				// rilasco connessione gestore
				openspcoopstateGestore.releaseResource();
				
				EsitoLib result = null;
				OpenSPCoopStateful openspcoopstateMessaggio = null;
				try {
					ConsegnaContenutiApplicativi lib = new ConsegnaContenutiApplicativi(OpenSPCoop2Logger.getLoggerOpenSPCoopCore());
					openspcoopstateMessaggio = new OpenSPCoopStateful();
					// viene inizializzata dentro il modulo ConsegnaContenutiApplicativi
					//openspcoopstateMessaggio.initResource(identitaPdD,TimerConsegnaContenutiApplicativiThread.ID_MODULO, bustaToSend.getID());
					openspcoopstateMessaggio.setMessageLib(consegnaMSG);
					result = lib.onMessage(openspcoopstateMessaggio);
				}finally {
					try{
						if(openspcoopstateMessaggio!=null && !openspcoopstateMessaggio.resourceReleased()){
							openspcoopstateMessaggio.releaseResource();
						}
					}catch(Exception e){}
					
					// riprendo connessione gestore
					openspcoopstateGestore.updateResource(identificativo);
					messaggioDaInviare.updateOpenSPCoopState(openspcoopstateGestore);
				}
				
				
				
				if(this.debug)
					this.log.debug("Invocato ConsegnaContenutiApplicativi per ["+bustaToSend.getID()+
							"] con esito: "+result.getStatoInvocazione(),result.getErroreNonGestito());
				if(EsitoLib.ERRORE_NON_GESTITO==result.getStatoInvocazione()){
					// per evitare i loop infinito
					Timestamp tMinTimeoutResend = new Timestamp(DateManager.getTimeMillis()+(this.minTimeoutResend*1000));
					if(result.getDataRispedizioneAggiornata()==null || result.getDataRispedizioneAggiornata().before(tMinTimeoutResend)){
						messaggioDaInviare.aggiornaDataRispedizione(tMinTimeoutResend, servizioApplicativo);
					}
					if(result.isErroreProcessamentoMessaggioAggiornato()==false){
						if(result.getErroreNonGestito()!=null){
							messaggioDaInviare.aggiornaErroreProcessamentoMessaggio("["+TimerConsegnaContenutiApplicativiThread.ID_MODULO+"] "+
									result.getErroreNonGestito().getMessage(), servizioApplicativo);
						}
						else if(result.getMotivazioneErroreNonGestito()!=null){
							messaggioDaInviare.aggiornaErroreProcessamentoMessaggio("["+TimerConsegnaContenutiApplicativiThread.ID_MODULO+"] "+
									result.getMotivazioneErroreNonGestito(), servizioApplicativo);
						}
						else{
							messaggioDaInviare.aggiornaErroreProcessamentoMessaggio("["+TimerConsegnaContenutiApplicativiThread.ID_MODULO+"] "+
									"Invocato ConsegnaContenutiApplicativi per ["+bustaToSend.getID()+
									"] con esito: "+result.getStatoInvocazione(), servizioApplicativo);
						}
					}
				}
				else{
	
					msgDiag.logPersonalizzato("inoltroMessaggio");
					if(this.debug)
						this.log.debug(msgDiag.getMessaggio_replaceKeywords("inoltroMessaggio"));
	
				}
	
			}catch(Exception e){
				msgDiag.logErroreGenerico(e,"InoltroMessaggioInbox("+idMsgDaInoltrare+")");
				this.log.error("ErroreInoltroMessaggioInbox("+idMsgDaInoltrare+"): "+e.getMessage(),e);
				// per evitare i loop infinito
				if(openspcoopstateGestore!=null && !openspcoopstateGestore.resourceReleased()){
					messaggioDaInviare.aggiornaDataRispedizione(new Timestamp(DateManager.getTimeMillis()+(this.minTimeoutResend*1000)), servizioApplicativo);
					messaggioDaInviare.aggiornaErroreProcessamentoMessaggio("["+TimerConsegnaContenutiApplicativiThread.ID_MODULO+"] "+e.getMessage(), servizioApplicativo);
				}
			}finally{
				if(openspcoopstateGestore!=null && !openspcoopstateGestore.resourceReleased()){
					messaggioDaInviare.releaseMessaggioPresaInCosegna(servizioApplicativo, this.clusterId, this.debug, this.logSql); // può già essere stato eliminato
				}
			}
			
			this.log.debug("Riconsegna in corso del messaggio '"+idMsgDaInoltrare+"' per l'applicativo '"+servizioApplicativo+"' terminata");
		}
		catch (Exception e) {
			msgDiag.logErroreGenerico(e,"GestioneRiconsegnaMessaggio");
			this.log.error("Riscontrato errore durante la consegna del messaggio '"+idMsgDaInoltrare+"' per l'applicativo '"+servizioApplicativo+"': "+ e.getMessage(),e);
		}finally{
			if(openspcoopstateGestore!=null)
				openspcoopstateGestore.releaseResource();
		}
	}

}