manually cherry pick this patch https://git.opendaylight.org/gerrit/#/c/34579/
[unimgr.git] / it / src / test / java / org / opendaylight / unimgr / it / UnimgrIT.java
1 /*
2  * Copyright © 2016 Inocybe Technologies and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.unimgr.it;
9
10 import static org.ops4j.pax.exam.CoreOptions.composite;
11 import static org.ops4j.pax.exam.CoreOptions.maven;
12 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
13
14 import java.math.BigInteger;
15 import java.util.ArrayList;
16 import java.util.List;
17
18 import org.junit.Assert;
19 import org.junit.Test;
20 import org.junit.runner.RunWith;
21 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
22 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
23 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
24 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
25 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
26 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
27 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.EvcAugmentation;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.EvcAugmentationBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.UniAugmentation;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.UniAugmentationBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.evc.UniDest;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.evc.UniDestBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.evc.UniDestKey;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.evc.UniSource;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.evc.UniSourceBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.evc.UniSourceKey;
41 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.LinkId;
42 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
43 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
44 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
45 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.Destination;
46 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.DestinationBuilder;
47 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.Source;
48 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.link.attributes.SourceBuilder;
49 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
50 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
51 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
52 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkBuilder;
53 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkKey;
54 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
55 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
56 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
57 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
58 import org.ops4j.pax.exam.Option;
59 import org.ops4j.pax.exam.junit.PaxExam;
60 import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel;
61 import org.ops4j.pax.exam.options.MavenUrlReference;
62 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
63 import org.ops4j.pax.exam.spi.reactors.PerClass;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
66
67 import com.google.common.base.Optional;
68 import com.google.common.util.concurrent.CheckedFuture;
69
70 @RunWith(PaxExam.class)
71 @ExamReactorStrategy(PerClass.class)
72 public class UnimgrIT extends AbstractMdsalTestBase {
73     private static final Logger LOG = LoggerFactory.getLogger(UnimgrIT.class);
74     private DataBroker dataBroker;
75
76     private static final String MAC_ADDRESS_1 = "68:5b:35:bc:0f:7d";
77     private static final String MAC_ADDRESS_2 = "68:5b:35:bc:0f:7e";
78     private static final String MAC_LAYER = "IEEE 802.3-2005";
79     private static final String MODE = "Full Duplex";
80     private static final String MTU_SIZE = "0";
81     private static final String PHY_MEDIUM = "UNI TypeFull Duplex 2 Physical Interface";
82     private static final String TYPE = "";
83     private static final String IP_1 = "10.0.0.1";
84     private static final String IP_2 = "10.0.0.2";
85     private static final String EVC_ID_1 = "1";
86
87     @Override
88     public void setup() throws Exception {
89         super.setup();
90         Thread.sleep(3000);
91         dataBroker =  getSession().getSALService(DataBroker.class);
92         Assert.assertNotNull("db should not be null", dataBroker);
93     }
94
95     @Override
96     public String getModuleName() {
97         return "unimgr";
98     }
99
100     @Override
101     public String getInstanceName() {
102         return "unimgr-default";
103     }
104
105     @Override
106     public MavenUrlReference getFeatureRepo() {
107         return maven()
108                 .groupId("org.opendaylight.unimgr")
109                 .artifactId("unimgr-features")
110                 .classifier("features")
111                 .type("xml")
112                 .versionAsInProject();
113     }
114
115     @Override
116     public String getFeatureName() {
117         return "odl-unimgr";
118     }
119
120     @Override
121     public Option getLoggingOption() {
122         Option option = editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
123                 logConfiguration(UnimgrIT.class),
124                 LogLevel.INFO.name());
125         option = composite(option, super.getLoggingOption());
126         return option;
127     }
128
129     @Test
130     public void testUnimgrFeatureLoad() {
131         Assert.assertTrue(true);
132     }
133
134     @Test
135     public void testUnimgr() {
136         InstanceIdentifier<Topology> uniTopoPath = InstanceIdentifier
137                 .create(NetworkTopology.class)
138                 .child(Topology.class,
139                         new TopologyKey(new TopologyId(new Uri("unimgr:uni"))));
140         InstanceIdentifier<Topology> evcTopoPath = InstanceIdentifier
141                 .create(NetworkTopology.class)
142                 .child(Topology.class,
143                         new TopologyKey(new TopologyId(new Uri("unimgr:evc"))));
144         InstanceIdentifier<Topology> ovdbTopoPath = InstanceIdentifier
145                 .create(NetworkTopology.class)
146                 .child(Topology.class, new TopologyKey(new TopologyId(new Uri("ovsdb:1"))));
147
148         // Read from md-sal and check if it is initialized with Uni and Evc augmentations
149         Topology topology = read(LogicalDatastoreType.CONFIGURATION, uniTopoPath);
150         Assert.assertNotNull("UNI Topology could not be found in " + LogicalDatastoreType.CONFIGURATION,
151                 topology);
152         topology = read(LogicalDatastoreType.OPERATIONAL, uniTopoPath);
153         Assert.assertNotNull("UNI Topology could not be found in " + LogicalDatastoreType.OPERATIONAL,
154                 topology);
155         topology = read(LogicalDatastoreType.CONFIGURATION, evcTopoPath);
156         Assert.assertNotNull("EVC Topology could not be found in " + LogicalDatastoreType.CONFIGURATION,
157                 topology);
158         topology = read(LogicalDatastoreType.OPERATIONAL, evcTopoPath);
159         Assert.assertNotNull("EVC Topology could not be found in " + LogicalDatastoreType.OPERATIONAL,
160                 topology);
161         topology = read(LogicalDatastoreType.CONFIGURATION, ovdbTopoPath);
162         Assert.assertNotNull("OVSDB Topology could not be found in " + LogicalDatastoreType.CONFIGURATION,
163                 topology);
164         topology = read(LogicalDatastoreType.CONFIGURATION, ovdbTopoPath);
165         Assert.assertNotNull("OVSDB Topology could not be found in " + LogicalDatastoreType.OPERATIONAL,
166                 topology);
167     }
168
169     @Test
170     public void createAndDeleteUNITest() {
171         UniAugmentation uni = new UniAugmentationBuilder()
172                 .setMacAddress(new MacAddress(MAC_ADDRESS_1))
173                 .setMacLayer(MAC_LAYER)
174                 .setMode(MODE)
175                 .setMtuSize(BigInteger.valueOf(Long.valueOf(MTU_SIZE)))
176                 .setPhysicalMedium(PHY_MEDIUM)
177                 .setSpeed(null)
178                 .setType(TYPE)
179                 .setIpAddress(new IpAddress(IP_1.toCharArray()))
180                 .build();
181
182         InstanceIdentifier<Node> nodePath = createUniNode(MAC_ADDRESS_1, IP_1);
183         Assert.assertTrue(validateUni(true, nodePath));
184
185         InstanceIdentifier<Node> deletedNodePath = deleteNode(MAC_ADDRESS_1, IP_1);
186         Assert.assertTrue(validateUni(false, deletedNodePath));
187     }
188
189     @Test
190     public void testCreateAndDeleteEvc() {
191         LOG.info("Test for create Evc");
192         // Create an evc between the two Uni nodes
193         InstanceIdentifier<Link> evcIid = createEvcLink(IP_1, MAC_ADDRESS_1, IP_2, MAC_ADDRESS_2, EVC_ID_1);
194         Assert.assertNotNull(evcIid);
195
196         // Validate Evc create operation
197         boolean status = validateEvc(true, EVC_ID_1);
198         Assert.assertTrue(status);
199
200         //Delete the Evc
201         evcIid = deleteEvc(EVC_ID_1);
202         Assert.assertNotNull(evcIid);
203
204         // Validate Evc delete operation
205         status = validateEvc(false, EVC_ID_1);
206         Assert.assertTrue(status);
207     }
208
209     private boolean validateEvc(boolean forCreate, String evcId) {
210         InstanceIdentifier<Link> iid = getEvcLinkIid(evcId);
211         Link evc = read(LogicalDatastoreType.CONFIGURATION, iid);
212         if (forCreate && evc != null) {
213             return true;
214         } else if (!forCreate && evc == null) {
215             return true;
216         }
217         return false;
218     }
219
220     private InstanceIdentifier<Node> createUniNode(String macAddress, String ipAddress) {
221         UniAugmentation uni = new UniAugmentationBuilder()
222                 .setMacAddress(new MacAddress(macAddress))
223                 .setMacLayer(MAC_LAYER)
224                 .setMode(MODE)
225                 .setMtuSize(BigInteger.valueOf(Long.valueOf(MTU_SIZE)))
226                 .setPhysicalMedium(PHY_MEDIUM)
227                 .setType(TYPE)
228                 .setIpAddress(new IpAddress(ipAddress.toCharArray()))
229                 .build();
230
231         NodeId uniNodeId = new NodeId(new NodeId("uni://" + uni.getIpAddress().getIpv4Address().getValue().toString()));
232         InstanceIdentifier<Node> uniNodeIid = null;
233         try {
234             uniNodeIid = getUniIid("uni://" + uni.getIpAddress().getIpv4Address().getValue().toString());
235             NodeKey uniNodeKey = new NodeKey(uniNodeId);
236             Node nodeData = new NodeBuilder()
237                                     .setNodeId(uniNodeId)
238                                     .setKey(uniNodeKey)
239                                     .addAugmentation(UniAugmentation.class, uni)
240                                     .build();
241             WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
242             transaction.put(LogicalDatastoreType.CONFIGURATION, uniNodeIid, nodeData);
243             CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
244             future.checkedGet();
245             LOG.info("Created and submitted a new Uni node {}", nodeData.getNodeId());
246         } catch (Exception e) {
247             LOG.error("Exception while creating Uni Node" + "Uni Node Id: {}, {}", uniNodeId, e);
248             return null;
249         }
250         return uniNodeIid;
251     }
252
253     private InstanceIdentifier<Link> deleteEvc(String evcId) {
254         LinkId evcLinkId = new LinkId(new LinkId("evc://" + evcId));
255         InstanceIdentifier<Link> evcLinkIid = null;
256         evcLinkIid = getEvcLinkIid(evcId);
257         if (evcLinkIid != null) {
258             WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
259             transaction.delete(LogicalDatastoreType.CONFIGURATION, evcLinkIid);
260             CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
261             try {
262                 future.checkedGet();
263             } catch (TransactionCommitFailedException e) {
264                 LOG.error("Error while deleting Evc {}", evcLinkIid);
265             }
266             LOG.info("Deleted an Evc link {}", evcLinkId);
267         }
268         return evcLinkIid;
269     }
270
271     private InstanceIdentifier<Link> createEvcLink(String srcUniIp, String srcMac,
272             String dstUniIp, String dstMac, String evcId) {
273         // Create two Uni nodes before creating an Evc
274         InstanceIdentifier<Node> uniIid = createUniNode(srcMac, srcUniIp);
275         Assert.assertNotNull(uniIid);
276
277         uniIid = createUniNode(dstMac, dstUniIp);
278         Assert.assertNotNull(uniIid);
279
280         // Create Evc link between the two Uni Nodes
281         List<UniSource> src = new ArrayList<>();
282         InstanceIdentifier<?> srcUniIid = getUniIid("uni://" + srcUniIp);
283         UniSource uniSrc = new UniSourceBuilder()
284                 .setIpAddress(new IpAddress(srcUniIp.toCharArray()))
285                 .setOrder((short) 1)
286                 .setKey(new UniSourceKey((short) 1))
287                 .setUni(srcUniIid)
288                 .build();
289         src.add(uniSrc);
290
291         List<UniDest> dst = new ArrayList<>();
292         InstanceIdentifier<?> dstUniIid = getUniIid("uni://" + dstUniIp);;
293         UniDest uniDst = new UniDestBuilder()
294                 .setIpAddress(new IpAddress(dstUniIp.toCharArray()))
295                 .setOrder((short) 2)
296                 .setKey(new UniDestKey((short) 2))
297                 .setUni(dstUniIid)
298                 .build();
299         dst.add(uniDst);
300
301         EvcAugmentation evc = new EvcAugmentationBuilder()
302                 .setUniDest(dst)
303                 .setUniSource(src)
304                 .build();
305
306         LinkId evcLinkId = new LinkId(new LinkId("evc://" + evcId));
307         InstanceIdentifier<Link> evcLinkIid = null;
308         try {
309             evcLinkIid = getEvcLinkIid(evcId);
310             LinkKey evcLinkKey = new LinkKey(evcLinkId);
311             Source mandatorySrcNode = new SourceBuilder().setSourceNode(new NodeId("uni://" + srcUniIp)).build();
312             Destination mandatoryDstNode = new DestinationBuilder().setDestNode(new NodeId("uni://" + dstUniIp)).build();
313             Link linkData = new LinkBuilder()
314                         .setKey(evcLinkKey)
315                         .setSource(mandatorySrcNode)
316                         .setDestination(mandatoryDstNode)
317                         .setLinkId(evcLinkId)
318                         .addAugmentation(EvcAugmentation.class, evc)
319                         .build();
320             WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
321             transaction.put(LogicalDatastoreType.CONFIGURATION, evcLinkIid, linkData);
322             CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
323             future.checkedGet();
324             LOG.info("Created and submitted a new Evc link {}", evcLinkId);
325         } catch (Exception e) {
326             LOG.error("Exception while creating Evc " + "Evc link Id: {}, {}", evcLinkId, e);
327             return null;
328         }
329         return evcLinkIid;
330     }
331
332     private InstanceIdentifier<Node> getUniIid(String nodeId) {
333         NodeId uniNodeId = new NodeId(new NodeId(nodeId));
334         InstanceIdentifier<Node> uniNodeIid = InstanceIdentifier
335                 .create(NetworkTopology.class)
336                 .child(Topology.class, new TopologyKey(new TopologyId(new Uri("unimgr:uni"))))
337                 .child(Node.class, new NodeKey(uniNodeId));
338         return uniNodeIid;
339     }
340
341     private InstanceIdentifier<Link> getEvcLinkIid(String linkId) {
342         LinkId evcLinkId = new LinkId(new LinkId("evc://" + linkId));
343         InstanceIdentifier<Link> linkPath = InstanceIdentifier
344                 .create(NetworkTopology.class)
345                 .child(Topology.class,new TopologyKey(new TopologyId(new Uri("unimgr:evc"))))
346                 .child(Link.class, new LinkKey(evcLinkId));
347         return linkPath;
348     }
349
350     private <D extends org.opendaylight.yangtools.yang.binding.DataObject> D read(
351             final LogicalDatastoreType store, final InstanceIdentifier<D> path)  {
352         D result = null;
353         final ReadOnlyTransaction transaction = dataBroker.newReadOnlyTransaction();
354         Optional<D> optionalDataObject;
355         CheckedFuture<Optional<D>, ReadFailedException> future = transaction.read(store, path);
356         try {
357             optionalDataObject = future.checkedGet();
358             if (optionalDataObject.isPresent()) {
359                 result = optionalDataObject.get();
360             } else {
361                 LOG.error("{}: Failed to read {}",
362                         Thread.currentThread().getStackTrace()[1], path);
363             }
364         } catch (ReadFailedException e) {
365             LOG.error("Failed to read {} ", path, e);
366         }
367         transaction.close();
368         return result;
369     }
370
371     private boolean validateUni(boolean forCreate, InstanceIdentifier<Node> iid) {
372         Node uni = read(LogicalDatastoreType.CONFIGURATION, iid);
373         if (forCreate && uni != null) {
374             return true;
375         } else if (!forCreate && uni == null) {
376             return true;
377         }
378         return false;
379     }
380
381     private InstanceIdentifier<Node> deleteNode(String macAddress, String ipAddress) {
382         UniAugmentation uni = new UniAugmentationBuilder().setMacAddress(new MacAddress(macAddress))
383                 .setMacLayer(MAC_LAYER).setMode(MODE).setMtuSize(BigInteger.valueOf(Long.valueOf(MTU_SIZE)))
384                 .setPhysicalMedium(PHY_MEDIUM).setType(TYPE).setIpAddress(new IpAddress(ipAddress.toCharArray()))
385                 .build();
386
387         NodeId uniNodeId = new NodeId(new NodeId("uni://" + uni.getIpAddress().getIpv4Address().getValue().toString()));
388         InstanceIdentifier<Node> genericNode = InstanceIdentifier
389                 .create(NetworkTopology.class)
390                 .child(Topology.class,
391                         new TopologyKey(new TopologyId(new Uri("unimgr:uni"))))
392                 .child(Node.class,
393                         new NodeKey(uniNodeId));
394
395         LOG.info("Received a request to delete node {}", genericNode);
396         WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
397         transaction.delete(LogicalDatastoreType.CONFIGURATION, genericNode);
398         try {
399             transaction.submit().checkedGet();
400         } catch (TransactionCommitFailedException e) {
401             LOG.error("Unable to remove node with Iid {} from store {}.", genericNode, LogicalDatastoreType.CONFIGURATION);
402             return null;
403         }
404         return genericNode;
405     }
406 }