Expose a List of changes in DOMDataTreeChangeListener 33/97633/3
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 20 Jan 2022 11:16:27 +0000 (12:16 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 20 Jan 2022 11:20:35 +0000 (12:20 +0100)
The order of changes have a semantic meaning in that they occur
in-order. There are a number of use cases where we would want to access
only the last delta (i.e. for the last state), which is easier when we
expose a proper List instead of Collection.

Change-Id: I159983207dfc935cbc81eccc24296e3db885f73e
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMDataTreeChangeListenerAdapter.java
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/LazyDataTreeModification.java
dom/mdsal-dom-api/src/main/java/org/opendaylight/mdsal/dom/api/DOMDataTreeChangeListener.java
dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/DOMDataTreeChangeListenerTest.java
dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/DOMDataTreeListenerTest.java
replicate/mdsal-replicate-netty/src/main/java/org/opendaylight/mdsal/replicate/netty/AbstractSourceMessage.java
replicate/mdsal-replicate-netty/src/main/java/org/opendaylight/mdsal/replicate/netty/SourceRequestHandler.java

index 1372e1cf13bf312a7087ad49d47f56d25d32753f..31296762d6c9bb165694d81a8992db0dc2c80c96 100644 (file)
@@ -9,7 +9,7 @@ package org.opendaylight.mdsal.binding.dom.adapter;
 
 import static java.util.Objects.requireNonNull;
 
-import java.util.Collection;
+import java.util.List;
 import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
@@ -33,7 +33,7 @@ class BindingDOMDataTreeChangeListenerAdapter<T extends DataObject> implements D
     }
 
     @Override
-    public void onDataTreeChanged(final Collection<DataTreeCandidate> domChanges) {
+    public void onDataTreeChanged(final List<DataTreeCandidate> domChanges) {
         listener.onDataTreeChanged(LazyDataTreeModification.from(adapterContext.currentSerializer(), domChanges,
             store));
     }
index 95aec5e11099f8d281d9e63507311acc9a1a7725..5773430629231d324ab941a3522a9d4a5a8f97cf 100644 (file)
@@ -11,7 +11,6 @@ import static java.util.Objects.requireNonNull;
 
 import com.google.common.base.MoreObjects;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.List;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.mdsal.binding.api.DataObjectModification;
@@ -60,9 +59,8 @@ final class LazyDataTreeModification<T extends DataObject> implements DataTreeMo
             LazyDataObjectModification.create(codec, candidate.getRootNode()));
     }
 
