1 package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager;
3 import com.google.common.base.Optional;
4 import com.google.common.util.concurrent.CheckedFuture;
5 import org.junit.Before;
7 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
8 import org.opendaylight.controller.md.sal.binding.api.MountPointService;
9 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
10 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
11 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
12 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
13 import org.opendaylight.groupbasedpolicy.test.CustomDataBrokerTest;
14 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
15 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
16 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererNodes;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNode;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilities;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
25 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
26 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
27 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
30 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
31 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
33 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
35 import javax.annotation.Nonnull;
36 import java.util.Arrays;
37 import java.util.Collection;
38 import java.util.Collections;
39 import java.util.List;
41 import static org.junit.Assert.assertEquals;
42 import static org.junit.Assert.assertNotNull;
43 import static org.junit.Assert.assertNull;
44 import static org.junit.Assert.assertTrue;
45 import static org.mockito.Matchers.any;
46 import static org.mockito.Mockito.mock;
47 import static org.mockito.Mockito.when;
48 import static org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus.Connected;
49 import static org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus.Connecting;
50 import static org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus.UnableToConnect;
53 public class NodeManagerTest extends CustomDataBrokerTest {
55 private final NodeId NODE_NAME = new NodeId("testNode");
56 private final TopologyId TOPOLOGY_ID = new TopologyId("topology-netconf");
57 private final Ipv4Address IPv4_ADDRESS = new Ipv4Address("174.25.75.11");
58 private NodeManager nodeManager;
59 private DataBroker dataBroker;
63 public Collection<java.lang.Class<?>> getClassesFromModules() {
64 return Arrays.asList(Renderers.class, NetworkTopology.class, NetconfNode.class);
69 dataBroker = getDataBroker();
70 BindingAwareBroker.ProviderContext context = mock(BindingAwareBroker.ProviderContext.class);
71 MountPointService mountPointService = mock(MountPointService.class);
72 when(context.getSALService(any())).thenReturn(mountPointService);
73 nodeManager = new NodeManager(dataBroker, context);
77 public void testRegisterNewNode_connectingCase() throws Exception {
78 Node testNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
79 nodeManager.syncNodes(testNode, null);
80 List<RendererNode> result = rendererNodesReader();
81 assertTrue(result.isEmpty());
87 public void testRegisterNewNode_connectedCaseNoIpAddress() throws Exception {
88 Node testNode = createNode(Connected, null, NODE_NAME, Capabilities.None);
89 nodeManager.syncNodes(testNode, null);
90 List<RendererNode> result = rendererNodesReader();
91 assertTrue(result.isEmpty());
95 public void testRegisterNewNode_connectedCaseNullCapabilities() throws Exception {
96 Node testNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.None);
97 nodeManager.syncNodes(testNode, null);
98 List<RendererNode> result = rendererNodesReader();
99 assertTrue(result.isEmpty());
103 public void testRegisterNewNode_connectedCasePartialCapabilities() throws Exception {
104 Node testNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Partial);
105 nodeManager.syncNodes(testNode, null);
106 List<RendererNode> result = rendererNodesReader();
107 assertTrue(result.isEmpty());
111 public void testRegisterNewNode_connectedCaseFullCapabilities() throws Exception {
112 Node testNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
113 nodeManager.syncNodes(testNode, null);
114 List<RendererNode> result = rendererNodesReader();
115 assertNotNull(result);
116 assertTrue(result.size() == 1);
120 public void testRegisterNewNode_unableToConnectCase() throws Exception {
121 Node testNode = createNode(UnableToConnect, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
122 nodeManager.syncNodes(testNode, null);
123 List<RendererNode> result = rendererNodesReader();
124 assertTrue(result.isEmpty());
128 public void testUpdateNode_fromConnectingToConnected() throws Exception {
129 Node oldNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
130 Node newNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
131 nodeManager.syncNodes(oldNode, null);
132 List<RendererNode> result = rendererNodesReader();
133 assertTrue(result.isEmpty());
134 nodeManager.syncNodes(newNode, oldNode);
135 result = rendererNodesReader();
136 assertNotNull(result);
137 assertTrue(result.size() == 1);
143 public void testUpdateNode_fromConnectingToUnableToConnect() throws Exception {
144 Node oldNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
145 Node newNode = createNode(UnableToConnect, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
146 nodeManager.syncNodes(oldNode, null);
147 List<RendererNode> result = rendererNodesReader();
148 assertTrue(result.isEmpty());
149 nodeManager.syncNodes(newNode, oldNode);
150 result = rendererNodesReader();
151 assertTrue(result.isEmpty());
155 public void testUpdateNode_fromConnectedToConnecting() throws Exception {
156 Node oldNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
157 Node newNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
158 nodeManager.syncNodes(oldNode, null);
159 List<RendererNode> result = rendererNodesReader();
160 assertNotNull(result);
161 assertTrue(result.size() == 1);
162 nodeManager.syncNodes(newNode, oldNode);
163 result = rendererNodesReader();
164 assertTrue(result.isEmpty());
168 public void testUpdateNode_fromConnectedToUnableToConnect() throws Exception {
169 Node oldNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
170 Node newNode = createNode(UnableToConnect, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
171 nodeManager.syncNodes(oldNode, null);
172 List<RendererNode> result = rendererNodesReader();
173 assertNotNull(result);
174 assertTrue(result.size() == 1);
175 nodeManager.syncNodes(newNode, oldNode);
176 result = rendererNodesReader();
177 assertTrue(result.isEmpty());
181 public void testUpdateNode_fromUnableToConnectToConnecting() throws Exception {
182 Node oldNode = createNode(UnableToConnect, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
183 Node newNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
184 nodeManager.syncNodes(oldNode, null);
185 List<RendererNode> result = rendererNodesReader();
186 assertTrue(result.isEmpty());
187 nodeManager.syncNodes(newNode, oldNode);
188 result = rendererNodesReader();
189 assertTrue(result.isEmpty());
193 public void testUpdateNode_fromUnableToConnectToConnected() throws Exception {
194 Node oldNode = createNode(UnableToConnect, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
195 Node newNode = createNode(Connected, 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 assertNotNull(result);
202 assertTrue(result.size() == 1);
206 public void testUpdateNode_advancedCase() throws Exception {
207 Node oldNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Partial);
208 nodeManager.syncNodes(oldNode, null);
209 List<RendererNode> result = rendererNodesReader();
210 // One node is connecting, partial capabilities = empty list
211 assertTrue(result.isEmpty());
212 Node newNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Partial);
213 nodeManager.syncNodes(newNode, oldNode);
214 result = rendererNodesReader();
215 // Update 1.: node is connected, still partial capabilities = empty list
216 assertTrue(result.isEmpty());
218 newNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
219 nodeManager.syncNodes(newNode, oldNode);
220 result = rendererNodesReader();
221 // Update 2.: node is connected, full capabilities = 1 entry in list
222 assertNotNull(result);
223 assertTrue(result.size() == 1);
225 newNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.None);
226 nodeManager.syncNodes(newNode, oldNode);
227 result = rendererNodesReader();
228 // Update 3.: node remains connected, but without capabilities = empty list
229 assertTrue(result.isEmpty());
232 // Advanced update Case
235 public void testRemoveNode() throws Exception {
236 Node testNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
237 nodeManager.syncNodes(testNode, null);
238 List<RendererNode> result = rendererNodesReader();
239 assertNotNull(result);
240 assertTrue(result.size() == 1);
241 nodeManager.syncNodes(null, testNode);
242 result = rendererNodesReader();
243 assertTrue(result.isEmpty());
249 public void getNodeManagementIpByMountPointIid_absentNode() {
250 NodeId testNodeId = new NodeId(NODE_NAME);
251 InstanceIdentifier mountpointIid = InstanceIdentifier.builder(NetworkTopology.class)
252 .child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID)))
253 .child(Node.class, new NodeKey(testNodeId)).build();
254 String ipAddress = nodeManager.getNodeManagementIpByMountPointIid(mountpointIid);
255 assertNull(ipAddress);
259 public void getNodeManagementIpByMountPointIid_ipV4Case() throws Exception {
261 Node testNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
262 InstanceIdentifier<Node> testNodeIid = InstanceIdentifier.builder(NetworkTopology.class)
263 .child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID)))
264 .child(Node.class, new NodeKey(testNode.getNodeId())).build();
265 ReadWriteTransaction rwt = dataBroker.newReadWriteTransaction();
266 rwt.put(LogicalDatastoreType.CONFIGURATION, testNodeIid, testNode, true);
267 rwt.submit().checkedGet();
268 InstanceIdentifier mountpointIid = InstanceIdentifier.builder(NetworkTopology.class)
269 .child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID)))
270 .child(Node.class, new NodeKey(NODE_NAME)).build();
271 String result = nodeManager.getNodeManagementIpByMountPointIid(mountpointIid);
272 assertEquals(IPv4_ADDRESS.getValue(), result);
275 private Node createNode(final NetconfNodeConnectionStatus.ConnectionStatus connectionStatus,
276 final Ipv4Address ipAddress,
277 final NodeId nodeName,
278 final Capabilities choice) {
279 AvailableCapabilities capabilities = null;
282 capabilities = emptyCapabilities();
286 capabilities = partialCapabilities();
290 capabilities = fullCapabilities();
294 NetconfNodeBuilder netconfNodeBuilder = new NetconfNodeBuilder();
295 netconfNodeBuilder.setConnectionStatus(connectionStatus)
296 .setAvailableCapabilities(capabilities)
297 .setHost(new Host(new IpAddress(ipAddress)));
299 NodeBuilder nodeBuilder = new NodeBuilder();
300 nodeBuilder.setNodeId(new NodeId(nodeName))
301 .setKey(new NodeKey(new NodeId(nodeName)))
302 .addAugmentation(NetconfNode.class, netconfNodeBuilder.build());
303 return nodeBuilder.build();
308 private List<RendererNode> rendererNodesReader() throws Exception {
309 InstanceIdentifier<Renderers> renderersIid =
310 InstanceIdentifier.builder(Renderers.class).build();
311 ReadWriteTransaction rwt = dataBroker.newReadWriteTransaction();
312 CheckedFuture<Optional<Renderers>, ReadFailedException> submitFuture =
313 rwt.read(LogicalDatastoreType.OPERATIONAL, renderersIid);
314 Optional<Renderers> optionalRenderers = submitFuture.checkedGet();
315 if (optionalRenderers.isPresent()) {
316 Renderers renderers = optionalRenderers.get();
317 if (renderers != null && renderers.getRenderer() != null && !renderers.getRenderer().isEmpty()) {
318 RendererNodes writtenNodes = renderers.getRenderer().get(0).getRendererNodes();
319 if (writtenNodes != null) {
320 return writtenNodes.getRendererNode();
324 return Collections.emptyList();
327 private AvailableCapabilities emptyCapabilities() {
328 AvailableCapabilitiesBuilder availableCapabilitiesBuilder = new AvailableCapabilitiesBuilder();
329 return availableCapabilitiesBuilder.build();
332 private AvailableCapabilities partialCapabilities() {
333 final String c1 = "(urn:ios?revision=2016-03-08)ned";
334 final String c2 = "(http://tail-f.com/yang/common?revision=2015-05-22)tailf-common";
335 final String c3 = "(http://tail-f.com/yang/common?revision=2015-03-19)tailf-cli-extensions";
336 String[] capabilityList = {c1, c2, c3};
337 AvailableCapabilitiesBuilder availableCapabilitiesBuilder = new AvailableCapabilitiesBuilder();
338 availableCapabilitiesBuilder.setAvailableCapability(Arrays.asList(capabilityList));
339 return availableCapabilitiesBuilder.build();
342 private AvailableCapabilities fullCapabilities() {
343 final String c1 = "(urn:ios?revision=2016-03-08)ned";
344 final String c2 = "(http://tail-f.com/yang/common?revision=2015-05-22)tailf-common";
345 final String c3 = "(http://tail-f.com/yang/common?revision=2015-03-19)tailf-cli-extensions";
346 final String c4 = "(http://tail-f.com/yang/common?revision=2013-11-07)tailf-meta-extensions";
347 final String c5 = "(urn:ietf:params:xml:ns:yang:ietf-yang-types?revision=2013-07-15)ietf-yang-types";
348 final String c6 = "(urn:ietf:params:xml:ns:yang:ietf-inet-types?revision=2013-07-15)ietf-inet-types";
349 String[] capabilityList = {c1, c2, c3, c4, c5, c6};
350 AvailableCapabilitiesBuilder availableCapabilitiesBuilder = new AvailableCapabilitiesBuilder();
351 availableCapabilitiesBuilder.setAvailableCapability(Arrays.asList(capabilityList));
352 return availableCapabilitiesBuilder.build();
355 private enum Capabilities {None, Partial, Full}