/******************************************************************************* * Copyright 2017 Graz University of Technology * EAAF-Core Components has been developed in a cooperation between EGIZ, * A-SIT Plus, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by * the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. *******************************************************************************/ /******************************************************************************* *******************************************************************************/ /******************************************************************************* *******************************************************************************/ package at.gv.egiz.eaaf.core.impl.idp.conf; import java.net.URI; import java.net.URISyntaxException; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import javax.annotation.PostConstruct; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.CompositePropertySource; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.EnumerablePropertySource; import org.springframework.core.env.Environment; import org.springframework.core.env.PropertySource; import at.gv.egiz.eaaf.core.api.idp.IConfiguration; import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException; import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils; public abstract class AbstractSpringBootConfigurationImpl implements IConfiguration { private static final Logger log = LoggerFactory.getLogger(AbstractSpringBootConfigurationImpl.class); @Autowired private Environment env; public static final String PROP_CONFIG_ROOT_DIR = "core.configRootDir"; @PostConstruct private void initialize() throws EAAFConfigurationException { if (getConfigurationRootDirectory() == null) { throw new EAAFConfigurationException("config.08", new Object[] {addPrefixToKey(PROP_CONFIG_ROOT_DIR)}); } } @Override public String getBasicConfiguration(String key) { if (StringUtils.isNotEmpty(key)) { final String value = env.getProperty(addPrefixToKey(key)); if (value != null) return value.trim(); } return null; } @Override public String getBasicConfiguration(String key, String defaultValue) { if (StringUtils.isNotEmpty(key)) { final String value = env.getProperty(addPrefixToKey(key), defaultValue); if (value != null) return value.trim(); } return defaultValue; } @Override public Map getBasicConfigurationWithPrefix(String prefix) { final Map configProps = getPropertiesStartingWith((ConfigurableEnvironment) env, addPrefixToKey(prefix)); return KeyValueUtils.removePrefixFromKeys(configProps, addPrefixToKey(prefix) + "."); } @Override public Boolean getBasicConfigurationBoolean(String key) { final String value = getBasicConfiguration(key); if (StringUtils.isNotEmpty(value)) return Boolean.valueOf(value.trim()); else return null; } @Override public boolean getBasicConfigurationBoolean(String key, boolean defaultValue) { final Boolean value = getBasicConfigurationBoolean(key); if (value != null) return value; else return defaultValue; } @Override public URI getConfigurationRootDirectory() { try { return new URI(env.getRequiredProperty(addPrefixToKey(PROP_CONFIG_ROOT_DIR))); } catch (IllegalStateException | URISyntaxException e) { log.warn("ConfigRootDirectory is NOT set"); return null; } } /** * Get the path to backup configuration * * @return A filepath file: or a classpath classpath: */ abstract protected String getBackupConfigPath(); /** * Get a specific configuration-key prefix for this software implementation * * @return */ abstract public String getApplicationSpecificKeyPrefix(); private String addPrefixToKey(String key) { if (StringUtils.isNotEmpty(getApplicationSpecificKeyPrefix())) { if (getApplicationSpecificKeyPrefix().endsWith(KeyValueUtils.KEY_DELIMITER)) return getApplicationSpecificKeyPrefix() + key; else return getApplicationSpecificKeyPrefix() + KeyValueUtils.KEY_DELIMITER + key; } return key; } private static Map getPropertiesStartingWith( ConfigurableEnvironment aEnv, String aKeyPrefix ) { final Map result = new HashMap<>(); final Map map = getAllProperties(aEnv); for (final Entry entry : map.entrySet()) { final String key = entry.getKey(); if ( key.startsWith( aKeyPrefix ) ) { result.put( key, (String) entry.getValue() ); } } return result; } private static Map getAllProperties( ConfigurableEnvironment aEnv ) { final Map result = new HashMap<>(); aEnv.getPropertySources().forEach( ps -> addAll( result, getAllProperties( ps ) ) ); return result; } private static Map getAllProperties( PropertySource aPropSource ) { final Map result = new HashMap<>(); if ( aPropSource instanceof CompositePropertySource) { final CompositePropertySource cps = (CompositePropertySource) aPropSource; cps.getPropertySources().forEach( ps -> addAll( result, getAllProperties( ps ) ) ); return result; } if ( aPropSource instanceof EnumerablePropertySource ) { final EnumerablePropertySource ps = (EnumerablePropertySource) aPropSource; Arrays.asList( ps.getPropertyNames() ).forEach( key -> result.put( key, ps.getProperty( key ) ) ); return result; } // note: Most descendants of PropertySource are EnumerablePropertySource. There are some // few others like JndiPropertySource or StubPropertySource log.debug( "Given PropertySource is instanceof " + aPropSource.getClass().getName() + " and cannot be iterated" ); return result; } private static void addAll( Map aBase, Map aToBeAdded ) { for (final Entry entry : aToBeAdded.entrySet()) { if ( aBase.containsKey( entry.getKey() ) ) { continue; } aBase.put( entry.getKey(), entry.getValue() ); } } }