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 java.util.List;
16 import java.util.concurrent.TimeUnit;
17 import org.junit.jupiter.api.Test;
18 import org.junit.jupiter.api.extension.ExtendWith;
19 import org.mockito.Mock;
20 import org.mockito.junit.jupiter.MockitoExtension;
21 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
22 import org.opendaylight.mdsal.binding.api.DataBroker;
23 import org.opendaylight.mdsal.binding.api.DataObjectModification;
24 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
25 import org.opendaylight.mdsal.binding.api.DataTreeModification;
26 import org.opendaylight.mdsal.binding.api.RpcProviderService;
27 import org.opendaylight.mdsal.binding.api.WriteTransaction;
28 import org.opendaylight.mdsal.common.api.CommitInfo;
29 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
30 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
31 import org.opendaylight.netconf.client.NetconfClientFactory;
32 import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemaProvider;
33 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
34 import org.opendaylight.netconf.client.mdsal.impl.DefaultBaseNetconfSchemaProvider;
35 import org.opendaylight.netconf.common.NetconfTimer;
36 import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory;
37 import org.opendaylight.netconf.topology.spi.NetconfTopologySchemaAssembler;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev240120.credentials.credentials.LoginPwUnencryptedBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev240120.credentials.credentials.login.pw.unencrypted.LoginPasswordUnencryptedBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev231121.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 NetconfClientFactory mockedClientFactory;
69 private NetconfTimer mockedTimer;
71 private SchemaResourceManager mockedResourceManager;
73 private DataBroker dataBroker;
75 private DOMMountPointService mountPointService;
77 private AAAEncryptionService encryptionService;
79 private RpcProviderService rpcProviderService;
81 private NetconfClientConfigurationBuilderFactory builderFactory;
83 private WriteTransaction wtx;
85 private DataObjectModification<Node> objMod;
87 private DataTreeModification<Node> treeMod;
90 void testOnDataTreeChange() throws Exception {
91 doReturn(wtx).when(dataBroker).newWriteOnlyTransaction();
92 doReturn(CommitInfo.emptyFluentFuture()).when(wtx).commit();
94 try (var schemaAssembler = new NetconfTopologySchemaAssembler(1, 1, 0, TimeUnit.SECONDS)) {
95 final var topology = new TestingNetconfTopologyImpl(TOPOLOGY_KEY.getTopologyId().getValue(),
96 mockedClientFactory, mockedTimer, schemaAssembler, mockedResourceManager, dataBroker, mountPointService,
97 encryptionService, builderFactory, rpcProviderService,
98 new DefaultBaseNetconfSchemaProvider(new DefaultYangParserFactory()));
99 //verify initialization of topology
100 verify(wtx).merge(LogicalDatastoreType.OPERATIONAL, TOPOLOGY_PATH,
101 new TopologyBuilder().withKey(TOPOLOGY_KEY).build());
103 final var spyTopology = spy(topology);
105 final var key = new NodeKey(new NodeId("testing-node"));
106 final var node = new NodeBuilder()
108 .addAugmentation(new NetconfNodeBuilder()
109 .setLockDatastore(true)
110 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
111 .setPort(new PortNumber(Uint16.valueOf(9999)))
112 .setReconnectOnChangedSchema(true)
113 .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
114 .setMinBackoffMillis(Uint16.valueOf(100))
115 .setKeepaliveDelay(Uint32.valueOf(1000))
117 .setCredentials(new LoginPwUnencryptedBuilder()
118 .setLoginPasswordUnencrypted(new LoginPasswordUnencryptedBuilder()
119 .setUsername("testuser")
120 .setPassword("testpassword")
126 doReturn(DataObjectModification.ModificationType.WRITE).when(objMod).modificationType();
127 doReturn(node).when(objMod).dataAfter();
129 doReturn(DataTreeIdentifier.of(LogicalDatastoreType.CONFIGURATION,
130 TOPOLOGY_PATH.child(Node.class, key))).when(treeMod).getRootPath();
131 final var changes = List.of(treeMod);
133 doReturn(objMod).when(treeMod).getRootNode();
134 spyTopology.onDataTreeChanged(changes);
135 verify(spyTopology).ensureNode(node);
137 doReturn(DataObjectModification.ModificationType.DELETE).when(objMod).modificationType();
138 spyTopology.onDataTreeChanged(changes);
139 verify(spyTopology).deleteNode(key.getNodeId());
141 doReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED).when(objMod).modificationType();
142 spyTopology.onDataTreeChanged(changes);
144 // one in previous creating and deleting node and one in updating
145 verify(spyTopology, times(2)).ensureNode(node);
149 private static class TestingNetconfTopologyImpl extends NetconfTopologyImpl {
150 TestingNetconfTopologyImpl(final String topologyId, final NetconfClientFactory clientFactory,
151 final NetconfTimer timer, final NetconfTopologySchemaAssembler schemaAssembler,
152 final SchemaResourceManager schemaRepositoryProvider, final DataBroker dataBroker,
153 final DOMMountPointService mountPointService, final AAAEncryptionService encryptionService,
154 final NetconfClientConfigurationBuilderFactory builderFactory,
155 final RpcProviderService rpcProviderService, final BaseNetconfSchemaProvider baseSchemaProvider) {
156 super(topologyId, clientFactory, timer, schemaAssembler, schemaRepositoryProvider, dataBroker,
157 mountPointService, encryptionService, builderFactory, rpcProviderService, baseSchemaProvider);
161 public void ensureNode(final Node configNode) {
166 public void deleteNode(final NodeId nodeId) {