Add southbound utils.
[ovsdb.git] / utils / southbound-utils / src / main / java / org / opendaylight / ovsdb / utils / southbound / utils / SouthboundUtils.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
9 package org.opendaylight.ovsdb.utils.southbound.utils;
10
11 import java.net.InetAddress;
12 import java.net.NetworkInterface;
13 import java.net.UnknownHostException;
14 import java.util.Enumeration;
15
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
18 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
19 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentationBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
30 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
31 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
32 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
33 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
35 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
36 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 public class SouthboundUtils {
41     private static final Logger LOG = LoggerFactory.getLogger(SouthboundUtils.class);
42     private static final int OVSDB_UPDATE_TIMEOUT = 1000;
43     private static final String DEFAULT_OPENFLOW_PORT = "6653";
44     private static final String OPENFLOW_CONNECTION_PROTOCOL = "tcp";
45     private MdsalUtils mdsalUtils;
46
47     public SouthboundUtils(MdsalUtils mdsalUtils) {
48         this.mdsalUtils = mdsalUtils;
49     }
50
51     public NodeId createNodeId(IpAddress ip, PortNumber port) {
52         String uriString = SouthboundConstants.OVSDB_URI_PREFIX + "://"
53                 + new String(ip.getValue()) + ":" + port.getValue();
54         Uri uri = new Uri(uriString);
55         return new NodeId(uri);
56     }
57
58     public Node createNode(ConnectionInfo key) {
59         NodeBuilder nodeBuilder = new NodeBuilder();
60         nodeBuilder.setNodeId(createNodeId(key.getRemoteIp(), key.getRemotePort()));
61         nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, createOvsdbAugmentation(key));
62         return nodeBuilder.build();
63     }
64
65     public OvsdbNodeAugmentation createOvsdbAugmentation(ConnectionInfo key) {
66         OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
67         ovsdbNodeBuilder.setConnectionInfo(key);
68         return ovsdbNodeBuilder.build();
69     }
70
71     public InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key) {
72         return createInstanceIdentifier(key.getRemoteIp(), key.getRemotePort());
73     }
74
75     public InstanceIdentifier<Node> createInstanceIdentifier(IpAddress ip, PortNumber port) {
76         InstanceIdentifier<Node> path = InstanceIdentifier
77                 .create(NetworkTopology.class)
78                 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
79                 .child(Node.class,createNodeKey(ip,port));
80         LOG.debug("Created ovsdb path: {}",path);
81         return path;
82     }
83
84     public InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key,OvsdbBridgeName bridgeName) {
85         return SouthboundMapper.createInstanceIdentifier(createManagedNodeId(key, bridgeName));
86     }
87
88     public NodeKey createNodeKey(IpAddress ip, PortNumber port) {
89         return new NodeKey(createNodeId(ip, port));
90     }
91
92     public NodeId createManagedNodeId(ConnectionInfo key, OvsdbBridgeName bridgeName) {
93         return createManagedNodeId(key.getRemoteIp(), key.getRemotePort(), bridgeName);
94     }
95
96     public NodeId createManagedNodeId(IpAddress ip, PortNumber port, OvsdbBridgeName bridgeName) {
97         return new NodeId(createNodeId(ip,port).getValue()
98                 + "/" + SouthboundConstants.BRIDGE_URI_PREFIX + "/" + bridgeName.getValue());
99     }
100
101     public ConnectionInfo getConnectionInfo(final String addressStr, final String portStr) {
102         InetAddress inetAddress = null;
103         try {
104             inetAddress = InetAddress.getByName(addressStr);
105         } catch (UnknownHostException e) {
106             LOG.warn("Could not allocate InetAddress");
107         }
108
109         IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
110         PortNumber port = new PortNumber(Integer.parseInt(portStr));
111
112         LOG.info("connectionInfo: {}", new ConnectionInfoBuilder()
113                 .setRemoteIp(address)
114                 .setRemotePort(port)
115                 .build());
116         return new ConnectionInfoBuilder()
117                 .setRemoteIp(address)
118                 .setRemotePort(port)
119                 .build();
120     }
121
122     public String connectionInfoToString(final ConnectionInfo connectionInfo) {
123         return new String(connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
124     }
125
126     public boolean addOvsdbNode(final ConnectionInfo connectionInfo) {
127         boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
128                 createInstanceIdentifier(connectionInfo),
129                 createNode(connectionInfo));
130         try {
131             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
132         } catch (InterruptedException e) {
133             e.printStackTrace();
134         }
135         return result;
136     }
137
138     public Node getOvsdbNode(final ConnectionInfo connectionInfo) {
139         Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
140                 createInstanceIdentifier(connectionInfo));
141         return node;
142     }
143
144     public boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) {
145         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
146                 createInstanceIdentifier(connectionInfo));
147         try {
148             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
149         } catch (InterruptedException e) {
150             e.printStackTrace();
151         }
152         return result;
153     }
154
155     public Node connectOvsdbNode(final ConnectionInfo connectionInfo) {
156         addOvsdbNode(connectionInfo);
157         Node node = getOvsdbNode(connectionInfo);
158         LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
159         return node;
160     }
161
162     public boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) {
163         deleteOvsdbNode(connectionInfo);
164         LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
165         return true;
166     }
167
168     public String getLocalControllerHostIpAddress() {
169         String ipaddress = null;
170         try {
171             for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
172                  ifaces.hasMoreElements();) {
173                 NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
174
175                 for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
176                     InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
177                     if (!inetAddr.isLoopbackAddress()) {
178                         if (inetAddr.isSiteLocalAddress()) {
179                             ipaddress = inetAddr.getHostAddress();
180                             break;
181                         }
182                     }
183                 }
184             }
185         } catch (Exception e) {
186             LOG.warn("Exception while fetching local host ip address ",e);
187         }
188         return ipaddress;
189     }
190
191     public String getControllerTarget(Node ovsdbNode) {
192         String target = null;
193         String ipAddr = null;
194         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
195         ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
196         LOG.info("connectionInfo: {}", connectionInfo);
197         if (connectionInfo != null && connectionInfo.getLocalIp() != null) {
198             ipAddr = new String(connectionInfo.getLocalIp().getValue());
199         }
200         if (ipAddr == null) {
201             ipAddr = getLocalControllerHostIpAddress();
202         }
203
204         if (ipAddr != null) {
205             target = OPENFLOW_CONNECTION_PROTOCOL + ":"
206                     + ipAddr + ":" + DEFAULT_OPENFLOW_PORT;
207         }
208
209         return target;
210     }
211
212     /**
213      * Extract the <code>store</code> type data store contents for the particular bridge identified by
214      * <code>bridgeName</code>.
215      *
216      * @param connectionInfo address for the node
217      * @param bridgeName name of the bridge
218      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
219      * @return <code>store</code> type data store contents
220      */
221     public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
222                                               LogicalDatastoreType store) {
223         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
224         Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
225         if (bridgeNode != null) {
226             ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
227         }
228         return ovsdbBridgeAugmentation;
229     }
230
231     /**
232      * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
233      * identified by <code>bridgeName</code>
234      *
235      * @param connectionInfo address for the node
236      * @param bridgeName name of the bridge
237      * @see <code>NetvirtIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
238      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
239      */
240     public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
241         return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
242     }
243
244     /**
245      * Extract the node contents from <code>store</code> type data store for the
246      * bridge identified by <code>bridgeName</code>.
247      *
248      * @param connectionInfo address for the node
249      * @param bridgeName name of the bridge
250      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
251      * @return <code>store</code> type data store contents
252      */
253     public Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
254         InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
255         return mdsalUtils.read(store, bridgeIid);
256     }
257
258     public boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName) {
259
260         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
261                 createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName)));
262         try {
263             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
264         } catch (InterruptedException e) {
265             e.printStackTrace();
266         }
267         return result;
268     }
269 }