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 <[email protected]> Authored: Sun Feb 26 11:05:11 2017 +0100 Committer: Oliver B. Fischer <[email protected]> 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!"); + } +} +
