2 * Copyright (c) 2015 Red Hat, Inc. and others. All rights reserved.
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
9 package org.opendaylight.ovsdb.utils.southbound.utils;
11 import com.google.common.collect.ImmutableBiMap;
12 import java.net.InetAddress;
13 import java.net.UnknownHostException;
14 import java.util.ArrayList;
16 import java.util.List;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
19 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
20 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.*;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
33 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
35 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
36 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
37 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
38 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
39 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
40 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
44 public class SouthboundUtils {
45 private static final Logger LOG = LoggerFactory.getLogger(SouthboundUtils.class);
46 private static final int OVSDB_UPDATE_TIMEOUT = 1000;
47 private static final String DEFAULT_OPENFLOW_PORT = "6653";
48 private static final String OPENFLOW_CONNECTION_PROTOCOL = "tcp";
49 private MdsalUtils mdsalUtils;
51 public SouthboundUtils(MdsalUtils mdsalUtils) {
52 this.mdsalUtils = mdsalUtils;
55 public NodeId createNodeId(IpAddress ip, PortNumber port) {
56 String uriString = SouthboundConstants.OVSDB_URI_PREFIX + "://"
57 + new String(ip.getValue()) + ":" + port.getValue();
58 Uri uri = new Uri(uriString);
59 return new NodeId(uri);
62 public Node createNode(ConnectionInfo key) {
63 NodeBuilder nodeBuilder = new NodeBuilder();
64 nodeBuilder.setNodeId(createNodeId(key.getRemoteIp(), key.getRemotePort()));
65 nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, createOvsdbAugmentation(key));
66 return nodeBuilder.build();
69 public OvsdbNodeAugmentation createOvsdbAugmentation(ConnectionInfo key) {
70 OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
71 ovsdbNodeBuilder.setConnectionInfo(key);
72 return ovsdbNodeBuilder.build();
75 public InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key) {
76 return createInstanceIdentifier(key.getRemoteIp(), key.getRemotePort());
79 public InstanceIdentifier<Node> createInstanceIdentifier(IpAddress ip, PortNumber port) {
80 InstanceIdentifier<Node> path = InstanceIdentifier
81 .create(NetworkTopology.class)
82 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
83 .child(Node.class,createNodeKey(ip,port));
84 LOG.debug("Created ovsdb path: {}",path);
88 public InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key,OvsdbBridgeName bridgeName) {
89 return SouthboundMapper.createInstanceIdentifier(createManagedNodeId(key, bridgeName));
92 public NodeKey createNodeKey(IpAddress ip, PortNumber port) {
93 return new NodeKey(createNodeId(ip, port));
96 public NodeId createManagedNodeId(ConnectionInfo key, OvsdbBridgeName bridgeName) {
97 return createManagedNodeId(key.getRemoteIp(), key.getRemotePort(), bridgeName);
100 public NodeId createManagedNodeId(IpAddress ip, PortNumber port, OvsdbBridgeName bridgeName) {
101 return new NodeId(createNodeId(ip,port).getValue()
102 + "/" + SouthboundConstants.BRIDGE_URI_PREFIX + "/" + bridgeName.getValue());
105 public ConnectionInfo getConnectionInfo(final String addressStr, final String portStr) {
106 InetAddress inetAddress = null;
108 inetAddress = InetAddress.getByName(addressStr);
109 } catch (UnknownHostException e) {
110 LOG.warn("Could not allocate InetAddress");
113 IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
114 PortNumber port = new PortNumber(Integer.parseInt(portStr));
116 LOG.info("connectionInfo: {}", new ConnectionInfoBuilder()
117 .setRemoteIp(address)
120 return new ConnectionInfoBuilder()
121 .setRemoteIp(address)
126 public String connectionInfoToString(final ConnectionInfo connectionInfo) {
127 return new String(connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
130 public boolean addOvsdbNode(final ConnectionInfo connectionInfo) {
131 boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
132 createInstanceIdentifier(connectionInfo),
133 createNode(connectionInfo));
135 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
136 } catch (InterruptedException e) {
137 LOG.warn("Interrupted while waiting after adding OVSDB node {}", connectionInfoToString(connectionInfo), e);
142 public Node getOvsdbNode(final ConnectionInfo connectionInfo) {
143 return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
144 createInstanceIdentifier(connectionInfo));
147 public boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) {
148 boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
149 createInstanceIdentifier(connectionInfo));
151 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
152 } catch (InterruptedException e) {
153 LOG.warn("Interrupted while waiting after deleting OVSDB node {}", connectionInfoToString(connectionInfo),
159 public Node connectOvsdbNode(final ConnectionInfo connectionInfo) {
160 addOvsdbNode(connectionInfo);
161 Node node = getOvsdbNode(connectionInfo);
162 LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
166 public boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) {
167 deleteOvsdbNode(connectionInfo);
168 LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
172 public List<ControllerEntry> createControllerEntry(String controllerTarget) {
173 List<ControllerEntry> controllerEntriesList = new ArrayList<>();
174 controllerEntriesList.add(new ControllerEntryBuilder()
175 .setTarget(new Uri(controllerTarget))
177 return controllerEntriesList;
181 * Extract the <code>store</code> type data store contents for the particular bridge identified by
182 * <code>bridgeName</code>.
184 * @param connectionInfo address for the node
185 * @param bridgeName name of the bridge
186 * @param store defined by the <code>LogicalDatastoreType</code> enumeration
187 * @return <code>store</code> type data store contents
189 public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
190 LogicalDatastoreType store) {
191 OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
192 Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
193 if (bridgeNode != null) {
194 ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
196 return ovsdbBridgeAugmentation;
200 * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
201 * identified by <code>bridgeName</code>
203 * @param connectionInfo address for the node
204 * @param bridgeName name of the bridge
205 * @see <code>NetvirtIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
206 * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
208 public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
209 return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
213 * Extract the node contents from <code>store</code> type data store for the
214 * bridge identified by <code>bridgeName</code>.
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
221 public Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
222 InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
223 return mdsalUtils.read(store, bridgeIid);
226 public boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName) {
228 boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
229 createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName)));
231 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
232 } catch (InterruptedException e) {
233 LOG.warn("Interrupted while waiting after deleting bridge {}", bridgeName, e);
238 public List<ProtocolEntry> createMdsalProtocols() {
239 List<ProtocolEntry> protocolList = new ArrayList<>();
240 ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
241 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
242 protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build());
247 * base method for adding test bridges. Other helper methods used to create bridges should utilize this method.
249 * @param connectionInfo
250 * @param bridgeIid if passed null, one is created
251 * @param bridgeName cannot be null
252 * @param bridgeNodeId if passed null, one is created based on <code>bridgeIid</code>
253 * @param setProtocolEntries toggles whether default protocol entries are set for the bridge
254 * @param failMode toggles whether default fail mode is set for the bridge
255 * @param setManagedBy toggles whether to setManagedBy for the bridge
256 * @param dpType if passed null, this parameter is ignored
257 * @param externalIds if passed null, this parameter is ignored
258 * @param otherConfig if passed null, this parameter is ignored
259 * @return success of bridge addition
260 * @throws InterruptedException
262 public boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
263 final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
264 final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
265 final Class<? extends DatapathTypeBase> dpType,
266 final List<BridgeExternalIds> externalIds,
267 final List<ControllerEntry> controllerEntries,
268 final List<BridgeOtherConfigs> otherConfigs,
269 final String dpid) throws InterruptedException {
271 NodeBuilder bridgeNodeBuilder = new NodeBuilder();
272 if (bridgeIid == null) {
273 bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
275 if (bridgeNodeId == null) {
276 bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
278 bridgeNodeBuilder.setNodeId(bridgeNodeId);
279 OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
280 ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
281 if (setProtocolEntries) {
282 ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
284 if (failMode != null) {
285 ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
288 setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
290 if (dpType != null) {
291 ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
293 if (externalIds != null) {
294 ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
296 if (controllerEntries != null) {
297 ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
299 if (otherConfigs != null) {
300 ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
302 if (dpid != null && !dpid.isEmpty()) {
303 DatapathId datapathId = new DatapathId(dpid);
304 ovsdbBridgeAugmentationBuilder.setDatapathId(datapathId);
306 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
307 LOG.debug("Built with the intent to store bridge data {}",
308 ovsdbBridgeAugmentationBuilder.toString());
309 boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
310 bridgeIid, bridgeNodeBuilder.build());
311 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
315 public boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
316 final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
317 final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
318 final Class<? extends DatapathTypeBase> dpType,
319 final List<BridgeExternalIds> externalIds,
320 final List<ControllerEntry> controllerEntries,
321 final List<BridgeOtherConfigs> otherConfigs) throws InterruptedException {
322 return addBridge(connectionInfo, bridgeIid, bridgeName, bridgeNodeId, setProtocolEntries,
323 failMode, setManagedBy, dpType, externalIds, controllerEntries,
327 public boolean addBridge(final ConnectionInfo connectionInfo, final String bridgeName)
328 throws InterruptedException {
330 return addBridge(connectionInfo, null, bridgeName, null, true,
331 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null);
334 private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
335 final ConnectionInfo connectionInfo) {
336 InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(connectionInfo);
337 ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));