Nest id-ints list inside a container 95/55995/2
authorTomas Cere <tcere@cisco.com>
Tue, 25 Apr 2017 10:50:52 +0000 (12:50 +0200)
committerTom Pantelis <tompantelis@gmail.com>
Wed, 26 Apr 2017 12:10:09 +0000 (12:10 +0000)
Needs to be nested to be able to refer to the whole list via restconf
and instance-identifier yang element, so update the model and the handlers
to account for this change.

Change-Id: Idf50de5e6faa9757f45ec68e9b796ae0742f6aa9
Signed-off-by: Tomas Cere <tcere@cisco.com>
opendaylight/md-sal/samples/clustering-test-app/model/src/main/yang/odl-mdsal-lowlevel-target.yang
opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/MdsalLowLevelTestProvider.java
opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/IdIntsDOMDataTreeLIstener.java
opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/IdIntsListener.java
opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/ProduceTransactionsHandler.java
opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/WriteTransactionsHandler.java

index b4f9c25843e2ebf3aac6ba198a6448776b5e14b1..8b799536a0f3562b07e461d402ef0d37d3a1b6c9 100644 (file)
@@ -65,27 +65,28 @@ module odl-mdsal-lowlevel-target {
         }
     }
 
-    list id-ints {
-        description "A list of integers nested in list of ids.
-            Ids are there to avoid OptimisticLockFailures from different writers.
-            Typical use of the int list is to generate data change notifications.
-            Config is true, in order to allow Restconf to reset content at will.
-            Expected writes should create and delete items at random, values 0 .. 2^20.";
-        ordered-by system;
-        config true;
-        key "id";
-        uses llc:id-grouping;
-        list item {
-            description "Unsorted keyed list item. One write should create or delete up to one item.";
+    container id-ints {
+        list id-int {
+            description "A list of integers nested in list of ids.
+                Ids are there to avoid OptimisticLockFailures from different writers.
+                Typical use of the int list is to generate data change notifications.
+                Config is true, in order to allow Restconf to reset content at will.
+                Expected writes should create and delete items at random, values 0 .. 2^20.";
             ordered-by system;
             config true;
-            key "number";
-            leaf number {
-                description "The integer value of this item.
-                    Not range restricted, to allow more scenarios.";
-                type int32;
+            key "id";
+            uses llc:id-grouping;
+            list item {
+                description "Unsorted keyed list item. One write should create or delete up to one item.";
+                ordered-by system;
+                config true;
+                key "number";
+                leaf number {
+                    description "The integer value of this item.
+                        Not range restricted, to allow more scenarios.";
+                    type int32;
+                }
             }
         }
     }
-
 }
index 98ae842a505863fec0e7199a56ab18d1ebd75f05..8ebac1c01e88c07da64324e4eb9d2f507a81e299 100644 (file)
@@ -217,7 +217,7 @@ public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService
         dtclReg = domDataTreeChangeService
                 .registerDataTreeChangeListener(
                         new org.opendaylight.controller.md.sal.dom.api.DOMDataTreeIdentifier(
-                                CONTROLLER_CONFIG, WriteTransactionsHandler.ID_INTS_YID),
+                                CONTROLLER_CONFIG, WriteTransactionsHandler.ID_INT_YID),
                         idIntsListener);
 
         return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
@@ -374,7 +374,7 @@ public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService
             ddtlReg =
                     domDataTreeService.registerListener(idIntsDdtl,
                             Collections.singleton(new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION,
-                                    ProduceTransactionsHandler.ID_INTS_YID))
+                                    ProduceTransactionsHandler.ID_INT_YID))
                             , true, Collections.emptyList());
         } catch (DOMDataTreeLoopException e) {
             LOG.error("Failed to register DOMDataTreeListener.", e);
@@ -447,7 +447,7 @@ public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService
             }
 
             final Optional<NormalizedNode<?, ?>> readResult =
-                    rTx.read(CONTROLLER_CONFIG, WriteTransactionsHandler.ID_INTS_YID).checkedGet();
+                    rTx.read(CONTROLLER_CONFIG, WriteTransactionsHandler.ID_INT_YID).checkedGet();
 
             if (!readResult.isPresent()) {
                 final RpcError error = RpcResultBuilder.newError(
@@ -584,7 +584,7 @@ public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService
         try {
             final ListenerRegistration<ReadListener> registration = domDataTreeService.registerListener(readListener,
                     Collections.singleton(new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION,
-                            ProduceTransactionsHandler.ID_INTS_YID))
+                            ProduceTransactionsHandler.ID_INT_YID))
                     , true, Collections.emptyList());
 
             final DataTreeCandidate dataTreeCandidate = readListener.getFirstNotif().get();
