You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@deltaspike.apache.org by st...@apache.org on 2018/04/27 18:54:53 UTC

deltaspike git commit: DELTASPIKE-1335 add onChange callback and improve docs for ConfigSnapshot logic

Repository: deltaspike
Updated Branches:
  refs/heads/master a13c57ff2 -> 6e7005fe3


DELTASPIKE-1335 add onChange callback and improve docs for ConfigSnapshot logic


Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo
Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/6e7005fe
Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/6e7005fe
Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/6e7005fe

Branch: refs/heads/master
Commit: 6e7005fe35cf0a608e84ee8e7534ba6510e9b838
Parents: a13c57f
Author: Mark Struberg <st...@apache.org>
Authored: Fri Apr 27 20:54:13 2018 +0200
Committer: Mark Struberg <st...@apache.org>
Committed: Fri Apr 27 20:54:13 2018 +0200

----------------------------------------------------------------------
 .../core/api/config/ConfigResolver.java         | 31 +++++++++++++++++
 .../deltaspike/core/impl/config/ConfigImpl.java |  2 +-
 .../core/impl/config/TypedResolverImpl.java     | 22 ++++++++++--
 .../core/api/config/ConfigResolverTest.java     | 36 ++++++++++++++++++++
 4 files changed, 88 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/deltaspike/blob/6e7005fe/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
index fdb8245..bd087fc 100644
--- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
+++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java
@@ -497,6 +497,26 @@ public final class ConfigResolver
         TypedResolver<T> logChanges(boolean logChanges);
 
         /**
+         * A user can register a Callback which gets notified whenever
+         * a config change got detected.
+         * The check is performed on every call to {@link #getValue()}
+         * and also inside {@link Config#snapshotFor(TypedResolver...)}.
+         *
+         * If a change got detected the {@param valueChangedCallback} will
+         * get invoked in a synchronous way before the {@link #getValue()}
+         * or {@link Config#snapshotFor(TypedResolver...)} returns.
+         *
+         * There can only be a single valueChangedCallback.
+         * Using this method multiple times will replace the previously set callback.
+         *
+         * @param valueChangedCallback a lambda or implementation which will get invoked
+         *                             whenever a value change is being detected.
+         * @return This builder
+         */
+        TypedResolver<T> onChange(ConfigChanged<T> valueChangedCallback);
+
+
+        /**
          * Returns the converted resolved filtered value.
          * @return the resolved value
          */
@@ -507,6 +527,8 @@ public final class ConfigResolver
          *
          * @return the resolved Value
          * @see Config#snapshotFor(TypedResolver[])
+         * @throws IllegalArgumentException if the {@link ConfigSnapshot} hasn't been resolved
+         *          for this {@link TypedResolver}
          */
         T getValue(ConfigSnapshot configSnapshot);
 
@@ -625,4 +647,13 @@ public final class ConfigResolver
 
         void releaseConfig(ClassLoader cl);
     }
+
+    /**
+     * Callback which can be used with {@link TypedResolver#onChange(ConfigChanged)}
+     */
+    public interface ConfigChanged<T>
+    {
+        void onValueChange(String key, T oldValue, T newValue);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/6e7005fe/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigImpl.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigImpl.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigImpl.java
index 558f3bb..2e7c48c 100644
--- a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigImpl.java
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/ConfigImpl.java
@@ -130,7 +130,7 @@ public class ConfigImpl implements Config
     }
 
     @Override
