ConsegnaInOrdine.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.protocol.engine.driver;


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import org.slf4j.Logger;
import org.openspcoop2.protocol.engine.Configurazione;
import org.openspcoop2.protocol.engine.constants.Costanti;
import org.openspcoop2.protocol.sdk.Busta;
import org.openspcoop2.protocol.sdk.Eccezione;
import org.openspcoop2.protocol.sdk.IProtocolFactory;
import org.openspcoop2.protocol.sdk.ProtocolException;
import org.openspcoop2.protocol.sdk.constants.ErroriCooperazione;
import org.openspcoop2.protocol.sdk.state.IState;
import org.openspcoop2.protocol.sdk.state.StateMessage;
import org.openspcoop2.protocol.sdk.state.StatefulMessage;
import org.openspcoop2.utils.LoggerWrapperFactory;
import org.openspcoop2.utils.Utilities;
import org.openspcoop2.utils.date.DateManager;
import org.openspcoop2.utils.jdbc.JDBCUtilities;
import org.openspcoop2.utils.sql.ISQLQueryObject;
import org.openspcoop2.utils.sql.SQLObjectFactory;

/**
 * Sono inclusi i metodi per la gestione della consegna in ordine (sequenza).
 *
 *
 * @author Poli Andrea (apoli@link.it)
 * @author Tronci Fabio (tronci@link.it)
 * @author $Author$
 * @version $Rev$, $Date$
 */

public class ConsegnaInOrdine  {



	/** Logger utilizzato per debug. */
	private Logger log = null;

	/** Se IState e' un'istanza di StatefulMessage possiede una Connessione SQL in autoCommit mode su cui effettuare query 
	 *  Altrimenti, e' un'istanza di StatelessMessage e nn necessita di connessioni */
	private IState state;
	
	private IProtocolFactory<?> protocolFactory;

	

	/* ********  C O S T R U T T O R E  ******** */

	/**
	 * Costruttore. 
	 *
	 * @param state Oggetto che rappresenta lo stato di una busta
	 * 
	 */
	public ConsegnaInOrdine(IState state,IProtocolFactory<?> protocolFactory){
		this(state,Configurazione.getLibraryLog(),protocolFactory);
	}
	/**
	 * Costruttore. 
	 *
	 * @param state Oggetto che rappresenta lo stato di una busta
	 * 
	 */
	public ConsegnaInOrdine(IState state, Logger alog,IProtocolFactory<?> protocolFactory){
		this.state = state;
		if(alog!=null){
			this.log = alog;
		}else{
			this.log = LoggerWrapperFactory.getLogger(ConsegnaInOrdine.class.getName());
		}
		this.protocolFactory = protocolFactory;
	}
	
	/**
	 * Aggiorna lo stato della Busta
	 * Utilizzato per reimpostare la connessione ??
	 * 
	 */
	public void updateState(IState state){
		this.state = state;
	}

	private static final String NOT_USED = ""; // azione null


