Factor out SchemaResourceManager
[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 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;
73
74 @RunWith(MockitoJUnitRunner.StrictStubs.class)
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 SchemaResourceManager mockedResourceManager;
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         when(mockedProcessingExecutor.getExecutor()).thenReturn(MoreExecutors.newDirectExecutorService());
110
111         topology = new TestingNetconfTopologyImpl(TOPOLOGY_ID, mockedClientDispatcher, mockedEventExecutor,
112             mockedKeepaliveExecutor, mockedProcessingExecutor, mockedResourceManager, dataBroker, mountPointService,
113             encryptionService);
114
115         spyTopology = spy(topology);
116     }
117
118     @Test
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();
125         topology.init();
126
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);
138     }
139
140     @Test
141     public void testOnDataTreeChange() {
142
143         final DataObjectModification<Node> newNode = mock(DataObjectModification.class);
144         when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);
145
146         PathArgument pa = IdentifiableItem.of(Node.class, new NodeKey(NODE_ID));
147         when(newNode.getIdentifier()).thenReturn(pa);
148
149
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))
157                 .setTcpOnly(true)
158                 .setCredentials(new LoginPasswordBuilder()
159                         .setUsername("testuser").setPassword("testpassword").build())
160                 .build();
161
162         final NodeBuilder nn = new NodeBuilder().addAugmentation(NetconfNode.class, testingNode);
163
164         when(newNode.getDataAfter()).thenReturn(nn.build());
165
166
167         final Collection<DataTreeModification<Node>> changes = new HashSet<>();
168         final DataTreeModification<Node> ch = mock(DataTreeModification.class);
169         when(ch.getRootNode()).thenReturn(newNode);
170         changes.add(ch);
171         spyTopology.onDataTreeChanged(changes);
172         verify(spyTopology).connectNode(NetconfTopologyImpl.getNodeId(pa), nn.build());
173
174         when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE);
175         spyTopology.onDataTreeChanged(changes);
176         verify(spyTopology).disconnectNode(NetconfTopologyImpl.getNodeId(pa));
177
178         when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED);
179         spyTopology.onDataTreeChanged(changes);
180
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());
184
185
186     }
187
188     @Test
189     public void testGetClientConfig() {
190         final NetconfClientSessionListener sessionListener = mock(NetconfClientSessionListener.class);
191
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))
199                 .setTcpOnly(true)
200                 .setCredentials(new LoginPasswordBuilder()
201                         .setUsername("testuser").setPassword("testpassword").build())
202                 .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());
208
209
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))
217                 .setTcpOnly(false)
218                 .setCredentials(new LoginPasswordBuilder()
219                         .setUsername("testuser").setPassword("testpassword").build())
220                 .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());
226
227
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))
235                 .setTcpOnly(false)
236                 .setProtocol(new ProtocolBuilder().setName(Name.SSH).build())
237                 .setCredentials(new LoginPasswordBuilder()
238                         .setUsername("testuser").setPassword("testpassword").build())
239                 .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());
245
246
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))
254                 .setTcpOnly(false)
255                 .setProtocol(new ProtocolBuilder().setName(Name.TLS).build())
256                 .setCredentials(new LoginPasswordBuilder()
257                         .setUsername("testuser").setPassword("testpassword").build())
258                 .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());
264     }
265
266     public static class TestingNetconfTopologyImpl extends NetconfTopologyImpl {
267
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);
278         }
279
280         @Override
281         public ListenableFuture<NetconfDeviceCapabilities> connectNode(final NodeId nodeId, final Node configNode) {
282             return Futures.immediateFuture(new NetconfDeviceCapabilities());
283         }
284
285         @Override
286         public ListenableFuture<Void> disconnectNode(final NodeId nodeId) {
287             return Futures.immediateFuture(null);
288         }
289     }
290
291     @Test
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))
302                 .setTcpOnly(false)
303                 .setProtocol(new ProtocolBuilder().setName(Name.TLS).build())
304                 .setCredentials(new LoginPasswordBuilder()
305                         .setUsername(userName).setPassword(password).build())
306                 .build();
307         final Node node = new NodeBuilder()
308                 .addAugmentation(NetconfNode.class, netconfNode)
309                 .setNodeId(NodeId.getDefaultInstance("junos"))
310                 .build();
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));
315     }
316 }