MapProperties.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.utils.properties;


  21. import java.io.File;
  22. import java.io.Reader;
  23. import java.io.StringReader;
  24. import java.security.MessageDigest;
  25. import java.util.ArrayList;
  26. import java.util.List;
  27. import java.util.Properties;

  28. import org.apache.commons.lang.StringUtils;
  29. import org.openspcoop2.utils.LoggerWrapperFactory;
  30. import org.openspcoop2.utils.SortedMap;
  31. import org.openspcoop2.utils.Utilities;
  32. import org.openspcoop2.utils.UtilsException;
  33. import org.openspcoop2.utils.io.Base64Utilities;
  34. import org.openspcoop2.utils.resources.Charset;
  35. import org.openspcoop2.utils.resources.FileSystemUtilities;
  36. import org.slf4j.Logger;


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


  44. public class MapProperties {    

  45.     public static final String FILE_NAME = "govway.map.properties";
  46.    
  47.     public static final String ENV_PREFIX = "env.";
  48.     public static final String JAVA_PREFIX = "java.";
  49.    
  50.     public static final String OBFUSCATED_ENV_KEYS = "obfuscated.env.keys";
  51.     public static final String OBFUSCATED_JAVA_KEYS = "obfuscated.java.keys";
  52.    
  53.     public static final String OBFUSCATED_MODE = "obfuscated.mode";
  54.     public static final String OBFUSCATED_MODE_NON_INIZIALIZZATO = "not initialized";
  55.     public static final String OBFUSCATED_MODE_NONE = "none";
  56.     public static final String OBFUSCATED_MODE_DIGEST = "digest";
  57.     public static final String OBFUSCATED_MODE_STATIC = "static";
  58.    
  59.     public static final String OBFUSCATED_DIGEST = "obfuscated.digest";
  60.     public static final String OBFUSCATED_DIGEST_DEFAULT = "SHA-256";
  61.    
  62.     public static final String OBFUSCATED_STATIC = "obfuscated.static";
  63.     public static final String OBFUSCATED_STATIC_DEFAULT = "******";
  64.    
  65.    
  66.    
  67.    
  68.     /** Logger utilizzato per errori eventuali. */
  69.     protected Logger log = null;



  70.     /* ********  F I E L D S  P R I V A T I  ******** */

  71.     /** Reader delle proprieta' impostate nel file 'govway.map.properties' */
  72.     protected PropertiesReader reader;
  73.     protected String content;

  74.     /** Copia Statica */
  75.     private static MapProperties mapProperties = null;

  76.     /** Variabili impostate */
  77.     protected SortedMap<String> envMap = new SortedMap<>();
  78.     protected SortedMap<String> javaMap = new SortedMap<>();
  79.     public SortedMap<String> getEnvMap() {
  80.         return this.envMap;
  81.     }
  82.     public SortedMap<String> getJavaMap() {
  83.         return this.javaMap;
  84.     }
  85.    

  86.     /* ********  C O S T R U T T O R E  ******** */

  87.     /**
  88.      * Viene chiamato in causa per istanziare il properties reader
  89.      *
  90.      *
  91.      */
  92.     /**private MapProperties(Logger log, boolean throwNotFound) throws UtilsException {
  93.         init(log, FILE_NAME, throwNotFound);
  94.     }*/
  95.     protected MapProperties(Logger log, String fileName, boolean throwNotFound) throws UtilsException {
  96.         init(log, fileName, throwNotFound);
  97.     }
  98.     protected void init(Logger log, String fileName, boolean throwNotFound) throws UtilsException {

  99.         if(log==null) {
  100.             this.log = LoggerWrapperFactory.getLogger(MapProperties.class);
  101.         }
  102.         else {
  103.             this.log = log;
  104.         }
  105.        
  106.         /* ---- Lettura del cammino del file di configurazione ---- */
  107.         Properties propertiesReader = readProperties(fileName);
  108.        
  109.         if(propertiesReader!=null) {
  110.             this.reader = new PropertiesReader(propertiesReader, true);
  111.         }
  112.         else if(throwNotFound){
  113.             throw new UtilsException("Config '"+fileName+"' not found");
  114.         }
  115.        
  116.     }
  117.     private Properties readProperties(String fileName) throws UtilsException {
  118.         File fCheck = new File(fileName);
  119.         if(fCheck.exists()) {
  120.             if(!fCheck.canRead()) {
  121.                 throw new UtilsException("File '"+fCheck.getAbsolutePath()+"' cannot read");
  122.             }
  123.             try{
  124.                 this.content = FileSystemUtilities.readFile(fCheck);
  125.             }catch(Exception e) {
  126.                 throw new UtilsException("File '"+fCheck.getAbsolutePath()+"' read failed: "+e.getMessage(),e);
  127.             }
  128.         }
  129.         else {
  130.             String uri = fileName;
  131.             if(!fileName.startsWith("/")) {
  132.                 uri = "/" + fileName;
  133.             }
  134.             try(java.io.InputStream properties = MapProperties.class.getResourceAsStream(uri)){
  135.                 if(properties!=null) {
  136.                     this.content = Utilities.getAsString(properties, Charset.UTF_8.getValue());
  137.                 }
  138.             }catch(Exception e) {
  139.                 throw new UtilsException("Uri '"+uri+"' access failed: "+e.getMessage(),e);
  140.             }
  141.         }
  142.        
  143.         Properties props = null;
  144.         if(this.content!=null) {
  145.             props = new Properties();
  146.             try(Reader properties = new StringReader(this.content)){
  147.                 props.load(properties);
  148.             }catch(Exception e) {
  149.                 throw new UtilsException("Config '"+fileName+"' access failed: "+e.getMessage(),e);
  150.             }
  151.         }
  152.        
  153.         return props;
  154.     }


  155.     /**
  156.      * Il Metodo si occupa di inizializzare il propertiesReader
  157.      *
  158.      *
  159.      */
  160.     public static boolean initialize(Logger log, String fileName, boolean throwNotFound){

  161.         try {
  162.             MapProperties.mapProperties = new MapProperties(log, fileName, throwNotFound);  
  163.             return true;
  164.         }
  165.         catch(Exception e) {
  166.             return false;
  167.         }
  168.     }
  169.    
  170.     /**
  171.      * Ritorna l'istanza di questa classe
  172.      *
  173.      * @return Istanza di MapProperties
  174.      *
  175.      */
  176.     public static MapProperties getInstance(){
  177.         // spotbugs warning 'SING_SINGLETON_GETTER_NOT_SYNCHRONIZED': l'istanza viene creata allo startup
  178.         if (MapProperties.mapProperties == null) {
  179.             synchronized (MapProperties.class) {
  180.                 if (MapProperties.mapProperties == null) {
  181.                     return null;
  182.                 }
  183.             }
  184.         }
  185.         return MapProperties.mapProperties;
  186.     }
  187.    
  188.    
  189.     public void initEnvironment() throws UtilsException {  
  190.         if(this.content!=null) {
  191.             SortedMap<String> convertTextToProperties = PropertiesUtilities.convertTextToSortedMap(this.content, false);
  192.             if(convertTextToProperties!=null && !convertTextToProperties.isEmpty()) {
  193.                 List<String> keys = convertTextToProperties.keys();
  194.                 if(keys!=null && !keys.isEmpty()) {
  195.                     for (String key : keys) {
  196.                         loadPropertyInEnvironment(key);
  197.                     }
  198.                 }
  199.             }
  200.         }
  201.     }
  202.    
  203.     public void loadPropertyInEnvironment(String key) throws UtilsException {
  204.         if(key.startsWith(ENV_PREFIX) && key.length()>ENV_PREFIX.length()) {
  205.             String envKey = key.substring(ENV_PREFIX.length());
  206.             String value = this.reader.getValue_convertEnvProperties(key);
  207.             setEnvProperty(envKey, value);
  208.         }
  209.         else if(key.startsWith(JAVA_PREFIX) && key.length()>JAVA_PREFIX.length()) {
  210.             String envKey = key.substring(JAVA_PREFIX.length());
  211.             String value = this.reader.getValue_convertEnvProperties(key);
  212.             setJavaProperty(envKey, value);
  213.         }
  214.     }

  215.     protected void setJavaProperty(String envKey, String value) throws UtilsException {
  216.         if(value!=null) {
  217.             System.setProperty(envKey, value);
  218.            
  219.             // per preservare l'ordine
  220.             if(this.javaMap.containsKey(envKey)) {
  221.                 this.javaMap.remove(envKey);
  222.             }
  223.             this.javaMap.put(envKey, value);
  224.             /**System.out.println("---- JAVAP ["+envKey+"]=["+value+"]");*/
  225.         }
  226.     }
  227.    
  228.     protected void setEnvProperty(String envKey, String value) throws UtilsException {
  229.         if(value!=null) {
  230.             Utilities.setEnvProperty(envKey, value);
  231.            
  232.             // per preservare l'ordine
  233.             if(this.envMap.containsKey(envKey)) {
  234.                 this.envMap.remove(envKey);
  235.             }
  236.             this.envMap.put(envKey, value);
  237.             /**System.out.println("---- ENVP ["+envKey+"]=["+value+"]");*/
  238.         }
  239.     }
  240.    
  241.     public List<String> getObfuscatedEnvKeys() throws UtilsException{
  242.         return getObfuscatedKeys(OBFUSCATED_ENV_KEYS);
  243.     }
  244.     public List<String> getObfuscatedJavaKeys() throws UtilsException{
  245.         return getObfuscatedKeys(OBFUSCATED_JAVA_KEYS);
  246.     }
  247.     private List<String> getObfuscatedKeys(String pName) throws UtilsException{
  248.         List<String> l = new ArrayList<>();
  249.         if(this.reader==null) {
  250.             return l; // non inizializzato
  251.         }
  252.         if(isObfuscatedModeEnabled()) {
  253.             String value = this.reader.getValue_convertEnvProperties(pName);
  254.             if(value!=null && StringUtils.isNotEmpty(value.trim())) {
  255.                 value = value.trim();
  256.                 if(value.contains(",")) {
  257.                     fillObfuscatedKeys(value, l);
  258.                 }
  259.                 else {
  260.                     l.add(value);
  261.                 }
  262.             }
  263.         }
  264.         return l;
  265.     }
  266.     private void fillObfuscatedKeys(String value, List<String> l) {
  267.         String [] tmp = value.split(",");
  268.         if(tmp!=null && tmp.length>0) {
  269.             for (String t : tmp) {
  270.                 if(t!=null && StringUtils.isNotEmpty(t.trim())) {
  271.                     l.add(t);
  272.                 }
  273.             }
  274.         }
  275.     }
  276.    
  277.     public boolean isObfuscatedModeEnabled() throws UtilsException {
  278.         if(this.reader==null) {
  279.             return false; // non inizializzato
  280.         }
  281.         String value = this.reader.getValue_convertEnvProperties(OBFUSCATED_MODE);
  282.         if(value!=null && StringUtils.isNotEmpty(value.trim())) {
  283.             value = value.trim();
  284.             if(OBFUSCATED_MODE_DIGEST.equals(value) || (OBFUSCATED_MODE_STATIC.equals(value))) {
  285.                  return true;
  286.             }
  287.             else if(OBFUSCATED_MODE_NONE.equals(value)) {
  288.                 return false;
  289.             }
  290.             else {
  291.                 throw new UtilsException("["+OBFUSCATED_MODE+"] unknown mode '"+value+"'");
  292.             }
  293.         }
  294.         else {
  295.             return true; // default
  296.         }
  297.     }
  298.    
  299.     public String getObfuscateModeDescription() throws UtilsException {
  300.         if(this.reader==null) {
  301.             return OBFUSCATED_MODE_NON_INIZIALIZZATO; // non inizializzato
  302.         }
  303.         String obfuscateMode = OBFUSCATED_MODE_NONE;
  304.         if(this.isObfuscatedModeStatic()) {
  305.             obfuscateMode = OBFUSCATED_MODE_STATIC+" ("+this.getObfuscatedModeStaticValue()+")";
  306.         }
  307.         else if(this.isObfuscatedModeDigest()) {
  308.             obfuscateMode = OBFUSCATED_MODE_DIGEST+" ("+this.getObfuscatedModeDigestAlgo()+")";
  309.         }
  310.         return obfuscateMode;
  311.     }  
  312.    
  313.     public boolean isObfuscatedModeStatic() throws UtilsException {
  314.         return getObfuscatedModeStaticValue()!=null;
  315.     }
  316.     public String getObfuscatedModeStaticValue() throws UtilsException {
  317.         if(this.reader==null) {
  318.             return null; // non inizializzato
  319.         }
  320.         String value = this.reader.getValue_convertEnvProperties(OBFUSCATED_MODE);
  321.         if(value!=null && StringUtils.isNotEmpty(value.trim())) {
  322.             value = value.trim();
  323.             if(OBFUSCATED_MODE_STATIC.equals(value)) {
  324.                 String s = this.reader.getValue_convertEnvProperties(OBFUSCATED_STATIC);
  325.                 if(s!=null && StringUtils.isNotEmpty(s.trim())) {
  326.                     return s.trim();
  327.                 }
  328.                 else {
  329.                     return OBFUSCATED_STATIC_DEFAULT; // default
  330.                 }
  331.             }
  332.             else if(OBFUSCATED_MODE_DIGEST.equals(value) || (OBFUSCATED_MODE_NONE.equals(value))) {
  333.                 return null;
  334.             }
  335.             else {
  336.                 throw new UtilsException("["+OBFUSCATED_MODE+"] unknown property value '"+value+"'");
  337.             }
  338.         }
  339.         else {
  340.             return null;
  341.         }
  342.     }
  343.    
  344.     public boolean isObfuscatedModeDigest() throws UtilsException {
  345.         return getObfuscatedModeDigestAlgo()!=null;
  346.     }
  347.     public String getObfuscatedModeDigestAlgo() throws UtilsException {
  348.         if(this.reader==null) {
  349.             return null; // non inizializzato
  350.         }
  351.         String value = this.reader.getValue_convertEnvProperties(OBFUSCATED_MODE);
  352.         if(value!=null && StringUtils.isNotEmpty(value.trim())) {
  353.             value = value.trim();
  354.             if(OBFUSCATED_MODE_DIGEST.equals(value)) {
  355.                 String s = this.reader.getValue_convertEnvProperties(OBFUSCATED_DIGEST);
  356.                 if(s!=null && StringUtils.isNotEmpty(s.trim())) {
  357.                     return s.trim();
  358.                 }
  359.                 else {
  360.                     return OBFUSCATED_DIGEST_DEFAULT; // default
  361.                 }
  362.             }
  363.             else if(OBFUSCATED_MODE_STATIC.equals(value) || (OBFUSCATED_MODE_NONE.equals(value))) {
  364.                 return null;
  365.             }
  366.             else {
  367.                 throw new UtilsException("["+OBFUSCATED_MODE+"] unknown property value '"+value+"'");
  368.             }
  369.         }
  370.         else {
  371.             return OBFUSCATED_DIGEST_DEFAULT; // default
  372.         }
  373.     }

  374.     protected boolean obfuscate(boolean java, String key) {
  375.         if(java || key!=null) {
  376.             // parametri forniti nel caso venga re-implementato il metodo
  377.         }
  378.         return true;
  379.     }
  380.    
  381.     public String obfuscateJavaProperty(String key, String value) throws UtilsException {
  382.         return obfuscate(true, key, value);
  383.     }
  384.     public String obfuscateEnvProperty(String key, String value) throws UtilsException {
  385.         return obfuscate(false, key, value);
  386.     }
  387.     protected String obfuscate(boolean java, String key, String value) throws UtilsException {
  388.         if(!this.obfuscate(java, key)) {
  389.             return value;
  390.         }
  391.         if(!isObfuscatedModeEnabled() || value==null || StringUtils.isEmpty(value)) {
  392.             return value;
  393.         }
  394.         if(this.isObfuscatedModeStatic()) {
  395.             return this.getObfuscatedModeStaticValue();
  396.         }
  397.         else if(this.isObfuscatedModeDigest()) {
  398.             try {
  399.                 return Base64Utilities.encodeAsString(MessageDigest.getInstance(this.getObfuscatedModeDigestAlgo()).digest(value.getBytes()));
  400.             }catch(Exception e) {
  401.                 throw new UtilsException(e.getMessage(),e);
  402.             }
  403.         }
  404.         else {
  405.             throw new UtilsException("["+OBFUSCATED_MODE+"] unsupported mode");
  406.         }
  407.     }
  408.    
  409.     public static String obfuscateByDigest(String value) throws UtilsException {
  410.         try {
  411.             return Base64Utilities.encodeAsString(MessageDigest.getInstance(OBFUSCATED_DIGEST_DEFAULT).digest(value.getBytes()));
  412.         }catch(Exception e) {
  413.             throw new UtilsException(e.getMessage(),e);
  414.         }
  415.     }
  416. }