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.NetconfClientDispatcher;
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.rev230430.credentials.credentials.LoginPasswordBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev221225.NetconfNodeBuilder;
45 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
46 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
47 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
48 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
49 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
50 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
51 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
52 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
53 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
54 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
55 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
56 import org.opendaylight.yangtools.yang.common.Uint16;
57 import org.opendaylight.yangtools.yang.common.Uint32;
58 import org.opendaylight.yangtools.yang.parser.impl.DefaultYangParserFactory;
60 @ExtendWith(MockitoExtension.class)
61 class NetconfTopologyImplTest {
62 private static final TopologyKey TOPOLOGY_KEY = new TopologyKey(new TopologyId("testing-topology"));
63 private static final KeyedInstanceIdentifier<Topology, TopologyKey> TOPOLOGY_PATH =
64 InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class, TOPOLOGY_KEY).build();
67 private NetconfClientDispatcher mockedClientDispatcher;
69 private EventExecutor mockedEventExecutor;
71 private ScheduledThreadPool mockedKeepaliveExecutor;
73 private ThreadPool mockedProcessingExecutor;
75 private SchemaResourceManager mockedResourceManager;
77 private DataBroker dataBroker;
79 private DOMMountPointService mountPointService;
81 private AAAEncryptionService encryptionService;
83 private RpcProviderService rpcProviderService;
85 private NetconfClientConfigurationBuilderFactory builderFactory;
87 private WriteTransaction wtx;
89 private DataObjectModification<Node> objMod;
91 private DataTreeModification<Node> treeMod;
93 private TestingNetconfTopologyImpl topology;
94 private TestingNetconfTopologyImpl spyTopology;
97 void testOnDataTreeChange() throws Exception {
98 doReturn(MoreExecutors.newDirectExecutorService()).when(mockedProcessingExecutor).getExecutor();
99 doReturn(wtx).when(dataBroker).newWriteOnlyTransaction();
100 doReturn(CommitInfo.emptyFluentFuture()).when(wtx).commit();
102 topology = new TestingNetconfTopologyImpl(TOPOLOGY_KEY.getTopologyId().getValue(), mockedClientDispatcher,
103 mockedEventExecutor, mockedKeepaliveExecutor, mockedProcessingExecutor, mockedResourceManager, dataBroker,
104 mountPointService, encryptionService, builderFactory, rpcProviderService,
105 new DefaultBaseNetconfSchemas(new DefaultYangParserFactory()));
106 //verify initialization of topology
107 verify(wtx).merge(LogicalDatastoreType.OPERATIONAL, TOPOLOGY_PATH,
108 new TopologyBuilder().withKey(TOPOLOGY_KEY).build());
110 spyTopology = spy(topology);
112 final var key = new NodeKey(new NodeId("testing-node"));
113 final var node = new NodeBuilder()
115 .addAugmentation(new NetconfNodeBuilder()
116 .setLockDatastore(true)
117 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
118 .setPort(new PortNumber(Uint16.valueOf(9999)))
119 .setReconnectOnChangedSchema(true)
120 .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
121 .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
122 .setKeepaliveDelay(Uint32.valueOf(1000))
124 .setCredentials(new LoginPasswordBuilder()
125 .setUsername("testuser")
126 .setPassword("testpassword")
131 doReturn(DataObjectModification.ModificationType.WRITE).when(objMod).getModificationType();
132 doReturn(node).when(objMod).getDataAfter();
134 doReturn(DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION, TOPOLOGY_PATH.child(Node.class, key)))
135 .when(treeMod).getRootPath();
136 final var changes = List.of(treeMod);
138 doReturn(objMod).when(treeMod).getRootNode();
139 spyTopology.onDataTreeChanged(changes);
140 verify(spyTopology).ensureNode(node);
142 doReturn(DataObjectModification.ModificationType.DELETE).when(objMod).getModificationType();
143 spyTopology.onDataTreeChanged(changes);
144 verify(spyTopology).deleteNode(key.getNodeId());
146 doReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED).when(objMod).getModificationType();
147 spyTopology.onDataTreeChanged(changes);
149 // one in previous creating and deleting node and one in updating
150 verify(spyTopology, times(2)).ensureNode(node);
153 private static class TestingNetconfTopologyImpl extends NetconfTopologyImpl {
154 TestingNetconfTopologyImpl(final String topologyId, final NetconfClientDispatcher clientDispatcher,
155 final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor,
156 final ThreadPool processingExecutor, final SchemaResourceManager schemaRepositoryProvider,
157 final DataBroker dataBroker, final DOMMountPointService mountPointService,
158 final AAAEncryptionService encryptionService,
159 final NetconfClientConfigurationBuilderFactory builderFactory,
160 final RpcProviderService rpcProviderService, final BaseNetconfSchemas baseSchemas) {
161 super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor, processingExecutor,
162 schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, builderFactory,
163 rpcProviderService, baseSchemas);
167 public void ensureNode(final Node configNode) {
172 public void deleteNode(final NodeId nodeId) {