From: Tomas Cere Date: Tue, 25 Apr 2017 10:50:52 +0000 (+0200) Subject: Nest id-ints list inside a container X-Git-Tag: release/nitrogen~314 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=64dbc396e21d73a7323b3e9dbf51b31df295cfb5 Nest id-ints list inside a container 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 --- diff --git a/opendaylight/md-sal/samples/clustering-test-app/model/src/main/yang/odl-mdsal-lowlevel-target.yang b/opendaylight/md-sal/samples/clustering-test-app/model/src/main/yang/odl-mdsal-lowlevel-target.yang index b4f9c25843..8b799536a0 100644 --- a/opendaylight/md-sal/samples/clustering-test-app/model/src/main/yang/odl-mdsal-lowlevel-target.yang +++ b/opendaylight/md-sal/samples/clustering-test-app/model/src/main/yang/odl-mdsal-lowlevel-target.yang @@ -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; + } } } } - } diff --git a/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/MdsalLowLevelTestProvider.java b/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/MdsalLowLevelTestProvider.java index 98ae842a50..8ebac1c01e 100644 --- a/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/MdsalLowLevelTestProvider.java +++ b/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/MdsalLowLevelTestProvider.java @@ -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.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> 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 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( diff --git a/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/IdIntsDOMDataTreeLIstener.java b/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/IdIntsDOMDataTreeLIstener.java index be46a0ee31..3f9a3c52f6 100644 --- a/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/IdIntsDOMDataTreeLIstener.java +++ b/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/IdIntsDOMDataTreeLIstener.java @@ -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())) { diff --git a/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/IdIntsListener.java b/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/IdIntsListener.java index 5767008d05..fc3f9adfdd 100644 --- a/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/IdIntsListener.java +++ b/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/IdIntsListener.java @@ -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())) { diff --git a/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/ProduceTransactionsHandler.java b/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/ProduceTransactionsHandler.java index ee46a74746..917f685769 100644 --- a/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/ProduceTransactionsHandler.java +++ b/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/ProduceTransactionsHandler.java @@ -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> 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> 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( diff --git a/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/WriteTransactionsHandler.java b/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/WriteTransactionsHandler.java index 664e7fd26f..a6f687b5b6 100644 --- a/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/WriteTransactionsHandler.java +++ b/opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/clustering/it/provider/impl/WriteTransactionsHandler.java @@ -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> 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);