ec9ded6690a892c6b0d3fba2499db1c9e2b816b9
[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.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;
35
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;
41
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;
52
53
54 public class NodeManagerTest extends CustomDataBrokerTest {
55
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;
61
62     @Nonnull
63     @Override
64     public Collection<java.lang.Class<?>> getClassesFromModules() {
65         return Arrays.asList(Renderers.class, NetworkTopology.class, NetconfNode.class);
66     }
67
68     @Before
69     public void init() {
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);
75     }
76
77     @Test
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());
83     }
84
85     // Create Cases
86
87     @Test
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());
93     }
94
95     @Test
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());
101     }
102
103     @Test
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());
109     }
110
111     @Test
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);
118     }
119
120     @Test
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());
126     }
127
128     @Test
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);
139     }
140
141     // Update Cases
142
143     @Test
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());
153     }
154
155     @Test
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());
166     }
167
168     @Test
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());
179     }
180
181     @Test
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());
191     }
192
193     @Test
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);
204     }
205
206     @Test
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());
218         oldNode = newNode;
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);
225         oldNode = newNode;
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());
231     }
232
233     // Advanced update Case
234
235     @Test
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());
245     }
246
247     // Remove Case
248
249     @Test
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);
257     }
258
259     @Test
260     public void getNodeManagementIpByMountPointIid_ipV4Case() throws Exception {
261         // Put node
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();
269
270         String result = nodeManager.getNodeManagementIpByMountPointIid(testNodeIid);
271         assertEquals(IPv4_ADDRESS.getValue(), result);
272     }
273
274     private Node createNode(final NetconfNodeConnectionStatus.ConnectionStatus connectionStatus,
275                             final Ipv4Address ipAddress,
276                             final NodeId nodeName,
277                             final Capabilities choice) {
278         AvailableCapabilities capabilities = null;
279         switch (choice) {
280             case None: {
281                 capabilities = emptyCapabilities();
282                 break;
283             }
284             case Partial: {
285                 capabilities = partialCapabilities();
286                 break;
287             }
288             case Full: {
289                 capabilities = fullCapabilities();
290             }
291         }
292         // Netconf node
293         NetconfNodeBuilder netconfNodeBuilder = new NetconfNodeBuilder();
294         netconfNodeBuilder.setConnectionStatus(connectionStatus)
295                 .setAvailableCapabilities(capabilities)
296                 .setHost(new Host(new IpAddress(ipAddress)));
297         // Node
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();
303     }
304
305     // Utility methods
306
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();
320                 }
321             }
322         }
323         return Collections.emptyList();
324     }
325
326     private AvailableCapabilities emptyCapabilities() {
327         AvailableCapabilitiesBuilder availableCapabilitiesBuilder = new AvailableCapabilitiesBuilder();
328         return availableCapabilitiesBuilder.build();
329     }
330
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();
339     }
340
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();
352     }
353
354     private enum Capabilities {None, Partial, Full}
355 }