SouthboundIT: merge the CRUD tests methods
[netvirt.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 com.google.common.collect.ImmutableBiMap;
12 import java.net.InetAddress;
13 import java.net.UnknownHostException;
14 import java.util.ArrayList;
15
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;
43
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;
50
51     public SouthboundUtils(MdsalUtils mdsalUtils) {
52         this.mdsalUtils = mdsalUtils;
53     }
54
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);
60     }
61
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();
67     }
68
69     public OvsdbNodeAugmentation createOvsdbAugmentation(ConnectionInfo key) {
70         OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
71         ovsdbNodeBuilder.setConnectionInfo(key);
72         return ovsdbNodeBuilder.build();
73     }
74
75     public InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key) {
76         return createInstanceIdentifier(key.getRemoteIp(), key.getRemotePort());
77     }
78
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);
85         return path;
86     }
87
88     public InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key,OvsdbBridgeName bridgeName) {
89         return SouthboundMapper.createInstanceIdentifier(createManagedNodeId(key, bridgeName));
90     }
91
92     public NodeKey createNodeKey(IpAddress ip, PortNumber port) {
93         return new NodeKey(createNodeId(ip, port));
94     }
95
96     public NodeId createManagedNodeId(ConnectionInfo key, OvsdbBridgeName bridgeName) {
97         return createManagedNodeId(key.getRemoteIp(), key.getRemotePort(), bridgeName);
98     }
99
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());
103     }
104
105     public ConnectionInfo getConnectionInfo(final String addressStr, final String portStr) {
106         InetAddress inetAddress = null;
107         try {
108             inetAddress = InetAddress.getByName(addressStr);
109         } catch (UnknownHostException e) {
110             LOG.warn("Could not allocate InetAddress");
111         }
112
113         IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
114         PortNumber port = new PortNumber(Integer.parseInt(portStr));
115
116         LOG.info("connectionInfo: {}", new ConnectionInfoBuilder()
117                 .setRemoteIp(address)
118                 .setRemotePort(port)
119                 .build());
120         return new ConnectionInfoBuilder()
121                 .setRemoteIp(address)
122                 .setRemotePort(port)
123                 .build();
124     }
125
126     public String connectionInfoToString(final ConnectionInfo connectionInfo) {
127         return new String(connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
128     }
129
130     public boolean addOvsdbNode(final ConnectionInfo connectionInfo) {
131         boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
132                 createInstanceIdentifier(connectionInfo),
133                 createNode(connectionInfo));
134         try {
135             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
136         } catch (InterruptedException e) {
137             LOG.warn("Interrupted while waiting after adding OVSDB node {}", connectionInfoToString(connectionInfo), e);
138         }
139         return result;
140     }
141
142     public Node getOvsdbNode(final ConnectionInfo connectionInfo) {
143         return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
144                 createInstanceIdentifier(connectionInfo));
145     }
146
147     public boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) {
148         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
149                 createInstanceIdentifier(connectionInfo));
150         try {
151             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
152         } catch (InterruptedException e) {
153             LOG.warn("Interrupted while waiting after deleting OVSDB node {}", connectionInfoToString(connectionInfo),
154                     e);
155         }
156         return result;
157     }
158
159     public Node connectOvsdbNode(final ConnectionInfo connectionInfo) {
160         addOvsdbNode(connectionInfo);
161         Node node = getOvsdbNode(connectionInfo);
162         LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
163         return node;
164     }
165
166     public boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) {
167         deleteOvsdbNode(connectionInfo);
168         LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
169         return true;
170     }
171
172     public List<ControllerEntry> createControllerEntry(String controllerTarget) {
173         List<ControllerEntry> controllerEntriesList = new ArrayList<>();
174         controllerEntriesList.add(new ControllerEntryBuilder()
175                 .setTarget(new Uri(controllerTarget))
176                 .build());
177         return controllerEntriesList;
178     }
179
180     /**
181      * Extract the <code>store</code> type data store contents for the particular bridge identified by
182      * <code>bridgeName</code>.
183      *
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
188      */
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);
195         }
196         return ovsdbBridgeAugmentation;
197     }
198
199     /**
200      * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
201      * identified by <code>bridgeName</code>
202      *
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
207      */
208     public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
209         return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
210     }
211
212     /**
213      * Extract the node contents from <code>store</code> type data store for the
214      * bridge identified by <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 Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
222         InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
223         return mdsalUtils.read(store, bridgeIid);
224     }
225
226     public boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName) {
227
228         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
229                 createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName)));
230         try {
231             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
232         } catch (InterruptedException e) {
233             LOG.warn("Interrupted while waiting after deleting bridge {}", bridgeName, e);
234         }
235         return result;
236     }
237
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());
243         return protocolList;
244     }
245
246     /*
247      * base method for adding test bridges.  Other helper methods used to create bridges should utilize this method.
248      *
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
261      */
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 {
270
271         NodeBuilder bridgeNodeBuilder = new NodeBuilder();
272         if (bridgeIid == null) {
273             bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
274         }
275         if (bridgeNodeId == null) {
276             bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
277         }
278         bridgeNodeBuilder.setNodeId(bridgeNodeId);
279         OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
280         ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
281         if (setProtocolEntries) {
282             ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
283         }
284         if (failMode != null) {
285             ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
286         }
287         if (setManagedBy) {
288             setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
289         }
290         if (dpType != null) {
291             ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
292         }
293         if (externalIds != null) {
294             ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
295         }
296         if (controllerEntries != null) {
297             ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
298         }
299         if (otherConfigs != null) {
300             ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
301         }
302         if (dpid != null && !dpid.isEmpty()) {
303             DatapathId datapathId = new DatapathId(dpid);
304             ovsdbBridgeAugmentationBuilder.setDatapathId(datapathId);
305         }
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);
312         return result;
313     }
314
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,
324                 otherConfigs, null);
325     }
326
327     public boolean addBridge(final ConnectionInfo connectionInfo, final String bridgeName)
328             throws InterruptedException {
329
330         return addBridge(connectionInfo, null, bridgeName, null, true,
331                 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null);
332     }
333
334     private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
335                               final ConnectionInfo connectionInfo) {
336         InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(connectionInfo);
337         ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
338     }
339 }