	/**
	 * Ritorna l'identificativo di una collaborazione identificata da mittente/destinatario/servizio/azione.
	 * In caso la collaborazione non esiste, viene creata.
	 *  
	 * @param busta Busta su cui impostare la sequenza
	 * 
	 */
	public void setNextSequenza_daInviare(Busta busta)throws ProtocolException{

		if(this.state instanceof StateMessage) {
			
			StateMessage stateful = (StateMessage)this.state;
			Connection connectionDB = stateful.getConnectionDB();

			PreparedStatement pstmt = null;
			ResultSet rs = null;
			PreparedStatement pstmtInsert = null;
			String idCollaborazione = null;
			long sequenza = -1;
			try{	

				StringBuilder query = new StringBuilder();
				query.append("SELECT ID_COLLABORAZIONE,PROSSIMA_SEQUENZA FROM ");
				query.append(Costanti.SEQUENZA_DA_INVIARE);
				query.append(" WHERE MITTENTE=? AND TIPO_MITTENTE=? AND DESTINATARIO=? AND TIPO_DESTINATARIO=? AND SERVIZIO=? AND TIPO_SERVIZIO=? AND AZIONE=?");
				pstmt = connectionDB.prepareStatement(query.toString());
				pstmt.setString(1,busta.getMittente());
				pstmt.setString(2,busta.getTipoMittente());
				pstmt.setString(3,busta.getDestinatario());
				pstmt.setString(4,busta.getTipoDestinatario());
				pstmt.setString(5,busta.getServizio());
				pstmt.setString(6,busta.getTipoServizio());
				if(busta.getAzione()!=null)
					pstmt.setString(7,busta.getAzione());
				else
					pstmt.setString(7,NOT_USED);

				// Esecuzione comando SQL
				rs = pstmt.executeQuery();		
				if(rs == null) {
					pstmt.close();
					throw new ProtocolException("RS NULL?");
				}		
				if(rs.next()){
					// Collaborazione preesistente
					idCollaborazione = rs.getString("ID_COLLABORAZIONE");
					sequenza=rs.getLong("PROSSIMA_SEQUENZA");

					// devo aggiornare il next sequence

					long next_sequenza = sequenza + 1;
					if(next_sequenza > Costanti.MAX_VALUE_SEQUENZA_COUNTER){
						next_sequenza = 1;
					} 

					rs.close();
					pstmt.close();

					// aggiornamento sequenza
					StringBuilder queryInsert = new StringBuilder();
					queryInsert.append("UPDATE ");
					queryInsert.append(Costanti.SEQUENZA_DA_INVIARE);
					queryInsert.append(" SET PROSSIMA_SEQUENZA = ? WHERE MITTENTE=? AND TIPO_MITTENTE=? AND DESTINATARIO=? AND TIPO_DESTINATARIO=? AND SERVIZIO=? AND TIPO_SERVIZIO=? AND AZIONE=?");
					pstmtInsert = connectionDB.prepareStatement(queryInsert.toString());
					int index = 1;
					pstmtInsert.setLong(index++,next_sequenza);
					pstmtInsert.setString(index++,busta.getMittente());
					pstmtInsert.setString(index++,busta.getTipoMittente());
					pstmtInsert.setString(index++,busta.getDestinatario());
					pstmtInsert.setString(index++,busta.getTipoDestinatario());
					pstmtInsert.setString(index++,busta.getServizio());
					pstmtInsert.setString(index++,busta.getTipoServizio());
					if(busta.getAzione()!=null){
						pstmtInsert.setString(index++,busta.getAzione());
					}else{
						pstmtInsert.setString(index++,NOT_USED);
					}

					stateful.getPreparedStatement().put("UPDATE setNextSequenza_daInviare"+busta.getCollaborazione(), pstmtInsert);


				}else{

					// Nuova collaborazione
					idCollaborazione = busta.getID();
					sequenza=1;

					rs.close();
					pstmt.close();				

					StringBuilder queryInsert = new StringBuilder();
					queryInsert.append("INSERT INTO  ");
					queryInsert.append(Costanti.SEQUENZA_DA_INVIARE);
					queryInsert.append(" VALUES ( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? )");
					pstmtInsert = connectionDB.prepareStatement(queryInsert.toString());
					int index = 1;
					pstmtInsert.setString(index++,busta.getMittente());
					pstmtInsert.setString(index++,busta.getTipoMittente());
					pstmtInsert.setString(index++,busta.getDestinatario());
					pstmtInsert.setString(index++,busta.getTipoDestinatario());
					pstmtInsert.setString(index++,busta.getServizio());
					pstmtInsert.setString(index++,busta.getTipoServizio());
					if(busta.getAzione()!=null){
						pstmtInsert.setString(index++,busta.getAzione());
					}else{
						pstmtInsert.setString(index++,NOT_USED);
					}
					pstmtInsert.setLong(index++,2); // next sequence is 2
					pstmtInsert.setString(index++,busta.getID()); // idCollaborazione is idRequest
					pstmtInsert.setTimestamp(index++, DateManager.getTimestamp());

					stateful.getPreparedStatement().put("INSERT setNextSequenza_daInviare"+busta.getCollaborazione(), pstmtInsert);


				}

				// impostazione busta
				busta.setSequenza(sequenza);
				busta.setCollaborazione(idCollaborazione);


			} catch(Exception e) {
				String errorMsg = "ConsegnaInOrdine, Errore durante la setNextSequenza_daInviare: "+e.getMessage();		
				try{
					if( rs != null )
						rs.close();
				} catch(Exception er) {
					// close
				}
				try{
					if( pstmt != null )
						pstmt.close();
				} catch(Exception er) {
					// close
				}
				try{
					if( pstmtInsert != null )
						pstmtInsert.close();
				} catch(Exception er) {
					// close
				}
				this.log.error(errorMsg,e);
				throw new ProtocolException(errorMsg,e);
			}

		}else{
			throw new ProtocolException("Metodo invocato con IState non valido");
		}
	}










