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.mock;
12 import static org.mockito.Mockito.spy;
13 import static org.mockito.Mockito.times;
14 import static org.mockito.Mockito.verify;
16 import com.google.common.util.concurrent.MoreExecutors;
17 import io.netty.util.concurrent.EventExecutor;
18 import java.util.Collection;
19 import java.util.HashSet;
20 import org.junit.Before;
21 import org.junit.Test;
22 import org.junit.runner.RunWith;
23 import org.mockito.Mock;
24 import org.mockito.junit.MockitoJUnitRunner;
25 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
26 import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
27 import org.opendaylight.controller.config.threadpool.ThreadPool;
28 import org.opendaylight.mdsal.binding.api.DataBroker;
29 import org.opendaylight.mdsal.binding.api.DataObjectModification;
30 import org.opendaylight.mdsal.binding.api.DataTreeModification;
31 import org.opendaylight.mdsal.binding.api.RpcProviderService;
32 import org.opendaylight.mdsal.binding.api.WriteTransaction;
33 import org.opendaylight.mdsal.common.api.CommitInfo;
34 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
35 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
36 import org.opendaylight.netconf.client.NetconfClientDispatcher;
37 import org.opendaylight.netconf.client.mdsal.api.BaseNetconfSchemas;
38 import org.opendaylight.netconf.client.mdsal.api.SchemaResourceManager;
39 import org.opendaylight.netconf.client.mdsal.impl.DefaultBaseNetconfSchemas;
40 import org.opendaylight.netconf.topology.spi.NetconfClientConfigurationBuilderFactory;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.device.rev230430.credentials.credentials.LoginPasswordBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev221225.NetconfNodeBuilder;
47 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
48 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
49 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
50 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
51 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
52 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
53 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
54 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
55 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
56 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
57 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
58 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
59 import org.opendaylight.yangtools.yang.common.Uint16;
60 import org.opendaylight.yangtools.yang.common.Uint32;
61 import org.opendaylight.yangtools.yang.parser.api.YangParserException;
62 import org.opendaylight.yangtools.yang.parser.impl.DefaultYangParserFactory;
64 @RunWith(MockitoJUnitRunner.StrictStubs.class)
65 public class NetconfTopologyImplTest {
66 private static final NodeId NODE_ID = new NodeId("testing-node");
67 private static final String TOPOLOGY_ID = "testing-topology";
70 private NetconfClientDispatcher mockedClientDispatcher;
72 private EventExecutor mockedEventExecutor;
74 private ScheduledThreadPool mockedKeepaliveExecutor;
76 private ThreadPool mockedProcessingExecutor;
78 private SchemaResourceManager mockedResourceManager;
80 private DataBroker dataBroker;
82 private DOMMountPointService mountPointService;
84 private AAAEncryptionService encryptionService;
86 private RpcProviderService rpcProviderService;
88 private NetconfClientConfigurationBuilderFactory builderFactory;
90 private WriteTransaction wtx;
92 private TestingNetconfTopologyImpl topology;
93 private TestingNetconfTopologyImpl spyTopology;
97 doReturn(MoreExecutors.newDirectExecutorService()).when(mockedProcessingExecutor).getExecutor();
98 doReturn(wtx).when(dataBroker).newWriteOnlyTransaction();
99 doReturn(CommitInfo.emptyFluentFuture()).when(wtx).commit();
101 topology = new TestingNetconfTopologyImpl(TOPOLOGY_ID, mockedClientDispatcher, mockedEventExecutor,
102 mockedKeepaliveExecutor, mockedProcessingExecutor, mockedResourceManager, dataBroker, mountPointService,
103 encryptionService, builderFactory, rpcProviderService);
104 //verify initialization of topology
105 verify(wtx).merge(LogicalDatastoreType.OPERATIONAL, InstanceIdentifier.builder(NetworkTopology.class)
106 .child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID))).build(),
107 new TopologyBuilder().setTopologyId(new TopologyId(TOPOLOGY_ID)).build());
109 spyTopology = spy(topology);
113 public void testOnDataTreeChange() {
114 final DataObjectModification<Node> newNode = mock(DataObjectModification.class);
115 doReturn(DataObjectModification.ModificationType.WRITE).when(newNode).getModificationType();
117 NodeKey key = new NodeKey(NODE_ID);
118 PathArgument pa = IdentifiableItem.of(Node.class, key);
119 doReturn(pa).when(newNode).getIdentifier();
121 final NodeBuilder nn = new NodeBuilder()
123 .addAugmentation(new NetconfNodeBuilder()
124 .setHost(new Host(new IpAddress(new Ipv4Address("127.0.0.1"))))
125 .setPort(new PortNumber(Uint16.valueOf(9999)))
126 .setReconnectOnChangedSchema(true)
127 .setDefaultRequestTimeoutMillis(Uint32.valueOf(1000))
128 .setBetweenAttemptsTimeoutMillis(Uint16.valueOf(100))
129 .setKeepaliveDelay(Uint32.valueOf(1000))
131 .setCredentials(new LoginPasswordBuilder()
132 .setUsername("testuser")
133 .setPassword("testpassword")
136 doReturn(nn.build()).when(newNode).getDataAfter();
138 final Collection<DataTreeModification<Node>> changes = new HashSet<>();
139 final DataTreeModification<Node> ch = mock(DataTreeModification.class);
140 doReturn(newNode).when(ch).getRootNode();
142 spyTopology.onDataTreeChanged(changes);
143 verify(spyTopology).ensureNode(nn.build());
145 doReturn(DataObjectModification.ModificationType.DELETE).when(newNode).getModificationType();
146 spyTopology.onDataTreeChanged(changes);
147 verify(spyTopology).deleteNode(NetconfTopologyImpl.getNodeId(pa));
149 doReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED).when(newNode).getModificationType();
150 spyTopology.onDataTreeChanged(changes);
152 // one in previous creating and deleting node and one in updating
153 verify(spyTopology, times(2)).ensureNode(nn.build());
156 public static class TestingNetconfTopologyImpl extends NetconfTopologyImpl {
157 private static final BaseNetconfSchemas BASE_SCHEMAS;
161 BASE_SCHEMAS = new DefaultBaseNetconfSchemas(new DefaultYangParserFactory());
162 } catch (YangParserException e) {
163 throw new ExceptionInInitializerError(e);
167 public TestingNetconfTopologyImpl(final String topologyId, final NetconfClientDispatcher clientDispatcher,
168 final EventExecutor eventExecutor, final ScheduledThreadPool keepaliveExecutor,
169 final ThreadPool processingExecutor, final SchemaResourceManager schemaRepositoryProvider,
170 final DataBroker dataBroker, final DOMMountPointService mountPointService,
171 final AAAEncryptionService encryptionService,
172 final NetconfClientConfigurationBuilderFactory builderFactory,
173 final RpcProviderService rpcProviderService) {
174 super(topologyId, clientDispatcher, eventExecutor, keepaliveExecutor, processingExecutor,
175 schemaRepositoryProvider, dataBroker, mountPointService, encryptionService, builderFactory,
176 rpcProviderService, BASE_SCHEMAS);
180 public void ensureNode(final Node configNode) {
185 public void deleteNode(final NodeId nodeId) {