7856afe1d8040e8d60c89ea548791a79e6c6ff6d
[oam/oam-controller.git] /
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 com.google.common.util.concurrent.ListenableFuture;
24 import java.io.File;
25 import java.io.FileNotFoundException;
26 import java.io.IOException;
27 import java.nio.file.Files;
28 import java.nio.file.Path;
29 import java.nio.file.Paths;
30 import java.util.AbstractMap;
31 import java.util.AbstractMap.SimpleEntry;
32 import java.util.Arrays;
33 import java.util.Collection;
34 import java.util.List;
35 import java.util.concurrent.ExecutionException;
36 import org.eclipse.jdt.annotation.NonNull;
37 import org.junit.AfterClass;
38
39 import static org.junit.Assert.assertEquals;
40 import static org.junit.Assert.assertNotNull;
41 import static org.junit.Assert.assertTrue;
42
43 import org.junit.BeforeClass;
44 import org.junit.Ignore;
45 import org.junit.Test;
46 import org.junit.jupiter.api.Disabled;
47 import org.mockito.ArgumentCaptor;
48 import org.mockito.Mockito;
49 import org.onap.ccsdk.features.sdnr.wt.dataprovider.model.IEntityDataProvider;
50 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfAccessor;
51 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeConnectListener;
52 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.NetconfNodeStateListener;
53 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.VesNotificationListener;
54 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.NetconfNodeStateServiceImpl;
55 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.rpc.NetconfnodeStateServiceRpcApiImpl;
56 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test.example.ExampleConfig;
57 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test.example.TestNetconfHelper;
58 import org.opendaylight.mdsal.binding.api.DataBroker;
59 import org.opendaylight.mdsal.binding.api.DataObjectModification;
60 import org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType;
61 import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
62 import org.opendaylight.mdsal.binding.api.DataTreeModification;
63 import org.opendaylight.mdsal.binding.api.MountPointService;
64 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
65 import org.opendaylight.mdsal.binding.api.RpcProviderService;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev241009.ConnectionOper.ConnectionStatus;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev240911.NetconfNodeAugment;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev240911.netconf.node.augment.NetconfNode;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev240911.netconf.node.augment.NetconfNodeBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.AttributeChangeNotification;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.AttributeChangeNotificationBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.FaultNotification;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.FaultNotificationBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusInputBuilder;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusOutput;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusOutputBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushAttributeChangeNotificationInputBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushAttributeChangeNotificationOutput;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushFaultNotificationInputBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushFaultNotificationOutput;
81 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
82 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
83 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
84 import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer;
85 import org.opendaylight.yangtools.binding.data.codec.impl.BindingCodecContext;
86 import org.opendaylight.yangtools.binding.impl.DataObjectReferenceBuilder;
87 import org.opendaylight.yangtools.binding.runtime.spi.BindingRuntimeHelpers;
88 import org.opendaylight.yangtools.concepts.Registration;
89 import org.opendaylight.yangtools.binding.DataObject;
90 import org.opendaylight.yangtools.yang.common.RpcResult;
91 import org.opendaylight.yangtools.yang.parser.api.YangParserException;
92 import org.opendaylight.yangtools.yang.parser.api.YangParserFactory;
93 import org.opendaylight.yangtools.yang.parser.impl.DefaultYangParserFactory;
94 import org.slf4j.Logger;
95 import org.slf4j.LoggerFactory;
96
97
98 public class TestNetconfNodeStateService extends Mockito {
99
100     private static Path KARAF_ETC = Paths.get("etc");
101     private static NetconfNodeStateServiceImpl netconfStateService;
102     //private static DataBrokerNetconfMock dataBrokerNetconf;
103     private static DataBroker dataBrokerNetconf;
104     private @NonNull
105     static DataTreeChangeListener<Node> listener;
106
107
108     private static final Logger LOG = LoggerFactory.getLogger(TestNetconfNodeStateService.class);
109
110     @SuppressWarnings("unchecked")
111     @BeforeClass
112     public static <T extends DataObject, L extends DataTreeChangeListener<T>> void before()
113             throws InterruptedException, IOException {
114
115         System.out.println("Logger: " + LOG.getClass().getName() + " " + LOG.getName());
116         // Call System property to get the classpath value
117         Path etc = KARAF_ETC;
118         delete(etc);
119
120         System.out.println("Create empty:" + etc.toString());
121         Files.createDirectories(etc);
122
123         // Create mocks
124         //dataBrokerNetconf = new DataBrokerNetconfMock();
125         //dataBrokerNetconf.newReadWriteTransaction();
126         dataBrokerNetconf = mock(DataBroker.class);
127         when(dataBrokerNetconf.registerTreeChangeListener(any(), any())).thenAnswer(invocation -> {
128             Object pListener = invocation.getArguments()[1];
129             System.out.println("Register " + pListener.getClass().getName());
130             if (pListener instanceof DataTreeChangeListener) {
131                 System.out.println("Listener");
132                 listener = (DataTreeChangeListener<Node>) pListener;
133             }
134             return new Registration() {
135
136                 @Override
137                 public void close() {
138                 }
139             };
140
141         });
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
147         YangParserFactory yangParserFactory = new DefaultYangParserFactory();
148         BindingNormalizedNodeSerializer bindingNormalizedNodeSerializer =mock(BindingNormalizedNodeSerializer.class);
149         when(bindingNormalizedNodeSerializer.fromNormalizedNode(any(),any())).thenReturn(new SimpleEntry<>(null,null));
150         // start using blueprint interface
151         netconfStateService = new NetconfNodeStateServiceImpl();
152
153         netconfStateService.setDataBroker(dataBrokerNetconf);
154         netconfStateService.setMountPointService(mountPointService);
155         netconfStateService.setNotificationPublishService(notificationPublishService);
156         netconfStateService.setRpcProviderRegistry(rpcProviderRegistry);
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         if (netconfStateService != null) {
169             netconfStateService.close();
170         }
171         delete(KARAF_ETC);
172
173     }
174
175     @Test
176     public void test1() {
177
178         System.out.println("Test1: Verify init state");
179         assertTrue("Devicemanager not initialized", netconfStateService.isInitializationSuccessful());
180     }
181
182
183     @Test
184     public void test2() {
185
186         System.out.println("Test2: Register state listener");
187
188         NetconfNodeStateListener nSL = mock(NetconfNodeStateListener.class);
189         Registration res = netconfStateService.registerNetconfNodeStateListener(nSL);
190         assertNotNull("Result should be null", res);
191
192         res.close();
193     }
194
195     @Test
196     public void test3() {
197
198         System.out.println("Test3: Register connect listener");
199
200         NetconfNodeConnectListener nCL = mock(NetconfNodeConnectListener.class);
201         Registration res =                netconfStateService.registerNetconfNodeConnectListener(nCL);
202         assertNotNull("Result should be null", res);
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     //TODO enable again
215     @SuppressWarnings("unchecked")
216     @Ignore
217     @Test
218     public void test5OnConnect() throws InterruptedException {
219         System.out.println("Test5: On Connect");
220         String nodeIdString = "Test";
221         String capabilityStringForNetworkElement = "network-element";
222         NodeId nodeId = new NodeId(nodeIdString);
223         Node rootNode = TestNetconfHelper.getTestNode(nodeId, capabilityStringForNetworkElement);
224
225         DataObjectModification<Node> dom = mock(DataObjectModification.class);
226         when(dom.dataAfter()).thenReturn(rootNode);
227         when(dom.modificationType()).thenReturn(ModificationType.WRITE);
228
229         DataTreeModification<Node> ntn = mock(DataTreeModification.class);
230         when(ntn.getRootNode()).thenReturn(dom);
231
232         NetconfNodeConnectListener nCL = mock(NetconfNodeConnectListener.class);
233         netconfStateService.registerNetconfNodeConnectListener(nCL);
234
235         List<DataTreeModification<Node>> changes = Arrays.asList(ntn);
236         sendClusteredChanges(changes);
237         sendChanges(changes);
238         Thread.sleep(300);
239         //verify that it was called one time and nodeId is the expected
240         ArgumentCaptor<NetconfAccessor> varArgs = ArgumentCaptor.forClass(NetconfAccessor.class);
241         verify(nCL).onEnterConnected(varArgs.capture());
242         NetconfAccessor accessor = varArgs.getValue();
243         System.out.println("Accessor " + accessor.getNodeId());
244         assertEquals(nodeIdString, accessor.getNodeId().getValue());
245     }
246
247     @SuppressWarnings("unchecked")
248     @Test
249     public void test6Update() {
250         System.out.println("Test6: OnChange");
251         NetconfNodeBuilder netconfNodeBuilder = new NetconfNodeBuilder();
252         netconfNodeBuilder.setConnectionStatus(ConnectionStatus.Connected);
253         NetconfNode rootNodeNetconf = netconfNodeBuilder.build();
254
255         NodeBuilder nodeBuilder = new NodeBuilder();
256         nodeBuilder.addAugmentation((NetconfNodeAugment) () -> rootNodeNetconf);
257         nodeBuilder.setNodeId(new NodeId("Test"));
258         Node rootNodeAfter = nodeBuilder.build();
259
260         DataObjectModification<Node> dom = mock(DataObjectModification.class);
261         when(dom.getDataBefore()).thenReturn(rootNodeAfter);
262         when(dom.getDataAfter()).thenReturn(rootNodeAfter);
263         when(dom.getModificationType()).thenReturn(ModificationType.WRITE);
264
265         DataTreeModification<Node> ntn = mock(DataTreeModification.class);
266         when(ntn.getRootNode()).thenReturn(dom);
267
268         List<DataTreeModification<Node>> changes = Arrays.asList(ntn);
269         sendClusteredChanges(changes);
270         sendChanges(changes);
271     }
272
273     @Test
274     public void test7ApiStatus() throws InterruptedException, ExecutionException {
275
276         NetconfnodeStateServiceRpcApiImpl api = netconfStateService.getNetconfnodeStateServiceRpcApiImpl();
277
278         GetStatusInputBuilder statusInput = new GetStatusInputBuilder();
279         ListenableFuture<RpcResult<GetStatusOutput>> statusOutput = api.getStatus(statusInput.build());
280         RpcResult<GetStatusOutput> res = statusOutput.get();
281         GetStatusOutput output = res.getResult();
282         System.out.println("Output " + output);
283     }
284
285
286     @Test
287     public void test8ApiPushFault() throws InterruptedException, ExecutionException {
288
289         NetconfnodeStateServiceRpcApiImpl api = netconfStateService.getNetconfnodeStateServiceRpcApiImpl();
290
291         VesNotificationListener vNL = mock(VesNotificationListener.class);
292         var registration = netconfStateService.registerVesNotifications(vNL);
293
294         FaultNotificationBuilder faultBuilder = new FaultNotificationBuilder();
295         faultBuilder.setProblem("problem1");
296         FaultNotification fault = faultBuilder.build();
297         PushFaultNotificationInputBuilder statusInput = new PushFaultNotificationInputBuilder();
298         statusInput.fieldsFrom(fault);
299         ListenableFuture<RpcResult<PushFaultNotificationOutput>> rpcOutput =
300                 api.pushFaultNotification(statusInput.build());
301         RpcResult<PushFaultNotificationOutput> res = rpcOutput.get();
302         PushFaultNotificationOutput output = res.getResult();
303
304         //verify that it was called one time
305         verify(vNL, times(1)).onNotification(fault);
306
307         registration.close();
308         System.out.println("Output " + output);
309     }
310
311     @Test
312     public void test9ApiPushNotifiction() throws InterruptedException, ExecutionException {
313
314         NetconfnodeStateServiceRpcApiImpl api = netconfStateService.getNetconfnodeStateServiceRpcApiImpl();
315
316         VesNotificationListener vNL = mock(VesNotificationListener.class);
317         var registration = netconfStateService.registerVesNotifications(vNL);
318
319         AttributeChangeNotificationBuilder changeBuilder = new AttributeChangeNotificationBuilder();
320         changeBuilder.setAttributeName("attribute1");
321         AttributeChangeNotification change = changeBuilder.build();
322         PushAttributeChangeNotificationInputBuilder statusInput = new PushAttributeChangeNotificationInputBuilder();
323         statusInput.fieldsFrom(change);
324         ListenableFuture<RpcResult<PushAttributeChangeNotificationOutput>> rpcOutput =
325                 api.pushAttributeChangeNotification(statusInput.build());
326         RpcResult<PushAttributeChangeNotificationOutput> res = rpcOutput.get();
327         PushAttributeChangeNotificationOutput output = res.getResult();
328
329         //verify that it was called one time
330         verify(vNL, times(1)).onNotification(change);
331
332         registration.close();
333         System.out.println("Output " + output);
334     }
335
336     @Test
337     @Ignore //TODO: fix mock for BindingNormalizedNodeSerializer (line 148)
338     public void test10ApiPushNotifiction() throws YangParserException, IOException {
339         ExampleConfig.exampleConfig(netconfStateService.getDomContext());
340     }
341
342     @Test
343     public void test10NetconfAccessorClone() {
344
345     }
346
347     // ------- private section
348
349     private static void delete(Path etc) throws IOException {
350         if (Files.exists(etc)) {
351             System.out.println("Found and remove:" + etc.toString());
352             delete(etc.toFile());
353         }
354     }
355
356     private static void delete(File f) throws IOException {
357         if (f.isDirectory()) {
358             for (File c : f.listFiles()) {
359                 delete(c);
360             }
361         }
362         if (!f.delete()) {
363             throw new FileNotFoundException("Failed to delete file: " + f);
364         }
365     }
366
367     public void sendChanges(List<DataTreeModification<Node>> changes) {
368         listener.onDataTreeChanged(changes);
369     }
370
371     public void sendClusteredChanges(List<DataTreeModification<Node>> changes) {
372         //listener.onDataTreeChanged(changes);
373     }
374
375
376 }