	/**
	 * Ritorna true se la busta contiene una sequenza/collaborazione valida
	 *  
	 * @param busta Busta su cui effettuare la validazione
	 * @return una eccezione se la busta contiene una sequenza/collaborazione non valida
	 * 
	 */
	public Eccezione validazioneDatiConsegnaInOrdine(Busta busta, IProtocolFactory<?> protocolFactory)throws ProtocolException{
		if(this.state instanceof StateMessage) {
			
			StateMessage stateful = (StateMessage)this.state;
			Connection connectionDB = stateful.getConnectionDB();
			
			// Check stateless
			boolean connessioneValida = false;
			try{
				if(stateful instanceof StatefulMessage)
					connessioneValida = true;
				else
					connessioneValida = ( (connectionDB!=null) && (!connectionDB.isClosed()) );
			}catch(Exception e){
				// ignore
			}
					
			if(connessioneValida && busta.getSequenza()!=-1 && busta.getCollaborazione()!=null){

				PreparedStatement pstmt = null;
				ResultSet rs = null;
				try{	

					if(busta.getID().equals(busta.getCollaborazione())){
						// busta Capostipite
						if(busta.getSequenza()!=1){
							this.log.debug("Riscontrato numero di sequenza diverso da 1, in una busta capostipite di una sequenza");
							return Eccezione.getEccezioneValidazione(ErroriCooperazione.CONSEGNA_IN_ORDINE_FUORI_SEQUENZA.getErroreCooperazione(), protocolFactory); 
						}
					}
					else{
						// busta non capostipite
						StringBuilder query = new StringBuilder();
						query.append("SELECT * FROM ");
						query.append(Costanti.SEQUENZA_DA_RICEVERE);
						query.append(" WHERE ID_COLLABORAZIONE=?");
						pstmt = connectionDB.prepareStatement(query.toString());
						pstmt.setString(1,busta.getCollaborazione());

						//	Esecuzione comando SQL
						rs = pstmt.executeQuery();		
						if(rs == null) {
							throw new ProtocolException("RS NULL?");
						}	
						if(rs.next()){
							String tipoMittente = rs.getString("TIPO_MITTENTE");
							String mittente = rs.getString("MITTENTE");
							String tipoDestinatario = rs.getString("TIPO_DESTINATARIO");
							String destinatario = rs.getString("DESTINATARIO");
							String tipoServizio = rs.getString("TIPO_SERVIZIO");
							String servizio = rs.getString("SERVIZIO");
							String azione = rs.getString("AZIONE");

							//	Check di coerenza
							if( tipoMittente.equals(busta.getTipoMittente())==false){
								this.log.debug("Il tipo di mittente non rispetta quello atteso nella gestione della collaborazione con consegna in ordine.");
								return Eccezione.getEccezioneValidazione(ErroriCooperazione.CONSEGNA_IN_ORDINE_TIPO_MITTENTE_NON_VALIDO.getErroreCooperazione(), protocolFactory);
							}
							if( mittente.equals(busta.getMittente())==false){
								this.log.debug("Il mittente non rispetta quello atteso nella gestione della collaborazione con consegna in ordine.");
								return Eccezione.getEccezioneValidazione(ErroriCooperazione.CONSEGNA_IN_ORDINE_MITTENTE_NON_VALIDO.getErroreCooperazione(), protocolFactory);
							}
							if( tipoDestinatario.equals(busta.getTipoDestinatario())==false){
								this.log.debug("Il tipo di destinatario non rispetta quello atteso nella gestione della collaborazione con consegna in ordine.");
								return Eccezione.getEccezioneValidazione(ErroriCooperazione.CONSEGNA_IN_ORDINE_TIPO_DESTINATARIO_NON_VALIDO.getErroreCooperazione(), protocolFactory);
							}
							if( destinatario.equals(busta.getDestinatario())==false){
								this.log.debug("Il destinatario non rispetta quello atteso nella gestione della collaborazione con consegna in ordine.");
								return Eccezione.getEccezioneValidazione(ErroriCooperazione.CONSEGNA_IN_ORDINE_DESTINATARIO_NON_VALIDO.getErroreCooperazione(),protocolFactory);
							}
							if( tipoServizio.equals(busta.getTipoServizio())==false){
								this.log.debug("Il tipo di servizio non rispetta quello atteso nella gestione della collaborazione con consegna in ordine.");
								return Eccezione.getEccezioneValidazione(ErroriCooperazione.CONSEGNA_IN_ORDINE_TIPO_SERVIZIO_NON_VALIDO.getErroreCooperazione(), protocolFactory);
							}
							if( servizio.equals(busta.getServizio())==false){
								this.log.debug("Il servizio non rispetta quello atteso nella gestione della collaborazione con consegna in ordine.");
								return Eccezione.getEccezioneValidazione(ErroriCooperazione.CONSEGNA_IN_ORDINE_SERVIZIO_NON_VALIDO.getErroreCooperazione(), protocolFactory);
							}
							if( (azione==null && busta.getAzione()!=null) ||
									(azione!=null && azione.equals(busta.getAzione())==false) ){
								this.log.debug("L'azione non rispetta quello attesa nella gestione della collaborazione con consegna in ordine.");
								return Eccezione.getEccezioneValidazione(ErroriCooperazione.CONSEGNA_IN_ORDINE_AZIONE_NON_VALIDA.getErroreCooperazione(), protocolFactory);
							}
						}else{
							this.log.debug("Busta non capostipite che richiede funzionalità di consegna in ordine presenta una collaborazione non registrata per le funzioni di consegna in ordine");
							return Eccezione.getEccezioneValidazione(ErroriCooperazione.CONSEGNA_IN_ORDINE_COLLABORAZIONE_IN_BUSTA_NON_CAPOSTIPITE_SCONOSCIUTA.getErroreCooperazione(), protocolFactory);
						}

					}

				} catch(Exception e) {
					this.log.error("ERROR validazioneDatiConsegnaInOrdine ["+e.getMessage()+"]",e);
					throw new ProtocolException("ERROR validazioneDatiConsegnaInOrdine ["+e.getMessage()+"]",e);
				}
				finally {
					try{
						if( rs != null )
							rs.close();
					} catch(Exception er) {
						// close
					}
					try{
						if( pstmt != null )
							pstmt.close();
					} catch(Exception er) {
						// close
					}
				}

			}

			return null;
		}else{
			throw new ProtocolException("Metodo invocato con IState non valido");
		}
	}
	
	
	
	
	/**
	 * Ritorna true se la consegna deve essere effettuata, false altrimenti
	 *  
	 * @param busta Busta su cui gestire la sequenza
	 * @return true se la consegna deve essere effettuata, false altrimenti
	 * 
	 */
	public boolean isConsegnaInOrdine(Busta busta)throws ProtocolException{
		return isConsegnaInOrdine(busta, 60l, 100);
	}
	/**
	 * Ritorna true se la consegna deve essere effettuata, false altrimenti
	 *  
	 * @param busta Busta su cui gestire la sequenza
	 * @param attesaAttiva AttesaAttiva per la gestione del livello di serializable
	 * @param checkInterval Intervallo di check per la gestione  del livello di serializable
	 * @return true se la consegna deve essere effettuata, false altrimenti
	 * 
	 */
	private long sequenzaAttesa = -1;
	public long getSequenzaAttesa() {
		return this.sequenzaAttesa;
	}
	public boolean isConsegnaInOrdine(Busta busta, long attesaAttiva, int checkInterval) throws ProtocolException{

		if(this.state instanceof StateMessage) {
			
			StateMessage stateMsg = (StateMessage)this.state;
			Connection connectionDB = stateMsg.getConnectionDB();

			//controllo che non abbia gia' gestito un numero di sequenza per la busta
			RepositoryBuste repository = new RepositoryBuste(stateMsg, this.log, true, this.protocolFactory);
			long sequenzaGestita = repository.getSequenzaFromInBox(busta.getID());
			if(sequenzaGestita == -2){
				return true; // posso consegnare, sicuramente l'ho gia' consegnata prima.
			}


			/*
	  	Viene realizzato con livello di isolamento SERIALIZABLE, per essere sicuri
	  	di creare sequenza crescenti.
			 */
			// setAutoCommit e livello Isolamento
			int oldTransactionIsolation = -1;
			try{
				oldTransactionIsolation = connectionDB.getTransactionIsolation();
				connectionDB.setAutoCommit(false);
				JDBCUtilities.setTransactionIsolationSerializable(Configurazione.getSqlQueryObjectType(), connectionDB);
			} catch(Exception er) {
				String errorMsg = "ConsegnaInOrdine, errore durante isConsegnaInOrdine(setIsolation): "+er.getMessage();		
				this.log.error(errorMsg,er);
				throw new ProtocolException(errorMsg,er);
			}


			boolean nextSequenceOK = false;
			boolean bustaInOrdine = false;

			long scadenzaWhile = DateManager.getTimeMillis() + attesaAttiva;

			while(nextSequenceOK==false && DateManager.getTimeMillis() < scadenzaWhile){

				PreparedStatement pstmt = null;
				ResultSet rs = null;
				try{	

					if(busta.getID().equals(busta.getCollaborazione())){
						// busta Capostipite

						bustaInOrdine = true;

					}else{
						// busta da controllare

						StringBuilder query = new StringBuilder();
						if(Configurazione.getSqlQueryObjectType()!=null){
							ISQLQueryObject sqlQueryObject = SQLObjectFactory.createSQLQueryObject(Configurazione.getSqlQueryObjectType());
							sqlQueryObject.addSelectField("SEQUENZA_ATTESA");
							sqlQueryObject.addFromTable(Costanti.SEQUENZA_DA_RICEVERE);
							sqlQueryObject.addWhereCondition("ID_COLLABORAZIONE=?");
							sqlQueryObject.setANDLogicOperator(true);
							sqlQueryObject.setSelectForUpdate(true);
							query.append(sqlQueryObject.createSQLQuery());
						}
						else{
							query.append("SELECT SEQUENZA_ATTESA FROM ");
							query.append(Costanti.SEQUENZA_DA_RICEVERE);
							query.append(" WHERE ID_COLLABORAZIONE=? FOR UPDATE");
						}
						pstmt =  connectionDB.prepareStatement(query.toString());
						pstmt.setString(1,busta.getCollaborazione());

						//	Esecuzione comando SQL
						rs = pstmt.executeQuery();		
						if(rs == null) {
							pstmt.close();
							throw new ProtocolException("RS NULL?");
						}	
						if(rs.next()==false){
							throw new Exception("Informazioni su consegna in ordine non trovate, durante il check di una busta non capostipite");
						}

						this.sequenzaAttesa = rs.getLong("SEQUENZA_ATTESA");
						rs.close();
						pstmt.close();

						// se non e' la sequenza attesa, vado in congelamento
						if(this.sequenzaAttesa!=busta.getSequenza()){
							bustaInOrdine = false;
						}else{
							bustaInOrdine = true;
						}
					}

					// Chiusura Transazione
					connectionDB.commit();

					// ID Costruito
					nextSequenceOK = true;

				} catch(Exception e) {
					this.log.error("ERROR isConsegnaInOrdine ["+e.getMessage()+"]");
					try{
						if( rs != null )
							rs.close();
					} catch(Exception er) {
						// close
					}
					try{
						if( pstmt != null )
							pstmt.close();
					} catch(Exception er) {
						// close
					}
					try{
						connectionDB.rollback();
					} catch(Exception er) {
						// ignore
					}
				}

				if(nextSequenceOK == false){
					// Per aiutare ad evitare conflitti
					try{
						Utilities.sleep(ProtocolRandomUtilities.getRandom().nextInt(checkInterval)); // random da 0ms a checkIntervalms
					}catch(Exception eRandom){
						// ignore
					}
				}
			}

			// Ripristino Transazione
			try{
				connectionDB.setTransactionIsolation(oldTransactionIsolation);
				connectionDB.setAutoCommit(true);
			} catch(Exception er) {
				String errorMsg = "ConsegnaInOrdine, Errore durante la isConsegnaInOrdine(ripristinoIsolation): "+er.getMessage();		
				this.log.error(errorMsg,er);
				throw new ProtocolException(errorMsg,er);
			}


			if(nextSequenceOK==false){
				throw new ProtocolException("Controllo sequenza per gestione funzionalita' di consegna in ordine non riuscita");
			}

			return bustaInOrdine;
		}else{
			throw new ProtocolException("Metodo invocato con IState non valido");
		}
	}
	
	
	
	





