Fix mergeParentStructure{Merge,Put} with augmentations 66/107566/4
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 30 Aug 2023 08:35:26 +0000 (10:35 +0200)
committerRobert Varga <nite@hq.sk>
Wed, 30 Aug 2023 11:44:53 +0000 (11:44 +0000)
We need to pay attention to the result of normalization, as
AugmentationResult points to the parent YangInstanceIdentifier --
and hence we should just use it instead of peeling its last component.

JIRA: MDSAL-837
Change-Id: I7f108a6dff96a010f029b38b2cbba5548551b56e
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
binding/mdsal-binding-dom-adapter/src/main/java/org/opendaylight/mdsal/binding/dom/adapter/BindingDOMWriteTransactionAdapter.java
binding/mdsal-binding-dom-adapter/src/test/java/org/opendaylight/mdsal/binding/dom/adapter/WriteTransactionTest.java

index 02a6c58b6bf9ed6af9618a5185b059bb6081e4a3..742ba5c927eb6a53ccc3123726026c35c9ddf526 100644 (file)
@@ -68,7 +68,7 @@ class BindingDOMWriteTransactionAdapter<T extends DOMDataTreeWriteTransaction> e
             final InstanceIdentifier<U> path, final U data) {
         final var serializer = adapterContext().currentSerializer();
         final var normalized = toNormalized(serializer, "put", path, data);
-        ensureParentsByMerge(serializer, store, normalized.path());
+        ensureParentsByMerge(serializer, store, normalized);
         put(store, normalized);
     }
 
@@ -100,7 +100,7 @@ class BindingDOMWriteTransactionAdapter<T extends DOMDataTreeWriteTransaction> e
             final InstanceIdentifier<U> path, final U data) {
         final var serializer = adapterContext().currentSerializer();
         final var normalized = toNormalized(serializer, "merge", path, data);
-        ensureParentsByMerge(serializer, store, normalized.path());
+        ensureParentsByMerge(serializer, store, normalized);
         merge(store, normalized);
     }
 
@@ -137,12 +137,15 @@ class BindingDOMWriteTransactionAdapter<T extends DOMDataTreeWriteTransaction> e
      * Subclasses of this class are required to implement creation of parent nodes based on behaviour of their
      * underlying transaction.
      *
+     * @param serializer Current serializer
      * @param store an instance of LogicalDatastoreType
