2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.data.impl.schema.tree;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.fail;
14 import com.google.common.collect.ImmutableMap;
15 import org.junit.Before;
16 import org.junit.Test;
17 import org.opendaylight.yangtools.yang.common.QName;
18 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
19 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
21 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
22 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
23 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
24 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
25 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
26 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeConfiguration;
27 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
28 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
29 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
30 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
31 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
32 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
33 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
35 public class Bug5968MergeTest {
36 private static final String NS = "foo";
37 private static final String REV = "2016-07-28";
38 private static final QName ROOT = QName.create(NS, REV, "root");
39 private static final QName MY_LIST = QName.create(NS, REV, "my-list");
40 private static final QName LIST_ID = QName.create(NS, REV, "list-id");
41 private static final QName MANDATORY_LEAF = QName.create(NS, REV, "mandatory-leaf");
42 private static final QName COMMON_LEAF = QName.create(NS, REV, "common-leaf");
43 private SchemaContext schemaContext;
47 this.schemaContext = TestModel.createTestContext("/bug5968/foo.yang");
48 assertNotNull("Schema context must not be null.", this.schemaContext);
51 private static DataTree initDataTree(final SchemaContext schemaContext, final boolean withMapNode)
52 throws DataValidationFailedException {
53 final DataTree inMemoryDataTree = new InMemoryDataTreeFactory().create(
54 DataTreeConfiguration.DEFAULT_CONFIGURATION, schemaContext);
56 final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> root = Builders.containerBuilder()
57 .withNodeIdentifier(new NodeIdentifier(ROOT));
58 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
59 modificationTree.merge(
60 YangInstanceIdentifier.of(ROOT),
61 withMapNode ? root.withChild(
62 Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(MY_LIST)).build()).build() : root
64 modificationTree.ready();
66 inMemoryDataTree.validate(modificationTree);
67 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
68 inMemoryDataTree.commit(prepare);
70 return inMemoryDataTree;
73 private static DataTree emptyDataTree(final SchemaContext schemaContext)
74 throws DataValidationFailedException {
75 return new InMemoryDataTreeFactory().create(DataTreeConfiguration.DEFAULT_CONFIGURATION, schemaContext);
79 public void mergeInvalidContainerTest() throws DataValidationFailedException {
80 final DataTree inMemoryDataTree = emptyDataTree(schemaContext);
82 final MapNode myList = createMap(true);
83 final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> root = Builders.containerBuilder()
84 .withNodeIdentifier(new NodeIdentifier(ROOT)).withChild(myList);
86 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
87 modificationTree.merge(YangInstanceIdentifier.of(ROOT), root.build());
90 modificationTree.ready();
91 inMemoryDataTree.validate(modificationTree);
92 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
93 inMemoryDataTree.commit(prepare);
94 fail("Should fail due to missing mandatory leaf.");
95 } catch (final IllegalArgumentException e) {
97 "Node (foo?revision=2016-07-28)my-list[{(foo?revision=2016-07-28)list-id=1}] is missing mandatory "
98 + "descendant /(foo?revision=2016-07-28)mandatory-leaf", e.getMessage());
103 public void mergeInvalidMapTest() throws DataValidationFailedException {
104 final DataTree inMemoryDataTree = emptyDataTree(schemaContext);
105 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
106 mergeMap(modificationTree, true);
109 modificationTree.ready();
110 inMemoryDataTree.validate(modificationTree);
111 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
112 inMemoryDataTree.commit(prepare);
113 fail("Should fail due to missing mandatory leaf.");
114 } catch (final IllegalArgumentException e) {
116 "Node (foo?revision=2016-07-28)my-list[{(foo?revision=2016-07-28)list-id=1}] is missing mandatory "
117 + "descendant /(foo?revision=2016-07-28)mandatory-leaf", e.getMessage());
122 public void mergeInvalidMapEntryTest() throws DataValidationFailedException {
123 final DataTree inMemoryDataTree = initDataTree(schemaContext, true);
124 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
126 mergeMapEntry(modificationTree, "1", null, "common-value");
129 modificationTree.ready();
130 inMemoryDataTree.validate(modificationTree);
131 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
132 inMemoryDataTree.commit(prepare);
133 fail("Should fail due to missing mandatory leaf.");
134 } catch (final IllegalArgumentException e) {
136 "Node (foo?revision=2016-07-28)my-list[{(foo?revision=2016-07-28)list-id=1}] is missing mandatory "
137 + "descendant /(foo?revision=2016-07-28)mandatory-leaf", e.getMessage());
141 private static void mergeMap(final DataTreeModification modificationTree,
142 final boolean mandatoryDataMissing) throws DataValidationFailedException {
143 final MapNode myList = createMap(mandatoryDataMissing);
144 modificationTree.merge(YangInstanceIdentifier.of(ROOT).node(MY_LIST), myList);
147 private static MapNode createMap(final boolean mandatoryDataMissing) throws DataValidationFailedException {
150 .withNodeIdentifier(new NodeIdentifier(MY_LIST))
152 mandatoryDataMissing ? createMapEntry("1", "common-value") : createMapEntry("1",
153 "mandatory-value", "common-value")).build();
156 private static void mergeMapEntry(final DataTreeModification modificationTree, final Object listIdValue,
157 final Object mandatoryLeafValue, final Object commonLeafValue) throws DataValidationFailedException {
158 final MapEntryNode taskEntryNode = mandatoryLeafValue == null ? createMapEntry(listIdValue, commonLeafValue)
159 : createMapEntry(listIdValue, mandatoryLeafValue, commonLeafValue);
161 modificationTree.merge(
162 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
163 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, listIdValue))),
167 private static MapEntryNode createMapEntry(final Object listIdValue, final Object mandatoryLeafValue,
168 final Object commonLeafValue) throws DataValidationFailedException {
169 return Builders.mapEntryBuilder()
170 .withNodeIdentifier(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, listIdValue)))
171 .withChild(ImmutableNodes.leafNode(LIST_ID, listIdValue))
172 .withChild(ImmutableNodes.leafNode(MANDATORY_LEAF, mandatoryLeafValue))
173 .withChild(ImmutableNodes.leafNode(COMMON_LEAF, commonLeafValue)).build();
176 private static MapEntryNode createMapEntry(final Object listIdValue, final Object commonLeafValue)
177 throws DataValidationFailedException {
178 return Builders.mapEntryBuilder()
179 .withNodeIdentifier(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, listIdValue)))
180 .withChild(ImmutableNodes.leafNode(LIST_ID, listIdValue))
181 .withChild(ImmutableNodes.leafNode(COMMON_LEAF, commonLeafValue)).build();
184 private static MapEntryNode createMapEntryM(final Object listIdValue, final Object mandatoryLeafValue)
185 throws DataValidationFailedException {
186 return Builders.mapEntryBuilder()
187 .withNodeIdentifier(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, listIdValue)))
188 .withChild(ImmutableNodes.leafNode(LIST_ID, listIdValue))
189 .withChild(ImmutableNodes.leafNode(MANDATORY_LEAF, mandatoryLeafValue)).build();
193 public void mergeValidContainerTest() throws DataValidationFailedException {
194 final DataTree inMemoryDataTree = emptyDataTree(schemaContext);
196 final MapNode myList = createMap(false);
197 final DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> root = Builders.containerBuilder()
198 .withNodeIdentifier(new NodeIdentifier(ROOT)).withChild(myList);
200 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
201 modificationTree.merge(YangInstanceIdentifier.of(ROOT), root.build());
202 modificationTree.ready();
203 inMemoryDataTree.validate(modificationTree);
204 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
205 inMemoryDataTree.commit(prepare);
209 public void mergeValidMapTest() throws DataValidationFailedException {
210 final DataTree inMemoryDataTree = emptyDataTree(schemaContext);
211 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
212 mergeMap(modificationTree, false);
214 modificationTree.ready();
215 inMemoryDataTree.validate(modificationTree);
216 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
217 inMemoryDataTree.commit(prepare);
221 public void mergeValidMapEntryTest() throws DataValidationFailedException {
222 final DataTree inMemoryDataTree = initDataTree(schemaContext, true);
223 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
225 mergeMapEntry(modificationTree, "1", "mandatory-value", "common-value");
227 modificationTree.ready();
228 inMemoryDataTree.validate(modificationTree);
229 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
230 inMemoryDataTree.commit(prepare);
234 public void validMultiStepsMergeTest() throws DataValidationFailedException {
235 final DataTree inMemoryDataTree = emptyDataTree(schemaContext);
236 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
238 modificationTree.merge(YangInstanceIdentifier.of(ROOT), createContainerBuilder().build());
239 modificationTree.merge(YangInstanceIdentifier.of(ROOT).node(MY_LIST), createMapBuilder().build());
240 modificationTree.merge(
241 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
242 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
243 createEmptyMapEntryBuilder("1").build());
244 modificationTree.merge(
245 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
246 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
247 createMapEntry("1", "mandatory-value", "common-value"));
249 modificationTree.ready();
250 inMemoryDataTree.validate(modificationTree);
251 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
252 inMemoryDataTree.commit(prepare);
256 public void invalidMultiStepsMergeTest() throws DataValidationFailedException {
257 final DataTree inMemoryDataTree = emptyDataTree(schemaContext);
258 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
260 modificationTree.merge(YangInstanceIdentifier.of(ROOT), createContainerBuilder().build());
261 modificationTree.merge(YangInstanceIdentifier.of(ROOT).node(MY_LIST), createMapBuilder().build());
262 modificationTree.merge(
263 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
264 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
265 createEmptyMapEntryBuilder("1").build());
266 modificationTree.merge(
267 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
268 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
269 createMapEntry("1", "common-value"));
272 modificationTree.ready();
273 inMemoryDataTree.validate(modificationTree);
274 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
275 inMemoryDataTree.commit(prepare);
276 fail("Should fail due to missing mandatory leaf.");
277 } catch (final IllegalArgumentException e) {
279 "Node (foo?revision=2016-07-28)my-list[{(foo?revision=2016-07-28)list-id=1}] is missing mandatory "
280 + "descendant /(foo?revision=2016-07-28)mandatory-leaf", e.getMessage());
284 private static DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> createEmptyMapEntryBuilder(
285 final Object listIdValue) throws DataValidationFailedException {
286 return Builders.mapEntryBuilder()
287 .withNodeIdentifier(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, listIdValue)))
288 .withChild(ImmutableNodes.leafNode(LIST_ID, listIdValue));
291 private static CollectionNodeBuilder<MapEntryNode, MapNode> createMapBuilder() {
292 return Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(MY_LIST));
295 private static DataContainerNodeAttrBuilder<NodeIdentifier, ContainerNode> createContainerBuilder() {
296 return Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(ROOT));
300 public void validMultiStepsWriteAndMergeTest() throws DataValidationFailedException {
301 final DataTree inMemoryDataTree = emptyDataTree(schemaContext);
302 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
304 modificationTree.write(YangInstanceIdentifier.of(ROOT), createContainerBuilder().build());
305 modificationTree.merge(YangInstanceIdentifier.of(ROOT).node(MY_LIST), createMapBuilder().build());
306 modificationTree.merge(
307 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
308 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
309 createEmptyMapEntryBuilder("1").build());
310 modificationTree.merge(
311 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
312 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
313 createMapEntry("1", "mandatory-value", "common-value"));
315 modificationTree.ready();
316 inMemoryDataTree.validate(modificationTree);
317 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
318 inMemoryDataTree.commit(prepare);
322 public void invalidMultiStepsWriteAndMergeTest() throws DataValidationFailedException {
323 final DataTree inMemoryDataTree = emptyDataTree(schemaContext);
324 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
326 modificationTree.write(YangInstanceIdentifier.of(ROOT), createContainerBuilder().build());
327 modificationTree.merge(YangInstanceIdentifier.of(ROOT).node(MY_LIST), createMapBuilder().build());
328 modificationTree.merge(
329 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
330 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
331 createEmptyMapEntryBuilder("1").build());
332 modificationTree.merge(
333 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
334 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
335 createMapEntry("1", "common-value"));
338 modificationTree.ready();
339 inMemoryDataTree.validate(modificationTree);
340 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
341 inMemoryDataTree.commit(prepare);
342 fail("Should fail due to missing mandatory leaf.");
343 } catch (final IllegalArgumentException e) {
345 "Node (foo?revision=2016-07-28)my-list[{(foo?revision=2016-07-28)list-id=1}] is missing mandatory "
346 + "descendant /(foo?revision=2016-07-28)mandatory-leaf", e.getMessage());
351 public void validMapEntryMultiCommitMergeTest() throws DataValidationFailedException {
352 final DataTree inMemoryDataTree = emptyDataTree(schemaContext);
353 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
355 modificationTree.write(YangInstanceIdentifier.of(ROOT), createContainerBuilder().build());
356 modificationTree.merge(YangInstanceIdentifier.of(ROOT).node(MY_LIST), createMapBuilder().build());
357 modificationTree.merge(
358 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
359 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
360 createEmptyMapEntryBuilder("1").build());
361 modificationTree.merge(
362 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
363 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
364 createMapEntryM("1", "mandatory-value"));
366 modificationTree.ready();
367 inMemoryDataTree.validate(modificationTree);
368 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
369 inMemoryDataTree.commit(prepare);
371 final DataTreeModification modificationTree2 = inMemoryDataTree.takeSnapshot().newModification();
372 modificationTree2.merge(
373 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
374 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
375 createMapEntry("1", "common-value"));
376 modificationTree2.ready();
377 inMemoryDataTree.validate(modificationTree2);
378 final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
379 inMemoryDataTree.commit(prepare2);
383 public void invalidMapEntryMultiCommitMergeTest() throws DataValidationFailedException {
384 final DataTree inMemoryDataTree = emptyDataTree(schemaContext);
385 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
387 modificationTree.write(YangInstanceIdentifier.of(ROOT), createContainerBuilder().build());
388 modificationTree.merge(YangInstanceIdentifier.of(ROOT).node(MY_LIST), createMapBuilder().build());
389 modificationTree.merge(
390 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
391 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
392 createEmptyMapEntryBuilder("1").build());
393 modificationTree.merge(
394 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
395 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
396 createMapEntryM("1", "mandatory-value"));
398 modificationTree.ready();
399 inMemoryDataTree.validate(modificationTree);
400 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
401 inMemoryDataTree.commit(prepare);
403 final DataTreeModification modificationTree2 = inMemoryDataTree.takeSnapshot().newModification();
404 modificationTree2.write(
405 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
406 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
407 createMapEntry("1", "common-value"));
408 modificationTree2.merge(
409 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
410 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
411 createMapEntryM("1", "mandatory-value"));
412 modificationTree2.merge(
413 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
414 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, "2"))),
415 createMapEntry("2", "common-value"));
417 modificationTree2.ready();
418 inMemoryDataTree.validate(modificationTree2);
419 final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
420 inMemoryDataTree.commit(prepare2);
421 fail("Should fail due to missing mandatory leaf.");
422 } catch (final IllegalArgumentException e) {
424 "Node (foo?revision=2016-07-28)my-list[{(foo?revision=2016-07-28)list-id=2}] is missing mandatory "
425 + "descendant /(foo?revision=2016-07-28)mandatory-leaf", e.getMessage());
430 * This test consists of two transactions (i.e. data tree modifications) on
431 * empty data tree. The first one writes mandatory data and second one
432 * writes common data without any mandatory data.
435 public void validMapEntryMultiCommitMergeTest2() throws DataValidationFailedException {
436 final DataTree inMemoryDataTree = emptyDataTree(schemaContext);
437 final DataTreeModification modificationTree = inMemoryDataTree.takeSnapshot().newModification();
438 final DataTreeModification modificationTree2 = inMemoryDataTree.takeSnapshot().newModification();
440 modificationTree.write(YangInstanceIdentifier.of(ROOT), createContainerBuilder().build());
441 modificationTree.merge(YangInstanceIdentifier.of(ROOT).node(MY_LIST), createMapBuilder().build());
442 modificationTree.merge(
443 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
444 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
445 createEmptyMapEntryBuilder("1").build());
446 modificationTree.merge(
447 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
448 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
449 createMapEntryM("1", "mandatory-value"));
451 modificationTree.ready();
452 inMemoryDataTree.validate(modificationTree);
453 final DataTreeCandidate prepare = inMemoryDataTree.prepare(modificationTree);
454 inMemoryDataTree.commit(prepare);
456 modificationTree2.merge(
457 YangInstanceIdentifier.of(ROOT).node(MY_LIST)
458 .node(new NodeIdentifierWithPredicates(MY_LIST, ImmutableMap.of(LIST_ID, "1"))),
459 createMapEntry("1", "common-value"));
460 modificationTree2.ready();
461 inMemoryDataTree.validate(modificationTree2);
462 final DataTreeCandidate prepare2 = inMemoryDataTree.prepare(modificationTree2);
463 inMemoryDataTree.commit(prepare2);