Skip to content

Commit

Permalink
refactor #384 to update api and only track the dynamic config updates
Browse files Browse the repository at this point in the history
Signed-off-by: Emily Jiang <[email protected]>
  • Loading branch information
Emily-Jiang committed Dec 9, 2018
2 parents 5c29d64 + a6717b5 commit bd2b3c9
Show file tree
Hide file tree
Showing 21 changed files with 1,001 additions and 60 deletions.
5 changes: 4 additions & 1 deletion api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,15 @@
</archive>
</configuration>
</plugin>
<!--
messed up again. Too tired to battle this plugin...
<plugin>
<groupId>biz.aQute.bnd</groupId>
<artifactId>bnd-baseline-maven-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<base>
<version>1.2.1</version>
<version>1.3</version>
</base>
</configuration>
<executions>
Expand All @@ -114,6 +116,7 @@
</execution>
</executions>
</plugin>
-->
</plugins>
</build>

Expand Down
101 changes: 84 additions & 17 deletions api/src/main/java/org/eclipse/microprofile/config/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
* Extracted the Config part out of Apache DeltaSpike and proposed as Microprofile-Config
* 2016-11-14 - Emily Jiang / IBM Corp
* Experiments with separate methods per type, JavaDoc, method renaming
* 2018-04-04 - Mark Struberg, Manfred Huber, Alex Falb, Gerhard Petracek
* ConfigSnapshot added. Initially authored in Apache DeltaSpike fdd1e3dcd9a12ceed831dd
* Additional reviews and feedback by Tomas Langer.
*
*******************************************************************************/

