MTOMProcessor.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;

  21. import org.slf4j.Logger;
  22. import org.openspcoop2.core.config.constants.MTOMProcessorType;
  23. import org.openspcoop2.core.constants.Costanti;
  24. import org.openspcoop2.core.constants.TipoPdD;
  25. import org.openspcoop2.message.OpenSPCoop2Message;
  26. import org.openspcoop2.message.OpenSPCoop2SoapMessage;
  27. import org.openspcoop2.message.constants.MessageRole;
  28. import org.openspcoop2.message.constants.ServiceBinding;
  29. import org.openspcoop2.pdd.config.MTOMProcessorConfig;
  30. import org.openspcoop2.pdd.config.MessageSecurityConfig;
  31. import org.openspcoop2.pdd.core.transazioni.Transaction;
  32. import org.openspcoop2.pdd.core.transazioni.TransactionContext;
  33. import org.openspcoop2.pdd.core.transazioni.TransactionNotExistsException;
  34. import org.openspcoop2.pdd.logger.MsgDiagnosticiProperties;
  35. import org.openspcoop2.pdd.logger.MsgDiagnostico;
  36. import org.openspcoop2.protocol.sdk.constants.RuoloMessaggio;

  37. /**
  38.  * MTOMProcessor
  39.  *
  40.  * @author Andrea Poli (apoli@link.it)
  41.  * @author $Author$
  42.  * @version $Rev$, $Date$
  43.  */
  44. public class MTOMProcessor {

  45.     private MTOMProcessorConfig config;
  46.     private MessageSecurityConfig secConfig;
  47.     private TipoPdD tipoPdD;
  48.     private MsgDiagnostico msgDiag;
  49.     private Logger log;
  50.     private PdDContext pddContext;
  51.     private Transaction transactionNullable;
  52.    
  53.     public MTOMProcessor(MTOMProcessorConfig config, MessageSecurityConfig secConfig, TipoPdD tipoPdD,
  54.             MsgDiagnostico msgDiag, Logger log, PdDContext pddContext){
  55.         this.config = config;
  56.         this.secConfig = secConfig;
  57.         this.tipoPdD = tipoPdD;
  58.         this.msgDiag = msgDiag;
  59.         this.log = log;
  60.         this.pddContext = pddContext;
  61.         if(this.pddContext!=null && this.pddContext.containsKey(Costanti.ID_TRANSAZIONE)) {
  62.             String idTransazione = (String) this.pddContext.getObject(Costanti.ID_TRANSAZIONE);
  63.             try {
  64.                 this.transactionNullable = TransactionContext.getTransaction(idTransazione);
  65.             }catch(TransactionNotExistsException e) {
  66.                 // Puo' succedere nelle comunicazioni stateful
  67.             }
  68.         }
  69.     }
  70.    
  71.    
  72.     public MTOMProcessorType getMTOMProcessorType(){
  73.         if(this.config!=null)
  74.             return this.config.getMtomProcessorType();
  75.         else
  76.             return null;
  77.     }
  78.    
  79.     public void mtomBeforeSecurity(OpenSPCoop2Message msg,RuoloMessaggio tipo) throws Exception{
  80.        
  81.         if(msg==null) {
  82.             return;
  83.         }
  84.         if(!ServiceBinding.SOAP.equals(msg.getServiceBinding())){
  85.             return;
  86.         }
  87.        
  88.         boolean emitDiagDisabled = false;
  89.        
  90.         if(this.isEngineEnabled()){
  91.            
  92.             if(this.isMTOMBeforeSecurity(tipo)){
  93.                
  94.                 if(this.transactionNullable!=null) {
  95.                     switch (tipo) {
  96.                     case RICHIESTA:
  97.                         this.transactionNullable.getTempiElaborazione().startGestioneAttachmentsRichiesta();
  98.                         break;
  99.                     case RISPOSTA:
  100.                         this.transactionNullable.getTempiElaborazione().startGestioneAttachmentsRisposta();
  101.                         break;
  102.                     }
  103.                 }
  104.                 try {
  105.                
  106.                     this.setProcessorTypeIntoDiagnostic(tipo);
  107.                    
  108.                     this.emitDiagnostic(tipo,
  109.                             "mtom.processamentoRichiestaInCorso",
  110.                             "mtom.processamentoRispostaInCorso");
  111.                    
  112.                     try{
  113.                        
  114.                         this.mtomApply(msg.castAsSoap());
  115.                        
  116.                         this.emitDiagnostic(tipo,
  117.                                 "mtom.processamentoRichiestaEffettuato",
  118.                                 "mtom.processamentoRispostaEffettuato");
  119.                        
  120.                     }catch(Exception e){
  121.                        
  122.                         if(MessageRole.REQUEST.equals(msg.getMessageRole())) {
  123.                             this.pddContext.addObject(org.openspcoop2.core.constants.Costanti.ERRORE_ALLEGATI_MESSAGGIO_RICHIESTA, "true");
  124.                         }
  125.                         else {
  126.                             this.pddContext.addObject(org.openspcoop2.core.constants.Costanti.ERRORE_ALLEGATI_MESSAGGIO_RISPOSTA, "true");
  127.                         }
  128.                        
  129.                         this.msgDiag.addKeywordErroreProcessamento(e);
  130.                         this.log.error("[MTOM BeforeSecurity "+tipo.getTipo()+"] "+e.getMessage(),e);
  131.                        
  132.                         this.emitDiagnostic(tipo,
  133.                                 "mtom.processamentoRichiestaInErrore",
  134.                                 "mtom.processamentoRispostaInErrore");
  135.                        
  136.                         throw e;
  137.                     }
  138.                    
  139.                 }
  140.                 finally {
  141.                     if(this.transactionNullable!=null) {
  142.                         switch (tipo) {
  143.                         case RICHIESTA:
  144.                             this.transactionNullable.getTempiElaborazione().endGestioneAttachmentsRichiesta();
  145.                             break;
  146.                         case RISPOSTA:
  147.                             this.transactionNullable.getTempiElaborazione().endGestioneAttachmentsRisposta();
  148.                             break;
  149.                         }
  150.                     }  
  151.                 }
  152.                
  153.             }
  154.             else{
  155.                 emitDiagDisabled = true;
  156.             }
  157.            
  158.         }
  159.         else{
  160.             emitDiagDisabled = true;
  161.         }
  162.        
  163.         if(emitDiagDisabled){
  164.             this.emitDiagnostic(tipo,
  165.                     "mtom.beforeSecurity.processamentoRichiestaDisabilitato",
  166.                     "mtom.beforeSecurity.processamentoRispostaDisabilitato");          
  167.         }
  168.        
  169.     }
  170.    
  171.     public void mtomAfterSecurity(OpenSPCoop2Message msg,RuoloMessaggio tipo) throws Exception{
  172.        
  173.         if(msg==null) {
  174.             return;
  175.         }
  176.         if(!ServiceBinding.SOAP.equals(msg.getServiceBinding())){
  177.             return;
  178.         }
  179.        
  180.         boolean emitDiagDisabled = false;
  181.        
  182.         if(this.isEngineEnabled()){
  183.            
  184.             if(this.isMTOMBeforeSecurity(tipo)==false){
  185.                
  186.                 if(this.transactionNullable!=null) {
  187.                     switch (tipo) {
  188.                     case RICHIESTA:
  189.                         this.transactionNullable.getTempiElaborazione().startGestioneAttachmentsRichiesta();
  190.                         break;
  191.                     case RISPOSTA:
  192.                         this.transactionNullable.getTempiElaborazione().startGestioneAttachmentsRisposta();
  193.                         break;
  194.                     }
  195.                 }
  196.                 try {
  197.                    
  198.                     this.setProcessorTypeIntoDiagnostic(tipo);
  199.                    
  200.                     this.emitDiagnostic(tipo,
  201.                             "mtom.processamentoRichiestaInCorso",
  202.                             "mtom.processamentoRispostaInCorso");
  203.                    
  204.                     try{
  205.                        
  206.                         this.mtomApply(msg.castAsSoap());
  207.                        
  208.                         this.emitDiagnostic(tipo,
  209.                                 "mtom.processamentoRichiestaEffettuato",
  210.                                 "mtom.processamentoRispostaEffettuato");
  211.                        
  212.                     }catch(Exception e){
  213.                        
  214.                         this.msgDiag.addKeywordErroreProcessamento(e);
  215.                         this.log.error("[MTOM AfterSecurity "+tipo.getTipo()+"] "+e.getMessage(),e);
  216.                        
  217.                         this.emitDiagnostic(tipo,
  218.                                 "mtom.processamentoRichiestaInErrore",
  219.                                 "mtom.processamentoRispostaInErrore");
  220.                        
  221.                         throw e;
  222.                     }
  223.                
  224.                 }
  225.                 finally {
  226.                     if(this.transactionNullable!=null) {
  227.                         switch (tipo) {
  228.                         case RICHIESTA:
  229.                             this.transactionNullable.getTempiElaborazione().endGestioneAttachmentsRichiesta();
  230.                             break;
  231.                         case RISPOSTA:
  232.                             this.transactionNullable.getTempiElaborazione().endGestioneAttachmentsRisposta();
  233.                             break;
  234.                         }
  235.                     }  
  236.                 }
  237.             }
  238.             else{
  239.                 emitDiagDisabled = true;
  240.             }
  241.            
  242.         }
  243.         else{
  244.             emitDiagDisabled = true;
  245.         }
  246.        
  247.         if(emitDiagDisabled){
  248.             this.emitDiagnostic(tipo,
  249.                     "mtom.afterSecurity.processamentoRichiestaDisabilitato",
  250.                     "mtom.afterSecurity.processamentoRispostaDisabilitato");            
  251.         }
  252.        
  253.     }
  254.    
  255.    
  256.     /* **** UTILITIES INTERNE ***** */
  257.    
  258.     private void setProcessorTypeIntoDiagnostic(RuoloMessaggio tipo){
  259.         switch (tipo) {
  260.         case RICHIESTA:
  261.             this.msgDiag.addKeyword(CostantiPdD.KEY_TIPO_PROCESSAMENTO_MTOM_RICHIESTA, this.config.getMtomProcessorType().getValue());
  262.             this.pddContext.addObject(CostantiPdD.TIPO_PROCESSAMENTO_MTOM_RICHIESTA, this.config.getMtomProcessorType().getValue());
  263.             break;
  264.         case RISPOSTA:
  265.             this.msgDiag.addKeyword(CostantiPdD.KEY_TIPO_PROCESSAMENTO_MTOM_RISPOSTA, this.config.getMtomProcessorType().getValue());
  266.             this.pddContext.addObject(CostantiPdD.TIPO_PROCESSAMENTO_MTOM_RISPOSTA, this.config.getMtomProcessorType().getValue());
  267.             break;
  268.         }  
  269.     }
  270.    
  271.     private void emitDiagnostic(RuoloMessaggio tipo, String idDiagnosticRichiesta, String idDiagnosticRisposta){
  272.        
  273.         // Il set del prefisso viene fatto poichè il processor viene usato anche in moduli (es. LocalForward) dove non è correttamente impostato
  274.        
  275.         String originalPrefix = this.msgDiag.getPrefixMsgPersonalizzati();
  276.         try{
  277.             switch (this.tipoPdD) {
  278.             case DELEGATA:
  279.                 this.msgDiag.setPrefixMsgPersonalizzati(MsgDiagnosticiProperties.MSG_DIAG_INOLTRO_BUSTE);
  280.                 break;
  281.             case APPLICATIVA:
  282.                 this.msgDiag.setPrefixMsgPersonalizzati(MsgDiagnosticiProperties.MSG_DIAG_RICEZIONE_BUSTE);
  283.                 break;
  284.             default:
  285.                 return; // nessun diagnostico
  286.             }
  287.            
  288.             switch (tipo) {
  289.             case RICHIESTA:
  290.                 this.msgDiag.logPersonalizzato(idDiagnosticRichiesta);
  291.                 break;
  292.             case RISPOSTA:
  293.                 this.msgDiag.logPersonalizzato(idDiagnosticRisposta);
  294.                 break;
  295.             }  
  296.         }finally{
  297.             this.msgDiag.setPrefixMsgPersonalizzati(originalPrefix);
  298.         }
  299.     }
  300.    
  301.     private void mtomApply(OpenSPCoop2SoapMessage msg) throws Exception{
  302.         switch (this.config.getMtomProcessorType()) {
  303.         case PACKAGING:
  304.            
  305.             if(this.config.getInfo()!=null && this.config.getInfo().size()>0){
  306.                 msg.mtomPackaging(this.config.getInfo());
  307.             }
  308.            
  309.             break;
  310.            
  311.         case UNPACKAGING:
  312.            
  313.             msg.mtomUnpackaging();
  314.            
  315.             break;
  316.            
  317.         case VERIFY:
  318.            
  319.             if(this.config.getInfo()!=null && this.config.getInfo().size()>0){
  320.                 msg.mtomVerify(this.config.getInfo());
  321.             }
  322.            
  323.             break;

  324.         default:
  325.             break;
  326.         }
  327.     }
  328.    
  329.     private boolean isMTOMBeforeSecurity(RuoloMessaggio tipoTraccia) throws Exception{
  330.        
  331.         MTOMProcessorType processorType = null;
  332.         if(this.config!=null && this.config.getMtomProcessorType()!=null){
  333.             processorType = this.config.getMtomProcessorType();
  334.         }
  335.         else{
  336.             processorType = MTOMProcessorType.DISABLE;
  337.         }
  338.        
  339.         // NOTA: per default la sicurezza viene sempre applicato prima del processo di packaging
  340.         //      e dopo il processo di unpackaging trattando di fatto l'MTOM come un mero trasporto.
  341.         Boolean applyToMtom = null;
  342.         if(this.secConfig!=null && this.secConfig.getApplyToMtom()!=null){
  343.             applyToMtom = this.secConfig.getApplyToMtom();
  344.         }
  345.        
  346.        
  347.         switch (this.tipoPdD) {
  348.        
  349.         case DELEGATA:
  350.        
  351.             switch (tipoTraccia) {
  352.            
  353.             case RICHIESTA:
  354.                
  355.                 switch (processorType) {
  356.                
  357.                 case DISABLE:
  358.                     // caso che non puo' avvenire grazie al metodo isEngineEnabled
  359.                     throw new Exception("Caso non previsto ["+processorType+"] Delegata.richiesta.disabile");
  360.                    
  361.                 case PACKAGING:
  362.                     if(applyToMtom==null){
  363.                         return false; // (role:sender) primo cifro/firmo e poi applico packaging, in pratica mtom e' un mero trasporto (come se venisse chiamato sul connettore)
  364.                     }
  365.                     else if(applyToMtom){
  366.                         return true; // (role:sender) prima applico il packaging in modo da applicare la sicurezza sul messaggio mtom
  367.                     }else{
  368.                         return false; // (role:sender) prima cifro/firmo e poi applico packaging, in pratica mtom e' un mero trasporto
  369.                     }
  370.                    
  371.                 case UNPACKAGING:
  372.                     if(applyToMtom==null){
  373.                         return false; // (role:sender) primo cifro/firmo e poi applico packaging, in pratica mtom e' un mero trasporto (come se venisse chiamato sul connettore)
  374.                     }
  375.                     else if(applyToMtom){
  376.                         return false; // (role:sender) primo cifro/firmo e poi effettuo unpacking. Scenario senza senso !!!!
  377.                     }else{
  378.                         return true; // (role:sender) prima applico unpackaging poi cifro e firmo, in pratica mtom e' un mero trasporto (Sembra poco indicato al contesto della PdD)
  379.                     }
  380.                    
  381.                 case VERIFY:
  382.                     return true; // (role:sender) prima verifico le references e poi applico la sicurezza (in modo da leggere eventuali elementi che saranno poi cifrati)

  383.                 default:
  384.                     throw new Exception("Caso non previsto Delegata.richiesta.["+processorType+"]");
  385.                 }
  386.                
  387.             case RISPOSTA:
  388.                
  389.                 switch (processorType) {
  390.                
  391.                 case DISABLE:
  392.                     // caso che non puo' avvenire grazie al metodo isEngineEnabled
  393.                     throw new Exception("Caso non previsto ["+processorType+"] Delegata.risposta.disabile");
  394.                    
  395.                 case PACKAGING:
  396.                     if(applyToMtom==null){
  397.                         return true; // (role:receiver) prima applico il packaging e solo dopo verifico firma cifratura, in pratica mtom e' un mero trasporto (come se venisse chiamato sul connettore)
  398.                     }
  399.                     else if(applyToMtom){
  400.                         return true; // (role:receiver) prima applico il packaging e solo dopo verifico firma e cifratura
  401.                     }else{
  402.                         return false;  // (role:receiver) prima verifico firma cifratura, poi applico il packaging
  403.                     }
  404.                    
  405.                 case UNPACKAGING:
  406.                     if(applyToMtom==null){
  407.                         return true; // (role:receiver) primo applico l'unpackaging e solo dopo verifico firma cifratura, in pratica mtom e' un mero trasporto (come se venisse chiamato sul connettore)
  408.                     }
  409.                     else if(applyToMtom){
  410.                         return false; // (role:receiver) prima verifico firma cifratura, poi applico il l'unpackaging
  411.                     }else{
  412.                         return true; // (role:receiver) prima applico l'unpackaging e solo dopo verifico firma e cifratura
  413.                     }
  414.                    
  415.                 case VERIFY:
  416.                     return true; // (role:receiver) prima applico la sicurezza e solo dopo verifico (in modo da leggere eventuali elementi cifrati)

  417.                 default:
  418.                     throw new Exception("Caso non previsto Delegata.risposta.["+processorType+"]");
  419.                 }
  420.                    
  421.             default:
  422.                 throw new Exception("Tipo non gestito ["+tipoTraccia+"] in Delegata.risposta");
  423.             }
  424.            
  425.            
  426.         case APPLICATIVA:
  427.            
  428.             switch (tipoTraccia) {
  429.            
  430.             case RICHIESTA:
  431.                
  432.                 switch (processorType) {
  433.                
  434.                 case DISABLE:
  435.                     // caso che non puo' avvenire grazie al metodo isEngineEnabled
  436.                     throw new Exception("Caso non previsto ["+processorType+"] Applicativa.richiesta.disabile");
  437.                    
  438.                 case PACKAGING:
  439.                     if(applyToMtom==null){
  440.                         return true; // (role:receiver) prima applico il packaging e solo dopo verifico firma cifratura, in pratica mtom e' un mero trasporto (come se venisse chiamato sul connettore)
  441.                     }
  442.                     else if(applyToMtom){
  443.                         return true; // (role:receiver) prima applico il packaging e solo dopo verifico firma e cifratura
  444.                     }else{
  445.                         return false;  // (role:receiver) prima verifico firma cifratura, poi applico il packaging
  446.                     }
  447.                    
  448.                 case UNPACKAGING:
  449.                     if(applyToMtom==null){
  450.                         return true; // (role:receiver) primo applico l'unpackaging e solo dopo verifico firma cifratura, in pratica mtom e' un mero trasporto (come se venisse chiamato sul connettore)
  451.                     }
  452.                     else if(applyToMtom){
  453.                         return false; // (role:receiver) prima verifico firma cifratura, poi applico il l'unpackaging
  454.                     }else{
  455.                         return true; // (role:receiver) prima applico l'unpackaging e solo dopo verifico firma e cifratura
  456.                     }
  457.                    
  458.                 case VERIFY:
  459.                     return true; // (role:receiver) prima applico la sicurezza e solo dopo verifico (in modo da leggere eventuali elementi cifrati)

  460.                 default:
  461.                     throw new Exception("Caso non previsto Applicativa.richiesta.["+processorType+"]");
  462.                 }
  463.                
  464.             case RISPOSTA:
  465.                
  466.                 switch (processorType) {
  467.                
  468.                 case DISABLE:
  469.                     // caso che non puo' avvenire grazie al metodo isEngineEnabled
  470.                     throw new Exception("Caso non previsto ["+processorType+"] Applicativa.risposta.disabile");
  471.                    
  472.                 case PACKAGING:
  473.                     if(applyToMtom==null){
  474.                         return false; // (role:sender) primo cifro/firmo e poi applico packaging, in pratica mtom e' un mero trasporto (come se venisse chiamato sul connettore)
  475.                     }
  476.                     else if(applyToMtom){
  477.                         return true; // (role:sender) prima applico il packaging in modo da applicare la sicurezza sul messaggio mtom
  478.                     }else{
  479.                         return false; // (role:sender) prima cifro/firmo e poi applico packaging, in pratica mtom e' un mero trasporto
  480.                     }
  481.                    
  482.                 case UNPACKAGING:
  483.                     if(applyToMtom==null){
  484.                         return false; // (role:sender) primo cifro/firmo e poi applico packaging, in pratica mtom e' un mero trasporto (come se venisse chiamato sul connettore)
  485.                     }
  486.                     else if(applyToMtom){
  487.                         return false; // (role:sender) primo cifro/firmo e poi effettuo unpacking. Scenario senza senso !!!!
  488.                     }else{
  489.                         return true; // (role:sender) prima applico unpackaging poi cifro e firmo, in pratica mtom e' un mero trasporto (Sembra poco indicato al contesto della PdD)
  490.                     }
  491.                    
  492.                 case VERIFY:
  493.                     return true; // (role:sender) prima verifico le references e poi applico la sicurezza (in modo da leggere eventuali elementi che saranno poi cifrati)

  494.                 default:
  495.                     throw new Exception("Caso non previsto Applicativa.risposta.["+processorType+"]");
  496.                 }
  497.                    
  498.             default:
  499.                 throw new Exception("Tipo non gestito ["+tipoTraccia+"] in Applicativa.risposta");
  500.             }
  501.            
  502.         case INTEGRATION_MANAGER:
  503.         case ROUTER:
  504.         default:
  505.                 throw new Exception("Ruolo ["+this.tipoPdD+"] non gestito");
  506.            
  507.         }
  508.        
  509.        
  510.     }
  511.    
  512.     private boolean isEngineEnabled(){
  513.         if(!TipoPdD.DELEGATA.equals(this.tipoPdD) && !TipoPdD.APPLICATIVA.equals(this.tipoPdD)){
  514.             return false;
  515.         }
  516.         if(this.config!=null && this.config.getMtomProcessorType()!=null && !MTOMProcessorType.DISABLE.equals(this.config.getMtomProcessorType())){
  517.             return true;
  518.         }
  519.         return false;
  520.     }
  521. }