2 * Copyright © 2016 Inocybe Technologies and others. All rights reserved.
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
8 package org.opendaylight.unimgr.it;
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;
14 import java.math.BigInteger;
15 import java.util.ArrayList;
16 import java.util.List;
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.rev130715.IpAddress;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.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;
67 import com.google.common.base.Optional;
68 import com.google.common.util.concurrent.CheckedFuture;
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;
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";
88 public void setup() throws Exception {
91 dataBroker = getSession().getSALService(DataBroker.class);
92 Assert.assertNotNull("db should not be null", dataBroker);
96 public String getModuleName() {
101 public String getInstanceName() {
102 return "unimgr-default";
106 public MavenUrlReference getFeatureRepo() {
108 .groupId("org.opendaylight.unimgr")
109 .artifactId("unimgr-features")
110 .classifier("features")
112 .versionAsInProject();
116 public String getFeatureName() {
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());
130 public void testUnimgrFeatureLoad() {
131 Assert.assertTrue(true);
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"))));
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,
152 topology = read(LogicalDatastoreType.OPERATIONAL, uniTopoPath);
153 Assert.assertNotNull("UNI Topology could not be found in " + LogicalDatastoreType.OPERATIONAL,
155 topology = read(LogicalDatastoreType.CONFIGURATION, evcTopoPath);
156 Assert.assertNotNull("EVC Topology could not be found in " + LogicalDatastoreType.CONFIGURATION,
158 topology = read(LogicalDatastoreType.OPERATIONAL, evcTopoPath);
159 Assert.assertNotNull("EVC Topology could not be found in " + LogicalDatastoreType.OPERATIONAL,
161 topology = read(LogicalDatastoreType.CONFIGURATION, ovdbTopoPath);
162 Assert.assertNotNull("OVSDB Topology could not be found in " + LogicalDatastoreType.CONFIGURATION,
164 topology = read(LogicalDatastoreType.CONFIGURATION, ovdbTopoPath);
165 Assert.assertNotNull("OVSDB Topology could not be found in " + LogicalDatastoreType.OPERATIONAL,
170 public void createAndDeleteUNITest() {
171 LOG.info("Test for create and delete UNI");
173 InstanceIdentifier<Node> nodePath = createUniNode(MAC_ADDRESS_1, IP_1);
174 Assert.assertNotNull(nodePath);
175 Assert.assertTrue(validateUni(true, nodePath));
177 InstanceIdentifier<Node> deletedNodePath = deleteNode(MAC_ADDRESS_1, IP_1);
178 Assert.assertNotNull(deletedNodePath);
179 Assert.assertTrue(validateUni(false, deletedNodePath));
183 public void testCreateAndDeleteEvc() {
184 LOG.info("Test for create Evc");
185 // Create an evc between the two Uni nodes
186 InstanceIdentifier<Link> evcIid = createEvcLink(IP_1, MAC_ADDRESS_1, IP_2, MAC_ADDRESS_2, EVC_ID_1);
187 Assert.assertNotNull(evcIid);
189 // Validate Evc create operation
190 boolean status = validateEvc(true, EVC_ID_1);
191 Assert.assertTrue(status);
194 evcIid = deleteEvc(EVC_ID_1);
195 Assert.assertNotNull(evcIid);
197 // Validate Evc delete operation
198 status = validateEvc(false, EVC_ID_1);
199 Assert.assertTrue(status);
202 private boolean validateEvc(boolean forCreate, String evcId) {
203 InstanceIdentifier<Link> iid = getEvcLinkIid(evcId);
204 Link evc = read(LogicalDatastoreType.CONFIGURATION, iid);
205 if (forCreate && evc != null) {
207 } else if (!forCreate && evc == null) {
213 private InstanceIdentifier<Node> createUniNode(String macAddress, String ipAddress) {
214 UniAugmentation uni = new UniAugmentationBuilder()
215 .setMacAddress(new MacAddress(macAddress))
216 .setMacLayer(MAC_LAYER)
218 .setMtuSize(BigInteger.valueOf(Long.valueOf(MTU_SIZE)))
219 .setPhysicalMedium(PHY_MEDIUM)
221 .setIpAddress(new IpAddress(ipAddress.toCharArray()))
224 NodeId uniNodeId = new NodeId(new NodeId("uni://" + uni.getIpAddress().getIpv4Address().getValue().toString()));
225 InstanceIdentifier<Node> uniNodeIid = null;
226 uniNodeIid = getUniIid("uni://" + uni.getIpAddress().getIpv4Address().getValue().toString());
227 NodeKey uniNodeKey = new NodeKey(uniNodeId);
228 Node nodeData = new NodeBuilder()
229 .setNodeId(uniNodeId)
231 .addAugmentation(UniAugmentation.class, uni)
233 WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
235 writeUNI(uniNodeIid, nodeData, transaction);
236 LOG.info("Created and submitted a new Uni node {}", nodeData.getNodeId());
238 } catch (Exception e) {
239 transaction.cancel();
240 LOG.error("Could not create Uni Node - Id: {}, {}", uniNodeId, e);
245 private void writeUNI(InstanceIdentifier<Node> uniNodeIid, Node nodeData, WriteTransaction transaction) throws TransactionCommitFailedException {
246 transaction.put(LogicalDatastoreType.CONFIGURATION, uniNodeIid, nodeData);
247 CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
251 private InstanceIdentifier<Link> deleteEvc(String evcId) {
252 LinkId evcLinkId = new LinkId(new LinkId("evc://" + evcId));
253 InstanceIdentifier<Link> evcLinkIid = null;
254 evcLinkIid = getEvcLinkIid(evcId);
255 if (evcLinkIid != null) {
256 WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
257 transaction.delete(LogicalDatastoreType.CONFIGURATION, evcLinkIid);
258 CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
261 } catch (TransactionCommitFailedException e) {
262 LOG.error("Error while deleting Evc {}", evcLinkIid);
264 LOG.info("Deleted an Evc link {}", evcLinkId);
269 private InstanceIdentifier<Link> createEvcLink(String srcUniIp, String srcMac,
270 String dstUniIp, String dstMac, String evcId) {
271 // Create two Uni nodes before creating an Evc
272 InstanceIdentifier<Node> uniIid = createUniNode(srcMac, srcUniIp);
273 Assert.assertNotNull(uniIid);
275 uniIid = createUniNode(dstMac, dstUniIp);
276 Assert.assertNotNull(uniIid);
278 // Create Evc link between the two Uni Nodes
279 List<UniSource> src = new ArrayList<>();
280 InstanceIdentifier<?> srcUniIid = getUniIid("uni://" + srcUniIp);
281 UniSource uniSrc = new UniSourceBuilder()
282 .setIpAddress(new IpAddress(srcUniIp.toCharArray()))
284 .setKey(new UniSourceKey((short) 1))
289 List<UniDest> dst = new ArrayList<>();
290 InstanceIdentifier<?> dstUniIid = getUniIid("uni://" + dstUniIp);;
291 UniDest uniDst = new UniDestBuilder()
292 .setIpAddress(new IpAddress(dstUniIp.toCharArray()))
294 .setKey(new UniDestKey((short) 2))
299 EvcAugmentation evc = new EvcAugmentationBuilder()
304 LinkId evcLinkId = new LinkId(new LinkId("evc://" + evcId));
305 InstanceIdentifier<Link> evcLinkIid = null;
307 evcLinkIid = getEvcLinkIid(evcId);
308 LinkKey evcLinkKey = new LinkKey(evcLinkId);
309 Source mandatorySrcNode = new SourceBuilder().setSourceNode(new NodeId("uni://" + srcUniIp)).build();
310 Destination mandatoryDstNode = new DestinationBuilder().setDestNode(new NodeId("uni://" + dstUniIp)).build();
311 Link linkData = new LinkBuilder()
313 .setSource(mandatorySrcNode)
314 .setDestination(mandatoryDstNode)
315 .setLinkId(evcLinkId)
316 .addAugmentation(EvcAugmentation.class, evc)
318 WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
319 transaction.put(LogicalDatastoreType.CONFIGURATION, evcLinkIid, linkData);
320 CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
322 LOG.info("Created and submitted a new Evc link {}", evcLinkId);
323 } catch (Exception e) {
324 LOG.error("Exception while creating Evc " + "Evc link Id: {}, {}", evcLinkId, e);
330 private InstanceIdentifier<Node> getUniIid(String nodeId) {
331 NodeId uniNodeId = new NodeId(new NodeId(nodeId));
332 InstanceIdentifier<Node> uniNodeIid = InstanceIdentifier
333 .create(NetworkTopology.class)
334 .child(Topology.class, new TopologyKey(new TopologyId(new Uri("unimgr:uni"))))
335 .child(Node.class, new NodeKey(uniNodeId));
339 private InstanceIdentifier<Link> getEvcLinkIid(String linkId) {
340 LinkId evcLinkId = new LinkId(new LinkId("evc://" + linkId));
341 InstanceIdentifier<Link> linkPath = InstanceIdentifier
342 .create(NetworkTopology.class)
343 .child(Topology.class,new TopologyKey(new TopologyId(new Uri("unimgr:evc"))))
344 .child(Link.class, new LinkKey(evcLinkId));
348 private <D extends org.opendaylight.yangtools.yang.binding.DataObject> D read(
349 final LogicalDatastoreType store, final InstanceIdentifier<D> path) {
351 final ReadOnlyTransaction transaction = dataBroker.newReadOnlyTransaction();
352 Optional<D> optionalDataObject;
353 CheckedFuture<Optional<D>, ReadFailedException> future = transaction.read(store, path);
355 optionalDataObject = future.checkedGet();
356 if (optionalDataObject.isPresent()) {
357 result = optionalDataObject.get();
359 LOG.error("{}: Failed to read {}",
360 Thread.currentThread().getStackTrace()[1], path);
362 } catch (ReadFailedException e) {
363 LOG.error("Failed to read {} ", path, e);
369 private boolean validateUni(boolean forCreate, InstanceIdentifier<Node> iid) {
370 Node uni = read(LogicalDatastoreType.CONFIGURATION, iid);
371 if (forCreate && uni != null) {
373 } else if (!forCreate && uni == null) {
379 private InstanceIdentifier<Node> deleteNode(String macAddress, String ipAddress) {
380 UniAugmentation uni = new UniAugmentationBuilder().setMacAddress(new MacAddress(macAddress))
381 .setMacLayer(MAC_LAYER).setMode(MODE).setMtuSize(BigInteger.valueOf(Long.valueOf(MTU_SIZE)))
382 .setPhysicalMedium(PHY_MEDIUM).setType(TYPE).setIpAddress(new IpAddress(ipAddress.toCharArray()))
385 NodeId uniNodeId = new NodeId(new NodeId("uni://" + uni.getIpAddress().getIpv4Address().getValue().toString()));
386 InstanceIdentifier<Node> genericNode = InstanceIdentifier
387 .create(NetworkTopology.class)
388 .child(Topology.class,
389 new TopologyKey(new TopologyId(new Uri("unimgr:uni"))))
391 new NodeKey(uniNodeId));
393 LOG.info("Received a request to delete node {}", genericNode);
394 WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
395 transaction.delete(LogicalDatastoreType.CONFIGURATION, genericNode);
397 transaction.submit().checkedGet();
398 } catch (TransactionCommitFailedException e) {
399 LOG.error("Unable to remove node with Iid {} from store {}.", genericNode, LogicalDatastoreType.CONFIGURATION);