@@ -603,7 +603,6 @@ public class MdsalLowLevelTestProvider implements OdlMdsalLowlevelControlService
                     RpcResultBuilder.success(new UnsubscribeDdtlOutputBuilder()
                             .setCopyMatches(idIntsDdtl.checkEqual(lastRead))).build());
 
-
         } catch (final DOMDataTreeLoopException | InterruptedException | ExecutionException e) {
             LOG.error("Unable to read data to verify ddtl data.", e);
             final RpcError error = RpcResultBuilder.newError(
index be46a0ee31de218821f04672fd695be799a3b8c2..3f9a3c52f6a7426d05a700dd7e6ac7056c137fb9 100644 (file)
@@ -38,7 +38,9 @@ public class IdIntsDOMDataTreeLIstener implements DOMDataTreeListener {
 
         changes.forEach(change -> {
             if (change.getRootNode().getDataAfter().isPresent()) {
-                LOG.trace("Received change, data before: {}, data after: ", change.getRootNode().getDataBefore().get(),
+                LOG.trace("Received change, data before: {}, data after: ",
+                        change.getRootNode().getDataBefore().isPresent()
+                                ? change.getRootNode().getDataBefore().get() : "",
                         change.getRootNode().getDataAfter().get());
 
                 if (localCopy == null || checkEqual(change.getRootNode().getDataBefore().get())) {
index 5767008d05cd4d3bfebc34de3ae6933d248be469..fc3f9adfddf71b2f4759d21875012b04b17fd92a 100644 (file)
@@ -37,7 +37,9 @@ public class IdIntsListener implements DOMDataTreeChangeListener {
 
         changes.forEach(change -> {
             if (change.getRootNode().getDataAfter().isPresent()) {
-                LOG.trace("Received change, data before: {}, data after: ", change.getRootNode().getDataBefore().get(),
+                LOG.trace("Received change, data before: {}, data after: ",
+                        change.getRootNode().getDataBefore().isPresent()
+                                ? change.getRootNode().getDataBefore().get() : "",
                         change.getRootNode().getDataAfter().get());
 
                 if (localCopy == null || checkEqual(change.getRootNode().getDataBefore().get())) {
index ee46a74746c56c52451fa091746a9ed1e1b566af..917f6857694bc780b827f0273ddffd8907f7bbe5 100644 (file)
@@ -40,10 +40,14 @@ import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -56,6 +60,8 @@ public class ProduceTransactionsHandler implements Runnable {
 
     private static final QName ID_INTS =
             QName.create("tag:opendaylight.org,2017:controller:yang:lowlevel:target", "2017-02-15", "id-ints");
+    private static final QName ID_INT =
+            QName.create("tag:opendaylight.org,2017:controller:yang:lowlevel:target", "2017-02-15", "id-int");
     private static final QName ID =
             QName.create("tag:opendaylight.org,2017:controller:yang:lowlevel:target", "2017-02-15", "id");
     private static final QName ITEM =
@@ -63,8 +69,8 @@ public class ProduceTransactionsHandler implements Runnable {
     private static final QName NUMBER =
             QName.create("tag:opendaylight.org,2017:controller:yang:lowlevel:target", "2017-02-15", "number");
 
-    public static final YangInstanceIdentifier ID_INTS_YID =
-            YangInstanceIdentifier.create(new YangInstanceIdentifier.NodeIdentifier(ID_INTS));
+    public static final YangInstanceIdentifier ID_INTS_YID = YangInstanceIdentifier.of(ID_INTS);
+    public static final YangInstanceIdentifier ID_INT_YID = ID_INTS_YID.node(ID_INT);
 
     private final DOMDataTreeService domDataTreeService;
 
@@ -107,10 +113,10 @@ public class ProduceTransactionsHandler implements Runnable {
     }
 
     public void start(final SettableFuture<RpcResult<ProduceTransactionsOutput>> settableFuture) {
+        completionFuture = settableFuture;
 
         if (ensureListExists(completionFuture) && fillInitialList(completionFuture)) {
             startTime = System.nanoTime();
-            completionFuture = settableFuture;
             scheduledFuture = executor.scheduleAtFixedRate(this, 0, delay, TimeUnit.NANOSECONDS);
         } else {
             executor.shutdown();
@@ -119,14 +125,19 @@ public class ProduceTransactionsHandler implements Runnable {
 
     private boolean ensureListExists(final SettableFuture<RpcResult<ProduceTransactionsOutput>> settableFuture) {
 
-        final MapEntryNode entry = ImmutableNodes.mapEntryBuilder(ID_INTS, ID, id)
+        final MapEntryNode entry = ImmutableNodes.mapEntryBuilder(ID_INT, ID, id)
                 .withChild(ImmutableNodes.mapNodeBuilder(ITEM).build())
                 .build();
         final MapNode mapNode =
-                ImmutableNodes.mapNodeBuilder(ID_INTS)
+                ImmutableNodes.mapNodeBuilder(ID_INT)
                         .withChild(entry)
                         .build();
 
+        final ContainerNode containerNode = ImmutableContainerNodeBuilder.create()
+                .withNodeIdentifier(new NodeIdentifier(ID_INTS))
+                .withChild(mapNode)
+                .build();
+
         final DOMDataTreeProducer producer = domDataTreeService.createProducer(Collections.singleton(
                 new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.EMPTY)));
 
@@ -136,9 +147,9 @@ public class ProduceTransactionsHandler implements Runnable {
                 tx.createCursor(new DOMDataTreeIdentifier(
                         LogicalDatastoreType.CONFIGURATION, YangInstanceIdentifier.EMPTY));
 
-        idListWithKey = ID_INTS_YID.node(entry.getIdentifier());
+        idListWithKey = ID_INT_YID.node(entry.getIdentifier());
 
-        cursor.merge(mapNode.getIdentifier(), mapNode);
+        cursor.merge(containerNode.getIdentifier(), containerNode);
         cursor.close();
 
         try {
@@ -195,7 +206,7 @@ public class ProduceTransactionsHandler implements Runnable {
         final int i = random.nextInt(MAX_ITEM + 1);
 
         final YangInstanceIdentifier entryId =
-                idListWithKey.node(ITEM).node(new YangInstanceIdentifier.NodeIdentifierWithPredicates(ITEM, NUMBER, i));
+                idListWithKey.node(ITEM).node(new NodeIdentifierWithPredicates(ITEM, NUMBER, i));
 
         final DOMDataTreeCursorAwareTransaction tx = itemProducer.createTransaction(false);
         final DOMDataTreeWriteCursor cursor = tx.createCursor(
index 664e7fd26fcb85f8fedbb2ae1f36c0fe2c2ea8ac..a6f687b5b6e0742427543d101be59704f7064b5b 100644 (file)
@@ -41,10 +41,14 @@ import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -57,6 +61,8 @@ public class WriteTransactionsHandler implements Runnable {
 
     private static final QName ID_INTS =
             QName.create("tag:opendaylight.org,2017:controller:yang:lowlevel:target", "2017-02-15", "id-ints");
+    private static final QName ID_INT =
+            QName.create("tag:opendaylight.org,2017:controller:yang:lowlevel:target", "2017-02-15", "id-int");
     private static final QName ID =
             QName.create("tag:opendaylight.org,2017:controller:yang:lowlevel:target", "2017-02-15", "id");
     private static final QName ITEM =
@@ -65,6 +71,7 @@ public class WriteTransactionsHandler implements Runnable {
             QName.create("tag:opendaylight.org,2017:controller:yang:lowlevel:target", "2017-02-15", "number");
 
     public static final YangInstanceIdentifier ID_INTS_YID = YangInstanceIdentifier.of(ID_INTS);
+    public static final YangInstanceIdentifier ID_INT_YID = ID_INTS_YID.node(ID_INT);
 
     private final DOMDataBroker domDataBroker;
     private final Long timeToTake;
@@ -128,11 +135,14 @@ public class WriteTransactionsHandler implements Runnable {
 
     private boolean ensureListExists(final SettableFuture<RpcResult<WriteTransactionsOutput>> settableFuture) {
 
-        final MapNode mapNode = ImmutableNodes.mapNodeBuilder(ID_INTS).build();
+        final ContainerNode containerNode = ImmutableContainerNodeBuilder.create()
+                .withNodeIdentifier(new NodeIdentifier(ID_INTS))
+                .withChild(ImmutableNodes.mapNodeBuilder(ID_INT).build())
+                .build();
 
         DOMDataWriteTransaction tx = txProvider.createTransaction();
         // write only the top list
-        tx.merge(LogicalDatastoreType.CONFIGURATION, ID_INTS_YID, mapNode);
+        tx.merge(LogicalDatastoreType.CONFIGURATION, ID_INTS_YID, containerNode);
         try {
             tx.submit().checkedGet();
         } catch (final OptimisticLockFailedException e) {
@@ -146,11 +156,11 @@ public class WriteTransactionsHandler implements Runnable {
             return false;
         }
 
-        final MapEntryNode entry = ImmutableNodes.mapEntryBuilder(ID_INTS, ID, id)
+        final MapEntryNode entry = ImmutableNodes.mapEntryBuilder(ID_INT, ID, id)
                 .withChild(ImmutableNodes.mapNodeBuilder(ITEM).build())
                 .build();
 
-        idListWithKey = ID_INTS_YID.node(entry.getIdentifier());
+        idListWithKey = ID_INT_YID.node(entry.getIdentifier());
         tx = txProvider.createTransaction();
         tx.merge(LogicalDatastoreType.CONFIGURATION, idListWithKey, entry);