From b8f480d11472d83603030ab765df424814d536cb Mon Sep 17 00:00:00 2001 From: Mark Struberg Date: Fri, 10 Mar 2017 00:14:04 +0100 Subject: [PATCH 1/8] adopt to microprofile API + fix a few things --- api/pom.xml | 43 ---- .../java/io/microprofile/config/Config.java | 87 -------- .../microprofile/config/ConfigProvider.java | 198 ------------------ .../io/microprofile/config/ConfigValue.java | 139 ------------ .../microprofile/config/spi/ConfigSource.java | 99 --------- .../config/spi/ConfigSourceProvider.java | 46 ---- .../io/microprofile/config/spi/Converter.java | 51 ----- impl/pom.xml | 12 +- .../apache/geronimo/config/ConfigImpl.java | 36 ++-- .../geronimo/config/ConfigValueImpl.java | 133 ++++++------ .../geronimo/config/DefaultConfigBuilder.java | 36 ++-- .../config/DefaultConfigProvider.java | 20 +- .../ManualApplicationConfigBuilder.java | 6 +- .../config/configsource/BaseConfigSource.java | 7 +- .../PropertyFileConfigSource.java | 6 +- .../PropertyFileConfigSourceProvider.java | 4 +- .../configsource/SystemEnvConfigSource.java | 6 +- .../SystemPropertyConfigSource.java | 6 +- .../config/converters/BooleanConverter.java | 2 +- .../config/converters/DoubleConverter.java | 2 +- .../config/converters/FloatConverter.java | 2 +- .../config/converters/IntegerConverter.java | 2 +- .../config/converters/LongConverter.java | 2 +- ...profile.config.spi.ConfigProviderResolver} | 0 impl/tck-suite.xml | 2 +- pom.xml | 7 +- spec/pom.xml | 98 --------- spec/src/main/asciidoc/architecture.asciidoc | 51 ----- .../src/main/asciidoc/configexamples.asciidoc | 92 -------- .../src/main/asciidoc/configprovider.asciidoc | 57 ----- spec/src/main/asciidoc/configsources.asciidoc | 137 ------------ spec/src/main/asciidoc/converters.asciidoc | 48 ----- spec/src/main/asciidoc/license-alv2.asciidoc | 44 ---- .../microprofile-config-spec.asciidoc | 46 ---- tck/pom.xml | 55 ----- .../config/tck/ConfigProviderTest.java | 148 ------------- .../config/tck/ConfigSourceProviderTest.java | 35 ---- .../config/tck/ConfigValueTest.java | 132 ------------ .../config/tck/ConverterTest.java | 46 ---- .../config/tck/CustomConfigSourceTest.java | 35 ---- .../CustomConfigSourceProvider.java | 47 ----- .../configsources/CustomDbConfigSource.java | 63 ------ .../configsources/SampleYamlConfigSource.java | 55 ----- .../config/tck/converters/Duck.java | 33 --- .../config/tck/converters/DuckConverter.java | 30 --- .../resources/META-INF/java-config.properties | 73 ------- .../io.microprofile.config.spi.ConfigSource | 20 -- ...croprofile.config.spi.ConfigSourceProvider | 20 -- tck/src/main/resources/sampleconfig.yaml | 20 -- 49 files changed, 151 insertions(+), 2188 deletions(-) delete mode 100644 api/pom.xml delete mode 100644 api/src/main/java/io/microprofile/config/Config.java delete mode 100644 api/src/main/java/io/microprofile/config/ConfigProvider.java delete mode 100644 api/src/main/java/io/microprofile/config/ConfigValue.java delete mode 100644 api/src/main/java/io/microprofile/config/spi/ConfigSource.java delete mode 100644 api/src/main/java/io/microprofile/config/spi/ConfigSourceProvider.java delete mode 100644 api/src/main/java/io/microprofile/config/spi/Converter.java rename impl/src/main/resources/META-INF/services/{io.microprofile.config.ConfigProvider$SPI => org.eclipse.microprofile.config.spi.ConfigProviderResolver} (100%) delete mode 100644 spec/pom.xml delete mode 100644 spec/src/main/asciidoc/architecture.asciidoc delete mode 100644 spec/src/main/asciidoc/configexamples.asciidoc delete mode 100644 spec/src/main/asciidoc/configprovider.asciidoc delete mode 100644 spec/src/main/asciidoc/configsources.asciidoc delete mode 100644 spec/src/main/asciidoc/converters.asciidoc delete mode 100644 spec/src/main/asciidoc/license-alv2.asciidoc delete mode 100644 spec/src/main/asciidoc/microprofile-config-spec.asciidoc delete mode 100644 tck/pom.xml delete mode 100644 tck/src/main/java/io/microprofile/config/tck/ConfigProviderTest.java delete mode 100644 tck/src/main/java/io/microprofile/config/tck/ConfigSourceProviderTest.java delete mode 100644 tck/src/main/java/io/microprofile/config/tck/ConfigValueTest.java delete mode 100644 tck/src/main/java/io/microprofile/config/tck/ConverterTest.java delete mode 100644 tck/src/main/java/io/microprofile/config/tck/CustomConfigSourceTest.java delete mode 100644 tck/src/main/java/io/microprofile/config/tck/configsources/CustomConfigSourceProvider.java delete mode 100644 tck/src/main/java/io/microprofile/config/tck/configsources/CustomDbConfigSource.java delete mode 100644 tck/src/main/java/io/microprofile/config/tck/configsources/SampleYamlConfigSource.java delete mode 100644 tck/src/main/java/io/microprofile/config/tck/converters/Duck.java delete mode 100644 tck/src/main/java/io/microprofile/config/tck/converters/DuckConverter.java delete mode 100644 tck/src/main/resources/META-INF/java-config.properties delete mode 100644 tck/src/main/resources/META-INF/services/io.microprofile.config.spi.ConfigSource delete mode 100644 tck/src/main/resources/META-INF/services/io.microprofile.config.spi.ConfigSourceProvider delete mode 100644 tck/src/main/resources/sampleconfig.yaml diff --git a/api/pom.xml b/api/pom.xml deleted file mode 100644 index 3a68c25..0000000 --- a/api/pom.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - 4.0.0 - - - - org.apache.geronimo.config - config-parent - 0.1-SNAPSHOT - - - org.apache.geronimo.config - config-api - - - - Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0.txt - repo - A business-friendly OSS license - - - - - diff --git a/api/src/main/java/io/microprofile/config/Config.java b/api/src/main/java/io/microprofile/config/Config.java deleted file mode 100644 index 76e2e55..0000000 --- a/api/src/main/java/io/microprofile/config/Config.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * See the NOTICE file distributed with this work for additional information - * regarding copyright ownership. - * The author licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.microprofile.config; - -import java.util.Map; - -import io.microprofile.config.spi.ConfigSourceProvider; -import io.microprofile.config.spi.Converter; -import io.microprofile.config.spi.ConfigSource; - -/** - *

Resolves configured values of properties by going through the list - * of configured {@link ConfigSource}s and using the one with the highest ordinal. - * If multiple {@link ConfigSource}s have the same ordinal, their order is undefined.

- * - *

You can provide your own lookup paths by implementing and registering additional - * {@link ConfigSource}s and {@link ConfigSourceProvider} implementations.

- * - * - * @see ConfigProvider to resolve the current configuration. - * - * @author Mark Struberg - */ -public interface Config { - - /** - * Create a {@link ConfigValue} to access the underlying configuration. - * - * @param key the property key - */ - ConfigValue access(String key); - - /** - * Resolves the value configured for the given key. - * - * @param key the property key - * - * @return the configured property value from the {@link ConfigSource} with the highest ordinal - * or {@code null} if there is no configured value for it - */ - String getValue(String key); - - /** - * Resolves the value configured for the given key and convert it to the required asType. - * - * @param key - * @param asType Also support parameterized Types? - * @param - * @return - * @throws UnsupportedOperationException if there is no {@link Converter} registered for asType - */ - T getValue(String key, Class asType); - - /** - * Apply the - * @return the String converted - * @throws UnsupportedOperationException if there is no {@link Converter} registered for asType - */ - T convert(String value, Class asType); - - /** - * Returns a Map of all properties from all scannable config sources. The values of the properties reflect the - * values that would be obtained by a call to {@link #getValue(java.lang.String)}, that is, the value of the - * property from the ConfigSource with the highest ordinal. - */ - Map getAllProperties(); - - /** - * @return all currently registered {@link ConfigSource}s - */ - ConfigSource[] getConfigSources(); - -} diff --git a/api/src/main/java/io/microprofile/config/ConfigProvider.java b/api/src/main/java/io/microprofile/config/ConfigProvider.java deleted file mode 100644 index ae0f690..0000000 --- a/api/src/main/java/io/microprofile/config/ConfigProvider.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * See the NOTICE file distributed with this work for additional information - * regarding copyright ownership. - * The author licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.microprofile.config; - -import java.util.ServiceLoader; -import java.util.logging.Logger; - -import io.microprofile.config.spi.ConfigSource; -import io.microprofile.config.spi.Converter; - -/** - *

This is the central class to access a {@link Config}.

- * - *

A {@link Config} contains the configuration for a certain - * situation. That might be the configuration found in a certain ClassLoader - * or even a manually created Configuration

- * - *

The default usage is to use {@link #getConfig()} to automatically - * pick up the 'Configuration' for the Thread Context ClassLoader - * (See {@link Thread#getContextClassLoader()}).

- * - *

A 'Configuration' consists of the information collected from the registered - * {@link ConfigSource}s. These {@link ConfigSource}s - * get sorted according to their ordinal defined via {@link ConfigSource#getOrdinal()}. - * That way it is possible to overwrite configuration with lower importance from outside.

- * - *

It is also possible to register custom {@link ConfigSource}s to - * flexibly extend the configuration mechanism. An example would be to pick up configuration values - * from a database table./p> - * - *

Example usage: - * - *

- *     String restUrl = ConfigProvider.getConfig().getValue("myproject.some.remote.service.url");
- *     Integer port = ConfigProvider.getConfig().getValue("myproject.some.remote.service.port", Integer.class);
- * 
- * - *

- * - * @author Mark Struberg - * @author Romain Manni-Bucau - */ -public class ConfigProvider { - - private static volatile SPI instance; - - /** - * Provide a {@link Config} based on all {@link ConfigSource}s - * of the current Thread Context ClassLoader (TCCL) - * - *

There is exactly a single Config instance per Application

- */ - public static Config getConfig() { - return loadSpi().getConfig(); - } - - /** - * Provide a {@link Config} based on all {@link ConfigSource}s - * of the given ClassLoader. - * - *

There is exactly a single Config instance per Application. The Application get's identified via a ClassLoader

- */ - public static Config getConfig(ClassLoader forClassLoader) { - return instance.getConfig(forClassLoader); - } - - /** - * Create a {@link ConfigBuilder} for providing a fresh {@link Config} instance. - * - * The ConfigProvider will not manage the Config instance internally. - * That means that {@link #getConfig()} does not pick up a Config created that way. - */ - public static ConfigBuilder newConfig() { - return instance.newConfig(); - } - - /** - * Create a {@link ConfigBuilder} for register a {@link Config} instance to a certain Application. - * Invoking {@link ConfigBuilder#build()} will effectively register the Config. - * Use {@link ConfigBuilder#forClassLoader(ClassLoader)} to define the application the Config should be for, - * otherwise the current ThreadContextClassLoader will be used. - * - * A {@link Config} registered that way will get picked up on any subsequent call to {@link ConfigProvider#getConfig()}. - * - * @throws IllegalStateException if a {@link Config} has already been associated for the Application. - */ - public static ConfigBuilder registerConfig() { - return instance.registerConfig(); - } - - - /** - * A {@link Config} normally gets released if the ClassLoader it represents gets destroyed. - * Invoke this method if you like to destroy the Config prematurely. - */ - public static void releaseConfig(Config config) { - instance.releaseConfig(config); - } - - - /** - * Builder for manually creating an instance of a {@code Config}. - * - * @see ConfigProvider#newConfig() - */ - public interface ConfigBuilder { - ConfigBuilder ignoreDefaultSources(); - ConfigBuilder forClassLoader(ClassLoader loader); - ConfigBuilder withSources(ConfigSource... sources); - ConfigBuilder withConverters(Converter... filters); - Config build(); - } - - /** - * This interface gets implemented internally by the Config library. - * The implementation registers itself via {@link java.util.ServiceLoader} mechanism. - * In an OSGi environment - */ - public interface SPI { - Config getConfig(); - Config getConfig(ClassLoader forClassLoader); - ConfigBuilder newConfig(); - ConfigBuilder registerConfig(); - void releaseConfig(Config config); - } - - /** - * Attention, handle with care! - * This method is not intended to be used from a user. - * It is for integration with e.g. OSGi from within a BundleActivator. - * TODO probably remove this and add native OSGi support later. - */ - public static synchronized void setSPI(SPI newInstance) { - instance = newInstance; - } - - private static SPI loadSpi() { - if (instance == null) { - synchronized (SPI.class) { - if (instance != null) { - return instance; - } - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if (cl == null) { - cl = SPI.class.getClassLoader(); - } - - SPI newInstance = loadSpi(cl); - - if (newInstance == null) { - throw new IllegalStateException("No ConfigResolver SPI implementation found!"); - } - - instance = newInstance; - } - } - - return instance; - } - - private static SPI loadSpi(ClassLoader cl) { - if (cl == null) { - return null; - } - - // start from the root CL and go back down to the TCCL - SPI instance = loadSpi(cl.getParent()); - - if (instance == null) { - ServiceLoader sl = ServiceLoader.load(SPI.class, cl); - for (SPI spi : sl) { - if (instance != null) { - Logger.getLogger(ConfigProvider.class.getName()) - .warning("Multiple ConfigResolver SPIs found. Ignoring " + spi.getClass().getName()); - } else { - instance = spi; - } - } - } - return instance; - } - - -} diff --git a/api/src/main/java/io/microprofile/config/ConfigValue.java b/api/src/main/java/io/microprofile/config/ConfigValue.java deleted file mode 100644 index d93b95b..0000000 --- a/api/src/main/java/io/microprofile/config/ConfigValue.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * See the NOTICE file distributed with this work for additional information - * regarding copyright ownership. - * The author licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.microprofile.config; - - -import java.util.concurrent.TimeUnit; - -/** - * Accessor to a configured value. - * It follows a builder pattern. - * - * Accessing the configured value is finally done via {@link #getValue()} - * - * @author Mark Struberg - * @author Gerhard Petracek - * @author Ron Smeral - */ -public interface ConfigValue { - - /** - * Sets the type of the configuration entry to the given class and returns this builder. - * The default type of a ConfigValue is {@code String}. - * - * @param clazz The target type - * @param The target type - * @return This builder as a typed ConfigValue - */ - ConfigValue as(Class clazz); - - /** - * Sets the default value to use in case the resolution returns null. - * @param value the default value - * @return This builder - */ - ConfigValue withDefault(T value); - - /** - * Sets the default value to use in case the resolution returns null. Converts the given String to the type of - * this resolver using the same method as used for the configuration entries. - * @param value string value to be converted and used as default - * @return This builder - */ - ConfigValue withStringDefault(String value); - - /** - * Specify that a resolved value will get cached for a certain amount of time. - * After the time expires the next {@link #getValue()} will again resolve the value - * from the underlying {@link Config}. - * - * @param value the amount of the TimeUnit to wait - * @param timeUnit the TimeUnit for the value - * - * @return This builder - */ - ConfigValue cacheFor(long value, TimeUnit timeUnit); - - /** - * Whether to evaluate variables in configured values. - * A variable starts with '${' and ends with '}', e.g. - *
-     * mycompany.some.url=${myserver.host}/some/path
-     * myserver.host=http://localhost:8081
-     * 
- * If 'evaluateVariables' is enabled, the result for the above key - * {@code "mycompany.some.url"} would be: - * {@code "http://localhost:8081/some/path"} - * @param evaluateVariables whether to evaluate variables in values or not - * @return This builder - */ - ConfigValue evaluateVariables(boolean evaluateVariables); - - /** - * Appends the resolved value of the given property to the key of this builder. - * TODO further explain. - * @return This builder - */ - ConfigValue withLookupChain(String... postfixNames); - - /** - * Whether to log picking up any value changes as INFO. - * - * @return This builder - */ - ConfigValue logChanges(boolean logChanges); - - /** - * Returns the converted resolved filtered value. - * @return the resolved value - */ - T getValue(); - - /** - * Resolves the value and split it on each comma (',') character. - * If a comma is contained in the values it must get escaped with a preceding backslash ("\,"). - * Any backslash needs to get escaped via double-backslash ("\\"). - * - * @return the list of configured comma separated values or an empty Iterable if no - */ - Iterable getValueList(); - - /** - * Returns the key given in {@link Config#access(String)}. - * @return the original key - */ - String getKey(); - - /** - * Returns the actual key which led to successful resolution and corresponds to the resolved value. This applies - * only when {@link #withLookupChain(String...)} is used. - * Otherwise the resolved key should always be equal to the original key. - * This method is provided for cases, when arameterized resolution is - * requested but the value for such appended key is not found and some of the fallback keys is used. - * - * This should be called only after calling {@link #getValue()} otherwise the value is undefined (but likely - * null). - */ - String getResolvedKey(); - - /** - * Returns the default value provided by {@link #withDefault(Object)} or {@link #withStringDefault(String)}. - * Returns null if no default was provided. - * @return the default value or {@code null} - */ - T getDefaultValue(); -} diff --git a/api/src/main/java/io/microprofile/config/spi/ConfigSource.java b/api/src/main/java/io/microprofile/config/spi/ConfigSource.java deleted file mode 100644 index 6340aea..0000000 --- a/api/src/main/java/io/microprofile/config/spi/ConfigSource.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * See the NOTICE file distributed with this work for additional information - * regarding copyright ownership. - * The author licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.microprofile.config.spi; - -import java.util.Map; - -/** - *

Implement this interfaces to provide a ConfigSource. - * A ConfigSource provides properties from a specific place, like - * JNDI configuration, a properties file, etc. - * A ConfigSource is always read-only, any potential updates of the - * configured values must be handled directly inside each ConfigSource.

- * - *

The custom implementation can be 'registered' using a - * {@link ConfigSourceProvider} or via the - * {@link java.util.ServiceLoader} mechanism. In the later case - * it must get registered via creating a - * META-INF/services/javax.config.spi.ConfigSource - * file and adding the fully qualified class name of your ConfigSource - * implementation into it.

- * - * @author Mark Struberg - * @author Gerhard Petracek - */ -public interface ConfigSource { - /** - * The default name for the ordinal field. - * Any ConfigSource might use it's own though or even return a hardcoded - * in {@link #getOrdinal()}. - */ - String CONFIG_ORDINAL = "config_ordinal"; - - - /** - * Lookup order: - * - *
    - *
  1. System properties (ordinal 400)
  2. - *
  3. Environment properties (ordinal 300)
  4. - *
  5. JNDI values (ordinal 200)
  6. - *
  7. Properties file values (/META-INF/java-config.properties) (ordinal 100)
  8. - *
- *

- *

Important Hints for custom implementations:

- *

- * If a custom implementation should be invoked before the default implementations, use a value > 400 - *

- *

- * If a custom implementation should be invoked after the default implementations, use a value < 100 - *

- *

- * - * - *

- *

- *

Reordering of the default order of the config-sources:

- *

Example: If the properties file/s should be used before the other implementations, - * you have to configure an ordinal > 400. That means, you have to add e.g. config_ordinal=401 to - * /META-INF/java-config.properties . Hint: In case of property files every file is handled as independent - * config-source, but all of them have ordinal 400 by default (and can be reordered in a fine-grained manner.

- * - * @return the 'importance' aka ordinal of the configured values. The higher, the more important. - */ - int getOrdinal(); - - /** - * Return properties contained in this config source. - * @return Properties available in this config source. - */ - Map getProperties(); - - /** - * @param key for the property - * @return configured value or null if this ConfigSource doesn't provide any value for the given key. - */ - String getPropertyValue(String key); - - /** - * The name of the config might be used for logging or analysis of configured values. - * - * @return the 'name' of the configuration source, e.g. 'property-file mylocation/myproperty.properties' - */ - String getConfigName(); - -} diff --git a/api/src/main/java/io/microprofile/config/spi/ConfigSourceProvider.java b/api/src/main/java/io/microprofile/config/spi/ConfigSourceProvider.java deleted file mode 100644 index ca4e04c..0000000 --- a/api/src/main/java/io/microprofile/config/spi/ConfigSourceProvider.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * See the NOTICE file distributed with this work for additional information - * regarding copyright ownership. - * The author licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package io.microprofile.config.spi; - -import java.util.List; - -/** - *

Implement this interfaces to provide a ConfigSource provider which - * is able to maintain multiple ConfigSources. This is e.g. needed if - * there are multiple property files of a given name.

- * - *

If a ConfigSource like JNDI only exists once, then there is no need - * to implement it via the ConfigSourceProvider but should directly - * expose a {@link ConfigSource}.

- * - *

A ConfigSourceProvider will get picked up via the - * {@link java.util.ServiceLoader} mechanism and must get registered via - * META-INF/services/javax.config.spi.ConfigSourceProvider

- * - * @author Mark Struberg - */ -public interface ConfigSourceProvider -{ - - /** - * @param forClassLoader the classloader which should be used if any is needed - * - * @return For each e.g. property file, we return a single ConfigSource or an empty list if no ConfigSource exists. - */ - List getConfigSources(ClassLoader forClassLoader); -} diff --git a/api/src/main/java/io/microprofile/config/spi/Converter.java b/api/src/main/java/io/microprofile/config/spi/Converter.java deleted file mode 100644 index b6565b5..0000000 --- a/api/src/main/java/io/microprofile/config/spi/Converter.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * See the NOTICE file distributed with this work for additional information - * regarding copyright ownership. - * The author licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package io.microprofile.config.spi; - -/** - *

A very simple interface for conversion of configuration values from String to any Java type.

- * - *

A Converter can specify a {@link javax.annotation.Priority}. - * If no priority is explicitly assigned, the value of 100 is assumed.

- * - *

If multiple Converter get found the one with the highest priority will be used.

- * - *

The Converter for the following types are automatically enabled: - *

    - *
  • Boolean, values for {@code true}: (case insensitive) "true", "1", "YES", "Y" "JA" "J", "OUI"
  • - *
  • Integer
  • - *
  • Long
  • - *
  • Float, a dot '.' is used to separate the fractional digits
  • - *
  • Double, a dot '.' is used to separate the fractional digits - *
- * - *

- * - * @author Mark Struberg - * @author Ron Smeral - * @author Gerhard Petracek - */ -public interface Converter { - /** - * Returns the converted value of the configuration entry. - * @param value The String property value to convert - * @return Converted value - */ - T convert(String value); - -} diff --git a/impl/pom.xml b/impl/pom.xml index 69d8a7c..618a423 100644 --- a/impl/pom.xml +++ b/impl/pom.xml @@ -32,15 +32,15 @@ - org.apache.geronimo.config - config-api - 0.1-SNAPSHOT + org.eclipse.microprofile.config.api + microprofile-config-api + 1.0-SNAPSHOT - org.apache.geronimo.config - config-tck - 0.1-SNAPSHOT + org.eclipse.microprofile.config.tck + microprofile-config-tck + 1.0-SNAPSHOT test diff --git a/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java b/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java index a9feb00..89bf067 100644 --- a/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java +++ b/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java @@ -23,15 +23,18 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; -import io.microprofile.config.Config; -import io.microprofile.config.ConfigValue; -import io.microprofile.config.spi.ConfigSource; -import io.microprofile.config.spi.Converter; +import org.eclipse.microprofile.config.Config; +import org.eclipse.microprofile.config.ConfigValue; +import org.eclipse.microprofile.config.spi.ConfigSource; +import org.eclipse.microprofile.config.spi.Converter; import org.apache.geronimo.config.converters.BooleanConverter; import org.apache.geronimo.config.converters.DoubleConverter; import org.apache.geronimo.config.converters.FloatConverter; @@ -63,14 +66,18 @@ private void registerDefaultConverter() { } @Override + public Optional getString(String key) { + return Optional.ofNullable(getValue(key)); + } + public String getValue(String key) { for (ConfigSource configSource : configSources) { - String value = configSource.getPropertyValue(key); + String value = configSource.getValue(key); if (value != null) { if (logger.isLoggable(Level.FINE)) { logger.log(Level.FINE, "found value {0} for key {1} in ConfigSource {2}.", - new Object[]{value, key, configSource.getConfigName()}); + new Object[]{value, key, configSource.getName()}); } return value; @@ -80,12 +87,11 @@ public String getValue(String key) { } @Override - public T getValue(String key, Class asType) { + public Optional getValue(String key, Class asType) { String value = getValue(key); - return convert(value, asType); + return Optional.ofNullable(convert(value, asType)); } - @Override public T convert(String value, Class asType) { Converter converter = getConverter(asType); if (value != null) { @@ -104,22 +110,22 @@ private Converter getConverter(Class asType) { } public ConfigValue access(String key) { - return new ConfigValueImpl<>(this, key); + return new ConfigValueImpl(this, key); } @Override - public Map getAllProperties() { - Map result = new HashMap(); + public Iterable getPropertyNames() { + Set result = new HashSet<>(); for (int i = configSources.length; i > 0; i--) { ConfigSource configSource = configSources[i]; - result.putAll(configSource.getProperties()); + result.addAll(configSource.getProperties().keySet()); } - - return Collections.unmodifiableMap(result); + return result; } + @Override public ConfigSource[] getConfigSources() { return configSources; diff --git a/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java b/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java index b552493..90f8884 100644 --- a/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java +++ b/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java @@ -16,17 +16,20 @@ */ package org.apache.geronimo.config; -import io.microprofile.config.ConfigValue; -import io.microprofile.config.spi.Converter; +import org.eclipse.microprofile.config.ConfigValue; +import org.eclipse.microprofile.config.spi.Converter; +import java.util.ArrayList; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; import java.util.concurrent.TimeUnit; -import java.util.logging.Level; import java.util.logging.Logger; /** * @author Mark Struberg */ -public class ConfigValueImpl implements ConfigValue { +public class ConfigValueImpl implements ConfigValue { private static final Logger logger = Logger.getLogger(ConfigValueImpl.class.getName()); private final ConfigImpl config; @@ -39,19 +42,12 @@ public class ConfigValueImpl implements ConfigValue { private String[] lookupChain; - private boolean withDefault = false; - private T defaultValue; - - - private Converter converter; - private boolean evaluateVariables = false; - private boolean logChanges = false; - private long cacheTimeMs = -1; private volatile long reloadAfter = -1; private T lastValue = null; + private ConfigChanged valueChangeListener; public ConfigValueImpl(ConfigImpl config, String key) { this.config = config; @@ -61,29 +57,9 @@ public ConfigValueImpl(ConfigImpl config, String key) { @Override public ConfigValue as(Class clazz) { configEntryType = clazz; - this.converter = null; return (ConfigValue) this; } - @Override - public ConfigValue withDefault(T value) { - defaultValue = value; - withDefault = true; - return this; - } - - @Override - public ConfigValue withStringDefault(String value) { - if (value == null || value.isEmpty()) - { - throw new RuntimeException("Empty String or null supplied as string-default value for property " - + keyOriginal); - } - - defaultValue = convert(value); - withDefault = true; - return this; - } @Override public ConfigValue cacheFor(long value, TimeUnit timeUnit) { @@ -97,20 +73,76 @@ public ConfigValue evaluateVariables(boolean evaluateVariables) { return this; } - @Override public ConfigValue withLookupChain(String... postfixNames) { this.lookupChain = postfixNames; return this; } @Override - public ConfigValue logChanges(boolean logChanges) { - this.logChanges = logChanges; + public T get() { + T val = getValue(); + if (val == null) { + throw new NoSuchElementException("No config value present for key " + keyOriginal); + } + return val; + } + + @Override + public Optional getOptional() { + return Optional.ofNullable(getValue()); + } + + @Override + public ConfigValue onChange(ConfigChanged valueChangeListener) { + this.valueChangeListener = valueChangeListener; return this; } @Override + public List getValueList() { + String rawList = (String) getValue(false); + List values = new ArrayList(); + StringBuilder sb = new StringBuilder(64); + for (int i= 0; i < rawList.length(); i++) { + char c = rawList.charAt(i); + if ('\\' == c) { + if (i == rawList.length()) { + throw new IllegalStateException("incorrect escaping of key " + keyOriginal + " value: " + rawList); + } + char nextChar = rawList.charAt(i+1); + if (nextChar == '\\') { + sb.append('\\'); + } + else if (nextChar == ',') { + sb.append(','); + } + i++; + } + else if (',' == c) { + addListValue(values, sb); + } + else { + sb.append(c); + } + } + addListValue(values, sb); + + return values; + } + + private void addListValue(List values, StringBuilder sb) { + String val = sb.toString().trim(); + if (!val.isEmpty()) { + values.add(convert(val)); + } + sb.setLength(0); + } + public T getValue() { + return getValue(true); + } + + private T getValue(boolean convert) { long now = -1; if (cacheTimeMs > 0) { @@ -122,17 +154,11 @@ public T getValue() { } String valueStr = resolveStringValue(); - T value = convert(valueStr); + T value = convert ? convert(valueStr) : (T) valueStr; - if (withDefault) + if (valueChangeListener != null && (value != null && !value.equals(lastValue) || (value == null && lastValue != null)) ) { - value = fallbackToDefaultIfEmpty(keyResolved, value, defaultValue); - } - - if (logChanges && (value != null && !value.equals(lastValue) || (value == null && lastValue != null)) ) - { - logger.log(Level.INFO, "New value {0} for key {1}.", - new Object[]{valueStr, keyOriginal}); + valueChangeListener.onValueChange(keyOriginal, lastValue, value); } lastValue = value; @@ -165,7 +191,7 @@ private String resolveStringValue() { { break; } - String variableValue = config.access(varName).evaluateVariables(true).withLookupChain(lookupChain).getValue(); + String variableValue = config.access(varName).evaluateVariables(true).get(); if (variableValue != null) { value = value.replace("${" + varName + "}", variableValue); @@ -186,11 +212,6 @@ public String getResolvedKey() { return keyResolved; } - @Override - public T getDefaultValue() { - return defaultValue; - } - private T convert(String value) { if (String.class == configEntryType) { return (T) value; @@ -204,16 +225,4 @@ private T convert(String value) { return (T) converter.convert(value); } - private T fallbackToDefaultIfEmpty(String key, T value, T defaultValue) { - if (value == null || (value instanceof String && ((String)value).isEmpty())) - { - logger.log(Level.FINE, "no configured value found for key {0}, using default value {1}.", - new Object[]{key, defaultValue}); - - return defaultValue; - } - - return value; - } - } diff --git a/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java b/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java index 2d504d3..49fbad0 100644 --- a/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java +++ b/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java @@ -16,11 +16,11 @@ */ package org.apache.geronimo.config; -import io.microprofile.config.Config; -import io.microprofile.config.ConfigProvider; -import io.microprofile.config.spi.ConfigSource; -import io.microprofile.config.spi.ConfigSourceProvider; -import io.microprofile.config.spi.Converter; +import org.eclipse.microprofile.config.Config; +import org.eclipse.microprofile.config.spi.ConfigBuilder; +import org.eclipse.microprofile.config.spi.ConfigSource; +import org.eclipse.microprofile.config.spi.ConfigSourceProvider; +import org.eclipse.microprofile.config.spi.Converter; import org.apache.geronimo.config.configsource.PropertyFileConfigSourceProvider; import org.apache.geronimo.config.configsource.SystemEnvConfigSource; import org.apache.geronimo.config.configsource.SystemPropertyConfigSource; @@ -36,32 +36,32 @@ * @author Romain Manni-Bucau * @author Mark Struberg */ -public class DefaultConfigBuilder implements ConfigProvider.ConfigBuilder { +public class DefaultConfigBuilder implements ConfigBuilder { protected ClassLoader forClassLoader; private final List sources = new ArrayList<>(); private final List> converters = new ArrayList<>(); - private boolean ignoreDefaultSources = false; + private boolean ignoreDefaultSources = true; @Override - public ConfigProvider.ConfigBuilder ignoreDefaultSources() { - this.ignoreDefaultSources = true; + public ConfigBuilder addDefaultSources() { + this.ignoreDefaultSources = false; return this; } @Override - public ConfigProvider.ConfigBuilder forClassLoader(final ClassLoader loader) { + public ConfigBuilder forClassLoader(final ClassLoader loader) { this.forClassLoader = loader; return this; } @Override - public ConfigProvider.ConfigBuilder withSources(final ConfigSource... sources) { + public ConfigBuilder withSources(final ConfigSource... sources) { this.sources.addAll(asList(sources)); return this; } @Override - public ConfigProvider.ConfigBuilder withConverters(Converter... converters) { + public ConfigBuilder withConverters(Converter... converters) { this.converters.addAll(asList(converters)); return this; } @@ -78,15 +78,13 @@ public Config build() { if (!ignoreDefaultSources) { // load all ConfigSource services ServiceLoader configSourceLoader = ServiceLoader.load(ConfigSource.class, forClassLoader); - for (ConfigSource configSource : configSourceLoader) { - configSources.add(configSource); - } + configSourceLoader.forEach(configSource -> configSources.add(configSource)); // load all ConfigSources from ConfigSourceProviders ServiceLoader configSourceProviderLoader = ServiceLoader.load(ConfigSourceProvider.class, forClassLoader); - for (ConfigSourceProvider configSourceProvider : configSourceProviderLoader) { - configSources.addAll(configSourceProvider.getConfigSources(forClassLoader)); - } + configSourceProviderLoader.forEach(configSourceProvider -> + configSourceProvider.getConfigSources(forClassLoader) + .forEach(configSource -> configSources.add(configSource))); } ConfigImpl config = new ConfigImpl(); @@ -104,7 +102,7 @@ protected Collection getBuiltInConfigSources(ClassLoader configSources.add(new SystemEnvConfigSource()); configSources.add(new SystemPropertyConfigSource()); - configSources.addAll(new PropertyFileConfigSourceProvider("META-INF/java-config.properties", true, forClassLoader).getConfigSources(forClassLoader)); + configSources.addAll(new PropertyFileConfigSourceProvider("META-INF/microprofile-config.properties", true, forClassLoader).getConfigSources(forClassLoader)); return configSources; } diff --git a/impl/src/main/java/org/apache/geronimo/config/DefaultConfigProvider.java b/impl/src/main/java/org/apache/geronimo/config/DefaultConfigProvider.java index 03adbff..0d280ed 100644 --- a/impl/src/main/java/org/apache/geronimo/config/DefaultConfigProvider.java +++ b/impl/src/main/java/org/apache/geronimo/config/DefaultConfigProvider.java @@ -21,16 +21,17 @@ import java.util.Iterator; import java.util.Map; import java.util.WeakHashMap; -import io.microprofile.config.Config; -import io.microprofile.config.ConfigProvider; +import org.eclipse.microprofile.config.Config; +import org.eclipse.microprofile.config.spi.ConfigBuilder; +import org.eclipse.microprofile.config.spi.ConfigProviderResolver; /** * @author Mark Struberg */ -public class DefaultConfigProvider implements ConfigProvider.SPI { +public class DefaultConfigProvider extends ConfigProviderResolver { - protected static Map> configs + private static Map> configs = Collections.synchronizedMap(new WeakHashMap>()); @@ -51,7 +52,7 @@ public Config getConfig(ClassLoader forClassLoader) { synchronized (DefaultConfigProvider.class) { config = existingConfig(forClassLoader); if (config == null) { - config = createConfig(forClassLoader); + config = getBuilder().forClassLoader(forClassLoader).addDefaultSources().build(); registerConfig(config, forClassLoader); } } @@ -64,9 +65,6 @@ Config existingConfig(ClassLoader forClassLoader) { return configRef != null ? configRef.get() : null; } - protected Config createConfig(ClassLoader forClassLoader) { - return newConfig().forClassLoader(forClassLoader).build(); - } void registerConfig(Config config, ClassLoader forClassLoader) { synchronized (DefaultConfigProvider.class) { @@ -75,13 +73,13 @@ void registerConfig(Config config, ClassLoader forClassLoader) { } @Override - public ConfigProvider.ConfigBuilder newConfig() { + public ConfigBuilder getBuilder() { return new DefaultConfigBuilder(); } @Override - public ConfigProvider.ConfigBuilder registerConfig() { - return new ManualApplicationConfigBuilder(this); + public void setConfig(Config config, ClassLoader classLoader) { + registerConfig(config, classLoader); } @Override diff --git a/impl/src/main/java/org/apache/geronimo/config/ManualApplicationConfigBuilder.java b/impl/src/main/java/org/apache/geronimo/config/ManualApplicationConfigBuilder.java index 9b91edf..01ee075 100644 --- a/impl/src/main/java/org/apache/geronimo/config/ManualApplicationConfigBuilder.java +++ b/impl/src/main/java/org/apache/geronimo/config/ManualApplicationConfigBuilder.java @@ -16,8 +16,8 @@ */ package org.apache.geronimo.config; -import io.microprofile.config.Config; -import io.microprofile.config.ConfigProvider; +import org.eclipse.microprofile.config.Config; +import org.eclipse.microprofile.config.spi.ConfigProviderResolver; /** * @author Mark Struberg @@ -36,7 +36,7 @@ public synchronized Config build() { if (cl == null) { cl = Thread.currentThread().getContextClassLoader(); if (cl == null) { - cl = ConfigProvider.SPI.class.getClassLoader(); + cl = ConfigProviderResolver.class.getClassLoader(); } } Config oldConfig = configProvider.existingConfig(cl); diff --git a/impl/src/main/java/org/apache/geronimo/config/configsource/BaseConfigSource.java b/impl/src/main/java/org/apache/geronimo/config/configsource/BaseConfigSource.java index 9ffbc10..d7117be 100644 --- a/impl/src/main/java/org/apache/geronimo/config/configsource/BaseConfigSource.java +++ b/impl/src/main/java/org/apache/geronimo/config/configsource/BaseConfigSource.java @@ -21,7 +21,7 @@ import java.util.logging.Level; import java.util.logging.Logger; -import io.microprofile.config.spi.ConfigSource; +import org.eclipse.microprofile.config.spi.ConfigSource; /** @@ -31,6 +31,9 @@ * @author Gerhard Petracek */ public abstract class BaseConfigSource implements ConfigSource { + + public final static String CONFIG_ORDINAL = "config_ordinal"; + protected Logger log = Logger.getLogger(getClass().getName()); private int ordinal = 1000; // default @@ -50,7 +53,7 @@ public int getOrdinal() { protected void initOrdinal(int defaultOrdinal) { ordinal = defaultOrdinal; - String configuredOrdinalString = getPropertyValue(ConfigSource.CONFIG_ORDINAL); + String configuredOrdinalString = getValue(CONFIG_ORDINAL); try { if (configuredOrdinalString != null) { diff --git a/impl/src/main/java/org/apache/geronimo/config/configsource/PropertyFileConfigSource.java b/impl/src/main/java/org/apache/geronimo/config/configsource/PropertyFileConfigSource.java index d98826d..7d86394 100644 --- a/impl/src/main/java/org/apache/geronimo/config/configsource/PropertyFileConfigSource.java +++ b/impl/src/main/java/org/apache/geronimo/config/configsource/PropertyFileConfigSource.java @@ -42,12 +42,12 @@ public PropertyFileConfigSource(URL propertyFileUrl) { * @return value for the given key or null if there is no configured value */ @Override - public String getPropertyValue(String key) { - return (String) properties.get(key); + public String getValue(String key) { + return properties.get(key); } @Override - public String getConfigName() { + public String getName() { return fileName; } diff --git a/impl/src/main/java/org/apache/geronimo/config/configsource/PropertyFileConfigSourceProvider.java b/impl/src/main/java/org/apache/geronimo/config/configsource/PropertyFileConfigSourceProvider.java index 6404f92..f4be5fa 100644 --- a/impl/src/main/java/org/apache/geronimo/config/configsource/PropertyFileConfigSourceProvider.java +++ b/impl/src/main/java/org/apache/geronimo/config/configsource/PropertyFileConfigSourceProvider.java @@ -26,8 +26,8 @@ import java.util.logging.Level; import java.util.logging.Logger; -import io.microprofile.config.spi.ConfigSource; -import io.microprofile.config.spi.ConfigSourceProvider; +import org.eclipse.microprofile.config.spi.ConfigSource; +import org.eclipse.microprofile.config.spi.ConfigSourceProvider; /** diff --git a/impl/src/main/java/org/apache/geronimo/config/configsource/SystemEnvConfigSource.java b/impl/src/main/java/org/apache/geronimo/config/configsource/SystemEnvConfigSource.java index bf5e171..1c31cc6 100644 --- a/impl/src/main/java/org/apache/geronimo/config/configsource/SystemEnvConfigSource.java +++ b/impl/src/main/java/org/apache/geronimo/config/configsource/SystemEnvConfigSource.java @@ -21,7 +21,7 @@ import java.util.Map; -import io.microprofile.config.spi.ConfigSource; +import org.eclipse.microprofile.config.spi.ConfigSource; /** * {@link ConfigSource} which uses {@link System#getenv()} @@ -40,7 +40,7 @@ public SystemEnvConfigSource() { } @Override - public String getConfigName() { + public String getName() { return "system_env"; } @@ -50,7 +50,7 @@ public Map getProperties() { } @Override - public String getPropertyValue(String key) { + public String getValue(String key) { String val = configValues.get(key); if (val == null || val.isEmpty()) { val = configValues.get(key.replace('.', '_')); diff --git a/impl/src/main/java/org/apache/geronimo/config/configsource/SystemPropertyConfigSource.java b/impl/src/main/java/org/apache/geronimo/config/configsource/SystemPropertyConfigSource.java index 73ce7f1..f5f8ea1 100644 --- a/impl/src/main/java/org/apache/geronimo/config/configsource/SystemPropertyConfigSource.java +++ b/impl/src/main/java/org/apache/geronimo/config/configsource/SystemPropertyConfigSource.java @@ -20,7 +20,7 @@ import java.util.Map; -import io.microprofile.config.spi.ConfigSource; +import org.eclipse.microprofile.config.spi.ConfigSource; /** * {@link ConfigSource} which uses {@link System#getProperties()} @@ -38,12 +38,12 @@ public Map getProperties() { } @Override - public String getPropertyValue(String key) { + public String getValue(String key) { return System.getProperty(key); } @Override - public String getConfigName() { + public String getName() { return "system-properties"; } } diff --git a/impl/src/main/java/org/apache/geronimo/config/converters/BooleanConverter.java b/impl/src/main/java/org/apache/geronimo/config/converters/BooleanConverter.java index 72e03b4..e2b5d3c 100644 --- a/impl/src/main/java/org/apache/geronimo/config/converters/BooleanConverter.java +++ b/impl/src/main/java/org/apache/geronimo/config/converters/BooleanConverter.java @@ -16,7 +16,7 @@ */ package org.apache.geronimo.config.converters; -import io.microprofile.config.spi.Converter; +import org.eclipse.microprofile.config.spi.Converter; import javax.annotation.Priority; diff --git a/impl/src/main/java/org/apache/geronimo/config/converters/DoubleConverter.java b/impl/src/main/java/org/apache/geronimo/config/converters/DoubleConverter.java index c32860f..c1eb6fb 100644 --- a/impl/src/main/java/org/apache/geronimo/config/converters/DoubleConverter.java +++ b/impl/src/main/java/org/apache/geronimo/config/converters/DoubleConverter.java @@ -16,7 +16,7 @@ */ package org.apache.geronimo.config.converters; -import io.microprofile.config.spi.Converter; +import org.eclipse.microprofile.config.spi.Converter; import javax.annotation.Priority; diff --git a/impl/src/main/java/org/apache/geronimo/config/converters/FloatConverter.java b/impl/src/main/java/org/apache/geronimo/config/converters/FloatConverter.java index fa7372a..1a4eaac 100644 --- a/impl/src/main/java/org/apache/geronimo/config/converters/FloatConverter.java +++ b/impl/src/main/java/org/apache/geronimo/config/converters/FloatConverter.java @@ -18,7 +18,7 @@ import javax.annotation.Priority; -import io.microprofile.config.spi.Converter; +import org.eclipse.microprofile.config.spi.Converter; /** * @author Mark Struberg diff --git a/impl/src/main/java/org/apache/geronimo/config/converters/IntegerConverter.java b/impl/src/main/java/org/apache/geronimo/config/converters/IntegerConverter.java index cb76c63..be32e8a 100644 --- a/impl/src/main/java/org/apache/geronimo/config/converters/IntegerConverter.java +++ b/impl/src/main/java/org/apache/geronimo/config/converters/IntegerConverter.java @@ -18,7 +18,7 @@ import javax.annotation.Priority; -import io.microprofile.config.spi.Converter; +import org.eclipse.microprofile.config.spi.Converter; /** * @author Mark Struberg diff --git a/impl/src/main/java/org/apache/geronimo/config/converters/LongConverter.java b/impl/src/main/java/org/apache/geronimo/config/converters/LongConverter.java index 4df6eaa..dc63f5a 100644 --- a/impl/src/main/java/org/apache/geronimo/config/converters/LongConverter.java +++ b/impl/src/main/java/org/apache/geronimo/config/converters/LongConverter.java @@ -16,7 +16,7 @@ */ package org.apache.geronimo.config.converters; -import io.microprofile.config.spi.Converter; +import org.eclipse.microprofile.config.spi.Converter; import javax.annotation.Priority; diff --git a/impl/src/main/resources/META-INF/services/io.microprofile.config.ConfigProvider$SPI b/impl/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigProviderResolver similarity index 100% rename from impl/src/main/resources/META-INF/services/io.microprofile.config.ConfigProvider$SPI rename to impl/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigProviderResolver diff --git a/impl/tck-suite.xml b/impl/tck-suite.xml index ab445be..eff3f62 100644 --- a/impl/tck-suite.xml +++ b/impl/tck-suite.xml @@ -22,7 +22,7 @@ - + diff --git a/pom.xml b/pom.xml index cf08594..487e84b 100644 --- a/pom.xml +++ b/pom.xml @@ -45,15 +45,12 @@ - 1.7 - 1.7 + 1.8 + 1.8 - api - tck impl - spec diff --git a/spec/pom.xml b/spec/pom.xml deleted file mode 100644 index 6389337..0000000 --- a/spec/pom.xml +++ /dev/null @@ -1,98 +0,0 @@ - - - - 4.0.0 - - - - org.apache.geronimo.config - config-parent - 0.1-SNAPSHOT - - - org.apache.geronimo.config - config-spec - pom - - - - Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0.txt - repo - A business-friendly OSS license - - - - - 1.5.3 - 1.5.0-alpha.10.1 - Apache License v 2.0 - MMMM dd, yyyy - ${maven.build.timestamp} - - - - clean package - - - org.asciidoctor - asciidoctor-maven-plugin - ${asciidoctor-maven.version} - - - org.asciidoctor - asciidoctorj-pdf - ${asciidoctorj-pdf.version} - - - - - generate-pdf-doc - generate-resources - - process-asciidoc - - - pdf - - - - output-html - generate-resources - - process-asciidoc - - - html5 - - - - - microprofile-config-spec.asciidoc - coderay - - Apache License v2.0 - - - - - - - diff --git a/spec/src/main/asciidoc/architecture.asciidoc b/spec/src/main/asciidoc/architecture.asciidoc deleted file mode 100644 index b715436..0000000 --- a/spec/src/main/asciidoc/architecture.asciidoc +++ /dev/null @@ -1,51 +0,0 @@ -// -// Licensed under the Apache License, Version 2.0 (the "License"). -// See the NOTICE file distributed with this work -// for additional information regarding copyright ownership. -// The author licenses this file to You under the Apache License, Version 2.0 -// (the "License"); you may not use this file except in compliance with -// the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -[[architecture]] -== Architecture - -This specification defines an easy to use and flexible system for application configuration. -It also defines a way to extend the configuration mechanism itself via a SPI (Service Provider Interface) in a portable way. - -=== Rational - -Released binaries often contain functionality which need to behave slightly differently depending on the deployment. -This might be different REST endpoints to talk to (e.g. depending on the customer for whom a WAR is deployed). -Or it might even be different features which need to be switched on and off depending on the installation. -All this must be possible without the need to re-package the whole application binary. - -Microprofile-Config provides a way to achieve this goal by aggregating configuration from many different <> and presents a single merged view to the user. -This allows the application to bundle default configuration within the application. -It also allows to override the defaults from outside, e.g. via an environment variable a Java system property or via Docker. -Microprofile-Config also allows to implement and register own configuration sources in a portable way, e.g. for reading configuration values from a shared database in an application cluster. - - -The core Microprofile-Config mechanism is purely String/String based. -Type-safety is only provided on top of that by using the proper <> before handing the value out to the caller. - -The configuration key might use dot-separated namespaces similar to Java package namespacing: - -[source, text] ----- -com.acme.myproject.someserver.url = http://some.server/some/endpoint -com.acme.myproject.someserver.port = 9085 -com.acme.myproject.someserver.active = true -com.acme.other.stuff.name = Karl -com.acme.myproject.notify.onerror=karl@mycompany,sue@mcompany ----- - -Config keys are usually case sensitive. diff --git a/spec/src/main/asciidoc/configexamples.asciidoc b/spec/src/main/asciidoc/configexamples.asciidoc deleted file mode 100644 index 4799e11..0000000 --- a/spec/src/main/asciidoc/configexamples.asciidoc +++ /dev/null @@ -1,92 +0,0 @@ -// -// Licensed under the Apache License, Version 2.0 (the "License"). -// See the NOTICE file distributed with this work -// for additional information regarding copyright ownership. -// The author licenses this file to You under the Apache License, Version 2.0 -// (the "License"); you may not use this file except in compliance with -// the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -[[configexamples]] -== Configuration Usage Examples - -An application can access it's configured values via a `Config` instance. -A user can use the `ConfigProvider` to access the `Config` of an application or simply use `@Inject Config` within CDI managed components. - -=== Simple Example - -[source, java] ----- -ppublic class ConfigUsageSample { - - public void useTheConfig() { - // get access to the Config instance - Config config = ConfigProvider.getConfig(); - - String serverUrl = config.getValue("com.acme.myproject.someserver.url"); - Integer serverPort = config.getValue("com.acme.myproject.someserver.port", - Integer.class); - - callToServer(serverUrl, serverPort); - } -} ----- - -If you need to access a different server then you can e.g. change the configuration via a `-D` system property: - -[source, text] ----- -$> java -jar some.jar -Dcom.acme.myproject.someserver.url=http://other.server/other/endpoint ----- - -Note that the way to inject this configuration into the application can be extended by providing custom `ConfigSource` s. - - - -=== Some advanced features - -It is also possible to dynamically pick up values which might change at runtime. -For example if the configured values get picked up from a custom <> which picks up it's values from a Database. - -[source, java] ----- -@ApplicationScoped -public class DynamicConfigUsageSample { - - private @Inject Config config; - - private ConfigValue serverUrlCfg; - private ConfigValue serverPortCfg - - @PostConstruct - private void init() { - serverUrlCfg= config.access("com.acme.myproject.someserver.url") - .cacheFor(5, TimeUnit.MINUTES) - .logChanges(true) - .evaluateVariables(true); - - serverPortCfg = config.access("com.acme.myproject.someserver.port") - .as(Integer.class) - .cacheFor(5, TimeUnit.MINUTES) - .logChanges(true) - .evaluateVariables(true) - .withDefault(8080); - } - - public void useTheConfig() { - callToServer(serverUrlCfg.getValue(), serverPortCfg.getValue()); - } -} ----- - -The `cacheFor(5, TimeUnit.MINUTES)` will have the `ConfigValue` behave like a local cache and thus reduce load on the configuration system. -5 minutes after `getValue()` got called the last time any fresh value will get picked up. -If `logChanges(true)` is set then any value change will get logged. \ No newline at end of file diff --git a/spec/src/main/asciidoc/configprovider.asciidoc b/spec/src/main/asciidoc/configprovider.asciidoc deleted file mode 100644 index ce39eb4..0000000 --- a/spec/src/main/asciidoc/configprovider.asciidoc +++ /dev/null @@ -1,57 +0,0 @@ -// -// Licensed under the Apache License, Version 2.0 (the "License"). -// See the NOTICE file distributed with this work -// for additional information regarding copyright ownership. -// The author licenses this file to You under the Apache License, Version 2.0 -// (the "License"); you may not use this file except in compliance with -// the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -[[configprovider]] -== Accessing or Creating a certain Configuration - - -For manually accessing the `ConfigProvider` is the central class to access a configuration. -It allows access to different configurations (represented by a `Config` instance) based on the application in which it is used. -We distinguish 5 different ways to create or `Config` instance: - -* In CDI manged components a user can use `@Inject` to access the current application configuration. - If no configuration is registered the automatic discovery of <> will be performed. - -* A factory method `ConfigProvider#getConfig()` to create a `Config` object based on automatically picked up `ConfigSources` - of the Application identified by the current Thread Context ClassLoader classpath. - Subsequent calls to this method for a certain Application will return the same `Config` instance. - -* A factory method `ConfigProvider#getConfig(ClassLoader forClassLoader)` to create a `Config` object based on automatically picked up `ConfigSources` - of the Application identified by the given ClassLoader. - This can be used if the Thread Context ClassLoader does not represent the correct layer. - E.g. if you need the Config for a class in a shared EAR lib folder. - Subsequent calls to this method for a certain Application will return the same `Config` instance. - -* A factory method `ConfigProvider#newConfig()` to create an empty `Config` object which can be filled manually via a builder. - This configuration instance will not be shared by the `ConfigProvider`. - This method is intended be used if a IoT container or any other external Factory can be used to give access to a manually created shared `Config`. - -* A factory method `ConfigProvider#registerConfig()` to create an empty `Config` object which can be filled manually via a builder. - This configuration instance *will* be shared by the `ConfigProvider`. - Any subsequent call to `ConfigProvider#getConfig()` will return the registered `Config` instance. - - -All methods in the `ConfigProvider` and `Config` implementations are thread safe and reentrant. - -If a `Config` is bound to an Application it is ensured that it gets properly removed if the Application gets destroyed. -The Config system deos not create any memory leaks in that case. - -A `Config` can be release manually by calling `ConfigProvider#release(Config)`. -ConfigSources which implement the `java.io.Closeable` interface will be properly destroyed. -Any subsequent call to `ConfigProvider#getConfig()` or `ConfigProvider#getConfig(ClassLoader forClassLoader)` will result in a new `Config` instance. - -<<< \ No newline at end of file diff --git a/spec/src/main/asciidoc/configsources.asciidoc b/spec/src/main/asciidoc/configsources.asciidoc deleted file mode 100644 index 22e5d85..0000000 --- a/spec/src/main/asciidoc/configsources.asciidoc +++ /dev/null @@ -1,137 +0,0 @@ -// -// Licensed under the Apache License, Version 2.0 (the "License"). -// See the NOTICE file distributed with this work -// for additional information regarding copyright ownership. -// The author licenses this file to You under the Apache License, Version 2.0 -// (the "License"); you may not use this file except in compliance with -// the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -[[configsource]] -== ConfigSource - -A `ConfigSource` is exactly what its name says: a source for configured values. -The `Config` uses all configured implementations of `ConfigSource` to look up the property in question. - -=== ConfigSource Ordering - -Each `ConfigSource` has a specified `ordinal`, which is used to determine the importance of the values taken from the associated `ConfigSource`. -A higher `ordinal` means that the values taken from this `ConfigSource` will override values from lower-priority `ConfigSource` s. -This allows a configuration to be customized from outside a binary, assuming that external `ConfigSource` s have higher `ordinal` values than the ones whose values originate within the release binaries. - -It can also be used to implement a drop-in configuration approach. -Simply create a jar containing a `ConfigSource` with a higher ordinal and override configuration values in it. -If the jar is present on the classpath then it will override configuration values from `ConfigSource` s with lower `ordinal` values. - -The ordinal for property file based `ConfigSource` s can be configured using the key `config_ordinal` inside the property file. - -[source, text] ----- -config_ordinal = 120 -com.acme.myproject.someserver.url = http://more_important.server/some/endpoint ----- - -[[default_configsources]] -=== Default ConfigSources - -A Microprofile-Config implementation must provide `ConfigSource` s for the following data out of the box: - -* System properties (ordinal=400) -* Environment properties (ordinal=300). - The built in `ConfigSource` for the environment provides an all upper-case fallback lookup where dots are replaced with underlines. - An environment setting `ACME_MYKEY=bla` machtches a lookup for `config.getValue("acme.mykey")`. -* A `ConfigSource` for each property file `META-INF/java-config.properties` found on the classpath. (default ordinal = 100) - -=== Custom ConfigSources - -`ConfigSource` s are discovered using the `java.util.ServiceLoader` mechanism. - -To add a custom `ConfigSource`, implement the interface `io.microprofile.config.spi.ConfigSource`. - -[source, java] ----- -public class CustomDbConfigSource implements ConfigSource { - - @Override - public int getOrdinal() { - return 112; - } - - @Override - public Map getProperties() { - return readPropertiesFromDb(); - } - - @Override - public String getPropertyValue(String key) { - return readPropertyFromDb(key); - } - - @Override - public String getConfigName() { - return "customDbConfig"; - } - - // + methods to read from the DB -} - ----- - -Then register your implementation in a resource file `/META-INF/services/io.microprofile.config.spi.ConfigSource` by including the fully-qualified class name of the custom implementation in the file. - - -=== Custom ConfigSources via ConfigSourceProvider - -If you need dynamic `ConfigSource` s you can also register a `ConfigSourceProvider` in a similar manner. -This is useful if you are required to dynamically pick up multiple `ConfigSource` s of the same kind; -for example, to pick up all `myproject.properties` resources from all the JARs in your classpath. - -A custom `ConfigSourceProvider` must implement the interface `io.microprofile.config.spi.ConfigSourceProvider`. -Register your implementation in a resource file `/META-INF/services/io.microprofile.config.spi.ConfigSourceProvider` by including the fully-qualified class name of the custom implementation/s in the file. - -An example which registers all YAML files with the name `exampleconfig.yaml`: - -[source, java] ----- -public class ExampleYamlConfigSourceProvider - implements io.microprofile.config.spi.ConfigSourceProvider { - @Override - public List getConfigSources(ClassLoader forClassLoader) { - List configSources = new ArrayList<>(); - - Enumeration yamlFiles - = forClassLoader.getResources("sampleconfig.yaml"); - while (yamlFiles.hasMoreElements()) { - configSources.add(new SampleYamlConfigSource(yamlFiles.nextElement())); - } - return configSources; - } -} ----- - -Please note that a single `ConfigSource` should be either registered directly or via a `ConfigSourceProvider`, but never both ways. - - -=== ConfigSource and Mutable Data - -A `Config` instance provides no caching but iterates over all `ConfigSources` for each `getValue(String)` operation. -A `ConfigSource` is allowed to cache the underlying values itself. - -Users might use the `cacheFor(long, TimeUnit)` method of a `ConfigValue` to pick up values which might change at runtime without penetrating the configuration system. - - -=== Manually adding ConfigSources - -A user can manually register `ConfigSource` s by using the method `void addConfigSources(List configSourcesToAdd)`. -This will add the given list to the already registered `ConfigSources` of the current `Config` instance. - -The order in which the `ConfigSources` are evaluated when using `Config#getValue(String key)` is independent of the order in which they were added to the `Config`; this depends only on the `ordinal` values of the available `ConfigSources`. - diff --git a/spec/src/main/asciidoc/converters.asciidoc b/spec/src/main/asciidoc/converters.asciidoc deleted file mode 100644 index 0131c39..0000000 --- a/spec/src/main/asciidoc/converters.asciidoc +++ /dev/null @@ -1,48 +0,0 @@ -// -// Licensed under the Apache License, Version 2.0 (the "License"). -// See the NOTICE file distributed with this work -// for additional information regarding copyright ownership. -// The author licenses this file to You under the Apache License, Version 2.0 -// (the "License"); you may not use this file except in compliance with -// the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -[[converter]] -== Converter - -For providing typeseafe configuration we need to convert from the configured Strings into target types. -This happens by providing `Converter` s in the `Config`. - -=== Built-in Converters - -The following `Converter` s are provided by Microprofile-Config by default: - -* `Boolean` , values for `true` (case insensitive) "true", "1", "YES", "Y" "JA" "J", "OUI". - Any other value will be interpreted as `false` -* `Integer` -* `Long` -* `Float` , a dot '.' is used to separate the fractional digits -* `Double` , a dot '.' is used to separate the fractional digits -* `java.util.Date` in ISO-8601 format (https://www.ietf.org/rfc/rfc3339.txt), e.g. YYYY-MM-DD. Remaining fractions are set to 0. -* Java8 `LocalDate` and `LocalDateTime`in ISO-8601 format - - -=== Adding custom Converters - -A custom `Converter` must implement the generic interface `io.microprofile.config.spi.Converter`. -The TypedParameter of the interface is the target type the String is converted to -You have to register your implementation in a file `/META-INF/services/io.microprofile.config.spi.Converter` by writing the fully qualified class name of the custom implementation into it. - -A custom `Converter` can define a priority with the `@javax.annotation.Priority` annotation. -If a Priority annotation isn't applied, a default priority of 100 is assumed. -The `Config` will use the `Converter` with the highest `Priority` for each target type. - -A custom `Converter` for a target type of any of the built-in Converters will overwrite the default Converter. diff --git a/spec/src/main/asciidoc/license-alv2.asciidoc b/spec/src/main/asciidoc/license-alv2.asciidoc deleted file mode 100644 index 276af0a..0000000 --- a/spec/src/main/asciidoc/license-alv2.asciidoc +++ /dev/null @@ -1,44 +0,0 @@ -// -// Licensed under the Apache License, Version 2.0 (the "License"). -// See the NOTICE file distributed with this work -// for additional information regarding copyright ownership. -// The author licenses this file to You under the Apache License, Version 2.0 -// (the "License"); you may not use this file except in compliance with -// the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -[subs="normal"] -.... - -Specification: {doctitle} - -Version: {revnumber} - -Status: {revremark} - -Specification Lead: Mark Struberg, Emily Jiang - -Release: {revdate} - -Copyright 2016-2017 Original Authors, -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -.... diff --git a/spec/src/main/asciidoc/microprofile-config-spec.asciidoc b/spec/src/main/asciidoc/microprofile-config-spec.asciidoc deleted file mode 100644 index eca5e96..0000000 --- a/spec/src/main/asciidoc/microprofile-config-spec.asciidoc +++ /dev/null @@ -1,46 +0,0 @@ -// -// Licensed under the Apache License, Version 2.0 (the "License"). -// See the NOTICE file distributed with this work -// for additional information regarding copyright ownership. -// The author licenses this file to You under the Apache License, Version 2.0 -// (the "License"); you may not use this file except in compliance with -// the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -= Configuration for Microprofile -:author: Mark Struberg -:email: struberg@apache.org -:revnumber: 0.2 -:revdate: 2017-01-15 -:revremark: Proposal -:version-label!: -:sectanchors: -:doctype: book -:license: Apache License v2.0 -:source-highlighter: coderay -:toc: left -:toclevels: 4 -:sectnumlevels: 4 -ifdef::backend-pdf[] -:pagenums: -endif::[] - -include::license-alv2.asciidoc[] - -include::architecture.asciidoc[] - -include::configexamples.asciidoc[] - -include::configprovider.asciidoc[] - -include::configsources.asciidoc[] - -include::converters.asciidoc[] diff --git a/tck/pom.xml b/tck/pom.xml deleted file mode 100644 index cff61bd..0000000 --- a/tck/pom.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - 4.0.0 - - - org.apache.geronimo.config - config-parent - 0.1-SNAPSHOT - - - org.apache.geronimo.config - config-tck - - - - Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0.txt - repo - A business-friendly OSS license - - - - - - org.apache.geronimo.config - config-api - 0.1-SNAPSHOT - - - - org.testng - testng - 6.9.9 - compile - - - diff --git a/tck/src/main/java/io/microprofile/config/tck/ConfigProviderTest.java b/tck/src/main/java/io/microprofile/config/tck/ConfigProviderTest.java deleted file mode 100644 index 6b9a4b0..0000000 --- a/tck/src/main/java/io/microprofile/config/tck/ConfigProviderTest.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.microprofile.config.tck; - -import java.net.URL; -import java.net.URLClassLoader; -import java.util.Map; -import java.util.Properties; - -import io.microprofile.config.Config; -import io.microprofile.config.ConfigProvider; - -import io.microprofile.config.tck.configsources.SampleYamlConfigSource; -import org.testng.Assert; -import org.testng.annotations.Test; - -/** - * @author Mark Struberg - */ -public class ConfigProviderTest { - - @Test - public void testConfigProviderWithDefaultTCCL() { - ClassLoader oldTccl = Thread.currentThread().getContextClassLoader(); - try { - ClassLoader tempCl = new URLClassLoader(new URL[0], this.getClass().getClassLoader()); - Thread.currentThread().setContextClassLoader(tempCl); - Config config = ConfigProvider.getConfig(); - Assert.assertNotNull(config); - - Config config2 = ConfigProvider.getConfig(tempCl); - Assert.assertNotNull(config2); - Assert.assertEquals(config, config2); - } - finally { - Thread.currentThread().setContextClassLoader(oldTccl); - } - } - - @Test - public void testEnvironmentConfigSource() { - Map env = System.getenv(); - Config config = ConfigProvider.getConfig(); - for (Map.Entry envEntry : env.entrySet()) { - Assert.assertEquals(envEntry.getValue(), config.getValue(envEntry.getKey())); - } - } - - @Test - public void testPropertyConfigSource() { - Properties properties = System.getProperties(); - Config config = ConfigProvider.getConfig(); - - for (Map.Entry propEntry : properties.entrySet()) { - Assert.assertEquals(propEntry.getValue(), config.getValue((String) propEntry.getKey())); - } - } - - @Test - public void testDynamicValueInPropertyConfigSource() { - Config config = ConfigProvider.getConfig(); - String configKey = "tck.config.test.systemproperty.dynamic.value"; - String configValue = "myDynamicValue;"; - - System.setProperty(configKey, configValue); - Assert.assertEquals(config.getValue(configKey), configValue); - } - - @Test - public void testJavaConfigPropertyFilesConfigSource() { - Config config = ConfigProvider.getConfig(); - Assert.assertEquals(config.getValue("tck.config.test.javaconfig.properties.key1"), "VALue1"); - } - - @Test - public void testNonExistingConfigKey() { - Config config = ConfigProvider.getConfig(); - Assert.assertNull(config.getValue("tck.config.test.keydoesnotexist")); - } - - @Test - public void testRegisterManualConfig() { - // make sure we get a clean config - ConfigProvider.releaseConfig(ConfigProvider.getConfig()); - - ConfigProvider.registerConfig() - .ignoreDefaultSources() - .withSources(new SampleYamlConfigSource(null)) - .build(); - - Config config = ConfigProvider.getConfig(); - Assert.assertNotNull(config); - Assert.assertNotNull(config.getConfigSources()); - Assert.assertEquals(1, config.getConfigSources().length); - Assert.assertEquals(SampleYamlConfigSource.class, config.getConfigSources()[0].getClass()); - - Assert.assertEquals("yamlvalue1", config.getValue("tck.config.test.sampleyaml.key1")); - - Assert.assertNull(config.getValue("tck.config.test.javaconfig.properties.key1")); - - { - // try it again, Sam - // this time we should fail as we already have a Config registered for this application - try { - ConfigProvider.registerConfig() - .ignoreDefaultSources() - .withSources(new SampleYamlConfigSource(null)) - .build(); - - Assert.fail("We fail because subsequently registering another Config for the application is not allowed"); - } - catch (IllegalStateException ise) { - // all fine - } - } - - // clean up the dirt afterwards - ConfigProvider.releaseConfig(ConfigProvider.getConfig()); - } - - @Test - public void testConfigProviderRelease() { - Config config1 = ConfigProvider.getConfig(); - Config config2 = ConfigProvider.getConfig(); - - Assert.assertEquals(config2, config1); - - ConfigProvider.releaseConfig(config2); - - Config config3 = ConfigProvider.getConfig(); - - Assert.assertNotEquals(config1, config3); - } -} diff --git a/tck/src/main/java/io/microprofile/config/tck/ConfigSourceProviderTest.java b/tck/src/main/java/io/microprofile/config/tck/ConfigSourceProviderTest.java deleted file mode 100644 index 28a65a9..0000000 --- a/tck/src/main/java/io/microprofile/config/tck/ConfigSourceProviderTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.microprofile.config.tck; - -import io.microprofile.config.Config; -import io.microprofile.config.ConfigProvider; -import org.testng.Assert; -import org.testng.annotations.Test; - -/** - * @author Mark Struberg - */ -public class ConfigSourceProviderTest { - - @Test - public void testConfigSourceProvider() { - Config config = ConfigProvider.getConfig(); - - Assert.assertEquals(config.getValue("tck.config.test.sampleyaml.key1"), "yamlvalue1"); - } -} diff --git a/tck/src/main/java/io/microprofile/config/tck/ConfigValueTest.java b/tck/src/main/java/io/microprofile/config/tck/ConfigValueTest.java deleted file mode 100644 index 575f00a..0000000 --- a/tck/src/main/java/io/microprofile/config/tck/ConfigValueTest.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.microprofile.config.tck; - -import io.microprofile.config.Config; -import io.microprofile.config.ConfigProvider; -import io.microprofile.config.ConfigValue; -import org.testng.Assert; -import org.testng.annotations.Test; - -import java.util.concurrent.TimeUnit; - -/** - * @author Mark Struberg - */ -public class ConfigValueTest { - - private Config config = ConfigProvider.getConfig(); - - @Test - public void testGetValue() { - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.key1").getValue(), "value1"); - } - - @Test - public void testGetValueWithDefault() { - ConfigValue cfga = config.access("tck.config.test.javaconfig.configvalue.withdefault.notexisting") - .as(Integer.class) - .withDefault(Integer.valueOf(1234)); - - Assert.assertEquals(cfga.getValue(), Integer.valueOf(1234)); - } - - @Test - public void testGetValueWithStringDefault() { - ConfigValue cfga = config.access("tck.config.test.javaconfig.configvalue.withdefault.notexisting") - .as(Integer.class) - .withStringDefault("1234"); - - Assert.assertEquals(cfga.getValue(), Integer.valueOf(1234)); - } - - @Test - public void testIntegerConverter() { - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.integer").as(Integer.class).getValue(), Integer.valueOf(1234)); - } - - @Test - public void testLongConverter() { - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.long").as(Long.class).getValue(), Long.valueOf(1234567890123456L)); - } - - @Test - public void testFloatConverter() { - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.float").as(Float.class).getValue(), Float.valueOf(12.34f)); - } - - @Test - public void testDoubleonverter() { - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.double").as(Double.class).getValue(), Double.valueOf(12.34567890123456)); - } - - @Test - public void testBooleanConverter() { - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.true").as(Boolean.class).getValue(), Boolean.TRUE); - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.true_uppercase").as(Boolean.class).getValue(), Boolean.TRUE); - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.true_mixedcase").as(Boolean.class).getValue(), Boolean.TRUE); - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.false").as(Boolean.class).getValue(), Boolean.FALSE); - - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.one").as(Boolean.class).getValue(), Boolean.TRUE); - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.zero").as(Boolean.class).getValue(), Boolean.FALSE); - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.seventeen").as(Boolean.class).getValue(), Boolean.FALSE); - - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.yes").as(Boolean.class).getValue(), Boolean.TRUE); - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.yes_uppercase").as(Boolean.class).getValue(), Boolean.TRUE); - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.yes_mixedcase").as(Boolean.class).getValue(), Boolean.TRUE); - - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.y").as(Boolean.class).getValue(), Boolean.TRUE); - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.y_uppercase").as(Boolean.class).getValue(), Boolean.TRUE); - - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.ja").as(Boolean.class).getValue(), Boolean.TRUE); - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.ja_uppercase").as(Boolean.class).getValue(), Boolean.TRUE); - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.ja_mixedcase").as(Boolean.class).getValue(), Boolean.TRUE); - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.no_mixedcase").as(Boolean.class).getValue(), Boolean.FALSE); - - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.j").as(Boolean.class).getValue(), Boolean.TRUE); - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.j_uppercase").as(Boolean.class).getValue(), Boolean.TRUE); - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.n_uppercase").as(Boolean.class).getValue(), Boolean.FALSE); - - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.oui").as(Boolean.class).getValue(), Boolean.TRUE); - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.oui_uppercase").as(Boolean.class).getValue(), Boolean.TRUE); - Assert.assertEquals(config.access("tck.config.test.javaconfig.configvalue.boolean.oui_mixedcase").as(Boolean.class).getValue(), Boolean.TRUE); - } - - @Test - public void testCacheFor() throws Exception { - String key = "tck.config.cachefor.key"; - System.setProperty(key, "firstvalue"); - ConfigValue val = config.access(key).cacheFor(30, TimeUnit.MILLISECONDS); - Assert.assertEquals(val.getValue(), "firstvalue"); - - // immediately change the value - System.setProperty(key, "secondvalue"); - - // we should still see the first value, because it is cached! - Assert.assertEquals(val.getValue(), "firstvalue"); - - // but now let's wait a bit - Thread.sleep(40); - Assert.assertEquals(val.getValue(), "secondvalue"); - } - - @Test - public void testWithVariable() throws Exception { - ConfigValue val = config.access("tck.config.test.javaconfig.configvalue.withvariable.key").evaluateVariables(true); - Assert.assertEquals(val.getValue(), "This key needs the perfect value!"); - } -} diff --git a/tck/src/main/java/io/microprofile/config/tck/ConverterTest.java b/tck/src/main/java/io/microprofile/config/tck/ConverterTest.java deleted file mode 100644 index bbb0419..0000000 --- a/tck/src/main/java/io/microprofile/config/tck/ConverterTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.microprofile.config.tck; - -import io.microprofile.config.Config; -import io.microprofile.config.ConfigProvider; -import org.testng.Assert; -import org.testng.annotations.Test; - -/** - * @author Mark Struberg - */ -public class ConverterTest { - - @Test - public void testIntegerConverter() { - Config config = ConfigProvider.getConfig(); - Integer value = config.getValue("tck.config.test.javaconfig.converter.integervalue", Integer.class); - Assert.assertEquals(value, Integer.valueOf(1234)); - - } - - @Test - public void testFloatConverter() { - Config config = ConfigProvider.getConfig(); - Float value = config.getValue("tck.config.test.javaconfig.converter.floatvalue", Float.class); - Assert.assertEquals(value, Float.valueOf(12.34f)); - - } - - -} diff --git a/tck/src/main/java/io/microprofile/config/tck/CustomConfigSourceTest.java b/tck/src/main/java/io/microprofile/config/tck/CustomConfigSourceTest.java deleted file mode 100644 index 5a8d80d..0000000 --- a/tck/src/main/java/io/microprofile/config/tck/CustomConfigSourceTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.microprofile.config.tck; - -import io.microprofile.config.Config; -import io.microprofile.config.ConfigProvider; -import org.testng.Assert; -import org.testng.annotations.Test; - -/** - * @author Mark Struberg - */ -public class CustomConfigSourceTest { - - @Test - public void testConfigSourceProvider() { - Config config = ConfigProvider.getConfig(); - - Assert.assertEquals(config.getValue("tck.config.test.customDbConfig.key1"), "valueFromDb1"); - } -} diff --git a/tck/src/main/java/io/microprofile/config/tck/configsources/CustomConfigSourceProvider.java b/tck/src/main/java/io/microprofile/config/tck/configsources/CustomConfigSourceProvider.java deleted file mode 100644 index 2f2d0c4..0000000 --- a/tck/src/main/java/io/microprofile/config/tck/configsources/CustomConfigSourceProvider.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.microprofile.config.tck.configsources; - -import java.io.IOException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Enumeration; -import java.util.List; - -import io.microprofile.config.spi.ConfigSource; -import io.microprofile.config.spi.ConfigSourceProvider; - -/** - * @author Mark Struberg - */ -public class CustomConfigSourceProvider implements ConfigSourceProvider { - @Override - public List getConfigSources(ClassLoader forClassLoader) { - List detectedConfigSources = new ArrayList<>(); - - Enumeration yamlFiles = null; - try { - yamlFiles = forClassLoader.getResources("sampleconfig.yaml"); - } catch (IOException e) { - throw new RuntimeException(e); - } - while (yamlFiles.hasMoreElements()) { - detectedConfigSources.add(new SampleYamlConfigSource(yamlFiles.nextElement())); - } - return detectedConfigSources; - } -} diff --git a/tck/src/main/java/io/microprofile/config/tck/configsources/CustomDbConfigSource.java b/tck/src/main/java/io/microprofile/config/tck/configsources/CustomDbConfigSource.java deleted file mode 100644 index 83e27a1..0000000 --- a/tck/src/main/java/io/microprofile/config/tck/configsources/CustomDbConfigSource.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.microprofile.config.tck.configsources; - -import java.util.HashMap; -import java.util.Map; - -import io.microprofile.config.spi.ConfigSource; - -/** - * @author Mark Struberg - */ -public class CustomDbConfigSource implements ConfigSource { - - private Map configValues = new HashMap<>(); - - public CustomDbConfigSource() { - configValues.put("tck.config.test.customDbConfig.key1", "valueFromDb1"); - configValues.put("tck.config.test.customDbConfig.key2", "valueFromDb2"); - } - - @Override - public int getOrdinal() { - return 112; - } - - @Override - public Map getProperties() { - return readPropertiesFromDb(); - } - - @Override - public String getPropertyValue(String key) { - return readPropertyFromDb(key); - } - - @Override - public String getConfigName() { - return "customDbConfig"; - } - - private Map readPropertiesFromDb() { - return configValues; - } - - private String readPropertyFromDb(String key) { - return configValues.get(key); - } -} diff --git a/tck/src/main/java/io/microprofile/config/tck/configsources/SampleYamlConfigSource.java b/tck/src/main/java/io/microprofile/config/tck/configsources/SampleYamlConfigSource.java deleted file mode 100644 index 1d64de5..0000000 --- a/tck/src/main/java/io/microprofile/config/tck/configsources/SampleYamlConfigSource.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.microprofile.config.tck.configsources; - -import java.net.URL; -import java.util.HashMap; -import java.util.Map; - -import io.microprofile.config.spi.ConfigSource; - -/** - * @author Mark Struberg - */ -public class SampleYamlConfigSource implements ConfigSource { - private Map config = new HashMap<>(); - - public SampleYamlConfigSource(URL url) { - config.put("tck.config.test.sampleyaml.key1", "yamlvalue1"); - } - - @Override - public int getOrdinal() { - return config.get("ordinal") != null ? Integer.valueOf(config.get("ordinal")) : 110; - } - - @Override - public Map getProperties() { - return config; - } - - @Override - public String getPropertyValue(String key) { - return config.get(key); - } - - @Override - public String getConfigName() { - return null; - } - -} diff --git a/tck/src/main/java/io/microprofile/config/tck/converters/Duck.java b/tck/src/main/java/io/microprofile/config/tck/converters/Duck.java deleted file mode 100644 index 23a0542..0000000 --- a/tck/src/main/java/io/microprofile/config/tck/converters/Duck.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.microprofile.config.tck.converters; - -/** - * @author Mark Struberg - */ -public class Duck { - private final String name; - - - public Duck(String name) { - this.name = name; - } - - public String getName() { - return name; - } -} diff --git a/tck/src/main/java/io/microprofile/config/tck/converters/DuckConverter.java b/tck/src/main/java/io/microprofile/config/tck/converters/DuckConverter.java deleted file mode 100644 index b653fc1..0000000 --- a/tck/src/main/java/io/microprofile/config/tck/converters/DuckConverter.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package io.microprofile.config.tck.converters; - -import io.microprofile.config.spi.Converter; - -/** - * @author Mark Struberg - */ -public class DuckConverter implements Converter { - - @Override - public Duck convert(String value) { - return new Duck(value); - } -} diff --git a/tck/src/main/resources/META-INF/java-config.properties b/tck/src/main/resources/META-INF/java-config.properties deleted file mode 100644 index 8d478f9..0000000 --- a/tck/src/main/resources/META-INF/java-config.properties +++ /dev/null @@ -1,73 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy current the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - - -tck.config.test.javaconfig.properties.key1=VALue1 - - -tck.config.test.overwritten.in.custompropertyfile.key1=value from java-config.properties - - -tck.config.test.javaconfig.converter.integervalue = 1234 -tck.config.test.javaconfig.converter.floatvalue = 12.34 - - -tck.config.test.javaconfig.configvalue.key1=value1 - -# test BooleanConverter START -tck.config.test.javaconfig.configvalue.boolean.true=true -tck.config.test.javaconfig.configvalue.boolean.true_uppercase=TRUE -tck.config.test.javaconfig.configvalue.boolean.true_mixedcase=TruE -tck.config.test.javaconfig.configvalue.boolean.false=false - -tck.config.test.javaconfig.configvalue.boolean.one=1 -tck.config.test.javaconfig.configvalue.boolean.zero=0 -tck.config.test.javaconfig.configvalue.boolean.seventeen=17 - -tck.config.test.javaconfig.configvalue.boolean.yes=yes -tck.config.test.javaconfig.configvalue.boolean.yes_uppercase=YES -tck.config.test.javaconfig.configvalue.boolean.yes_mixedcase=Yes - -tck.config.test.javaconfig.configvalue.boolean.y=y -tck.config.test.javaconfig.configvalue.boolean.y_uppercase=Y - -tck.config.test.javaconfig.configvalue.boolean.ja=ja -tck.config.test.javaconfig.configvalue.boolean.ja_uppercase=ja -tck.config.test.javaconfig.configvalue.boolean.ja_mixedcase=Ja -tck.config.test.javaconfig.configvalue.boolean.no_mixedcase=No - -tck.config.test.javaconfig.configvalue.boolean.j=j -tck.config.test.javaconfig.configvalue.boolean.j_uppercase=J -tck.config.test.javaconfig.configvalue.boolean.n_uppercase=N - -tck.config.test.javaconfig.configvalue.boolean.oui=oui -tck.config.test.javaconfig.configvalue.boolean.oui_uppercase=OUI -tck.config.test.javaconfig.configvalue.boolean.oui_mixedcase=Oui -# test BooleanConverter END - -# various other converter -tck.config.test.javaconfig.configvalue.integer=1234 -tck.config.test.javaconfig.configvalue.long=1234567890123456 -tck.config.test.javaconfig.configvalue.float=12.34 -tck.config.test.javaconfig.configvalue.double=12.34567890123456 - - -# withVariable -tck.config.test.javaconfig.configvalue.variable = the perfect value -tck.config.test.javaconfig.configvalue.withvariable.key = This key needs ${tck.config.test.javaconfig.configvalue.variable}! \ No newline at end of file diff --git a/tck/src/main/resources/META-INF/services/io.microprofile.config.spi.ConfigSource b/tck/src/main/resources/META-INF/services/io.microprofile.config.spi.ConfigSource deleted file mode 100644 index 677a9fb..0000000 --- a/tck/src/main/resources/META-INF/services/io.microprofile.config.spi.ConfigSource +++ /dev/null @@ -1,20 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy current the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -io.microprofile.config.tck.configsources.CustomDbConfigSource \ No newline at end of file diff --git a/tck/src/main/resources/META-INF/services/io.microprofile.config.spi.ConfigSourceProvider b/tck/src/main/resources/META-INF/services/io.microprofile.config.spi.ConfigSourceProvider deleted file mode 100644 index bbcd7a0..0000000 --- a/tck/src/main/resources/META-INF/services/io.microprofile.config.spi.ConfigSourceProvider +++ /dev/null @@ -1,20 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy current the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# - -io.microprofile.config.tck.configsources.CustomConfigSourceProvider \ No newline at end of file diff --git a/tck/src/main/resources/sampleconfig.yaml b/tck/src/main/resources/sampleconfig.yaml deleted file mode 100644 index ee228a4..0000000 --- a/tck/src/main/resources/sampleconfig.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy current the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# -# just needed as a trigger for the ConfigSource pickup. -# Content is hardcoded in SampleYamlConfigSource \ No newline at end of file From 9edcde41362d490a4800537f1d3c32626f0baf77 Mon Sep 17 00:00:00 2001 From: Mark Struberg Date: Fri, 10 Mar 2017 00:22:28 +0100 Subject: [PATCH 2/8] disable travis for now as the API isn't available on any repo yet and I removed the original version from here --- .travis.yml => .travis.yml.disabled | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .travis.yml => .travis.yml.disabled (100%) diff --git a/.travis.yml b/.travis.yml.disabled similarity index 100% rename from .travis.yml rename to .travis.yml.disabled From 4d956ba82f2ef4f2602db15d89cf9cdefc453b3b Mon Sep 17 00:00:00 2001 From: Mark Struberg Date: Fri, 10 Mar 2017 10:39:49 +0100 Subject: [PATCH 3/8] apply latest spec changes --- impl/pom.xml | 4 ++-- .../apache/geronimo/config/ConfigImpl.java | 23 +++++++++++-------- .../config/DefaultConfigProvider.java | 7 ++---- impl/tck-suite.xml | 8 ++----- pom.xml | 2 +- 5 files changed, 20 insertions(+), 24 deletions(-) diff --git a/impl/pom.xml b/impl/pom.xml index 618a423..0199f08 100644 --- a/impl/pom.xml +++ b/impl/pom.xml @@ -32,8 +32,8 @@ - org.eclipse.microprofile.config.api - microprofile-config-api + org.eclipse.microprofile.apis + microprofile-config_1.0_api 1.0-SNAPSHOT diff --git a/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java b/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java index 89bf067..9e62c31 100644 --- a/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java +++ b/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java @@ -19,7 +19,6 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; @@ -49,7 +48,7 @@ public class ConfigImpl implements Config { protected Logger logger = Logger.getLogger(ConfigImpl.class.getName()); - protected ConfigSource[] configSources = new ConfigSource[0]; + protected List configSources = new ArrayList<>(); protected Map converters = new HashMap<>(); @@ -67,7 +66,11 @@ private void registerDefaultConverter() { @Override public Optional getString(String key) { - return Optional.ofNullable(getValue(key)); + String val = getValue(key); + if (val == null || val.isEmpty()) { + return Optional.empty(); + } + return Optional.ofNullable(val); } public String getValue(String key) { @@ -117,9 +120,9 @@ public ConfigValue access(String key) { public Iterable getPropertyNames() { Set result = new HashSet<>(); - for (int i = configSources.length; i > 0; i--) { - ConfigSource configSource = configSources[i]; + for (ConfigSource configSource : configSources) { result.addAll(configSource.getProperties().keySet()); + } return result; } @@ -127,12 +130,12 @@ public Iterable getPropertyNames() { @Override - public ConfigSource[] getConfigSources() { - return configSources; + public Iterable getConfigSources() { + return Collections.unmodifiableList(configSources); } public synchronized void addConfigSources(List configSourcesToAdd) { - List allConfigSources = new ArrayList<>(Arrays.asList(configSources)); + List allConfigSources = new ArrayList<>(configSources); allConfigSources.addAll(configSourcesToAdd); // finally put all the configSources back into the map @@ -171,14 +174,14 @@ public Map getConverters() { } - protected ConfigSource[] sortDescending(List configSources) { + protected List sortDescending(List configSources) { Collections.sort(configSources, new Comparator() { @Override public int compare(ConfigSource configSource1, ConfigSource configSource2) { return (configSource1.getOrdinal() > configSource2.getOrdinal()) ? -1 : 1; } }); - return configSources.toArray(new ConfigSource[configSources.size()]); + return configSources; } diff --git a/impl/src/main/java/org/apache/geronimo/config/DefaultConfigProvider.java b/impl/src/main/java/org/apache/geronimo/config/DefaultConfigProvider.java index 0d280ed..09e3767 100644 --- a/impl/src/main/java/org/apache/geronimo/config/DefaultConfigProvider.java +++ b/impl/src/main/java/org/apache/geronimo/config/DefaultConfigProvider.java @@ -66,7 +66,8 @@ Config existingConfig(ClassLoader forClassLoader) { } - void registerConfig(Config config, ClassLoader forClassLoader) { + @Override + public void registerConfig(Config config, ClassLoader forClassLoader) { synchronized (DefaultConfigProvider.class) { configs.put(forClassLoader, new WeakReference<>(config)); } @@ -77,10 +78,6 @@ public ConfigBuilder getBuilder() { return new DefaultConfigBuilder(); } - @Override - public void setConfig(Config config, ClassLoader classLoader) { - registerConfig(config, classLoader); - } @Override public void releaseConfig(Config config) { diff --git a/impl/tck-suite.xml b/impl/tck-suite.xml index eff3f62..f0033e6 100644 --- a/impl/tck-suite.xml +++ b/impl/tck-suite.xml @@ -15,18 +15,14 @@ the specific language governing permissions and limitations under the License. --> - - - - - + + - diff --git a/pom.xml b/pom.xml index 487e84b..05e8c78 100644 --- a/pom.xml +++ b/pom.xml @@ -67,7 +67,7 @@ - .travis.yml + .travis.yml.* From a1a1dbdfa19427824eeb8e443aea3b51fd3c9fbb Mon Sep 17 00:00:00 2001 From: Mark Struberg Date: Fri, 10 Mar 2017 17:51:56 +0100 Subject: [PATCH 4/8] move to arquillian for CDI integration --- impl/pom.xml | 87 +++++++++++++++++++ .../config/ConfigInjectionProducer.java | 37 ++++++++ .../geronimo/config/DefaultConfigBuilder.java | 2 +- impl/src/main/resources/META-INF/beans.xml | 0 4 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 impl/src/main/java/org/apache/geronimo/config/ConfigInjectionProducer.java create mode 100644 impl/src/main/resources/META-INF/beans.xml diff --git a/impl/pom.xml b/impl/pom.xml index 0199f08..8c1790f 100644 --- a/impl/pom.xml +++ b/impl/pom.xml @@ -30,6 +30,23 @@ org.apache.geronimo.config config-impl + + 1.1.7.Final + + + + + + org.jboss.arquillian + arquillian-bom + ${arquillian.version} + pom + import + + + + + org.eclipse.microprofile.apis @@ -57,6 +74,15 @@ provided + + org.jboss.arquillian.testng + arquillian-testng-container + ${arquillian.version} + test + + + + @@ -73,4 +99,65 @@ + + + + OWB + + true + + + + 1.7.1 + + + + + org.apache.geronimo.specs + geronimo-atinject_1.0_spec + 1.0 + provided + + + org.apache.geronimo.specs + geronimo-jcdi_1.1_spec + 1.0 + provided + + + org.apache.geronimo.specs + geronimo-interceptor_1.2_spec + 1.0 + provided + + + org.apache.geronimo.specs + geronimo-el_2.2_spec + 1.0.2 + provided + + + + org.apache.openwebbeans + openwebbeans-spi + ${owb.version} + test + + + org.apache.openwebbeans + openwebbeans-impl + ${owb.version} + test + + + org.apache.openwebbeans.arquillian + owb-arquillian-standalone + ${owb.version} + test + + + + + + diff --git a/impl/src/main/java/org/apache/geronimo/config/ConfigInjectionProducer.java b/impl/src/main/java/org/apache/geronimo/config/ConfigInjectionProducer.java new file mode 100644 index 0000000..049366d --- /dev/null +++ b/impl/src/main/java/org/apache/geronimo/config/ConfigInjectionProducer.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.config; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Produces; + +import org.eclipse.microprofile.config.Config; +import org.eclipse.microprofile.config.ConfigProvider; + +/** + * @author Mark Struberg + */ +@ApplicationScoped +public class ConfigInjectionProducer { + + @Produces + @ApplicationScoped + public Config createConfig() { + return ConfigProvider.getConfig(); + } + +} diff --git a/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java b/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java index 49fbad0..0362c73 100644 --- a/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java +++ b/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java @@ -102,7 +102,7 @@ protected Collection getBuiltInConfigSources(ClassLoader configSources.add(new SystemEnvConfigSource()); configSources.add(new SystemPropertyConfigSource()); - configSources.addAll(new PropertyFileConfigSourceProvider("META-INF/microprofile-config.properties", true, forClassLoader).getConfigSources(forClassLoader)); + configSources.addAll(new PropertyFileConfigSourceProvider("internal/META-INF/microprofile-config.properties", true, forClassLoader).getConfigSources(forClassLoader)); return configSources; } diff --git a/impl/src/main/resources/META-INF/beans.xml b/impl/src/main/resources/META-INF/beans.xml new file mode 100644 index 0000000..e69de29 From 231c7a05ab353e1f38b4546ad10277cd524a7e9a Mon Sep 17 00:00:00 2001 From: Mark Struberg Date: Fri, 10 Mar 2017 17:56:36 +0100 Subject: [PATCH 5/8] add missing license --- impl/src/main/resources/META-INF/beans.xml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/impl/src/main/resources/META-INF/beans.xml b/impl/src/main/resources/META-INF/beans.xml index e69de29..48bb5d2 100644 --- a/impl/src/main/resources/META-INF/beans.xml +++ b/impl/src/main/resources/META-INF/beans.xml @@ -0,0 +1,18 @@ + From ef969116302dfc7493eae5f25ae7c532446fabbb Mon Sep 17 00:00:00 2001 From: Mark Struberg Date: Mon, 13 Mar 2017 22:34:33 +0100 Subject: [PATCH 6/8] CDI integration adopted to new TCK This currently needs a bugfix in the OWB Arquillian container to work --- impl/pom.xml | 2 +- .../apache/geronimo/config/ConfigImpl.java | 2 + .../geronimo/config/ConfigValueImpl.java | 3 + .../geronimo/config/DefaultConfigBuilder.java | 5 +- .../config/DefaultConfigProvider.java | 4 ++ .../ManualApplicationConfigBuilder.java | 49 ---------------- .../{ => cdi}/ConfigInjectionProducer.java | 2 +- .../test/GeronimoConfigArchiveProcessor.java | 56 +++++++++++++++++++ .../config/test/GeronimoConfigExtension.java | 30 ++++++++++ ...boss.arquillian.core.spi.LoadableExtension | 21 +++++++ 10 files changed, 122 insertions(+), 52 deletions(-) delete mode 100644 impl/src/main/java/org/apache/geronimo/config/ManualApplicationConfigBuilder.java rename impl/src/main/java/org/apache/geronimo/config/{ => cdi}/ConfigInjectionProducer.java (96%) create mode 100644 impl/src/test/java/org/apache/geronimo/config/test/GeronimoConfigArchiveProcessor.java create mode 100644 impl/src/test/java/org/apache/geronimo/config/test/GeronimoConfigExtension.java create mode 100644 impl/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension diff --git a/impl/pom.xml b/impl/pom.xml index 8c1790f..c4b5177 100644 --- a/impl/pom.xml +++ b/impl/pom.xml @@ -108,7 +108,7 @@ - 1.7.1 + 1.7.3-SNAPSHOT diff --git a/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java b/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java index 9e62c31..4884ef2 100644 --- a/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java +++ b/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java @@ -41,10 +41,12 @@ import org.apache.geronimo.config.converters.LongConverter; import javax.annotation.Priority; +import javax.enterprise.inject.Typed; /** * @author Mark Struberg */ +@Typed public class ConfigImpl implements Config { protected Logger logger = Logger.getLogger(ConfigImpl.class.getName()); diff --git a/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java b/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java index 90f8884..17ca81a 100644 --- a/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java +++ b/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java @@ -26,9 +26,12 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Logger; +import javax.enterprise.inject.Typed; + /** * @author Mark Struberg */ +@Typed public class ConfigValueImpl implements ConfigValue { private static final Logger logger = Logger.getLogger(ConfigValueImpl.class.getName()); diff --git a/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java b/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java index 0362c73..6aeddf0 100644 --- a/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java +++ b/impl/src/main/java/org/apache/geronimo/config/DefaultConfigBuilder.java @@ -30,12 +30,15 @@ import java.util.List; import java.util.ServiceLoader; +import javax.enterprise.inject.Typed; + import static java.util.Arrays.asList; /** * @author Romain Manni-Bucau * @author Mark Struberg */ +@Typed public class DefaultConfigBuilder implements ConfigBuilder { protected ClassLoader forClassLoader; private final List sources = new ArrayList<>(); @@ -102,7 +105,7 @@ protected Collection getBuiltInConfigSources(ClassLoader configSources.add(new SystemEnvConfigSource()); configSources.add(new SystemPropertyConfigSource()); - configSources.addAll(new PropertyFileConfigSourceProvider("internal/META-INF/microprofile-config.properties", true, forClassLoader).getConfigSources(forClassLoader)); + configSources.addAll(new PropertyFileConfigSourceProvider("/META-INF/microprofile-config.properties", true, forClassLoader).getConfigSources(forClassLoader)); return configSources; } diff --git a/impl/src/main/java/org/apache/geronimo/config/DefaultConfigProvider.java b/impl/src/main/java/org/apache/geronimo/config/DefaultConfigProvider.java index 09e3767..f28c716 100644 --- a/impl/src/main/java/org/apache/geronimo/config/DefaultConfigProvider.java +++ b/impl/src/main/java/org/apache/geronimo/config/DefaultConfigProvider.java @@ -21,6 +21,9 @@ import java.util.Iterator; import java.util.Map; import java.util.WeakHashMap; + +import javax.enterprise.inject.Typed; + import org.eclipse.microprofile.config.Config; import org.eclipse.microprofile.config.spi.ConfigBuilder; import org.eclipse.microprofile.config.spi.ConfigProviderResolver; @@ -29,6 +32,7 @@ /** * @author Mark Struberg */ +@Typed public class DefaultConfigProvider extends ConfigProviderResolver { private static Map> configs diff --git a/impl/src/main/java/org/apache/geronimo/config/ManualApplicationConfigBuilder.java b/impl/src/main/java/org/apache/geronimo/config/ManualApplicationConfigBuilder.java deleted file mode 100644 index 01ee075..0000000 --- a/impl/src/main/java/org/apache/geronimo/config/ManualApplicationConfigBuilder.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.geronimo.config; - -import org.eclipse.microprofile.config.Config; -import org.eclipse.microprofile.config.spi.ConfigProviderResolver; - -/** - * @author Mark Struberg - */ -public class ManualApplicationConfigBuilder extends DefaultConfigBuilder { - private DefaultConfigProvider configProvider; - - public ManualApplicationConfigBuilder(DefaultConfigProvider configProvider) { - this.configProvider = configProvider; - } - - @Override - public synchronized Config build() { - Config config = super.build(); - ClassLoader cl = forClassLoader; - if (cl == null) { - cl = Thread.currentThread().getContextClassLoader(); - if (cl == null) { - cl = ConfigProviderResolver.class.getClassLoader(); - } - } - Config oldConfig = configProvider.existingConfig(cl); - if (oldConfig != null) { - throw new IllegalStateException("This Application already has a registered Configuration!"); - } - configProvider.registerConfig(config, cl); - return config; - } -} diff --git a/impl/src/main/java/org/apache/geronimo/config/ConfigInjectionProducer.java b/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionProducer.java similarity index 96% rename from impl/src/main/java/org/apache/geronimo/config/ConfigInjectionProducer.java rename to impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionProducer.java index 049366d..5bd8bb1 100644 --- a/impl/src/main/java/org/apache/geronimo/config/ConfigInjectionProducer.java +++ b/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionProducer.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.geronimo.config; +package org.apache.geronimo.config.cdi; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; diff --git a/impl/src/test/java/org/apache/geronimo/config/test/GeronimoConfigArchiveProcessor.java b/impl/src/test/java/org/apache/geronimo/config/test/GeronimoConfigArchiveProcessor.java new file mode 100644 index 0000000..7316c01 --- /dev/null +++ b/impl/src/test/java/org/apache/geronimo/config/test/GeronimoConfigArchiveProcessor.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.config.test; + +import org.apache.geronimo.config.ConfigImpl; +import org.apache.geronimo.config.DefaultConfigProvider; +import org.apache.geronimo.config.cdi.ConfigInjectionProducer; +import org.apache.geronimo.config.configsource.BaseConfigSource; +import org.apache.geronimo.config.converters.BooleanConverter; +import org.eclipse.microprofile.config.spi.ConfigProviderResolver; +import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor; +import org.jboss.arquillian.test.spi.TestClass; +import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.jboss.shrinkwrap.api.spec.WebArchive; + +/** + * Adds the whole Config implementation classes and resources to the + * Arqillian deployment archive. This is needed to have the container + * pick up the beans from within the impl for the TCK tests. + * + * @author Mark Struberg + */ +public class GeronimoConfigArchiveProcessor implements ApplicationArchiveProcessor { + + @Override + public void process(Archive applicationArchive, TestClass testClass) { + if (applicationArchive instanceof WebArchive) { + JavaArchive configJar = ShrinkWrap + .create(JavaArchive.class, "geronimo-config-impl.jar") + .addPackage(ConfigImpl.class.getPackage()) + .addPackage(BooleanConverter.class.getPackage()) + .addPackage(BaseConfigSource.class.getPackage()) + .addPackage(ConfigInjectionProducer.class.getPackage()) + .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml") + .addAsServiceProvider(ConfigProviderResolver.class, DefaultConfigProvider.class); + ((WebArchive) applicationArchive).addAsLibraries(configJar); + } + } +} diff --git a/impl/src/test/java/org/apache/geronimo/config/test/GeronimoConfigExtension.java b/impl/src/test/java/org/apache/geronimo/config/test/GeronimoConfigExtension.java new file mode 100644 index 0000000..22335a0 --- /dev/null +++ b/impl/src/test/java/org/apache/geronimo/config/test/GeronimoConfigExtension.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.config.test; + +import org.jboss.arquillian.container.test.spi.client.deployment.ApplicationArchiveProcessor; +import org.jboss.arquillian.core.spi.LoadableExtension; + +/** + * @author Mark Struberg + */ +public class GeronimoConfigExtension implements LoadableExtension { + @Override + public void register(ExtensionBuilder extensionBuilder) { + extensionBuilder.service(ApplicationArchiveProcessor.class, GeronimoConfigArchiveProcessor.class); + } +} diff --git a/impl/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension b/impl/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension new file mode 100644 index 0000000..91c04d4 --- /dev/null +++ b/impl/src/test/resources/META-INF/services/org.jboss.arquillian.core.spi.LoadableExtension @@ -0,0 +1,21 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy current the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + + +org.apache.geronimo.config.test.GeronimoConfigExtension \ No newline at end of file From 594fe81cd2920a22c6965b3be9f4b4b26561af42 Mon Sep 17 00:00:00 2001 From: Ondrej Mihalyi Date: Tue, 14 Mar 2017 15:20:23 +0100 Subject: [PATCH 7/8] Aligned with branch CDI_API_direct_injection in ondrejm fork of mp-config --- impl/pom.xml | 21 +- .../apache/geronimo/config/ConfigImpl.java | 5 - .../geronimo/config/ConfigValueImpl.java | 231 ------------------ 3 files changed, 17 insertions(+), 240 deletions(-) delete mode 100644 impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java diff --git a/impl/pom.xml b/impl/pom.xml index c4b5177..725e5cc 100644 --- a/impl/pom.xml +++ b/impl/pom.xml @@ -31,7 +31,7 @@ config-impl - 1.1.7.Final + 1.1.12.Final @@ -80,6 +80,12 @@ ${arquillian.version} test + + org.jboss.arquillian.junit + arquillian-junit-container + test + + @@ -92,10 +98,17 @@ maven-surefire-plugin 2.19.1 - - tck-suite.xml - + + org.eclipse.microprofile.config.tck:microprofile-config-tck + + + + org.apache.maven.surefire + surefire-junit4 + 2.19.1 + + diff --git a/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java b/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java index 4884ef2..3eb41a8 100644 --- a/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java +++ b/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java @@ -31,7 +31,6 @@ import java.util.logging.Logger; import org.eclipse.microprofile.config.Config; -import org.eclipse.microprofile.config.ConfigValue; import org.eclipse.microprofile.config.spi.ConfigSource; import org.eclipse.microprofile.config.spi.Converter; import org.apache.geronimo.config.converters.BooleanConverter; @@ -114,10 +113,6 @@ private Converter getConverter(Class asType) { return converter; } - public ConfigValue access(String key) { - return new ConfigValueImpl(this, key); - } - @Override public Iterable getPropertyNames() { Set result = new HashSet<>(); diff --git a/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java b/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java deleted file mode 100644 index 17ca81a..0000000 --- a/impl/src/main/java/org/apache/geronimo/config/ConfigValueImpl.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.geronimo.config; - -import org.eclipse.microprofile.config.ConfigValue; -import org.eclipse.microprofile.config.spi.Converter; - -import java.util.ArrayList; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.concurrent.TimeUnit; -import java.util.logging.Logger; - -import javax.enterprise.inject.Typed; - -/** - * @author Mark Struberg - */ -@Typed -public class ConfigValueImpl implements ConfigValue { - private static final Logger logger = Logger.getLogger(ConfigValueImpl.class.getName()); - - private final ConfigImpl config; - - private String keyOriginal; - - private String keyResolved; - - private Class configEntryType = String.class; - - private String[] lookupChain; - - private boolean evaluateVariables = false; - - private long cacheTimeMs = -1; - private volatile long reloadAfter = -1; - private T lastValue = null; - private ConfigChanged valueChangeListener; - - public ConfigValueImpl(ConfigImpl config, String key) { - this.config = config; - this.keyOriginal = key; - } - - @Override - public ConfigValue as(Class clazz) { - configEntryType = clazz; - return (ConfigValue) this; - } - - - @Override - public ConfigValue cacheFor(long value, TimeUnit timeUnit) { - this.cacheTimeMs = timeUnit.toMillis(value); - return this; - } - - @Override - public ConfigValue evaluateVariables(boolean evaluateVariables) { - this.evaluateVariables = evaluateVariables; - return this; - } - - public ConfigValue withLookupChain(String... postfixNames) { - this.lookupChain = postfixNames; - return this; - } - - @Override - public T get() { - T val = getValue(); - if (val == null) { - throw new NoSuchElementException("No config value present for key " + keyOriginal); - } - return val; - } - - @Override - public Optional getOptional() { - return Optional.ofNullable(getValue()); - } - - @Override - public ConfigValue onChange(ConfigChanged valueChangeListener) { - this.valueChangeListener = valueChangeListener; - return this; - } - - @Override - public List getValueList() { - String rawList = (String) getValue(false); - List values = new ArrayList(); - StringBuilder sb = new StringBuilder(64); - for (int i= 0; i < rawList.length(); i++) { - char c = rawList.charAt(i); - if ('\\' == c) { - if (i == rawList.length()) { - throw new IllegalStateException("incorrect escaping of key " + keyOriginal + " value: " + rawList); - } - char nextChar = rawList.charAt(i+1); - if (nextChar == '\\') { - sb.append('\\'); - } - else if (nextChar == ',') { - sb.append(','); - } - i++; - } - else if (',' == c) { - addListValue(values, sb); - } - else { - sb.append(c); - } - } - addListValue(values, sb); - - return values; - } - - private void addListValue(List values, StringBuilder sb) { - String val = sb.toString().trim(); - if (!val.isEmpty()) { - values.add(convert(val)); - } - sb.setLength(0); - } - - public T getValue() { - return getValue(true); - } - - private T getValue(boolean convert) { - long now = -1; - if (cacheTimeMs > 0) - { - now = System.currentTimeMillis(); - if (now <= reloadAfter) - { - return lastValue; - } - } - - String valueStr = resolveStringValue(); - T value = convert ? convert(valueStr) : (T) valueStr; - - if (valueChangeListener != null && (value != null && !value.equals(lastValue) || (value == null && lastValue != null)) ) - { - valueChangeListener.onValueChange(keyOriginal, lastValue, value); - } - - lastValue = value; - - if (cacheTimeMs > 0) - { - reloadAfter = now + cacheTimeMs; - } - - return value; - } - - private String resolveStringValue() { - //X TODO implement lookupChain - - String value = config.getValue(keyOriginal); - if (evaluateVariables) - { - // recursively resolve any ${varName} in the value - int startVar = 0; - while ((startVar = value.indexOf("${", startVar)) >= 0) - { - int endVar = value.indexOf("}", startVar); - if (endVar <= 0) - { - break; - } - String varName = value.substring(startVar + 2, endVar); - if (varName.isEmpty()) - { - break; - } - String variableValue = config.access(varName).evaluateVariables(true).get(); - if (variableValue != null) - { - value = value.replace("${" + varName + "}", variableValue); - } - startVar++; - } - } - return value; - } - - @Override - public String getKey() { - return keyOriginal; - } - - @Override - public String getResolvedKey() { - return keyResolved; - } - - private T convert(String value) { - if (String.class == configEntryType) { - return (T) value; - } - - Converter converter = config.getConverters().get(configEntryType); - if (converter == null) { - throw new IllegalStateException("No Converter for type " + configEntryType); - } - - return (T) converter.convert(value); - } - -} From d3f6a455ac642e4015256995fa500bef142568dd Mon Sep 17 00:00:00 2001 From: Ondrej Mihalyi Date: Tue, 14 Mar 2017 20:46:49 +0100 Subject: [PATCH 8/8] Passes tests --- .../apache/geronimo/config/ConfigImpl.java | 2 + .../config/cdi/ConfigInjectionProducer.java | 2 + .../cdi/ConfigPropertyInjectionProducer.java | 120 ++++++++++++++++++ .../test/GeronimoConfigArchiveProcessor.java | 3 + 4 files changed, 127 insertions(+) create mode 100644 impl/src/main/java/org/apache/geronimo/config/cdi/ConfigPropertyInjectionProducer.java diff --git a/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java b/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java index 3eb41a8..98a8d7b 100644 --- a/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java +++ b/impl/src/main/java/org/apache/geronimo/config/ConfigImpl.java @@ -41,11 +41,13 @@ import javax.annotation.Priority; import javax.enterprise.inject.Typed; +import javax.enterprise.inject.Vetoed; /** * @author Mark Struberg */ @Typed +@Vetoed public class ConfigImpl implements Config { protected Logger logger = Logger.getLogger(ConfigImpl.class.getName()); diff --git a/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionProducer.java b/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionProducer.java index 5bd8bb1..c77ecb5 100644 --- a/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionProducer.java +++ b/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigInjectionProducer.java @@ -17,6 +17,8 @@ package org.apache.geronimo.config.cdi; import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.context.Dependent; +import javax.enterprise.inject.Any; import javax.enterprise.inject.Produces; import org.eclipse.microprofile.config.Config; diff --git a/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigPropertyInjectionProducer.java b/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigPropertyInjectionProducer.java new file mode 100644 index 0000000..44d6886 --- /dev/null +++ b/impl/src/main/java/org/apache/geronimo/config/cdi/ConfigPropertyInjectionProducer.java @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.geronimo.config.cdi; + +import java.lang.annotation.Annotation; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Date; +import javax.annotation.PostConstruct; +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.context.Dependent; +import javax.enterprise.inject.Produces; +import javax.enterprise.inject.spi.InjectionPoint; +import org.eclipse.microprofile.config.Config; +import org.eclipse.microprofile.config.ConfigProvider; +import org.eclipse.microprofile.config.inject.ConfigProperty; + +/** + * + * @author Ondrej Mihalyi + */ +@ApplicationScoped +public class ConfigPropertyInjectionProducer { + + private Config config; + + @PostConstruct + public void init() { + config = ConfigProvider.getConfig(); + } + + @Produces + @Dependent + @ConfigProperty + public Float produceFloat(InjectionPoint ip) { + return config.getValue(getConfigKeyFrom(ip), Float.class).orElse(null); + } + + @Produces + @Dependent + @ConfigProperty + public String produceString(InjectionPoint ip) { + return config.getString(getConfigKeyFrom(ip)).orElse(null); + } + + @Produces + @Dependent + @ConfigProperty + public Boolean produceBoolean(InjectionPoint ip) { + return config.getValue(getConfigKeyFrom(ip), Boolean.class).orElse(null); + } + + @Produces + @Dependent + @ConfigProperty + public Integer produceInteger(InjectionPoint ip) { + return config.getValue(getConfigKeyFrom(ip), Integer.class).orElse(null); + } + + @Produces + @Dependent + @ConfigProperty + public Long produceLong(InjectionPoint ip) { + return config.getValue(getConfigKeyFrom(ip), Long.class).orElse(null); + } + + @Produces + @Dependent + @ConfigProperty + public Double produceDouble(InjectionPoint ip) { + return config.getValue(getConfigKeyFrom(ip), Double.class).orElse(null); + } + + private String getConfigKeyFrom(InjectionPoint ip) { + String configKey = getConfigKeyFromQualifier(ip); + if (configKey == null) { + configKey = getGeneratedConfigKey(ip); + } + if (configKey == null) { + throw new IllegalArgumentException("The injection point (" + ip + ") doesn't define a config key"); + } + return configKey; + } + + private String getGeneratedConfigKey(InjectionPoint ip) { + if (ip.getBean() != null && ip.getBean().getBeanClass() != null) { + if (ip.getMember() != null) { + return ip.getBean().getBeanClass().getSimpleName() + "." + ip.getMember().getName(); + } + } + return null; + } + + private String getConfigKeyFromQualifier(InjectionPoint ip) { + for (Annotation q : ip.getQualifiers()) { + if (q.annotationType().equals(ConfigProperty.class)) { + ConfigProperty cp = (ConfigProperty)q; + if (!cp.value().isEmpty()) { + return cp.value(); + } + } + } + return null; + } +} diff --git a/impl/src/test/java/org/apache/geronimo/config/test/GeronimoConfigArchiveProcessor.java b/impl/src/test/java/org/apache/geronimo/config/test/GeronimoConfigArchiveProcessor.java index 7316c01..e06c099 100644 --- a/impl/src/test/java/org/apache/geronimo/config/test/GeronimoConfigArchiveProcessor.java +++ b/impl/src/test/java/org/apache/geronimo/config/test/GeronimoConfigArchiveProcessor.java @@ -16,6 +16,7 @@ */ package org.apache.geronimo.config.test; +import java.io.File; import org.apache.geronimo.config.ConfigImpl; import org.apache.geronimo.config.DefaultConfigProvider; import org.apache.geronimo.config.cdi.ConfigInjectionProducer; @@ -27,6 +28,7 @@ import org.jboss.shrinkwrap.api.Archive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.exporter.ZipExporter; import org.jboss.shrinkwrap.api.spec.JavaArchive; import org.jboss.shrinkwrap.api.spec.WebArchive; @@ -51,6 +53,7 @@ public void process(Archive applicationArchive, TestClass testClass) { .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml") .addAsServiceProvider(ConfigProviderResolver.class, DefaultConfigProvider.class); ((WebArchive) applicationArchive).addAsLibraries(configJar); + applicationArchive.as(ZipExporter.class).exportTo(new File("/home/omihalyi/mp-config.war"), true); } } }