	/**
	 * Aggiorna la sequenza
	 * 
	 * @param busta Busta su cui gestire la sequenza
	 * 
	 */
	public void setNextSequenza_daRicevere(Busta busta)throws ProtocolException{
		if(this.state instanceof StateMessage) {
			
			StateMessage stateful = (StateMessage)this.state;
			Connection connectionDB = stateful.getConnectionDB();
			// controllo che non abbia gia' gestito il numero di sequenza per la busta
			RepositoryBuste repository = new RepositoryBuste(stateful, this.log, true, this.protocolFactory);
			long sequenzaGestita = repository.getSequenzaFromInBox(busta.getID());
			if(sequenzaGestita == -2){
				return; // gia gestita
			}

			PreparedStatement pstmtInsert = null;
			try{	

				if(busta.getID().equals(busta.getCollaborazione())){
					// busta Capostipite

					StringBuilder queryInsert = new StringBuilder();
					queryInsert.append("INSERT INTO  ");
					queryInsert.append(Costanti.SEQUENZA_DA_RICEVERE);
					queryInsert.append(" VALUES ( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? )");
					pstmtInsert =  connectionDB.prepareStatement(queryInsert.toString());
					int index = 1;
					pstmtInsert.setString(index++,busta.getCollaborazione());
					pstmtInsert.setLong(index++,(busta.getSequenza()+1)); //prossima sequenza attesa
					pstmtInsert.setString(index++,busta.getMittente());
					pstmtInsert.setString(index++,busta.getTipoMittente());
					pstmtInsert.setString(index++,busta.getDestinatario());
					pstmtInsert.setString(index++,busta.getTipoDestinatario());
					pstmtInsert.setString(index++,busta.getServizio());
					pstmtInsert.setString(index++,busta.getTipoServizio());
					pstmtInsert.setString(index++,busta.getAzione());
					pstmtInsert.setTimestamp(index++, DateManager.getTimestamp());

				}else{
					// aggiorno prossima sequenza attesa
					StringBuilder queryInsert = new StringBuilder();
					queryInsert.append("UPDATE ");
					queryInsert.append(Costanti.SEQUENZA_DA_RICEVERE);
					queryInsert.append(" SET SEQUENZA_ATTESA = ? WHERE ID_COLLABORAZIONE=? ");
					pstmtInsert =  connectionDB.prepareStatement(queryInsert.toString());

					long next_sequenza = busta.getSequenza() + 1;
					if(next_sequenza > Costanti.MAX_VALUE_SEQUENZA_COUNTER){
						next_sequenza = 1;
					} 
					pstmtInsert.setLong(1,next_sequenza);
					pstmtInsert.setString(2,busta.getCollaborazione());
				}
				stateful.getPreparedStatement().put("INSERT setNextSequenza_daRicevere"+busta.getCollaborazione(), pstmtInsert);

				// imposto gestione della sequenza per la busta effettuata
				repository.aggiornaSequenzaIntoInBox(busta.getID(),-2);

			} catch(Exception e) {
				String errorMsg = "ConsegnaInOrdine, Errore durante la setNextSequenza_daRicevere: "+e.getMessage();		
				try{
					if( pstmtInsert != null )
						pstmtInsert.close();
				} catch(Exception er) {
					// close
				}
				this.log.error(errorMsg,e);
				throw new ProtocolException(errorMsg,e);
			}


		}else{
			throw new ProtocolException("Metodo invocato con IState non valido");
		}
	}

}