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 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
117 .setPort(new PortNumber(Uint16.valueOf(9999)))
118 .setReconnectOnChangedSchema(true)
119 .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
120 .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
121 .setKeepaliveDelay(Uint32.valueOf(1000))
123 .setCredentials(new LoginPasswordBuilder()
124 .setUsername("testuser")
125 .setPassword("testpassword")
130 doReturn(DataObjectModification.ModificationType.WRITE).when(objMod).getModificationType();
131 doReturn(node).when(objMod).getDataAfter();
133 doReturn(DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION, TOPOLOGY_PATH.child(Node.class, key)))
134 .when(treeMod).getRootPath();
135 final var changes = List.of(treeMod);
137 doReturn(objMod).when(treeMod).getRootNode();
138 spyTopology.onDataTreeChanged(changes);
139 verify(spyTopology).ensureNode(node);
141 doReturn(DataObjectModification.ModificationType.DELETE).when(objMod).getModificationType();
142 spyTopology.onDataTreeChanged(changes);
143 verify(spyTopology).deleteNode(key.getNodeId());
145 doReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED).when(objMod).getModificationType();
146 spyTopology.onDataTreeChanged(changes);
148 // one in previous creating and deleting node and one in updating
149 verify(spyTopology, times(2)).ensureNode(node);
152 private static class TestingNetconfTopologyImpl extends NetconfTopologyImpl {
153 TestingNetconfTopologyImpl(final String topologyId, final NetconfClientDispatcher clientDispatcher,
154 final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor,
155 final ThreadPool processingExecutor, final SchemaResourceManager schemaRepositoryProvider,
156 final DataBroker dataBroker, final DOMMountPointService mountPointService,
157 final AAAEncryptionService encryptionService,
158 final NetconfClientConfigurationBuilderFactory builderFactory,
159 final RpcProviderService rpcProviderService, final BaseNetconfSchemas baseSchemas) {
160 super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor, processingExecutor,
161 schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, builderFactory,
162 rpcProviderService, baseSchemas);
166 public void ensureNode(final Node configNode) {
171 public void deleteNode(final NodeId nodeId) {