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