-    static <T extends DataObject> @NonNull Collection<DataTreeModification<T>> from(
-            final CurrentAdapterSerializer codec, final Collection<DataTreeCandidate> domChanges,
-            final LogicalDatastoreType datastoreType) {
+    static <T extends DataObject> @NonNull List<DataTreeModification<T>> from(final CurrentAdapterSerializer codec,
+            final List<DataTreeCandidate> domChanges, final LogicalDatastoreType datastoreType) {
         final List<DataTreeModification<T>> result = new ArrayList<>(domChanges.size());
         for (final DataTreeCandidate domChange : domChanges) {
             result.add(LazyDataTreeModification.create(codec, domChange, datastoreType));
index da1f92926549914e5ff2904cc24671d73b02618b..4ac6106280dbb8e9c5062070ad649cf147d81724 100644 (file)
@@ -7,8 +7,8 @@
  */
 package org.opendaylight.mdsal.dom.api;
 
-import java.util.Collection;
 import java.util.EventListener;
+import java.util.List;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
 
@@ -35,15 +35,15 @@ public interface DOMDataTreeChangeListener extends EventListener {
      * a {@link org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType} other than UNMODIFIED, while
      * the before- and after- data items compare as equal.
      *
-     * @param changes Collection of change events, may not be null or empty.
+     * @param changes List of change events, may not be null or empty.
      * @throws NullPointerException if {@code changes} is null
      */
-    void onDataTreeChanged(@NonNull Collection<DataTreeCandidate> changes);
+    void onDataTreeChanged(@NonNull List<DataTreeCandidate> changes);
 
     /**
      * Invoked only once during registration of the listener if there was no data in the conceptual data tree
      * for the supplied path, which was used to register this listener, and after this
-     * {@link #onDataTreeChanged(Collection)} would always be invoked for data changes.
+     * {@link #onDataTreeChanged(List)} would always be invoked for data changes.
      */
     void onInitialData();
 }
index d85ed73dc3cdabbb256748cee624c9cd25fbb91f..a1b19c1ea3ffe8432b0d06d3a29632f3cad557e9 100644 (file)
@@ -18,7 +18,7 @@ import static org.mockito.Mockito.verify;
 
 import com.google.common.collect.Iterables;
 import com.google.common.util.concurrent.MoreExecutors;
-import java.util.Collection;
+import java.util.List;
 import java.util.concurrent.ExecutionException;
 import org.junit.Before;
 import org.junit.Test;
@@ -56,7 +56,7 @@ public class DOMDataTreeChangeListenerTest extends AbstractDatastoreTest {
     @Test
     public void receiveOnDataInitialEventForNonExistingData() throws InterruptedException, ExecutionException {
         final DOMDataTreeChangeListener listener = mock(DOMDataTreeChangeListener.class);
-        final ArgumentCaptor<Collection> candidateCapture = ArgumentCaptor.forClass(Collection.class);
+        final ArgumentCaptor<List> candidateCapture = ArgumentCaptor.forClass(List.class);
         doNothing().when(listener).onInitialData();
         doNothing().when(listener).onDataTreeChanged(any());
 
@@ -79,7 +79,7 @@ public class DOMDataTreeChangeListenerTest extends AbstractDatastoreTest {
     @Test
     public void receiveOnDataTreeChangedEventForPreExistingEmptyData() throws InterruptedException, ExecutionException {
         final DOMDataTreeChangeListener listener = mock(DOMDataTreeChangeListener.class);
-        final ArgumentCaptor<Collection> candidateCapture = ArgumentCaptor.forClass(Collection.class);
+        final ArgumentCaptor<List> candidateCapture = ArgumentCaptor.forClass(List.class);
         doNothing().when(listener).onDataTreeChanged(any());
 
         final NormalizedNode testNode = ImmutableNodes.containerNode(TestModel.TEST_QNAME);
@@ -101,7 +101,7 @@ public class DOMDataTreeChangeListenerTest extends AbstractDatastoreTest {
     @Test
     public void receiveOnDataTreeChangeEventForPreExistingData() throws InterruptedException, ExecutionException {
         final DOMDataTreeChangeListener listener = mock(DOMDataTreeChangeListener.class);
-        final ArgumentCaptor<Collection> candidateCapture = ArgumentCaptor.forClass(Collection.class);
+        final ArgumentCaptor<List> candidateCapture = ArgumentCaptor.forClass(List.class);
         doNothing().when(listener).onDataTreeChanged(any());
 
         final ContainerNode testNode = ImmutableContainerNodeBuilder.create()
index a77775f382c28ee23e6de2e308aeee1af0fcd393..b2dd818d15650c7faac9df5d643c4e9551f29814 100644 (file)
@@ -19,7 +19,6 @@ import com.google.common.util.concurrent.ForwardingExecutorService;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutionException;
@@ -136,10 +135,10 @@ public class DOMDataTreeListenerTest extends AbstractDatastoreTest {
         latch.await(5, TimeUnit.SECONDS);
 
         assertEquals(1, listener.getReceivedChanges().size());
-        final Collection<DataTreeCandidate> changes = listener.getReceivedChanges().get(0);
+        final List<DataTreeCandidate> changes = listener.getReceivedChanges().get(0);
         assertEquals(1, changes.size());
 
-        final DataTreeCandidate candidate = changes.iterator().next();
+        final DataTreeCandidate candidate = changes.get(0);
         assertNotNull(candidate);
         final DataTreeCandidateNode candidateRoot = candidate.getRootNode();
         checkChange(null, TEST_CONTAINER, ModificationType.WRITE, candidateRoot);
@@ -168,10 +167,10 @@ public class DOMDataTreeListenerTest extends AbstractDatastoreTest {
         latch.await(5, TimeUnit.SECONDS);
 
         assertEquals(2, listener.getReceivedChanges().size());
-        Collection<DataTreeCandidate> changes = listener.getReceivedChanges().get(0);
+        List<DataTreeCandidate> changes = listener.getReceivedChanges().get(0);
         assertEquals(1, changes.size());
 
-        DataTreeCandidate candidate = changes.iterator().next();
+        DataTreeCandidate candidate = changes.get(0);
         assertNotNull(candidate);
         DataTreeCandidateNode candidateRoot = candidate.getRootNode();
         checkChange(null, TEST_CONTAINER, ModificationType.WRITE, candidateRoot);
@@ -179,7 +178,7 @@ public class DOMDataTreeListenerTest extends AbstractDatastoreTest {
         changes = listener.getReceivedChanges().get(1);
         assertEquals(1, changes.size());
 
-        candidate = changes.iterator().next();
+        candidate = changes.get(0);
         assertNotNull(candidate);
         candidateRoot = candidate.getRootNode();
         checkChange(TEST_CONTAINER, TEST_CONTAINER_2, ModificationType.WRITE, candidateRoot);
@@ -209,10 +208,10 @@ public class DOMDataTreeListenerTest extends AbstractDatastoreTest {
         latch.await(5, TimeUnit.SECONDS);
 
         assertEquals(2, listener.getReceivedChanges().size());
-        Collection<DataTreeCandidate> changes = listener.getReceivedChanges().get(0);
+        List<DataTreeCandidate> changes = listener.getReceivedChanges().get(0);
         assertEquals(1, changes.size());
 
-        DataTreeCandidate candidate = changes.iterator().next();
+        DataTreeCandidate candidate = changes.get(0);
         assertNotNull(candidate);
         DataTreeCandidateNode candidateRoot = candidate.getRootNode();
         checkChange(null, TEST_CONTAINER, ModificationType.WRITE, candidateRoot);
@@ -220,7 +219,7 @@ public class DOMDataTreeListenerTest extends AbstractDatastoreTest {
         changes = listener.getReceivedChanges().get(1);
         assertEquals(1, changes.size());
 
-        candidate = changes.iterator().next();
+        candidate = changes.get(0);
         assertNotNull(candidate);
         candidateRoot = candidate.getRootNode();
         checkChange(TEST_CONTAINER, null, ModificationType.DELETE, candidateRoot);
@@ -250,10 +249,10 @@ public class DOMDataTreeListenerTest extends AbstractDatastoreTest {
         latch.await(5, TimeUnit.SECONDS);
 
         assertEquals(2, listener.getReceivedChanges().size());
-        Collection<DataTreeCandidate> changes = listener.getReceivedChanges().get(0);
+        List<DataTreeCandidate> changes = listener.getReceivedChanges().get(0);
         assertEquals(1, changes.size());
 
-        DataTreeCandidate candidate = changes.iterator().next();
+        DataTreeCandidate candidate = changes.get(0);
         assertNotNull(candidate);
         DataTreeCandidateNode candidateRoot = candidate.getRootNode();
         checkChange(null, TEST_CONTAINER, ModificationType.WRITE, candidateRoot);
@@ -261,7 +260,7 @@ public class DOMDataTreeListenerTest extends AbstractDatastoreTest {
         changes = listener.getReceivedChanges().get(1);
         assertEquals(1, changes.size());
 
-        candidate = changes.iterator().next();
+        candidate = changes.get(0);
         assertNotNull(candidate);
         candidateRoot = candidate.getRootNode();
         checkChange(TEST_CONTAINER, TEST_CONTAINER_2, ModificationType.SUBTREE_MODIFIED, candidateRoot);
@@ -294,10 +293,10 @@ public class DOMDataTreeListenerTest extends AbstractDatastoreTest {
         latch.await(1, TimeUnit.SECONDS);
 
         assertEquals(2, listener.getReceivedChanges().size());
-        Collection<DataTreeCandidate> changes = listener.getReceivedChanges().get(0);
+        List<DataTreeCandidate> changes = listener.getReceivedChanges().get(0);
         assertEquals(1, changes.size());
 
-        DataTreeCandidate candidate = changes.iterator().next();
+        DataTreeCandidate candidate = changes.get(0);
         assertNotNull(candidate);
         DataTreeCandidateNode candidateRoot = candidate.getRootNode();
         checkChange(null, OUTER_LIST, ModificationType.WRITE, candidateRoot);
@@ -305,7 +304,7 @@ public class DOMDataTreeListenerTest extends AbstractDatastoreTest {
         changes = listener.getReceivedChanges().get(1);
         assertEquals(1, changes.size());
 
-        candidate = changes.iterator().next();
+        candidate = changes.get(0);
         assertNotNull(candidate);
         candidateRoot = candidate.getRootNode();
         checkChange(OUTER_LIST, OUTER_LIST_2, ModificationType.WRITE, candidateRoot);
@@ -355,10 +354,10 @@ public class DOMDataTreeListenerTest extends AbstractDatastoreTest {
         latch.await(5, TimeUnit.SECONDS);
 
         assertEquals(2, listener.getReceivedChanges().size());
-        Collection<DataTreeCandidate> changes = listener.getReceivedChanges().get(0);
+        List<DataTreeCandidate> changes = listener.getReceivedChanges().get(0);
         assertEquals(1, changes.size());
 
-        DataTreeCandidate candidate = changes.iterator().next();
+        DataTreeCandidate candidate = changes.get(0);
         assertNotNull(candidate);
         DataTreeCandidateNode candidateRoot = candidate.getRootNode();
         checkChange(null, OUTER_LIST, ModificationType.WRITE, candidateRoot);
@@ -366,7 +365,7 @@ public class DOMDataTreeListenerTest extends AbstractDatastoreTest {
         changes = listener.getReceivedChanges().get(1);
         assertEquals(1, changes.size());
 
-        candidate = changes.iterator().next();
+        candidate = changes.get(0);
         assertNotNull(candidate);
         candidateRoot = candidate.getRootNode();
         checkChange(OUTER_LIST, listAfter, ModificationType.SUBTREE_MODIFIED, candidateRoot);
@@ -417,7 +416,7 @@ public class DOMDataTreeListenerTest extends AbstractDatastoreTest {
     }
 
     static class TestDataTreeListener implements DOMDataTreeChangeListener {
-        private final List<Collection<DataTreeCandidate>> receivedChanges = new ArrayList<>();
+        private final List<List<DataTreeCandidate>> receivedChanges = new ArrayList<>();
         private final CountDownLatch latch;
 
         TestDataTreeListener(final CountDownLatch latch) {
@@ -425,7 +424,7 @@ public class DOMDataTreeListenerTest extends AbstractDatastoreTest {
         }
 
         @Override
-        public void onDataTreeChanged(final Collection<DataTreeCandidate> changes) {
+        public void onDataTreeChanged(final List<DataTreeCandidate> changes) {
             receivedChanges.add(changes);
             latch.countDown();
         }
@@ -435,7 +434,7 @@ public class DOMDataTreeListenerTest extends AbstractDatastoreTest {
             // noop
         }
 
-        List<Collection<DataTreeCandidate>> getReceivedChanges() {
+        List<List<DataTreeCandidate>> getReceivedChanges() {
             return receivedChanges;
         }
     }
index 0df9b42ff07f18fdced9a1a37af4624be62580f2..5c5eeeb549eded3431d964a4d139cff70220ace3 100644 (file)
@@ -11,7 +11,6 @@ import static java.util.Objects.requireNonNull;
 
 import java.io.DataOutputStream;
 import java.io.IOException;
-import java.util.Collection;
 import java.util.List;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
 import org.opendaylight.yangtools.yang.data.codec.binfmt.DataTreeCandidateInputOutput;
@@ -27,9 +26,9 @@ abstract class AbstractSourceMessage {
     }
 
     private static final class Deltas extends AbstractSourceMessage {
-        private final Collection<DataTreeCandidate> deltas;
+        private final List<DataTreeCandidate> deltas;
 
-        Deltas(final Collection<DataTreeCandidate> deltas) {
+        Deltas(final List<DataTreeCandidate> deltas) {
             this.deltas = requireNonNull(deltas);
         }
 
@@ -52,7 +51,7 @@ abstract class AbstractSourceMessage {
         return EMPTY;
     }
 
-    static AbstractSourceMessage of(final Collection<DataTreeCandidate> deltas) {
+    static AbstractSourceMessage of(final List<DataTreeCandidate> deltas) {
         return new Deltas(deltas);
     }
 
index 2d2065d50d4657aee58ccef5e6b38bc73080bf3a..dc5201a419d73081bd79dbfca53f92bc33808ed7 100644 (file)
@@ -16,7 +16,7 @@ import io.netty.channel.Channel;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.SimpleChannelInboundHandler;
 import java.io.IOException;
-import java.util.Collection;
+import java.util.List;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.mdsal.dom.api.ClusteredDOMDataTreeChangeListener;
 import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeService;
@@ -95,7 +95,7 @@ final class SourceRequestHandler extends SimpleChannelInboundHandler<ByteBuf> {
             }
 
             @Override
-            public void onDataTreeChanged(final Collection<DataTreeCandidate> changes) {
+            public void onDataTreeChanged(final List<DataTreeCandidate> changes) {
                 LOG.debug("Channel {} tree {} has {} changes", channel, dataTree, changes.size());
                 channel.writeAndFlush(AbstractSourceMessage.of(changes));
             }