b6d73141873b2a9ccf7b57e23531ff786933b96c
[ccsdk/features.git] / sdnr / wt / netconfnode-state-service / provider / src / test / java / org / onap / ccsdk / features / sdnr / wt / netconfnodestateservice / test / TestNetconfNodeStateService.java
1 /*
2  * ============LICENSE_START=======================================================
3  * ONAP : ccsdk features
4  * ================================================================================
5  * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property.
6  * All rights reserved.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21 package org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test;
22
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertNotNull;
25 import static org.junit.Assert.assertTrue;
26 import com.google.common.util.concurrent.ListenableFuture;
27 import java.io.File;
28 import java.io.FileNotFoundException;
29 import java.io.IOException;
30 import java.nio.file.Files;
31 import java.nio.file.Path;
32 import java.nio.file.Paths;
33 import java.util.Arrays;
34 import java.util.Collection;
35 import java.util.concurrent.ExecutionException;
36 import org.eclipse.jdt.annotation.NonNull;
37 import org.junit.AfterClass;
38 import org.junit.BeforeClass;
39 import org.junit.Test;
40 import org.mockito.ArgumentCaptor;
41 import org.mockito.Mockito;
42 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.IEntityDataProvider;
43 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor;
44 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeConnectListener;
45 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeStateListener;
46 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.VesNotificationListener;
47 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.NetconfNodeStateServiceImpl;
48 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.rpc.NetconfnodeStateServiceRpcApiImpl;
49 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test.example.ExampleConfig;
50 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test.example.TestNetconfHelper;
51 import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener;
52 import org.opendaylight.mdsal.binding.api.DataBroker;
53 import org.opendaylight.mdsal.binding.api.DataObjectModification;
54 import org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType;
55 import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
56 import org.opendaylight.mdsal.binding.api.DataTreeModification;
57 import org.opendaylight.mdsal.binding.api.MountPointService;
58 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
59 import org.opendaylight.mdsal.binding.api.RpcProviderService;
60 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
61 import org.opendaylight.mdsal.binding.dom.codec.impl.BindingCodecContext;
62 import org.opendaylight.mdsal.binding.runtime.spi.BindingRuntimeHelpers;
63 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.AttributeChangeNotification;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.AttributeChangeNotificationBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.FaultNotification;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.FaultNotificationBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusInputBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusOutput;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusOutputBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushAttributeChangeNotificationInputBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushAttributeChangeNotificationOutput;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushFaultNotificationInputBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushFaultNotificationOutput;
78 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
79 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
80 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
81 import org.opendaylight.yangtools.concepts.ListenerRegistration;
82 import org.opendaylight.yangtools.yang.binding.DataObject;
83 import org.opendaylight.yangtools.yang.common.RpcResult;
84 import org.opendaylight.yangtools.yang.model.parser.api.YangParserException;
85 import org.opendaylight.yangtools.yang.model.parser.api.YangParserFactory;
86 import org.opendaylight.yangtools.yang.parser.impl.YangParserFactoryImpl;
87 import org.slf4j.Logger;
88 import org.slf4j.LoggerFactory;
89
90
91 public class TestNetconfNodeStateService extends Mockito {
92
93     private static Path KARAF_ETC = Paths.get("etc");
94     private static NetconfNodeStateServiceImpl netconfStateService;
95     //private static DataBrokerNetconfMock dataBrokerNetconf;
96     private static DataBroker dataBrokerNetconf;
97     private @NonNull static DataTreeChangeListener<Node> listener;
98     private @NonNull static ClusteredDataTreeChangeListener<Node> listenerClustered;
99
100
101     private static final Logger LOG = LoggerFactory.getLogger(TestNetconfNodeStateService.class);
102
103     @SuppressWarnings("unchecked")
104     @BeforeClass
105     public static <T extends DataObject, L extends DataTreeChangeListener<T>> void before()
106             throws InterruptedException, IOException {
107
108         System.out.println("Logger: " + LOG.getClass().getName() + " " + LOG.getName());
109         // Call System property to get the classpath value
110         Path etc = KARAF_ETC;
111         delete(etc);
112
113         System.out.println("Create empty:" + etc.toString());
114         Files.createDirectories(etc);
115
116         // Create mocks
117         //dataBrokerNetconf = new DataBrokerNetconfMock();
118         //dataBrokerNetconf.newReadWriteTransaction();
119         dataBrokerNetconf = mock(DataBroker.class);
120         when(dataBrokerNetconf.registerDataTreeChangeListener(any(), any())).thenAnswer(invocation -> {
121             Object pListener = invocation.getArguments()[1];
122             System.out.println("Register " + pListener.getClass().getName());
123             if (pListener instanceof ClusteredDataTreeChangeListener) {
124                 System.out.println("Clustered listener");
125                 listenerClustered = (ClusteredDataTreeChangeListener<Node>) pListener;
126             } else if (pListener instanceof DataTreeChangeListener) {
127                 System.out.println("Listener");
128                 listener = (DataTreeChangeListener<Node>) pListener;
129             }
130             return new ListenerRegistration<L>() {
131                 @Override
132                 public L getInstance() {
133                     return (L) pListener;
134                 }
135
136                 @Override
137                 public void close() {}
138             };
139
140         });
141         ClusterSingletonServiceProvider clusterSingletonService = mock(ClusterSingletonServiceProvider.class);
142         MountPointService mountPointService = mock(MountPointService.class);
143         NotificationPublishService notificationPublishService = mock(NotificationPublishService.class);
144         RpcProviderService rpcProviderRegistry = mock(RpcProviderService.class);
145         IEntityDataProvider entityProviderMock = mock(IEntityDataProvider.class);
146         YangParserFactory yangParserFactory = new YangParserFactoryImpl();
147         BindingNormalizedNodeSerializer bindingNormalizedNodeSerializer =
148                 new BindingCodecContext(BindingRuntimeHelpers.createRuntimeContext());
149         // start using blueprint interface
150         netconfStateService = new NetconfNodeStateServiceImpl();
151
152         netconfStateService.setDataBroker(dataBrokerNetconf);
153         netconfStateService.setMountPointService(mountPointService);
154         netconfStateService.setNotificationPublishService(notificationPublishService);
155         netconfStateService.setRpcProviderRegistry(rpcProviderRegistry);
156         netconfStateService.setClusterSingletonService(clusterSingletonService);
157         netconfStateService.setEntityDataProvider(entityProviderMock);
158         netconfStateService.setYangParserFactory(yangParserFactory);
159         netconfStateService.setBindingNormalizedNodeSerializer(bindingNormalizedNodeSerializer);
160         netconfStateService.init();
161         System.out.println("Initialization done");
162     }
163
164     @AfterClass
165     public static void after() throws InterruptedException, IOException {
166         System.out.println("Start shutdown");
167         // close using blueprint interface
168         netconfStateService.close();
169         delete(KARAF_ETC);
170
171     }
172
173     @Test
174     public void test1() {
175
176         System.out.println("Test1: Verify init state");
177         assertTrue("Devicemanager not initialized", netconfStateService.isInitializationSuccessful());
178     }
179
180
181     @Test
182     public void test2() {
183
184         System.out.println("Test2: Register state listener");
185
186         NetconfNodeStateListener nSL = mock(NetconfNodeStateListener.class);
187         ListenerRegistration<NetconfNodeStateListener> res = netconfStateService.registerNetconfNodeStateListener(nSL);
188         assertNotNull("Result should be null", res);
189         res.getInstance();
190         res.close();
191     }
192
193     @Test
194     public void test3() {
195
196         System.out.println("Test3: Register connect listener");
197
198         NetconfNodeConnectListener nCL = mock(NetconfNodeConnectListener.class);
199         ListenerRegistration<NetconfNodeConnectListener> res =
200                 netconfStateService.registerNetconfNodeConnectListener(nCL);
201         assertNotNull("Result should be null", res);
202         res.getInstance();
203         res.close();
204     }
205
206     @Test
207     public void test4() {
208         System.out.println("Test4: Get status listener");
209         GetStatusInputBuilder inputBuilder = new GetStatusInputBuilder();
210         GetStatusOutputBuilder res = netconfStateService.getStatus(inputBuilder.build());
211         assertNotNull("Result should be null", res);
212     }
213
214     @SuppressWarnings("unchecked")
215     @Test
216     public void test5OnConnect() throws InterruptedException {
217         System.out.println("Test5: On Connect");
218         String nodeIdString = "Test";
219         String capabilityStringForNetworkElement = "network-element";
220         NodeId nodeId = new NodeId(nodeIdString);
221         Node rootNode = TestNetconfHelper.getTestNode(nodeId, capabilityStringForNetworkElement);
222
223         DataObjectModification<Node> dom = mock(DataObjectModification.class);
224         when(dom.getDataAfter()).thenReturn(rootNode);
225         when(dom.getModificationType()).thenReturn(ModificationType.WRITE);
226
227         DataTreeModification<Node> ntn = mock(DataTreeModification.class);
228         when(ntn.getRootNode()).thenReturn(dom);
229
230         NetconfNodeConnectListener nCL = mock(NetconfNodeConnectListener.class);
231         netconfStateService.registerNetconfNodeConnectListener(nCL);
232
233         Collection<DataTreeModification<Node>> changes = Arrays.asList(ntn);
234         sendClusteredChanges(changes);
235         sendChanges(changes);
236         Thread.sleep(300);
237         //verify that it was called one time and nodeId is the expected
238         ArgumentCaptor<NetconfAccessor> varArgs = ArgumentCaptor.forClass(NetconfAccessor.class);
239         verify(nCL).onEnterConnected(varArgs.capture());
240         NetconfAccessor accessor = varArgs.getValue();
241         System.out.println("Accessor " + accessor.getNodeId());
242         assertEquals(nodeIdString, accessor.getNodeId().getValue());
243     }
244
245     @SuppressWarnings("unchecked")
246     @Test
247     public void test6Update() {
248         System.out.println("Test6: OnChange");
249         NetconfNodeBuilder netconfNodeBuilder = new NetconfNodeBuilder();
250         netconfNodeBuilder.setConnectionStatus(ConnectionStatus.Connected);
251         NetconfNode rootNodeNetconf = netconfNodeBuilder.build();
252
253         NodeBuilder nodeBuilder = new NodeBuilder();
254         nodeBuilder.addAugmentation(rootNodeNetconf);
255         nodeBuilder.setNodeId(new NodeId("Test"));
256         Node rootNodeAfter = nodeBuilder.build();
257
258         DataObjectModification<Node> dom = mock(DataObjectModification.class);
259         when(dom.getDataBefore()).thenReturn(rootNodeAfter);
260         when(dom.getDataAfter()).thenReturn(rootNodeAfter);
261         when(dom.getModificationType()).thenReturn(ModificationType.WRITE);
262
263         DataTreeModification<Node> ntn = mock(DataTreeModification.class);
264         when(ntn.getRootNode()).thenReturn(dom);
265
266         Collection<DataTreeModification<Node>> changes = Arrays.asList(ntn);
267         sendClusteredChanges(changes);
268         sendChanges(changes);
269     }
270
271     @Test
272     public void test7ApiStatus() throws InterruptedException, ExecutionException {
273
274         NetconfnodeStateServiceRpcApiImpl api = netconfStateService.getNetconfnodeStateServiceRpcApiImpl();
275
276         GetStatusInputBuilder statusInput = new GetStatusInputBuilder();
277         ListenableFuture<RpcResult<GetStatusOutput>> statusOutput = api.getStatus(statusInput.build());
278         RpcResult<GetStatusOutput> res = statusOutput.get();
279         GetStatusOutput output = res.getResult();
280         System.out.println("Output " + output);
281     }
282
283
284     @Test
285     public void test8ApiPushFault() throws InterruptedException, ExecutionException {
286
287         NetconfnodeStateServiceRpcApiImpl api = netconfStateService.getNetconfnodeStateServiceRpcApiImpl();
288
289         VesNotificationListener vNL = mock(VesNotificationListener.class);
290         ListenerRegistration<VesNotificationListener> registration = netconfStateService.registerVesNotifications(vNL);
291
292         FaultNotificationBuilder faultBuilder = new FaultNotificationBuilder();
293         faultBuilder.setProblem("problem1");
294         FaultNotification fault = faultBuilder.build();
295         PushFaultNotificationInputBuilder statusInput = new PushFaultNotificationInputBuilder();
296         statusInput.fieldsFrom(fault);
297         ListenableFuture<RpcResult<PushFaultNotificationOutput>> rpcOutput =
298                 api.pushFaultNotification(statusInput.build());
299         RpcResult<PushFaultNotificationOutput> res = rpcOutput.get();
300         PushFaultNotificationOutput output = res.getResult();
301
302         //verify that it was called one time
303         verify(vNL, times(1)).onNotification(fault);
304
305         registration.close();
306         System.out.println("Output " + output);
307     }
308
309     @Test
310     public void test9ApiPushNotifiction() throws InterruptedException, ExecutionException {
311
312         NetconfnodeStateServiceRpcApiImpl api = netconfStateService.getNetconfnodeStateServiceRpcApiImpl();
313
314         VesNotificationListener vNL = mock(VesNotificationListener.class);
315         ListenerRegistration<VesNotificationListener> registration = netconfStateService.registerVesNotifications(vNL);
316
317         AttributeChangeNotificationBuilder changeBuilder = new AttributeChangeNotificationBuilder();
318         changeBuilder.setAttributeName("attribute1");
319         AttributeChangeNotification change = changeBuilder.build();
320         PushAttributeChangeNotificationInputBuilder statusInput = new PushAttributeChangeNotificationInputBuilder();
321         statusInput.fieldsFrom(change);
322         ListenableFuture<RpcResult<PushAttributeChangeNotificationOutput>> rpcOutput =
323                 api.pushAttributeChangeNotification(statusInput.build());
324         RpcResult<PushAttributeChangeNotificationOutput> res = rpcOutput.get();
325         PushAttributeChangeNotificationOutput output = res.getResult();
326
327         //verify that it was called one time
328         verify(vNL, times(1)).onNotification(change);
329
330         registration.close();
331         System.out.println("Output " + output);
332     }
333
334     @Test
335     public void test10ApiPushNotifiction() throws YangParserException, IOException {
336         ExampleConfig.exampleConfig(netconfStateService.getDomContext());
337     }
338
339     @Test
340     public void test10NetconfAccessorClone() {
341
342     }
343
344     // ------- private section
345
346     private static void delete(Path etc) throws IOException {
347         if (Files.exists(etc)) {
348             System.out.println("Found and remove:" + etc.toString());
349             delete(etc.toFile());
350         }
351     }
352
353     private static void delete(File f) throws IOException {
354         if (f.isDirectory()) {
355             for (File c : f.listFiles()) {
356                 delete(c);
357             }
358         }
359         if (!f.delete()) {
360             throw new FileNotFoundException("Failed to delete file: " + f);
361         }
362     }
363
364     public void sendChanges(Collection<DataTreeModification<Node>> changes) {
365         listener.onDataTreeChanged(changes);
366     }
367
368     public void sendClusteredChanges(Collection<DataTreeModification<Node>> changes) {
369         listenerClustered.onDataTreeChanged(changes);
370     }
371
372
373 }