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