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.groupbasedpolicy.renderer.ios_xe_provider.impl.manager;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertTrue;
14 import static org.mockito.Matchers.any;
15 import static org.mockito.Mockito.mock;
16 import static org.mockito.Mockito.when;
17 import static org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus.Connected;
18 import static org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus.Connecting;
19 import static org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus.UnableToConnect;
21 import java.util.Arrays;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.List;
26 import javax.annotation.Nonnull;
28 import org.junit.Before;
29 import org.junit.Test;
30 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
31 import org.opendaylight.controller.md.sal.binding.api.MountPointService;
32 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
33 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
34 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
35 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
36 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
37 import org.opendaylight.groupbasedpolicy.test.CustomDataBrokerTest;
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.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererNodes;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNode;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilities;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapability;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapabilityBuilder;
51 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
52 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
53 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
54 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
55 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
56 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
57 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
58 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
59 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
61 import com.google.common.base.Optional;
62 import com.google.common.util.concurrent.CheckedFuture;
65 public class NodeManagerTest extends CustomDataBrokerTest {
67 private final NodeId NODE_NAME = new NodeId("testNode");
68 private final TopologyId TOPOLOGY_ID = new TopologyId("topology-netconf");
69 private final Ipv4Address IPv4_ADDRESS = new Ipv4Address("174.25.75.11");
70 private NodeManager nodeManager;
71 private DataBroker dataBroker;
75 public Collection<java.lang.Class<?>> getClassesFromModules() {
76 return Arrays.asList(Renderers.class, NetworkTopology.class, NetconfNode.class);
81 dataBroker = getDataBroker();
82 BindingAwareBroker.ProviderContext context = mock(BindingAwareBroker.ProviderContext.class);
83 MountPointService mountPointService = mock(MountPointService.class);
84 when(context.getSALService(any())).thenReturn(mountPointService);
85 nodeManager = new NodeManager(dataBroker, context);
89 public void testRegisterNewNode_connectingCase() throws Exception {
90 Node testNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
91 nodeManager.syncNodes(testNode, null);
92 List<RendererNode> result = rendererNodesReader();
93 assertTrue(result.isEmpty());
99 public void testRegisterNewNode_connectedCaseNoIpAddress() throws Exception {
100 Node testNode = createNode(Connected, null, NODE_NAME, Capabilities.None);
101 nodeManager.syncNodes(testNode, null);
102 List<RendererNode> result = rendererNodesReader();
103 assertTrue(result.isEmpty());
107 public void testRegisterNewNode_connectedCaseNullCapabilities() throws Exception {
108 Node testNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.None);
109 nodeManager.syncNodes(testNode, null);
110 List<RendererNode> result = rendererNodesReader();
111 assertTrue(result.isEmpty());
115 public void testRegisterNewNode_connectedCasePartialCapabilities() throws Exception {
116 Node testNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Partial);
117 nodeManager.syncNodes(testNode, null);
118 List<RendererNode> result = rendererNodesReader();
119 assertTrue(result.isEmpty());
123 public void testRegisterNewNode_connectedCaseFullCapabilities() throws Exception {
124 Node testNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
125 nodeManager.syncNodes(testNode, null);
126 List<RendererNode> result = rendererNodesReader();
127 assertNotNull(result);
128 assertTrue(result.size() == 1);
132 public void testRegisterNewNode_unableToConnectCase() throws Exception {
133 Node testNode = createNode(UnableToConnect, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
134 nodeManager.syncNodes(testNode, null);
135 List<RendererNode> result = rendererNodesReader();
136 assertTrue(result.isEmpty());
140 public void testUpdateNode_fromConnectingToConnected() throws Exception {
141 Node oldNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
142 Node newNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
143 nodeManager.syncNodes(oldNode, null);
144 List<RendererNode> result = rendererNodesReader();
145 assertTrue(result.isEmpty());
146 nodeManager.syncNodes(newNode, oldNode);
147 result = rendererNodesReader();
148 assertNotNull(result);
149 assertTrue(result.size() == 1);
155 public void testUpdateNode_fromConnectingToUnableToConnect() throws Exception {
156 Node oldNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
157 Node newNode = createNode(UnableToConnect, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
158 nodeManager.syncNodes(oldNode, null);
159 List<RendererNode> result = rendererNodesReader();
160 assertTrue(result.isEmpty());
161 nodeManager.syncNodes(newNode, oldNode);
162 result = rendererNodesReader();
163 assertTrue(result.isEmpty());
167 public void testUpdateNode_fromConnectedToConnecting() throws Exception {
168 Node oldNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
169 Node newNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
170 nodeManager.syncNodes(oldNode, null);
171 List<RendererNode> result = rendererNodesReader();
172 assertNotNull(result);
173 assertTrue(result.size() == 1);
174 nodeManager.syncNodes(newNode, oldNode);
175 result = rendererNodesReader();
176 assertTrue(result.isEmpty());
180 public void testUpdateNode_fromConnectedToUnableToConnect() throws Exception {
181 Node oldNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
182 Node newNode = createNode(UnableToConnect, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
183 nodeManager.syncNodes(oldNode, null);
184 List<RendererNode> result = rendererNodesReader();
185 assertNotNull(result);
186 assertTrue(result.size() == 1);
187 nodeManager.syncNodes(newNode, oldNode);
188 result = rendererNodesReader();
189 assertTrue(result.isEmpty());
193 public void testUpdateNode_fromUnableToConnectToConnecting() throws Exception {
194 Node oldNode = createNode(UnableToConnect, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
195 Node newNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
196 nodeManager.syncNodes(oldNode, null);
197 List<RendererNode> result = rendererNodesReader();
198 assertTrue(result.isEmpty());
199 nodeManager.syncNodes(newNode, oldNode);
200 result = rendererNodesReader();
201 assertTrue(result.isEmpty());
205 public void testUpdateNode_fromUnableToConnectToConnected() throws Exception {
206 Node oldNode = createNode(UnableToConnect, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
207 Node newNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
208 nodeManager.syncNodes(oldNode, null);
209 List<RendererNode> result = rendererNodesReader();
210 assertTrue(result.isEmpty());
211 nodeManager.syncNodes(newNode, oldNode);
212 result = rendererNodesReader();
213 assertNotNull(result);
214 assertTrue(result.size() == 1);
218 public void testUpdateNode_advancedCase() throws Exception {
219 Node oldNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Partial);
220 nodeManager.syncNodes(oldNode, null);
221 List<RendererNode> result = rendererNodesReader();
222 // One node is connecting, partial capabilities = empty list
223 assertTrue(result.isEmpty());
224 Node newNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Partial);
225 nodeManager.syncNodes(newNode, oldNode);
226 result = rendererNodesReader();
227 // Update 1.: node is connected, still partial capabilities = empty list
228 assertTrue(result.isEmpty());
230 newNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
231 nodeManager.syncNodes(newNode, oldNode);
232 result = rendererNodesReader();
233 // Update 2.: node is connected, full capabilities = 1 entry in list
234 assertNotNull(result);
235 assertTrue(result.size() == 1);
237 newNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.None);
238 nodeManager.syncNodes(newNode, oldNode);
239 result = rendererNodesReader();
240 // Update 3.: node remains connected, but without capabilities = empty list
241 assertTrue(result.isEmpty());
244 // Advanced update Case
247 public void testRemoveNode() throws Exception {
248 Node testNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
249 nodeManager.syncNodes(testNode, null);
250 List<RendererNode> result = rendererNodesReader();
251 assertNotNull(result);
252 assertTrue(result.size() == 1);
253 nodeManager.syncNodes(null, testNode);
254 result = rendererNodesReader();
255 assertTrue(result.isEmpty());
261 public void getNodeManagementIpByMountPointIid_absentNode() {
262 NodeId testNodeId = new NodeId(NODE_NAME);
263 InstanceIdentifier mountpointIid = InstanceIdentifier.builder(NetworkTopology.class)
264 .child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID)))
265 .child(Node.class, new NodeKey(testNodeId)).build();
266 java.util.Optional<String> optionalIpAddress = nodeManager.getNodeManagementIpByMountPointIid(mountpointIid);
267 assertFalse(optionalIpAddress.isPresent());
271 public void getNodeManagementIpByMountPointIid_ipV4Case() throws Exception {
273 Node testNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
274 InstanceIdentifier<Node> testNodeIid = InstanceIdentifier.builder(NetworkTopology.class)
275 .child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID)))
276 .child(Node.class, new NodeKey(testNode.getNodeId())).build();
277 WriteTransaction wTx = dataBroker.newWriteOnlyTransaction();
278 wTx.put(LogicalDatastoreType.CONFIGURATION, testNodeIid, testNode, true);
279 wTx.submit().checkedGet();
281 java.util.Optional<String> optionalResult = nodeManager.getNodeManagementIpByMountPointIid(testNodeIid);
282 assertTrue(optionalResult.isPresent());
283 assertEquals(IPv4_ADDRESS.getValue(), optionalResult.get());
286 private Node createNode(final NetconfNodeConnectionStatus.ConnectionStatus connectionStatus,
287 final Ipv4Address ipAddress,
288 final NodeId nodeName,
289 final Capabilities choice) {
290 AvailableCapabilities capabilities = null;
293 capabilities = emptyCapabilities();
297 capabilities = partialCapabilities();
301 capabilities = fullCapabilities();
305 NetconfNodeBuilder netconfNodeBuilder = new NetconfNodeBuilder();
306 netconfNodeBuilder.setConnectionStatus(connectionStatus)
307 .setAvailableCapabilities(capabilities)
308 .setHost(new Host(new IpAddress(ipAddress)));
310 NodeBuilder nodeBuilder = new NodeBuilder();
311 nodeBuilder.setNodeId(new NodeId(nodeName))
312 .setKey(new NodeKey(new NodeId(nodeName)))
313 .addAugmentation(NetconfNode.class, netconfNodeBuilder.build());
314 return nodeBuilder.build();
319 private List<RendererNode> rendererNodesReader() throws Exception {
320 InstanceIdentifier<Renderers> renderersIid =
321 InstanceIdentifier.builder(Renderers.class).build();
322 ReadWriteTransaction rwt = dataBroker.newReadWriteTransaction();
323 CheckedFuture<Optional<Renderers>, ReadFailedException> submitFuture =
324 rwt.read(LogicalDatastoreType.OPERATIONAL, renderersIid);
325 Optional<Renderers> optionalRenderers = submitFuture.checkedGet();
326 if (optionalRenderers.isPresent()) {
327 Renderers renderers = optionalRenderers.get();
328 if (renderers != null && renderers.getRenderer() != null && !renderers.getRenderer().isEmpty()) {
329 RendererNodes writtenNodes = renderers.getRenderer().get(0).getRendererNodes();
330 if (writtenNodes != null) {
331 return writtenNodes.getRendererNode();
335 return Collections.emptyList();
338 private AvailableCapabilities emptyCapabilities() {
339 AvailableCapabilitiesBuilder availableCapabilitiesBuilder = new AvailableCapabilitiesBuilder();
340 return availableCapabilitiesBuilder.build();
343 private AvailableCapabilities partialCapabilities() {
344 final AvailableCapability c1 = new AvailableCapabilityBuilder()
345 .setCapability("(urn:ios?revision=2016-03-08)ned")
347 final AvailableCapability c2 = new AvailableCapabilityBuilder()
348 .setCapability("(http://tail-f.com/yang/common?revision=2015-05-22)tailf-common")
350 final AvailableCapability c3 = new AvailableCapabilityBuilder()
351 .setCapability("(http://tail-f.com/yang/common?revision=2015-03-19)tailf-cli-extensions")
353 AvailableCapability[] capabilityList = {c1, c2, c3};
354 AvailableCapabilitiesBuilder availableCapabilitiesBuilder = new AvailableCapabilitiesBuilder();
355 availableCapabilitiesBuilder.setAvailableCapability(Arrays.asList(capabilityList));
356 return availableCapabilitiesBuilder.build();
359 private AvailableCapabilities fullCapabilities() {
360 final AvailableCapability c1 = new AvailableCapabilityBuilder()
361 .setCapability("(urn:ios?revision=2016-03-08)ned")
363 final AvailableCapability c2 = new AvailableCapabilityBuilder()
364 .setCapability("(http://tail-f.com/yang/common?revision=2015-05-22)tailf-common")
366 final AvailableCapability c3 = new AvailableCapabilityBuilder()
367 .setCapability("(http://tail-f.com/yang/common?revision=2015-03-19)tailf-cli-extensions")
369 final AvailableCapability c4 = new AvailableCapabilityBuilder()
370 .setCapability("(http://tail-f.com/yang/common?revision=2013-11-07)tailf-meta-extensions")
372 final AvailableCapability c5 = new AvailableCapabilityBuilder()
373 .setCapability("(urn:ietf:params:xml:ns:yang:ietf-yang-types?revision=2013-07-15)ietf-yang-types")
375 final AvailableCapability c6 = new AvailableCapabilityBuilder()
376 .setCapability("(urn:ietf:params:xml:ns:yang:ietf-inet-types?revision=2013-07-15)ietf-inet-types")
378 AvailableCapability[] capabilityList = {c1, c2, c3, c4, c5, c6};
379 AvailableCapabilitiesBuilder availableCapabilitiesBuilder = new AvailableCapabilitiesBuilder();
380 availableCapabilitiesBuilder.setAvailableCapability(Arrays.asList(capabilityList));
381 return availableCapabilitiesBuilder.build();
384 private enum Capabilities {None, Partial, Full}