We now replicate DataTreeCandidates with root node type UNMODIFIED
however the deserialization in DataTreeCandidateInputOutput throws
an ISE with "Unhandled node type 2". The writeDataTreeCandidate
method writes the UNMODIFIED type but readDataTreeCandidate needs
to handle that case as well.
In addition, writeDataTreeCandidate also handles APPEARED and
DISAPPEARED but readDataTreeCandidate does not so I made that
change as well.
Change-Id: I19932e545bbeb95fa10d5f57d43a5780af586285
Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
final DataTreeCandidateNode rootNode;
switch (type) {
final DataTreeCandidateNode rootNode;
switch (type) {
+ case APPEARED:
+ rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.APPEARED, readChildren(reader));
+ break;
case DELETE:
rootNode = DeletedDataTreeCandidateNode.create();
break;
case DELETE:
rootNode = DeletedDataTreeCandidateNode.create();
break;
+ case DISAPPEARED:
+ rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.DISAPPEARED, readChildren(reader));
+ break;
- rootNode = ModifiedDataTreeCandidateNode.create(readChildren(reader));
+ rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.SUBTREE_MODIFIED,
+ readChildren(reader));
break;
case WRITE:
rootNode = DataTreeCandidateNodes.fromNormalizedNode(reader.readNormalizedNode());
break;
break;
case WRITE:
rootNode = DataTreeCandidateNodes.fromNormalizedNode(reader.readNormalizedNode());
break;
+ case UNMODIFIED:
+ rootNode = AbstractDataTreeCandidateNode.createUnmodified();
+ break;
default:
throw new IllegalArgumentException("Unhandled node type " + type);
}
default:
throw new IllegalArgumentException("Unhandled node type " + type);
}
this.children = Preconditions.checkNotNull(children);
}
this.children = Preconditions.checkNotNull(children);
}
- static DataTreeCandidateNode create(final Collection<DataTreeCandidateNode> children) {
- return new ModifiedDataTreeCandidateNode(ModificationType.SUBTREE_MODIFIED, children) {
+ static DataTreeCandidateNode create(final ModificationType type, final Collection<DataTreeCandidateNode> children) {
+ return new ModifiedDataTreeCandidateNode(type, children) {
@Override
public PathArgument getIdentifier() {
throw new UnsupportedOperationException("Root node does not have an identifier");
@Override
public PathArgument getIdentifier() {
throw new UnsupportedOperationException("Root node does not have an identifier");
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.cluster.datastore.AbstractTest;
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.cluster.datastore.AbstractTest;
+import org.opendaylight.controller.md.cluster.datastore.model.SchemaContextHelper;
import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidates;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidates;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.TipProducingDataTree;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeFactory;
public class CommitTransactionPayloadTest extends AbstractTest {
static final QName LEAF_SET = QName.create(TestModel.TEST_QNAME, "leaf-set");
public class CommitTransactionPayloadTest extends AbstractTest {
static final QName LEAF_SET = QName.create(TestModel.TEST_QNAME, "leaf-set");
private static void assertCandidateEquals(final DataTreeCandidate expected, final DataTreeCandidate actual) {
assertEquals("root path", expected.getRootPath(), actual.getRootPath());
private static void assertCandidateEquals(final DataTreeCandidate expected, final DataTreeCandidate actual) {
assertEquals("root path", expected.getRootPath(), actual.getRootPath());
-
- final DataTreeCandidateNode expRoot = expected.getRootNode();
- final DataTreeCandidateNode actRoot = expected.getRootNode();
- assertEquals("root type", expRoot.getModificationType(), actRoot.getModificationType());
-
- switch (actRoot.getModificationType()) {
- case DELETE:
- case WRITE:
- assertEquals("root data", expRoot.getDataAfter(), actRoot.getDataAfter());
- break;
- case SUBTREE_MODIFIED:
- assertChildrenEquals(expRoot.getChildNodes(), actRoot.getChildNodes());
- break;
- default:
- fail("Unexpect root type " + actRoot.getModificationType());
- break;
- }
-
assertCandidateNodeEquals(expected.getRootNode(), actual.getRootNode());
}
private static void assertCandidateNodeEquals(final DataTreeCandidateNode expected,
final DataTreeCandidateNode actual) {
assertEquals("child type", expected.getModificationType(), actual.getModificationType());
assertCandidateNodeEquals(expected.getRootNode(), actual.getRootNode());
}
private static void assertCandidateNodeEquals(final DataTreeCandidateNode expected,
final DataTreeCandidateNode actual) {
assertEquals("child type", expected.getModificationType(), actual.getModificationType());
- assertEquals("child identifier", expected.getIdentifier(), actual.getIdentifier());
switch (actual.getModificationType()) {
case DELETE:
case WRITE:
switch (actual.getModificationType()) {
case DELETE:
case WRITE:
+ assertEquals("child identifier", expected.getIdentifier(), actual.getIdentifier());
assertEquals("child data", expected.getDataAfter(), actual.getDataAfter());
break;
case SUBTREE_MODIFIED:
assertEquals("child data", expected.getDataAfter(), actual.getDataAfter());
break;
case SUBTREE_MODIFIED:
+ assertEquals("child identifier", expected.getIdentifier(), actual.getIdentifier());
assertChildrenEquals(expected.getChildNodes(), actual.getChildNodes());
break;
assertChildrenEquals(expected.getChildNodes(), actual.getChildNodes());
break;
+ case UNMODIFIED:
+ break;
default:
fail("Unexpect root type " + actual.getModificationType());
break;
default:
fail("Unexpect root type " + actual.getModificationType());
break;
CommitTransactionPayload payload = CommitTransactionPayload.create(nextTransactionId(), candidate);
assertCandidateEquals(candidate, payload.getCandidate().getValue());
}
CommitTransactionPayload payload = CommitTransactionPayload.create(nextTransactionId(), candidate);
assertCandidateEquals(candidate, payload.getCandidate().getValue());
}
+
+ @Test
+ public void testUnmodifiedRootCandidate() throws Exception {
+ final TipProducingDataTree dataTree = InMemoryDataTreeFactory.getInstance().create(TreeType.CONFIGURATION);
+ dataTree.setSchemaContext(SchemaContextHelper.select(SchemaContextHelper.CARS_YANG));
+
+ DataTreeModification modification = dataTree.takeSnapshot().newModification();
+ modification.ready();
+ candidate = dataTree.prepare(modification);
+
+ CommitTransactionPayload payload = CommitTransactionPayload.create(nextTransactionId(), candidate);
+ assertCandidateEquals(candidate, payload.getCandidate().getValue());
+ }