372dc443eae5b1542720fae3d48d6f9ed83819e5
[netconf.git] / netconf / netconf-topology-impl / src / test / java / org / opendaylight / netconf / topology / impl / NetconfTopologyImplTest.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.netconf.topology.impl;
9
10 import static org.mockito.ArgumentMatchers.any;
11 import static org.mockito.Mockito.doNothing;
12 import static org.mockito.Mockito.doReturn;
13 import static org.mockito.Mockito.mock;
14 import static org.mockito.Mockito.spy;
15 import static org.mockito.Mockito.times;
16 import static org.mockito.Mockito.verify;
17 import static org.mockito.Mockito.when;
18 import static org.opendaylight.mdsal.common.api.CommitInfo.emptyFluentFuture;
19
20 import com.google.common.util.concurrent.Futures;
21 import com.google.common.util.concurrent.ListenableFuture;
22 import com.google.common.util.concurrent.MoreExecutors;
23 import io.netty.util.concurrent.EventExecutor;
24 import io.netty.util.concurrent.Future;
25 import io.netty.util.concurrent.ImmediateEventExecutor;
26 import io.netty.util.concurrent.SucceededFuture;
27 import java.util.Collection;
28 import java.util.HashSet;
29 import org.junit.Assert;
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.mockito.Mock;
33 import org.mockito.MockitoAnnotations;
34 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
35 import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
36 import org.opendaylight.controller.config.threadpool.ThreadPool;
37 import org.opendaylight.mdsal.binding.api.DataBroker;
38 import org.opendaylight.mdsal.binding.api.DataObjectModification;
39 import org.opendaylight.mdsal.binding.api.DataTreeModification;
40 import org.opendaylight.mdsal.binding.api.WriteTransaction;
41 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
42 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
43 import org.opendaylight.netconf.client.NetconfClientDispatcher;
44 import org.opendaylight.netconf.client.NetconfClientSessionListener;
45 import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
46 import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
47 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
48 import org.opendaylight.netconf.topology.api.SchemaRepositoryProvider;
49 import org.opendaylight.netconf.topology.spi.AbstractNetconfTopology;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.Protocol.Name;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.ProtocolBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPasswordBuilder;
59 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
60 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
61 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
62 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
63 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
64 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
65 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
66 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
67 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
68 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
69 import org.opendaylight.yangtools.yang.binding.DataObject;
70 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
71 import org.opendaylight.yangtools.yang.common.Uint16;
72 import org.opendaylight.yangtools.yang.common.Uint32;
73 import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
74
75 public class NetconfTopologyImplTest {
76
77     private static final NodeId NODE_ID = new NodeId("testing-node");
78     private static final String TOPOLOGY_ID = "testing-topology";
79
80     @Mock
81     private NetconfClientDispatcher mockedClientDispatcher;
82
83     @Mock
84     private EventExecutor mockedEventExecutor;
85
86     @Mock
87     private ScheduledThreadPool mockedKeepaliveExecutor;
88
89     @Mock
90     private ThreadPool mockedProcessingExecutor;
91
92     @Mock
93     private SchemaRepositoryProvider mockedSchemaRepositoryProvider;
94
95     @Mock
96     private DataBroker dataBroker;
97
98     @Mock
99     private DOMMountPointService mountPointService;
100
101     @Mock
102     private AAAEncryptionService encryptionService;
103
104     private TestingNetconfTopologyImpl topology;
105     private TestingNetconfTopologyImpl spyTopology;
106
107     @Before
108     public void setUp() {
109         MockitoAnnotations.initMocks(this);
110
111         when(mockedSchemaRepositoryProvider.getSharedSchemaRepository())
112                 .thenReturn(new SharedSchemaRepository("testingSharedSchemaRepo"));
113         when(mockedProcessingExecutor.getExecutor()).thenReturn(MoreExecutors.newDirectExecutorService());
114         final Future future = new SucceededFuture(ImmediateEventExecutor.INSTANCE, new NetconfDeviceCapabilities());
115         when(mockedClientDispatcher.createReconnectingClient(any(NetconfReconnectingClientConfiguration.class)))
116                 .thenReturn(future);
117
118         topology = new TestingNetconfTopologyImpl(TOPOLOGY_ID, mockedClientDispatcher,
119                 mockedEventExecutor, mockedKeepaliveExecutor, mockedProcessingExecutor, mockedSchemaRepositoryProvider,
120                 dataBroker, mountPointService, encryptionService);
121
122         spyTopology = spy(topology);
123     }
124
125     @Test
126     public void testInit() {
127         final WriteTransaction wtx = mock(WriteTransaction.class);
128         when(dataBroker.newWriteOnlyTransaction()).thenReturn(wtx);
129         doNothing().when(wtx)
130                 .merge(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(DataObject.class));
131         doReturn(emptyFluentFuture()).when(wtx).commit();
132         topology.init();
133
134         //verify initialization of topology
135         final InstanceIdentifier<NetworkTopology> networkTopologyId =
136                 InstanceIdentifier.builder(NetworkTopology.class).build();
137         final Topology topo = new TopologyBuilder().setTopologyId(new TopologyId(TOPOLOGY_ID)).build();
138         final NetworkTopology networkTopology = new NetworkTopologyBuilder().build();
139         verify(wtx).merge(LogicalDatastoreType.CONFIGURATION, networkTopologyId, networkTopology);
140         verify(wtx).merge(LogicalDatastoreType.OPERATIONAL, networkTopologyId, networkTopology);
141         verify(wtx).merge(LogicalDatastoreType.CONFIGURATION,
142                 networkTopologyId.child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID))), topo);
143         verify(wtx).merge(LogicalDatastoreType.OPERATIONAL,
144                 networkTopologyId.child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID))), topo);
145     }
146
147     @Test
148     public void testOnDataTreeChange() {
149
150         final DataObjectModification<Node> newNode = mock(DataObjectModification.class);
151         when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);
152
153         InstanceIdentifier.PathArgument pa = null;
154
155         for (final InstanceIdentifier.PathArgument p
156                 : NetconfTopologyImpl.createTopologyListPath(TOPOLOGY_ID)
157                     .child(Node.class, new NodeKey(NODE_ID)).getPathArguments()) {
158             pa = p;
159         }
160
161         when(newNode.getIdentifier()).thenReturn(pa);
162
163
164         final NetconfNode testingNode = new NetconfNodeBuilder()
165                 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
166                 .setPort(new PortNumber(Uint16.valueOf(9999)))
167                 .setReconnectOnChangedSchema(true)
168                 .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
169                 .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
170                 .setKeepaliveDelay(Uint32.valueOf(1000))
171                 .setTcpOnly(true)
172                 .setCredentials(new LoginPasswordBuilder()
173                         .setUsername("testuser").setPassword("testpassword").build())
174                 .build();
175
176         final NodeBuilder nn = new NodeBuilder().addAugmentation(NetconfNode.class, testingNode);
177
178         when(newNode.getDataAfter()).thenReturn(nn.build());
179
180
181         final Collection<DataTreeModification<Node>> changes = new HashSet<>();
182         final DataTreeModification<Node> ch = mock(DataTreeModification.class);
183         when(ch.getRootNode()).thenReturn(newNode);
184         changes.add(ch);
185         spyTopology.onDataTreeChanged(changes);
186         verify(spyTopology).connectNode(NetconfTopologyImpl.getNodeId(pa), nn.build());
187
188         when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE);
189         spyTopology.onDataTreeChanged(changes);
190         verify(spyTopology).disconnectNode(NetconfTopologyImpl.getNodeId(pa));
191
192         when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED);
193         spyTopology.onDataTreeChanged(changes);
194
195         //one in previous creating and deleting node and one in updating
196         verify(spyTopology, times(2)).disconnectNode(NetconfTopologyImpl.getNodeId(pa));
197         verify(spyTopology, times(2)).connectNode(NetconfTopologyImpl.getNodeId(pa), nn.build());
198
199
200     }
201
202     @Test
203     public void testGetClientConfig() {
204         final NetconfClientSessionListener sessionListener = mock(NetconfClientSessionListener.class);
205
206         final NetconfNode testingNode = new NetconfNodeBuilder()
207                 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
208                 .setPort(new PortNumber(Uint16.valueOf(9999)))
209                 .setReconnectOnChangedSchema(true)
210                 .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
211                 .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
212                 .setKeepaliveDelay(Uint32.valueOf(1000))
213                 .setTcpOnly(true)
214                 .setCredentials(new LoginPasswordBuilder()
215                         .setUsername("testuser").setPassword("testpassword").build())
216                 .build();
217         final NetconfReconnectingClientConfiguration configuration =
218                 spyTopology.getClientConfig(sessionListener, testingNode);
219         Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.TCP, configuration.getProtocol());
220         Assert.assertNotNull(configuration.getAuthHandler());
221         Assert.assertNull(configuration.getSslHandlerFactory());
222
223
224         final NetconfNode testingNode2 = new NetconfNodeBuilder()
225                 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
226                 .setPort(new PortNumber(Uint16.valueOf(9999)))
227                 .setReconnectOnChangedSchema(true)
228                 .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
229                 .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
230                 .setKeepaliveDelay(Uint32.valueOf(1000))
231                 .setTcpOnly(false)
232                 .setCredentials(new LoginPasswordBuilder()
233                         .setUsername("testuser").setPassword("testpassword").build())
234                 .build();
235         final NetconfReconnectingClientConfiguration configuration2 =
236                 spyTopology.getClientConfig(sessionListener, testingNode2);
237         Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.SSH, configuration2.getProtocol());
238         Assert.assertNotNull(configuration2.getAuthHandler());
239         Assert.assertNull(configuration2.getSslHandlerFactory());
240
241
242         final NetconfNode testingNode3 = new NetconfNodeBuilder()
243                 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
244                 .setPort(new PortNumber(Uint16.valueOf(9999)))
245                 .setReconnectOnChangedSchema(true)
246                 .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
247                 .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
248                 .setKeepaliveDelay(Uint32.valueOf(1000))
249                 .setTcpOnly(false)
250                 .setProtocol(new ProtocolBuilder().setName(Name.SSH).build())
251                 .setCredentials(new LoginPasswordBuilder()
252                         .setUsername("testuser").setPassword("testpassword").build())
253                 .build();
254         final NetconfReconnectingClientConfiguration configuration3 =
255                 spyTopology.getClientConfig(sessionListener, testingNode3);
256         Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.SSH, configuration3.getProtocol());
257         Assert.assertNotNull(configuration3.getAuthHandler());
258         Assert.assertNull(configuration3.getSslHandlerFactory());
259
260
261         final NetconfNode testingNode4 = new NetconfNodeBuilder()
262                 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
263                 .setPort(new PortNumber(Uint16.valueOf(9999)))
264                 .setReconnectOnChangedSchema(true)
265                 .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
266                 .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
267                 .setKeepaliveDelay(Uint32.valueOf(1000))
268                 .setTcpOnly(false)
269                 .setProtocol(new ProtocolBuilder().setName(Name.TLS).build())
270                 .setCredentials(new LoginPasswordBuilder()
271                         .setUsername("testuser").setPassword("testpassword").build())
272                 .build();
273         final NetconfReconnectingClientConfiguration configuration4 =
274                 spyTopology.getClientConfig(sessionListener, testingNode4);
275         Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.TLS, configuration4.getProtocol());
276         Assert.assertNull(configuration4.getAuthHandler());
277         Assert.assertNotNull(configuration4.getSslHandlerFactory());
278     }
279
280     public static class TestingNetconfTopologyImpl extends NetconfTopologyImpl {
281
282         public TestingNetconfTopologyImpl(final String topologyId, final NetconfClientDispatcher clientDispatcher,
283                                           final EventExecutor eventExecutor,
284                                           final ScheduledThreadPool keepaliveExecutor,
285                                           final ThreadPool processingExecutor,
286                                           final SchemaRepositoryProvider schemaRepositoryProvider,
287                                           final DataBroker dataBroker, final DOMMountPointService mountPointService,
288                                           final AAAEncryptionService encryptionService) {
289             super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor,
290                     processingExecutor, schemaRepositoryProvider, dataBroker,
291                   mountPointService, encryptionService);
292         }
293
294         @Override
295         public ListenableFuture<NetconfDeviceCapabilities> connectNode(final NodeId nodeId, final Node configNode) {
296             return Futures.immediateFuture(new NetconfDeviceCapabilities());
297         }
298
299         @Override
300         public ListenableFuture<Void> disconnectNode(final NodeId nodeId) {
301             return Futures.immediateFuture(null);
302         }
303     }
304
305     @Test
306     public void hideCredentialsTest() {
307         final String userName = "admin";
308         final String password = "pa$$word";
309         final NetconfNode netconfNode = new NetconfNodeBuilder()
310                 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
311                 .setPort(new PortNumber(Uint16.valueOf(9999)))
312                 .setReconnectOnChangedSchema(true)
313                 .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
314                 .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
315                 .setKeepaliveDelay(Uint32.valueOf(1000))
316                 .setTcpOnly(false)
317                 .setProtocol(new ProtocolBuilder().setName(Name.TLS).build())
318                 .setCredentials(new LoginPasswordBuilder()
319                         .setUsername(userName).setPassword(password).build())
320                 .build();
321         final Node node = new NodeBuilder()
322                 .addAugmentation(NetconfNode.class, netconfNode)
323                 .setNodeId(NodeId.getDefaultInstance("junos"))
324                 .build();
325         final String transformedNetconfNode = AbstractNetconfTopology.hideCredentials(node);
326         Assert.assertTrue(transformedNetconfNode.contains("credentials=***"));
327         Assert.assertFalse(transformedNetconfNode.contains(userName));
328         Assert.assertFalse(transformedNetconfNode.contains(password));
329     }
330 }