2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.netconf.topology.impl;
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;
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 java.util.Collection;
25 import java.util.HashSet;
26 import org.junit.Assert;
27 import org.junit.Before;
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 import org.mockito.Mock;
31 import org.mockito.junit.MockitoJUnitRunner;
32 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
33 import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
34 import org.opendaylight.controller.config.threadpool.ThreadPool;
35 import org.opendaylight.mdsal.binding.api.DataBroker;
36 import org.opendaylight.mdsal.binding.api.DataObjectModification;
37 import org.opendaylight.mdsal.binding.api.DataTreeModification;
38 import org.opendaylight.mdsal.binding.api.WriteTransaction;
39 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
40 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
41 import org.opendaylight.netconf.client.NetconfClientDispatcher;
42 import org.opendaylight.netconf.client.NetconfClientSessionListener;
43 import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
44 import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
45 import org.opendaylight.netconf.sal.connect.api.SchemaResourceManager;
46 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
47 import org.opendaylight.netconf.topology.spi.AbstractNetconfTopology;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
49 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.Protocol.Name;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.ProtocolBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPasswordBuilder;
57 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
58 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
59 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
60 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
61 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
62 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
63 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
64 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
65 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
66 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
67 import org.opendaylight.yangtools.yang.binding.DataObject;
68 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
69 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
70 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
71 import org.opendaylight.yangtools.yang.common.Uint16;
72 import org.opendaylight.yangtools.yang.common.Uint32;
74 @RunWith(MockitoJUnitRunner.StrictStubs.class)
75 public class NetconfTopologyImplTest {
77 private static final NodeId NODE_ID = new NodeId("testing-node");
78 private static final String TOPOLOGY_ID = "testing-topology";
81 private NetconfClientDispatcher mockedClientDispatcher;
84 private EventExecutor mockedEventExecutor;
87 private ScheduledThreadPool mockedKeepaliveExecutor;
90 private ThreadPool mockedProcessingExecutor;
93 private SchemaResourceManager mockedResourceManager;
96 private DataBroker dataBroker;
99 private DOMMountPointService mountPointService;
102 private AAAEncryptionService encryptionService;
104 private TestingNetconfTopologyImpl topology;
105 private TestingNetconfTopologyImpl spyTopology;
108 public void setUp() {
109 when(mockedProcessingExecutor.getExecutor()).thenReturn(MoreExecutors.newDirectExecutorService());
111 topology = new TestingNetconfTopologyImpl(TOPOLOGY_ID, mockedClientDispatcher, mockedEventExecutor,
112 mockedKeepaliveExecutor, mockedProcessingExecutor, mockedResourceManager, dataBroker, mountPointService,
115 spyTopology = spy(topology);
119 public void testInit() {
120 final WriteTransaction wtx = mock(WriteTransaction.class);
121 when(dataBroker.newWriteOnlyTransaction()).thenReturn(wtx);
122 doNothing().when(wtx)
123 .merge(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(DataObject.class));
124 doReturn(emptyFluentFuture()).when(wtx).commit();
127 //verify initialization of topology
128 final InstanceIdentifier<NetworkTopology> networkTopologyId =
129 InstanceIdentifier.builder(NetworkTopology.class).build();
130 final Topology topo = new TopologyBuilder().setTopologyId(new TopologyId(TOPOLOGY_ID)).build();
131 final NetworkTopology networkTopology = new NetworkTopologyBuilder().build();
132 verify(wtx).merge(LogicalDatastoreType.CONFIGURATION, networkTopologyId, networkTopology);
133 verify(wtx).merge(LogicalDatastoreType.OPERATIONAL, networkTopologyId, networkTopology);
134 verify(wtx).merge(LogicalDatastoreType.CONFIGURATION,
135 networkTopologyId.child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID))), topo);
136 verify(wtx).merge(LogicalDatastoreType.OPERATIONAL,
137 networkTopologyId.child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID))), topo);
141 public void testOnDataTreeChange() {
143 final DataObjectModification<Node> newNode = mock(DataObjectModification.class);
144 when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);
146 PathArgument pa = IdentifiableItem.of(Node.class, new NodeKey(NODE_ID));
147 when(newNode.getIdentifier()).thenReturn(pa);
150 final NetconfNode testingNode = new NetconfNodeBuilder()
151 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
152 .setPort(new PortNumber(Uint16.valueOf(9999)))
153 .setReconnectOnChangedSchema(true)
154 .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
155 .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
156 .setKeepaliveDelay(Uint32.valueOf(1000))
158 .setCredentials(new LoginPasswordBuilder()
159 .setUsername("testuser").setPassword("testpassword").build())
162 final NodeBuilder nn = new NodeBuilder().addAugmentation(NetconfNode.class, testingNode);
164 when(newNode.getDataAfter()).thenReturn(nn.build());
167 final Collection<DataTreeModification<Node>> changes = new HashSet<>();
168 final DataTreeModification<Node> ch = mock(DataTreeModification.class);
169 when(ch.getRootNode()).thenReturn(newNode);
171 spyTopology.onDataTreeChanged(changes);
172 verify(spyTopology).connectNode(NetconfTopologyImpl.getNodeId(pa), nn.build());
174 when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE);
175 spyTopology.onDataTreeChanged(changes);
176 verify(spyTopology).disconnectNode(NetconfTopologyImpl.getNodeId(pa));
178 when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED);
179 spyTopology.onDataTreeChanged(changes);
181 //one in previous creating and deleting node and one in updating
182 verify(spyTopology, times(2)).disconnectNode(NetconfTopologyImpl.getNodeId(pa));
183 verify(spyTopology, times(2)).connectNode(NetconfTopologyImpl.getNodeId(pa), nn.build());
189 public void testGetClientConfig() {
190 final NetconfClientSessionListener sessionListener = mock(NetconfClientSessionListener.class);
192 final NetconfNode testingNode = new NetconfNodeBuilder()
193 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
194 .setPort(new PortNumber(Uint16.valueOf(9999)))
195 .setReconnectOnChangedSchema(true)
196 .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
197 .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
198 .setKeepaliveDelay(Uint32.valueOf(1000))
200 .setCredentials(new LoginPasswordBuilder()
201 .setUsername("testuser").setPassword("testpassword").build())
203 final NetconfReconnectingClientConfiguration configuration =
204 spyTopology.getClientConfig(sessionListener, testingNode);
205 Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.TCP, configuration.getProtocol());
206 Assert.assertNotNull(configuration.getAuthHandler());
207 Assert.assertNull(configuration.getSslHandlerFactory());
210 final NetconfNode testingNode2 = new NetconfNodeBuilder()
211 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
212 .setPort(new PortNumber(Uint16.valueOf(9999)))
213 .setReconnectOnChangedSchema(true)
214 .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
215 .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
216 .setKeepaliveDelay(Uint32.valueOf(1000))
218 .setCredentials(new LoginPasswordBuilder()
219 .setUsername("testuser").setPassword("testpassword").build())
221 final NetconfReconnectingClientConfiguration configuration2 =
222 spyTopology.getClientConfig(sessionListener, testingNode2);
223 Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.SSH, configuration2.getProtocol());
224 Assert.assertNotNull(configuration2.getAuthHandler());
225 Assert.assertNull(configuration2.getSslHandlerFactory());
228 final NetconfNode testingNode3 = new NetconfNodeBuilder()
229 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
230 .setPort(new PortNumber(Uint16.valueOf(9999)))
231 .setReconnectOnChangedSchema(true)
232 .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
233 .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
234 .setKeepaliveDelay(Uint32.valueOf(1000))
236 .setProtocol(new ProtocolBuilder().setName(Name.SSH).build())
237 .setCredentials(new LoginPasswordBuilder()
238 .setUsername("testuser").setPassword("testpassword").build())
240 final NetconfReconnectingClientConfiguration configuration3 =
241 spyTopology.getClientConfig(sessionListener, testingNode3);
242 Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.SSH, configuration3.getProtocol());
243 Assert.assertNotNull(configuration3.getAuthHandler());
244 Assert.assertNull(configuration3.getSslHandlerFactory());
247 final NetconfNode testingNode4 = new NetconfNodeBuilder()
248 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
249 .setPort(new PortNumber(Uint16.valueOf(9999)))
250 .setReconnectOnChangedSchema(true)
251 .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
252 .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
253 .setKeepaliveDelay(Uint32.valueOf(1000))
255 .setProtocol(new ProtocolBuilder().setName(Name.TLS).build())
256 .setCredentials(new LoginPasswordBuilder()
257 .setUsername("testuser").setPassword("testpassword").build())
259 final NetconfReconnectingClientConfiguration configuration4 =
260 spyTopology.getClientConfig(sessionListener, testingNode4);
261 Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.TLS, configuration4.getProtocol());
262 Assert.assertNull(configuration4.getAuthHandler());
263 Assert.assertNotNull(configuration4.getSslHandlerFactory());
266 public static class TestingNetconfTopologyImpl extends NetconfTopologyImpl {
268 public TestingNetconfTopologyImpl(final String topologyId, final NetconfClientDispatcher clientDispatcher,
269 final EventExecutor eventExecutor,
270 final ScheduledThreadPool keepaliveExecutor,
271 final ThreadPool processingExecutor,
272 final SchemaResourceManager schemaRepositoryProvider,
273 final DataBroker dataBroker, final DOMMountPointService mountPointService,
274 final AAAEncryptionService encryptionService) {
275 super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor,
276 processingExecutor, schemaRepositoryProvider, dataBroker,
277 mountPointService, encryptionService);
281 public ListenableFuture<NetconfDeviceCapabilities> connectNode(final NodeId nodeId, final Node configNode) {
282 return Futures.immediateFuture(new NetconfDeviceCapabilities());
286 public ListenableFuture<Void> disconnectNode(final NodeId nodeId) {
287 return Futures.immediateFuture(null);
292 public void hideCredentialsTest() {
293 final String userName = "admin";
294 final String password = "pa$$word";
295 final NetconfNode netconfNode = new NetconfNodeBuilder()
296 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
297 .setPort(new PortNumber(Uint16.valueOf(9999)))
298 .setReconnectOnChangedSchema(true)
299 .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
300 .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
301 .setKeepaliveDelay(Uint32.valueOf(1000))
303 .setProtocol(new ProtocolBuilder().setName(Name.TLS).build())
304 .setCredentials(new LoginPasswordBuilder()
305 .setUsername(userName).setPassword(password).build())
307 final Node node = new NodeBuilder()
308 .addAugmentation(NetconfNode.class, netconfNode)
309 .setNodeId(NodeId.getDefaultInstance("junos"))
311 final String transformedNetconfNode = AbstractNetconfTopology.hideCredentials(node);
312 Assert.assertTrue(transformedNetconfNode.contains("credentials=***"));
313 Assert.assertFalse(transformedNetconfNode.contains(userName));
314 Assert.assertFalse(transformedNetconfNode.contains(password));