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.Matchers.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;
19 import com.google.common.collect.Sets;
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 org.junit.Assert;
29 import org.junit.Before;
30 import org.junit.Test;
31 import org.mockito.Mock;
32 import org.mockito.MockitoAnnotations;
33 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
34 import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
35 import org.opendaylight.controller.config.threadpool.ThreadPool;
36 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
37 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
38 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
39 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
40 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
41 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
42 import org.opendaylight.mdsal.common.api.CommitInfo;
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.util.concurrent.FluentFutures;
69 import org.opendaylight.yangtools.yang.binding.DataObject;
70 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
71 import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
73 public class NetconfTopologyImplTest {
75 private static final NodeId NODE_ID = new NodeId("testing-node");
76 private static final String TOPOLOGY_ID = "testing-topology";
79 private NetconfClientDispatcher mockedClientDispatcher;
82 private EventExecutor mockedEventExecutor;
85 private ScheduledThreadPool mockedKeepaliveExecutor;
88 private ThreadPool mockedProcessingExecutor;
91 private SchemaRepositoryProvider mockedSchemaRepositoryProvider;
94 private DataBroker dataBroker;
97 private DOMMountPointService mountPointService;
100 private AAAEncryptionService encryptionService;
102 private TestingNetconfTopologyImpl topology;
103 private TestingNetconfTopologyImpl spyTopology;
106 public void setUp() {
107 MockitoAnnotations.initMocks(this);
109 when(mockedSchemaRepositoryProvider.getSharedSchemaRepository())
110 .thenReturn(new SharedSchemaRepository("testingSharedSchemaRepo"));
111 when(mockedProcessingExecutor.getExecutor()).thenReturn(MoreExecutors.newDirectExecutorService());
112 final Future future = new SucceededFuture(ImmediateEventExecutor.INSTANCE, new NetconfDeviceCapabilities());
113 when(mockedClientDispatcher.createReconnectingClient(any(NetconfReconnectingClientConfiguration.class)))
116 topology = new TestingNetconfTopologyImpl(TOPOLOGY_ID, mockedClientDispatcher,
117 mockedEventExecutor, mockedKeepaliveExecutor, mockedProcessingExecutor, mockedSchemaRepositoryProvider,
118 dataBroker, mountPointService, encryptionService);
120 spyTopology = spy(topology);
124 public void testInit() {
125 final WriteTransaction wtx = mock(WriteTransaction.class);
126 when(dataBroker.newWriteOnlyTransaction()).thenReturn(wtx);
127 doNothing().when(wtx)
128 .merge(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(DataObject.class));
129 doReturn(FluentFutures.immediateFluentFuture(mock(CommitInfo.class))).when(wtx).commit();
132 //verify initialization of topology
133 final InstanceIdentifier<NetworkTopology> networkTopologyId =
134 InstanceIdentifier.builder(NetworkTopology.class).build();
135 final Topology topo = new TopologyBuilder().setTopologyId(new TopologyId(TOPOLOGY_ID)).build();
136 final NetworkTopology networkTopology = new NetworkTopologyBuilder().build();
137 verify(wtx).merge(LogicalDatastoreType.CONFIGURATION, networkTopologyId, networkTopology);
138 verify(wtx).merge(LogicalDatastoreType.OPERATIONAL, networkTopologyId, networkTopology);
139 verify(wtx).merge(LogicalDatastoreType.CONFIGURATION,
140 networkTopologyId.child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID))), topo);
141 verify(wtx).merge(LogicalDatastoreType.OPERATIONAL,
142 networkTopologyId.child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID))), topo);
146 public void testOnDataTreeChange() {
148 final DataObjectModification<Node> newNode = mock(DataObjectModification.class);
149 when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);
151 InstanceIdentifier.PathArgument pa = null;
153 for (final InstanceIdentifier.PathArgument p
154 : TopologyUtil.createTopologyListPath(TOPOLOGY_ID)
155 .child(Node.class, new NodeKey(NODE_ID)).getPathArguments()) {
159 when(newNode.getIdentifier()).thenReturn(pa);
162 final NetconfNode testingNode = new NetconfNodeBuilder()
163 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
164 .setPort(new PortNumber(9999))
165 .setReconnectOnChangedSchema(true)
166 .setDefaultRequestTimeoutMillis(1000L)
167 .setBetweenAttemptsTimeoutMillis(100)
168 .setKeepaliveDelay(1000L)
170 .setCredentials(new LoginPasswordBuilder()
171 .setUsername("testuser").setPassword("testpassword").build())
174 final NodeBuilder nn = new NodeBuilder().addAugmentation(NetconfNode.class, testingNode);
176 when(newNode.getDataAfter()).thenReturn(nn.build());
179 final Collection<DataTreeModification<Node>> changes = Sets.newHashSet();
180 final DataTreeModification<Node> ch = mock(DataTreeModification.class);
181 when(ch.getRootNode()).thenReturn(newNode);
183 spyTopology.onDataTreeChanged(changes);
184 verify(spyTopology).connectNode(TopologyUtil.getNodeId(pa), nn.build());
186 when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE);
187 spyTopology.onDataTreeChanged(changes);
188 verify(spyTopology).disconnectNode(TopologyUtil.getNodeId(pa));
190 when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED);
191 spyTopology.onDataTreeChanged(changes);
193 //one in previous creating and deleting node and one in updating
194 verify(spyTopology, times(2)).disconnectNode(TopologyUtil.getNodeId(pa));
195 verify(spyTopology, times(2)).connectNode(TopologyUtil.getNodeId(pa), nn.build());
201 public void testGetClientConfig() {
202 final NetconfClientSessionListener sessionListener = mock(NetconfClientSessionListener.class);
204 final NetconfNode testingNode = new NetconfNodeBuilder()
205 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
206 .setPort(new PortNumber(9999))
207 .setReconnectOnChangedSchema(true)
208 .setDefaultRequestTimeoutMillis(1000L)
209 .setBetweenAttemptsTimeoutMillis(100)
210 .setKeepaliveDelay(1000L)
212 .setCredentials(new LoginPasswordBuilder()
213 .setUsername("testuser").setPassword("testpassword").build())
215 final NetconfReconnectingClientConfiguration configuration =
216 spyTopology.getClientConfig(sessionListener, testingNode);
217 Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.TCP, configuration.getProtocol());
218 Assert.assertNotNull(configuration.getAuthHandler());
219 Assert.assertNull(configuration.getSslHandlerFactory());
222 final NetconfNode testingNode2 = new NetconfNodeBuilder()
223 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
224 .setPort(new PortNumber(9999))
225 .setReconnectOnChangedSchema(true)
226 .setDefaultRequestTimeoutMillis(1000L)
227 .setBetweenAttemptsTimeoutMillis(100)
228 .setKeepaliveDelay(1000L)
230 .setCredentials(new LoginPasswordBuilder()
231 .setUsername("testuser").setPassword("testpassword").build())
233 final NetconfReconnectingClientConfiguration configuration2 =
234 spyTopology.getClientConfig(sessionListener, testingNode2);
235 Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.SSH, configuration2.getProtocol());
236 Assert.assertNotNull(configuration2.getAuthHandler());
237 Assert.assertNull(configuration2.getSslHandlerFactory());
240 final NetconfNode testingNode3 = new NetconfNodeBuilder()
241 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
242 .setPort(new PortNumber(9999))
243 .setReconnectOnChangedSchema(true)
244 .setDefaultRequestTimeoutMillis(1000L)
245 .setBetweenAttemptsTimeoutMillis(100)
246 .setKeepaliveDelay(1000L)
248 .setProtocol(new ProtocolBuilder().setName(Name.SSH).build())
249 .setCredentials(new LoginPasswordBuilder()
250 .setUsername("testuser").setPassword("testpassword").build())
252 final NetconfReconnectingClientConfiguration configuration3 =
253 spyTopology.getClientConfig(sessionListener, testingNode3);
254 Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.SSH, configuration3.getProtocol());
255 Assert.assertNotNull(configuration3.getAuthHandler());
256 Assert.assertNull(configuration3.getSslHandlerFactory());
259 final NetconfNode testingNode4 = new NetconfNodeBuilder()
260 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
261 .setPort(new PortNumber(9999))
262 .setReconnectOnChangedSchema(true)
263 .setDefaultRequestTimeoutMillis(1000L)
264 .setBetweenAttemptsTimeoutMillis(100)
265 .setKeepaliveDelay(1000L)
267 .setProtocol(new ProtocolBuilder().setName(Name.TLS).build())
268 .setCredentials(new LoginPasswordBuilder()
269 .setUsername("testuser").setPassword("testpassword").build())
271 final NetconfReconnectingClientConfiguration configuration4 =
272 spyTopology.getClientConfig(sessionListener, testingNode4);
273 Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.TLS, configuration4.getProtocol());
274 Assert.assertNull(configuration4.getAuthHandler());
275 Assert.assertNotNull(configuration4.getSslHandlerFactory());
278 public static class TestingNetconfTopologyImpl extends NetconfTopologyImpl {
280 public TestingNetconfTopologyImpl(final String topologyId, final NetconfClientDispatcher clientDispatcher,
281 final EventExecutor eventExecutor,
282 final ScheduledThreadPool keepaliveExecutor,
283 final ThreadPool processingExecutor,
284 final SchemaRepositoryProvider schemaRepositoryProvider,
285 final DataBroker dataBroker, final DOMMountPointService mountPointService,
286 final AAAEncryptionService encryptionService) {
287 super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor,
288 processingExecutor, schemaRepositoryProvider, dataBroker,
289 mountPointService, encryptionService);
293 public ListenableFuture<NetconfDeviceCapabilities> connectNode(final NodeId nodeId, final Node configNode) {
294 return Futures.immediateFuture(new NetconfDeviceCapabilities());
298 public ListenableFuture<Void> disconnectNode(final NodeId nodeId) {
299 return Futures.immediateFuture(null);