9c9bdbe860481c24429956cbec118c8f837ce03a
[netconf.git] / restconf / restconf-nb-rfc8040 / src / test / java / org / opendaylight / restconf / nb / rfc8040 / rests / utils / PutDataTransactionUtilTest.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
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
15 import com.google.common.base.Optional;
16 import com.google.common.util.concurrent.Futures;
17 import org.junit.Before;
18 import org.junit.Test;
19 import org.mockito.Mock;
20 import org.mockito.MockitoAnnotations;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
23 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
24 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
25 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
26 import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
27 import org.opendaylight.restconf.common.context.NormalizedNodeContext;
28 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
29 import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils;
30 import org.opendaylight.restconf.nb.rfc8040.references.SchemaContextRef;
31 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.TransactionVarsWrapper;
32 import org.opendaylight.yangtools.yang.common.QName;
33 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
34 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
35 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
36 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
37 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
38 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
39 import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
40 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
41 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
42 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
43
44 public class PutDataTransactionUtilTest {
45
46     private static final String PATH_FOR_NEW_SCHEMA_CONTEXT = "/jukebox";
47
48     @Mock
49     private DOMTransactionChain transactionChain;
50     @Mock
51     private DOMDataReadWriteTransaction readWrite;
52     @Mock
53     private DOMDataReadOnlyTransaction read;
54     @Mock
55     private DOMDataWriteTransaction write;
56
57
58     private SchemaContextRef refSchemaCtx;
59     private LeafNode buildLeaf;
60     private ContainerNode buildBaseCont;
61     private ContainerNode buildBaseContWithList;
62     private MapEntryNode buildListEntry;
63     private SchemaContext schema;
64     private DataSchemaNode schemaNode;
65     private YangInstanceIdentifier iid;
66     private DataSchemaNode schemaNode2;
67     private YangInstanceIdentifier iid2;
68     private DataSchemaNode schemaNode3;
69     private YangInstanceIdentifier iid3;
70
71     @Before
72     public void setUp() throws Exception {
73         MockitoAnnotations.initMocks(this);
74         this.refSchemaCtx = new SchemaContextRef(
75                 YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles(PATH_FOR_NEW_SCHEMA_CONTEXT)));
76         this.schema = this.refSchemaCtx.get();
77
78         final QName baseQName = QName.create("http://example.com/ns/example-jukebox", "2015-04-04", "jukebox");
79         final QName containerQname = QName.create(baseQName, "player");
80         final QName leafQname = QName.create(baseQName, "gap");
81         final QName listQname = QName.create(baseQName, "playlist");
82         final QName listKeyQname = QName.create(baseQName, "name");
83
84         final YangInstanceIdentifier.NodeIdentifierWithPredicates nodeWithKey =
85                 new YangInstanceIdentifier.NodeIdentifierWithPredicates(listQname, listKeyQname, "name of band");
86         final YangInstanceIdentifier.NodeIdentifierWithPredicates nodeWithKey2 =
87                 new YangInstanceIdentifier.NodeIdentifierWithPredicates(listQname, listKeyQname, "name of band 2");
88
89         this.iid = YangInstanceIdentifier.builder()
90                 .node(baseQName)
91                 .node(containerQname)
92                 .node(leafQname)
93                 .build();
94         this.schemaNode = DataSchemaContextTree.from(this.schema).getChild(this.iid).getDataSchemaNode();
95
96         this.iid2 = YangInstanceIdentifier.builder()
97                 .node(baseQName)
98                 .build();
99         this.schemaNode2 = DataSchemaContextTree.from(this.schema).getChild(this.iid2).getDataSchemaNode();
100
101         this.iid3 = YangInstanceIdentifier.builder()
102                 .node(baseQName)
103                 .node(listQname)
104                 .node(nodeWithKey)
105                 .build();
106         this.schemaNode3 = DataSchemaContextTree.from(this.schema).getChild(this.iid3).getDataSchemaNode();
107
108         this.buildLeaf = Builders.leafBuilder()
109                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(leafQname))
110                 .withValue(0.2)
111                 .build();
112         final ContainerNode buildPlayerCont = Builders.containerBuilder()
113                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(containerQname))
114                 .withChild(this.buildLeaf)
115                 .build();
116         this.buildBaseCont = Builders.containerBuilder()
117                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(baseQName))
118                 .withChild(buildPlayerCont)
119                 .build();
120         final LeafNode<Object> content = Builders.leafBuilder()
121                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create(baseQName, "name")))
122                 .withValue("name of band")
123                 .build();
124         final LeafNode<Object> content2 = Builders.leafBuilder()
125                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create(baseQName, "description")))
126                 .withValue("band description")
127                 .build();
128         this.buildListEntry = Builders.mapEntryBuilder()
129                 .withNodeIdentifier(nodeWithKey)
130                 .withChild(content)
131                 .withChild(content2)
132                 .build();
133         final LeafNode<Object> content3 = Builders.leafBuilder()
134                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create(baseQName, "name")))
135                 .withValue("name of band 2")
136                 .build();
137         final LeafNode<Object> content4 = Builders.leafBuilder()
138                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create(baseQName, "description")))
139                 .withValue("band description 2")
140                 .build();
141         final MapEntryNode buildListEntry2 = Builders.mapEntryBuilder()
142                 .withNodeIdentifier(nodeWithKey2)
143                 .withChild(content3)
144                 .withChild(content4)
145                 .build();
146         final MapNode buildList = Builders.mapBuilder()
147                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(listQname))
148                 .withChild(this.buildListEntry)
149                 .withChild(buildListEntry2)
150                 .build();
151         this.buildBaseContWithList = Builders.containerBuilder()
152                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(baseQName))
153                 .withChild(buildList)
154                 .build();
155
156     }
157
158     @Test
159     public void testValidInputData() throws Exception {
160         final InstanceIdentifierContext<DataSchemaNode> iidContext =
161                 new InstanceIdentifierContext<>(this.iid, this.schemaNode, null, this.schema);
162         final NormalizedNodeContext payload = new NormalizedNodeContext(iidContext, this.buildLeaf);
163         PutDataTransactionUtil.validInputData(iidContext.getSchemaNode(), payload);
164     }
165
166     @Test
167     public void testValidTopLevelNodeName() throws Exception {
168         InstanceIdentifierContext<DataSchemaNode> iidContext =
169                 new InstanceIdentifierContext<>(this.iid, this.schemaNode, null, this.schema);
170         NormalizedNodeContext payload = new NormalizedNodeContext(iidContext, this.buildLeaf);
171         PutDataTransactionUtil.validTopLevelNodeName(iidContext.getInstanceIdentifier(), payload);
172
173         iidContext = new InstanceIdentifierContext<>(this.iid2, this.schemaNode2, null, this.schema);
174         payload = new NormalizedNodeContext(iidContext, this.buildBaseCont);
175         PutDataTransactionUtil.validTopLevelNodeName(iidContext.getInstanceIdentifier(), payload);
176     }
177
178     @Test(expected = RestconfDocumentedException.class)
179     public void testValidTopLevelNodeNamePathEmpty() throws Exception {
180         final InstanceIdentifierContext<DataSchemaNode> iidContext =
181                 new InstanceIdentifierContext<>(this.iid, this.schemaNode, null, this.schema);
182         final NormalizedNodeContext payload = new NormalizedNodeContext(iidContext, this.buildLeaf);
183         PutDataTransactionUtil.validTopLevelNodeName(YangInstanceIdentifier.EMPTY, payload);
184     }
185
186     @Test(expected = RestconfDocumentedException.class)
187     public void testValidTopLevelNodeNameWrongTopIdentifier() throws Exception {
188         final InstanceIdentifierContext<DataSchemaNode> iidContext =
189                 new InstanceIdentifierContext<>(this.iid, this.schemaNode, null, this.schema);
190         final NormalizedNodeContext payload = new NormalizedNodeContext(iidContext, this.buildLeaf);
191         PutDataTransactionUtil.validTopLevelNodeName(this.iid.getAncestor(1), payload);
192     }
193
194     @Test
195     public void testValidateListKeysEqualityInPayloadAndUri() throws Exception {
196         final InstanceIdentifierContext<DataSchemaNode> iidContext =
197                 new InstanceIdentifierContext<>(this.iid3, this.schemaNode3, null, this.schema);
198         final NormalizedNodeContext payload = new NormalizedNodeContext(iidContext, this.buildListEntry);
199         PutDataTransactionUtil.validateListKeysEqualityInPayloadAndUri(payload);
200     }
201
202     @Test
203     public void testPutContainerData() throws Exception {
204         final InstanceIdentifierContext<DataSchemaNode> iidContext =
205                 new InstanceIdentifierContext<>(this.iid2, this.schemaNode2, null, this.schema);
206         final NormalizedNodeContext payload = new NormalizedNodeContext(iidContext, this.buildBaseCont);
207
208         doReturn(this.readWrite).when(this.transactionChain).newReadWriteTransaction();
209         doReturn(this.read).when(this.transactionChain).newReadOnlyTransaction();
210         doReturn(this.write).when(this.transactionChain).newWriteOnlyTransaction();
211         doReturn(Futures.immediateCheckedFuture(Optional.absent()))
212                 .when(this.read).read(LogicalDatastoreType.CONFIGURATION, this.iid2);
213         doNothing().when(this.write).put(LogicalDatastoreType.CONFIGURATION,
214                 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
215         doReturn(Futures.immediateCheckedFuture(null)).when(this.readWrite).submit();
216
217         PutDataTransactionUtil.putData(payload, this.refSchemaCtx,
218                 new TransactionVarsWrapper(payload.getInstanceIdentifierContext(), null, this.transactionChain), null,
219                 null);
220         verify(this.read).read(LogicalDatastoreType.CONFIGURATION,
221                 payload.getInstanceIdentifierContext().getInstanceIdentifier());
222         verify(this.readWrite).put(LogicalDatastoreType.CONFIGURATION,
223                 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
224     }
225
226     @Test
227     public void testPutleafData() throws Exception {
228         final InstanceIdentifierContext<DataSchemaNode> iidContext =
229                 new InstanceIdentifierContext<>(this.iid, this.schemaNode, null, this.schema);
230         final NormalizedNodeContext payload = new NormalizedNodeContext(iidContext, this.buildLeaf);
231
232         doReturn(this.readWrite).when(this.transactionChain).newReadWriteTransaction();
233         doReturn(this.read).when(this.transactionChain).newReadOnlyTransaction();
234         doReturn(this.write).when(this.transactionChain).newWriteOnlyTransaction();
235         doReturn(Futures.immediateCheckedFuture(Optional.absent()))
236                 .when(this.read).read(LogicalDatastoreType.CONFIGURATION, this.iid);
237         doNothing().when(this.write).put(LogicalDatastoreType.CONFIGURATION,
238                 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
239         doReturn(Futures.immediateCheckedFuture(null)).when(this.readWrite).submit();
240
241         PutDataTransactionUtil.putData(payload, this.refSchemaCtx,
242                 new TransactionVarsWrapper(payload.getInstanceIdentifierContext(), null, this.transactionChain), null,
243                 null);
244         verify(this.read).read(LogicalDatastoreType.CONFIGURATION,
245                 payload.getInstanceIdentifierContext().getInstanceIdentifier());
246         verify(this.readWrite).put(LogicalDatastoreType.CONFIGURATION,
247                 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
248     }
249
250     @Test
251     public void testPutListData() throws Exception {
252         final InstanceIdentifierContext<DataSchemaNode> iidContext =
253                 new InstanceIdentifierContext<>(this.iid2, this.schemaNode2, null, this.schema);
254         final NormalizedNodeContext payload = new NormalizedNodeContext(iidContext, this.buildBaseContWithList);
255
256         doReturn(this.readWrite).when(this.transactionChain).newReadWriteTransaction();
257         doReturn(this.read).when(this.transactionChain).newReadOnlyTransaction();
258         doReturn(this.write).when(this.transactionChain).newWriteOnlyTransaction();
259         doReturn(Futures.immediateCheckedFuture(Optional.absent()))
260                 .when(this.read).read(LogicalDatastoreType.CONFIGURATION, this.iid2);
261         doNothing().when(this.write).put(LogicalDatastoreType.CONFIGURATION,
262                 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
263         doReturn(Futures.immediateCheckedFuture(null)).when(this.readWrite).submit();
264         PutDataTransactionUtil.putData(payload, this.refSchemaCtx,
265                 new TransactionVarsWrapper(payload.getInstanceIdentifierContext(), null, this.transactionChain), null,
266                 null);
267         verify(this.read).read(LogicalDatastoreType.CONFIGURATION, this.iid2);
268         verify(this.readWrite).put(LogicalDatastoreType.CONFIGURATION, this.iid2, payload.getData());
269     }
270
271 }
272