5d27c53ac52e487e8cc528634173765e4a35b4c3
[groupbasedpolicy.git] / renderers / ios-xe / src / test / java / org / opendaylight / groupbasedpolicy / renderer / ios_xe_provider / impl / manager / NodeManagerTest.java
1 package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager;
2
3 import com.google.common.base.Optional;
4 import com.google.common.util.concurrent.CheckedFuture;
5 import org.junit.Before;
6 import org.junit.Test;
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;
34
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;
40
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;
51
52
53 public class NodeManagerTest extends CustomDataBrokerTest {
54
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;
60
61     @Nonnull
62     @Override
63     public Collection<java.lang.Class<?>> getClassesFromModules() {
64         return Arrays.asList(Renderers.class, NetworkTopology.class, NetconfNode.class);
65     }
66
67     @Before
68     public void init() {
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);
74     }
75
76     @Test
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());
82     }
83
84     // Create Cases
85
86     @Test
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());
92     }
93
94     @Test
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());
100     }
101
102     @Test
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());
108     }
109
110     @Test
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);
117     }
118
119     @Test
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());
125     }
126
127     @Test
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);
138     }
139
140     // Update Cases
141
142     @Test
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());
152     }
153
154     @Test
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());
165     }
166
167     @Test
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());
178     }
179
180     @Test
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());
190     }
191
192     @Test
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);
203     }
204
205     @Test
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());
217         oldNode = newNode;
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);
224         oldNode = newNode;
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());
230     }
231
232     // Advanced update Case
233
234     @Test
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());
244     }
245
246     // Remove Case
247
248     @Test
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);
256     }
257
258     @Test
259     public void getNodeManagementIpByMountPointIid_ipV4Case() throws Exception {
260         // Put node
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);
273     }
274
275     private Node createNode(final NetconfNodeConnectionStatus.ConnectionStatus connectionStatus,
276                             final Ipv4Address ipAddress,
277                             final NodeId nodeName,
278                             final Capabilities choice) {
279         AvailableCapabilities capabilities = null;
280         switch (choice) {
281             case None: {
282                 capabilities = emptyCapabilities();
283                 break;
284             }
285             case Partial: {
286                 capabilities = partialCapabilities();
287                 break;
288             }
289             case Full: {
290                 capabilities = fullCapabilities();
291             }
292         }
293         // Netconf node
294         NetconfNodeBuilder netconfNodeBuilder = new NetconfNodeBuilder();
295         netconfNodeBuilder.setConnectionStatus(connectionStatus)
296                 .setAvailableCapabilities(capabilities)
297                 .setHost(new Host(new IpAddress(ipAddress)));
298         // Node
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();
304     }
305
306     // Utility methods
307
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();
321                 }
322             }
323         }
324         return Collections.emptyList();
325     }
326
327     private AvailableCapabilities emptyCapabilities() {
328         AvailableCapabilitiesBuilder availableCapabilitiesBuilder = new AvailableCapabilitiesBuilder();
329         return availableCapabilitiesBuilder.build();
330     }
331
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();
340     }
341
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();
353     }
354
355     private enum Capabilities {None, Partial, Full}
356 }