Remove SchemaContextRef
[netconf.git] / restconf / restconf-nb-rfc8040 / src / test / java / org / opendaylight / restconf / nb / rfc8040 / rests / utils / PlainPatchDataTransactionUtilTest.java
1 /*
2  * Copyright (c) 2020 Lumina Networks, Inc. and others. All rights reserved.
3  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7  * and is available at http://www.eclipse.org/legal/epl-v10.html
8  */
9 package org.opendaylight.restconf.nb.rfc8040.rests.utils;
10
11 import static org.mockito.Mockito.doNothing;
12 import static org.mockito.Mockito.doReturn;
13 import static org.mockito.Mockito.verify;
14 import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFalseFluentFuture;
15
16 import org.junit.Before;
17 import org.junit.Test;
18 import org.mockito.Mock;
19 import org.mockito.Mockito;
20 import org.mockito.MockitoAnnotations;
21 import org.opendaylight.mdsal.common.api.CommitInfo;
22 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
23 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
24 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
25 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
26 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
27 import org.opendaylight.mdsal.dom.api.DOMTransactionChain;
28 import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
29 import org.opendaylight.restconf.common.context.NormalizedNodeContext;
30 import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils;
31 import org.opendaylight.restconf.nb.rfc8040.handlers.TransactionChainHandler;
32 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.TransactionVarsWrapper;
33 import org.opendaylight.yangtools.yang.common.QName;
34 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
35 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
36 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
37 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
38 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
39 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
40 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
41 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
42 import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
43 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
44 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
45 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
46
47 public class PlainPatchDataTransactionUtilTest {
48
49     private static final String PATH_FOR_NEW_SCHEMA_CONTEXT = "/jukebox";
50
51     @Mock
52     private DOMTransactionChain transactionChain;
53     @Mock
54     private DOMDataTreeReadWriteTransaction readWrite;
55     @Mock
56     private DOMDataTreeReadTransaction read;
57     @Mock
58     private DOMDataTreeWriteTransaction write;
59     @Mock
60     private DOMDataBroker mockDataBroker;
61
62     private TransactionChainHandler transactionChainHandler;
63     private LeafNode leafGap;
64     private ContainerNode jukeboxContainerWithPlayer;
65     private ContainerNode jukeboxContainerWithPlaylist;
66     private EffectiveModelContext schema;
67     private DataSchemaNode schemaNodeForGap;
68     private YangInstanceIdentifier iidGap;
69     private DataSchemaNode schemaNodeForJukebox;
70     private YangInstanceIdentifier iidJukebox;
71
72     @Before
73     public void setUp() throws Exception {
74         MockitoAnnotations.initMocks(this);
75         this.schema = YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles(PATH_FOR_NEW_SCHEMA_CONTEXT));
76
77         final QName qnJukebox = QName.create("http://example.com/ns/example-jukebox", "2015-04-04", "jukebox");
78         final QName qnPlayer = QName.create(qnJukebox, "player");
79         final QName qnGap = QName.create(qnJukebox, "gap");
80         final QName qnPlaylist = QName.create(qnJukebox, "playlist");
81         final QName qnPlaylistKey = QName.create(qnJukebox, "name");
82
83         final NodeIdentifierWithPredicates nidBandA =
84                 NodeIdentifierWithPredicates.of(qnPlaylist, qnPlaylistKey, "MyFavoriteBand-A");
85         final NodeIdentifierWithPredicates nidBandB =
86                 NodeIdentifierWithPredicates.of(qnPlaylist, qnPlaylistKey, "MyFavoriteBand-B");
87
88         this.iidGap = YangInstanceIdentifier.builder()
89                 .node(qnJukebox)
90                 .node(qnPlayer)
91                 .node(qnGap)
92                 .build();
93         this.schemaNodeForGap = DataSchemaContextTree.from(this.schema).getChild(this.iidGap).getDataSchemaNode();
94
95         this.iidJukebox = YangInstanceIdentifier.builder()
96                 .node(qnJukebox)
97                 .build();
98         this.schemaNodeForJukebox = DataSchemaContextTree.from(this.schema)
99                 .getChild(this.iidJukebox).getDataSchemaNode();
100
101         this.leafGap = Builders.leafBuilder()
102                 .withNodeIdentifier(new NodeIdentifier(qnGap))
103                 .withValue(0.2)
104                 .build();
105         final ContainerNode playerContainer = Builders.containerBuilder()
106                 .withNodeIdentifier(new NodeIdentifier(qnPlayer))
107                 .withChild(this.leafGap)
108                 .build();
109         this.jukeboxContainerWithPlayer = Builders.containerBuilder()
110                 .withNodeIdentifier(new NodeIdentifier(qnJukebox))
111                 .withChild(playerContainer)
112                 .build();
113
114         // ----------
115
116         final LeafNode<Object> leafBandA = Builders.leafBuilder()
117                 .withNodeIdentifier(new NodeIdentifier(QName.create(qnJukebox, "name")))
118                 .withValue("MyFavoriteBand-A")
119                 .build();
120         final LeafNode<Object> leafDescriptionA = Builders.leafBuilder()
121                 .withNodeIdentifier(new NodeIdentifier(QName.create(qnJukebox, "description")))
122                 .withValue("band description A")
123                 .build();
124         final MapEntryNode entryBandA = Builders.mapEntryBuilder()
125                 .withNodeIdentifier(nidBandA)
126                 .withChild(leafBandA)
127                 .withChild(leafDescriptionA)
128                 .build();
129
130         final LeafNode<Object> leafBandB = Builders.leafBuilder()
131                 .withNodeIdentifier(new NodeIdentifier(QName.create(qnJukebox, "name")))
132                 .withValue("MyFavoriteBand-B")
133                 .build();
134         final LeafNode<Object> leafDescriptionB = Builders.leafBuilder()
135                 .withNodeIdentifier(new NodeIdentifier(QName.create(qnJukebox, "description")))
136                 .withValue("band description B")
137                 .build();
138         final MapEntryNode entryBandB = Builders.mapEntryBuilder()
139                 .withNodeIdentifier(nidBandB)
140                 .withChild(leafBandB)
141                 .withChild(leafDescriptionB)
142                 .build();
143
144         final MapNode listBands = Builders.mapBuilder()
145                 .withNodeIdentifier(new NodeIdentifier(qnPlaylist))
146                 .withChild(entryBandA)
147                 .withChild(entryBandB)
148                 .build();
149         this.jukeboxContainerWithPlaylist = Builders.containerBuilder()
150                 .withNodeIdentifier(new NodeIdentifier(qnJukebox))
151                 .withChild(listBands)
152                 .build();
153
154         Mockito.doReturn(transactionChain).when(mockDataBroker).createTransactionChain(Mockito.any());
155         transactionChainHandler = new TransactionChainHandler(mockDataBroker);
156     }
157
158     @Test
159     public void testPatchContainerData() {
160         final InstanceIdentifierContext<DataSchemaNode> iidContext =
161                 new InstanceIdentifierContext<>(this.iidJukebox, this.schemaNodeForJukebox, null, this.schema);
162         final NormalizedNodeContext payload = new NormalizedNodeContext(iidContext, this.jukeboxContainerWithPlayer);
163
164         doReturn(this.readWrite).when(this.transactionChain).newReadWriteTransaction();
165         doReturn(this.read).when(this.transactionChain).newReadOnlyTransaction();
166         doReturn(this.write).when(this.transactionChain).newWriteOnlyTransaction();
167         doReturn(immediateFalseFluentFuture())
168                 .when(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, this.iidJukebox);
169         doNothing().when(this.readWrite).put(LogicalDatastoreType.CONFIGURATION,
170                 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
171         doReturn(CommitInfo.emptyFluentFuture()).when(this.readWrite).commit();
172
173         PlainPatchDataTransactionUtil.patchData(payload,
174                 new TransactionVarsWrapper(payload.getInstanceIdentifierContext(), null, transactionChainHandler),
175                 this.schema);
176
177         verify(this.readWrite).merge(LogicalDatastoreType.CONFIGURATION,
178                 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
179     }
180
181     @Test
182     public void testPatchLeafData() {
183         final InstanceIdentifierContext<DataSchemaNode> iidContext =
184                 new InstanceIdentifierContext<>(this.iidGap, this.schemaNodeForGap, null, this.schema);
185         final NormalizedNodeContext payload = new NormalizedNodeContext(iidContext, this.leafGap);
186
187         doReturn(this.readWrite).when(this.transactionChain).newReadWriteTransaction();
188         doReturn(this.read).when(this.transactionChain).newReadOnlyTransaction();
189         doReturn(this.write).when(this.transactionChain).newWriteOnlyTransaction();
190         doReturn(immediateFalseFluentFuture())
191                 .when(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, this.iidGap);
192         doNothing().when(this.readWrite).put(LogicalDatastoreType.CONFIGURATION,
193                 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
194         doReturn(CommitInfo.emptyFluentFuture()).when(this.readWrite).commit();
195
196         PlainPatchDataTransactionUtil.patchData(payload,
197                 new TransactionVarsWrapper(payload.getInstanceIdentifierContext(), null, transactionChainHandler),
198                 this.schema);
199
200         verify(this.readWrite).merge(LogicalDatastoreType.CONFIGURATION,
201                 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
202     }
203
204     @Test
205     public void testPatchListData() {
206         final InstanceIdentifierContext<DataSchemaNode> iidContext =
207                 new InstanceIdentifierContext<>(this.iidJukebox, this.schemaNodeForJukebox, null, this.schema);
208         final NormalizedNodeContext payload = new NormalizedNodeContext(iidContext, this.jukeboxContainerWithPlaylist);
209
210         doReturn(this.readWrite).when(this.transactionChain).newReadWriteTransaction();
211         doReturn(this.read).when(this.transactionChain).newReadOnlyTransaction();
212         doReturn(this.write).when(this.transactionChain).newWriteOnlyTransaction();
213         doReturn(immediateFalseFluentFuture())
214                 .when(this.readWrite).exists(LogicalDatastoreType.CONFIGURATION, this.iidJukebox);
215         doNothing().when(this.readWrite).put(LogicalDatastoreType.CONFIGURATION,
216                 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
217         doReturn(CommitInfo.emptyFluentFuture()).when(this.readWrite).commit();
218
219         PlainPatchDataTransactionUtil.patchData(payload,
220                 new TransactionVarsWrapper(payload.getInstanceIdentifierContext(), null, transactionChainHandler),
221                 this.schema);
222
223         verify(this.readWrite).merge(LogicalDatastoreType.CONFIGURATION, this.iidJukebox, payload.getData());
224     }
225 }