You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tamaya.apache.org by pl...@apache.org on 2017/02/26 10:07:17 UTC

incubator-tamaya-extensions git commit: [TAMAYA-243] Fix for the DefaultConfigChangeObserver. The last used configuration was never updated after its initial assignment.

Repository: incubator-tamaya-extensions
Updated Branches:
  refs/heads/master 7c2728d1b -> 0f1a2c637


[TAMAYA-243] Fix for the DefaultConfigChangeObserver. The last used configuration was never updated after its initial assignment.


Project: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/commit/0f1a2c63
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/tree/0f1a2c63
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/diff/0f1a2c63

Branch: refs/heads/master
Commit: 0f1a2c63782bd2cb4e8da7f8e53ff713bacd4a94
Parents: 7c2728d
Author: Oliver B. Fischer <pl...@apache.org>
Authored: Sun Feb 26 11:05:11 2017 +0100
Committer: Oliver B. Fischer <pl...@apache.org>
Committed: Sun Feb 26 11:05:11 2017 +0100

----------------------------------------------------------------------
 .../events/ConfigurationChangeBuilder.java      |  51 ++++---
 .../internal/DefaultConfigChangeObserver.java   |   3 -
 .../events/ConfigurationChangeBuilderTest.java  | 139 +++++++++++++++++++
 .../tamaya/events/MethodNotMockedAnswer.java    |  37 +++++
 4 files changed, 208 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/0f1a2c63/modules/events/src/main/java/org/apache/tamaya/events/ConfigurationChangeBuilder.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/ConfigurationChangeBuilder.java b/modules/events/src/main/java/org/apache/tamaya/events/ConfigurationChangeBuilder.java
