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