e083b5446b059be9474d002c09ff2dc103f68d39
[netconf.git] / netconf / netconf-topology / 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
9 package org.opendaylight.netconf.topology.impl;
10
11 import static org.mockito.Matchers.any;
12 import static org.mockito.Mockito.doNothing;
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
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.common.api.data.TransactionCommitFailedException;
42 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
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.yang.binding.DataObject;
69 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
70 import org.opendaylight.yangtools.yang.parser.repo.SharedSchemaRepository;
71
72 public class NetconfTopologyImplTest {
73
74     private static final NodeId NODE_ID = new NodeId("testing-node");
75     private static final String TOPOLOGY_ID = "testing-topology";
76
77     @Mock
78     private NetconfClientDispatcher mockedClientDispatcher;
79
80     @Mock
81     private EventExecutor mockedEventExecutor;
82
83     @Mock
84     private ScheduledThreadPool mockedKeepaliveExecutor;
85
86     @Mock
87     private ThreadPool mockedProcessingExecutor;
88
89     @Mock
90     private SchemaRepositoryProvider mockedSchemaRepositoryProvider;
91
92     @Mock
93     private DataBroker dataBroker;
94
95     @Mock
96     private DOMMountPointService mountPointService;
97
98     @Mock
99     private AAAEncryptionService encryptionService;
100
101     private TestingNetconfTopologyImpl topology;
102     private TestingNetconfTopologyImpl spyTopology;
103
104     @Before
105     public void setUp() {
106         MockitoAnnotations.initMocks(this);
107
108         when(mockedSchemaRepositoryProvider.getSharedSchemaRepository())
109                 .thenReturn(new SharedSchemaRepository("testingSharedSchemaRepo"));
110         when(mockedProcessingExecutor.getExecutor()).thenReturn(MoreExecutors.newDirectExecutorService());
111         final Future future = new SucceededFuture(ImmediateEventExecutor.INSTANCE, new NetconfDeviceCapabilities());
112         when(mockedClientDispatcher.createReconnectingClient(any(NetconfReconnectingClientConfiguration.class)))
113                 .thenReturn(future);
114
115         topology = new TestingNetconfTopologyImpl(TOPOLOGY_ID, mockedClientDispatcher,
116                 mockedEventExecutor, mockedKeepaliveExecutor, mockedProcessingExecutor, mockedSchemaRepositoryProvider,
117                 dataBroker, mountPointService, encryptionService);
118
119         spyTopology = spy(topology);
120     }
121
122     @Test
123     public void testInit() {
124         final WriteTransaction wtx = mock(WriteTransaction.class);
125         when(dataBroker.newWriteOnlyTransaction()).thenReturn(wtx);
126         doNothing().when(wtx)
127                 .merge(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(DataObject.class));
128         when(wtx.submit()).thenReturn(Futures.<Void, TransactionCommitFailedException>immediateCheckedFuture(null));
129         topology.init();
130
131         //verify initialization of topology
132         final InstanceIdentifier<NetworkTopology> networkTopologyId =
133                 InstanceIdentifier.builder(NetworkTopology.class).build();
134         final Topology topo = new TopologyBuilder().setTopologyId(new TopologyId(TOPOLOGY_ID)).build();
135         final NetworkTopology networkTopology = new NetworkTopologyBuilder().build();
136         verify(wtx).merge(LogicalDatastoreType.CONFIGURATION, networkTopologyId, networkTopology);
137         verify(wtx).merge(LogicalDatastoreType.OPERATIONAL, networkTopologyId, networkTopology);
138         verify(wtx).merge(LogicalDatastoreType.CONFIGURATION,
139                 networkTopologyId.child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID))), topo);
140         verify(wtx).merge(LogicalDatastoreType.OPERATIONAL,
141                 networkTopologyId.child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID))), topo);
142     }
143
144     @Test
145     public void testOnDataTreeChange() {
146
147         final DataObjectModification<Node> newNode = mock(DataObjectModification.class);
148         when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);
149
150         InstanceIdentifier.PathArgument pa = null;
151
152         for (final InstanceIdentifier.PathArgument p
153                 : TopologyUtil.createTopologyListPath(TOPOLOGY_ID)
154                     .child(Node.class, new NodeKey(NODE_ID)).getPathArguments()) {
155             pa = p;
156         }
157
158         when(newNode.getIdentifier()).thenReturn(pa);
159
160
161         final NetconfNode testingNode = new NetconfNodeBuilder()
162                 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
163                 .setPort(new PortNumber(9999))
164                 .setReconnectOnChangedSchema(true)
165                 .setDefaultRequestTimeoutMillis(1000L)
166                 .setBetweenAttemptsTimeoutMillis(100)
167                 .setKeepaliveDelay(1000L)
168                 .setTcpOnly(true)
169                 .setCredentials(new LoginPasswordBuilder()
170                         .setUsername("testuser").setPassword("testpassword").build())
171                 .build();
172
173         final NodeBuilder nn = new NodeBuilder().addAugmentation(NetconfNode.class, testingNode);
174
175         when(newNode.getDataAfter()).thenReturn(nn.build());
176
177
178         final Collection<DataTreeModification<Node>> changes = Sets.newHashSet();
179         final DataTreeModification<Node> ch = mock(DataTreeModification.class);
180         when(ch.getRootNode()).thenReturn(newNode);
181         changes.add(ch);
182         spyTopology.onDataTreeChanged(changes);
183         verify(spyTopology).connectNode(TopologyUtil.getNodeId(pa), nn.build());
184
185         when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE);
186         spyTopology.onDataTreeChanged(changes);
187         verify(spyTopology).disconnectNode(TopologyUtil.getNodeId(pa));
188
189         when(newNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED);
190         spyTopology.onDataTreeChanged(changes);
191
192         //one in previous creating and deleting node and one in updating
193         verify(spyTopology, times(2)).disconnectNode(TopologyUtil.getNodeId(pa));
194         verify(spyTopology, times(2)).connectNode(TopologyUtil.getNodeId(pa), nn.build());
195
196
197     }
198
199     @Test
200     public void testGetClientConfig() {
201         final NetconfClientSessionListener sessionListener = mock(NetconfClientSessionListener.class);
202
203         final NetconfNode testingNode = new NetconfNodeBuilder()
204                 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
205                 .setPort(new PortNumber(9999))
206                 .setReconnectOnChangedSchema(true)
207                 .setDefaultRequestTimeoutMillis(1000L)
208                 .setBetweenAttemptsTimeoutMillis(100)
209                 .setKeepaliveDelay(1000L)
210                 .setTcpOnly(true)
211                 .setCredentials(new LoginPasswordBuilder()
212                         .setUsername("testuser").setPassword("testpassword").build())
213                 .build();
214         final NetconfReconnectingClientConfiguration configuration =
215                 spyTopology.getClientConfig(sessionListener, testingNode);
216         Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.TCP, configuration.getProtocol());
217         Assert.assertNotNull(configuration.getAuthHandler());
218         Assert.assertNull(configuration.getSslHandlerFactory());
219
220
221         final NetconfNode testingNode2 = new NetconfNodeBuilder()
222                 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
223                 .setPort(new PortNumber(9999))
224                 .setReconnectOnChangedSchema(true)
225                 .setDefaultRequestTimeoutMillis(1000L)
226                 .setBetweenAttemptsTimeoutMillis(100)
227                 .setKeepaliveDelay(1000L)
228                 .setTcpOnly(false)
229                 .setCredentials(new LoginPasswordBuilder()
230                         .setUsername("testuser").setPassword("testpassword").build())
231                 .build();
232         final NetconfReconnectingClientConfiguration configuration2 =
233                 spyTopology.getClientConfig(sessionListener, testingNode2);
234         Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.SSH, configuration2.getProtocol());
235         Assert.assertNotNull(configuration2.getAuthHandler());
236         Assert.assertNull(configuration2.getSslHandlerFactory());
237
238
239         final NetconfNode testingNode3 = new NetconfNodeBuilder()
240                 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
241                 .setPort(new PortNumber(9999))
242                 .setReconnectOnChangedSchema(true)
243                 .setDefaultRequestTimeoutMillis(1000L)
244                 .setBetweenAttemptsTimeoutMillis(100)
245                 .setKeepaliveDelay(1000L)
246                 .setTcpOnly(false)
247                 .setProtocol(new ProtocolBuilder().setName(Name.SSH).build())
248                 .setCredentials(new LoginPasswordBuilder()
249                         .setUsername("testuser").setPassword("testpassword").build())
250                 .build();
251         final NetconfReconnectingClientConfiguration configuration3 =
252                 spyTopology.getClientConfig(sessionListener, testingNode3);
253         Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.SSH, configuration3.getProtocol());
254         Assert.assertNotNull(configuration3.getAuthHandler());
255         Assert.assertNull(configuration3.getSslHandlerFactory());
256
257
258         final NetconfNode testingNode4 = new NetconfNodeBuilder()
259                 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
260                 .setPort(new PortNumber(9999))
261                 .setReconnectOnChangedSchema(true)
262                 .setDefaultRequestTimeoutMillis(1000L)
263                 .setBetweenAttemptsTimeoutMillis(100)
264                 .setKeepaliveDelay(1000L)
265                 .setTcpOnly(false)
266                 .setProtocol(new ProtocolBuilder().setName(Name.TLS).build())
267                 .setCredentials(new LoginPasswordBuilder()
268                         .setUsername("testuser").setPassword("testpassword").build())
269                 .build();
270         final NetconfReconnectingClientConfiguration configuration4 =
271                 spyTopology.getClientConfig(sessionListener, testingNode4);
272         Assert.assertEquals(NetconfClientConfiguration.NetconfClientProtocol.TLS, configuration4.getProtocol());
273         Assert.assertNull(configuration4.getAuthHandler());
274         Assert.assertNotNull(configuration4.getSslHandlerFactory());
275     }
276
277     public static class TestingNetconfTopologyImpl extends NetconfTopologyImpl {
278
279         public TestingNetconfTopologyImpl(final String topologyId, final NetconfClientDispatcher clientDispatcher,
280                                           final EventExecutor eventExecutor,
281                                           final ScheduledThreadPool keepaliveExecutor,
282                                           final ThreadPool processingExecutor,
283                                           final SchemaRepositoryProvider schemaRepositoryProvider,
284                                           final DataBroker dataBroker, final DOMMountPointService mountPointService,
285                                           final AAAEncryptionService encryptionService) {
286             super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor,
287                     processingExecutor, schemaRepositoryProvider, dataBroker,
288                   mountPointService, encryptionService);
289         }
290
291         @Override
292         public ListenableFuture<NetconfDeviceCapabilities> connectNode(final NodeId nodeId, final Node configNode) {
293             return Futures.immediateFuture(new NetconfDeviceCapabilities());
294         }
295
296         @Override
297         public ListenableFuture<Void> disconnectNode(final NodeId nodeId) {
298             return Futures.immediateFuture(null);
299         }
300     }
301 }