2 * Copyright (c) 2016 CableLabs 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
9 package org.opendaylight.unimgr.utils;
11 import java.net.InetAddress;
12 import java.net.UnknownHostException;
13 import java.util.ArrayList;
14 import java.util.HashMap;
15 import java.util.HashSet;
16 import java.util.List;
18 import java.util.Map.Entry;
20 import java.util.UUID;
22 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
23 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
24 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
27 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
28 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
29 import org.opendaylight.unimgr.impl.UnimgrConstants;
30 import org.opendaylight.unimgr.impl.UnimgrMapper;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentationBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes.VlanMode;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntries;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesKey;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Queues;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QueuesBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QueuesKey;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosOtherConfig;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosOtherConfigBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosOtherConfigKey;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueList;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueListBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueListKey;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesOtherConfig;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesOtherConfigBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesOtherConfigKey;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsKey;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.EvcAugmentation;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.Uni;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.UniAugmentation;
74 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
75 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
76 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
77 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
78 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
79 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
80 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
81 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
82 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
83 import org.opendaylight.yangtools.yang.binding.DataObject;
84 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
85 import org.slf4j.Logger;
86 import org.slf4j.LoggerFactory;
88 import com.google.common.base.Optional;
89 import com.google.common.collect.ImmutableBiMap;
90 import com.google.common.collect.Lists;
91 import com.google.common.util.concurrent.CheckedFuture;
93 public class OvsdbUtils {
95 private static final Logger LOG = LoggerFactory.getLogger(OvsdbUtils.class);
97 private OvsdbUtils() {
98 throw new AssertionError("Instantiating utility class.");
102 * Creates and submit a Bridge Node to the Configuration Data Store.
103 * @param dataBroker The Data Broker Instance to create a transaction
104 * @param ovsdbNode The OVSDB node
105 * @param uni The UNI linked to the OVSDB node
106 * @param bridgeName The bridge name (example: br0)
108 public static void createBridgeNode(DataBroker dataBroker,
112 LOG.info("Creating a bridge on node {}", ovsdbNode.getNodeId().getValue());
113 final InstanceIdentifier<Node> ovsdbNodeIid = uni.getOvsdbNodeRef().getValue().firstIdentifierOf(Node.class);
114 if (ovsdbNodeIid != null) {
115 final NodeBuilder bridgeNodeBuilder = new NodeBuilder();
116 final InstanceIdentifier<Node> bridgeIid = UnimgrMapper.createOvsdbBridgeNodeIid(ovsdbNode,
118 final NodeId bridgeNodeId = new NodeId(ovsdbNode.getNodeId()
119 + UnimgrConstants.DEFAULT_BRIDGE_NODE_ID_SUFFIX
121 bridgeNodeBuilder.setNodeId(bridgeNodeId);
122 final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
123 ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
124 ovsdbBridgeAugmentationBuilder.setProtocolEntry(OvsdbUtils.createMdsalProtocols());
125 final OvsdbNodeRef ovsdbNodeRef = new OvsdbNodeRef(ovsdbNodeIid);
126 ovsdbBridgeAugmentationBuilder.setManagedBy(ovsdbNodeRef);
127 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
128 final WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
129 transaction.put(LogicalDatastoreType.CONFIGURATION, bridgeIid, bridgeNodeBuilder.build());
130 transaction.submit();
132 LOG.info("OvsdbNodeRef is null");
137 * Creates and submit a Bridge Node to the Configuration Data Store.
138 * @param dataBroker The Data Broker Instance to create a transaction
139 * @param ovsdbNodeIid The OVSDB node Instance Identifier
140 * @param uni The UNI linked to the OVSDB node
141 * @param bridgeName The bridge name (example: br0)
143 public static void createBridgeNode(DataBroker dataBroker,
144 InstanceIdentifier<Node> ovsdbNodeIid,
147 LOG.info("Creating a bridge on node {}", ovsdbNodeIid);
148 if (ovsdbNodeIid != null) {
149 final NodeBuilder bridgeNodeBuilder = new NodeBuilder();
150 final Optional<Node> optionalOvsdbNode = MdsalUtils.readNode(dataBroker,
151 LogicalDatastoreType.OPERATIONAL,
153 if (optionalOvsdbNode.isPresent()) {
154 final Node ovsdbNode = optionalOvsdbNode.get();
155 final InstanceIdentifier<Node> bridgeIid = UnimgrMapper.createOvsdbBridgeNodeIid(ovsdbNode,
157 final NodeId bridgeNodeId = new NodeId(ovsdbNode.getNodeId().getValue()
158 + UnimgrConstants.DEFAULT_BRIDGE_NODE_ID_SUFFIX
160 bridgeNodeBuilder.setNodeId(bridgeNodeId);
161 final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
162 ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
163 ovsdbBridgeAugmentationBuilder.setProtocolEntry(OvsdbUtils.createMdsalProtocols());
164 final OvsdbNodeRef ovsdbNodeRef = new OvsdbNodeRef(ovsdbNodeIid);
165 ovsdbBridgeAugmentationBuilder.setManagedBy(ovsdbNodeRef);
166 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class,
167 ovsdbBridgeAugmentationBuilder.build());
168 final WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
169 transaction.put(LogicalDatastoreType.CONFIGURATION,
171 bridgeNodeBuilder.build());
172 transaction.submit();
175 LOG.info("OvsdbNodeRef is null");
180 * Creates a List of Controller Entry to be used when adding controllers
182 * @param targetString The URI in string format of the Controller Entry
183 * @return A List of Controller Entry to be used when adding controllers
185 public static List<ControllerEntry> createControllerEntries(String targetString) {
186 final List<ControllerEntry> controllerEntries = new ArrayList<ControllerEntry>();
187 final ControllerEntryBuilder controllerEntryBuilder = new ControllerEntryBuilder();
188 controllerEntryBuilder.setTarget(new Uri(targetString));
189 controllerEntries.add(controllerEntryBuilder.build());
190 return controllerEntries;
194 * Creates a submit a GRE tunnel to the Configuration DataStore.
195 * @param dataBroker An instance of the Data Broker to create a transaction
196 * @param source The source UNI
197 * @param destination The destination UNI
198 * @param bridgeNode The bridge Node
199 * @param bridgeName The bridge name (example br0)
200 * @param portName The Port Name (example: eth0)
202 public static void createGreTunnel(DataBroker dataBroker,
208 final InstanceIdentifier<TerminationPoint> tpIid =
209 UnimgrMapper.getTerminationPointIid(bridgeNode,
211 final OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder =
212 new OvsdbTerminationPointAugmentationBuilder();
213 tpAugmentationBuilder.setName(portName);
214 final ArrayList<Options> options = Lists.newArrayList();
215 final OptionsKey optionKey = new OptionsKey("remote_ip");
216 final Options destinationIp = new OptionsBuilder()
217 .setOption(destination.getIpAddress().getIpv4Address().getValue())
218 .setKey(optionKey).setValue(destination.getIpAddress().getIpv4Address().getValue())
220 options.add(destinationIp);
221 tpAugmentationBuilder.setOptions(options);
222 tpAugmentationBuilder.setInterfaceType(SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP.get("gre"));
223 if (source.getSpeed() != null) {
224 final Uuid qosUuid = getQosUuid(dataBroker, source);
225 tpAugmentationBuilder.setQos(getQosUuid(dataBroker, source));
226 LOG.info("Updating Qos {} to termination point {}", qosUuid , bridgeName);
228 final TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
229 tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
230 tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
231 final WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
232 transaction.put(LogicalDatastoreType.CONFIGURATION,
235 transaction.submit();
239 * Utility function used to create a protocol entry when creating a bridge node.
240 * @return A List of protocol entry
242 public static List<ProtocolEntry> createMdsalProtocols() {
243 final List<ProtocolEntry> protocolList = new ArrayList<ProtocolEntry>();
244 final ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
245 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
246 protocolList.add(new ProtocolEntryBuilder().
247 setProtocol((Class<? extends OvsdbBridgeProtocolBase>) mapper.get("OpenFlow13")).build());
252 * Creates a Bridge Augmentation by using a UNI
253 * @param uni Contains data used to create the augmentation
254 * @return A Built OvsdbBridgeAugmentation with data.
255 * @throws Exception if the Ovsdb Node Reference cannot be found.
257 public static OvsdbBridgeAugmentation createOvsdbBridgeAugmentation(Uni uni) throws Exception {
258 final OvsdbNodeRef ovsdbNodeRef = uni.getOvsdbNodeRef();
259 if ((ovsdbNodeRef != null) && (ovsdbNodeRef.getValue() != null)) {
260 final UUID bridgeUuid = UUID.randomUUID();
261 final OvsdbBridgeAugmentation ovsdbBridge = new OvsdbBridgeAugmentationBuilder()
263 new OvsdbBridgeName(UnimgrConstants.DEFAULT_BRIDGE_NAME))
264 .setManagedBy(ovsdbNodeRef)
266 new Uuid(bridgeUuid.toString()))
270 throw new Exception("Ovsdb Node Reference does not exist !");
275 * Creates a submit an OvsdbNode to the Configuration DataStore.
276 * @param dataBroker The instance of the Data Broker to create transactions.
277 * @param ovsdbNodeId The Ovsdb Node Id to use on creation
278 * @param uni The UNI's data
280 public static void createOvsdbNode(DataBroker dataBroker,
283 final InstanceIdentifier<Node> ovsdbNodeIid = UnimgrMapper.getOvsdbNodeIid(uni.getIpAddress());
285 final NodeKey ovsdbNodeKey = new NodeKey(ovsdbNodeId);
286 final Node nodeData = new NodeBuilder()
287 .setNodeId(ovsdbNodeId)
288 .setKey(ovsdbNodeKey)
289 .addAugmentation(OvsdbNodeAugmentation.class,
290 OvsdbUtils.createOvsdbNodeAugmentation(uni))
292 // Submit the node to the datastore
293 final WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
294 transaction.put(LogicalDatastoreType.CONFIGURATION, ovsdbNodeIid, nodeData);
295 transaction.submit();
296 LOG.info("Created and submitted a new OVSDB node {}", nodeData.getNodeId());
297 } catch (final Exception e) {
298 LOG.error("Exception while creating OvsdbNodeAugmentation, Uni is null. Node Id: {}", ovsdbNodeId, e);
303 * Creates and submit an OvsdbNode by using the Data contained in the UniAugmentation
304 * @param dataBroker The instance of the DataBroker to create transactions
305 * @param uni The UNI's data
306 * @return The instance of the Node
308 public static Node createOvsdbNode(DataBroker dataBroker,
309 UniAugmentation uni) {
310 final NodeId ovsdbNodeId = new NodeId(createOvsdbNodeId(uni.getIpAddress()));
312 final InstanceIdentifier<Node> ovsdbNodeIid = UnimgrMapper.getOvsdbNodeIid(ovsdbNodeId);
313 final NodeKey ovsdbNodeKey = new NodeKey(ovsdbNodeId);
314 final Node nodeData = new NodeBuilder()
315 .setNodeId(ovsdbNodeId)
316 .setKey(ovsdbNodeKey)
317 .addAugmentation(OvsdbNodeAugmentation.class,
318 OvsdbUtils.createOvsdbNodeAugmentation(uni))
320 // Submit the node to the datastore
321 final WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
322 transaction.put(LogicalDatastoreType.CONFIGURATION, ovsdbNodeIid, nodeData);
323 transaction.submit();
324 LOG.info("Created and submitted a new OVSDB node {}", nodeData.getNodeId());
326 } catch (final Exception e) {
327 LOG.error("Exception while creating OvsdbNodeAugmentation, Uni is null. Node Id: {}", ovsdbNodeId, e);
333 * Creates and Build the data for an OvsdbNodeAugmentation.
334 * @param uni The UNI"s data
335 * @return The built OsvdbNodeAugmentation
337 public static OvsdbNodeAugmentation createOvsdbNodeAugmentation(Uni uni) {
338 final ConnectionInfo connectionInfos = new ConnectionInfoBuilder()
339 .setRemoteIp(uni.getIpAddress())
340 .setRemotePort(new PortNumber(UnimgrConstants.OVSDB_PORT))
342 final OvsdbNodeAugmentation ovsdbNode = new OvsdbNodeAugmentationBuilder()
343 .setConnectionInfo(connectionInfos).build();
347 public static OvsdbNodeAugmentation createOvsdbNodeAugmentation(UniAugmentation uni,
348 PortNumber remotePort) {
349 final ConnectionInfo connectionInfos = new ConnectionInfoBuilder()
350 .setRemoteIp(uni.getIpAddress())
351 .setRemotePort(remotePort)
353 final OvsdbNodeAugmentation ovsdbNode = new OvsdbNodeAugmentationBuilder()
354 .setConnectionInfo(connectionInfos)
355 .setQosEntries(createQosEntries(uni))
356 .setQueues(createQueues(uni))
361 public static Node createQoSForOvsdbNode (DataBroker dataBroker, UniAugmentation uni) {
362 final Optional<Node> optionalNode = findOvsdbNode(dataBroker, uni);
363 if (optionalNode.isPresent()) {
364 final NodeId ovsdbNodeId = optionalNode.get().getNodeId();
365 final InstanceIdentifier<OvsdbNodeAugmentation> ovsdbNodeAugmentationIid = UnimgrMapper
366 .getOvsdbNodeIid(ovsdbNodeId)
367 .augmentation(OvsdbNodeAugmentation.class);
368 final OvsdbNodeAugmentation ovsdbNodeAugmentation = createOvsdbNodeAugmentation(uni,
369 getRemotePort(dataBroker, uni));
370 final WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
371 transaction.delete(LogicalDatastoreType.CONFIGURATION, ovsdbNodeAugmentationIid);
372 transaction.put(LogicalDatastoreType.CONFIGURATION, ovsdbNodeAugmentationIid, ovsdbNodeAugmentation, true);
373 final CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
375 Thread.sleep(UnimgrConstants.OVSDB_UPDATE_TIMEOUT);
376 } catch (final InterruptedException e) {
377 LOG.warn("Interrupted while waiting after OVSDB node augmentation {}", ovsdbNodeId, e);
381 LOG.trace("Update qos and queues to ovsdb for node {} {}", ovsdbNodeId, ovsdbNodeAugmentationIid);
382 } catch (final TransactionCommitFailedException e) {
383 LOG.warn("Failed to put {} ", ovsdbNodeAugmentationIid, e);
385 updateQosEntries(dataBroker, uni);
390 private static PortNumber getRemotePort(DataBroker dataBroker, UniAugmentation uni) {
391 PortNumber remotePort = null;
392 final Optional<Node> optionalNode = findOvsdbNode(dataBroker, uni);
394 if (optionalNode.isPresent()) {
395 remotePort = optionalNode.get()
396 .getAugmentation(OvsdbNodeAugmentation.class)
397 .getConnectionInfo().getRemotePort();
402 private static List<QosEntries> createQosEntries(Uni uni) {
403 // Configure queue for best-effort dscp and max rate
404 final List<QosOtherConfig> otherConfig = new ArrayList<>();
405 QosOtherConfig qOtherConfig = new QosOtherConfigBuilder()
406 .setKey(new QosOtherConfigKey(UnimgrConstants.QOS_DSCP_ATTRIBUTE))
407 .setOtherConfigKey(UnimgrConstants.QOS_DSCP_ATTRIBUTE)
408 .setOtherConfigValue(UnimgrConstants.QOS_DSCP_ATTRIBUTE_VALUE)
410 otherConfig.add(qOtherConfig);
412 qOtherConfig = new QosOtherConfigBuilder()
413 .setKey(new QosOtherConfigKey(UnimgrConstants.QOS_MAX_RATE))
414 .setOtherConfigKey(UnimgrConstants.QOS_MAX_RATE)
415 .setOtherConfigValue(UniUtils.getSpeed(uni.getSpeed().getSpeed()))
417 otherConfig.add(qOtherConfig);
419 final Uuid qosUuid = new Uuid(UUID.randomUUID().toString());
420 final QosEntries qosEntry = new QosEntriesBuilder()
421 .setKey(new QosEntriesKey(new Uri(UnimgrConstants.QOS_PREFIX + qosUuid.getValue())))
422 .setQosId(new Uri(UnimgrConstants.QOS_PREFIX + qosUuid.getValue()))
423 .setQosOtherConfig(otherConfig)
424 .setQosType(SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HTB))
427 final List<QosEntries> qosEntries = new ArrayList<>();
428 qosEntries.add(qosEntry);
432 private static List<Queues> createQueues(Uni uni) {
433 final List<QueuesOtherConfig> otherConfig = new ArrayList<>();
434 QueuesOtherConfig queuesOtherConfig = new QueuesOtherConfigBuilder()
435 .setKey(new QueuesOtherConfigKey(UnimgrConstants.QOS_DSCP_ATTRIBUTE))
436 .setQueueOtherConfigKey(UnimgrConstants.QOS_DSCP_ATTRIBUTE)
437 .setQueueOtherConfigValue(UnimgrConstants.QOS_DSCP_ATTRIBUTE_VALUE)
439 otherConfig.add(queuesOtherConfig);
441 queuesOtherConfig = new QueuesOtherConfigBuilder()
442 .setKey(new QueuesOtherConfigKey(UnimgrConstants.QOS_MAX_RATE))
443 .setQueueOtherConfigKey(UnimgrConstants.QOS_MAX_RATE)
444 .setQueueOtherConfigValue(UniUtils.getSpeed(uni.getSpeed().getSpeed()))
446 otherConfig.add(queuesOtherConfig);
448 // Configure dscp value for best-effort
449 final Uuid queueUuid = new Uuid(UUID.randomUUID().toString());
450 final Queues queues = new QueuesBuilder()
451 .setDscp(Short.parseShort(UnimgrConstants.QOS_DSCP_ATTRIBUTE_VALUE))
452 .setKey(new QueuesKey(new Uri(UnimgrConstants.QUEUE_PREFIX + queueUuid.getValue())))
453 .setQueueId(new Uri(UnimgrConstants.QUEUE_PREFIX + queueUuid.getValue()))
454 .setQueuesOtherConfig(otherConfig)
457 final List<Queues> queuesList = new ArrayList<>();
458 queuesList.add(queues);
462 private static void updateQosEntries(DataBroker dataBroker, UniAugmentation uni) {
463 final Optional<Node> optionalNode = findOvsdbNode(dataBroker, uni);
464 if (optionalNode.isPresent()) {
465 final NodeId ovsdbNodeId = optionalNode.get().getNodeId();
466 final Long queueNumber = 0L;
467 final List<QosEntries> qosList = optionalNode.get()
468 .getAugmentation(OvsdbNodeAugmentation.class)
470 LOG.trace("QOS entries list {} for node {}", qosList, ovsdbNodeId);
471 QosEntriesKey qosEntryKey = null;
472 for (final QosEntries qosEntry : qosList) {
473 qosEntryKey = qosEntry.getKey();
475 final InstanceIdentifier<QueueList> queueIid = UnimgrMapper
476 .getOvsdbQueueListIid(ovsdbNodeId, qosEntryKey, queueNumber);
478 Uuid queueUuid = null;
479 final List<Queues> queuesList = optionalNode.get()
480 .getAugmentation(OvsdbNodeAugmentation.class).getQueues();
481 for (final Queues queue : queuesList) {
482 queueUuid = queue.getQueueUuid();
484 final QueueList queueList = new QueueListBuilder()
485 .setKey(new QueueListKey(queueNumber))
486 .setQueueNumber(queueNumber)
487 .setQueueUuid(queueUuid)
490 final WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
491 transaction.delete(LogicalDatastoreType.CONFIGURATION, queueIid);
492 transaction.put(LogicalDatastoreType.CONFIGURATION, queueIid, queueList, true);
493 final CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
496 LOG.info("Update qos-entries to ovsdb for node {} {}", ovsdbNodeId, queueIid);
497 } catch (final TransactionCommitFailedException e) {
498 LOG.warn("Failed to put {} ", queueIid, e);
503 public static void updateMaxRate (DataBroker dataBroker,
504 UniAugmentation sourceUniAugmentation,
505 UniAugmentation destinationUniAugmentation,
506 EvcAugmentation evc) {
507 Optional<Node> optionalNode;
508 if (UniUtils.getSpeed(sourceUniAugmentation.getSpeed().getSpeed())
509 .equals(UniUtils.getSpeed(evc.getIngressBw().getSpeed()))) {
510 LOG.info("Source UNI speed matches EVC ingress BW");
512 // update Uni's ovsdbNodeRef qos-entries and queues for max-rate to match EVC ingress BW
513 optionalNode = findOvsdbNode(dataBroker, sourceUniAugmentation);
514 if (optionalNode.isPresent()) {
515 updateQosMaxRate(dataBroker, optionalNode, evc);
516 updateQueuesMaxRate(dataBroker, optionalNode, evc);
520 if (UniUtils.getSpeed(destinationUniAugmentation.getSpeed().getSpeed())
521 .equals(UniUtils.getSpeed(evc.getIngressBw().getSpeed()))) {
522 LOG.info("Destination UNI speed matches EVC ingress BW");
524 // update Uni's ovsdbNodeRef qos-entries and queues for max-rate to match EVC ingress BW
525 optionalNode = findOvsdbNode(dataBroker, destinationUniAugmentation);
526 if (optionalNode.isPresent()) {
527 updateQosMaxRate(dataBroker, optionalNode, evc);
528 updateQueuesMaxRate(dataBroker, optionalNode, evc);
533 private static void updateQosMaxRate(DataBroker dataBroker,
534 Optional<Node> optionalOvsdbNode,
535 EvcAugmentation evc) {
536 final NodeId ovsdbNodeId = optionalOvsdbNode.get().getNodeId();
537 final List<QosEntries> qosList = optionalOvsdbNode.get()
538 .getAugmentation(OvsdbNodeAugmentation.class)
540 LOG.trace("QOS entries list {} for node {}", qosList, ovsdbNodeId);
541 QosEntriesKey qosEntryKey = null;
542 for (final QosEntries qosEntry : qosList) {
543 qosEntryKey = qosEntry.getKey();
545 final InstanceIdentifier<QosOtherConfig> qosOtherConfigIid = UnimgrMapper
546 .getQosOtherConfigIid(ovsdbNodeId, qosEntryKey);
547 final QosOtherConfig qOtherConfig = new QosOtherConfigBuilder()
548 .setKey(new QosOtherConfigKey(UnimgrConstants.QOS_MAX_RATE))
549 .setOtherConfigKey(UnimgrConstants.QOS_MAX_RATE)
550 .setOtherConfigValue(UniUtils.getSpeed(evc.getIngressBw().getSpeed()))
552 final WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
553 transaction.put(LogicalDatastoreType.CONFIGURATION, qosOtherConfigIid, qOtherConfig, true);
554 final CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
557 LOG.info("Update qos-entries max-rate to ovsdb for node {} {}", ovsdbNodeId, qosOtherConfigIid);;
558 } catch (final TransactionCommitFailedException e) {
559 LOG.warn("Failed to put {}", qosOtherConfigIid, e);
563 private static void updateQueuesMaxRate(DataBroker dataBroker,
564 Optional<Node> optionalOvsdbNode,
565 EvcAugmentation evc) {
566 final NodeId ovsdbNodeId = optionalOvsdbNode.get().getNodeId();
567 final List<Queues> queues = optionalOvsdbNode.get()
568 .getAugmentation(OvsdbNodeAugmentation.class)
570 QueuesKey queuesKey = null;
571 for (final Queues queue: queues) {
572 queuesKey = queue.getKey();
574 final InstanceIdentifier<QueuesOtherConfig> queuesOtherConfigIid = UnimgrMapper
575 .getQueuesOtherConfigIid(ovsdbNodeId, queuesKey);
576 final QueuesOtherConfig queuesOtherConfig = new QueuesOtherConfigBuilder()
577 .setKey(new QueuesOtherConfigKey(UnimgrConstants.QOS_MAX_RATE))
578 .setQueueOtherConfigKey(UnimgrConstants.QOS_MAX_RATE)
579 .setQueueOtherConfigValue(UniUtils.getSpeed(evc.getIngressBw().getSpeed()))
581 final WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
582 transaction.put(LogicalDatastoreType.CONFIGURATION, queuesOtherConfigIid, queuesOtherConfig, true);
583 final CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
586 LOG.info("Update queues max-rate to ovsdb for node {} {}", ovsdbNodeId, queuesOtherConfigIid);;
587 } catch (final TransactionCommitFailedException e) {
588 LOG.warn("Failed to put {} ", queuesOtherConfigIid, e);
593 * Creates an OVSDB node Id with an IP Address.
594 * @param ipAddress The IP address of the UNI (therefo the OVSDB node)
595 * @return A NodeId for a Specific Ovsdb Node Id
597 public static NodeId createOvsdbNodeId(IpAddress ipAddress) {
598 final String nodeId = UnimgrConstants.OVSDB_PREFIX
599 + ipAddress.getIpv4Address().getValue().toString()
601 + UnimgrConstants.OVSDB_PORT;
602 return new NodeId(nodeId);
606 * Creates a built OvsdbTerminationAugmentation with data
607 * @param uni The UNI's data
608 * @return A Built OvsdbTerminationPointAugmentation with data
610 public static OvsdbTerminationPointAugmentation createOvsdbTerminationPointAugmentation(Uni uni) {
611 // we will use nodeId to set interface port id
612 final VlanId vlanID = new VlanId(1);
613 final OvsdbTerminationPointAugmentation terminationPoint = new OvsdbTerminationPointAugmentationBuilder()
614 .setName(UnimgrConstants.DEFAULT_INTERNAL_IFACE)
616 .setVlanMode(VlanMode.Access)
618 return terminationPoint;
622 * Creates and Submit a termination point Node to the configuration DateStore.
623 * @param dataBroker The instance of the data broker to create transactions
624 * @param uni The UNI's data
625 * @param bridgeNode The Bridge node
626 * @param bridgeName The Bridge name (example: br0)
627 * @param portName The Port name (example: eth0)
628 * @param type The type of termination (example: gre) Refer to OVSDB_INTERFACE_TYPE_MAP
629 * to review the list of available Interface Types.
631 public static void createTerminationPointNode(DataBroker dataBroker,
637 final InstanceIdentifier<TerminationPoint> tpIid = UnimgrMapper
638 .getTerminationPointIid(bridgeNode,
640 final OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder =
641 new OvsdbTerminationPointAugmentationBuilder();
642 tpAugmentationBuilder.setName(portName);
644 tpAugmentationBuilder.setInterfaceType(SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP.get(type));
646 final TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
647 tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
648 tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class,
649 tpAugmentationBuilder.build());
650 final WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
651 transaction.put(LogicalDatastoreType.CONFIGURATION,
654 transaction.submit();
658 * Creates and Submit a termination point Node without specifying its interface type.
659 * @param dataBroker The instance of the data broker to create transactions
660 * @param uni The UNI's data
661 * @param bridgeNode The Bridge node
662 * @param bridgeName The Bridge name (example: br0)
663 * @param portName The Port name (example: eth0)
665 public static void createTerminationPointNode(DataBroker dataBroker,
670 final InstanceIdentifier<TerminationPoint> tpIid = UnimgrMapper
671 .getTerminationPointIid(bridgeNode,
673 final OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder =
674 new OvsdbTerminationPointAugmentationBuilder();
675 tpAugmentationBuilder.setName(portName);
676 tpAugmentationBuilder.setInterfaceType(null);
677 if (uni.getSpeed() != null) {
678 final Uuid qosUuid = getQosUuid(dataBroker, uni);
679 tpAugmentationBuilder.setQos(getQosUuid(dataBroker, uni));
680 LOG.info("Updating Qos {} to termination point {}", qosUuid , bridgeName);
682 final TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
683 tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
684 tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class,
685 tpAugmentationBuilder.build());
686 final WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
687 transaction.put(LogicalDatastoreType.CONFIGURATION,
690 transaction.submit();
693 private static Uuid getQosUuid(DataBroker dataBroker, Uni uni) {
695 final Optional<Node> optionalNode = UniUtils.findUniNode(dataBroker, uni.getIpAddress());
697 if (optionalNode.isPresent()) {
698 final UniAugmentation uniAugmentation = optionalNode.get()
699 .getAugmentation(UniAugmentation.class);
700 final Optional<Node> ovsdbNode = findOvsdbNode(dataBroker, uniAugmentation);
701 if (ovsdbNode.isPresent()) {
702 final List<QosEntries> qosEntries = ovsdbNode.get()
703 .getAugmentation(OvsdbNodeAugmentation.class)
705 for (final QosEntries qosEntry : qosEntries) {
706 qosUuid = qosEntry.getQosUuid();
714 * Deletes a generic node
715 * @param dataBroker The instance of the data broker to create transactions
716 * @param store The DataStore where the delete
717 * @param path The path to delete
718 * @return An instance of a generic Data Object
720 public <D extends org.opendaylight.yangtools.yang.binding.DataObject> boolean delete(
721 DataBroker dataBroker,
722 final LogicalDatastoreType store,
723 final InstanceIdentifier<D> path) {
724 boolean result = false;
725 final WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
726 transaction.delete(store, path);
727 final CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
731 } catch (final TransactionCommitFailedException e) {
732 LOG.warn("Failed to delete {} ", path, e);
738 * Deletes a termination Point from the configuration data store.
739 * @param dataBroker The instance of the data broker to create transactions
740 * @param terminationPoint The Termination Point of the OVSDB bridge
741 * @param ovsdbNode The ovsdb Node
742 * @return A checked Future
744 public static CheckedFuture<Void, TransactionCommitFailedException> deleteTerminationPoint(DataBroker dataBroker,
745 TerminationPoint terminationPoint,
747 final InstanceIdentifier<TerminationPoint> terminationPointPath =
749 .create(NetworkTopology.class)
750 .child(Topology.class,
751 new TopologyKey(UnimgrConstants.OVSDB_TOPOLOGY_ID))
754 .child(TerminationPoint.class,
755 terminationPoint.getKey());
756 final WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
757 transaction.delete(LogicalDatastoreType.CONFIGURATION, terminationPointPath);
758 transaction.delete(LogicalDatastoreType.OPERATIONAL, terminationPointPath);
759 return transaction.submit();
764 * Extract a data object by using its instance indentifier and it's class type.
765 * @param changes Data Change object
766 * @param klazz Class type
767 * @return The extracted DataObject as an Object casted as the class type
769 public static <T extends DataObject> Map<InstanceIdentifier<T>,T> extract(
770 Map<InstanceIdentifier<?>, DataObject> changes, Class<T> klazz) {
771 final Map<InstanceIdentifier<T>,T> result = new HashMap<InstanceIdentifier<T>,T>();
772 if ((changes != null) && (changes.entrySet() != null)) {
773 for (final Entry<InstanceIdentifier<?>, DataObject> created : changes.entrySet()) {
774 if (klazz.isInstance(created.getValue())) {
775 @SuppressWarnings("unchecked")
777 T value = (T) created.getValue();
778 final Class<?> type = created.getKey().getTargetType();
779 if (type.equals(klazz)) {
780 @SuppressWarnings("unchecked") // Actually checked above
782 InstanceIdentifier<T> iid = (InstanceIdentifier<T>) created.getKey();
783 result.put(iid, value);
792 * Extract original data from the data store.
793 * @param changes The dataChange object
794 * @param klazz The class type
795 * @return The DataObject casted as a Class type
797 public static <T extends DataObject> Map<InstanceIdentifier<T>,T> extractOriginal(
798 AsyncDataChangeEvent<InstanceIdentifier<?>,DataObject> changes,Class<T> klazz) {
799 return extract(changes.getOriginalData(),klazz);
803 * Extracts the removed nodes
804 * @param changes he dataChange object
805 * @param klazz The class type
806 * @return A set to removed nodes as DataObject casted as the class type
808 public static <T extends DataObject> Set<InstanceIdentifier<T>> extractRemoved(
809 AsyncDataChangeEvent<InstanceIdentifier<?>,DataObject> changes,Class<T> klazz) {
810 final Set<InstanceIdentifier<T>> result = new HashSet<InstanceIdentifier<T>>();
811 if ((changes != null) && (changes.getRemovedPaths() != null)) {
812 for (final InstanceIdentifier<?> iid : changes.getRemovedPaths()) {
813 if (iid.getTargetType().equals(klazz)) {
814 @SuppressWarnings("unchecked") // Actually checked above
816 InstanceIdentifier<T> iidn = (InstanceIdentifier<T>)iid;
825 * Search the Operational Datastore for a specific OvsdbNode.
826 * @param dataBroker The dataBroker instance to create transactions
827 * @param uni The UNI's data
828 * @return The Optional OvsdbNode
830 public static Optional<Node> findOvsdbNode(DataBroker dataBroker,
831 UniAugmentation uni) {
832 final List<Node> ovsdbNodes = getOvsdbNodes(dataBroker);
833 Optional<Node> optionalOvsdb;
834 if (!ovsdbNodes.isEmpty()) {
835 for (final Node ovsdbNode : ovsdbNodes) {
836 final OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode
837 .getAugmentation(OvsdbNodeAugmentation.class);
838 if (ovsdbNodeAugmentation.getConnectionInfo()
841 .equals(uni.getIpAddress().getIpv4Address())) {
842 LOG.info("Found ovsdb node");
843 optionalOvsdb = Optional.of(ovsdbNode);
844 return optionalOvsdb;
848 return Optional.absent();
852 * Retrieves the connection information from an Ovsdb Connection by
853 * using the Ovsdb Node Id
854 * @param dataBroker The dataBroker instance to create transactions
855 * @param ovsdbNodeId The NodeId of the OVSDB node
856 * @return The ConnectionInfo object
858 public static ConnectionInfo getConnectionInfo(DataBroker dataBroker,
859 NodeId ovsdbNodeId) {
860 final InstanceIdentifier<Node> nodeIid = UnimgrMapper.getOvsdbNodeIid(ovsdbNodeId);
861 final Optional<Node> node = MdsalUtils.readNode(dataBroker,
862 LogicalDatastoreType.OPERATIONAL,
864 if (node.isPresent()) {
865 final Node ovsdbNode = node.get();
866 final OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode
867 .getAugmentation(OvsdbNodeAugmentation.class);
868 return ovsdbNodeAugmentation.getConnectionInfo();
875 * Retrieve the Local IP of the controller
876 * @return The LocalIp object of the Controller
878 public static IpAddress getLocalIp() {
881 ip = InetAddress.getLocalHost().getHostAddress();
882 final Ipv4Address ipv4 = new Ipv4Address(ip);
883 return new IpAddress(ipv4);
884 } catch (final UnknownHostException e) {
885 LOG.info("Unable to retrieve controller's ip address, using loopback. {}", e);
887 return new IpAddress(UnimgrConstants.LOCAL_IP);
891 * Retrieve a list of Ovsdb Nodes from the Operational DataStore
892 * @param dataBroker The dataBroker instance to create transactions
893 * @return The Ovsdb Node retrieved from the Operational DataStore
895 public static List<Node> getOvsdbNodes(DataBroker dataBroker) {
896 final List<Node> ovsdbNodes = new ArrayList<>();
897 final InstanceIdentifier<Topology> ovsdbTopoIdentifier = UnimgrMapper.getOvsdbTopologyIid();
898 Topology topology = MdsalUtils.read(dataBroker,
899 LogicalDatastoreType.OPERATIONAL,
900 ovsdbTopoIdentifier);
901 if ((topology != null) && (topology.getNode() != null)) {
902 for (final Node node : topology.getNode()) {
903 final OvsdbNodeAugmentation ovsdbNodeAugmentation = node.getAugmentation(OvsdbNodeAugmentation.class);
904 if (ovsdbNodeAugmentation != null) {
905 ovsdbNodes.add(node);
909 topology = MdsalUtils.read(dataBroker, LogicalDatastoreType.CONFIGURATION, ovsdbTopoIdentifier);
910 if ((topology != null) && (topology.getNode() != null)) {
911 for (final Node node : topology.getNode()) {
912 final OvsdbNodeAugmentation ovsdbNodeAugmentation = node.getAugmentation(OvsdbNodeAugmentation.class);
913 if (ovsdbNodeAugmentation != null) {
914 ovsdbNodes.add(node);