Merge changes I4a8650ae,Ie2e119fd,Ic2acced7,Ieeb5ae5b,I2f7b6f8f
[ovsdb.git] / openstack / net-virt / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / impl / SouthboundImpl.java
1 /*
2  * Copyright (c) 2015 Red Hat, Inc. 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.ovsdb.openstack.netvirt.impl;
9
10 import java.math.BigInteger;
11 import java.security.InvalidParameterException;
12 import java.util.ArrayList;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.ovsdb.openstack.netvirt.MdsalHelper;
20 import org.opendaylight.ovsdb.openstack.netvirt.NetworkHandler;
21 import org.opendaylight.ovsdb.openstack.netvirt.api.OvsdbTables;
22 import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeNetdev;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdk;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntry;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchExternalIds;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsKey;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigs;
51 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
52 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
53 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
54 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
55 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
56 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
57 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
58 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
59 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
60 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
63
64 import com.google.common.collect.ImmutableBiMap;
65
66 /**
67  * Utility class to wrap mdsal transactions.
68  *
69  * @author Sam Hague (shague@redhat.com)
70  */
71 public class SouthboundImpl implements Southbound {
72     private static final Logger LOG = LoggerFactory.getLogger(SouthboundImpl.class);
73     private DataBroker databroker = null;
74     private static final String PATCH_PORT_TYPE = "patch";
75     private MdsalUtils mdsalUtils = null;
76
77     /**
78      * Class constructor setting the data broker.
79      *
80      * @param dataBroker the {@link org.opendaylight.controller.md.sal.binding.api.DataBroker}
81      */
82     public SouthboundImpl(DataBroker dataBroker) {
83         this.databroker = dataBroker;
84         mdsalUtils = new MdsalUtils(dataBroker);
85     }
86
87     public DataBroker getDatabroker() {
88         return databroker;
89     }
90
91     public ConnectionInfo getConnectionInfo(Node ovsdbNode) {
92         ConnectionInfo connectionInfo = null;
93         OvsdbNodeAugmentation ovsdbNodeAugmentation = extractOvsdbNode(ovsdbNode);
94         if (ovsdbNodeAugmentation != null) {
95             connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
96         }
97         return connectionInfo;
98     }
99
100     public OvsdbNodeAugmentation extractOvsdbNode(Node node) {
101         return node.getAugmentation(OvsdbNodeAugmentation.class);
102     }
103
104     public NodeId extractBridgeOvsdbNodeId(Node bridgeNode) {
105         NodeId ovsdbNodeId = null;
106         OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode);
107         if (bridgeAugmentation != null) {
108             @SuppressWarnings("unchecked")
109             InstanceIdentifier<Node> ovsdbNodeIid =
110                     (InstanceIdentifier<Node>) (bridgeAugmentation.getManagedBy().getValue());
111             ovsdbNodeId = InstanceIdentifier.keyOf(ovsdbNodeIid).getNodeId();
112         }
113         return ovsdbNodeId;
114     }
115
116     public List<Node> readOvsdbTopologyNodes() {
117         List<Node> ovsdbNodes = new ArrayList<>();
118         InstanceIdentifier<Topology> topologyInstanceIdentifier = MdsalHelper.createInstanceIdentifier();
119         Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyInstanceIdentifier);
120         if (topology != null && topology.getNode() != null) {
121             for (Node node : topology.getNode()) {
122                 OvsdbNodeAugmentation ovsdbNodeAugmentation = node.getAugmentation(OvsdbNodeAugmentation.class);
123                 if (ovsdbNodeAugmentation != null) {
124                     ovsdbNodes.add(node);
125                 }
126             }
127         }
128         return ovsdbNodes;
129     }
130
131     public List<Node> readOvsdbTopologyBridgeNodes() {
132         List<Node> ovsdbNodes = new ArrayList<>();
133         InstanceIdentifier<Topology> topologyInstanceIdentifier = MdsalHelper.createInstanceIdentifier();
134         Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyInstanceIdentifier);
135         if (topology != null && topology.getNode() != null) {
136             for (Node node : topology.getNode()) {
137                 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = node.getAugmentation(OvsdbBridgeAugmentation.class);
138                 if (ovsdbBridgeAugmentation != null) {
139                     ovsdbNodes.add(node);
140                 }
141             }
142         }
143         return ovsdbNodes;
144     }
145
146     public Node readOvsdbNode(Node bridgeNode) {
147         Node ovsdbNode = null;
148         OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode);
149         if (bridgeAugmentation != null) {
150             InstanceIdentifier<Node> ovsdbNodeIid =
151                     (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
152             ovsdbNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid);
153         }else{
154             LOG.debug("readOvsdbNode: Provided node is not a bridge node : {}",bridgeNode);
155         }
156         return ovsdbNode;
157     }
158
159     public String getOvsdbNodeUUID(Node node) {
160         String nodeUUID = null;
161         OvsdbNodeAugmentation ovsdbNodeAugmentation = node.getAugmentation(OvsdbNodeAugmentation.class);
162         if (ovsdbNodeAugmentation != null) {
163             // TODO replace with proper uuid and not the system-id
164             nodeUUID = getOsdbNodeExternalIdsValue(ovsdbNodeAugmentation, "system-id");
165         }
166         return nodeUUID;
167     }
168
169     public String getOsdbNodeExternalIdsValue(OvsdbNodeAugmentation ovsdbNodeAugmentation, String key) {
170         String value = null;
171         List<OpenvswitchExternalIds> pairs = ovsdbNodeAugmentation.getOpenvswitchExternalIds();
172         if (pairs != null && !pairs.isEmpty()) {
173             for (OpenvswitchExternalIds pair : pairs) {
174                 if (pair.getExternalIdKey().equals(key)) {
175                     value = pair.getExternalIdValue();
176                     break;
177                 }
178             }
179         }
180         return value;
181     }
182
183     public boolean addBridge(Node ovsdbNode, String bridgeName, List<String> controllersStr) {
184         boolean result = false;
185
186         LOG.info("addBridge: node: {}, bridgeName: {}, controller(s): {}", ovsdbNode, bridgeName, controllersStr);
187         ConnectionInfo connectionInfo = getConnectionInfo(ovsdbNode);
188         if (connectionInfo != null) {
189             NodeBuilder bridgeNodeBuilder = new NodeBuilder();
190             InstanceIdentifier<Node> bridgeIid =
191                     MdsalHelper.createInstanceIdentifier(ovsdbNode.getKey(), bridgeName);
192             NodeId bridgeNodeId = MdsalHelper.createManagedNodeId(bridgeIid);
193             bridgeNodeBuilder.setNodeId(bridgeNodeId);
194             OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
195             ovsdbBridgeAugmentationBuilder.setControllerEntry(createControllerEntries(controllersStr));
196             ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
197             ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
198             ovsdbBridgeAugmentationBuilder.setFailMode(
199                     MdsalHelper.OVSDB_FAIL_MODE_MAP.inverse().get("secure"));
200             setManagedByForBridge(ovsdbBridgeAugmentationBuilder, ovsdbNode.getKey());
201             if (isOvsdbNodeDpdk(ovsdbNode)) {
202                 ovsdbBridgeAugmentationBuilder.setDatapathType(DatapathTypeNetdev.class);
203             }
204             bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
205
206             result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, bridgeIid, bridgeNodeBuilder.build());
207             LOG.info("addBridge: result: {}", result);
208         } else {
209             throw new InvalidParameterException("Could not find ConnectionInfo");
210         }
211         return result;
212     }
213
214     public boolean deleteBridge(Node ovsdbNode) {
215         boolean result = false;
216         InstanceIdentifier<Node> bridgeIid =
217                 MdsalHelper.createInstanceIdentifier(ovsdbNode.getNodeId());
218
219         result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, bridgeIid);
220         LOG.info("deleteBridge node: {}, bridgeName: {} result : {}", ovsdbNode, ovsdbNode.getNodeId(),result);
221         return result;
222     }
223
224     public OvsdbBridgeAugmentation readBridge(Node node, String name) {
225         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
226         ConnectionInfo connectionInfo = getConnectionInfo(node);
227         if (connectionInfo != null) {
228             InstanceIdentifier<Node> bridgeIid =
229             MdsalHelper.createInstanceIdentifier(node.getKey(), name);
230             Node bridgeNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeIid);
231             if (bridgeNode != null) {
232                 ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
233             }
234         }
235         return ovsdbBridgeAugmentation;
236     }
237
238     public Node readBridgeNode(Node node, String name) {
239         Node ovsdbNode = node;
240         if (extractNodeAugmentation(ovsdbNode) == null) {
241             ovsdbNode = readOvsdbNode(node);
242         }
243         Node bridgeNode = null;
244         ConnectionInfo connectionInfo = getConnectionInfo(ovsdbNode);
245         if (connectionInfo != null) {
246             InstanceIdentifier<Node> bridgeIid =
247             MdsalHelper.createInstanceIdentifier(node.getKey(), name);
248             bridgeNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeIid);
249         }
250         return bridgeNode;
251     }
252
253     public Node getBridgeNode(Node node, String bridgeName) {
254         Node bridgeNode = null;
255         OvsdbBridgeAugmentation bridge = extractBridgeAugmentation(node);
256         if (bridge != null && bridge.getBridgeName().getValue().equals(bridgeName)) {
257                 bridgeNode = node;
258         } else {
259             bridgeNode = readBridgeNode(node, bridgeName);
260         }
261
262         return bridgeNode;
263     }
264
265     public String getBridgeUuid(Node node, String name) {
266         String uuid = null;
267         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = readBridge(node, name);
268         if (ovsdbBridgeAugmentation != null) {
269             uuid = ovsdbBridgeAugmentation.getBridgeUuid().getValue();
270         }
271         return uuid;
272     }
273
274     private void setManagedByForBridge(OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
275                 NodeKey ovsdbNodeKey) {
276             InstanceIdentifier<Node> connectionNodePath = MdsalHelper.createInstanceIdentifier(ovsdbNodeKey.getNodeId());
277         ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
278     }
279
280     private void setControllersForBridge(Node ovsdbNode, String bridgeName, List<String> controllersString) {
281         ConnectionInfo connectionInfo = getConnectionInfo(ovsdbNode);
282         if (connectionInfo != null) {
283             for (ControllerEntry controllerEntry : createControllerEntries(controllersString)) {
284                 InstanceIdentifier<ControllerEntry> iid =
285                         MdsalHelper.createInstanceIdentifier(ovsdbNode.getKey(), bridgeName)
286                                 .augmentation(OvsdbBridgeAugmentation.class)
287                                 .child(ControllerEntry.class, controllerEntry.getKey());
288
289                 boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, iid, controllerEntry);
290                 LOG.info("addController: result: {}", result);
291             }
292         }
293     }
294
295     private List<ControllerEntry> createControllerEntries(List<String> controllersStr) {
296         List<ControllerEntry> controllerEntries = new ArrayList<>();
297         if (controllersStr != null) {
298             for (String controllerStr : controllersStr) {
299                 ControllerEntryBuilder controllerEntryBuilder = new ControllerEntryBuilder();
300                 controllerEntryBuilder.setTarget(new Uri(controllerStr));
301                 controllerEntries.add(controllerEntryBuilder.build());
302             }
303         }
304         return controllerEntries;
305     }
306
307     private List<ProtocolEntry> createMdsalProtocols() {
308         List<ProtocolEntry> protocolList = new ArrayList<>();
309         ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
310                 MdsalHelper.OVSDB_PROTOCOL_MAP.inverse();
311         protocolList.add(new ProtocolEntryBuilder().
312                 setProtocol(mapper.get("OpenFlow13")).build());
313         return protocolList;
314     }
315
316     public long getDataPathId(Node node) {
317         long dpid = 0L;
318         String datapathId = getDatapathId(node);
319         if (datapathId != null) {
320             dpid = new BigInteger(datapathId.replaceAll(":", ""), 16).longValue();
321         }
322         return dpid;
323     }
324
325     public String getDatapathId(Node node) {
326         String datapathId = null;
327         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = node.getAugmentation(OvsdbBridgeAugmentation.class);
328         if (ovsdbBridgeAugmentation != null && ovsdbBridgeAugmentation.getDatapathId() != null) {
329             datapathId = node.getAugmentation(OvsdbBridgeAugmentation.class).getDatapathId().getValue();
330         }
331         return datapathId;
332     }
333
334     public String getDatapathId(OvsdbBridgeAugmentation ovsdbBridgeAugmentation) {
335         String datapathId = null;
336         if (ovsdbBridgeAugmentation != null && ovsdbBridgeAugmentation.getDatapathId() != null) {
337             datapathId = ovsdbBridgeAugmentation.getDatapathId().getValue();
338         }
339         return datapathId;
340     }
341
342     public OvsdbBridgeAugmentation getBridge(Node node, String name) {
343         OvsdbBridgeAugmentation bridge = node.getAugmentation(OvsdbBridgeAugmentation.class);
344         if ((bridge != null) && (!bridge.getBridgeName().getValue().equals(name))) {
345             bridge = null;
346         }
347         return bridge;
348     }
349
350     public OvsdbBridgeAugmentation getBridge(Node node) {
351         return node.getAugmentation(OvsdbBridgeAugmentation.class);
352     }
353
354     public String getBridgeName(Node node) {
355         String bridgeName = null;
356         OvsdbBridgeAugmentation bridge = getBridge(node);
357         if (bridge != null) {
358             bridgeName = bridge.getBridgeName().getValue();
359         }
360         return bridgeName;
361     }
362
363     public String extractBridgeName(Node node) {
364         return node.getAugmentation(OvsdbBridgeAugmentation.class).getBridgeName().getValue();
365     }
366
367     public OvsdbBridgeAugmentation extractBridgeAugmentation(Node node) {
368         if (node == null) {
369             return null;
370         }
371         return node.getAugmentation(OvsdbBridgeAugmentation.class);
372     }
373
374     public List<Node> getAllBridgesOnOvsdbNode(Node node) {
375         List<Node> nodes = new ArrayList<>();
376         List<ManagedNodeEntry> managedNodes = node.getAugmentation(OvsdbNodeAugmentation.class).getManagedNodeEntry();
377         for (ManagedNodeEntry managedNode : managedNodes) {
378             InstanceIdentifier<?> bridgeIid = managedNode.getBridgeRef().getValue();
379             Node bridgeNode = (Node) mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeIid);
380             if (bridgeNode != null) {
381                 nodes.add(bridgeNode);
382             }
383         }
384         return nodes;
385     }
386
387     public boolean isBridgeOnOvsdbNode(Node ovsdbNode, String bridgeName) {
388         boolean found = false;
389         OvsdbNodeAugmentation ovsdbNodeAugmentation = extractNodeAugmentation(ovsdbNode);
390         if (ovsdbNodeAugmentation != null) {
391             List<ManagedNodeEntry> managedNodes = ovsdbNodeAugmentation.getManagedNodeEntry();
392             if (managedNodes != null) {
393                 for (ManagedNodeEntry managedNode : managedNodes) {
394                     InstanceIdentifier<?> bridgeIid = managedNode.getBridgeRef().getValue();
395                     if (bridgeIid.toString().contains(bridgeName)) {
396                         found = true;
397                         break;
398                     }
399                 }
400             }
401         }
402         return found;
403     }
404
405     public boolean isOvsdbNodeDpdk(Node ovsdbNode) {
406         boolean found = false;
407         OvsdbNodeAugmentation ovsdbNodeAugmentation = extractNodeAugmentation(ovsdbNode);
408         if (ovsdbNodeAugmentation != null) {
409             List<InterfaceTypeEntry> ifTypes = ovsdbNodeAugmentation.getInterfaceTypeEntry();
410             if (ifTypes != null) {
411                 for (InterfaceTypeEntry ifType : ifTypes) {
412                     if (ifType.getInterfaceType().equals(InterfaceTypeDpdk.class)) {
413                         found = true;
414                         break;
415                     }
416                 }
417             }
418         }
419         return found;
420     }
421
422     public OvsdbNodeAugmentation extractNodeAugmentation(Node node) {
423         return node.getAugmentation(OvsdbNodeAugmentation.class);
424     }
425
426     /**
427      * Method read ports from bridge node. Method will check if the provided node
428      * has the ports details, if not, it will read from Operational data store.
429      * @param node Target bridge to getch termination points from.
430      * @return List of termination points on the given bridge
431      */
432     public List<OvsdbTerminationPointAugmentation> getTerminationPointsOfBridge(Node node) {
433         List<OvsdbTerminationPointAugmentation> tpAugmentations = extractTerminationPointAugmentations(node);
434         if(tpAugmentations.isEmpty()){
435             tpAugmentations = readTerminationPointAugmentations(node);
436         }
437         return tpAugmentations;
438     }
439
440     public OvsdbTerminationPointAugmentation getTerminationPointOfBridge(Node node, String portName) {
441         OvsdbTerminationPointAugmentation tpAugmentation = extractTerminationPointAugmentation(node,portName);
442         if(tpAugmentation == null){
443             List<OvsdbTerminationPointAugmentation> tpAugmentations = readTerminationPointAugmentations(node);
444             if(tpAugmentations != null){
445                 for(OvsdbTerminationPointAugmentation ovsdbTpAugmentation : tpAugmentations){
446                     if(ovsdbTpAugmentation.getName().equals(portName)){
447                         return ovsdbTpAugmentation;
448                     }
449                 }
450             }
451         }
452         return tpAugmentation;
453     }
454
455     public OvsdbTerminationPointAugmentation extractTerminationPointAugmentation(Node bridgeNode, String portName) {
456         if (bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class) != null) {
457             List<OvsdbTerminationPointAugmentation> tpAugmentations = extractTerminationPointAugmentations(bridgeNode);
458             for (OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation : tpAugmentations) {
459                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
460                     return ovsdbTerminationPointAugmentation;
461                 }
462             }
463         }
464         return null;
465     }
466
467     public List<TerminationPoint> extractTerminationPoints(Node node) {
468         List<TerminationPoint> terminationPoints = new ArrayList<>();
469         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = node.getAugmentation(OvsdbBridgeAugmentation.class);
470         if (ovsdbBridgeAugmentation != null) {
471             terminationPoints.addAll(node.getTerminationPoint());
472         }
473         return terminationPoints;
474     }
475
476     public List<OvsdbTerminationPointAugmentation> extractTerminationPointAugmentations( Node node ) {
477         List<OvsdbTerminationPointAugmentation> tpAugmentations = new ArrayList<>();
478         List<TerminationPoint> terminationPoints = node.getTerminationPoint();
479         if(terminationPoints != null && !terminationPoints.isEmpty()){
480             for(TerminationPoint tp : terminationPoints){
481                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
482                         tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
483                 if (ovsdbTerminationPointAugmentation != null) {
484                     tpAugmentations.add(ovsdbTerminationPointAugmentation);
485                 }
486             }
487         }
488         return tpAugmentations;
489     }
490
491     public List<OvsdbTerminationPointAugmentation> readTerminationPointAugmentations(Node node) {
492         InstanceIdentifier<Node> bridgeNodeIid = MdsalHelper.createInstanceIdentifier(node.getNodeId());
493         Node operNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeNodeIid);
494         if(operNode != null){
495             return extractTerminationPointAugmentations(operNode);
496         }
497         return new ArrayList<>();
498     }
499
500     public String getInterfaceExternalIdsValue(
501             OvsdbTerminationPointAugmentation terminationPointAugmentation, String key) {
502         String value = null;
503         List<InterfaceExternalIds> pairs = terminationPointAugmentation.getInterfaceExternalIds();
504         if (pairs != null && !pairs.isEmpty()) {
505             for (InterfaceExternalIds pair : pairs) {
506                 if (pair.getExternalIdKey().equals(key)) {
507                     value = pair.getExternalIdValue();
508                     break;
509                 }
510             }
511         }
512         return value;
513     }
514
515     public Boolean addTerminationPoint(Node bridgeNode, String bridgeName, String portName, String type) {
516         InstanceIdentifier<TerminationPoint> tpIid =
517                 MdsalHelper.createTerminationPointInstanceIdentifier(bridgeNode, portName);
518         OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder =
519                 new OvsdbTerminationPointAugmentationBuilder();
520
521         tpAugmentationBuilder.setName(portName);
522         if (type != null) {
523             tpAugmentationBuilder.setInterfaceType(MdsalHelper.OVSDB_INTERFACE_TYPE_MAP.get(type));
524         }
525         TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
526         tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
527         tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
528         return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
529     }
530
531     public Boolean deleteTerminationPoint(Node bridgeNode, String portName) {
532         InstanceIdentifier<TerminationPoint> tpIid =
533                 MdsalHelper.createTerminationPointInstanceIdentifier(bridgeNode, portName);
534         return mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, tpIid);
535     }
536
537     public Boolean addTerminationPoint(Node bridgeNode, String bridgeName, String portName,
538             String type, Map<String, String> options) {
539         InstanceIdentifier<TerminationPoint> tpIid = MdsalHelper.createTerminationPointInstanceIdentifier(
540                 bridgeNode, portName);
541         OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
542
543         tpAugmentationBuilder.setName(portName);
544         if (type != null) {
545             tpAugmentationBuilder.setInterfaceType(MdsalHelper.OVSDB_INTERFACE_TYPE_MAP.get(type));
546         }
547
548         List<Options> optionsList = new ArrayList<>();
549         for (Map.Entry<String, String> entry : options.entrySet()) {
550             OptionsBuilder optionsBuilder = new OptionsBuilder();
551             optionsBuilder.setKey(new OptionsKey(entry.getKey()));
552             optionsBuilder.setOption(entry.getKey());
553             optionsBuilder.setValue(entry.getValue());
554             optionsList.add(optionsBuilder.build());
555         }
556         tpAugmentationBuilder.setOptions(optionsList);
557
558         TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
559         tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
560         tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
561         /* TODO SB_MIGRATION should this be merge or mdsalUtils.put */
562         return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
563     }
564
565     public TerminationPoint readTerminationPoint(Node bridgeNode, String bridgeName, String portName) {
566         InstanceIdentifier<TerminationPoint> tpIid = MdsalHelper.createTerminationPointInstanceIdentifier(
567                 bridgeNode, portName);
568         return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, tpIid);
569     }
570
571     public Boolean addTunnelTerminationPoint(Node bridgeNode, String bridgeName, String portName, String type,
572                                         Map<String, String> options) {
573         return addTerminationPoint(bridgeNode, bridgeName, portName, type, options);
574     }
575
576     public Boolean isTunnelTerminationPointExist(Node bridgeNode, String bridgeName, String portName){
577         return readTerminationPoint(bridgeNode, bridgeName, portName) != null;
578     }
579
580     public Boolean addPatchTerminationPoint(Node node, String bridgeName, String portName, String peerPortName) {
581         Map<String, String> option = new HashMap<>();
582         option.put("peer", peerPortName);
583         return addTerminationPoint(node, bridgeName, portName, PATCH_PORT_TYPE, option);
584     }
585
586     public String getExternalId(Node node, OvsdbTables table, String key) {
587         switch (table) {
588         case BRIDGE:
589             OvsdbBridgeAugmentation bridge = extractBridgeAugmentation(node);
590             if (bridge != null && bridge.getBridgeExternalIds() != null) {
591                 for (BridgeExternalIds bridgeExternaIds :bridge.getBridgeExternalIds()) {
592                     if (bridgeExternaIds.getBridgeExternalIdKey().equals(key)) {
593                         return bridgeExternaIds.getBridgeExternalIdValue();
594                     }
595                 }
596             }
597             break;
598         case CONTROLLER:
599             LOG.warn("getExternalId: There is no external_id for OvsdbTables: ", table);
600             return null;
601         case OPENVSWITCH:
602             OvsdbNodeAugmentation ovsdbNode = extractNodeAugmentation(node);
603             if (ovsdbNode == null) {
604                 Node nodeFromReadOvsdbNode = readOvsdbNode(node);
605                 ovsdbNode = extractNodeAugmentation(nodeFromReadOvsdbNode);
606             }
607             if (ovsdbNode != null && ovsdbNode.getOpenvswitchExternalIds() != null) {
608                 for (OpenvswitchExternalIds openvswitchExternalIds : ovsdbNode.getOpenvswitchExternalIds()) {
609                     if (openvswitchExternalIds.getExternalIdKey().equals(key)) {
610                         return openvswitchExternalIds.getExternalIdValue();
611                     }
612                 }
613             }
614             break;
615         case PORT:
616             List <OvsdbTerminationPointAugmentation> ports = extractTerminationPointAugmentations(node);
617             for (OvsdbTerminationPointAugmentation port : ports) {
618                 if (port != null && port.getPortExternalIds() != null) {
619                     for (PortExternalIds portExternalIds :port.getPortExternalIds()) {
620                         if (portExternalIds.getExternalIdKey().equals(key)) {
621                             return portExternalIds.getExternalIdValue();
622                         }
623                     }
624                 }
625             }
626             break;
627         default:
628             LOG.debug("getExternalId: Couldn't find the specified OvsdbTable: ", table);
629             return null;
630         }
631         return null;
632     }
633
634     public String getOtherConfig(Node node, OvsdbTables table, String key) {
635         switch (table) {
636             case BRIDGE:
637                 OvsdbBridgeAugmentation bridge = extractBridgeAugmentation(node);
638                 if (bridge != null && bridge.getBridgeOtherConfigs() != null) {
639                     for (BridgeOtherConfigs bridgeOtherConfigs : bridge.getBridgeOtherConfigs()) {
640                         if (bridgeOtherConfigs.getBridgeOtherConfigKey().equals(key)) {
641                             return bridgeOtherConfigs.getBridgeOtherConfigValue();
642                         }
643                     }
644                 }
645                 break;
646             case CONTROLLER:
647                 LOG.warn("getOtherConfig: There is no other_config for OvsdbTables: ", table);
648                 return null;
649
650             case OPENVSWITCH:
651                 OvsdbNodeAugmentation ovsdbNode = extractNodeAugmentation(node);
652                 if (ovsdbNode == null) {
653                     Node nodeFromReadOvsdbNode = readOvsdbNode(node);
654                     ovsdbNode = extractNodeAugmentation(nodeFromReadOvsdbNode);
655                 }
656                 if (ovsdbNode != null && ovsdbNode.getOpenvswitchOtherConfigs() != null) {
657                     for (OpenvswitchOtherConfigs openvswitchOtherConfigs : ovsdbNode.getOpenvswitchOtherConfigs()) {
658                         if (openvswitchOtherConfigs.getOtherConfigKey().equals(key)) {
659                             return openvswitchOtherConfigs.getOtherConfigValue();
660                         }
661                     }
662                 }
663                 break;
664             case PORT:
665                 List <OvsdbTerminationPointAugmentation> ports = extractTerminationPointAugmentations(node);
666                 for (OvsdbTerminationPointAugmentation port : ports) {
667                     if (port != null && port.getPortOtherConfigs() != null) {
668                         for (PortOtherConfigs portOtherConfigs : port.getPortOtherConfigs()) {
669                             if (portOtherConfigs.getOtherConfigKey().equals(key)) {
670                                 return portOtherConfigs.getOtherConfigValue();
671                             }
672                         }
673                     }
674                 }
675                 break;
676             default:
677                 LOG.debug("getOtherConfig: Couldn't find the specified OvsdbTable: ", table);
678                 return null;
679         }
680         return null;
681     }
682
683     public boolean addVlanToTp(long vlan) {
684         return false;
685     }
686
687     public boolean isTunnel(OvsdbTerminationPointAugmentation port) {
688         LOG.trace("SouthboundImpl#isTunnel: Interface : {}", port);
689
690         if(port.getInterfaceType() == null){
691             LOG.warn("No type found for the interface : {}", port);
692             return false;
693         }
694         return MdsalHelper.createOvsdbInterfaceType(
695                 port.getInterfaceType()).equals(NetworkHandler.NETWORK_TYPE_VXLAN)
696                 || MdsalHelper.createOvsdbInterfaceType(
697                 port.getInterfaceType()).equals(NetworkHandler.NETWORK_TYPE_GRE);
698     }
699
700     public String getOptionsValue(List<Options> options, String key) {
701         String value = null;
702         for (Options option : options) {
703             if (option.getKey().equals(key)) {
704                 value = option.getValue();
705             }
706         }
707         return value;
708     }
709
710     public Topology getOvsdbTopology() {
711         InstanceIdentifier<Topology> path = InstanceIdentifier
712                 .create(NetworkTopology.class)
713                 .child(Topology.class, new TopologyKey(MdsalHelper.OVSDB_TOPOLOGY_ID));
714
715         return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
716     }
717
718     public Long getOFPort(OvsdbTerminationPointAugmentation port) {
719         Long ofPort = 0L;
720         if (port.getOfport() != null) {
721             ofPort = port.getOfport();
722         }
723         return ofPort;
724     }
725
726     public Long getOFPort(Node bridgeNode, String portName) {
727         Long ofPort = 0L;
728         OvsdbTerminationPointAugmentation port = extractTerminationPointAugmentation(bridgeNode, portName);
729         if (port != null) {
730             ofPort = getOFPort(port);
731         } else {
732             TerminationPoint tp = readTerminationPoint(bridgeNode, null, portName);
733             if (tp != null) {
734                 port = tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
735                 if (port != null) {
736                     ofPort = getOFPort(port);
737                 }
738             }
739         }
740         return ofPort;
741     }
742     public OvsdbBridgeAugmentation getBridgeFromConfig(Node node, String bridge) {
743         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
744         InstanceIdentifier<Node> bridgeIid =
745                 MdsalHelper.createInstanceIdentifier(node.getKey(), bridge);
746         Node bridgeNode = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, bridgeIid);
747         if (bridgeNode != null) {
748             ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
749         }
750         return ovsdbBridgeAugmentation;
751     }
752 }