2 * Copyright (c) 2016 Cisco and/or its affiliates.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package io.fd.honeycomb.data.impl;
19 import static org.junit.Assert.fail;
20 import static org.mockito.Matchers.any;
21 import static org.mockito.Matchers.eq;
22 import static org.mockito.Mockito.atLeastOnce;
23 import static org.mockito.Mockito.inOrder;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.times;
26 import static org.mockito.Mockito.verify;
27 import static org.mockito.Mockito.verifyNoMoreInteractions;
28 import static org.mockito.Mockito.when;
30 import com.google.common.collect.Lists;
31 import com.google.common.collect.Sets;
32 import io.fd.honeycomb.data.DataModification;
33 import io.fd.honeycomb.test.model.Ids;
34 import io.fd.honeycomb.translate.impl.write.registry.FlatWriterRegistryBuilder;
35 import io.fd.honeycomb.translate.util.YangDAG;
36 import io.fd.honeycomb.translate.write.WriteContext;
37 import io.fd.honeycomb.translate.write.WriteFailedException;
38 import io.fd.honeycomb.translate.write.Writer;
39 import io.fd.honeycomb.translate.write.registry.WriterRegistry;
40 import java.util.ArrayList;
41 import java.util.Arrays;
42 import java.util.Collections;
43 import java.util.List;
45 import javax.annotation.Nonnull;
46 import javax.annotation.Nullable;
47 import org.junit.Test;
48 import org.mockito.InOrder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.ComplexAugment;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.ComplexAugmentBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.ContainerWithChoice;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.ContainerWithChoiceBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.ContainerWithList;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.ContainerWithListBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.SimpleAugment;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.SimpleAugmentBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.SimpleContainer;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.SimpleContainerBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.choice.Choice;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.choice.choice.c3.C3;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.choice.choice.c3.C3Builder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.ListInContainer;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.ListInContainerBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.ListInContainerKey;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.list.in.container.ContainerInList;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.list.in.container.ContainerInListBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.list.in.container.container.in.list.NestedList;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.list.in.container.container.in.list.NestedListBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.list.in.container.container.in.list.NestedListKey;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.simple.container.ComplexAugmentContainer;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.simple.container.ComplexAugmentContainerBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.some.attributes.ContainerFromGrouping;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.some.attributes.ContainerFromGroupingBuilder;
74 import org.opendaylight.yangtools.yang.binding.DataObject;
75 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
76 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
77 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
78 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
79 import org.opendaylight.yangtools.yang.data.api.schema.tree.TipProducingDataTree;
80 import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
81 import org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeFactory;
84 * Testing honeycomb writes from data tree up to mocked writers.
86 public class HoneycombWriteInfraTest extends AbstractInfraTest {
88 private TipProducingDataTree dataTree;
89 private WriterRegistry writerRegistry;
91 Writer<SimpleContainer> simpleContainerWriter = mockWriter(Ids.SIMPLE_CONTAINER_ID);
92 Writer<ComplexAugment> complexAugmentWriter = mockWriter(Ids.COMPLEX_AUGMENT_ID);
93 Writer<ComplexAugmentContainer> complexAugmentContainerWriter = mockWriter(Ids.COMPLEX_AUGMENT_CONTAINER_ID);
94 Writer<SimpleAugment> simpleAugmentWriter = mockWriter(Ids.SIMPLE_AUGMENT_ID);
96 Writer<ContainerWithList> containerWithListWriter = mockWriter(Ids.CONTAINER_WITH_LIST_ID);
97 Writer<ListInContainer> listInContainerWriter = mockWriter(Ids.LIST_IN_CONTAINER_ID);
98 Writer<ContainerInList> containerInListWriter = mockWriter(Ids.CONTAINER_IN_LIST_ID);
99 Writer<NestedList> nestedListWriter = mockWriter(Ids.NESTED_LIST_ID);
101 Writer<ContainerWithChoice> containerWithChoiceWriter = mockWriter(Ids.CONTAINER_WITH_CHOICE_ID);
102 Writer<ContainerFromGrouping> containerFromGroupingWriter = mockWriter(Ids.CONTAINER_FROM_GROUPING_ID);
103 Writer<C3> c3Writer = mockWriter(Ids.C3_ID);
106 private static <D extends DataObject> Writer<D> mockWriter(final InstanceIdentifier<D> id) {
107 final Writer<D> mock = (Writer<D>) mock(Writer.class);
108 when(mock.getManagedDataObjectType()).thenReturn(id);
109 //TODO - HONEYCOMB-412 - to call default impl of canProcess()
110 when(mock.canProcess(any())).thenAnswer(invocationOnMock -> {
111 final Writer writer = Writer.class.cast(invocationOnMock.getMock());
112 final Writer delegatingWriter = new Writer() {
115 public InstanceIdentifier getManagedDataObjectType() {
116 return writer.getManagedDataObjectType();
120 public boolean supportsDirectUpdate() {
121 return writer.supportsDirectUpdate();
125 public void processModification(@Nonnull final InstanceIdentifier id,
126 @Nullable final DataObject dataBefore,
127 @Nullable final DataObject dataAfter, @Nonnull final WriteContext ctx)
128 throws WriteFailedException {
129 writer.processModification(id, dataBefore, dataAfter, ctx);
132 return delegatingWriter.canProcess(InstanceIdentifier.class.cast(invocationOnMock.getArguments()[0]));
140 initWriterRegistry();
143 private void initDataTree() {
144 dataTree = InMemoryDataTreeFactory.getInstance().create(TreeType.CONFIGURATION);
145 dataTree.setSchemaContext(schemaContext);
148 private void initWriterRegistry() {
149 writerRegistry = new FlatWriterRegistryBuilder(new YangDAG())
150 .add(complexAugmentWriter) // unordered
151 .add(nestedListWriter) // 6
152 .addAfter(listInContainerWriter, Ids.NESTED_LIST_ID) // 7
153 .addAfter(containerInListWriter, Ids.LIST_IN_CONTAINER_ID) // 8
154 .addAfter(containerWithListWriter, Ids.CONTAINER_IN_LIST_ID) // 9
155 .addBefore(containerFromGroupingWriter, Ids.NESTED_LIST_ID) // 5
156 .addBefore(containerWithChoiceWriter, Ids.CONTAINER_FROM_GROUPING_ID) // 4
157 .addBefore(simpleContainerWriter, Ids.CONTAINER_WITH_CHOICE_ID) // 3
158 .addBefore(c3Writer, Ids.SIMPLE_CONTAINER_ID) // 2
159 .addBefore(simpleAugmentWriter, Ids.SIMPLE_CONTAINER_ID) // 2
160 .addBefore(complexAugmentContainerWriter, Sets.newHashSet(Ids.C3_ID, Ids.SIMPLE_AUGMENT_ID)) // 1
165 public void testWriteEmptyNonPresenceContainer() throws Exception {
166 final ModifiableDataTreeDelegator modifiableDataTreeDelegator =
167 new ModifiableDataTreeDelegator(serializer, dataTree, schemaContext, writerRegistry, contextBroker);
169 final DataModification dataModification = modifiableDataTreeDelegator.newModification();
170 final SimpleContainer data = new SimpleContainerBuilder()
173 final Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNode =
174 serializer.toNormalizedNode(Ids.SIMPLE_CONTAINER_ID, data);
175 dataModification.write(normalizedNode.getKey(), normalizedNode.getValue());
177 dataModification.commit();
179 verify(simpleContainerWriter).getManagedDataObjectType();
180 verifyNoMoreInteractions(simpleContainerWriter);
184 public void testWriteEverything() throws Exception {
185 final ModifiableDataTreeDelegator modifiableDataTreeDelegator =
186 new ModifiableDataTreeDelegator(serializer, dataTree, schemaContext, writerRegistry, contextBroker);
188 final DataModification dataModification = modifiableDataTreeDelegator.newModification();
189 // Now write everything we can
190 writeSimpleContainer(dataModification);
191 writeContainerWithChoice(dataModification);
192 writeContainerWithList(dataModification);
193 dataModification.commit();
195 final Writer<?>[] orderedWriters = getOrderedWriters();
196 final InOrder inOrder = inOrder(orderedWriters);
197 verifyOrderedWrites(orderedWriters, inOrder);
200 private void verifyOrderedWrites(final Writer<?>[] orderedWriters, final InOrder inOrder)
201 throws WriteFailedException {
202 // Modifications are not produced for nodes that do not contain any actual leaves (except when choice is a child)
204 // verify(complexAugmentWriter).update(eq(COMPLEX_AUGMENT_ID), eq(null), eq(getComplexAugment()), any(WriteContext.class));
206 inOrder.verify(complexAugmentContainerWriter)
207 .processModification(eq(Ids.COMPLEX_AUGMENT_CONTAINER_ID), eq(null), eq(getComplexAugmentContainer()), any(WriteContext.class));
209 inOrder.verify(c3Writer)
210 .processModification(eq(Ids.C3_ID), eq(null), eq(getC3()), any(WriteContext.class));
212 verify(simpleAugmentWriter)
213 .processModification(eq(Ids.SIMPLE_AUGMENT_ID), eq(null), eq(getSimpleAugment()), any(WriteContext.class));
215 inOrder.verify(simpleContainerWriter)
216 .processModification(eq(Ids.SIMPLE_CONTAINER_ID), eq(null), eq(getSimpleContainer()), any(WriteContext.class));
218 inOrder.verify(containerWithChoiceWriter)
219 .processModification(eq(Ids.CONTAINER_WITH_CHOICE_ID), eq(null), eq(getContainerWithChoiceWithComplexCase()), any(WriteContext.class));
221 inOrder.verify(containerFromGroupingWriter)
222 .processModification(eq(Ids.CONTAINER_FROM_GROUPING_ID), eq(null), eq(getContainerFromGrouping()), any(WriteContext.class));
224 final KeyedInstanceIdentifier<ListInContainer, ListInContainerKey> keyedListInContainer1 =
225 Ids.CONTAINER_WITH_LIST_ID.child(ListInContainer.class, new ListInContainerKey((long) 1));
226 final KeyedInstanceIdentifier<NestedList, NestedListKey> keyedNestedList1 =
227 keyedListInContainer1.child(ContainerInList.class).child(NestedList.class, new NestedListKey("1"));
228 final KeyedInstanceIdentifier<ListInContainer, ListInContainerKey> keyedListInContainer2 =
229 Ids.CONTAINER_WITH_LIST_ID.child(ListInContainer.class, new ListInContainerKey((long) 2));
230 final KeyedInstanceIdentifier<NestedList, NestedListKey> keyedNestedList2 =
231 keyedListInContainer2.child(ContainerInList.class).child(NestedList.class, new NestedListKey("2"));
234 inOrder.verify(nestedListWriter)
235 .processModification(eq(keyedNestedList1), eq(null), eq(getSingleNestedList("1")), any(WriteContext.class));
236 verify(nestedListWriter)
237 .processModification(eq(keyedNestedList2), eq(null), eq(getSingleNestedList("2")), any(WriteContext.class));
240 inOrder.verify(listInContainerWriter)
241 .processModification(eq(keyedListInContainer1), eq(null), eq(getSingleListInContainer((long)1)), any(WriteContext.class));
242 verify(listInContainerWriter)
243 .processModification(eq(keyedListInContainer2), eq(null), eq(getSingleListInContainer((long)2)), any(WriteContext.class));
246 inOrder.verify(containerInListWriter)
247 .processModification(eq(keyedListInContainer1.child(ContainerInList.class)), eq(null), eq(getContainerInList("1")), any(WriteContext.class));
248 verify(containerInListWriter)
249 .processModification(eq(keyedListInContainer2.child(ContainerInList.class)), eq(null), eq(getContainerInList("2")), any(WriteContext.class));
251 // 9 - Ignored because the container has no leaves, only complex child nodes
252 // inOrder.verify(containerWithListWriter)
253 // .update(eq(CONTAINER_WITH_LIST_ID), eq(null), eq(getContainerWithList()), any(WriteContext.class));
255 for (Writer<?> orderedWriter : orderedWriters) {
256 verify(orderedWriter).getManagedDataObjectType();
257 //TODO - HONEYCOMB-412
258 //verifyNoMoreInteractions(orderedWriter);
261 verify(complexAugmentContainerWriter, times(1)).processModification(any(), any(), any(), any());
262 verify(c3Writer, times(1)).processModification(any(), any(), any(), any());
263 verify(simpleAugmentWriter, times(1)).processModification(any(), any(), any(), any());
264 verify(simpleContainerWriter, times(1)).processModification(any(), any(), any(), any());
265 verify(containerWithChoiceWriter, times(1)).processModification(any(), any(), any(), any());
266 verify(containerFromGroupingWriter, times(1)).processModification(any(), any(), any(), any());
267 verify(nestedListWriter, times(2)).processModification(any(), any(), any(), any());
268 verify(listInContainerWriter, times(2)).processModification(any(), any(), any(), any());
269 verify(containerInListWriter, times(2)).processModification(any(), any(), any(), any());
272 private Writer<?>[] getOrderedWriters() {
273 return new Writer<?>[]{complexAugmentWriter, // Unordered
274 complexAugmentContainerWriter, // 1
276 simpleAugmentWriter, // 2
277 simpleContainerWriter, // 3
278 containerWithChoiceWriter, // 4
279 containerFromGroupingWriter, // 5
280 nestedListWriter, // 6
281 listInContainerWriter, // 7
282 containerInListWriter, // 8
283 containerWithListWriter};
287 public void testDeletes() throws Exception {
288 final ModifiableDataTreeDelegator modifiableDataTreeDelegator =
289 new ModifiableDataTreeDelegator(serializer, dataTree, schemaContext, writerRegistry, contextBroker);
291 DataModification dataModification = modifiableDataTreeDelegator.newModification();
292 // Now write everything we can
293 writeSimpleContainer(dataModification);
294 writeContainerWithChoice(dataModification);
295 writeContainerWithList(dataModification);
296 dataModification.commit();
297 // Verify writes to be able to verifyNoMore interactions at the end
298 verifyOrderedWrites(getOrderedWriters(), inOrder(getOrderedWriters()));
300 dataModification = modifiableDataTreeDelegator.newModification();
301 deleteSimpleContainer(dataModification);
302 deleteContainerWithChoice(dataModification);
303 deleteContainerWithList(dataModification);
304 dataModification.commit();
306 final Writer<?>[] orderedWriters = getOrderedWriters();
307 Collections.reverse(Arrays.asList(orderedWriters));
308 final InOrder inOrder = inOrder(orderedWriters);
310 final KeyedInstanceIdentifier<ListInContainer, ListInContainerKey> keyedListInContainer1 =
311 Ids.CONTAINER_WITH_LIST_ID.child(ListInContainer.class, new ListInContainerKey((long) 1));
312 final KeyedInstanceIdentifier<NestedList, NestedListKey> keyedNestedList1 =
313 keyedListInContainer1.child(ContainerInList.class).child(NestedList.class, new NestedListKey("1"));
314 final KeyedInstanceIdentifier<ListInContainer, ListInContainerKey> keyedListInContainer2 =
315 Ids.CONTAINER_WITH_LIST_ID.child(ListInContainer.class, new ListInContainerKey((long) 2));
316 final KeyedInstanceIdentifier<NestedList, NestedListKey> keyedNestedList2 =
317 keyedListInContainer2.child(ContainerInList.class).child(NestedList.class, new NestedListKey("2"));
319 // Deletes are handled in reverse order
321 inOrder.verify(containerInListWriter)
322 .processModification(eq(keyedListInContainer1.child(ContainerInList.class)), eq(getContainerInList("1")), eq(null), any(WriteContext.class));
323 verify(containerInListWriter)
324 .processModification(eq(keyedListInContainer2.child(ContainerInList.class)), eq(getContainerInList("2")), eq(null), any(WriteContext.class));
327 inOrder.verify(listInContainerWriter)
328 .processModification(eq(keyedListInContainer1), eq(getSingleListInContainer((long)1)), eq(null), any(WriteContext.class));
329 verify(listInContainerWriter)
330 .processModification(eq(keyedListInContainer2), eq(getSingleListInContainer((long)2)), eq(null), any(WriteContext.class));
333 inOrder.verify(nestedListWriter)
334 .processModification(eq(keyedNestedList1), eq(getSingleNestedList("1")), eq(null), any(WriteContext.class));
335 verify(nestedListWriter)
336 .processModification(eq(keyedNestedList2), eq(getSingleNestedList("2")), eq(null), any(WriteContext.class));
338 inOrder.verify(containerFromGroupingWriter)
339 .processModification(eq(Ids.CONTAINER_FROM_GROUPING_ID), eq(getContainerFromGrouping()), eq(null), any(WriteContext.class));
341 inOrder.verify(containerWithChoiceWriter)
342 .processModification(eq(Ids.CONTAINER_WITH_CHOICE_ID), eq(getContainerWithChoiceWithComplexCase()), eq(null), any(WriteContext.class));
344 inOrder.verify(simpleContainerWriter)
345 .processModification(eq(Ids.SIMPLE_CONTAINER_ID), eq(getSimpleContainer()), eq(null), any(WriteContext.class));
347 verify(simpleAugmentWriter)
348 .processModification(eq(Ids.SIMPLE_AUGMENT_ID), eq(getSimpleAugment()), eq(null), any(WriteContext.class));
350 inOrder.verify(c3Writer)
351 .processModification(eq(Ids.C3_ID), eq(getC3()), eq(null), any(WriteContext.class));
353 inOrder.verify(complexAugmentContainerWriter)
354 .processModification(eq(Ids.COMPLEX_AUGMENT_CONTAINER_ID), eq(getComplexAugmentContainer()), eq(null), any(WriteContext.class));
356 for (Writer<?> orderedWriter : orderedWriters) {
357 verify(orderedWriter).getManagedDataObjectType();
358 //TODO - HONEYCOMB-412
359 // verifyNoMoreInteractions(orderedWriter);
362 verify(complexAugmentContainerWriter, times(2)).processModification(any(), any(), any(), any());
363 verify(c3Writer, times(2)).processModification(any(), any(), any(), any());
364 verify(simpleAugmentWriter, times(2)).processModification(any(), any(), any(), any());
365 verify(simpleContainerWriter, times(2)).processModification(any(), any(), any(), any());
366 verify(containerWithChoiceWriter, times(2)).processModification(any(), any(), any(), any());
367 verify(containerFromGroupingWriter, times(2)).processModification(any(), any(), any(), any());
368 verify(nestedListWriter, times(4)).processModification(any(), any(), any(), any());
369 verify(listInContainerWriter, times(4)).processModification(any(), any(), any(), any());
370 verify(containerInListWriter, times(4)).processModification(any(), any(), any(), any());
373 private void writeContainerWithList(final DataModification dataModification) {
374 final Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNode =
375 serializer.toNormalizedNode(Ids.CONTAINER_WITH_LIST_ID, getContainerWithList());
376 dataModification.write(normalizedNode.getKey(), normalizedNode.getValue());
379 private void deleteContainerWithList(final DataModification dataModification) {
380 dataModification.delete(serializer.toYangInstanceIdentifier(Ids.CONTAINER_WITH_LIST_ID));
383 private ContainerWithList getContainerWithList() {
384 return new ContainerWithListBuilder()
385 .setListInContainer(getListInContainer((long)1, (long)2))
389 private List<ListInContainer> getListInContainer(final Long... keys) {
390 final ArrayList<ListInContainer> objects = Lists.newArrayList();
391 for (Long key : keys) {
392 objects.add(getSingleListInContainer(key));
397 private ListInContainer getSingleListInContainer(final Long key) {
398 return new ListInContainerBuilder()
400 .setContainerInList(getContainerInList(Long.toString(key)))
404 private ContainerInList getContainerInList(String... nestedKeys) {
405 return new ContainerInListBuilder()
407 .setNestedList(getNestedList(nestedKeys))
411 private List<NestedList> getNestedList(String... keys) {
412 final ArrayList<NestedList> nestedList = new ArrayList<>();
413 for (String key : keys) {
414 nestedList.add(getSingleNestedList(key));
419 private NestedList getSingleNestedList(final String key) {
420 return new NestedListBuilder()
426 private void writeContainerWithChoice(final DataModification dataModification) {
427 writeContainerWithChoice(dataModification, getContainerWithChoiceWithComplexCase());
431 private void deleteContainerWithChoice(final DataModification dataModification) {
432 dataModification.delete(serializer.toYangInstanceIdentifier(Ids.CONTAINER_WITH_CHOICE_ID));
435 private void writeContainerWithChoice(final DataModification dataModification,
436 final ContainerWithChoice containerWithChoice) {
437 final Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNode =
438 serializer.toNormalizedNode(Ids.CONTAINER_WITH_CHOICE_ID, containerWithChoice);
439 dataModification.write(normalizedNode.getKey(), normalizedNode.getValue());
442 private ContainerWithChoice getContainerWithChoiceWithComplexCase() {
443 return new ContainerWithChoiceBuilder()
444 .setLeafFromGrouping("fromG")
446 .setContainerFromGrouping(getContainerFromGrouping())
447 .setChoice(getComplexCase())
451 private Choice getComplexCase() {
452 return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.choice.choice.C3Builder()
458 return new C3Builder()
463 private void writeContainerFromGrouping(final DataModification dataModification) {
464 final Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNode =
465 serializer.toNormalizedNode(Ids.CONTAINER_FROM_GROUPING_ID, getContainerFromGrouping());
466 dataModification.write(normalizedNode.getKey(), normalizedNode.getValue());
469 private ContainerFromGrouping getContainerFromGrouping() {
470 return new ContainerFromGroupingBuilder()
471 .setLeafInContainerFromGrouping(111)
476 private void writeSimpleContainer(final DataModification dataModification) {
477 final Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNode =
478 serializer.toNormalizedNode(Ids.SIMPLE_CONTAINER_ID, getSimpleContainer());
479 dataModification.write(normalizedNode.getKey(), normalizedNode.getValue());
482 private void deleteSimpleContainer(final DataModification dataModification) {
483 final YangInstanceIdentifier yangId =
484 serializer.toYangInstanceIdentifier(Ids.SIMPLE_CONTAINER_ID);
485 dataModification.delete(yangId);
488 private SimpleContainer getSimpleContainer() {
489 return new SimpleContainerBuilder()
490 .setSimpleContainerName("n")
491 .addAugmentation(SimpleAugment.class, getSimpleAugment())
492 .addAugmentation(ComplexAugment.class, getComplexAugment())
496 private ComplexAugment getComplexAugment() {
497 return new ComplexAugmentBuilder()
498 .setComplexAugmentContainer(getComplexAugmentContainer())
502 private ComplexAugmentContainer getComplexAugmentContainer() {
503 return new ComplexAugmentContainerBuilder().setSomeLeaf("s").build();
506 private SimpleAugment getSimpleAugment() {
507 return new SimpleAugmentBuilder().setSimpleAugmentLeaf("a").build();
511 public void testWriteAndDeleteInTx() throws Exception {
512 final ModifiableDataTreeDelegator modifiableDataTreeDelegator =
513 new ModifiableDataTreeDelegator(serializer, dataTree, schemaContext, writerRegistry, contextBroker);
515 final DataModification dataModification = modifiableDataTreeDelegator.newModification();
516 // Now write everything we can
517 writeSimpleContainer(dataModification);
518 deleteSimpleContainer(dataModification);
519 dataModification.commit();
521 verify(simpleContainerWriter).getManagedDataObjectType();
523 verifyNoMoreInteractions(simpleContainerWriter);
527 public void testSubtreeWriter() throws Exception {
528 writerRegistry = new FlatWriterRegistryBuilder(new YangDAG())
529 // Handles also container from grouping
530 .subtreeAdd(Sets.newHashSet(Ids.CONTAINER_FROM_GROUPING_ID), containerWithChoiceWriter)
533 final ModifiableDataTreeDelegator modifiableDataTreeDelegator =
534 new ModifiableDataTreeDelegator(serializer, dataTree, schemaContext, writerRegistry, contextBroker);
536 final ContainerWithChoice containerWithChoice =
537 new ContainerWithChoiceBuilder().setContainerFromGrouping(getContainerFromGrouping()).build();
539 // Test write subtree node
540 DataModification dataModification = modifiableDataTreeDelegator.newModification();
541 writeContainerFromGrouping(dataModification);
542 dataModification.commit();
544 verify(containerWithChoiceWriter, atLeastOnce()).getManagedDataObjectType();
545 verify(containerWithChoiceWriter)
546 .processModification(eq(Ids.CONTAINER_WITH_CHOICE_ID), eq(null), eq(containerWithChoice), any(WriteContext.class));
547 verifyNoMoreInteractions(containerWithChoiceWriter);
549 // Test delete sub-node
550 dataModification = modifiableDataTreeDelegator.newModification();
551 final ContainerWithChoice containerWithChoiceEmpty = new ContainerWithChoiceBuilder().build();
552 deleteContainerFromGrouping(dataModification);
553 dataModification.commit();
555 verify(containerWithChoiceWriter, atLeastOnce()).getManagedDataObjectType();
556 verify(containerWithChoiceWriter)
557 .processModification(eq(Ids.CONTAINER_WITH_CHOICE_ID), eq(containerWithChoice), eq(containerWithChoiceEmpty), any(WriteContext.class));
558 verifyNoMoreInteractions(containerWithChoiceWriter);
560 // Test write with subtree node that's not handled by subtree writer
561 dataModification = modifiableDataTreeDelegator.newModification();
562 writeContainerWithChoice(dataModification);
564 dataModification.commit();
565 fail("Missing writer for C3 should occur");
566 } catch (IllegalArgumentException e) {
571 private void deleteContainerFromGrouping(final DataModification dataModification) {
572 dataModification.delete(serializer.toYangInstanceIdentifier(Ids.CONTAINER_FROM_GROUPING_ID));