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