Split out RFC8040-only constructs from yang-common
[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.ArgumentMatchers.any;
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 java.util.Optional;
17 import org.junit.Before;
18 import org.junit.Test;
19 import org.junit.runner.RunWith;
20 import org.mockito.Mock;
21 import org.mockito.junit.MockitoJUnitRunner;
22 import org.opendaylight.mdsal.common.api.CommitInfo;
23 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
24 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
25 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
26 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
27 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
28 import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
29 import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
30 import org.opendaylight.restconf.common.context.InstanceIdentifierContext;
31 import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils;
32 import org.opendaylight.restconf.nb.rfc8040.legacy.NormalizedNodePayload;
33 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.MdsalRestconfStrategy;
34 import org.opendaylight.restconf.nb.rfc8040.rests.transactions.NetconfRestconfStrategy;
35 import org.opendaylight.yangtools.yang.common.QName;
36 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
37 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
38 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
39 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
40 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
41 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
42 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
43 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
44 import org.opendaylight.yangtools.yang.data.util.DataSchemaContextTree;
45 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
46 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
47 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
48
49 @RunWith(MockitoJUnitRunner.StrictStubs.class)
50 public class PlainPatchDataTransactionUtilTest {
51     private static final String PATH_FOR_NEW_SCHEMA_CONTEXT = "/jukebox";
52     @Mock
53     private DOMDataTreeReadWriteTransaction readWrite;
54     @Mock
55     private DOMDataTreeReadTransaction read;
56     @Mock
57     private DOMDataTreeWriteTransaction write;
58     @Mock
59     private DOMDataBroker mockDataBroker;
60     @Mock
61     private NetconfDataTreeService netconfService;
62
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         schema = YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles(PATH_FOR_NEW_SCHEMA_CONTEXT));
75
76         final QName qnJukebox = QName.create("http://example.com/ns/example-jukebox", "2015-04-04", "jukebox");
77         final QName qnPlayer = QName.create(qnJukebox, "player");
78         final QName qnGap = QName.create(qnJukebox, "gap");
79         final QName qnPlaylist = QName.create(qnJukebox, "playlist");
80         final QName qnPlaylistKey = QName.create(qnJukebox, "name");
81
82         final NodeIdentifierWithPredicates nidBandA =
83                 NodeIdentifierWithPredicates.of(qnPlaylist, qnPlaylistKey, "MyFavoriteBand-A");
84         final NodeIdentifierWithPredicates nidBandB =
85                 NodeIdentifierWithPredicates.of(qnPlaylist, qnPlaylistKey, "MyFavoriteBand-B");
86
87         iidGap = YangInstanceIdentifier.builder()
88                 .node(qnJukebox)
89                 .node(qnPlayer)
90                 .node(qnGap)
91                 .build();
92         schemaNodeForGap = DataSchemaContextTree.from(schema).findChild(iidGap).orElseThrow()
93                 .getDataSchemaNode();
94
95         iidJukebox = YangInstanceIdentifier.builder()
96                 .node(qnJukebox)
97                 .build();
98         schemaNodeForJukebox = DataSchemaContextTree.from(schema)
99                 .findChild(iidJukebox).orElseThrow().getDataSchemaNode();
100
101         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(leafGap)
108                 .build();
109         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         jukeboxContainerWithPlaylist = Builders.containerBuilder()
150                 .withNodeIdentifier(new NodeIdentifier(qnJukebox))
151                 .withChild(listBands)
152                 .build();
153
154         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).lock();
155         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).unlock();
156     }
157
158     @Test
159     public void testPatchContainerData() {
160         final InstanceIdentifierContext<DataSchemaNode> iidContext =
161                 new InstanceIdentifierContext<>(iidJukebox, schemaNodeForJukebox, null, schema);
162         final NormalizedNodePayload payload = NormalizedNodePayload.of(iidContext, jukeboxContainerWithPlayer);
163
164         doReturn(readWrite).when(mockDataBroker).newReadWriteTransaction();
165         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
166         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
167         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).merge(any(), any(),any(),
168                 any());
169
170         PlainPatchDataTransactionUtil.patchData(payload, new MdsalRestconfStrategy(mockDataBroker), schema);
171         verify(readWrite).merge(LogicalDatastoreType.CONFIGURATION,
172                 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
173
174         PlainPatchDataTransactionUtil.patchData(payload, new NetconfRestconfStrategy(netconfService),
175                 schema);
176         verify(netconfService).merge(LogicalDatastoreType.CONFIGURATION,
177                 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData(), Optional.empty());
178     }
179
180     @Test
181     public void testPatchLeafData() {
182         final InstanceIdentifierContext<DataSchemaNode> iidContext =
183                 new InstanceIdentifierContext<>(iidGap, schemaNodeForGap, null, schema);
184         final NormalizedNodePayload payload = NormalizedNodePayload.of(iidContext, leafGap);
185
186         doReturn(readWrite).when(mockDataBroker).newReadWriteTransaction();
187         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
188         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
189             .merge(any(), any(), any(), any());
190         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
191
192         PlainPatchDataTransactionUtil.patchData(payload, new MdsalRestconfStrategy(mockDataBroker), schema);
193         verify(readWrite).merge(LogicalDatastoreType.CONFIGURATION,
194                 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
195
196         PlainPatchDataTransactionUtil.patchData(payload, new NetconfRestconfStrategy(netconfService),
197                 schema);
198         verify(netconfService).lock();
199         verify(netconfService).merge(LogicalDatastoreType.CONFIGURATION,
200                 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData(), Optional.empty());
201     }
202
203     @Test
204     public void testPatchListData() {
205         final InstanceIdentifierContext<DataSchemaNode> iidContext =
206                 new InstanceIdentifierContext<>(iidJukebox, schemaNodeForJukebox, null, schema);
207         final NormalizedNodePayload payload = NormalizedNodePayload.of(iidContext, jukeboxContainerWithPlaylist);
208
209         doReturn(readWrite).when(mockDataBroker).newReadWriteTransaction();
210         doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
211         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
212         doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
213             .merge(any(), any(),any(),any());
214
215         PlainPatchDataTransactionUtil.patchData(payload, new MdsalRestconfStrategy(mockDataBroker), schema);
216         verify(readWrite).merge(LogicalDatastoreType.CONFIGURATION, iidJukebox, payload.getData());
217
218         PlainPatchDataTransactionUtil.patchData(payload, new NetconfRestconfStrategy(netconfService),
219                 schema);
220         verify(netconfService).merge(LogicalDatastoreType.CONFIGURATION, iidJukebox, payload.getData(),
221                 Optional.empty());
222     }
223 }