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