-    public ConfigSnapshot snapshotFor(ConfigResolver.TypedResolver<?>[] typedResolvers)
+    public ConfigSnapshot snapshotFor(ConfigResolver.TypedResolver<?>... typedResolvers)
     {
         // we implement kind of optimistic Locking
         // Means we try multiple time to resolve all the given values

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/6e7005fe/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/TypedResolverImpl.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/TypedResolverImpl.java b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/TypedResolverImpl.java
index e45b4b6..cd981cf 100644
--- a/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/TypedResolverImpl.java
+++ b/deltaspike/core/impl/src/main/java/org/apache/deltaspike/core/impl/config/TypedResolverImpl.java
@@ -64,7 +64,9 @@ public class TypedResolverImpl<T> implements ConfigResolver.UntypedResolver<T>
     private ConfigResolver.Converter<?> converter;
 
     private boolean evaluateVariables = false;
+
     private boolean logChanges = false;
+    private ConfigResolver.ConfigChanged<T> valueChangedCallback = null;
 
     private long cacheTimeMs = -1;
 
@@ -210,6 +212,13 @@ public class TypedResolverImpl<T> implements ConfigResolver.UntypedResolver<T>
     }
 
     @Override
+    public ConfigResolver.TypedResolver<T> onChange(ConfigResolver.ConfigChanged<T> valueChangedCallback)
+    {
+        this.valueChangedCallback = valueChangedCallback;
+        return this;
+    }
+
+    @Override
     public T getValue(ConfigSnapshot snapshot)
     {
         ConfigSnapshotImpl snapshotImpl = (ConfigSnapshotImpl) snapshot;
@@ -264,10 +273,19 @@ public class TypedResolverImpl<T> implements ConfigResolver.UntypedResolver<T>
             }
         }
 
-        if (logChanges && (value != null && !value.equals(lastValue) || (value == null && lastValue != null)))
+        if ((logChanges || valueChangedCallback != null)
+            && (value != null && !value.equals(lastValue) || (value == null && lastValue != null)))
         {
-            LOG.log(Level.INFO, "New value {0} for key {1}.",
+            if (logChanges)
+            {
+                LOG.log(Level.INFO, "New value {0} for key {1}.",
                     new Object[]{ConfigResolver.filterConfigValueForLog(keyOriginal, valueStr), keyOriginal});
+            }
+
+            if (valueChangedCallback != null)
+            {
+                valueChangedCallback.onValueChange(keyOriginal, lastValue, value);
+            }
         }
 
         lastValue = value;

http://git-wip-us.apache.org/repos/asf/deltaspike/blob/6e7005fe/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/ConfigResolverTest.java
----------------------------------------------------------------------
diff --git a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/ConfigResolverTest.java b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/ConfigResolverTest.java
index 44eea3f..5273fcd 100644
--- a/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/ConfigResolverTest.java
+++ b/deltaspike/core/impl/src/test/java/org/apache/deltaspike/test/core/api/config/ConfigResolverTest.java
@@ -29,6 +29,7 @@ import org.junit.Test;
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
 
 @SuppressWarnings("Duplicates")
 public class ConfigResolverTest
@@ -214,6 +215,41 @@ public class ConfigResolverTest
     }
     
     @Test
+    public void testTypedResolver_OnChange()
+    {
+        final String key = "non.existing.key";
+
+        final AtomicInteger valueChanged = new AtomicInteger(0);
+
+        ConfigResolver.TypedResolver<String> resolver = ConfigResolver.resolve(key)
+            .logChanges(true)
+            .onChange((k, oldValue, newValue) ->
+            {
+                Assert.assertEquals(key, k);
+                valueChanged.incrementAndGet();
+            });
+
+        Assert.assertNull(resolver.getValue());
+
+        setTestConfigSourceValue(key, "somevalue");
+        Assert.assertEquals("somevalue", resolver.getValue());
+        Assert.assertEquals(1, valueChanged.get());
+
+        setTestConfigSourceValue(key, "newvalue");
+        Assert.assertEquals("newvalue", resolver.getValue());
+        Assert.assertEquals(2, valueChanged.get());
+
+        // this time we do not change anything
+        Assert.assertEquals("newvalue", resolver.getValue());
+        Assert.assertEquals(2, valueChanged.get());
+
+        // last change
+        setTestConfigSourceValue(key, null);
+        Assert.assertNull(resolver.getValue());
+        Assert.assertEquals(3, valueChanged.get());
+    }
+
+    @Test
     public void testProjectStageAwarePropertyValueReference_1() {
         final String expectedFooUrl =
                 "http://bar-dev/services";