-     * @param domPath an instance of YangInstanceIdentifier
+     * @param normalized NormalizedResult of the operation
      */
     private void ensureParentsByMerge(final CurrentAdapterSerializer serializer, final LogicalDatastoreType store,
-            final YangInstanceIdentifier domPath) {
-        final var parentPath = domPath.getParent();
+            final NormalizedResult normalized) {
+        final var path = normalized.path();
+        // AugmentationResult already points to parent path
+        final var parentPath = normalized instanceof AugmentationResult ? path : path.getParent();
         if (parentPath != null && !parentPath.isEmpty()) {
             final var parentNode = ImmutableNodes.fromInstanceId(
                 serializer.getRuntimeContext().getEffectiveModelContext(), parentPath);
index 0a7a9179a5a45ea4afca729ef1fa2359b08c0d3e..519fc15e53207d81c7035df2b13b6c7afcccb011 100644 (file)
  */
 package org.opendaylight.mdsal.binding.dom.adapter;
 
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
 
 import java.util.Optional;
-import java.util.concurrent.ExecutionException;
 import org.junit.Test;
-import org.opendaylight.mdsal.binding.api.ReadTransaction;
-import org.opendaylight.mdsal.binding.api.WriteTransaction;
 import org.opendaylight.mdsal.binding.dom.adapter.test.AbstractDataBrokerTest;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.TreeLeafOnlyUsesAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.augment.rev140709.TreeLeafOnlyUsesAugmentBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.Top;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.TopBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.mdsal.test.binding.rev140701.two.level.list.TopLevelListKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.util.BindingMap;
 
 public class WriteTransactionTest extends AbstractDataBrokerTest {
     private static final InstanceIdentifier<Top> TOP_PATH = InstanceIdentifier.create(Top.class);
     private static final TopLevelListKey TOP_LIST_KEY = new TopLevelListKey("foo");
     private static final InstanceIdentifier<TopLevelList> NODE_PATH = TOP_PATH.child(TopLevelList.class, TOP_LIST_KEY);
+    private static final InstanceIdentifier<TreeLeafOnlyUsesAugment> NODE_AUGMENT_PATH =
+        NODE_PATH.augmentation(TreeLeafOnlyUsesAugment.class);
     private static final TopLevelList NODE = new TopLevelListBuilder().withKey(TOP_LIST_KEY).build();
+    private static final TreeLeafOnlyUsesAugment NODE_AUGMENT = new TreeLeafOnlyUsesAugmentBuilder()
+        .setLeafFromGrouping("foo")
+        .build();
 
     @Test
-    public void test() throws InterruptedException, ExecutionException {
-        final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+    public void test() throws Exception {
+        final var writeTx = getDataBroker().newWriteOnlyTransaction();
         writeTx.put(LogicalDatastoreType.OPERATIONAL, TOP_PATH, new TopBuilder().build());
         writeTx.put(LogicalDatastoreType.OPERATIONAL, NODE_PATH, NODE);
         writeTx.commit().get();
     }
 
     @Test
-    public void testPutCreateParentsSuccess() throws InterruptedException, ExecutionException {
-        final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+    public void testPutCreateParentsSuccess() throws Exception {
+        final var writeTx = getDataBroker().newWriteOnlyTransaction();
         writeTx.mergeParentStructurePut(LogicalDatastoreType.OPERATIONAL, NODE_PATH, NODE);
         writeTx.commit().get();
 
-        final ReadTransaction readTx = getDataBroker().newReadOnlyTransaction();
-        final Optional<Top> topNode = readTx.read(LogicalDatastoreType.OPERATIONAL, TOP_PATH).get();
-        assertTrue("Top node must exists after commit",topNode.isPresent());
-        final Optional<TopLevelList> listNode = readTx.read(LogicalDatastoreType.OPERATIONAL, NODE_PATH).get();
-        assertTrue("List node must exists after commit",listNode.isPresent());
+        assertTop(new TopBuilder().setTopLevelList(BindingMap.of(NODE)).build());
     }
 
     @Test
-    public void testPutCreateParentsSuperfluous() throws InterruptedException, ExecutionException {
-        final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+    public void testPutCreateAugmentationParentsSuccess() throws Exception {
+        final var writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.mergeParentStructurePut(LogicalDatastoreType.OPERATIONAL, NODE_AUGMENT_PATH, NODE_AUGMENT);
+        writeTx.commit().get();
+
+        assertTop(new TopBuilder()
+            .setTopLevelList(BindingMap.of(new TopLevelListBuilder()
+                .withKey(TOP_LIST_KEY)
+                .addAugmentation(NODE_AUGMENT)
+                .build()))
+            .build());
+    }
+
+    @Test
+    public void testPutCreateParentsSuperfluous() throws Exception {
+        final var writeTx = getDataBroker().newWriteOnlyTransaction();
         writeTx.mergeParentStructurePut(LogicalDatastoreType.OPERATIONAL, TOP_PATH, new TopBuilder().build());
         writeTx.commit().get();
     }
 
     @Test
-    public void testMergeCreateParentsSuccess() throws InterruptedException, ExecutionException {
-        final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+    public void testMergeCreateParentsSuccess() throws Exception {
+        final var writeTx = getDataBroker().newWriteOnlyTransaction();
         writeTx.mergeParentStructureMerge(LogicalDatastoreType.OPERATIONAL, NODE_PATH, NODE);
         writeTx.commit().get();
 
-        final ReadTransaction readTx = getDataBroker().newReadOnlyTransaction();
-        final Optional<Top> topNode = readTx.read(LogicalDatastoreType.OPERATIONAL, TOP_PATH).get();
-        assertTrue("Top node must exists after commit",topNode.isPresent());
-        final Optional<TopLevelList> listNode = readTx.read(LogicalDatastoreType.OPERATIONAL, NODE_PATH).get();
-        assertTrue("List node must exists after commit",listNode.isPresent());
+        assertTop(new TopBuilder().setTopLevelList(BindingMap.of(NODE)).build());
+    }
+
+    @Test
+    public void testMergeCreateAugmentationParentsSuccess() throws Exception {
+        final var writeTx = getDataBroker().newWriteOnlyTransaction();
+        writeTx.mergeParentStructureMerge(LogicalDatastoreType.OPERATIONAL, NODE_AUGMENT_PATH, NODE_AUGMENT);
+        writeTx.commit().get();
+
+        assertTop(new TopBuilder()
+            .setTopLevelList(BindingMap.of(new TopLevelListBuilder()
+                .withKey(TOP_LIST_KEY)
+                .addAugmentation(NODE_AUGMENT)
+                .build()))
+            .build());
     }
 
     @Test
-    public void testMergeCreateParentsSuperfluous() throws InterruptedException, ExecutionException {
-        final WriteTransaction writeTx = getDataBroker().newWriteOnlyTransaction();
+    public void testMergeCreateParentsSuperfluous() throws Exception {
+        final var writeTx = getDataBroker().newWriteOnlyTransaction();
         writeTx.mergeParentStructurePut(LogicalDatastoreType.OPERATIONAL, TOP_PATH, new TopBuilder().build());
         writeTx.commit().get();
     }
+
+    private void assertTop(final Top expected) throws Exception {
+        try (var readTx = getDataBroker().newReadOnlyTransaction()) {
+            assertEquals(Optional.of(expected), readTx.read(LogicalDatastoreType.OPERATIONAL, TOP_PATH).get());
+        }
+    }
 }