PreInRequestHandlerGestioneControlloTraffico.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.controllo_traffico.handler;

  21. import org.openspcoop2.core.commons.CoreException;
  22. import org.openspcoop2.core.constants.TipoPdD;
  23. import org.openspcoop2.core.controllo_traffico.ConfigurazioneGenerale;
  24. import org.openspcoop2.core.controllo_traffico.constants.TipoErrore;
  25. import org.openspcoop2.core.eventi.constants.CodiceEventoControlloTraffico;
  26. import org.openspcoop2.core.eventi.constants.TipoEvento;
  27. import org.openspcoop2.message.constants.ServiceBinding;
  28. import org.openspcoop2.pdd.config.ConfigurazionePdDManager;
  29. import org.openspcoop2.pdd.config.OpenSPCoop2Properties;
  30. import org.openspcoop2.pdd.core.controllo_traffico.CostantiControlloTraffico;
  31. import org.openspcoop2.pdd.core.controllo_traffico.GeneratoreMessaggiErrore;
  32. import org.openspcoop2.pdd.core.controllo_traffico.GestoreControlloTraffico;
  33. import org.openspcoop2.pdd.core.handlers.HandlerException;
  34. import org.openspcoop2.pdd.core.handlers.PreInRequestContext;
  35. import org.openspcoop2.pdd.logger.MsgDiagnosticiProperties;
  36. import org.openspcoop2.pdd.logger.MsgDiagnostico;
  37. import org.openspcoop2.pdd.logger.OpenSPCoop2Logger;
  38. import org.openspcoop2.pdd.services.connector.messages.ConnectorInMessage;
  39. import org.openspcoop2.utils.transport.Credential;
  40. import org.slf4j.Logger;

  41. /**    
  42.  * PreInRequestHandler_GestioneControlloTraffico
  43.  *
  44.  * @author Poli Andrea (poli@link.it)
  45.  * @author $Author$
  46.  * @version $Rev$, $Date$
  47.  */
  48. public class PreInRequestHandlerGestioneControlloTraffico {

  49.    
  50.     public void process(PreInRequestContext context) throws HandlerException{
  51.        
  52.         ConfigurazioneGenerale configurazioneGenerale = null;
  53.         GestoreControlloTraffico gestore = null;
  54.         Boolean maxThreadsEnabled = false;
  55.         Boolean maxThreadsWarningOnly = false;
  56.         Long maxThreads = null;
  57.         Integer threshold = null;
  58.         TipoErrore tipoErrore = TipoErrore.FAULT;
  59.         boolean includiDescrizioneErrore = true;
  60.         Logger logControlloTraffico = null;
  61.         ServiceBinding serviceBinding = ServiceBinding.REST;
  62.         try{
  63.        
  64.             // Prelevo la configurazione del Controllo del Traffico
  65.             OpenSPCoop2Properties propertiesReader = OpenSPCoop2Properties.getInstance();
  66.             logControlloTraffico = OpenSPCoop2Logger.getLoggerOpenSPCoopControlloTraffico(propertiesReader.isControlloTrafficoDebug());
  67.             ConfigurazionePdDManager configPdDManager = ConfigurazionePdDManager.getInstance();
  68.             if(configPdDManager==null) {
  69.                 throw new CoreException("configPdDManager is null");
  70.             }
  71.             configurazioneGenerale = configPdDManager.getConfigurazioneControlloTraffico(context!=null ? context.getRequestInfo() : null);
  72.             if(configurazioneGenerale.getControlloTraffico()==null){
  73.                 throw new CoreException("Impostazione maxThreads non corretta?? ControlloTraffico is null");
  74.             }
  75.            
  76.             if(context!=null && context.getTipoPorta()!=null && context.getRequestInfo()!=null) {
  77.                 if(TipoPdD.DELEGATA.equals(context.getTipoPorta())) {
  78.                     if(context.getRequestInfo().getIntegrationServiceBinding()!=null) {
  79.                         serviceBinding = context.getRequestInfo().getIntegrationServiceBinding();
  80.                     }
  81.                 }else {
  82.                     if(context.getRequestInfo().getProtocolServiceBinding()!=null) {
  83.                         serviceBinding = context.getRequestInfo().getProtocolServiceBinding();
  84.                     }
  85.                 }
  86.             }
  87.            
  88.             // Indicazione se il sistema di controllo dei max threads risulta attivo
  89.             maxThreadsEnabled = configurazioneGenerale.getControlloTraffico().isControlloMaxThreadsEnabled();
  90.             maxThreadsWarningOnly = configurazioneGenerale.getControlloTraffico().isControlloMaxThreadsWarningOnly();
  91.            
  92.             if(maxThreadsEnabled!=null && maxThreadsEnabled.booleanValue()) {
  93.            
  94.                 // Numero Massimo di richieste simultanee
  95.                 maxThreads = configurazioneGenerale.getControlloTraffico().getControlloMaxThreadsSoglia();
  96.                 if(maxThreads==null || maxThreads<=0l){
  97.                     throw new CoreException("Impostazione maxThreads non corretta?? ["+maxThreads+"]");
  98.                 }
  99.                
  100.                 // Indicazione se abilitare o meno il controllo del traffico ed eventuale threshold
  101.                 if(configurazioneGenerale.getControlloTraffico()!=null &&
  102.                         configurazioneGenerale.getControlloTraffico().isControlloCongestioneEnabled()){
  103.                     threshold = configurazioneGenerale.getControlloTraffico().getControlloCongestioneThreshold();
  104.                 }
  105.                
  106.                 // Tipo di errore in caso di superamento del max numero di threads
  107.                 if(configurazioneGenerale.getControlloTraffico()!=null) {
  108.                     if(configurazioneGenerale.getControlloTraffico().getControlloMaxThreadsTipoErrore()!=null) {
  109.                         TipoErrore tipoErrorTmp = TipoErrore.toEnumConstant(configurazioneGenerale.getControlloTraffico().getControlloMaxThreadsTipoErrore());
  110.                         if(tipoErrorTmp!=null) {
  111.                             tipoErrore = tipoErrorTmp;
  112.                         }
  113.                     }
  114.                     includiDescrizioneErrore = configurazioneGenerale.getControlloTraffico().isControlloMaxThreadsTipoErroreIncludiDescrizione();
  115.                 }
  116.                
  117.                
  118.                 // Gestore del Controllo del Traffico
  119.                 gestore = GestoreControlloTraffico.getInstance();
  120.                
  121.             }
  122.            
  123.         }catch(Exception e){
  124.             throw new HandlerException("Configurazione non disponibile: "+e.getMessage(), e);
  125.         }
  126.        
  127.        
  128.         MsgDiagnostico msgDiag = this.buildMsgDiagnostico(context);
  129.         try{
  130.            
  131.             // salvataggio informazioni lette
  132.             if(maxThreadsEnabled!=null && maxThreadsEnabled.booleanValue()) {
  133.                 context.getPddContext().addObject(GeneratoreMessaggiErrore.PDD_CONTEXT_MAX_THREADS_THRESHOLD, maxThreads);
  134.                 if(threshold!=null){
  135.                     context.getPddContext().addObject(GeneratoreMessaggiErrore.PDD_CONTEXT_CONTROLLO_TRAFFICO_THRESHOLD, threshold);
  136.                 }
  137.            
  138.                 // registro nuovo in thread in ingresso
  139.                 gestore.addThread(serviceBinding, maxThreads,threshold,maxThreadsWarningOnly,context.getPddContext(),msgDiag,tipoErrore,includiDescrizioneErrore,logControlloTraffico);
  140.            
  141.                 // se il metodo precedente non ha sollevato una eccezione registro nel contesto che è stato registrato il thread
  142.                 context.getPddContext().addObject(CostantiControlloTraffico.PDD_CONTEXT_MAX_REQUEST_THREAD_REGISTRATO, true);  
  143.             }
  144.            
  145.         }catch(Exception e){
  146.            
  147.             // il metodo gestore.addThread((..) ha sollevato una eccezione.
  148.            
  149.             if(maxThreadsWarningOnly!=null &&  maxThreadsWarningOnly.booleanValue()) {
  150.                
  151.                 // Devo comunque impostare questa variabile nel contesto, in modo che l'handler di uscita rimuovi il thread.
  152.                 context.getPddContext().addObject(CostantiControlloTraffico.PDD_CONTEXT_MAX_REQUEST_THREAD_REGISTRATO, true);
  153.                
  154.                 // salvo nel contesto che è stato violato il parametro max-threads e salvo anche l'evento 'LIMITE_RICHIESTE_SIMULTANEE_VIOLAZIONE' con severita' warning only
  155.                 context.getPddContext().addObject(CostantiControlloTraffico.PDD_CONTEXT_MAX_REQUEST_VIOLATED_EVENTO,
  156.                         TipoEvento.CONTROLLO_TRAFFICO_NUMERO_MASSIMO_RICHIESTE_SIMULTANEE.getValue()+"_"+CodiceEventoControlloTraffico.VIOLAZIONE_WARNING_ONLY.getValue());
  157.             }
  158.             else {
  159.                            
  160.                 // salvo nel contesto che è stato violato il parametro max-threads in modo che l'handler di uscita sappia che non deve decrementare il numero di threads,
  161.                 // essendo stato bloccato in questa fase
  162.                 context.getPddContext().addObject(CostantiControlloTraffico.PDD_CONTEXT_MAX_REQUEST_THREAD_REGISTRATO, false);
  163.                
  164.                 // salvo nel contesto che è stato violato il parametro max-threads e salvo anche l'evento 'LIMITE_RICHIESTE_SIMULTANEE_VIOLAZIONE' con violazione effettiva
  165.                 context.getPddContext().addObject(CostantiControlloTraffico.PDD_CONTEXT_MAX_REQUEST_VIOLATED_EVENTO,
  166.                         TipoEvento.CONTROLLO_TRAFFICO_NUMERO_MASSIMO_RICHIESTE_SIMULTANEE.getValue()+"_"+CodiceEventoControlloTraffico.VIOLAZIONE.getValue());
  167.                
  168.                 // Per registrare nel database anche le transazioni che vengono bloccate per maxThreads (default è false)
  169.                 // viene salvato nel contesto le informazioni riguardanti la url invocata e le credenziali
  170.                 // tali informazioni sono utili per aggiungerle come informazioni avanzate nella transazione.
  171.                 ConnectorInMessage req = null;
  172.                 try{
  173.                     req = (ConnectorInMessage) context.getTransportContext().get(PreInRequestContext.SERVLET_REQUEST);
  174.                 }catch(Exception eIgnore){
  175.                     // ignore
  176.                 }
  177.                 if(req!=null){
  178.                     try{
  179.                         String urlInvocazione = req.getURLProtocolContext().getUrlInvocazione_formBased();
  180.                         if(urlInvocazione!=null){
  181.                             if(req.getURLProtocolContext().getFunction()!=null){
  182.                                 urlInvocazione = "["+req.getURLProtocolContext().getFunction()+"] "+urlInvocazione;
  183.                             }
  184.                             context.getPddContext().addObject(CostantiControlloTraffico.PDD_CONTEXT_MAX_REQUEST_VIOLATED_URL_INVOCAZIONE, urlInvocazione);
  185.                         }
  186.                     }catch(Exception eIgnore){
  187.                         // ignore
  188.                     }
  189.                     try{
  190.                         Credential credenziali = req.getCredential();
  191.                         String credenzialiFornite = "";
  192.                         if(credenziali!=null){
  193.                             credenzialiFornite = credenziali.toString();
  194.                             context.getPddContext().addObject(CostantiControlloTraffico.PDD_CONTEXT_MAX_REQUEST_VIOLATED_CREDENZIALI, credenzialiFornite);
  195.                         }
  196.                     }catch(Exception eIgnore){
  197.                         // ignore
  198.                     }
  199.                 }
  200.                
  201.                 // Se l'eccezione è di tipo 'HandlerException' posso risollevarla immediatamente essendo stata generata dal metodo gestore.addThread((..)
  202.                 // Altrimenti la faccio trattatare dal Gestore dei Messaggi di Errore.
  203.                 if(e instanceof HandlerException){
  204.                     throw (HandlerException)e;
  205.                 }
  206.                 else{
  207.                     try{
  208.                         logControlloTraffico.error(e.getMessage(),e);
  209.                     }catch(Exception eLog){
  210.                         context.getLogCore().error(e.getMessage(),e);
  211.                     }
  212.                    
  213.                     GeneratoreMessaggiErrore.addPddContextInfoControlloTrafficoGenericError(context.getPddContext());
  214.                    
  215.                     throw GeneratoreMessaggiErrore.getErroreProcessamento(e,context.getPddContext());
  216.                 }
  217.             }
  218.         }
  219.            
  220.        
  221.        
  222.     }


  223.     // Ritorna un MsgDiagnostico generator
  224.     private MsgDiagnostico buildMsgDiagnostico(PreInRequestContext context) throws HandlerException{
  225.         try{
  226.             String nomePorta = null;
  227.             if(context.getRequestInfo()!=null && context.getRequestInfo().getProtocolContext()!=null) {
  228.                 nomePorta = context.getRequestInfo().getProtocolContext().getInterfaceName();
  229.             }
  230.             MsgDiagnostico msgDiag = MsgDiagnostico.newInstance(context.getTipoPorta(),context.getIdModulo(),nomePorta, context.getRequestInfo());
  231.             msgDiag.setPddContext(context.getPddContext(), context.getProtocolFactory());
  232.             if(org.openspcoop2.core.constants.TipoPdD.DELEGATA.equals(context.getTipoPorta())){
  233.                 msgDiag.setPrefixMsgPersonalizzati(MsgDiagnosticiProperties.MSG_DIAG_RICEZIONE_CONTENUTI_APPLICATIVI);
  234.             }
  235.             else{
  236.                 msgDiag.setPrefixMsgPersonalizzati(MsgDiagnosticiProperties.MSG_DIAG_RICEZIONE_BUSTE);
  237.             }
  238.             return msgDiag;
  239.         }catch(Exception e){
  240.             throw new HandlerException("Generazione Messaggio Diagnostico non riuscita: "+e.getMessage(), e);
  241.         }
  242.     }
  243. }