index 37232c7..651a80d 100644
--- a/modules/events/src/main/java/org/apache/tamaya/events/ConfigurationChangeBuilder.java
+++ b/modules/events/src/main/java/org/apache/tamaya/events/ConfigurationChangeBuilder.java
@@ -90,31 +90,44 @@ public final class ConfigurationChangeBuilder {
 
     /**
      * Compares the two property config/configurations and creates a collection with all changes
-     * that must be applied to render {@code original} into {@code target}.
+     * that must be applied to render {@code previous} into {@code target}.
      *
-     * @param original the original map, not null.
-     * @param target the target map, not null.
+     * @param previous the previous map, not null.
+     * @param current the target map, not null.
      * @return a collection current change events, never {@code null}.
      */
-    public static Collection<PropertyChangeEvent> compare(Configuration original, Configuration target) {
-        List<PropertyChangeEvent> changes = new ArrayList<>();
-        for (Map.Entry<String, String> en : original.getProperties().entrySet()) {
-            String val = target.get(en.getKey());
-            if (val == null) {
-                changes.add(new PropertyChangeEvent(original, en.getKey(), null, en.getValue()));
-            } else if (!val.equals(en.getValue())) {
-                changes.add(new PropertyChangeEvent(original, en.getKey(), val, en.getValue()));
+    public static Collection<PropertyChangeEvent> compare(Configuration previous, Configuration current) {
+        TreeMap<String, PropertyChangeEvent> events = new TreeMap<>();
+
+        for (Map.Entry<String, String> en : previous.getProperties().entrySet()) {
+            String key = en.getKey();
+            String previousValue = en.getValue();
+            String currentValue = current.get(en.getKey());
+
+            if (currentValue == null) {
+                PropertyChangeEvent event = new PropertyChangeEvent(previous, key, previousValue, null);
+                events.put(key, event);
+            } else if (!Objects.equals(current, previous)) {
+                PropertyChangeEvent event = new PropertyChangeEvent(previous, key, currentValue, previousValue);
+                events.put(key, event);
             }
         }
-        for (Map.Entry<String, String> en : target.getProperties().entrySet()) {
-            String val = original.get(en.getKey());
-            if (val == null) {
-                changes.add(new PropertyChangeEvent(original, en.getKey(), null, en.getValue()));
-            } else if (!val.equals(en.getValue())) {
-                changes.add(new PropertyChangeEvent(original, en.getKey(), val, en.getValue()));
+
+        for (Map.Entry<String, String> en : current.getProperties().entrySet()) {
+            String key = en.getKey();
+            String previousValue = previous.get(en.getKey());
+            String currentValue = en.getValue();
+
+            if (previousValue == null) {
+                PropertyChangeEvent event = new PropertyChangeEvent(current, key, null, currentValue);
+                events.put(key, event);
+            } else if (!(Objects.equals(previousValue, currentValue) && events.containsKey(key))) {
+                PropertyChangeEvent event = new PropertyChangeEvent(current, en.getKey(), previousValue, en.getValue());
+                events.put(key, event);
             }
         }
-        return changes;
+
+        return events.values();
     }
 
     /*
@@ -145,7 +158,7 @@ public final class ConfigurationChangeBuilder {
      * @return the builder for chaining.
      */
     public ConfigurationChangeBuilder addChanges(Configuration newState) {
-        for (PropertyChangeEvent c : compare(newState, this.source)) {
+        for (PropertyChangeEvent c : compare(this.source, newState)) {
             this.delta.put(c.getPropertyName(), c);
         }
         return this;

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/0f1a2c63/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigChangeObserver.java
----------------------------------------------------------------------
diff --git a/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigChangeObserver.java b/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigChangeObserver.java
index 95259b7..9ee5ac2 100644
--- a/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigChangeObserver.java
+++ b/modules/events/src/main/java/org/apache/tamaya/events/internal/DefaultConfigChangeObserver.java
@@ -79,9 +79,6 @@ public class DefaultConfigChangeObserver {
         }
         if(!changes.isEmpty()) {
             LOG.info("Identified configuration changes, publishing changes:\n" + changes);
-//            System.out.println("UPD detected with size=" + changes.getUpdatedSize());
-//            System.out.println("ADD detected with size=" + changes.getAddedSize());
-//            System.out.println("REM detected with size=" + changes.getRemovedSize());
             ConfigEventManager.fireEvent(changes);
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/0f1a2c63/modules/events/src/test/java/org/apache/tamaya/events/ConfigurationChangeBuilderTest.java
----------------------------------------------------------------------
diff --git a/modules/events/src/test/java/org/apache/tamaya/events/ConfigurationChangeBuilderTest.java b/modules/events/src/test/java/org/apache/tamaya/events/ConfigurationChangeBuilderTest.java
new file mode 100644
index 0000000..f249433
--- /dev/null
+++ b/modules/events/src/test/java/org/apache/tamaya/events/ConfigurationChangeBuilderTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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.tamaya.events;
+
+import org.apache.tamaya.Configuration;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.beans.PropertyChangeEvent;
+import java.util.*;
+
+import static java.util.Collections.emptyMap;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
+
+
+public class ConfigurationChangeBuilderTest {
+
+    @Test
+    public void compareReturnAnEmptyListOfChangesForTwoEmptyConfigurations() {
+        Configuration oc = Mockito.mock(Configuration.class, new MethodNotMockedAnswer());
+        Configuration nc = Mockito.mock(Configuration.class, new MethodNotMockedAnswer());
+
+        doReturn(emptyMap()).when(oc).getProperties();
+        doReturn(emptyMap()).when(nc).getProperties();
+
+        Collection<PropertyChangeEvent> diff = ConfigurationChangeBuilder.compare(oc, nc);
+
+        assertThat(diff).isNotNull().isEmpty();
+    }
+
+    @Test
+    public void compareReturnsAChangeEventIfThereIsANewKeyInTheNewVersionOfTheConfiguration() {
+        Configuration oc = Mockito.mock(Configuration.class, new MethodNotMockedAnswer());
+        Configuration nc = Mockito.mock(Configuration.class, new MethodNotMockedAnswer());
+
+        doReturn(emptyMap()).when(oc).getProperties();
+        doReturn(null).when(oc).get(eq("a"));
+
+        Map<String, String> valuesNC = new HashMap<String, String>() {{
+            put("a", "19");
+        }};
+
+        doReturn(valuesNC).when(nc).getProperties();
+        doReturn("19").when(nc).get(eq("a"));
+
+        Collection<PropertyChangeEvent> diff = ConfigurationChangeBuilder.compare(oc, nc);
+
+        assertThat(diff).isNotNull().isNotEmpty().hasSize(1);
+
+        PropertyChangeEvent change = diff.iterator().next();
+
+        assertThat(change).isNotNull();
+        assertThat(change.getNewValue()).isEqualTo("19");
+        assertThat(change.getOldValue()).isNull();
+        assertThat(change.getPropertyName()).isEqualTo("a");
+    }
+
+    @Test
+    public void compareReturnsAChangeEventIfAKeyHasBeenRemovedInTheNewVersionOfTheConfiguration() {
+        Configuration oc = Mockito.mock(Configuration.class, new MethodNotMockedAnswer());
+        Configuration nc = Mockito.mock(Configuration.class, new MethodNotMockedAnswer());
+
+        Map<String, String> valuesOC = new HashMap<String, String>() {{
+            put("a", "19");
+        }};
+
+        doReturn(valuesOC).when(oc).getProperties();
+        doReturn("19").when(oc).get(eq("a"));
+
+
+        doReturn(emptyMap()).when(nc).getProperties();
+        doReturn(null).when(nc).get(eq("a"));
+
+        Collection<PropertyChangeEvent> diff = ConfigurationChangeBuilder.compare(oc, nc);
+
+        assertThat(diff).isNotNull().isNotEmpty().hasSize(1);
+
+        PropertyChangeEvent change = diff.iterator().next();
+
+        assertThat(change).isNotNull();
+        assertThat(change.getNewValue()).isNull();
+        assertThat(change.getOldValue()).isEqualTo("19");
+        assertThat(change.getPropertyName()).isEqualTo("a");
+    }
+
+    @Test
+    public void compareReturnsAChangeEventIfValueOfExistingKeyHasChanged() {
+        Configuration oc = Mockito.mock(Configuration.class, new MethodNotMockedAnswer());
+        Configuration nc = Mockito.mock(Configuration.class, new MethodNotMockedAnswer());
+
+        Map<String, String> valuesOC = new HashMap<String, String>() {{
+            put("a", "91");
+        }};
+
+        doReturn(valuesOC).when(oc).getProperties();
+        doReturn("91").when(oc).get(eq("a"));
+        doReturn("old configuration").when(oc).toString();
+
+        Map<String, String> valuesNC = new HashMap<String, String>() {{
+            put("a", "19");
+        }};
+
+
+        doReturn(valuesNC).when(nc).getProperties();
+        doReturn("19").when(nc).get(eq("a"));
+        doReturn("new configuration").when(nc).toString();
+
+        Collection<PropertyChangeEvent> diff = ConfigurationChangeBuilder.compare(oc, nc);
+
+        assertThat(diff).isNotNull().isNotEmpty().hasSize(1);
+
+        PropertyChangeEvent change = diff.iterator().next();
+
+        assertThat(change).isNotNull();
+        assertThat(change.getNewValue()).isEqualTo("19");
+        assertThat(change.getOldValue()).isEqualTo("91");
+        assertThat(change.getPropertyName()).isEqualTo("a");
+    }
+
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-tamaya-extensions/blob/0f1a2c63/modules/events/src/test/java/org/apache/tamaya/events/MethodNotMockedAnswer.java
----------------------------------------------------------------------
diff --git a/modules/events/src/test/java/org/apache/tamaya/events/MethodNotMockedAnswer.java b/modules/events/src/test/java/org/apache/tamaya/events/MethodNotMockedAnswer.java
new file mode 100644
index 0000000..0fbcaa5
--- /dev/null
+++ b/modules/events/src/test/java/org/apache/tamaya/events/MethodNotMockedAnswer.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.tamaya.events;
+
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.lang.reflect.Method;
+
+public class MethodNotMockedAnswer implements Answer
+{
+    @Override
+    public Object answer(InvocationOnMock invocation) throws Throwable
+    {
+        Method calledMethod = invocation.getMethod();
+        String signature = calledMethod.toGenericString();
+
+        throw new RuntimeException(signature + " is not mocked!");
+    }
+}
+