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