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.collect.Sets;
21 import com.google.common.util.concurrent.Futures;
22 import com.google.common.util.concurrent.ListenableFuture;
23 import com.google.common.util.concurrent.MoreExecutors;
24 import io.netty.util.concurrent.EventExecutor;
25 import io.netty.util.concurrent.Future;
26 import io.netty.util.concurrent.ImmediateEventExecutor;
27 import io.netty.util.concurrent.SucceededFuture;
28 import java.util.Collection;
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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
50 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.Protocol.Name;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.ProtocolBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPasswordBuilder;
58 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
59 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
60 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
61 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
62 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
63 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
64 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
65 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
66 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
67 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
68 import org.opendaylight.yangtools.yang.binding.DataObject;
69 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
70 import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
72 public class NetconfTopologyImplTest {
74 private static final NodeId NODE_ID = new NodeId("testing-node");
75 private static final String TOPOLOGY_ID = "testing-topology";
78 private NetconfClientDispatcher mockedClientDispatcher;
81 private EventExecutor mockedEventExecutor;
84 private ScheduledThreadPool mockedKeepaliveExecutor;
87 private ThreadPool mockedProcessingExecutor;
90 private SchemaRepositoryProvider mockedSchemaRepositoryProvider;
93 private DataBroker dataBroker;
96 private DOMMountPointService mountPointService;
99 private AAAEncryptionService encryptionService;
101 private TestingNetconfTopologyImpl topology;
102 private TestingNetconfTopologyImpl spyTopology;
105 public void setUp() {
106 MockitoAnnotations.initMocks(this);
108 when(mockedSchemaRepositoryProvider.getSharedSchemaRepository())
109 .thenReturn(new SharedSchemaRepository("testingSharedSchemaRepo"));
110 when(mockedProcessingExecutor.getExecutor()).thenReturn(MoreExecutors.newDirectExecutorService());
111 final Future future = new SucceededFuture(ImmediateEventExecutor.INSTANCE, new NetconfDeviceCapabilities());
112 when(mockedClientDispatcher.createReconnectingClient(any(NetconfReconnectingClientConfiguration.class)))
115 topology = new TestingNetconfTopologyImpl(TOPOLOGY_ID, mockedClientDispatcher,
116 mockedEventExecutor, mockedKeepaliveExecutor, mockedProcessingExecutor, mockedSchemaRepositoryProvider,
117 dataBroker, mountPointService, encryptionService);
119 spyTopology = spy(topology);
123 public void testInit() {
124 final WriteTransaction wtx = mock(WriteTransaction.class);
125 when(dataBroker.newWriteOnlyTransaction()).thenReturn(wtx);
126 doNothing().when(wtx)
127 .merge(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(DataObject.class));
128 doReturn(emptyFluentFuture()).when(wtx).commit();
131 //verify initialization of topology
132 final InstanceIdentifier<NetworkTopology> networkTopologyId =
133 InstanceIdentifier.builder(NetworkTopology.class).build();
134 final Topology topo = new TopologyBuilder().setTopologyId(new TopologyId(TOPOLOGY_ID)).build();
135 final NetworkTopology networkTopology = new NetworkTopologyBuilder().build();
136 verify(wtx).merge(LogicalDatastoreType.CONFIGURATION, networkTopologyId, networkTopology);
137 verify(wtx).merge(LogicalDatastoreType.OPERATIONAL, networkTopologyId, networkTopology);
138 verify(wtx).merge(LogicalDatastoreType.CONFIGURATION,
139 networkTopologyId.child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID))), topo);
140 verify(wtx).merge(LogicalDatastoreType.OPERATIONAL,
141 networkTopologyId.child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID))), topo);
145 public void testOnDataTreeChange() {
147 final DataObjectModification<Node> newNode = mock(DataObjectModification.class);
148 when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);
150 InstanceIdentifier.PathArgument pa = null;
152 for (final InstanceIdentifier.PathArgument p
153 : TopologyUtil.createTopologyListPath(TOPOLOGY_ID)
154 .child(Node.class, new NodeKey(NODE_ID)).getPathArguments()) {
158 when(newNode.getIdentifier()).thenReturn(pa);
161 final NetconfNode testingNode = new NetconfNodeBuilder()
162 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
163 .setPort(new PortNumber(9999))
164 .setReconnectOnChangedSchema(true)
165 .setDefaultRequestTimeoutMillis(1000L)
166 .setBetweenAttemptsTimeoutMillis(100)
167 .setKeepaliveDelay(1000L)
169 .setCredentials(new LoginPasswordBuilder()
170 .setUsername("testuser").setPassword("testpassword").build())
173 final NodeBuilder nn = new NodeBuilder().addAugmentation(NetconfNode.class, testingNode);
175 when(newNode.getDataAfter()).thenReturn(nn.build());
178 final Collection<DataTreeModification<Node>> changes = Sets.newHashSet();
179 final DataTreeModification<Node> ch = mock(DataTreeModification.class);
180 when(ch.getRootNode()).thenReturn(newNode);
182 spyTopology.onDataTreeChanged(changes);
183 verify(spyTopology).connectNode(TopologyUtil.getNodeId(pa), nn.build());
185 when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE);
186 spyTopology.onDataTreeChanged(changes);
187 verify(spyTopology).disconnectNode(TopologyUtil.getNodeId(pa));
189 when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED);
190 spyTopology.onDataTreeChanged(changes);
192 //one in previous creating and deleting node and one in updating
193 verify(spyTopology, times(2)).disconnectNode(TopologyUtil.getNodeId(pa));
194 verify(spyTopology, times(2)).connectNode(TopologyUtil.getNodeId(pa), nn.build());
200 public void testGetClientConfig() {
201 final NetconfClientSessionListener sessionListener = mock(NetconfClientSessionListener.class);
203 final NetconfNode testingNode = new NetconfNodeBuilder()
204 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
205 .setPort(new PortNumber(9999))
206 .setReconnectOnChangedSchema(true)
207 .setDefaultRequestTimeoutMillis(1000L)
208 .setBetweenAttemptsTimeoutMillis(100)
209 .setKeepaliveDelay(1000L)
211 .setCredentials(new LoginPasswordBuilder()
212 .setUsername("testuser").setPassword("testpassword").build())
214 final NetconfReconnectingClientConfiguration configuration =
215 spyTopology.getClientConfig(sessionListener, testingNode);
216 Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.TCP, configuration.getProtocol());
217 Assert.assertNotNull(configuration.getAuthHandler());
218 Assert.assertNull(configuration.getSslHandlerFactory());
221 final NetconfNode testingNode2 = new NetconfNodeBuilder()
222 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
223 .setPort(new PortNumber(9999))
224 .setReconnectOnChangedSchema(true)
225 .setDefaultRequestTimeoutMillis(1000L)
226 .setBetweenAttemptsTimeoutMillis(100)
227 .setKeepaliveDelay(1000L)
229 .setCredentials(new LoginPasswordBuilder()
230 .setUsername("testuser").setPassword("testpassword").build())
232 final NetconfReconnectingClientConfiguration configuration2 =
233 spyTopology.getClientConfig(sessionListener, testingNode2);
234 Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.SSH, configuration2.getProtocol());
235 Assert.assertNotNull(configuration2.getAuthHandler());
236 Assert.assertNull(configuration2.getSslHandlerFactory());
239 final NetconfNode testingNode3 = new NetconfNodeBuilder()
240 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
241 .setPort(new PortNumber(9999))
242 .setReconnectOnChangedSchema(true)
243 .setDefaultRequestTimeoutMillis(1000L)
244 .setBetweenAttemptsTimeoutMillis(100)
245 .setKeepaliveDelay(1000L)
247 .setProtocol(new ProtocolBuilder().setName(Name.SSH).build())
248 .setCredentials(new LoginPasswordBuilder()
249 .setUsername("testuser").setPassword("testpassword").build())
251 final NetconfReconnectingClientConfiguration configuration3 =
252 spyTopology.getClientConfig(sessionListener, testingNode3);
253 Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.SSH, configuration3.getProtocol());
254 Assert.assertNotNull(configuration3.getAuthHandler());
255 Assert.assertNull(configuration3.getSslHandlerFactory());
258 final NetconfNode testingNode4 = new NetconfNodeBuilder()
259 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
260 .setPort(new PortNumber(9999))
261 .setReconnectOnChangedSchema(true)
262 .setDefaultRequestTimeoutMillis(1000L)
263 .setBetweenAttemptsTimeoutMillis(100)
264 .setKeepaliveDelay(1000L)
266 .setProtocol(new ProtocolBuilder().setName(Name.TLS).build())
267 .setCredentials(new LoginPasswordBuilder()
268 .setUsername("testuser").setPassword("testpassword").build())
270 final NetconfReconnectingClientConfiguration configuration4 =
271 spyTopology.getClientConfig(sessionListener, testingNode4);
272 Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.TLS, configuration4.getProtocol());
273 Assert.assertNull(configuration4.getAuthHandler());
274 Assert.assertNotNull(configuration4.getSslHandlerFactory());
277 public static class TestingNetconfTopologyImpl extends NetconfTopologyImpl {
279 public TestingNetconfTopologyImpl(final String topologyId, final NetconfClientDispatcher clientDispatcher,
280 final EventExecutor eventExecutor,
281 final ScheduledThreadPool keepaliveExecutor,
282 final ThreadPool processingExecutor,
283 final SchemaRepositoryProvider schemaRepositoryProvider,
284 final DataBroker dataBroker, final DOMMountPointService mountPointService,
285 final AAAEncryptionService encryptionService) {
286 super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor,
287 processingExecutor, schemaRepositoryProvider, dataBroker,
288 mountPointService, encryptionService);
292 public ListenableFuture<NetconfDeviceCapabilities> connectNode(final NodeId nodeId, final Node configNode) {
293 return Futures.immediateFuture(new NetconfDeviceCapabilities());
297 public ListenableFuture<Void> disconnectNode(final NodeId nodeId) {
298 return Futures.immediateFuture(null);