2 * Copyright (c) 2020 Lumina Networks, Inc. and others. All rights reserved.
3 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.restconf.nb.rfc8040.rests.utils;
11 import static org.mockito.ArgumentMatchers.any;
12 import static org.mockito.Mockito.doReturn;
13 import static org.mockito.Mockito.verify;
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.model.api.EffectiveModelContext;
45 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
47 @RunWith(MockitoJUnitRunner.StrictStubs.class)
48 public class PlainPatchDataTransactionUtilTest {
49 private static final String PATH_FOR_NEW_SCHEMA_CONTEXT = "/jukebox";
51 private DOMDataTreeReadWriteTransaction readWrite;
53 private DOMDataTreeReadTransaction read;
55 private DOMDataTreeWriteTransaction write;
57 private DOMDataBroker mockDataBroker;
59 private NetconfDataTreeService netconfService;
61 private LeafNode<?> leafGap;
62 private ContainerNode jukeboxContainerWithPlayer;
63 private ContainerNode jukeboxContainerWithPlaylist;
64 private EffectiveModelContext schema;
65 private YangInstanceIdentifier iidGap;
66 private YangInstanceIdentifier iidJukebox;
69 public void setUp() throws Exception {
70 schema = YangParserTestUtils.parseYangFiles(TestRestconfUtils.loadFiles(PATH_FOR_NEW_SCHEMA_CONTEXT));
72 final QName qnJukebox = QName.create("http://example.com/ns/example-jukebox", "2015-04-04", "jukebox");
73 final QName qnPlayer = QName.create(qnJukebox, "player");
74 final QName qnGap = QName.create(qnJukebox, "gap");
75 final QName qnPlaylist = QName.create(qnJukebox, "playlist");
76 final QName qnPlaylistKey = QName.create(qnJukebox, "name");
78 final NodeIdentifierWithPredicates nidBandA =
79 NodeIdentifierWithPredicates.of(qnPlaylist, qnPlaylistKey, "MyFavoriteBand-A");
80 final NodeIdentifierWithPredicates nidBandB =
81 NodeIdentifierWithPredicates.of(qnPlaylist, qnPlaylistKey, "MyFavoriteBand-B");
83 iidGap = YangInstanceIdentifier.builder()
89 iidJukebox = YangInstanceIdentifier.builder()
93 leafGap = Builders.leafBuilder()
94 .withNodeIdentifier(new NodeIdentifier(qnGap))
97 final ContainerNode playerContainer = Builders.containerBuilder()
98 .withNodeIdentifier(new NodeIdentifier(qnPlayer))
101 jukeboxContainerWithPlayer = Builders.containerBuilder()
102 .withNodeIdentifier(new NodeIdentifier(qnJukebox))
103 .withChild(playerContainer)
108 final LeafNode<Object> leafBandA = Builders.leafBuilder()
109 .withNodeIdentifier(new NodeIdentifier(QName.create(qnJukebox, "name")))
110 .withValue("MyFavoriteBand-A")
112 final LeafNode<Object> leafDescriptionA = Builders.leafBuilder()
113 .withNodeIdentifier(new NodeIdentifier(QName.create(qnJukebox, "description")))
114 .withValue("band description A")
116 final MapEntryNode entryBandA = Builders.mapEntryBuilder()
117 .withNodeIdentifier(nidBandA)
118 .withChild(leafBandA)
119 .withChild(leafDescriptionA)
122 final LeafNode<Object> leafBandB = Builders.leafBuilder()
123 .withNodeIdentifier(new NodeIdentifier(QName.create(qnJukebox, "name")))
124 .withValue("MyFavoriteBand-B")
126 final LeafNode<Object> leafDescriptionB = Builders.leafBuilder()
127 .withNodeIdentifier(new NodeIdentifier(QName.create(qnJukebox, "description")))
128 .withValue("band description B")
130 final MapEntryNode entryBandB = Builders.mapEntryBuilder()
131 .withNodeIdentifier(nidBandB)
132 .withChild(leafBandB)
133 .withChild(leafDescriptionB)
136 final MapNode listBands = Builders.mapBuilder()
137 .withNodeIdentifier(new NodeIdentifier(qnPlaylist))
138 .withChild(entryBandA)
139 .withChild(entryBandB)
141 jukeboxContainerWithPlaylist = Builders.containerBuilder()
142 .withNodeIdentifier(new NodeIdentifier(qnJukebox))
143 .withChild(listBands)
146 doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).lock();
147 doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).unlock();
151 public void testPatchContainerData() {
152 final InstanceIdentifierContext iidContext =
153 InstanceIdentifierContext.ofLocalPath(schema, iidJukebox);
154 final NormalizedNodePayload payload = NormalizedNodePayload.of(iidContext, jukeboxContainerWithPlayer);
156 doReturn(readWrite).when(mockDataBroker).newReadWriteTransaction();
157 doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
158 doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
159 doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).merge(any(), any(),any(),
162 PlainPatchDataTransactionUtil.patchData(payload, new MdsalRestconfStrategy(mockDataBroker), schema);
163 verify(readWrite).merge(LogicalDatastoreType.CONFIGURATION,
164 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
166 PlainPatchDataTransactionUtil.patchData(payload, new NetconfRestconfStrategy(netconfService),
168 verify(netconfService).merge(LogicalDatastoreType.CONFIGURATION,
169 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData(), Optional.empty());
173 public void testPatchLeafData() {
174 final InstanceIdentifierContext iidContext = InstanceIdentifierContext.ofLocalPath(schema, iidGap);
175 final NormalizedNodePayload payload = NormalizedNodePayload.of(iidContext, leafGap);
177 doReturn(readWrite).when(mockDataBroker).newReadWriteTransaction();
178 doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
179 doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
180 .merge(any(), any(), any(), any());
181 doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
183 PlainPatchDataTransactionUtil.patchData(payload, new MdsalRestconfStrategy(mockDataBroker), schema);
184 verify(readWrite).merge(LogicalDatastoreType.CONFIGURATION,
185 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData());
187 PlainPatchDataTransactionUtil.patchData(payload, new NetconfRestconfStrategy(netconfService),
189 verify(netconfService).lock();
190 verify(netconfService).merge(LogicalDatastoreType.CONFIGURATION,
191 payload.getInstanceIdentifierContext().getInstanceIdentifier(), payload.getData(), Optional.empty());
195 public void testPatchListData() {
196 final InstanceIdentifierContext iidContext = InstanceIdentifierContext.ofLocalPath(schema, iidJukebox);
197 final NormalizedNodePayload payload = NormalizedNodePayload.of(iidContext, jukeboxContainerWithPlaylist);
199 doReturn(readWrite).when(mockDataBroker).newReadWriteTransaction();
200 doReturn(CommitInfo.emptyFluentFuture()).when(readWrite).commit();
201 doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService).commit();
202 doReturn(Futures.immediateFuture(new DefaultDOMRpcResult())).when(netconfService)
203 .merge(any(), any(),any(),any());
205 PlainPatchDataTransactionUtil.patchData(payload, new MdsalRestconfStrategy(mockDataBroker), schema);
206 verify(readWrite).merge(LogicalDatastoreType.CONFIGURATION, iidJukebox, payload.getData());
208 PlainPatchDataTransactionUtil.patchData(payload, new NetconfRestconfStrategy(netconfService),
210 verify(netconfService).merge(LogicalDatastoreType.CONFIGURATION, iidJukebox, payload.getData(),