Add methods to SouthboundUtils for ElanService
[ovsdb.git] / utils / southbound-utils / src / main / java / org / opendaylight / ovsdb / utils / southbound / utils / SouthboundUtils.java
1 /*
2  * Copyright (c) 2015 - 2016 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
9 package org.opendaylight.ovsdb.utils.southbound.utils;
10
11 import java.math.BigInteger;
12 import java.net.Inet4Address;
13 import java.net.Inet6Address;
14 import java.net.InetAddress;
15 import java.net.NetworkInterface;
16 import java.net.UnknownHostException;
17 import java.security.InvalidParameterException;
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.Enumeration;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.ovsdb.utils.config.ConfigProperties;
27 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathId;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeNetdev;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdk;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdkr;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdkvhost;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeDpdkvhostuser;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeGeneve;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeGre;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeGre64;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeInternal;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeIpsecGre;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeIpsecGre64;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeLisp;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypePatch;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeSystem;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeTap;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeVxlan;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeVxlanGpe;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow10;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow11;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow12;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow13;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow14;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolOpenflow15;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeBase;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeSecure;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeStandalone;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentationBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntry;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagerEntry;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsKey;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsKey;
89 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
90 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
91 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
92 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
93 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
94 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
95 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
96 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
97 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
98 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
99 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
100 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
101 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
102 import org.slf4j.Logger;
103 import org.slf4j.LoggerFactory;
104
105 import com.google.common.collect.ImmutableBiMap;
106
107 public class SouthboundUtils {
108     private static final Logger LOG = LoggerFactory.getLogger(SouthboundUtils.class);
109     private static final int OVSDB_UPDATE_TIMEOUT = 1000;
110     public static final TopologyId OVSDB_TOPOLOGY_ID = new TopologyId(new Uri("ovsdb:1"));
111     private final MdsalUtils mdsalUtils;
112     public static final String OPENFLOW_CONNECTION_PROTOCOL = "tcp";
113     public static short OPENFLOW_PORT = 6653;
114     public static final String OVSDB_URI_PREFIX = "ovsdb";
115     public static final String BRIDGE_URI_PREFIX = "bridge";
116     private static final String DISABLE_IN_BAND = "disable-in-band";
117     private static final String PATCH_PORT_TYPE = "patch";
118
119     public SouthboundUtils(MdsalUtils mdsalUtils) {
120         this.mdsalUtils = mdsalUtils;
121     }
122
123     public static final ImmutableBiMap<String, Class<? extends InterfaceTypeBase>> OVSDB_INTERFACE_TYPE_MAP
124             = new ImmutableBiMap.Builder<String, Class<? extends InterfaceTypeBase>>()
125             .put("internal", InterfaceTypeInternal.class)
126             .put("vxlan", InterfaceTypeVxlan.class)
127             .put("vxlan-gpe", InterfaceTypeVxlanGpe.class)
128             .put("patch", InterfaceTypePatch.class)
129             .put("system", InterfaceTypeSystem.class)
130             .put("tap", InterfaceTypeTap.class)
131             .put("geneve", InterfaceTypeGeneve.class)
132             .put("gre", InterfaceTypeGre.class)
133             .put("ipsec_gre", InterfaceTypeIpsecGre.class)
134             .put("gre64", InterfaceTypeGre64.class)
135             .put("ipsec_gre64", InterfaceTypeIpsecGre64.class)
136             .put("lisp", InterfaceTypeLisp.class)
137             .put("dpdk", InterfaceTypeDpdk.class)
138             .put("dpdkr", InterfaceTypeDpdkr.class)
139             .put("dpdkvhost", InterfaceTypeDpdkvhost.class)
140             .put("dpdkvhostuser", InterfaceTypeDpdkvhostuser.class)
141             .build();
142
143     public static final ImmutableBiMap<Class<? extends OvsdbBridgeProtocolBase>,String> OVSDB_PROTOCOL_MAP
144             = new ImmutableBiMap.Builder<Class<? extends OvsdbBridgeProtocolBase>,String>()
145             .put(OvsdbBridgeProtocolOpenflow10.class,"OpenFlow10")
146             .put(OvsdbBridgeProtocolOpenflow11.class,"OpenFlow11")
147             .put(OvsdbBridgeProtocolOpenflow12.class,"OpenFlow12")
148             .put(OvsdbBridgeProtocolOpenflow13.class,"OpenFlow13")
149             .put(OvsdbBridgeProtocolOpenflow14.class,"OpenFlow14")
150             .put(OvsdbBridgeProtocolOpenflow15.class,"OpenFlow15")
151             .build();
152
153     private static final ImmutableBiMap<Class<? extends OvsdbFailModeBase>,String> OVSDB_FAIL_MODE_MAP
154             = new ImmutableBiMap.Builder<Class<? extends OvsdbFailModeBase>,String>()
155             .put(OvsdbFailModeStandalone.class,"standalone")
156             .put(OvsdbFailModeSecure.class,"secure")
157             .build();
158
159     public static NodeId createNodeId(IpAddress ip, PortNumber port) {
160         String uriString = OVSDB_URI_PREFIX + "://"
161                 + String.valueOf(ip.getValue()) + ":" + port.getValue();
162         Uri uri = new Uri(uriString);
163         return new NodeId(uri);
164     }
165
166     public static Node createNode(ConnectionInfo key) {
167         NodeBuilder nodeBuilder = new NodeBuilder();
168         nodeBuilder.setNodeId(createNodeId(key.getRemoteIp(), key.getRemotePort()));
169         nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, createOvsdbAugmentation(key));
170         return nodeBuilder.build();
171     }
172
173     public static OvsdbNodeAugmentation createOvsdbAugmentation(ConnectionInfo key) {
174         OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
175         ovsdbNodeBuilder.setConnectionInfo(key);
176         return ovsdbNodeBuilder.build();
177     }
178
179     public static InstanceIdentifier<Node> createInstanceIdentifier(NodeId nodeId) {
180         return InstanceIdentifier
181                 .create(NetworkTopology.class)
182                 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
183                 .child(Node.class,new NodeKey(nodeId));
184     }
185
186     public static InstanceIdentifier<Node> createInstanceIdentifier(NodeKey ovsdbNodeKey, String bridgeName) {
187         return createInstanceIdentifier(createManagedNodeId(ovsdbNodeKey.getNodeId(), bridgeName));
188     }
189
190     public static NodeId createManagedNodeId(NodeId ovsdbNodeId, String bridgeName) {
191         return new NodeId(ovsdbNodeId.getValue()
192                 + "/" + BRIDGE_URI_PREFIX + "/" + bridgeName);
193     }
194
195     public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key) {
196         return createInstanceIdentifier(key.getRemoteIp(), key.getRemotePort());
197     }
198
199     public static InstanceIdentifier<Node> createInstanceIdentifier(IpAddress ip, PortNumber port) {
200         InstanceIdentifier<Node> path = InstanceIdentifier
201                 .create(NetworkTopology.class)
202                 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
203                 .child(Node.class,createNodeKey(ip,port));
204         LOG.debug("Created ovsdb path: {}",path);
205         return path;
206     }
207
208     public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key,OvsdbBridgeName bridgeName) {
209         return createInstanceIdentifier(createManagedNodeId(key, bridgeName));
210     }
211
212     public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key, String bridgeName) {
213         return createInstanceIdentifier(key, new OvsdbBridgeName(bridgeName));
214     }
215
216     public InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(Node node, String portName){
217
218         InstanceIdentifier<TerminationPoint> terminationPointPath = InstanceIdentifier
219                 .create(NetworkTopology.class)
220                 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
221                 .child(Node.class,node.getKey())
222                 .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
223
224         LOG.debug("Termination point InstanceIdentifier generated : {}",terminationPointPath);
225         return terminationPointPath;
226     }
227
228     public static NodeKey createNodeKey(IpAddress ip, PortNumber port) {
229         return new NodeKey(createNodeId(ip, port));
230     }
231
232     public static NodeId createManagedNodeId(ConnectionInfo key, OvsdbBridgeName bridgeName) {
233         return createManagedNodeId(key.getRemoteIp(), key.getRemotePort(), bridgeName);
234     }
235
236     public static NodeId createManagedNodeId(IpAddress ip, PortNumber port, OvsdbBridgeName bridgeName) {
237         return new NodeId(createNodeId(ip,port).getValue()
238                 + "/" + BRIDGE_URI_PREFIX + "/" + bridgeName.getValue());
239     }
240
241     public static NodeId createManagedNodeId(InstanceIdentifier<Node> iid) {
242         NodeKey nodeKey = iid.firstKeyOf(Node.class);
243         return nodeKey.getNodeId();
244     }
245
246     public ConnectionInfo getConnectionInfo(Node ovsdbNode) {
247         ConnectionInfo connectionInfo = null;
248         OvsdbNodeAugmentation ovsdbNodeAugmentation = extractOvsdbNode(ovsdbNode);
249         if (ovsdbNodeAugmentation != null) {
250             connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
251         }
252         return connectionInfo;
253     }
254
255     public OvsdbNodeAugmentation extractOvsdbNode(Node node) {
256         return node.getAugmentation(OvsdbNodeAugmentation.class);
257     }
258
259     public static IpAddress createIpAddress(InetAddress address) {
260         IpAddress ip = null;
261         if (address instanceof Inet4Address) {
262             ip = createIpAddress((Inet4Address)address);
263         } else if (address instanceof Inet6Address) {
264             ip = createIpAddress((Inet6Address)address);
265         }
266         return ip;
267     }
268
269     public static IpAddress createIpAddress(Inet4Address address) {
270         return IetfInetUtil.INSTANCE.ipAddressFor(address);
271     }
272
273     public static IpAddress createIpAddress(Inet6Address address) {
274         Ipv6Address ipv6 = new Ipv6Address(address.getHostAddress());
275         return new IpAddress(ipv6);
276     }
277
278     public static ConnectionInfo getConnectionInfo(final String addressStr, final String portStr) {
279         InetAddress inetAddress = null;
280         try {
281             inetAddress = InetAddress.getByName(addressStr);
282         } catch (UnknownHostException e) {
283             LOG.warn("Could not allocate InetAddress", e);
284         }
285
286         IpAddress address = createIpAddress(inetAddress);
287         PortNumber port = new PortNumber(Integer.parseInt(portStr));
288
289         LOG.info("connectionInfo: {}", new ConnectionInfoBuilder()
290                 .setRemoteIp(address)
291                 .setRemotePort(port)
292                 .build());
293         return new ConnectionInfoBuilder()
294                 .setRemoteIp(address)
295                 .setRemotePort(port)
296                 .build();
297     }
298
299     public static String connectionInfoToString(final ConnectionInfo connectionInfo) {
300         return String.valueOf(
301                 connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
302     }
303
304     public boolean addOvsdbNode(final ConnectionInfo connectionInfo) {
305         return addOvsdbNode(connectionInfo, OVSDB_UPDATE_TIMEOUT);
306     }
307
308     public boolean addOvsdbNode(final ConnectionInfo connectionInfo, long timeout) {
309         boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
310                 createInstanceIdentifier(connectionInfo),
311                 createNode(connectionInfo));
312         if (timeout != 0) {
313             try {
314                 Thread.sleep(timeout);
315             } catch (InterruptedException e) {
316                 LOG.warn("Interrupted while waiting after adding OVSDB node {}",
317                         connectionInfoToString(connectionInfo), e);
318             }
319         }
320         return result;
321     }
322
323     public Node getOvsdbNode(final ConnectionInfo connectionInfo) {
324         return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
325                 createInstanceIdentifier(connectionInfo));
326     }
327
328     public boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) {
329         return deleteOvsdbNode(connectionInfo, OVSDB_UPDATE_TIMEOUT);
330     }
331
332     public boolean deleteOvsdbNode(final ConnectionInfo connectionInfo, long timeout) {
333         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
334                 createInstanceIdentifier(connectionInfo));
335         if (timeout != 0) {
336             try {
337                 Thread.sleep(timeout);
338             } catch (InterruptedException e) {
339                 LOG.warn("Interrupted while waiting after deleting OVSDB node {}",
340                         connectionInfoToString(connectionInfo), e);
341             }
342         }
343         return result;
344     }
345
346     public Node connectOvsdbNode(final ConnectionInfo connectionInfo) {
347         return connectOvsdbNode(connectionInfo, OVSDB_UPDATE_TIMEOUT);
348     }
349
350     public Node connectOvsdbNode(final ConnectionInfo connectionInfo, long timeout) {
351         addOvsdbNode(connectionInfo, timeout);
352         Node node = getOvsdbNode(connectionInfo);
353         LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
354         return node;
355     }
356
357     public boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) {
358         return disconnectOvsdbNode(connectionInfo, OVSDB_UPDATE_TIMEOUT);
359     }
360
361     public boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo, long timeout) {
362         deleteOvsdbNode(connectionInfo, timeout);
363         LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
364         return true;
365     }
366
367     public List<ControllerEntry> createControllerEntry(String controllerTarget) {
368         List<ControllerEntry> controllerEntriesList = new ArrayList<>();
369         controllerEntriesList.add(new ControllerEntryBuilder()
370                 .setTarget(new Uri(controllerTarget))
371                 .build());
372         return controllerEntriesList;
373     }
374
375     /**
376      * Extract the <code>store</code> type data store contents for the particular bridge identified by
377      * <code>bridgeName</code>.
378      *
379      * @param connectionInfo address for the node
380      * @param bridgeName name of the bridge
381      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
382      * @return <code>store</code> type data store contents
383      */
384     public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
385                                               LogicalDatastoreType store) {
386         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
387         Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
388         if (bridgeNode != null) {
389             ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
390         }
391         return ovsdbBridgeAugmentation;
392     }
393
394     /**
395      * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
396      * identified by <code>bridgeName</code>
397      *
398      * @param connectionInfo address for the node
399      * @param bridgeName name of the bridge
400      * @see <code>NetvirtIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
401      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
402      */
403     public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
404         return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
405     }
406
407     /**
408      * Extract the node contents from <code>store</code> type data store for the
409      * bridge identified by <code>bridgeName</code>.
410      *
411      * @param connectionInfo address for the node
412      * @param bridgeName name of the bridge
413      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
414      * @return <code>store</code> type data store contents
415      */
416     public Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
417         InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
418         return mdsalUtils.read(store, bridgeIid);
419     }
420
421     public Node getBridgeNode(Node node, String bridgeName) {
422         OvsdbBridgeAugmentation bridge = extractBridgeAugmentation(node);
423         if (bridge != null && bridge.getBridgeName().getValue().equals(bridgeName)) {
424             return node;
425         } else {
426             return readBridgeNode(node, bridgeName);
427         }
428     }
429
430     public Node readBridgeNode(Node node, String name) {
431         Node ovsdbNode = node;
432         if (extractNodeAugmentation(ovsdbNode) == null) {
433             ovsdbNode = readOvsdbNode(node);
434             if (ovsdbNode == null) {
435                 return null;
436             }
437         }
438         Node bridgeNode = null;
439         ConnectionInfo connectionInfo = getConnectionInfo(ovsdbNode);
440         if (connectionInfo != null) {
441             InstanceIdentifier<Node> bridgeIid =
442                     createInstanceIdentifier(node.getKey(), name);
443             bridgeNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, bridgeIid);
444         }
445         return bridgeNode;
446     }
447
448     public OvsdbNodeAugmentation extractNodeAugmentation(Node node) {
449         return node.getAugmentation(OvsdbNodeAugmentation.class);
450     }
451
452     public OvsdbBridgeAugmentation extractBridgeAugmentation(Node node) {
453         if (node == null) {
454             return null;
455         }
456         return node.getAugmentation(OvsdbBridgeAugmentation.class);
457     }
458
459     public Node readOvsdbNode(Node bridgeNode) {
460         Node ovsdbNode = null;
461         OvsdbBridgeAugmentation bridgeAugmentation = extractBridgeAugmentation(bridgeNode);
462         if (bridgeAugmentation != null) {
463             InstanceIdentifier<Node> ovsdbNodeIid =
464                     (InstanceIdentifier<Node>) bridgeAugmentation.getManagedBy().getValue();
465             ovsdbNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, ovsdbNodeIid);
466         }else{
467             LOG.debug("readOvsdbNode: Provided node is not a bridge node : {}",bridgeNode);
468         }
469         return ovsdbNode;
470     }
471
472     public boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName) {
473         return deleteBridge(connectionInfo, bridgeName, OVSDB_UPDATE_TIMEOUT);
474     }
475
476     public boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName, long timeout) {
477         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
478                 createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName)));
479         if (timeout != 0) {
480             try {
481                 Thread.sleep(timeout);
482             } catch (InterruptedException e) {
483                 LOG.warn("Interrupted while waiting after deleting bridge {}", bridgeName, e);
484             }
485         }
486         return result;
487     }
488
489     public List<ProtocolEntry> createMdsalProtocols() {
490         List<ProtocolEntry> protocolList = new ArrayList<>();
491         ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
492                 OVSDB_PROTOCOL_MAP.inverse();
493         protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build());
494         return protocolList;
495     }
496
497     public boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
498                              final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
499                              final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
500                              final Class<? extends DatapathTypeBase> dpType,
501                              final List<BridgeExternalIds> externalIds,
502                              final List<ControllerEntry> controllerEntries,
503                              final List<BridgeOtherConfigs> otherConfigs,
504                              final String dpid) throws InterruptedException {
505         return addBridge(connectionInfo, bridgeIid, bridgeName, bridgeNodeId, setProtocolEntries, failMode,
506                 setManagedBy, dpType, externalIds, controllerEntries, otherConfigs, dpid);
507     }
508
509     /*
510      * base method for adding test bridges.  Other helper methods used to create bridges should utilize this method.
511      *
512      * @param connectionInfo
513      * @param bridgeIid if passed null, one is created
514      * @param bridgeName cannot be null
515      * @param bridgeNodeId if passed null, one is created based on <code>bridgeIid</code>
516      * @param setProtocolEntries toggles whether default protocol entries are set for the bridge
517      * @param failMode toggles whether default fail mode is set for the bridge
518      * @param setManagedBy toggles whether to setManagedBy for the bridge
519      * @param dpType if passed null, this parameter is ignored
520      * @param externalIds if passed null, this parameter is ignored
521      * @param otherConfig if passed null, this parameter is ignored
522      * @return success of bridge addition
523      * @throws InterruptedException
524      */
525     public boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
526                              final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
527                              final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
528                              final Class<? extends DatapathTypeBase> dpType,
529                              final List<BridgeExternalIds> externalIds,
530                              final List<ControllerEntry> controllerEntries,
531                              final List<BridgeOtherConfigs> otherConfigs,
532                              final String dpid, long timeout) throws InterruptedException {
533
534         NodeBuilder bridgeNodeBuilder = new NodeBuilder();
535         if (bridgeIid == null) {
536             bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
537         }
538         if (bridgeNodeId == null) {
539             bridgeNodeId = createManagedNodeId(bridgeIid);
540         }
541         bridgeNodeBuilder.setNodeId(bridgeNodeId);
542         OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
543         ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
544         if (setProtocolEntries) {
545             ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
546         }
547         if (failMode != null) {
548             ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
549         }
550         if (setManagedBy) {
551             setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
552         }
553         if (dpType != null) {
554             ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
555         }
556         if (externalIds != null) {
557             ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
558         }
559         if (controllerEntries != null) {
560             ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
561         }
562         if (otherConfigs != null) {
563             ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
564         }
565         if (dpid != null && !dpid.isEmpty()) {
566             DatapathId datapathId = new DatapathId(dpid);
567             ovsdbBridgeAugmentationBuilder.setDatapathId(datapathId);
568         }
569         bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
570         LOG.debug("Built with the intent to store bridge data {}",
571                 ovsdbBridgeAugmentationBuilder.toString());
572         boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
573                 bridgeIid, bridgeNodeBuilder.build());
574         if (timeout != 0) {
575             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
576         }
577         return result;
578     }
579
580     public boolean addBridge(Node ovsdbNode, String bridgeName, List<String> controllersStr,
581                              final Class<? extends DatapathTypeBase> dpType, String mac) {
582         boolean result;
583
584         LOG.info("addBridge: node: {}, bridgeName: {}, controller(s): {}", ovsdbNode, bridgeName, controllersStr);
585         ConnectionInfo connectionInfo = getConnectionInfo(ovsdbNode);
586         if (connectionInfo != null) {
587             NodeBuilder bridgeNodeBuilder = new NodeBuilder();
588             InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(ovsdbNode.getKey(), bridgeName);
589             NodeId bridgeNodeId = createManagedNodeId(bridgeIid);
590             bridgeNodeBuilder.setNodeId(bridgeNodeId);
591             OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
592             ovsdbBridgeAugmentationBuilder.setControllerEntry(createControllerEntries(controllersStr));
593             ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
594             ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
595             ovsdbBridgeAugmentationBuilder.setFailMode( OVSDB_FAIL_MODE_MAP.inverse().get("secure"));
596             BridgeOtherConfigsBuilder bridgeOtherConfigsBuilder = new BridgeOtherConfigsBuilder();
597             bridgeOtherConfigsBuilder.setBridgeOtherConfigKey(DISABLE_IN_BAND);
598             bridgeOtherConfigsBuilder.setBridgeOtherConfigValue("true");
599             List<BridgeOtherConfigs> bridgeOtherConfigsList = new ArrayList<>();
600             bridgeOtherConfigsList.add(bridgeOtherConfigsBuilder.build());
601             if (mac != null) {
602                 BridgeOtherConfigsBuilder macOtherConfigBuilder = new BridgeOtherConfigsBuilder();
603                 macOtherConfigBuilder.setBridgeOtherConfigKey("hwaddr");
604                 macOtherConfigBuilder.setBridgeOtherConfigValue(mac);
605                 bridgeOtherConfigsList.add(macOtherConfigBuilder.build());
606             }
607             ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(bridgeOtherConfigsList);
608             setManagedByForBridge(ovsdbBridgeAugmentationBuilder, ovsdbNode.getKey());
609             if (dpType != null) {
610                 ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
611             }
612             if (isOvsdbNodeDpdk(ovsdbNode)) {
613                 ovsdbBridgeAugmentationBuilder.setDatapathType(DatapathTypeNetdev.class);
614             }
615             bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
616
617             Node node = bridgeNodeBuilder.build();
618             result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, bridgeIid, node);
619             LOG.info("addBridge: result: {}", result);
620         } else {
621             throw new InvalidParameterException("Could not find ConnectionInfo");
622         }
623         return result;
624     }
625
626
627     private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
628                               final ConnectionInfo connectionInfo) {
629         InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(connectionInfo);
630         ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
631     }
632
633     public boolean addTerminationPoint(
634             Node bridgeNode, String portName, String type, Map<String, String> options,
635             Map<String, String> externalIds) {
636         return addTerminationPoint(bridgeNode, portName, type, options, externalIds, null);
637     }
638
639     public boolean addTerminationPoint(
640             Node bridgeNode, String portName, String type, Map<String, String> options, Map<String, String> externalIds,
641             Long ofPort) {
642         InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(bridgeNode, portName);
643         OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
644
645         tpAugmentationBuilder.setName(portName);
646         tpAugmentationBuilder.setOfport(ofPort);
647         if (type != null) {
648             tpAugmentationBuilder.setInterfaceType(OVSDB_INTERFACE_TYPE_MAP.get(type));
649         }
650
651         if (options != null && options.size() > 0) {
652             List<Options> optionsList = new ArrayList<>();
653             for (Map.Entry<String, String> entry : options.entrySet()) {
654                 OptionsBuilder optionsBuilder = new OptionsBuilder();
655                 optionsBuilder.setKey(new OptionsKey(entry.getKey()));
656                 optionsBuilder.setOption(entry.getKey());
657                 optionsBuilder.setValue(entry.getValue());
658                 optionsList.add(optionsBuilder.build());
659             }
660             tpAugmentationBuilder.setOptions(optionsList);
661         }
662
663         if (externalIds != null && externalIds.size() > 0) {
664             List<InterfaceExternalIds> externalIdsList = new ArrayList<>();
665             for (Map.Entry<String, String> entry : externalIds.entrySet()) {
666                 InterfaceExternalIdsBuilder interfaceExternalIdsBuilder = new InterfaceExternalIdsBuilder();
667                 interfaceExternalIdsBuilder.setKey(new InterfaceExternalIdsKey(entry.getKey()));
668                 interfaceExternalIdsBuilder.setExternalIdKey(entry.getKey());
669                 interfaceExternalIdsBuilder.setExternalIdValue(entry.getValue());
670                 externalIdsList.add(interfaceExternalIdsBuilder.build());
671             }
672             tpAugmentationBuilder.setInterfaceExternalIds(externalIdsList);
673         }
674
675         TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
676         tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
677         tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
678         /* TODO SB_MIGRATION should this be merge or mdsalUtils.put */
679         return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
680     }
681
682     public Boolean addTerminationPoint(Node bridgeNode, String portName, String type) {
683         return addTerminationPoint(bridgeNode, portName, type, Collections.EMPTY_MAP, null);
684     }
685
686     public Boolean addTerminationPoint(Node bridgeNode, String bridgeName, String portName,
687                                        String type, Map<String, String> options) {
688         InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
689                 bridgeNode, portName);
690         OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
691
692         tpAugmentationBuilder.setName(portName);
693         if (type != null) {
694             tpAugmentationBuilder.setInterfaceType(OVSDB_INTERFACE_TYPE_MAP.get(type));
695         }
696
697         List<Options> optionsList = new ArrayList<>();
698         for (Map.Entry<String, String> entry : options.entrySet()) {
699             OptionsBuilder optionsBuilder = new OptionsBuilder();
700             optionsBuilder.setKey(new OptionsKey(entry.getKey()));
701             optionsBuilder.setOption(entry.getKey());
702             optionsBuilder.setValue(entry.getValue());
703             optionsList.add(optionsBuilder.build());
704         }
705         tpAugmentationBuilder.setOptions(optionsList);
706
707         TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
708         tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
709         tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
710         /* TODO SB_MIGRATION should this be merge or mdsalUtils.put */
711         return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
712     }
713
714     public Boolean addTerminationPoint(Node bridgeNode, String bridgeName, String portName, String type) {
715         InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(bridgeNode, portName);
716         OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder =
717                 new OvsdbTerminationPointAugmentationBuilder();
718
719         tpAugmentationBuilder.setName(portName);
720         if (type != null) {
721             tpAugmentationBuilder.setInterfaceType(OVSDB_INTERFACE_TYPE_MAP.get(type));
722         }
723         TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
724         tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
725         tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
726         return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
727     }
728
729     public Boolean addPatchTerminationPoint(Node node, String bridgeName, String portName, String peerPortName) {
730         Map<String, String> option = new HashMap<>();
731         option.put("peer", peerPortName);
732         return addTerminationPoint(node, bridgeName, portName, PATCH_PORT_TYPE, option);
733     }
734
735     private String getControllerIPAddress() {
736         String addressString = ConfigProperties.getProperty(this.getClass(), "ovsdb.controller.address");
737         if (addressString != null) {
738             try {
739                 if (InetAddress.getByName(addressString) != null) {
740                     return addressString;
741                 }
742             } catch (UnknownHostException e) {
743                 LOG.error("Host {} is invalid", addressString, e);
744             }
745         }
746
747         addressString = ConfigProperties.getProperty(this.getClass(), "of.address");
748         if (addressString != null) {
749             try {
750                 if (InetAddress.getByName(addressString) != null) {
751                     return addressString;
752                 }
753             } catch (UnknownHostException e) {
754                 LOG.error("Host {} is invalid", addressString, e);
755             }
756         }
757
758         return null;
759     }
760
761     private short getControllerOFPort() {
762         short openFlowPort = OPENFLOW_PORT;
763         String portString = ConfigProperties.getProperty(this.getClass(), "of.listenPort");
764         if (portString != null) {
765             try {
766                 openFlowPort = Short.parseShort(portString);
767             } catch (NumberFormatException e) {
768                 LOG.warn("Invalid port:{}, use default({})", portString,
769                         openFlowPort, e);
770             }
771         }
772         return openFlowPort;
773     }
774
775     public List<String> getControllersFromOvsdbNode(Node node) {
776         List<String> controllersStr = new ArrayList<>();
777
778         String controllerIpStr = getControllerIPAddress();
779         if (controllerIpStr != null) {
780             // If codepath makes it here, the ip address to be used was explicitly provided.
781             // Being so, also fetch openflowPort provided via ConfigProperties.
782             controllersStr.add(OPENFLOW_CONNECTION_PROTOCOL
783                     + ":" + controllerIpStr + ":" + getControllerOFPort());
784         } else {
785             // Check if ovsdb node has manager entries
786             OvsdbNodeAugmentation ovsdbNodeAugmentation = extractOvsdbNode(node);
787             if (ovsdbNodeAugmentation != null) {
788                 List<ManagerEntry> managerEntries = ovsdbNodeAugmentation.getManagerEntry();
789                 if (managerEntries != null && !managerEntries.isEmpty()) {
790                     for (ManagerEntry managerEntry : managerEntries) {
791                         if (managerEntry == null || managerEntry.getTarget() == null) {
792                             continue;
793                         }
794                         String[] tokens = managerEntry.getTarget().getValue().split(":");
795                         if (tokens.length == 3 && tokens[0].equalsIgnoreCase("tcp")) {
796                             controllersStr.add(OPENFLOW_CONNECTION_PROTOCOL
797                                     + ":" + tokens[1] + ":" + getControllerOFPort());
798                         } else if (tokens[0].equalsIgnoreCase("ptcp")) {
799                             ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
800                             if (connectionInfo != null && connectionInfo.getLocalIp() != null) {
801                                 controllerIpStr = String.valueOf(connectionInfo.getLocalIp().getValue());
802                                 controllersStr.add(OPENFLOW_CONNECTION_PROTOCOL
803                                         + ":" + controllerIpStr + ":" + OPENFLOW_PORT);
804                             } else {
805                                 LOG.warn("Ovsdb Node does not contain connection info: {}", node);
806                             }
807                         } else {
808                             LOG.trace("Skipping manager entry {} for node {}",
809                                     managerEntry.getTarget(), node.getNodeId().getValue());
810                         }
811                     }
812                 } else {
813                     LOG.warn("Ovsdb Node does not contain manager entries : {}", node);
814                 }
815             }
816         }
817
818         if (controllersStr.isEmpty()) {
819             // Neither user provided ip nor ovsdb node has manager entries. Lets use local machine ip address.
820             LOG.debug("Use local machine ip address as a OpenFlow Controller ip address");
821             controllerIpStr = getLocalControllerHostIpAddress();
822             if (controllerIpStr != null) {
823                 controllersStr.add(OPENFLOW_CONNECTION_PROTOCOL
824                         + ":" + controllerIpStr + ":" + OPENFLOW_PORT);
825             }
826         }
827
828         if (controllersStr.isEmpty()) {
829             LOG.warn("Failed to determine OpenFlow controller ip address");
830         } else if (LOG.isDebugEnabled()) {
831             controllerIpStr = "";
832             for (String currControllerIpStr : controllersStr) {
833                 controllerIpStr += " " + currControllerIpStr;
834             }
835             LOG.debug("Found {} OpenFlow Controller(s) :{}", controllersStr.size(), controllerIpStr);
836         }
837
838         return controllersStr;
839     }
840
841     private String getLocalControllerHostIpAddress() {
842         String ipaddress = null;
843         try{
844             for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();){
845                 NetworkInterface iface = ifaces.nextElement();
846
847                 for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
848                     InetAddress inetAddr = inetAddrs.nextElement();
849                     if (!inetAddr.isLoopbackAddress() && inetAddr.isSiteLocalAddress()) {
850                         ipaddress = inetAddr.getHostAddress();
851                         break;
852                     }
853                 }
854             }
855         }catch (Exception e){
856             LOG.warn("Exception while fetching local host ip address ", e);
857         }
858         return ipaddress;
859     }
860
861     public long getDataPathId(Node node) {
862         long dpid = 0L;
863         String datapathId = getDatapathId(node);
864         if (datapathId != null) {
865             dpid = new BigInteger(datapathId.replaceAll(":", ""), 16).longValue();
866         }
867         return dpid;
868     }
869
870     public String getDatapathId(Node node) {
871         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = node.getAugmentation(OvsdbBridgeAugmentation.class);
872         return getDatapathId(ovsdbBridgeAugmentation);
873     }
874
875     public String getDatapathId(OvsdbBridgeAugmentation ovsdbBridgeAugmentation) {
876         String datapathId = null;
877         if (ovsdbBridgeAugmentation != null && ovsdbBridgeAugmentation.getDatapathId() != null) {
878             datapathId = ovsdbBridgeAugmentation.getDatapathId().getValue();
879         }
880         return datapathId;
881     }
882
883     public String extractBridgeName(Node node) {
884         return node.getAugmentation(OvsdbBridgeAugmentation.class).getBridgeName().getValue();
885     }
886
887     public boolean isBridgeOnOvsdbNode(Node ovsdbNode, String bridgeName) {
888         boolean found = false;
889         OvsdbNodeAugmentation ovsdbNodeAugmentation = extractNodeAugmentation(ovsdbNode);
890         if (ovsdbNodeAugmentation != null) {
891             List<ManagedNodeEntry> managedNodes = ovsdbNodeAugmentation.getManagedNodeEntry();
892             if (managedNodes != null) {
893                 for (ManagedNodeEntry managedNode : managedNodes) {
894                     InstanceIdentifier<?> bridgeIid = managedNode.getBridgeRef().getValue();
895                     if (bridgeIid.toString().contains(bridgeName)) {
896                         found = true;
897                         break;
898                     }
899                 }
900             }
901         }
902         return found;
903     }
904
905     public OvsdbBridgeAugmentation getBridgeFromConfig(Node node, String bridge) {
906         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
907         InstanceIdentifier<Node> bridgeIid =
908                 createInstanceIdentifier(node.getKey(), bridge);
909         Node bridgeNode = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, bridgeIid);
910         if (bridgeNode != null) {
911             ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
912         }
913         return ovsdbBridgeAugmentation;
914     }
915
916     private void setManagedByForBridge(OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
917                                        NodeKey ovsdbNodeKey) {
918         InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(ovsdbNodeKey.getNodeId());
919         ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
920     }
921
922     public boolean isOvsdbNodeDpdk(Node ovsdbNode) {
923         boolean found = false;
924         OvsdbNodeAugmentation ovsdbNodeAugmentation = extractNodeAugmentation(ovsdbNode);
925         if (ovsdbNodeAugmentation != null) {
926             List<InterfaceTypeEntry> ifTypes = ovsdbNodeAugmentation.getInterfaceTypeEntry();
927             if (ifTypes != null) {
928                 for (InterfaceTypeEntry ifType : ifTypes) {
929                     if (ifType.getInterfaceType().equals(InterfaceTypeDpdk.class)) {
930                         found = true;
931                         break;
932                     }
933                 }
934             }
935         }
936         return found;
937     }
938
939     private List<ControllerEntry> createControllerEntries(List<String> controllersStr) {
940         List<ControllerEntry> controllerEntries = new ArrayList<>();
941         if (controllersStr != null) {
942             for (String controllerStr : controllersStr) {
943                 ControllerEntryBuilder controllerEntryBuilder = new ControllerEntryBuilder();
944                 controllerEntryBuilder.setTarget(new Uri(controllerStr));
945                 controllerEntries.add(controllerEntryBuilder.build());
946             }
947         }
948         return controllerEntries;
949     }
950
951     public OvsdbTerminationPointAugmentation extractTerminationPointAugmentation(Node bridgeNode, String portName) {
952         if (bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class) != null) {
953             List<OvsdbTerminationPointAugmentation> tpAugmentations = extractTerminationPointAugmentations(bridgeNode);
954             for (OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation : tpAugmentations) {
955                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
956                     return ovsdbTerminationPointAugmentation;
957                 }
958             }
959         }
960         return null;
961     }
962
963     public List<OvsdbTerminationPointAugmentation> extractTerminationPointAugmentations( Node node ) {
964         List<OvsdbTerminationPointAugmentation> tpAugmentations = new ArrayList<>();
965         if (node == null) {
966             LOG.error("extractTerminationPointAugmentations: Node value is null");
967             return Collections.<OvsdbTerminationPointAugmentation>emptyList();
968         }
969         List<TerminationPoint> terminationPoints = node.getTerminationPoint();
970         if(terminationPoints != null && !terminationPoints.isEmpty()){
971             for(TerminationPoint tp : terminationPoints){
972                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
973                         tp.getAugmentation(OvsdbTerminationPointAugmentation.class);
974                 if (ovsdbTerminationPointAugmentation != null) {
975                     tpAugmentations.add(ovsdbTerminationPointAugmentation);
976                 }
977             }
978         }
979         return tpAugmentations;
980     }
981
982 }