Expand All @@ -44,13 +47,11 @@
* <p>If multiple {@link ConfigSource ConfigSources} are specified with
* the same ordinal, the {@link ConfigSource#getName()} will be used for sorting.
* <p>
* The config objects produced via the injection model <pre>@Inject Config</pre> are guaranteed to be serializable, while
* The config objects produced via the injection model {@code @Inject Config} are guaranteed to be serializable, while
* the programmatically created ones are not required to be serializable.
* <p>
* If one or more converters are registered for a class of a requested value then one of the registered converters
* which has the highest priority is used to convert the string value retrieved from config sources.
* The highest priority means the highest priority number.
* For more information about converters, see {@link org.eclipse.microprofile.config.spi.Converter}
* If one or more converters are registered for a class of a requested value then the registered {@link org.eclipse.microprofile.config.spi.Converter}
* which has the highest {@code @javax.annotation.Priority} is used to convert the string value retrieved from the config sources.
*
* <h3>Usage</h3>
*
Expand All @@ -63,6 +64,11 @@
* Integer archivePort = cfg.getValue("my.project.archive.port", Integer.class);
* </pre>
*
* <p>For accessing a configuration in a dynamic way you can also use {@link #access(String, Class)}.
* This method returns a builder {@link ConfigAccessorBuilder} instance for the given key.
* You can further specify a Type of the underlying configuration, a cache time, lookup paths and
* many more.
*
* <p>It is also possible to inject the Config if a DI container is available:
*
* <pre>
Expand All @@ -72,7 +78,8 @@
* }
* </pre>
*
* <p>See {@link #getValue(String, Class)} and {@link #getOptionalValue(String, Class)} for accessing a configured value.
* <p>See {@link #getValue(String, Class)} and {@link #getOptionalValue(String, Class)} and
* {@link #access(String, Class)} for accessing a configured value.
*
* <p>Configured values can also be accessed via injection.
* See {@link org.eclipse.microprofile.config.inject.ConfigProperty} for more information.
Expand All @@ -82,6 +89,8 @@
* @author <a href="mailto:[email protected]">Ron Smeral</a>
* @author <a href="mailto:[email protected]">Emily Jiang</a>
* @author <a href="mailto:[email protected]">Gunnar Morling</a>
* @author <a href="mailto:[email protected]">Manfred Huber</a>
* @author <a href="mailto:[email protected]">Alex Falb</a>
*
*/
@org.osgi.annotation.versioning.ProviderType
Expand All @@ -90,47 +99,105 @@ public interface Config {
/**
* Return the resolved property value with the specified type for the
* specified property name from the underlying {@link ConfigSource ConfigSources}.
*
*
* If this method gets used very often then consider to locally store the configured value.
*
* @param <T>
* The property type
* <p>Note that no variable replacement like in {@link ConfigAccessorBuilder#evaluateVariables(boolean)} will be performed!
*
* @param <T> the property type
* @param propertyName
* The configuration propertyName.
* @param propertyType
* The type into which the resolve property value should get converted
* @return the resolved property value as an object of the requested type.
* @throws java.lang.IllegalArgumentException if the property cannot be converted to the specified type.
* @throws IllegalArgumentException if the property cannot be converted to the specified type.
* @throws java.util.NoSuchElementException if the property isn't present in the configuration.
*/
<T> T getValue(String propertyName, Class<T> propertyType);

/**
* Return the resolved property value with the specified type for the
* specified property name from the underlying {@link ConfigSource ConfigSources}.
*
*
* If this method is used very often then consider to locally store the configured value.
*
* @param <T>
* The property type
* <p>Note that no variable replacement like in {@link ConfigAccessorBuilder#evaluateVariables(boolean)} will be performed!
*
* @param <T> the property type
* @param propertyName
* The configuration propertyName.
* @param propertyType
* The type into which the resolve property value should be converted
* @return The resolved property value as an Optional of the requested type.
* @return the resolved property value as an Optional of the requested type.
*
* @throws java.lang.IllegalArgumentException if the property cannot be converted to the specified type.
* @throws IllegalArgumentException if the property cannot be converted to the specified type.
*/
<T> Optional<T> getOptionalValue(String propertyName, Class<T> propertyType);

/**
* Return a collection of property names.
* Create a {@link ConfigAccessor} to access the underlying configuration.
*
* @param propertyName the property key
* @param type type into which the resolve property value should get converted
* @param <T> the property type
* @return a {@code ConfigAccessor} to access the given propertyName
*/
<T> ConfigAccessorBuilder<T> access(String propertyName, Class<T> type);

/**
* <p>This method can be used to access multiple
* {@link ConfigAccessor} which must be consistent.
* The returned {@link ConfigSnapshot} is an immutable object which contains all the
* resolved values at the time of calling this method.
*
* <p>An example would be to access some {@code 'myapp.host'} and {@code 'myapp.port'}:
* The underlying values are {@code 'oldserver'} and {@code '8080'}.
*
* <pre>
* // get the current host value
* ConfigAccessor&lt;String&gt; hostCfg config.access("myapp.host", String.class)
* .cacheFor(60, TimeUnit.MINUTES)
* .build();
*
* // and right in between the underlying values get changed to 'newserver' and port 8082
*
* // get the current port for the host
* ConfigAccessor&lt;Integer&gt; portCfg config.access("myapp.port", Integer.class)
* .cacheFor(60, TimeUnit.MINUTES)
* .build();
* </pre>
*
* In ths above code we would get the combination of {@code 'oldserver'} but with the new port {@code 8081}.
* And this will obviously blow up because that host+port combination doesn't exist.
*
* To consistently access n different config values we can start a {@link ConfigSnapshot} for those values.
*
* <pre>
* ConfigSnapshot cfgSnap = config.createSnapshot(hostCfg, portCfg);
*
* String host = hostCfg.getValue(cfgSnap);
* Integer port = portCfg.getValue(cfgSnap);
* </pre>
*
* Note that there is no <em>close</em> on the snapshot.
* They should be used as local variables inside a method.
* Values will not be reloaded for an open {@link ConfigSnapshot}.
*
* @param configValues the list of {@link ConfigAccessor} to be accessed in an atomic way
*
* @return a new {@link ConfigSnapshot} which holds the resolved values of all the {@code configValues}.
*/
ConfigSnapshot snapshotFor(ConfigAccessor<?>... configValues);


/**
* Return all property names used in any of the underlying {@link ConfigSource ConfigSources}.
* @return the names of all configured keys of the underlying configuration.
*/
Iterable<String> getPropertyNames();

/**
* @return all currently registered {@link ConfigSource configsources} sorted with descending ordinal and ConfigSource name
* @return all currently registered {@link ConfigSource ConfigSources} sorted by descending ordinal and ConfigSource name
*/
Iterable<ConfigSource> getConfigSources();
}
118 changes: 118 additions & 0 deletions api/src/main/java/org/eclipse/microprofile/config/ConfigAccessor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
******************************************************************************
* Copyright (c) 2009-2018 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* 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.
*
* Contributors:
* 2011-12-28 - Mark Struberg & Gerhard Petracek
* Contributed to Apache DeltaSpike fb0131106481f0b9a8fd
* 2016-07-07 - Mark Struberg
* Extracted the Config part out of DeltaSpike and proposed as Microprofile-Config 8ff76eb3bcfaf4fd
*
*******************************************************************************/
package org.eclipse.microprofile.config;


import java.util.Optional;


/**
* Accessor to a configured value.
*
* It follows a builder-like pattern to define in which ways to access the configured value
* of a certain property name.
*
* Accessing the configured value is finally done via {@link #getValue()}
*
* @author <a href="mailto:[email protected]">Mark Struberg</a>
* @author <a href="mailto:[email protected]">Gerhard Petracek</a>
* @author <a href="mailto:[email protected]">Tomas Langer</a>
*/
public interface ConfigAccessor<T> {

/**
* Returns the converted resolved filtered value.
* @return the resolved value
*
* @throws IllegalArgumentException if the property cannot be converted to the specified type.
* @throws java.util.NoSuchElementException if the property isn't present in the configuration.
*/
T getValue();


/**
* Returns the value from a previously taken {@link ConfigSnapshot}.
*
* @param configSnapshot previously taken via {@link Config#snapshotFor(ConfigAccessor[])}
* @return the resolved Value
* @see Config#snapshotFor(ConfigAccessor...)
* @throws IllegalArgumentException if the {@link ConfigSnapshot} hasn't been resolved
* for this {@link ConfigAccessor}
*/
T getValue(ConfigSnapshot configSnapshot);

/**
* Returns the value from a previously taken {@link ConfigSnapshot}.
*
* @param configSnapshot previously taken via {@link Config#snapshotFor(ConfigAccessor[])}
* @return the resolved value as Optional
* @see Config#snapshotFor(ConfigAccessor...)
* @throws IllegalArgumentException if the {@link ConfigSnapshot} hasn't been resolved
* for this {@link ConfigAccessor}
*/
Optional<T> getOptionalValue(ConfigSnapshot configSnapshot);


/**
* Returns the converted resolved filtered value.
* @return the resolved value as Optional
*
* @throws IllegalArgumentException if the property cannot be converted to the specified type.
*/
Optional<T> getOptionalValue();

/**
* Returns the property name key given in {@link Config#access(String, Class)}.
* @return the original property name
*/
String getPropertyName();

/**
* Returns the actual key which led to successful resolution and corresponds to the resolved value.
* This is useful when {@link ConfigAccessorBuilder#addLookupSuffix(String)} is used.
* Otherwise the resolved key should always be equal to the original key.
* This method is provided for cases, when parameterized resolution is
* requested 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).
*
* Note that this will only give you the resolved key from the last non-cached value resolving.
* @return the actual property name which led to successful resolution and corresponds to the resolved value.
*/
String getResolvedPropertyName();

/**
* Returns the default value provided by {@link ConfigAccessorBuilder#withDefault(Object)}
* or {@link ConfigAccessorBuilder#withStringDefault(String)}.
*
* @return the default value or {@code null} if no default was provided.
*/
T getDefaultValue();

}

Loading

0 comments on commit bd2b3c9

Please sign in to comment.