2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.netconf.topology.impl;
10 import static org.mockito.Mockito.doReturn;
11 import static org.mockito.Mockito.spy;
12 import static org.mockito.Mockito.times;
13 import static org.mockito.Mockito.verify;
15 import com.google.common.util.concurrent.MoreExecutors;
16 import io.netty.util.concurrent.EventExecutor;
17 import java.util.List;
18 import org.junit.jupiter.api.Test;
19 import org.junit.jupiter.api.extension.ExtendWith;
20 import org.mockito.Mock;
21 import org.mockito.junit.jupiter.MockitoExtension;
22 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
23 import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
24 import org.opendaylight.controller.config.threadpool.ThreadPool;
25 import org.opendaylight.mdsal.binding.api.DataBroker;
26 import org.opendaylight.mdsal.binding.api.DataObjectModification;
27 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
28 import org.opendaylight.mdsal.binding.api.DataTreeModification;
29 import org.opendaylight.mdsal.binding.api.RpcProviderService;
30 import org.opendaylight.mdsal.binding.api.WriteTransaction;
31 import org.opendaylight.mdsal.common.api.CommitInfo;
32 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
33 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
34 import org.opendaylight.netconf.client.NetconfClientFactory;
35 import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
36 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
37 import org.opendaylight.netconf.client.mdsal.impl.DefaultBaseNetconfSchemas;
38 import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev231025.credentials.credentials.LoginPwUnencryptedBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev231025.credentials.credentials.login.pw.unencrypted.LoginPasswordUnencryptedBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev221225.NetconfNodeBuilder;
46 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
47 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
48 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
49 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
50 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
51 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
52 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
53 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
54 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
55 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
56 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
57 import org.opendaylight.yangtools.yang.common.Uint16;
58 import org.opendaylight.yangtools.yang.common.Uint32;
59 import org.opendaylight.yangtools.yang.parser.impl.DefaultYangParserFactory;
61 @ExtendWith(MockitoExtension.class)
62 class NetconfTopologyImplTest {
63 private static final TopologyKey TOPOLOGY_KEY = new TopologyKey(new TopologyId("testing-topology"));
64 private static final KeyedInstanceIdentifier<Topology, TopologyKey> TOPOLOGY_PATH =
65 InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, TOPOLOGY_KEY).build();
68 private NetconfClientFactory mockedClientFactory;
70 private EventExecutor mockedEventExecutor;
72 private ScheduledThreadPool mockedKeepaliveExecutor;
74 private ThreadPool mockedProcessingExecutor;
76 private SchemaResourceManager mockedResourceManager;
78 private DataBroker dataBroker;
80 private DOMMountPointService mountPointService;
82 private AAAEncryptionService encryptionService;
84 private RpcProviderService rpcProviderService;
86 private NetconfClientConfigurationBuilderFactory builderFactory;
88 private WriteTransaction wtx;
90 private DataObjectModification<Node> objMod;
92 private DataTreeModification<Node> treeMod;
94 private TestingNetconfTopologyImpl topology;
95 private TestingNetconfTopologyImpl spyTopology;
98 void testOnDataTreeChange() throws Exception {
99 doReturn(MoreExecutors.newDirectExecutorService()).when(mockedProcessingExecutor).getExecutor();
100 doReturn(wtx).when(dataBroker).newWriteOnlyTransaction();
101 doReturn(CommitInfo.emptyFluentFuture()).when(wtx).commit();
103 topology = new TestingNetconfTopologyImpl(TOPOLOGY_KEY.getTopologyId().getValue(), mockedClientFactory,
104 mockedEventExecutor, mockedKeepaliveExecutor, mockedProcessingExecutor, mockedResourceManager, dataBroker,
105 mountPointService, encryptionService, builderFactory, rpcProviderService,
106 new DefaultBaseNetconfSchemas(new DefaultYangParserFactory()));
107 //verify initialization of topology
108 verify(wtx).merge(LogicalDatastoreType.OPERATIONAL, TOPOLOGY_PATH,
109 new TopologyBuilder().withKey(TOPOLOGY_KEY).build());
111 spyTopology = spy(topology);
113 final var key = new NodeKey(new NodeId("testing-node"));
114 final var node = new NodeBuilder()
116 .addAugmentation(new NetconfNodeBuilder()
117 .setLockDatastore(true)
118 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
119 .setPort(new PortNumber(Uint16.valueOf(9999)))
120 .setReconnectOnChangedSchema(true)
121 .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
122 .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
123 .setKeepaliveDelay(Uint32.valueOf(1000))
125 .setCredentials(new LoginPwUnencryptedBuilder()
126 .setLoginPasswordUnencrypted(new LoginPasswordUnencryptedBuilder()
127 .setUsername("testuser")
128 .setPassword("testpassword")
134 doReturn(DataObjectModification.ModificationType.WRITE).when(objMod).getModificationType();
135 doReturn(node).when(objMod).getDataAfter();
137 doReturn(DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION, TOPOLOGY_PATH.child(Node.class, key)))
138 .when(treeMod).getRootPath();
139 final var changes = List.of(treeMod);
141 doReturn(objMod).when(treeMod).getRootNode();
142 spyTopology.onDataTreeChanged(changes);
143 verify(spyTopology).ensureNode(node);
145 doReturn(DataObjectModification.ModificationType.DELETE).when(objMod).getModificationType();
146 spyTopology.onDataTreeChanged(changes);
147 verify(spyTopology).deleteNode(key.getNodeId());
149 doReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED).when(objMod).getModificationType();
150 spyTopology.onDataTreeChanged(changes);
152 // one in previous creating and deleting node and one in updating
153 verify(spyTopology, times(2)).ensureNode(node);
156 private static class TestingNetconfTopologyImpl extends NetconfTopologyImpl {
157 TestingNetconfTopologyImpl(final String topologyId, final NetconfClientFactory clientFactory,
158 final EventExecutor eventExecutor, final ScheduledThreadPool scheduledThreadPool,
159 final ThreadPool processingThreadPool, final SchemaResourceManager schemaRepositoryProvider,
160 final DataBroker dataBroker, final DOMMountPointService mountPointService,
161 final AAAEncryptionService encryptionService,
162 final NetconfClientConfigurationBuilderFactory builderFactory,
163 final RpcProviderService rpcProviderService, final BaseNetconfSchemas baseSchemas) {
164 super(topologyId, clientFactory, eventExecutor, scheduledThreadPool, processingThreadPool,
165 schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, builderFactory,
166 rpcProviderService, baseSchemas);
170 public void ensureNode(final Node configNode) {
175 public void deleteNode(final NodeId nodeId) {