From 79e71e14c10670696b93807657411ab969edae26 Mon Sep 17 00:00:00 2001 From: Jan Hajnar Date: Tue, 5 Aug 2014 12:25:44 +0200 Subject: [PATCH] Bug 1418 - onDataChange notification is not returning any data to the getCreatedData and getModifiedData function calls. Data change notification does not seem to work. * Changed normalized to binding data change event translation call to include event listener path. This path is then used to decode leaf or mixin only augmentation because it can't be injected through children. * Added verification tests. Change-Id: Ia9d936f17b30b94fe4878e343cff7babb8d29d0f Signed-off-by: Jan Hajnar --- .../impl/AbstractForwardedDataBroker.java | 18 ++- .../impl/test/Bug1418AugmentationTest.java | 135 ++++++++++++++++++ .../test/model/util/ListsBindingUtils.java | 12 +- 3 files changed, 157 insertions(+), 8 deletions(-) create mode 100644 opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1418AugmentationTest.java diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedDataBroker.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedDataBroker.java index 2d81b6022d..e632e6336a 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedDataBroker.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedDataBroker.java @@ -97,6 +97,7 @@ public abstract class AbstractForwardedDataBroker implements Delegator, DataObject> toBinding( + InstanceIdentifier path, final Map> normalized) { Map, DataObject> newMap = new HashMap<>(); @@ -107,6 +108,11 @@ public abstract class AbstractForwardedDataBroker implements Delegator, DataObject> binding = potential.get(); newMap.put(binding.getKey(), binding.getValue()); + } else if (entry.getKey().getLastPathArgument() instanceof YangInstanceIdentifier.AugmentationIdentifier) { + DataObject bindingDataObject = getCodec().toBinding(path, entry.getValue()); + if (bindingDataObject != null) { + newMap.put(path, bindingDataObject); + } } } catch (DeserializationException e) { LOG.warn("Failed to transform {}, omitting it", entry, e); @@ -148,7 +154,7 @@ public abstract class AbstractForwardedDataBroker implements Delegator> toBinding( + protected Set> toBinding(InstanceIdentifier path, final Set normalized) { Set> hashSet = new HashSet<>(); for (YangInstanceIdentifier normalizedPath : normalized) { @@ -157,6 +163,8 @@ public abstract class AbstractForwardedDataBroker implements Delegator binding = potential.get(); hashSet.add(binding); + } else if (normalizedPath.getLastPathArgument() instanceof YangInstanceIdentifier.AugmentationIdentifier) { + hashSet.add(path); } } catch (DeserializationException e) { LOG.warn("Failed to transform {}, omitting it", normalizedPath, e); @@ -219,7 +227,7 @@ public abstract class AbstractForwardedDataBroker implements Delegator, DataObject> getCreatedData() { if (createdCache == null) { - createdCache = Collections.unmodifiableMap(toBinding(domEvent.getCreatedData())); + createdCache = Collections.unmodifiableMap(toBinding(path, domEvent.getCreatedData())); } return createdCache; } @@ -227,7 +235,7 @@ public abstract class AbstractForwardedDataBroker implements Delegator, DataObject> getUpdatedData() { if (updatedCache == null) { - updatedCache = Collections.unmodifiableMap(toBinding(domEvent.getUpdatedData())); + updatedCache = Collections.unmodifiableMap(toBinding(path, domEvent.getUpdatedData())); } return updatedCache; @@ -236,7 +244,7 @@ public abstract class AbstractForwardedDataBroker implements Delegator> getRemovedPaths() { if (removedCache == null) { - removedCache = Collections.unmodifiableSet(toBinding(domEvent.getRemovedPaths())); + removedCache = Collections.unmodifiableSet(toBinding(path, domEvent.getRemovedPaths())); } return removedCache; } @@ -244,7 +252,7 @@ public abstract class AbstractForwardedDataBroker implements Delegator, DataObject> getOriginalData() { if (originalCache == null) { - originalCache = Collections.unmodifiableMap(toBinding(domEvent.getOriginalData())); + originalCache = Collections.unmodifiableMap(toBinding(path, domEvent.getOriginalData())); } return originalCache; diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1418AugmentationTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1418AugmentationTest.java new file mode 100644 index 0000000000..6b5c825b83 --- /dev/null +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/Bug1418AugmentationTest.java @@ -0,0 +1,135 @@ +package org.opendaylight.controller.md.sal.binding.impl.test; + +import org.junit.Test; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.binding.test.AbstractDataChangeListenerTest; +import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker; +import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.TreeComplexUsesAugment; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.TreeLeafOnlyUsesAugment; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.complex.from.grouping.ListViaUses; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.complex.from.grouping.ListViaUsesKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.Top; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.two.level.list.TopLevelListKey; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +import static org.junit.Assert.assertTrue; +import static org.opendaylight.controller.md.sal.binding.test.AssertCollections.assertContains; +import static org.opendaylight.controller.md.sal.binding.test.AssertCollections.assertEmpty; +import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.top; +import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.TOP_FOO_KEY; +import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.topLevelList; +import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.leafOnlyUsesAugment; +import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.complexUsesAugment; + +public class Bug1418AugmentationTest extends AbstractDataChangeListenerTest{ + private static final InstanceIdentifier TOP = InstanceIdentifier.create(Top.class); + private static final InstanceIdentifier TOP_FOO = TOP.child(TopLevelList.class, TOP_FOO_KEY); + private static final InstanceIdentifier SIMPLE_AUGMENT = + TOP.child(TopLevelList.class, TOP_FOO_KEY).augmentation(TreeLeafOnlyUsesAugment.class); + private static final InstanceIdentifier COMPLEX_AUGMENT = + TOP.child(TopLevelList.class, TOP_FOO_KEY).augmentation(TreeComplexUsesAugment.class); + private static final ListViaUsesKey LIST_VIA_USES_KEY = + new ListViaUsesKey("list key"); + private static final ListViaUsesKey LIST_VIA_USES_KEY_MOD = + new ListViaUsesKey("list key modified"); + + @Test + public void leafOnlyAugmentationCreatedTest() { + TestListener listener = createListener(LogicalDatastoreType.CONFIGURATION, SIMPLE_AUGMENT, + AsyncDataBroker.DataChangeScope.SUBTREE); + WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction(); + writeTx.put(LogicalDatastoreType.CONFIGURATION, TOP, top()); + writeTx.put(LogicalDatastoreType.CONFIGURATION, TOP_FOO, topLevelList(new TopLevelListKey(TOP_FOO_KEY))); + writeTx.put(LogicalDatastoreType.CONFIGURATION, SIMPLE_AUGMENT, leafOnlyUsesAugment("test leaf")); + assertCommit(writeTx.submit()); + assertTrue(listener.hasEvent()); + AsyncDataChangeEvent, DataObject> event = listener.event(); + assertContains(event.getCreatedData(), SIMPLE_AUGMENT); + assertEmpty(event.getUpdatedData()); + assertEmpty(event.getOriginalData()); + assertEmpty(event.getRemovedPaths()); + } + + @Test + public void leafOnlyAugmentationUpdatedTest() { + WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction(); + writeTx.put(LogicalDatastoreType.CONFIGURATION, TOP, top()); + writeTx.put(LogicalDatastoreType.CONFIGURATION, TOP_FOO, topLevelList(new TopLevelListKey(TOP_FOO_KEY))); + writeTx.put(LogicalDatastoreType.CONFIGURATION, SIMPLE_AUGMENT, leafOnlyUsesAugment("test leaf")); + assertCommit(writeTx.submit()); + TestListener listener = createListener(LogicalDatastoreType.CONFIGURATION, SIMPLE_AUGMENT, + AsyncDataBroker.DataChangeScope.SUBTREE); + writeTx = getDataBroker().newWriteOnlyTransaction(); + writeTx.put(LogicalDatastoreType.CONFIGURATION, SIMPLE_AUGMENT, leafOnlyUsesAugment("test leaf changed")); + assertCommit(writeTx.submit()); + assertTrue(listener.hasEvent()); + AsyncDataChangeEvent, DataObject> event = listener.event(); + assertContains(event.getUpdatedData(), SIMPLE_AUGMENT); + assertContains(event.getOriginalData(), SIMPLE_AUGMENT); + assertEmpty(event.getCreatedData()); + assertEmpty(event.getRemovedPaths()); + } + + @Test + public void leafOnlyAugmentationDeletedTest() { + WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction(); + writeTx.put(LogicalDatastoreType.CONFIGURATION, TOP, top()); + writeTx.put(LogicalDatastoreType.CONFIGURATION, TOP_FOO, topLevelList(new TopLevelListKey(TOP_FOO_KEY))); + writeTx.put(LogicalDatastoreType.CONFIGURATION, SIMPLE_AUGMENT, leafOnlyUsesAugment("test leaf")); + assertCommit(writeTx.submit()); + TestListener listener = createListener(LogicalDatastoreType.CONFIGURATION, SIMPLE_AUGMENT, + AsyncDataBroker.DataChangeScope.SUBTREE); + writeTx = getDataBroker().newWriteOnlyTransaction(); + writeTx.delete(LogicalDatastoreType.CONFIGURATION, SIMPLE_AUGMENT); + assertCommit(writeTx.submit()); + assertTrue(listener.hasEvent()); + AsyncDataChangeEvent, DataObject> event = listener.event(); + assertContains(event.getRemovedPaths(), SIMPLE_AUGMENT); + assertContains(event.getOriginalData(), SIMPLE_AUGMENT); + assertEmpty(event.getCreatedData()); + assertEmpty(event.getUpdatedData()); + } + + @Test + public void complexAugmentationCreatedTest() { + TestListener listener = createListener(LogicalDatastoreType.CONFIGURATION, COMPLEX_AUGMENT, + AsyncDataBroker.DataChangeScope.SUBTREE); + WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction(); + writeTx.put(LogicalDatastoreType.CONFIGURATION, TOP, top()); + writeTx.put(LogicalDatastoreType.CONFIGURATION, TOP_FOO, topLevelList(new TopLevelListKey(TOP_FOO_KEY))); + writeTx.put(LogicalDatastoreType.CONFIGURATION, COMPLEX_AUGMENT, complexUsesAugment(LIST_VIA_USES_KEY)); + assertCommit(writeTx.submit()); + assertTrue(listener.hasEvent()); + AsyncDataChangeEvent, DataObject> event = listener.event(); + assertContains(event.getCreatedData(), COMPLEX_AUGMENT); + assertContains(event.getCreatedData(), COMPLEX_AUGMENT.child(ListViaUses.class, LIST_VIA_USES_KEY)); + assertEmpty(event.getUpdatedData()); + assertEmpty(event.getOriginalData()); + assertEmpty(event.getRemovedPaths()); + } + + @Test + public void complexAugmentationUpdatedTest() { + WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction(); + writeTx.put(LogicalDatastoreType.CONFIGURATION, TOP, top()); + writeTx.put(LogicalDatastoreType.CONFIGURATION, TOP_FOO, topLevelList(new TopLevelListKey(TOP_FOO_KEY))); + writeTx.put(LogicalDatastoreType.CONFIGURATION, COMPLEX_AUGMENT, complexUsesAugment(LIST_VIA_USES_KEY)); + assertCommit(writeTx.submit()); + TestListener listener = createListener(LogicalDatastoreType.CONFIGURATION, COMPLEX_AUGMENT, + AsyncDataBroker.DataChangeScope.SUBTREE); + writeTx = getDataBroker().newWriteOnlyTransaction(); + writeTx.put(LogicalDatastoreType.CONFIGURATION, COMPLEX_AUGMENT, complexUsesAugment(LIST_VIA_USES_KEY_MOD)); + assertCommit(writeTx.submit()); + assertTrue(listener.hasEvent()); + AsyncDataChangeEvent, DataObject> event = listener.event(); + assertContains(event.getUpdatedData(), COMPLEX_AUGMENT); + assertContains(event.getCreatedData(), COMPLEX_AUGMENT.child(ListViaUses.class, LIST_VIA_USES_KEY_MOD)); + assertContains(event.getRemovedPaths(), COMPLEX_AUGMENT.child(ListViaUses.class, LIST_VIA_USES_KEY)); + assertContains(event.getOriginalData(), COMPLEX_AUGMENT); + assertContains(event.getOriginalData(), COMPLEX_AUGMENT.child(ListViaUses.class, LIST_VIA_USES_KEY)); + } +} diff --git a/opendaylight/md-sal/sal-test-model/src/main/java/org/opendaylight/controller/md/sal/test/model/util/ListsBindingUtils.java b/opendaylight/md-sal/sal-test-model/src/main/java/org/opendaylight/controller/md/sal/test/model/util/ListsBindingUtils.java index a0c23aecb4..af7a32924b 100644 --- a/opendaylight/md-sal/sal-test-model/src/main/java/org/opendaylight/controller/md/sal/test/model/util/ListsBindingUtils.java +++ b/opendaylight/md-sal/sal-test-model/src/main/java/org/opendaylight/controller/md/sal/test/model/util/ListsBindingUtils.java @@ -7,10 +7,11 @@ */ package org.opendaylight.controller.md.sal.test.model.util; -import java.util.Arrays; - +import com.google.common.collect.ImmutableList; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.TreeComplexUsesAugment; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.TreeComplexUsesAugmentBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.TreeLeafOnlyUsesAugment; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.TreeLeafOnlyUsesAugmentBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.complex.from.grouping.ListViaUses; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.complex.from.grouping.ListViaUsesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.augment.rev140709.complex.from.grouping.ListViaUsesKey; @@ -25,7 +26,7 @@ import org.opendaylight.yangtools.yang.binding.Augmentation; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import com.google.common.collect.ImmutableList; +import java.util.Arrays; public class ListsBindingUtils { @@ -79,4 +80,9 @@ public class ListsBindingUtils { return new TreeComplexUsesAugmentBuilder().setListViaUses(listViaUses.build()).build(); } + public static TreeLeafOnlyUsesAugment leafOnlyUsesAugment(String leafFromGroupingValue) { + + return new TreeLeafOnlyUsesAugmentBuilder().setLeafFromGrouping(leafFromGroupingValue).build(); + } + } -- 2.36.6