From: Valentin Mayamsin Date: Fri, 16 Oct 2015 21:38:02 +0000 (-0700) Subject: MDSAL-107: Fix pre-existing data notification for wildcarded DTCL X-Git-Tag: release/oxygen~62 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=0f7afdeb0b33a9f1fa3a5085c536e6c3b6aba862 MDSAL-107: Fix pre-existing data notification for wildcarded DTCL This issue was fixed in CDS a while but should also be fixed for the in-memory DOM data store. Change-Id: Idb69ebed32b5b7a7e10bc373e2272c22b0198567 Signed-off-by: Tom Pantelis --- diff --git a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/DataTreeChangeListenerTest.java b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/DataTreeChangeListenerTest.java index 4e9a79f869..071c9bcb40 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/DataTreeChangeListenerTest.java +++ b/opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/md/sal/binding/impl/test/DataTreeChangeListenerTest.java @@ -11,6 +11,9 @@ package org.opendaylight.controller.md.sal.binding.impl.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.verify; import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUtils.TOP_BAR_KEY; 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.USES_ONE_KEY; @@ -22,10 +25,13 @@ import static org.opendaylight.controller.md.sal.test.model.util.ListsBindingUti import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.util.concurrent.SettableFuture; +import java.util.ArrayList; import java.util.Collection; import java.util.concurrent.TimeUnit; import org.junit.Before; import org.junit.Test; +import org.mockito.Matchers; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType; import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener; @@ -37,8 +43,10 @@ import org.opendaylight.controller.md.sal.binding.test.AbstractConcurrentDataBro 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.list.rev140701.Top; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.TopBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.test.list.rev140701.TwoLevelList; 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.TopLevelListBuilder; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument; @@ -137,7 +145,28 @@ public class DataTreeChangeListenerTest extends AbstractConcurrentDataBrokerTest verifyModification(barDeleteEvent.getRootNode(), BAR_ARGUMENT, ModificationType.DELETE); } + @SuppressWarnings("unchecked") + @Test + public void testWildcardNotificationOfPreexistingData() throws Exception { + InstanceIdentifier id = InstanceIdentifier.builder(Top.class).build(); + ArrayList list = new ArrayList<>(); + list.add(new TopLevelListBuilder().setName("name").build()); + TopBuilder builder = new TopBuilder().setTopLevelList(list); + + DataBroker dataBroker = getDataBroker(); + + WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction(); + writeTransaction.put(LogicalDatastoreType.OPERATIONAL, id, builder.build()); + assertCommit(writeTransaction.submit()); + DataTreeChangeListener listener = mock(DataTreeChangeListener.class); + InstanceIdentifier wildcard = InstanceIdentifier.builder(Top.class).child(TopLevelList.class) + .build(); + dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, wildcard), + listener); + + verify(listener, timeout(1000)).onDataTreeChanged(Matchers.anyObject()); + } private void createAndVerifyTop(final EventCapturingListener listener) throws Exception { putTx(TOP_PATH,TOP_INITIAL_DATA).submit().checkedGet(); diff --git a/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMStoreTreeChangePublisher.java b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMStoreTreeChangePublisher.java index 342dc0c35b..22e4c4d8a3 100644 --- a/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMStoreTreeChangePublisher.java +++ b/opendaylight/md-sal/sal-inmemory-datastore/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMStoreTreeChangePublisher.java @@ -43,6 +43,11 @@ final class InMemoryDOMStoreTreeChangePublisher extends AbstractDOMStoreTreeChan notificationManager = new QueuedNotificationManager<>(listenerExecutor, MANAGER_INVOKER, maxQueueSize, "DataTreeChangeListenerQueueMgr"); } + private InMemoryDOMStoreTreeChangePublisher(QueuedNotificationManager< + AbstractDOMDataTreeChangeListenerRegistration, DataTreeCandidate> notificationManager) { + this.notificationManager = notificationManager; + } + @Override protected void notifyListeners(final Collection> registrations, final YangInstanceIdentifier path, final DataTreeCandidateNode node) { final DataTreeCandidate candidate = DataTreeCandidates.newDataTreeCandidate(path, node); @@ -63,10 +68,15 @@ final class InMemoryDOMStoreTreeChangePublisher extends AbstractDOMStoreTreeChan ListenerRegistration registerTreeChangeListener(final YangInstanceIdentifier treeId, final L listener, final DataTreeSnapshot snapshot) { final AbstractDOMDataTreeChangeListenerRegistration reg = registerTreeChangeListener(treeId, listener); - final Optional> node = snapshot.readNode(treeId); + final Optional> node = snapshot.readNode(YangInstanceIdentifier.EMPTY); if (node.isPresent()) { - final DataTreeCandidate candidate = DataTreeCandidates.fromNormalizedNode(treeId, node.get()); - notificationManager.submitNotification(reg, candidate); + final DataTreeCandidate candidate = DataTreeCandidates.fromNormalizedNode( + YangInstanceIdentifier.EMPTY, node.get()); + + InMemoryDOMStoreTreeChangePublisher publisher = + new InMemoryDOMStoreTreeChangePublisher(notificationManager); + publisher.registerTreeChangeListener(treeId, listener); + publisher.publishChange(candidate); } return reg;