Bump upstreams to SNAPSHOTs
[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.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertNull;
14 import static org.junit.Assert.assertTrue;
15 import static org.mockito.ArgumentMatchers.any;
16 import static org.mockito.Mockito.doNothing;
17 import static org.mockito.Mockito.doReturn;
18 import static org.mockito.Mockito.mock;
19 import static org.mockito.Mockito.spy;
20 import static org.mockito.Mockito.times;
21 import static org.mockito.Mockito.verify;
22 import static org.mockito.Mockito.when;
23 import static org.opendaylight.mdsal.common.api.CommitInfo.emptyFluentFuture;
24
25 import com.google.common.util.concurrent.Futures;
26 import com.google.common.util.concurrent.ListenableFuture;
27 import com.google.common.util.concurrent.MoreExecutors;
28 import io.netty.util.concurrent.EventExecutor;
29 import java.util.Collection;
30 import java.util.HashSet;
31 import org.junit.Before;
32 import org.junit.Test;
33 import org.junit.runner.RunWith;
34 import org.mockito.Mock;
35 import org.mockito.junit.MockitoJUnitRunner;
36 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
37 import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
38 import org.opendaylight.controller.config.threadpool.ThreadPool;
39 import org.opendaylight.mdsal.binding.api.DataBroker;
40 import org.opendaylight.mdsal.binding.api.DataObjectModification;
41 import org.opendaylight.mdsal.binding.api.DataTreeModification;
42 import org.opendaylight.mdsal.binding.api.RpcProviderService;
43 import org.opendaylight.mdsal.binding.api.WriteTransaction;
44 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
45 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
46 import org.opendaylight.netconf.client.NetconfClientDispatcher;
47 import org.opendaylight.netconf.client.NetconfClientSessionListener;
48 import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
49 import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
50 import org.opendaylight.netconf.sal.connect.api.SchemaResourceManager;
51 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
52 import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.BaseNetconfSchemas;
53 import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.DefaultBaseNetconfSchemas;
54 import org.opendaylight.netconf.topology.spi.AbstractNetconfTopology;
55 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.Protocol.Name;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.parameters.ProtocolBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.credentials.credentials.LoginPasswordBuilder;
63 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
64 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopologyBuilder;
65 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
66 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
67 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
68 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
69 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
70 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
71 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
72 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
73 import org.opendaylight.yangtools.yang.binding.DataObject;
74 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
75 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
76 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
77 import org.opendaylight.yangtools.yang.common.Decimal64;
78 import org.opendaylight.yangtools.yang.common.Uint16;
79 import org.opendaylight.yangtools.yang.common.Uint32;
80 import org.opendaylight.yangtools.yang.parser.api.YangParserException;
81 import org.opendaylight.yangtools.yang.parser.impl.DefaultYangParserFactory;
82
83 @RunWith(MockitoJUnitRunner.StrictStubs.class)
84 public class NetconfTopologyImplTest {
85
86     private static final NodeId NODE_ID = new NodeId("testing-node");
87     private static final String TOPOLOGY_ID = "testing-topology";
88
89     @Mock
90     private NetconfClientDispatcher mockedClientDispatcher;
91
92     @Mock
93     private EventExecutor mockedEventExecutor;
94
95     @Mock
96     private ScheduledThreadPool mockedKeepaliveExecutor;
97
98     @Mock
99     private ThreadPool mockedProcessingExecutor;
100
101     @Mock
102     private SchemaResourceManager mockedResourceManager;
103
104     @Mock
105     private DataBroker dataBroker;
106
107     @Mock
108     private DOMMountPointService mountPointService;
109
110     @Mock
111     private AAAEncryptionService encryptionService;
112
113     @Mock
114     private RpcProviderService rpcProviderService;
115
116     private TestingNetconfTopologyImpl topology;
117     private TestingNetconfTopologyImpl spyTopology;
118
119     @Before
120     public void setUp() {
121         when(mockedProcessingExecutor.getExecutor()).thenReturn(MoreExecutors.newDirectExecutorService());
122
123         topology = new TestingNetconfTopologyImpl(TOPOLOGY_ID, mockedClientDispatcher, mockedEventExecutor,
124             mockedKeepaliveExecutor, mockedProcessingExecutor, mockedResourceManager, dataBroker, mountPointService,
125             encryptionService, rpcProviderService);
126
127         spyTopology = spy(topology);
128     }
129
130     @Test
131     public void testInit() {
132         final WriteTransaction wtx = mock(WriteTransaction.class);
133         when(dataBroker.newWriteOnlyTransaction()).thenReturn(wtx);
134         doNothing().when(wtx)
135                 .merge(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(DataObject.class));
136         doReturn(emptyFluentFuture()).when(wtx).commit();
137         topology.init();
138
139         //verify initialization of topology
140         final InstanceIdentifier<NetworkTopology> networkTopologyId =
141                 InstanceIdentifier.builder(NetworkTopology.class).build();
142         final Topology topo = new TopologyBuilder().setTopologyId(new TopologyId(TOPOLOGY_ID)).build();
143         final NetworkTopology networkTopology = new NetworkTopologyBuilder().build();
144         verify(wtx).merge(LogicalDatastoreType.CONFIGURATION, networkTopologyId, networkTopology);
145         verify(wtx).merge(LogicalDatastoreType.OPERATIONAL, networkTopologyId, networkTopology);
146         verify(wtx).merge(LogicalDatastoreType.CONFIGURATION,
147                 networkTopologyId.child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID))), topo);
148         verify(wtx).merge(LogicalDatastoreType.OPERATIONAL,
149                 networkTopologyId.child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID))), topo);
150     }
151
152     @Test
153     public void testOnDataTreeChange() {
154         final DataObjectModification<Node> newNode = mock(DataObjectModification.class);
155         when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);
156
157         NodeKey key = new NodeKey(NODE_ID);
158         PathArgument pa = IdentifiableItem.of(Node.class, key);
159         when(newNode.getIdentifier()).thenReturn(pa);
160
161         final NodeBuilder nn = new NodeBuilder()
162                 .withKey(key)
163                 .addAugmentation(new NetconfNodeBuilder()
164                     .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
165                     .setPort(new PortNumber(Uint16.valueOf(9999)))
166                     .setReconnectOnChangedSchema(true)
167                     .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
168                     .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
169                     .setKeepaliveDelay(Uint32.valueOf(1000))
170                     .setTcpOnly(true)
171                     .setCredentials(new LoginPasswordBuilder()
172                         .setUsername("testuser")
173                         .setPassword("testpassword")
174                         .build())
175                     .build());
176
177         when(newNode.getDataAfter()).thenReturn(nn.build());
178
179         final Collection<DataTreeModification<Node>> changes = new HashSet<>();
180         final DataTreeModification<Node> ch = mock(DataTreeModification.class);
181         when(ch.getRootNode()).thenReturn(newNode);
182         changes.add(ch);
183         spyTopology.onDataTreeChanged(changes);
184         verify(spyTopology).connectNode(NetconfTopologyImpl.getNodeId(pa), nn.build());
185
186         when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE);
187         spyTopology.onDataTreeChanged(changes);
188         verify(spyTopology).disconnectNode(NetconfTopologyImpl.getNodeId(pa));
189
190         when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED);
191         spyTopology.onDataTreeChanged(changes);
192
193         //one in previous creating and deleting node and one in updating
194         verify(spyTopology, times(2)).disconnectNode(NetconfTopologyImpl.getNodeId(pa));
195         verify(spyTopology, times(2)).connectNode(NetconfTopologyImpl.getNodeId(pa), nn.build());
196     }
197
198     @Test
199     public void testGetClientConfig() {
200         final NetconfClientSessionListener sessionListener = mock(NetconfClientSessionListener.class);
201         final NetconfNodeBuilder nodeBuilder = new NetconfNodeBuilder()
202                 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
203                 .setPort(new PortNumber(Uint16.valueOf(9999)))
204                 .setReconnectOnChangedSchema(true)
205                 .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
206                 .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
207                 .setKeepaliveDelay(Uint32.valueOf(1000))
208                 .setCredentials(new LoginPasswordBuilder().setUsername("testuser").setPassword("testpassword").build())
209                 .setMaxConnectionAttempts(Uint32.ZERO)
210                 .setSleepFactor(Decimal64.valueOf("1.5"))
211                 .setConnectionTimeoutMillis(Uint32.valueOf(20000));
212
213         final NetconfReconnectingClientConfiguration configuration =
214                 spyTopology.getClientConfig(sessionListener, nodeBuilder.setTcpOnly(true).build());
215         assertEquals(NetconfClientConfiguration.NetconfClientProtocol.TCP, configuration.getProtocol());
216         assertNotNull(configuration.getAuthHandler());
217         assertNull(configuration.getSslHandlerFactory());
218
219         final NetconfReconnectingClientConfiguration configuration2 =
220                 spyTopology.getClientConfig(sessionListener, nodeBuilder.setTcpOnly(false).build());
221         assertEquals(NetconfClientConfiguration.NetconfClientProtocol.SSH, configuration2.getProtocol());
222         assertNotNull(configuration2.getAuthHandler());
223         assertNull(configuration2.getSslHandlerFactory());
224
225         final NetconfReconnectingClientConfiguration configuration3 =
226                 spyTopology.getClientConfig(sessionListener, nodeBuilder
227                         .setProtocol(new ProtocolBuilder().setName(Name.SSH).build()).build());
228         assertEquals(NetconfClientConfiguration.NetconfClientProtocol.SSH, configuration3.getProtocol());
229         assertNotNull(configuration3.getAuthHandler());
230         assertNull(configuration3.getSslHandlerFactory());
231
232         final NetconfReconnectingClientConfiguration configuration4 =
233                 spyTopology.getClientConfig(sessionListener, nodeBuilder
234                         .setProtocol(new ProtocolBuilder().setName(Name.TLS).build()).build());
235         assertEquals(NetconfClientConfiguration.NetconfClientProtocol.TLS, configuration4.getProtocol());
236         assertNull(configuration4.getAuthHandler());
237         assertNotNull(configuration4.getSslHandlerFactory());
238     }
239
240     public static class TestingNetconfTopologyImpl extends NetconfTopologyImpl {
241         private static final BaseNetconfSchemas BASE_SCHEMAS;
242
243         static {
244             try {
245                 BASE_SCHEMAS = new DefaultBaseNetconfSchemas(new DefaultYangParserFactory());
246             } catch (YangParserException e) {
247                 throw new ExceptionInInitializerError(e);
248             }
249         }
250
251         public TestingNetconfTopologyImpl(final String topologyId, final NetconfClientDispatcher clientDispatcher,
252                                           final EventExecutor eventExecutor,
253                                           final ScheduledThreadPool keepaliveExecutor,
254                                           final ThreadPool processingExecutor,
255                                           final SchemaResourceManager schemaRepositoryProvider,
256                                           final DataBroker dataBroker, final DOMMountPointService mountPointService,
257                                           final AAAEncryptionService encryptionService,
258                                           final RpcProviderService rpcProviderService) {
259             super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor,
260                   processingExecutor, schemaRepositoryProvider, dataBroker,
261                   mountPointService, encryptionService, rpcProviderService, BASE_SCHEMAS);
262         }
263
264         @Override
265         public ListenableFuture<NetconfDeviceCapabilities> connectNode(final NodeId nodeId, final Node configNode) {
266             return Futures.immediateFuture(new NetconfDeviceCapabilities());
267         }
268
269         @Override
270         public ListenableFuture<Void> disconnectNode(final NodeId nodeId) {
271             return Futures.immediateFuture(null);
272         }
273     }
274
275     @Test
276     public void hideCredentialsTest() {
277         final String userName = "admin";
278         final String password = "pa$$word";
279         final Node node = new NodeBuilder()
280                 .addAugmentation(new NetconfNodeBuilder()
281                     .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
282                     .setPort(new PortNumber(Uint16.valueOf(9999)))
283                     .setReconnectOnChangedSchema(true)
284                     .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
285                     .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
286                     .setKeepaliveDelay(Uint32.valueOf(1000))
287                     .setTcpOnly(false)
288                     .setProtocol(new ProtocolBuilder().setName(Name.TLS).build())
289                     .setCredentials(new LoginPasswordBuilder()
290                         .setUsername(userName)
291                         .setPassword(password)
292                         .build())
293                     .build())
294                 .setNodeId(NodeId.getDefaultInstance("junos"))
295                 .build();
296         final String transformedNetconfNode = AbstractNetconfTopology.hideCredentials(node);
297         assertTrue(transformedNetconfNode.contains("credentials=***"));
298         assertFalse(transformedNetconfNode.contains(userName));
299         assertFalse(transformedNetconfNode.contains(password));
300     }
301 }