From f4bcfe76944585321bd239b48d6df25abe337cbb Mon Sep 17 00:00:00 2001 From: Thomas Lenz Date: Fri, 24 May 2019 08:20:01 +0200 Subject: update IConfiguration interfaces to support SpringBoot resources as configuration source --- .../impl/idp/conf/AbstractConfigurationImpl.java | 20 +- .../conf/AbstractSpringBootConfigurationImpl.java | 212 +++++++++++++++++++++ .../at/gv/egiz/eaaf/core/impl/utils/FileUtils.java | 26 +-- 3 files changed, 235 insertions(+), 23 deletions(-) create mode 100644 eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/conf/AbstractSpringBootConfigurationImpl.java (limited to 'eaaf_core/src/main') diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/conf/AbstractConfigurationImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/conf/AbstractConfigurationImpl.java index d20b33cc..af009b10 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/conf/AbstractConfigurationImpl.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/conf/AbstractConfigurationImpl.java @@ -39,11 +39,11 @@ import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import at.gv.egiz.eaaf.core.api.idp.IConfiguration; +import at.gv.egiz.eaaf.core.api.idp.IExtendedConfiguration; import at.gv.egiz.eaaf.core.exceptions.EAAFConfigurationException; import at.gv.egiz.eaaf.core.impl.utils.KeyValueUtils; -public abstract class AbstractConfigurationImpl implements IConfiguration { +public abstract class AbstractConfigurationImpl implements IExtendedConfiguration { private static final Logger log = LoggerFactory.getLogger(AbstractConfigurationImpl.class); private static final String URI_SCHEME_CLASSPATH = "classpath"; @@ -52,7 +52,7 @@ public abstract class AbstractConfigurationImpl implements IConfiguration { private final URI internalConfigPath; private final URI configRootDirectory; private final Properties properties; - + public AbstractConfigurationImpl(final String configPath) throws EAAFConfigurationException { InputStream is = null; try { @@ -60,7 +60,7 @@ public abstract class AbstractConfigurationImpl implements IConfiguration { if (StringUtils.isEmpty(configPath)) { log.debug("Primary configuration is empty. Search for backup configuration .... "); - String backupConfigPath = getBackupConfigPath(); + final String backupConfigPath = getBackupConfigPath(); if (StringUtils.isEmpty(backupConfigPath)) { log.error("No configuration file found."); throw new EAAFConfigurationException("config.01", null); @@ -77,14 +77,14 @@ public abstract class AbstractConfigurationImpl implements IConfiguration { //extract configuration root directory //TODO: check if it works with classpath - File propertiesFile = new File(internalConfigPath); + final File propertiesFile = new File(internalConfigPath); if (!propertiesFile.exists()) { log.error("Configuration file: " + internalConfigPath + " is NOT found on filesystem"); throw new EAAFConfigurationException("config.18", null); } - String configDir = propertiesFile.getParent(); + final String configDir = propertiesFile.getParent(); configRootDirectory = new File(configDir).toURI(); log.debug("Set EAAFCore configuration root directory to " + configRootDirectory.toString()); @@ -127,7 +127,7 @@ public abstract class AbstractConfigurationImpl implements IConfiguration { try { is.close(); - } catch (IOException e) { + } catch (final IOException e) { log.warn("Can not close inputstream from configuration loader!"); } @@ -139,7 +139,7 @@ public abstract class AbstractConfigurationImpl implements IConfiguration { @Override public String getBasicConfiguration(String key) { if (StringUtils.isNotEmpty(key)) { - String value = properties.getProperty(addPrefixToKey(key)); + final String value = properties.getProperty(addPrefixToKey(key)); if (value != null) return value.trim(); } @@ -150,7 +150,7 @@ public abstract class AbstractConfigurationImpl implements IConfiguration { @Override public String getBasicConfiguration(String key, String defaultValue) { if (StringUtils.isNotEmpty(key)) { - String value = properties.getProperty(addPrefixToKey(key), defaultValue); + final String value = properties.getProperty(addPrefixToKey(key), defaultValue); if (value != null) return value.trim(); } @@ -166,7 +166,7 @@ public abstract class AbstractConfigurationImpl implements IConfiguration { @Override public boolean getBasicMOAIDConfigurationBoolean(String key, boolean defaultValue) { - String value = getBasicConfiguration(key); + final String value = getBasicConfiguration(key); if (StringUtils.isNotEmpty(value)) return Boolean.valueOf(value.trim()); diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/conf/AbstractSpringBootConfigurationImpl.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/conf/AbstractSpringBootConfigurationImpl.java new file mode 100644 index 00000000..62245331 --- /dev/null +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/idp/conf/AbstractSpringBootConfigurationImpl.java @@ -0,0 +1,212 @@ +/******************************************************************************* + * 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 getBasicMOAIDConfigurationWithPrefix(String prefix) { + final Map configProps = getPropertiesStartingWith((ConfigurableEnvironment) env, addPrefixToKey(prefix)); + return KeyValueUtils.removePrefixFromKeys(configProps, addPrefixToKey(prefix) + "."); + + + } + + @Override + public boolean getBasicMOAIDConfigurationBoolean(String key, boolean defaultValue) { + final String value = getBasicConfiguration(key); + if (StringUtils.isNotEmpty(value)) + return Boolean.valueOf(value.trim()); + + 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() ); + } + } +} diff --git a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/FileUtils.java b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/FileUtils.java index 16b0d321..fff83e53 100644 --- a/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/FileUtils.java +++ b/eaaf_core/src/main/java/at/gv/egiz/eaaf/core/impl/utils/FileUtils.java @@ -54,9 +54,9 @@ public class FileUtils { * @throws IOException on any exception thrown */ public static byte[] readURL(String urlString) throws IOException { - URL url = new URL(urlString); - InputStream in = new BufferedInputStream(url.openStream()); - byte[] content = StreamUtils.readStream(in); + final URL url = new URL(urlString); + final InputStream in = new BufferedInputStream(url.openStream()); + final byte[] content = StreamUtils.readStream(in); in.close(); return content; } @@ -68,9 +68,9 @@ public class FileUtils { * @throws IOException on any exception thrown */ public static byte[] readResource(String name) throws IOException { - ClassLoader cl = FileUtils.class.getClassLoader(); - BufferedInputStream in = new BufferedInputStream(cl.getResourceAsStream(name)); - byte[] content = StreamUtils.readStream(in); + final ClassLoader cl = FileUtils.class.getClassLoader(); + final BufferedInputStream in = new BufferedInputStream(cl.getResourceAsStream(name)); + final byte[] content = StreamUtils.readStream(in); in.close(); return content; } @@ -82,7 +82,7 @@ public class FileUtils { * @throws IOException on any exception thrown */ public static String readResource(String name, String encoding) throws IOException { - byte[] content = readResource(name); + final byte[] content = readResource(name); return new String(content, encoding); } @@ -121,7 +121,7 @@ public class FileUtils { if(null == url) return null; - if (url.startsWith("http:/") || url.startsWith("https:/") || url.startsWith("file:/") || url.startsWith("ftp:/")) { + if (url.startsWith("http:") || url.startsWith("https:") || url.startsWith("file:") || url.startsWith("ftp:")) { return url; } else { @@ -146,18 +146,18 @@ public class FileUtils { { try { - byte[] buffer = new byte[ 0xFFFF ]; + final byte[] buffer = new byte[ 0xFFFF ]; for ( int len; (len = fis.read(buffer)) != -1; ) fos.write( buffer, 0, len ); } - catch( IOException e ) { + catch( final IOException e ) { System.err.println( e ); } finally { if ( fis != null ) - try { fis.close(); } catch ( IOException e ) { e.printStackTrace(); } + try { fis.close(); } catch ( final IOException e ) { e.printStackTrace(); } if ( fos != null ) - try { fos.close(); } catch ( IOException e ) { e.printStackTrace(); } + try { fos.close(); } catch ( final IOException e ) { e.printStackTrace(); } } } @@ -167,7 +167,7 @@ public class FileUtils { { copy( new FileInputStream( src ), new FileOutputStream( dest ) ); } - catch( IOException e ) { + catch( final IOException e ) { e.printStackTrace(); } } -- cgit v1.2.3