PolicyFiltroApplicativoUtilities.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.controllo_traffico.policy;
import org.openspcoop2.core.constants.Costanti;
import org.openspcoop2.core.controllo_traffico.beans.DatiTransazione;
import org.openspcoop2.core.controllo_traffico.constants.TipoFiltroApplicativo;
import org.openspcoop2.message.MessageUtils;
import org.openspcoop2.message.OpenSPCoop2Message;
import org.openspcoop2.message.constants.MessageType;
import org.openspcoop2.message.soap.SoapUtils;
import org.openspcoop2.pdd.config.OpenSPCoop2Properties;
import org.openspcoop2.pdd.config.dynamic.PddPluginLoader;
import org.openspcoop2.pdd.core.PdDContext;
import org.openspcoop2.pdd.core.connettori.InfoConnettoreIngresso;
import org.openspcoop2.pdd.core.controllo_traffico.plugins.Dati;
import org.openspcoop2.pdd.core.controllo_traffico.plugins.IRateLimiting;
import org.openspcoop2.pdd.core.handlers.InRequestProtocolContext;
import org.openspcoop2.protocol.sdk.state.URLProtocolContext;
import org.openspcoop2.utils.regexp.RegExpNotFoundException;
import org.openspcoop2.utils.regexp.RegularExpressionEngine;
import org.openspcoop2.utils.xml.AbstractXPathExpressionEngine;
import org.openspcoop2.utils.xml2json.JsonXmlPathExpressionEngine;
import org.slf4j.Logger;
import org.w3c.dom.Element;
/**
* PolicyFiltroApplicativoUtilities
*
* @author Poli Andrea (poli@link.it)
* @author $Author$
* @version $Rev$, $Date$
*/
public class PolicyFiltroApplicativoUtilities {
public static String getValore(Logger log,String tipo, String nome, InRequestProtocolContext context,
DatiTransazione datiTransazione, boolean forFilter) throws Exception{
if(context==null) {
throw new Exception("InRequestProtocolContext is null");
}
OpenSPCoop2Message message = context.getMessaggio();
URLProtocolContext urlProtocolContext = context.getConnettore().getUrlProtocolContext();
String soapAction = context.getConnettore().getSoapAction();
PdDContext pddContext = null;
if(context!=null && context.getPddContext()!=null) {
pddContext = context.getPddContext();
}
InfoConnettoreIngresso connettore = context.getConnettore();
return getValore(log, tipo, nome,
datiTransazione, forFilter,
message, urlProtocolContext, soapAction, pddContext,
connettore);
}
public static String getValore(Logger log,String tipo, String nome,
DatiTransazione datiTransazione, boolean forFilter,
OpenSPCoop2Message message, URLProtocolContext urlProtocolContext, String soapActionParam, PdDContext pddContext,
InfoConnettoreIngresso connettore) throws Exception{
TipoFiltroApplicativo tipoFiltro = TipoFiltroApplicativo.toEnumConstant(tipo);
switch (tipoFiltro) {
case CONTENT_BASED:
String idTransazione = null;
if(pddContext!=null) {
idTransazione = (String)pddContext.getObject(org.openspcoop2.core.constants.Costanti.ID_TRANSAZIONE);
}
AbstractXPathExpressionEngine xPathEngine = null;
boolean bufferMessage_readOnly = OpenSPCoop2Properties.getInstance().isReadByPathBufferEnabled();
boolean checkSoapBodyEmpty = false; // devo poter fare xpath anche su soapBody empty
Element element = null;
String elementJson = null;
if(message!=null) {
element = MessageUtils.getContentElement(message, checkSoapBodyEmpty, bufferMessage_readOnly, idTransazione);
elementJson = MessageUtils.getContentString(message, bufferMessage_readOnly, idTransazione);
}
if(element!=null) {
xPathEngine = new org.openspcoop2.message.xml.XPathExpressionEngine(message.getFactory());
return AbstractXPathExpressionEngine.extractAndConvertResultAsString(element, xPathEngine, nome, log);
}
else if(elementJson!=null) {
return JsonXmlPathExpressionEngine.extractAndConvertResultAsString(elementJson, nome, log);
}
else {
return null; // semplicemente non deve matchare il filtro
}
case URLBASED:
String urlInvocazionePD = urlProtocolContext.getUrlInvocazione_formBased();
try{
return RegularExpressionEngine.getStringMatchPattern(urlInvocazionePD, nome);
}catch(RegExpNotFoundException notFound){
return null;
}
case FORM_BASED:
return urlProtocolContext.getParameterFirstValue(nome);
case HEADER_BASED:
return urlProtocolContext.getHeaderFirstValue(nome);
case SOAPACTION_BASED:
String soapAction = soapActionParam;
if(soapAction==null) {
// provo una soluzione veloce di vedere se รจ presente nell'header di trasporto o nel content-type
// non so che tipo di message type possiedo
try{
soapAction = SoapUtils.getSoapAction(urlProtocolContext, MessageType.SOAP_11, urlProtocolContext.getContentType());
}catch(Exception e){
// ignore
}
if(soapAction==null){
try{
soapAction = SoapUtils.getSoapAction(urlProtocolContext, MessageType.SOAP_12, urlProtocolContext.getContentType());
}catch(Exception e){
// ignore
}
}
}
if(soapAction!=null) {
soapAction = soapAction.trim();
if(soapAction.startsWith("\"") && soapAction.length()>1){
soapAction = soapAction.substring(1);
}
if(soapAction.endsWith("\"") && soapAction.length()>1){
soapAction = soapAction.substring(0, (soapAction.length()-1));
}
}
return soapAction;
case INDIRIZZO_IP:
if(pddContext!=null && pddContext.containsKey(Costanti.CLIENT_IP_REMOTE_ADDRESS)) {
return (String) pddContext.getObject(Costanti.CLIENT_IP_REMOTE_ADDRESS);
}
return null;
case INDIRIZZO_IP_FORWARDED:
if(pddContext!=null && pddContext.containsKey(Costanti.CLIENT_IP_TRANSPORT_ADDRESS)) {
return (String) pddContext.getObject(Costanti.CLIENT_IP_TRANSPORT_ADDRESS);
}
return null;
case PLUGIN_BASED:
IRateLimiting rateLimitingPlugin = null;
try{
rateLimitingPlugin = PddPluginLoader.getInstance().newRateLimiting(nome);
}catch(Exception e){
throw e;
}
String className = null;
try{
className = rateLimitingPlugin.getClass().getName();
Dati datiRichiesta = new Dati();
datiRichiesta.setConnettore(connettore);
datiRichiesta.setDatiTransazione(datiTransazione);
datiRichiesta.setMessaggio(message);
datiRichiesta.setPddContext(pddContext);
if(forFilter){
return rateLimitingPlugin.estraiValoreFiltro(log,datiRichiesta);
}
else{
return rateLimitingPlugin.estraiValoreCollezionamentoDati(log,datiRichiesta);
}
}catch(Exception e){
throw new Exception("Instance plugin ["+nome+"] [class:"+className+"] error: "+e.getMessage(),e);
}
}
throw new Exception("TipoFiltro ["+tipo+"] non gestito");
}
}