InformazioniServizioURLMapping.java
/*
* GovWay - A customizable API Gateway
* https://govway.org
*
* Copyright (c) 2005-2025 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.mapping;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import org.openspcoop2.core.config.driver.DriverConfigurazioneNotFound;
import org.openspcoop2.core.id.IDSoggetto;
import org.openspcoop2.message.OpenSPCoop2Message;
import org.openspcoop2.message.constants.MessageType;
import org.openspcoop2.message.constants.ServiceBinding;
import org.openspcoop2.message.xml.MessageDynamicNamespaceContextFactory;
import org.openspcoop2.protocol.engine.constants.ModalitaIdentificazione;
import org.openspcoop2.protocol.manifest.Openspcoop2;
import org.openspcoop2.protocol.manifest.UrlMapping;
import org.openspcoop2.protocol.manifest.constants.UrlMappingSourceType;
import org.openspcoop2.protocol.sdk.IProtocolFactory;
import org.openspcoop2.protocol.sdk.ProtocolException;
import org.openspcoop2.protocol.sdk.constants.IDService;
import org.openspcoop2.protocol.sdk.state.FunctionContextsCustom;
import org.openspcoop2.protocol.sdk.state.URLProtocolContext;
import org.openspcoop2.utils.regexp.RegularExpressionEngine;
import org.openspcoop2.utils.transport.Credential;
import org.openspcoop2.utils.xml.AbstractXPathExpressionEngine;
import org.openspcoop2.utils.xml.DynamicNamespaceContext;
import org.openspcoop2.utils.xml2json.JsonXmlPathExpressionEngine;
import org.slf4j.Logger;
import org.w3c.dom.Element;
/**
* Informazioni Servizi Porta
*
* @author Poli Andrea (apoli@link.it)
* @author $Author$
* @version $Rev$, $Date$
*/
public class InformazioniServizioURLMapping {
/* ********* STATIC ********* */
private static final String TIPO_MITTENTE = "identificazione-tipo-mittente";
private static final String NOME_MITTENTE = "identificazione-mittente";
private static final String INFORMAZIONI_PROTOCOLLO = "identificazione-informazioni-protocollo";
private static final String ID_PROTOCOLLO = "identificazione-id-protocollo";
private static final String GENERAZIONE_LISTA_TRASMISSIONI = "generazione-lista-trasmissioni";
private static MappingProperties getMappingProperties(IProtocolFactory<?> protocolFactory) throws ProtocolException{
Openspcoop2 manifest = protocolFactory.getManifest();
if(InformazioniServizioURLMapping.mappingPropertiesTable.containsKey(manifest.getProtocol().getName())==false){
InformazioniServizioURLMapping.initMappingProperties(protocolFactory);
}
return InformazioniServizioURLMapping.mappingPropertiesTable.get(manifest.getProtocol().getName());
}
private static HashMap<String, MappingProperties> mappingPropertiesTable = new HashMap<String, MappingProperties>();
public static synchronized void initMappingProperties(IProtocolFactory<?> protocolFactory) throws ProtocolException{
try{
Openspcoop2 manifest = protocolFactory.getManifest();
if(InformazioniServizioURLMapping.mappingPropertiesTable.containsKey(manifest.getProtocol().getName())==false){
UrlMapping urlMapping = manifest.getUrlMapping();
if(UrlMappingSourceType.XML.equals(urlMapping.getType())){
//TODO IMPLEMENTARE VERSIONE XML
throw new ProtocolException("Not implemented");
}
else if(UrlMappingSourceType.PROPERTIES.equals(urlMapping.getType())){
File f = new File(urlMapping.getFile());
InputStream is = null;
try{
if(f.exists()){
is = new FileInputStream(f);
}
else{
is = protocolFactory.getClass().getResourceAsStream(urlMapping.getFile());
}
MappingProperties m = new MappingProperties(urlMapping.getFile(), is, protocolFactory.getLogger());
InformazioniServizioURLMapping.mappingPropertiesTable.put(manifest.getProtocol().getName(), m);
}finally{
try{
if(is!=null){
is.close();
}
}catch(Exception eClose){
// close
}
}
}
else{
throw new ProtocolException("["+urlMapping.getType().getValue()+"] Not supported");
}
}
}catch(Exception e){
throw new ProtocolException(e.getMessage(),e);
}
}
/* *********** INSTANCE ********* */
// Dati ricevuti dal costruttore
private OpenSPCoop2Message msg;
private URLProtocolContext urlProtocolContext;
@SuppressWarnings("unused")
private Logger log;
// Gestore delle properties
private MappingProperties mp;
// Id Mapping
private String idMapping; // la keyword che indica il mapping per quanto concerne la url invocata
// Mittente
private MappingInfo tipoMittente;
private MappingInfo mittente;
// Informazioni di protocollo
private MappingInfo infoProtocollo;
// ID di protocollo
private MappingInfo idProtocollo;
// Indicazione se generare la lista trasmissione
private boolean generateListaTrasmissione = false;
public InformazioniServizioURLMapping(OpenSPCoop2Message msg,IProtocolFactory<?> protocolFactory,
URLProtocolContext urlProtocolContext, Logger log, IDService idService,
FunctionContextsCustom customContexts) throws ProtocolException{
this.mp = InformazioniServizioURLMapping.getMappingProperties(protocolFactory);
this.msg = msg;
this.urlProtocolContext = urlProtocolContext;
this.log = log;
// Id Mapping
this.idMapping = resolveMappingName(urlProtocolContext, idService, customContexts);
// Mittente
this.tipoMittente = this.getMappingInfo(TIPO_MITTENTE);
this.mittente = this.getMappingInfo(NOME_MITTENTE);
// Informazioni di protocollo
this.infoProtocollo = this.getMappingInfo(INFORMAZIONI_PROTOCOLLO);
// ID di protocollo
this.idProtocollo = this.getMappingInfo(ID_PROTOCOLLO);
// ListaTrasmissione
String generazioneListaTrasmissioniTmp = this.mp.getValue(this.msg.getProtocolName(), this.idMapping, GENERAZIONE_LISTA_TRASMISSIONI);
if(generazioneListaTrasmissioniTmp!=null){
this.generateListaTrasmissione = Boolean.parseBoolean(generazioneListaTrasmissioniTmp);
}
}
@Override
public String toString(){
StringBuilder bf = new StringBuilder();
bf.append("MappingId(");
bf.append(this.idMapping);
bf.append(") ");
bf.append("TipoMittente(");
if(this.tipoMittente!=null)
bf.append(this.tipoMittente.toString());
else
bf.append("?non presente?");
bf.append(") ");
bf.append("Mittente(");
if(this.mittente!=null)
bf.append(this.mittente.toString());
else
bf.append("?non presente?");
bf.append(") ");
bf.append("InformazioniProtocollo(");
if(this.infoProtocollo!=null)
bf.append(this.infoProtocollo.toString());
else
bf.append("?non presente?");
bf.append(") ");
bf.append("IDProtocollo(");
if(this.idProtocollo!=null)
bf.append(this.idProtocollo.toString());
else
bf.append("?non presente?");
bf.append(") ");
bf.append("GenerazioneListaTrasmissioni(");
bf.append(this.generateListaTrasmissione);
bf.append(") ");
return bf.toString();
}
/* ************ UTILITIES ********************** */
/**
* Recupera il nome del Mapping configurato per la URL invocata.
*
* @return Nome del mapping configurato per gestire la URL invocata.
* @throws IOException Se ci sono problemi di accesso al file di configurazione.
* @throws ProtocolException Se la configurazione non e' corretta.
*/
private String resolveMappingName(URLProtocolContext urlProtocolContext, IDService idService, FunctionContextsCustom customContexts) throws ProtocolException {
// Recupero il nome del mapping per la url invocata
String mappingName = this.mp.getMappingName(this.msg.getProtocolName(), urlProtocolContext.getRequestURI(), idService, customContexts);
return mappingName;
}
/**
* Recupera la modalita' di identificazione di una properieta'
*/
private MappingInfo getMappingInfo(String proprieta) throws ProtocolException {
MappingInfo mappingInfo = new MappingInfo();
mappingInfo.setModalitaIdentificazione(this.mp.getModalita(this.msg.getProtocolName(), this.idMapping, proprieta));
mappingInfo.setName(this.mp.getName(this.msg.getProtocolName(), this.idMapping, proprieta));
mappingInfo.setValue(this.mp.getValue(this.msg.getProtocolName(), this.idMapping, proprieta));
mappingInfo.setPattern(this.mp.getPattern(this.msg.getProtocolName(), this.idMapping, proprieta));
mappingInfo.setAnonymous(this.mp.getAnonymous(this.msg.getProtocolName(), this.idMapping, proprieta));
if(ID_PROTOCOLLO.equals(proprieta) || INFORMAZIONI_PROTOCOLLO.equals(proprieta)){
if( !ModalitaIdentificazione.STATIC.equals(mappingInfo.getModalitaIdentificazione())
&&
!ModalitaIdentificazione.PLUGIN_BASED.equals(mappingInfo.getModalitaIdentificazione()) ){
throw new ProtocolException("La Modalita' '"+mappingInfo.getModalitaIdentificazione().toString()+"', indicata per la proprieta' ["+proprieta+"], non puo' essere utilizzata");
}
return mappingInfo;
}
if(ModalitaIdentificazione.STATIC.equals(mappingInfo.getModalitaIdentificazione())){
if(mappingInfo.getValue()==null){
throw new ProtocolException("La Modalita' '"+ModalitaIdentificazione.STATIC.toString()+"', indicata per la proprieta' ["+proprieta+"], richiede la definizione di una omonima proprieta' con suffisso '.value'");
}
}
if(ModalitaIdentificazione.URL_BASED.equals(mappingInfo.getModalitaIdentificazione())){
if(mappingInfo.getPattern()==null){
throw new ProtocolException("La Modalita' '"+ModalitaIdentificazione.URL_BASED.toString()+"', indicata per la proprieta' ["+proprieta+"], richiede la definizione di una omonima proprieta' con suffisso '.pattern'");
}
}
if(ModalitaIdentificazione.CONTENT_BASED.equals(mappingInfo.getModalitaIdentificazione())){
if(mappingInfo.getPattern()==null){
throw new ProtocolException("La Modalita' '"+ModalitaIdentificazione.CONTENT_BASED.toString()+"', indicata per la proprieta' ["+proprieta+"], richiede la definizione di una omonima proprieta' con suffisso '.pattern'");
}
}
if(ModalitaIdentificazione.HEADER_BASED.equals(mappingInfo.getModalitaIdentificazione())){
if(mappingInfo.getName()==null){
throw new ProtocolException("La Modalita' '"+ModalitaIdentificazione.CONTENT_BASED.toString()+"', indicata per la proprieta' ["+proprieta+"], richiede la definizione di una omonima proprieta' con suffisso '.name'");
}
}
if(ModalitaIdentificazione.IDENTITY_BASED.equals(mappingInfo.getModalitaIdentificazione())){
if(!NOME_MITTENTE.equals(proprieta)){
throw new ProtocolException("La Modalita' '"+ModalitaIdentificazione.IDENTITY_BASED.toString()+"', indicata per la proprieta' ["+proprieta+"], puo' essere utilizzata solamente per identificare il nome del mittente");
}
}
return mappingInfo;
}
public boolean existsUrlBasedIdentificationMode(){
if(this.tipoMittente!=null){
if(ModalitaIdentificazione.URL_BASED.equals(this.tipoMittente.getModalitaIdentificazione())){
return true;
}
}
if(this.mittente!=null){
if(ModalitaIdentificazione.URL_BASED.equals(this.mittente.getModalitaIdentificazione())){
return true;
}
}
return false;
}
public boolean existsContentBasedIdentificationMode(){
if(this.tipoMittente!=null){
if(ModalitaIdentificazione.CONTENT_BASED.equals(this.tipoMittente.getModalitaIdentificazione())){
return true;
}
}
if(this.mittente!=null){
if(ModalitaIdentificazione.CONTENT_BASED.equals(this.mittente.getModalitaIdentificazione())){
return true;
}
}
return false;
}
public boolean existsIdentityBasedIdentificationMode(){
if(this.mittente!=null){
if(ModalitaIdentificazione.IDENTITY_BASED.equals(this.mittente.getModalitaIdentificazione())){
return true;
}
}
return false;
}
public boolean isStaticBasedIdentificationMode_InfoProtocol(){
if(this.infoProtocollo!=null){
if(ModalitaIdentificazione.STATIC.equals(this.infoProtocollo.getModalitaIdentificazione())){
return true;
}
}
return false;
}
public boolean isStaticBasedIdentificationMode_IdProtocol(){
if(this.idProtocollo!=null){
if(ModalitaIdentificazione.STATIC.equals(this.idProtocollo.getModalitaIdentificazione())){
return true;
}
}
return false;
}
public boolean isGenerateListaTrasmissione() {
return this.generateListaTrasmissione;
}
/* ***** INIT BUSTA **** */
public void refreshDati(IDSoggetto idMittente, Credential identity, IDSoggetto headerIntegrazioneRichiestaSoggettoMittente) throws ProtocolException{
String urlInvocazione = null;
DynamicNamespaceContext dnc = null;
AbstractXPathExpressionEngine xPathEngine = null;
Element element = null;
String elementJson = null;
if(this.existsUrlBasedIdentificationMode()){
urlInvocazione = this.urlProtocolContext.getUrlInvocazione_formBased();
}
if(this.existsContentBasedIdentificationMode()){
try{
if(ServiceBinding.SOAP.equals(this.msg.getServiceBinding())){
element = this.msg.castAsSoap().getSOAPPart().getEnvelope();
}
else{
if(MessageType.XML.equals(this.msg.getMessageType())){
element = this.msg.castAsRestXml().getContent();
}
else if(MessageType.JSON.equals(this.msg.getMessageType())){
elementJson = this.msg.castAsRestJson().getContent();
}
else{
throw new DriverConfigurazioneNotFound("Identificazione 'contentBased' non supportata per il message-type '"+this.msg.getMessageType()+"'");
}
}
if(element!=null) {
dnc = MessageDynamicNamespaceContextFactory.getInstance(this.msg.getFactory()).getNamespaceContext(element);
xPathEngine = new org.openspcoop2.message.xml.XPathExpressionEngine(this.msg.getFactory());
}
}catch(Exception e){
throw new ProtocolException(e.getMessage(),e);
}
}
// TipoMittente
String tipoMittente = null;
try{
tipoMittente = this.readValue(this.tipoMittente, TIPO_MITTENTE, identity, urlInvocazione,
element, dnc, xPathEngine,
elementJson,
headerIntegrazioneRichiestaSoggettoMittente);
}catch(ProtocolException e){
if(tipoMittente==null && !ModalitaIdentificazione.PLUGIN_BASED.equals(this.tipoMittente.getModalitaIdentificazione())){
if(this.tipoMittente.getAnonymous()==null){
throw e;
}
else{
tipoMittente = this.tipoMittente.getAnonymous();
}
}
}
if(tipoMittente!=null){
idMittente.setTipo(tipoMittente);
}
// Mittente
String mittente = null;
try{
mittente = this.readValue(this.mittente, NOME_MITTENTE, identity, urlInvocazione,
element, dnc, xPathEngine,
elementJson,
headerIntegrazioneRichiestaSoggettoMittente);
}catch(ProtocolException e){
if(mittente==null && !ModalitaIdentificazione.PLUGIN_BASED.equals(this.mittente.getModalitaIdentificazione())){
if(this.mittente.getAnonymous()==null){
throw e;
}
else{
mittente = this.mittente.getAnonymous();
}
}
}
if(mittente!=null){
idMittente.setNome(mittente);
}
}
private String readValue(MappingInfo mappingInfo,String oggetto,
Credential identity,String urlInvocazione,
Element element, DynamicNamespaceContext dnc ,AbstractXPathExpressionEngine xPathEngine,
String elementJson,
IDSoggetto headerIntegrazioneRichiestaSoggettoMittente) throws ProtocolException{
if(ModalitaIdentificazione.STATIC.equals(mappingInfo.getModalitaIdentificazione())){
if(mappingInfo.getValue()==null){
throw new ProtocolException("URLMapping["+oggetto+"] identificazione "+ModalitaIdentificazione.STATIC.toString()+" non riuscita: valore nell'omonima proprieta' con suffisso '.value' non fornito");
}else{
return mappingInfo.getValue();
}
}
else if(ModalitaIdentificazione.PLUGIN_BASED.equals(mappingInfo.getModalitaIdentificazione())){
return null; // delegata al plugin
}
else if(ModalitaIdentificazione.URL_BASED.equals(mappingInfo.getModalitaIdentificazione())){
try{
return RegularExpressionEngine.getStringMatchPattern(urlInvocazione, mappingInfo.getPattern());
}catch(Exception e){
throw new ProtocolException("URLMapping["+oggetto+"] identificazione "+ModalitaIdentificazione.URL_BASED.toString()+" non riuscita: "+e.getMessage(),e);
}
}
else if(ModalitaIdentificazione.CONTENT_BASED.equals(mappingInfo.getModalitaIdentificazione())){
try{
if(element!=null) {
return AbstractXPathExpressionEngine.extractAndConvertResultAsString(element,dnc, xPathEngine, mappingInfo.getPattern(), this.log);
}
else {
return JsonXmlPathExpressionEngine.extractAndConvertResultAsString(elementJson, mappingInfo.getPattern(), this.log);
}
}catch(Exception e){
throw new ProtocolException("URLMapping["+oggetto+"] identificazione "+ModalitaIdentificazione.CONTENT_BASED.toString()+" non riuscita: "+e.getMessage(),e);
}
}
else if(ModalitaIdentificazione.INPUT_BASED.equals(mappingInfo.getModalitaIdentificazione())){
if(headerIntegrazioneRichiestaSoggettoMittente==null){
throw new ProtocolException("URLMapping["+oggetto+"] identificazione "+ModalitaIdentificazione.HEADER_BASED.toString()+" non riuscita: non esistono informazioni di integrazione");
}
else{
if(TIPO_MITTENTE.equals(oggetto)){
if(headerIntegrazioneRichiestaSoggettoMittente.getTipo()==null){
throw new ProtocolException("URLMapping["+oggetto+"] identificazione "+ModalitaIdentificazione.HEADER_BASED.toString()+" non riuscita: non esistono informazioni di integrazione (TipoMittente)");
}
else{
return headerIntegrazioneRichiestaSoggettoMittente.getTipo();
}
}
else if(NOME_MITTENTE.equals(oggetto)){
if(headerIntegrazioneRichiestaSoggettoMittente.getNome()==null){
throw new ProtocolException("URLMapping["+oggetto+"] identificazione "+ModalitaIdentificazione.HEADER_BASED.toString()+" non riuscita: non esistono informazioni di integrazione (Mittente)");
}
else{
return headerIntegrazioneRichiestaSoggettoMittente.getNome();
}
}
else{
throw new ProtocolException("URLMapping["+oggetto+"] identificazione "+ModalitaIdentificazione.HEADER_BASED.toString()+" non supportata per l'oggetto "+oggetto);
}
}
}
else if(ModalitaIdentificazione.HEADER_BASED.equals(mappingInfo.getModalitaIdentificazione())){
if(mappingInfo.getName()==null){
throw new ProtocolException("URLMapping["+oggetto+"] identificazione "+ModalitaIdentificazione.HEADER_BASED.toString()+" non riuscita: nome header nell'omonima proprieta' con suffisso '.name' non fornito");
}
String value = this.urlProtocolContext.getHeaderFirstValue(mappingInfo.getName());
if(value==null){
throw new ProtocolException("URLMapping["+oggetto+"] identificazione "+ModalitaIdentificazione.HEADER_BASED.toString()+" non riuscita: header di trasporto con nome ["+mappingInfo.getName()+"] non trovato");
}
return value;
}
else if(ModalitaIdentificazione.IDENTITY_BASED.equals(mappingInfo.getModalitaIdentificazione())){
if(identity==null){
throw new ProtocolException("URLMapping["+oggetto+"] identificazione "+ModalitaIdentificazione.IDENTITY_BASED.toString()+" non riuscita: Identity non fornita");
}
String id = null;
if(identity.getPrincipal()!=null){
id = identity.getPrincipal();
}
else if(identity.getSubject()!=null){
id = identity.getSubject();
}
else if(identity.getUsername()!=null){
id = identity.getUsername();
}
if(id!=null){
if(mappingInfo.getPattern()!=null){
try{
String tmp = RegularExpressionEngine.getStringMatchPattern(id, mappingInfo.getPattern());
if(tmp!=null && !"".equals(tmp.trim())){
return tmp.trim();
}
}catch(Exception e){
}
}
return id;
}
throw new ProtocolException("URLMapping["+oggetto+"] identificazione "+ModalitaIdentificazione.IDENTITY_BASED.toString()+" non riuscita: Identity fornita non contiene una identita");
}
return null;
}
}