AccordoServizioWrapperUtilities.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.core.registry.rest;

  21. import java.io.File;
  22. import java.net.URL;
  23. import java.util.ArrayList;
  24. import java.util.HashMap;
  25. import java.util.List;
  26. import java.util.Map;

  27. import org.openspcoop2.core.registry.AccordoServizioParteComune;
  28. import org.openspcoop2.core.registry.Documento;
  29. import org.openspcoop2.core.registry.constants.FormatoSpecifica;
  30. import org.openspcoop2.core.registry.driver.DriverRegistroServiziException;
  31. import org.openspcoop2.message.OpenSPCoop2MessageFactory;
  32. import org.openspcoop2.message.xml.MessageXMLUtils;
  33. import org.openspcoop2.utils.LoggerWrapperFactory;
  34. import org.openspcoop2.utils.json.JSONUtils;
  35. import org.openspcoop2.utils.json.YAMLUtils;
  36. import org.openspcoop2.utils.resources.FileSystemUtilities;
  37. import org.openspcoop2.utils.rest.ApiFactory;
  38. import org.openspcoop2.utils.rest.ApiFormats;
  39. import org.openspcoop2.utils.rest.ApiReaderConfig;
  40. import org.openspcoop2.utils.rest.IApiReader;
  41. import org.openspcoop2.utils.rest.api.Api;
  42. import org.openspcoop2.utils.rest.api.ApiSchema;
  43. import org.openspcoop2.utils.rest.api.ApiSchemaType;
  44. import org.openspcoop2.utils.transport.http.HttpUtilities;
  45. import org.openspcoop2.utils.xml.AbstractXMLUtils;
  46. import org.openspcoop2.utils.xml.XSDUtils;
  47. import org.slf4j.Logger;


  48. /**
  49.  * Classe utilizzata per leggere/modificare i wsdl che formano un accordo di un servizio
  50.  *
  51.  *
  52.  * @author Poli Andrea (apoli@link.it)
  53.  * @author $Author$
  54.  * @version $Rev$, $Date$
  55.  */


  56. public class AccordoServizioWrapperUtilities {

  57.     private Logger logger = null;
  58.     private AbstractXMLUtils xmlUtils = null;
  59.     private XSDUtils xsdUtils = null;
  60.     private JSONUtils jsonUtils = null;
  61.     private YAMLUtils yamlUtils = null;
  62.     private OpenSPCoop2MessageFactory messageFactory;
  63.    
  64.     /** Accordo Servizio */
  65.     public AccordoServizioWrapperUtilities(OpenSPCoop2MessageFactory messageFactory, Logger log, AccordoServizioWrapper accordoServizio){
  66.         if(log!=null)
  67.             this.logger = log;
  68.         else
  69.             this.logger = LoggerWrapperFactory.getLogger(AccordoServizioWrapperUtilities.class);
  70.         this.accordoServizioWrapper = accordoServizio;
  71.         this.messageFactory = messageFactory;
  72.         this.xmlUtils = MessageXMLUtils.getInstance(this.messageFactory);
  73.         this.xsdUtils = new XSDUtils(this.xmlUtils);
  74.         this.jsonUtils = JSONUtils.getInstance();
  75.         this.yamlUtils = YAMLUtils.getInstance();
  76.     }
  77.     private AccordoServizioWrapper accordoServizioWrapper = null;
  78.     public AccordoServizioWrapper getAccordoServizioWrapper() {
  79.         return this.accordoServizioWrapper;
  80.     }
  81.     public void setAccordoServizio(AccordoServizioWrapper accordoServizio) {
  82.         this.accordoServizioWrapper = accordoServizio;
  83.     }
  84.    
  85.    
  86.    
  87.    
  88.    
  89.     public static final String API_SENZA_SPECIFICA = "L'API non contiene una specifica";
  90.    
  91.     public void buildApiFromSpecific(boolean fromBytes,boolean buildSchemi,boolean processInclude) throws DriverRegistroServiziException {
  92.        
  93.         if(this.accordoServizioWrapper==null) {
  94.             throw new DriverRegistroServiziException("AccordoWrapper non fornito");
  95.         }
  96.         if(this.accordoServizioWrapper.getAccordoServizio()==null) {
  97.             throw new DriverRegistroServiziException("API non fornita");
  98.         }
  99.         AccordoServizioParteComune as = this.accordoServizioWrapper.getAccordoServizio();
  100.        
  101.         IApiReader apiReader = null;
  102.         FormatoSpecifica formato = as.getFormatoSpecifica();
  103.         if(formato==null) {
  104.             formato = FormatoSpecifica.OPEN_API_3;
  105.         }
  106.         switch (formato) {
  107.         case WADL:
  108.             try {
  109.                 apiReader = ApiFactory.newApiReader(ApiFormats.WADL);
  110.             }catch(Exception e) {
  111.                 throw new DriverRegistroServiziException("Inizializzazione Reader Specifica ["+this.accordoServizioWrapper.getAccordoServizio().getFormatoSpecifica()+"] fallito: "+e.getMessage(),e);
  112.             }
  113.             break;
  114.         case SWAGGER_2:
  115.             try {
  116.                 apiReader = ApiFactory.newApiReader(ApiFormats.SWAGGER_2);
  117.             }catch(Exception e) {
  118.                 throw new DriverRegistroServiziException("Inizializzazione Reader Specifica ["+this.accordoServizioWrapper.getAccordoServizio().getFormatoSpecifica()+"] fallito: "+e.getMessage(),e);
  119.             }
  120.             break;
  121.         case OPEN_API_3:
  122.             try {
  123.                 apiReader = ApiFactory.newApiReader(ApiFormats.OPEN_API_3);
  124.             }catch(Exception e) {
  125.                 throw new DriverRegistroServiziException("Inizializzazione Reader Specifica ["+this.accordoServizioWrapper.getAccordoServizio().getFormatoSpecifica()+"] fallito: "+e.getMessage(),e);
  126.             }
  127.             break;
  128.         case WSDL_11:
  129.             throw new DriverRegistroServiziException("Tipo specifica ["+this.accordoServizioWrapper.getAccordoServizio().getFormatoSpecifica()+"] non supportata");
  130.         }
  131.        
  132.         if(apiReader==null) {
  133.             throw new DriverRegistroServiziException("Inizializzazione Reader Specifica ["+this.accordoServizioWrapper.getAccordoServizio().getFormatoSpecifica()+"] fallita");
  134.         }
  135.        
  136.        
  137.         byte [] specifica = null;
  138.         if(fromBytes){
  139.             if(as.getByteWsdlConcettuale()!=null){
  140.                 specifica = as.getByteWsdlConcettuale();
  141.             }
  142.         }
  143.         else{
  144.             if(as.getWsdlConcettuale()!=null){
  145.                 try{
  146.                     String location = as.getWsdlConcettuale();
  147.                     if(location.startsWith("http://") || location.startsWith("file://")){
  148.                         URL url = new URL(location);
  149.                         specifica = HttpUtilities.requestHTTPFile(url.toString());
  150.                     }
  151.                     else{
  152.                         File f = new File(location);
  153.                         specifica = FileSystemUtilities.readBytesFromFile(f);
  154.                     }
  155.                 }catch(Exception e){
  156.                     throw new DriverRegistroServiziException("L'API contiene una specifica corrotta: "+e.getMessage(),e);
  157.                 }
  158.             }
  159.         }
  160.         if(specifica==null) {
  161.             throw new DriverRegistroServiziException(API_SENZA_SPECIFICA);
  162.         }
  163.        
  164.        
  165.        
  166.         ApiSchema [] s = null;
  167.         ApiReaderConfig config = new ApiReaderConfig();
  168.         if(buildSchemi) {
  169.             config.setProcessInclude(processInclude);
  170.             config.setProcessInlineSchema(true);
  171.             s = this.buildSchemas(as, fromBytes);
  172.         }
  173.         else {
  174.             config.setProcessInclude(false);
  175.             config.setProcessInlineSchema(false);
  176.         }
  177.         try {
  178.             if(s!=null) {
  179.                 apiReader.init(this.logger, specifica, config, s);
  180.             }
  181.             else {
  182.                 apiReader.init(this.logger, specifica, config);
  183.             }
  184.             Api api = apiReader.read();
  185.             this.accordoServizioWrapper.setApi(api);
  186.         }catch(Exception e) {
  187.             throw new DriverRegistroServiziException("Inizializzazione Specifica ["+this.accordoServizioWrapper.getAccordoServizio().getFormatoSpecifica()+"] fallita: "+e.getMessage(),e);
  188.         }
  189.        
  190.        
  191.     }
  192.    
  193.    
  194.     public void buildApiFromRegistry(boolean fromBytes,boolean buildSchemi) throws DriverRegistroServiziException {
  195.            
  196.         if(this.accordoServizioWrapper==null) {
  197.             throw new DriverRegistroServiziException("AccordoWrapper non fornito");
  198.         }
  199.         if(this.accordoServizioWrapper.getAccordoServizio()==null) {
  200.             throw new DriverRegistroServiziException("API non fornita");
  201.         }
  202.         AccordoServizioParteComune as = this.accordoServizioWrapper.getAccordoServizio();
  203.        
  204.         try {
  205.             RegistryAPI api = new RegistryAPI(as, "http://TODO");
  206.            
  207.             ApiSchema [] s = null;
  208.             if(buildSchemi) {
  209.                 s = this.buildSchemas(as, fromBytes);
  210.                 if(s!=null && s.length>0) {
  211.                     for (int i = 0; i < s.length; i++) {
  212.                         api.addSchema(s[i]);
  213.                     }
  214.                 }
  215.             }
  216.            
  217.             this.accordoServizioWrapper.setApi(api);
  218.         }catch(Exception e) {
  219.             throw new DriverRegistroServiziException("Inizializzazione Specifica ["+this.accordoServizioWrapper.getAccordoServizio().getFormatoSpecifica()+"] fallita: "+e.getMessage(),e);
  220.         }
  221.     }
  222.    
  223.    
  224.     private ApiSchema [] buildSchemas(AccordoServizioParteComune as, boolean fromBytes) throws DriverRegistroServiziException{
  225.         Map<String, byte[]> resourcesXSD = new HashMap<String, byte[]>();
  226.         Map<String, byte[]> resourcesJSON = new HashMap<String, byte[]>();
  227.         Map<String, byte[]> resourcesYAML = new HashMap<String, byte[]>();
  228.        
  229.         // --------- ALLEGATI ---------
  230.         if(as.sizeAllegatoList()>0){
  231.             for(int i=0; i<as.sizeAllegatoList();i++){

  232.                 Documento allegato = as.getAllegato(i);
  233.                 byte[] resource = null;
  234.                 String systemId = null;
  235.                 //String location = null;
  236.                 if(fromBytes){
  237.                     //location = allegato.getFile();
  238.                     systemId = allegato.getFile();
  239.                     resource = allegato.getByteContenuto();
  240.                     if(resource==null){
  241.                         throw new DriverRegistroServiziException("Allegato ["+systemId+"] non contiene i bytes che ne definiscono il contenuto");
  242.                     }
  243.                 }
  244.                 else{
  245.                     String location = allegato.getFile();
  246.                     try{
  247.                         if(location.startsWith("http://") || location.startsWith("file://")){
  248.                             URL url = new URL(location);
  249.                             resource = HttpUtilities.requestHTTPFile(url.toString());
  250.                             systemId = (new File(url.getFile())).getName();
  251.                         }
  252.                         else{
  253.                             File f = new File(location);
  254.                             resource = FileSystemUtilities.readBytesFromFile(f);
  255.                             systemId = f.getName();
  256.                         }  
  257.                     }catch(Exception e){
  258.                         throw new DriverRegistroServiziException("Allegato ["+location+"] indirizza un documento non esistente");
  259.                     }
  260.                 }

  261.                 try{
  262.                     if(this.xsdUtils.isXSDSchema(resource)){
  263.                         if(resourcesXSD.containsKey(systemId)){
  264.                             throw new Exception("Esiste più di un documento xsd, registrato tra allegati e specifiche semiformali, con nome ["+systemId+"] (La validazione di Govway richiede l'utilizzo di nomi diversi)");
  265.                         }
  266.                         resourcesXSD.put(systemId,resource);
  267.                     }
  268.                     else if(this.yamlUtils.isYaml(resource)){
  269.                         if(resourcesYAML.containsKey(systemId)){
  270.                             throw new Exception("Esiste più di un documento yaml, registrato tra allegati e specifiche semiformali, con nome ["+systemId+"] (La validazione di Govway richiede l'utilizzo di nomi diversi)");
  271.                         }
  272.                         resourcesYAML.put(systemId,resource);
  273.                     }
  274.                     else if(this.jsonUtils.isJson(resource)){
  275.                         if(resourcesJSON.containsKey(systemId)){
  276.                             throw new Exception("Esiste più di un documento json, registrato tra allegati e specifiche semiformali, con nome ["+systemId+"] (La validazione di Govway richiede l'utilizzo di nomi diversi)");
  277.                         }
  278.                         resourcesJSON.put(systemId,resource);
  279.                     }
  280.                 }catch(Exception e){
  281.                     throw new DriverRegistroServiziException("La lettura dell'allegato ["+systemId+"] ha causato un errore: "+e.getMessage(),e);
  282.                 }

  283.             }
  284.         }


  285.         // --------- SPECIFICHE SEMIFORMALI ---------
  286.         if(as.sizeSpecificaSemiformaleList()>0){
  287.             for(int i=0; i<as.sizeSpecificaSemiformaleList();i++){

  288.                 Documento specificaSemiformale = as.getSpecificaSemiformale(i);
  289.                 byte[] resource = null;
  290.                 String systemId = null;
  291.                 //String location = null;
  292.                 if(fromBytes){
  293.                     //location = specificaSemiformale.getFile();
  294.                     systemId = specificaSemiformale.getFile();
  295.                     resource = specificaSemiformale.getByteContenuto();
  296.                     if(resource==null){
  297.                         throw new DriverRegistroServiziException("Specifica Semiformale ["+systemId+"] non contiene i bytes che ne definiscono il contenuto");
  298.                     }
  299.                 }
  300.                 else{
  301.                     String location = specificaSemiformale.getFile();
  302.                     try{
  303.                         if(location.startsWith("http://") || location.startsWith("file://")){
  304.                             URL url = new URL(location);
  305.                             resource = HttpUtilities.requestHTTPFile(url.toString());
  306.                             systemId = (new File(url.getFile())).getName();
  307.                         }
  308.                         else{
  309.                             File f = new File(location);
  310.                             resource = FileSystemUtilities.readBytesFromFile(f);
  311.                             systemId = f.getName();
  312.                         }  
  313.                     }catch(Exception e){
  314.                         throw new DriverRegistroServiziException("Specifica Semiformale ["+location+"] indirizza un documento non esistente");
  315.                     }
  316.                 }

  317.                 try{
  318.                     if(this.xsdUtils.isXSDSchema(resource)){
  319.                         if(resourcesXSD.containsKey(systemId)){
  320.                             throw new Exception("Esiste più di un documento xsd, registrato tra allegati e specifiche semiformali, con nome ["+systemId+"] (La validazione di Govway richiede l'utilizzo di nomi diversi)");
  321.                         }
  322.                         resourcesXSD.put(systemId,resource);
  323.                     }
  324.                     else if(this.yamlUtils.isYaml(resource)){
  325.                         if(resourcesYAML.containsKey(systemId)){
  326.                             throw new Exception("Esiste più di un documento yaml, registrato tra allegati e specifiche semiformali, con nome ["+systemId+"] (La validazione di Govway richiede l'utilizzo di nomi diversi)");
  327.                         }
  328.                         resourcesYAML.put(systemId,resource);
  329.                     }
  330.                     else if(this.jsonUtils.isJson(resource)){
  331.                         if(resourcesJSON.containsKey(systemId)){
  332.                             throw new Exception("Esiste più di un documento json, registrato tra allegati e specifiche semiformali, con nome ["+systemId+"] (La validazione di Govway richiede l'utilizzo di nomi diversi)");
  333.                         }
  334.                         resourcesJSON.put(systemId,resource);
  335.                     }
  336.                 }catch(Exception e){
  337.                     throw new DriverRegistroServiziException("La lettura della specifica semiformale ["+systemId+"] ha causato un errore: "+e.getMessage(),e);
  338.                 }

  339.             }
  340.         }

  341.         List<ApiSchema> schemas = new ArrayList<ApiSchema>();
  342.         if(resourcesXSD!=null && resourcesXSD.size()>0) {
  343.             for (String key : resourcesXSD.keySet()) {
  344.                 byte[] value = resourcesXSD.get(key);
  345.                 schemas.add(new ApiSchema(key, value, ApiSchemaType.XSD));
  346.             }
  347.         }
  348.         if(resourcesYAML!=null && resourcesYAML.size()>0) {
  349.             for (String key : resourcesYAML.keySet()) {
  350.                 byte[] value = resourcesYAML.get(key);
  351.                 schemas.add(new ApiSchema(key, value, ApiSchemaType.YAML));
  352.             }
  353.         }
  354.         if(resourcesJSON!=null && resourcesJSON.size()>0) {
  355.             for (String key : resourcesJSON.keySet()) {
  356.                 byte[] value = resourcesJSON.get(key);
  357.                 schemas.add(new ApiSchema(key, value, ApiSchemaType.JSON));
  358.             }
  359.         }
  360.         ApiSchema [] s = null;
  361.         if(schemas.size()>0) {
  362.             s = schemas.toArray(new ApiSchema[1]);
  363.         }
  364.        
  365.         return s;
  366.     }
  367. }