Skip to content

Commit

Permalink
Refactor #384
Browse files Browse the repository at this point in the history
Update the onAttributeChange method to return a ChangeSupport class that
can be used to handle release of resources (in the close method).

When a Config is released, it should call ChangeSupport.close to ensure
that the ConfigSource has a chance to properly release any resources
held by the callbacks.

* Add TCK test ConfigAccessorTest#testOnAttributeChange

Signed-off-by: Jeff Mesnil <[email protected]>
  • Loading branch information
jmesnil committed Feb 11, 2019
1 parent 20e1d59 commit 7183da6
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@
* Extracted the Config part out of DeltaSpike and proposed as Microprofile-Config cf41cf130bcaf5447ff8
* 2016-11-14 - Emily Jiang / IBM Corp
* Methods renamed, JavaDoc and cleanup
*
*
*
*******************************************************************************/
package org.eclipse.microprofile.config.spi;

import java.io.Closeable;
import java.io.Serializable;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
Expand Down Expand Up @@ -164,18 +166,6 @@ default int getOrdinal() {
*/
String getName();

/**
* Determines if this config source should be scanned for its list of properties.
*
* Generally, slow ConfigSources should return false here.
*
* @return {@code true} if this ConfigSource should be scanned for its list of properties,
* {@code false} if it should not be scanned.
*/
default boolean isScannable() {
return true;
}

/**
* The callback should get invoked if an attribute change got detected inside the ConfigSource.
*
Expand All @@ -188,33 +178,42 @@ default boolean isScannable() {
default ChangeSupport onAttributeChange(Consumer<Set<String>> callback) {
// do nothing by default. Just for compat with older ConfigSources.
// return unsupported to tell config that it must re-query this source every time
return ChangeSupport.UNSUPPORTED;
return () -> ChangeSupport.Type.UNSUPPORTED;
}

/**
* What kind of change support this config source has.
* <p>
* {@link org.eclipse.microprofile.config.Config} implementations may use this information for internal optimizations.
*/
enum ChangeSupport {
/**
* Config change is supported, this config source will invoke the callback provided by
* {@link ConfigSource#onAttributeChange(Consumer)}.
* <p>
* Example: File based config source that watches the file for changes
*/
SUPPORTED,
/**
* Config change is not supported. Configuration values can change, though this change is not reported back.
* <p>
* Example: LDAP based config source
*/
UNSUPPORTED,
/**
* Configuration values cannot change for the lifetime of this {@link ConfigSource}.
* <p>
* Example: Environment variables config source, classpath resource config source
*/
IMMUTABLE
interface ChangeSupport extends Closeable, Serializable {

enum Type {
/**
* Config change is supported, this config source will invoke the callback provided by
* {@link ConfigSource#onAttributeChange(Consumer)}.
* <p>
* Example: File based config source that watches the file for changes
*/
SUPPORTED,
/**
* Config change is not supported. Configuration values can change, though this change is not reported back.
* <p>
* Example: LDAP based config source
*/
UNSUPPORTED,
/**
* Configuration values cannot change for the lifetime of this {@link ConfigSource}.
* <p>
* Example: Environment variables config source, classpath resource config source
*/
IMMUTABLE
}

Type getType();

@Override
default void close() {
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,21 @@ public void testCacheFor() throws Exception {
Assert.assertEquals(val.getValue(), "secondvalue");
}

@Test
public void testOnAttributeChange() {
String key = "tck.config.test.onattributechange.key";
ConfigurableConfigSource.configure(config, key, "firstvalue");

ConfigAccessor<String> val = config.access(key, String.class).cacheFor(Duration.ofMillis(30)).build();
Assert.assertEquals(val.getValue(), "firstvalue");

// immediately change the value on the ConfigurableConfigSource that will notify the Config of the change
ConfigurableConfigSource.configure(config, key, "secondvalue");

// we should see the new value right now as the ConfigurableConfigSource has notified that its attribute has changed
Assert.assertEquals(val.getValue(), "secondvalue");
}

@Test
public void testDefaultValue() {
String key = "tck.config.test.javaconfig.somerandom.default.key";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,15 @@ public String getName() {
@Override
public ConfigSource.ChangeSupport onAttributeChange(Consumer<Set<String>> reportAttributeChange) {
this.reportAttributeChange = reportAttributeChange;
return ChangeSupport.SUPPORTED;
return () -> ChangeSupport.Type.SUPPORTED;
}

public static void configure(Config cfg, String propertyName, String value) {
for (ConfigSource configSource : cfg.getConfigSources()) {
if (configSource instanceof ConfigurableConfigSource) {
((ConfigurableConfigSource) configSource).properties.put(propertyName, value);
((ConfigurableConfigSource) configSource).reportAttributeChange.accept(Collections.singleton(propertyName));
ConfigurableConfigSource configurableConfigSource = (ConfigurableConfigSource) configSource;
configurableConfigSource.properties.put(propertyName, value);
configurableConfigSource.reportAttributeChange.accept(Collections.singleton(propertyName));
return;
}
}
Expand Down

0 comments on commit 7183da6

Please sign in to comment.