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