ad410dd441662ba9c1fabc9ebc1e4059bd87d7e9
[ccsdk/features.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 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.GenericTransactionUtils;
48 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.NetconfAccessorImpl;
49 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.NetconfNodeStateServiceImpl;
50 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.impl.rpc.NetconfnodeStateServiceRpcApiImpl;
51 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test.mock.ClusterSingletonServiceProviderMock;
52 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test.mock.MountPointMock;
53 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test.mock.MountPointServiceMock;
54 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test.mock.NotificationPublishServiceMock;
55 import org.onap.ccsdk.features.sdnr.wt.netconfnodestateservice.test.mock.RpcProviderRegistryMock;
56 import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener;
57 import org.opendaylight.mdsal.binding.api.DataBroker;
58 import org.opendaylight.mdsal.binding.api.DataObjectModification;
59 import org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType;
60 import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
61 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
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.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapabilityBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.AttributeChangeNotification;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.AttributeChangeNotificationBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.FaultNotification;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.FaultNotificationBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusInputBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusOutput;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.GetStatusOutputBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushAttributeChangeNotificationInputBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushAttributeChangeNotificationOutput;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushFaultNotificationInputBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netconfnode.state.rev191011.PushFaultNotificationOutput;
83 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
84 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
85 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
86 import org.opendaylight.yangtools.concepts.ListenerRegistration;
87 import org.opendaylight.yangtools.yang.binding.DataObject;
88 import org.opendaylight.yangtools.yang.common.RpcResult;
89 import org.slf4j.Logger;
90 import org.slf4j.LoggerFactory;
91
92
93 public class TestNetconfNodeStateService extends Mockito {
94
95     private static Path KARAF_ETC = Paths.get("etc");
96     private static NetconfNodeStateServiceImpl netconfStateService;
97     private static MountPointMock mountPoint;
98     //private static DataBrokerNetconfMock dataBrokerNetconf;
99     private static DataBroker dataBrokerNetconf;
100     private @NonNull
101     static DataTreeChangeListener<Node> listener;
102     private @NonNull
103     static ClusteredDataTreeChangeListener<Node> listenerClustered;
104
105
106     private static final Logger LOG = LoggerFactory.getLogger(TestNetconfNodeStateService.class);
107
108     @BeforeClass
109     public static <T extends DataObject, L extends DataTreeChangeListener<T>> void before() throws InterruptedException, IOException {
110
111         System.out.println("Logger: " + LOG.getClass().getName() + " " + LOG.getName());
112         // Call System property to get the classpath value
113         Path etc = KARAF_ETC;
114         delete(etc);
115
116         System.out.println("Create empty:" + etc.toString());
117         Files.createDirectories(etc);
118
119         // Create mocks
120         //dataBrokerNetconf = new DataBrokerNetconfMock();
121         //dataBrokerNetconf.newReadWriteTransaction();
122         dataBrokerNetconf = mock(DataBroker.class);
123         ArgumentCaptor<DataTreeIdentifier<?>> argument1 = ArgumentCaptor.forClass(DataTreeIdentifier.class);
124         ArgumentCaptor<DataTreeChangeListener<?>> argument2 = ArgumentCaptor.forClass(DataTreeChangeListener.class);
125         when(dataBrokerNetconf.registerDataTreeChangeListener(any(), any())).thenAnswer(
126                 invocation -> {
127                     Object pListener = invocation.getArguments()[1];
128                     System.out.println("Register " + pListener.getClass().getName());
129                     if (pListener instanceof ClusteredDataTreeChangeListener) {
130                         System.out.println("Clustered listener");
131                         listenerClustered = (ClusteredDataTreeChangeListener<Node>) pListener;
132                     } else if (pListener instanceof DataTreeChangeListener) {
133                         System.out.println("Listener");
134                         listener = (DataTreeChangeListener<Node>) pListener;
135                     }
136                     return new ListenerRegistration<L>() {
137                         @Override
138                         public L getInstance() {
139                             return (L) pListener;
140                         }
141
142                         @Override
143                         public void close() {
144                         }
145                     };
146
147                 }
148 );
149
150         mountPoint = new MountPointMock();
151         ClusterSingletonServiceProvider clusterSingletonService = new ClusterSingletonServiceProviderMock();
152         MountPointService mountPointService = new MountPointServiceMock(mountPoint);
153         NotificationPublishService notificationPublishService = new NotificationPublishServiceMock();
154         RpcProviderService rpcProviderRegistry = new RpcProviderRegistryMock();
155         IEntityDataProvider entityProviderMock = mock(IEntityDataProvider.class);
156
157         // start using blueprint interface
158         netconfStateService = new NetconfNodeStateServiceImpl();
159
160         netconfStateService.setDataBroker(dataBrokerNetconf);
161         netconfStateService.setMountPointService(mountPointService);
162         netconfStateService.setNotificationPublishService(notificationPublishService);
163         netconfStateService.setRpcProviderRegistry(rpcProviderRegistry);
164         netconfStateService.setClusterSingletonService(clusterSingletonService);
165         netconfStateService.setEntityDataProvider(entityProviderMock);
166         netconfStateService.init();
167         System.out.println("Initialization done");
168     }
169
170     @AfterClass
171     public static void after() throws InterruptedException, IOException {
172         System.out.println("Start shutdown");
173         // close using blueprint interface
174         netconfStateService.close();
175         delete(KARAF_ETC);
176
177     }
178
179     @Test
180     public void test1() {
181
182         System.out.println("Test1: Verify init state");
183         assertTrue("Devicemanager not initialized", netconfStateService.isInitializationSuccessful());
184     }
185
186
187     @Test
188     public void test2() {
189
190         System.out.println("Test2: Register state listener");
191
192         NetconfNodeStateListener nSL = mock(NetconfNodeStateListener.class);
193         ListenerRegistration<NetconfNodeStateListener> res = netconfStateService.registerNetconfNodeStateListener(nSL);
194         assertNotNull("Result should be null", res);
195         res.getInstance();
196         res.close();
197     }
198
199     @Test
200     public void test3() {
201
202         System.out.println("Test3: Register connect listener");
203
204         NetconfNodeConnectListener nCL = mock(NetconfNodeConnectListener.class);
205         ListenerRegistration<NetconfNodeConnectListener> res =
206                 netconfStateService.registerNetconfNodeConnectListener(nCL);
207         assertNotNull("Result should be null", res);
208         res.getInstance();
209         res.close();
210     }
211
212     @Test
213     public void test4() {
214         System.out.println("Test4: Get status listener");
215         GetStatusInputBuilder inputBuilder = new GetStatusInputBuilder();
216         GetStatusOutputBuilder res = netconfStateService.getStatus(inputBuilder.build());
217         assertNotNull("Result should be null", res);
218     }
219
220     @SuppressWarnings("unchecked")
221     @Test
222     public void test5OnConnect() throws InterruptedException {
223         System.out.println("Test5: On Connect");
224         NetconfNodeBuilder netconfNodeBuilder = new NetconfNodeBuilder();
225         netconfNodeBuilder.setConnectionStatus(ConnectionStatus.Connected);
226         AvailableCapabilityBuilder availableCapabilityBuilder = new AvailableCapabilityBuilder();
227         availableCapabilityBuilder.setCapability("network-element");
228         AvailableCapabilitiesBuilder availableCapabilitesBuilder = new AvailableCapabilitiesBuilder();
229         availableCapabilitesBuilder.setAvailableCapability(Arrays.asList(availableCapabilityBuilder.build()));
230         netconfNodeBuilder.setAvailableCapabilities(availableCapabilitesBuilder.build());
231         NetconfNode rootNodeNetconf = netconfNodeBuilder.build();
232
233         String nodeIdString = "Test";
234         NodeId nodeId = new NodeId(nodeIdString);
235         NodeBuilder nodeBuilder = new NodeBuilder();
236         nodeBuilder.addAugmentation(NetconfNode.class, rootNodeNetconf);
237         nodeBuilder.setNodeId(nodeId);
238         Node rootNode = nodeBuilder.build();
239         NetconfAccessor acessor = new NetconfAccessorImpl(nodeId, rootNodeNetconf, mountPoint.getDataBroker(),
240                 mountPoint, new GenericTransactionUtils());
241
242         DataObjectModification<Node> dom = mock(DataObjectModification.class);
243         when(dom.getDataAfter()).thenReturn(rootNode);
244         when(dom.getModificationType()).thenReturn(ModificationType.WRITE);
245
246         DataTreeModification<Node> ntn = mock(DataTreeModification.class);
247         when(ntn.getRootNode()).thenReturn(dom);
248
249         NetconfNodeConnectListener nCL = mock(NetconfNodeConnectListener.class);
250         netconfStateService.registerNetconfNodeConnectListener(nCL);
251         mountPoint.setDatabrokerAbsent(false);
252
253         Collection<DataTreeModification<Node>> changes = Arrays.asList(ntn);
254         sendClusteredChanges(changes);
255         sendChanges(changes);
256         Thread.sleep(300);
257         //verify that it was called one time and nodeId is the expected
258         ArgumentCaptor<NetconfAccessor> varArgs = ArgumentCaptor.forClass(NetconfAccessor.class);
259         verify(nCL).onEnterConnected(varArgs.capture());
260         System.out.println("Accessor " + varArgs.getValue().getNodeId());
261         assertEquals(nodeIdString, varArgs.getValue().getNodeId().getValue());
262
263     }
264
265     @SuppressWarnings("unchecked")
266     @Test
267     public void test6Update() {
268         System.out.println("Test6: OnChange");
269         NetconfNodeBuilder netconfNodeBuilder = new NetconfNodeBuilder();
270         netconfNodeBuilder.setConnectionStatus(ConnectionStatus.Connected);
271         NetconfNode rootNodeNetconf = netconfNodeBuilder.build();
272
273         NodeBuilder nodeBuilder = new NodeBuilder();
274         nodeBuilder.addAugmentation(NetconfNode.class, rootNodeNetconf);
275         nodeBuilder.setNodeId(new NodeId("Test"));
276         Node rootNodeAfter = nodeBuilder.build();
277
278         DataObjectModification<Node> dom = mock(DataObjectModification.class);
279         when(dom.getDataBefore()).thenReturn(rootNodeAfter);
280         when(dom.getDataAfter()).thenReturn(rootNodeAfter);
281         when(dom.getModificationType()).thenReturn(ModificationType.WRITE);
282
283         DataTreeModification<Node> ntn = mock(DataTreeModification.class);
284         when(ntn.getRootNode()).thenReturn(dom);
285
286         Collection<DataTreeModification<Node>> changes = Arrays.asList(ntn);
287         sendClusteredChanges(changes);
288         sendChanges(changes);
289     }
290
291     @Test
292     public void test7ApiStatus() throws InterruptedException, ExecutionException {
293
294         NetconfnodeStateServiceRpcApiImpl api = netconfStateService.getNetconfnodeStateServiceRpcApiImpl();
295
296         GetStatusInputBuilder statusInput = new GetStatusInputBuilder();
297         ListenableFuture<RpcResult<GetStatusOutput>> statusOutput = api.getStatus(statusInput.build());
298         RpcResult<GetStatusOutput> res = statusOutput.get();
299         GetStatusOutput output = res.getResult();
300         System.out.println("Output " + output);
301     }
302
303
304     @Test
305     public void test8ApiPushFault() throws InterruptedException, ExecutionException {
306
307         NetconfnodeStateServiceRpcApiImpl api = netconfStateService.getNetconfnodeStateServiceRpcApiImpl();
308
309         VesNotificationListener vNL = mock(VesNotificationListener.class);
310         ListenerRegistration<VesNotificationListener> registration = netconfStateService.registerVesNotifications(vNL);
311
312         FaultNotificationBuilder faultBuilder = new FaultNotificationBuilder();
313         faultBuilder.setProblem("problem1");
314         FaultNotification fault = faultBuilder.build();
315         PushFaultNotificationInputBuilder statusInput = new PushFaultNotificationInputBuilder();
316         statusInput.fieldsFrom(fault);
317         ListenableFuture<RpcResult<PushFaultNotificationOutput>> rpcOutput =
318                 api.pushFaultNotification(statusInput.build());
319         RpcResult<PushFaultNotificationOutput> res = rpcOutput.get();
320         PushFaultNotificationOutput output = res.getResult();
321
322         //verify that it was called one time
323         verify(vNL, times(1)).onNotification(fault);
324
325         registration.close();
326         System.out.println("Output " + output);
327     }
328
329     @Test
330     public void test9ApiPushNotifiction() throws InterruptedException, ExecutionException {
331
332         NetconfnodeStateServiceRpcApiImpl api = netconfStateService.getNetconfnodeStateServiceRpcApiImpl();
333
334         VesNotificationListener vNL = mock(VesNotificationListener.class);
335         ListenerRegistration<VesNotificationListener> registration = netconfStateService.registerVesNotifications(vNL);
336
337         AttributeChangeNotificationBuilder changeBuilder = new AttributeChangeNotificationBuilder();
338         changeBuilder.setAttributeName("attribute1");
339         AttributeChangeNotification change = changeBuilder.build();
340         PushAttributeChangeNotificationInputBuilder statusInput = new PushAttributeChangeNotificationInputBuilder();
341         statusInput.fieldsFrom(change);
342         ListenableFuture<RpcResult<PushAttributeChangeNotificationOutput>> rpcOutput =
343                 api.pushAttributeChangeNotification(statusInput.build());
344         RpcResult<PushAttributeChangeNotificationOutput> res = rpcOutput.get();
345         PushAttributeChangeNotificationOutput output = res.getResult();
346
347         //verify that it was called one time
348         verify(vNL, times(1)).onNotification(change);
349
350         registration.close();
351         System.out.println("Output " + output);
352     }
353
354
355     // ------- private section
356
357     private static void delete(Path etc) throws IOException {
358         if (Files.exists(etc)) {
359             System.out.println("Found and remove:" + etc.toString());
360             delete(etc.toFile());
361         }
362     }
363
364     private static void delete(File f) throws IOException {
365         if (f.isDirectory()) {
366             for (File c : f.listFiles()) {
367                 delete(c);
368             }
369         }
370         if (!f.delete()) {
371             throw new FileNotFoundException("Failed to delete file: " + f);
372         }
373     }
374
375     public void sendChanges(Collection<DataTreeModification<Node>> changes) {
376         listener.onDataTreeChanged(changes);
377     }
378
379     public void sendClusteredChanges(Collection<DataTreeModification<Node>> changes) {
380         listenerClustered.onDataTreeChanged(changes);
381     }
382
383
384 }