Merge "Wait to process datastore until providers are ready"
[netvirt.git] / openstack / net-virt-it / src / test / java / org / opendaylight / ovsdb / openstack / netvirt / it / NetvirtIT.java
1 /*
2  * Copyright (c) 2015 Red Hat, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.ovsdb.openstack.netvirt.it;
9
10 import static org.junit.Assert.fail;
11 import static org.ops4j.pax.exam.CoreOptions.maven;
12 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
13
14 import com.google.common.collect.ImmutableBiMap;
15 import com.google.common.collect.Lists;
16 import com.google.common.collect.ObjectArrays;
17 import java.net.InetAddress;
18 import java.net.UnknownHostException;
19 import java.util.ArrayList;
20 import java.util.List;
21 import java.util.Properties;
22 import javax.inject.Inject;
23 import org.junit.Assert;
24 import org.junit.Before;
25 import org.junit.Ignore;
26 import org.junit.Test;
27 import org.junit.runner.RunWith;
28 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
29 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.*;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntryBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
41 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
42 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
43 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
44 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
45 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
46 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
47 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
48 import org.ops4j.pax.exam.Configuration;
49 import org.ops4j.pax.exam.Option;
50 import org.ops4j.pax.exam.junit.PaxExam;
51 import org.ops4j.pax.exam.karaf.options.LogLevelOption;
52 import org.ops4j.pax.exam.options.MavenUrlReference;
53 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
54 import org.ops4j.pax.exam.spi.reactors.PerClass;
55 import org.osgi.framework.Bundle;
56 import org.osgi.framework.BundleContext;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59
60 /**
61  * Integration tests for netvirt
62  *
63  * @author Sam Hague (shague@redhat.com)
64  */
65 @RunWith(PaxExam.class)
66 @ExamReactorStrategy(PerClass.class)
67 public class NetvirtIT extends AbstractMdsalTestBase {
68     private static final Logger LOG = LoggerFactory.getLogger(NetvirtIT.class);
69     private static final int OVSDB_UPDATE_TIMEOUT = 1000;
70     private static DataBroker dataBroker = null;
71     private static String addressStr;
72     private static String portStr;
73     private static String connectionType;
74     private static Boolean setup = false;
75     private static MdsalUtils mdsalUtils = null;
76     private static final String NETVIRT = "org.opendaylight.ovsdb.openstack.net-virt";
77     private static final String NETVIRTPROVIDERS = "org.opendaylight.ovsdb.openstack.net-virt-providers";
78
79     @Inject
80     private BundleContext bundleContext;
81
82     @Configuration
83     public Option[] config() {
84         return super.config();
85     }
86
87     @Override
88     public String getModuleName() {
89         return "openstack.net-virt-providers";
90     }
91
92     @Override
93     public String getInstanceName() {
94         return "net-virt-providers-default";
95     }
96
97     @Override
98     public MavenUrlReference getFeatureRepo() {
99         return maven()
100                 .groupId("org.opendaylight.ovsdb")
101                 .artifactId("features-ovsdb")
102                 .classifier("features")
103                 .type("xml")
104                 .versionAsInProject();
105     }
106
107     @Override
108     public String getFeatureName() {
109         return "odl-ovsdb-openstack";
110     }
111
112     protected String usage() {
113         return "Integration Test needs a valid connection configuration as follows :\n"
114                 + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
115                 + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
116     }
117
118     @Override
119     public Option[] getFeaturesOptions() {
120         return new Option[]{};
121     }
122
123     @Override
124     public Option[] getLoggingOptions() {
125         Option[] options;
126
127         options = new Option[] {
128             editConfigurationFilePut(NetvirtITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
129                     "log4j.logger.org.opendaylight.ovsdb",
130                     LogLevelOption.LogLevel.DEBUG.name()),
131             editConfigurationFilePut(NetvirtITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
132                     "log4j.logger.org.opendaylight.ovsdb.lib",
133                     LogLevelOption.LogLevel.INFO.name()),
134             /*editConfigurationFilePut(NetvirtITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
135                     "log4j.logger.org.opendaylight.ovsdb.openstack.net-virt",
136                     LogLevelOption.LogLevel.DEBUG.name())*/
137         };
138
139         options = ObjectArrays.concat(options, super.getLoggingOptions(), Option.class);
140         return options;
141     }
142
143     @Override
144     public Option[] getPropertiesOptions() {
145         Properties props = new Properties(System.getProperties());
146         String addressStr = props.getProperty(NetvirtITConstants.SERVER_IPADDRESS,
147                 NetvirtITConstants.DEFAULT_SERVER_IPADDRESS);
148         String portStr = props.getProperty(NetvirtITConstants.SERVER_PORT,
149                 NetvirtITConstants.DEFAULT_SERVER_PORT);
150         String connectionType = props.getProperty(NetvirtITConstants.CONNECTION_TYPE,
151                 NetvirtITConstants.CONNECTION_TYPE_ACTIVE);
152
153         LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}",
154                 connectionType, addressStr, portStr);
155
156         Option[] options = new Option[] {
157                 editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
158                         NetvirtITConstants.SERVER_IPADDRESS, addressStr),
159                 editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
160                         NetvirtITConstants.SERVER_PORT, portStr),
161                 editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
162                         NetvirtITConstants.CONNECTION_TYPE, connectionType),
163         };
164         return options;
165     }
166
167     @Before
168     public void setUp() throws InterruptedException {
169         if (setup == true) {
170             LOG.info("Skipping setUp, already initialized");
171             return;
172         }
173
174         try {
175             super.setup();
176         } catch (Exception e) {
177             e.printStackTrace();
178         }
179
180         addressStr = bundleContext.getProperty(NetvirtITConstants.SERVER_IPADDRESS);
181         portStr = bundleContext.getProperty(NetvirtITConstants.SERVER_PORT);
182         connectionType = bundleContext.getProperty(NetvirtITConstants.CONNECTION_TYPE);
183
184         LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
185                 connectionType, addressStr, portStr);
186         if (connectionType.equalsIgnoreCase(NetvirtITConstants.CONNECTION_TYPE_ACTIVE)) {
187             if (addressStr == null) {
188                 fail(usage());
189             }
190         }
191
192         isBundleReady(bundleContext, NETVIRT);
193         isBundleReady(bundleContext, NETVIRTPROVIDERS);
194
195         //dataBroker = getSession().getSALService(DataBroker.class);
196         //Thread.sleep(3000);
197         //dataBroker = OvsdbInventoryServiceImpl.getDataBroker();
198         for (int i=0; i<10; i++) {
199             dataBroker = org.opendaylight.ovsdb.openstack.netvirt.MdsalUtils.getDatabroker();
200             if (dataBroker == null) {
201                 LOG.warn("NetvirtIT: dataBroker is null");
202                 Thread.sleep(5000);
203                 continue;
204             } else {
205                 break;
206             }
207         }
208         Assert.assertNotNull("dataBroker should not be null", dataBroker);
209         Thread.sleep(5000);
210
211         mdsalUtils = new MdsalUtils(dataBroker);
212         setup = true;
213     }
214
215     /**
216      * Test passive connection mode. The southbound starts in a listening mode waiting for connections on port
217      * 6640. This test will wait for incoming connections for {@link NetvirtITConstants.CONNECTION_INIT_TIMEOUT} ms.
218      *
219      * @throws InterruptedException
220      */
221     @Test
222     public void testPassiveNode() throws InterruptedException {
223         if (connectionType.equalsIgnoreCase(NetvirtITConstants.CONNECTION_TYPE_PASSIVE)) {
224             //Wait for CONNECTION_INIT_TIMEOUT for the Passive connection to be initiated by the ovsdb-server.
225             Thread.sleep(NetvirtITConstants.CONNECTION_INIT_TIMEOUT);
226         }
227     }
228
229     private ConnectionInfo getConnectionInfo(final String addressStr, final String portStr) {
230         InetAddress inetAddress = null;
231         try {
232             inetAddress = InetAddress.getByName(addressStr);
233         } catch (UnknownHostException e) {
234             fail("Could not allocate InetAddress: " + e);
235         }
236
237         IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
238         PortNumber port = new PortNumber(Integer.parseInt(portStr));
239
240         LOG.info("connectionInfo: {}", new ConnectionInfoBuilder()
241                 .setRemoteIp(address)
242                 .setRemotePort(port)
243                 .build());
244         return new ConnectionInfoBuilder()
245                        .setRemoteIp(address)
246                        .setRemotePort(port)
247                        .build();
248     }
249
250     private String connectionInfoToString(final ConnectionInfo connectionInfo) {
251         return new String(connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
252     }
253
254     private boolean addOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
255         boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
256                 SouthboundMapper.createInstanceIdentifier(connectionInfo),
257                 SouthboundMapper.createNode(connectionInfo));
258         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
259         return result;
260     }
261
262     private Node getOvsdbNode(final ConnectionInfo connectionInfo) {
263         Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
264                 SouthboundMapper.createInstanceIdentifier(connectionInfo));
265         return node;
266     }
267
268     private boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
269         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
270                 SouthboundMapper.createInstanceIdentifier(connectionInfo));
271         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
272         return result;
273     }
274
275     private Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
276         Assert.assertTrue(addOvsdbNode(connectionInfo));
277         Node node = getOvsdbNode(connectionInfo);
278         Assert.assertNotNull("Should find OVSDB node after connect", node);
279         LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
280         return node;
281     }
282
283     private boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
284         Assert.assertTrue(deleteOvsdbNode(connectionInfo));
285         Node node = getOvsdbNode(connectionInfo);
286         Assert.assertNull("Should not find OVSDB node after disconnect", node);
287         //Assume.assumeNotNull(node); // Using assumeNotNull because there is no assumeNull
288         LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
289         return true;
290     }
291
292     @Test
293     public void testAddDeleteOvsdbNode() throws InterruptedException {
294         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
295         connectOvsdbNode(connectionInfo);
296         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
297         //Assume.assumeTrue(disconnectOvsdbNode(connectionInfo));
298     }
299
300     @Ignore
301     @Test
302     public void testOpenVSwitchOtherConfig() throws InterruptedException {
303         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
304         Node ovsdbNode = connectOvsdbNode(connectionInfo);
305         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
306         Assert.assertNotNull(ovsdbNodeAugmentation);
307         List<OpenvswitchOtherConfigs> otherConfigsList = ovsdbNodeAugmentation.getOpenvswitchOtherConfigs();
308         if (otherConfigsList != null) {
309             for (OpenvswitchOtherConfigs otherConfig : otherConfigsList) {
310                 if (otherConfig.getOtherConfigKey().equals("local_ip")) {
311                     LOG.info("local_ip: {}", otherConfig.getOtherConfigValue());
312                     break;
313                 } else {
314                     LOG.info("other_config {}:{}", otherConfig.getOtherConfigKey(), otherConfig.getOtherConfigValue());
315                 }
316             }
317         } else {
318             LOG.info("other_config is not present");
319         }
320         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
321         //Assume.assumeTrue(disconnectOvsdbNode(connectionInfo));
322     }
323
324     private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
325                               final ConnectionInfo connectionInfo) {
326         InstanceIdentifier<Node> connectionNodePath = SouthboundMapper.createInstanceIdentifier(connectionInfo);
327         ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
328     }
329
330     private List<ProtocolEntry> createMdsalProtocols() {
331         List<ProtocolEntry> protocolList = new ArrayList<ProtocolEntry>();
332         ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
333                 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
334         protocolList.add(new ProtocolEntryBuilder().
335                 setProtocol((Class<? extends OvsdbBridgeProtocolBase>) mapper.get("OpenFlow13")).build());
336         return protocolList;
337     }
338
339     private OvsdbTerminationPointAugmentationBuilder createGenericOvsdbTerminationPointAugmentationBuilder() {
340         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder =
341                 new OvsdbTerminationPointAugmentationBuilder();
342         ovsdbTerminationPointAugmentationBuilder.setInterfaceType(
343                 new InterfaceTypeEntryBuilder()
344                         .setInterfaceType(
345                                 SouthboundMapper.createInterfaceType("internal"))
346                         .build().getInterfaceType());
347         return ovsdbTerminationPointAugmentationBuilder;
348     }
349
350     private boolean addTerminationPoint(final NodeId bridgeNodeId, final String portName,
351             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder)
352         throws InterruptedException {
353
354         InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(bridgeNodeId);
355         NodeBuilder portNodeBuilder = new NodeBuilder();
356         NodeId portNodeId = SouthboundMapper.createManagedNodeId(portIid);
357         portNodeBuilder.setNodeId(portNodeId);
358         TerminationPointBuilder entry = new TerminationPointBuilder();
359         entry.setKey(new TerminationPointKey(new TpId(portName)));
360         entry.addAugmentation(
361                 OvsdbTerminationPointAugmentation.class,
362                 ovsdbTerminationPointAugmentationBuilder.build());
363         portNodeBuilder.setTerminationPoint(Lists.newArrayList(entry.build()));
364         boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
365                 portIid, portNodeBuilder.build());
366         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
367         return result;
368     }
369
370     /*
371      * base method for adding test bridges.  Other helper methods used to create bridges should utilize this method.
372      *
373      * @param connectionInfo
374      * @param bridgeIid if passed null, one is created
375      * @param bridgeName cannot be null
376      * @param bridgeNodeId if passed null, one is created based on <code>bridgeIid</code>
377      * @param setProtocolEntries toggles whether default protocol entries are set for the bridge
378      * @param failMode toggles whether default fail mode is set for the bridge
379      * @param setManagedBy toggles whether to setManagedBy for the bridge
380      * @param dpType if passed null, this parameter is ignored
381      * @param externalIds if passed null, this parameter is ignored
382      * @param otherConfig if passed null, this parameter is ignored
383      * @return success of bridge addition
384      * @throws InterruptedException
385      */
386     private boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
387             final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
388             final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
389             final Class<? extends DatapathTypeBase> dpType,
390             final List<BridgeExternalIds> externalIds,
391             final List<BridgeOtherConfigs> otherConfigs) throws InterruptedException {
392
393         NodeBuilder bridgeNodeBuilder = new NodeBuilder();
394         if (bridgeIid == null) {
395             bridgeIid = SouthboundMapper.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
396         }
397         if (bridgeNodeId == null) {
398             bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
399         }
400         bridgeNodeBuilder.setNodeId(bridgeNodeId);
401         OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
402         ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
403         if (setProtocolEntries) {
404             ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
405         }
406         if (failMode != null) {
407             ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
408         }
409         if (setManagedBy) {
410             setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
411         }
412         if (dpType != null) {
413             ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
414         }
415         if (externalIds != null) {
416             ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
417         }
418         if (otherConfigs != null) {
419             ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
420         }
421         bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
422         LOG.debug("Built with the intent to store bridge data {}",
423                 ovsdbBridgeAugmentationBuilder.toString());
424         boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
425                 bridgeIid, bridgeNodeBuilder.build());
426         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
427         return result;
428     }
429
430     private boolean addBridge(final ConnectionInfo connectionInfo, final String bridgeName)
431         throws InterruptedException {
432
433         return addBridge(connectionInfo, null, bridgeName, null, true,
434                 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null);
435     }
436
437     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo) {
438         return getBridge(connectionInfo, NetvirtITConstants.BRIDGE_NAME);
439     }
440
441     /**
442      * Extract the <code>store</code> type data store contents for the particular bridge identified by
443      * <code>bridgeName</code>.
444      *
445      * @param connectionInfo
446      * @param bridgeName
447      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
448      * @return <code>store</code> type data store contents
449      */
450     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
451             LogicalDatastoreType store) {
452         Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
453         Assert.assertNotNull(bridgeNode);
454         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
455         Assert.assertNotNull(ovsdbBridgeAugmentation);
456         return ovsdbBridgeAugmentation;
457     }
458
459     /**
460      * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
461      * identified by <code>bridgeName</code>
462      *
463      * @param connectionInfo
464      * @param bridgeName
465      * @see <code>NetvirtIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
466      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
467      */
468     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
469         return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
470     }
471
472     /**
473      * Extract the node contents from <code>store</code> type data store for the
474      * bridge identified by <code>bridgeName</code>
475      *
476      * @param connectionInfo
477      * @param bridgeName
478      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
479      * @return <code>store</code> type data store contents
480      */
481     private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
482         InstanceIdentifier<Node> bridgeIid =
483                 SouthboundMapper.createInstanceIdentifier(connectionInfo,
484                     new OvsdbBridgeName(bridgeName));
485         return mdsalUtils.read(store, bridgeIid);
486     }
487
488     /**
489      * Extract the node contents from <code>LogicalDataStoreType.OPERATIONAL</code> data store for the
490      * bridge identified by <code>bridgeName</code>
491      *
492      * @param connectionInfo
493      * @param bridgeName
494      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
495      */
496     private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName) {
497         return getBridgeNode(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
498     }
499
500     private boolean deleteBridge(ConnectionInfo connectionInfo) throws InterruptedException {
501         return deleteBridge(connectionInfo, NetvirtITConstants.BRIDGE_NAME);
502     }
503
504     private boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName)
505         throws InterruptedException {
506
507         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
508                 SouthboundMapper.createInstanceIdentifier(connectionInfo,
509                         new OvsdbBridgeName(bridgeName)));
510         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
511         return result;
512     }
513
514     private InstanceIdentifier<Node> getTpIid(ConnectionInfo connectionInfo, OvsdbBridgeAugmentation bridge) {
515         return SouthboundMapper.createInstanceIdentifier(connectionInfo,
516             bridge.getBridgeName());
517     }
518
519     /**
520      * isBundleReady is used to check if the requested bundle is Active
521      */
522     public void isBundleReady(BundleContext bundleContext, String bundleName) throws InterruptedException {
523         boolean ready = false;
524
525         while (!ready) {
526             int state = Bundle.UNINSTALLED;
527             Bundle[] bundles = bundleContext.getBundles();
528             for (Bundle element : bundles) {
529                 if (element.getSymbolicName().equals(bundleName)) {
530                     state = element.getState();
531                     LOG.info(">>>>> bundle is ready {}", bundleName);
532                     break;
533                 }
534             }
535             if (state != Bundle.ACTIVE) {
536                 LOG.info(">>>>> bundle not ready {}", bundleName);
537                 Thread.sleep(5000);
538             } else {
539                 ready = true;
540             }
541         }
542     }
543
544     private void netVirtAddPort(ConnectionInfo connectionInfo) throws InterruptedException {
545         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME);
546         Assert.assertNotNull(bridge);
547         NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier(
548                 connectionInfo, bridge.getBridgeName()));
549         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
550                 createGenericOvsdbTerminationPointAugmentationBuilder();
551         String portName = NetvirtITConstants.PORT_NAME;
552         ovsdbTerminationBuilder.setName(portName);
553         Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
554         InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
555         Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
556         Assert.assertNotNull(terminationPointNode);
557     }
558
559     /**
560      * Test for basic southbound events to netvirt.
561      * <pre>The test will:
562      * - connect to an OVSDB node and verify it is added to operational
563      * - then verify that br-int was created on the node and stored in operational
564      * - a port is then added to the bridge to verify that it is ignored by netvirt
565      * - remove the bridge
566      * - remove the node and verify it is not in operational
567      * </pre>
568      * @throws InterruptedException
569      */
570     // TODO add verification of flows
571     @Test
572     public void testNetVirt() throws InterruptedException {
573         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
574         connectOvsdbNode(connectionInfo);
575         Thread.sleep(10000);
576         netVirtAddPort(connectionInfo);
577         Thread.sleep(10000);
578         Assert.assertTrue(deleteBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME));
579         Thread.sleep(10000);
580         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
581     }
582
583     @Test
584     public void testNetVirt2() throws InterruptedException {
585         Thread.sleep(60000);
586     }
587
588     @Test
589     public void testReadOvsdbTopologyNodes() throws InterruptedException {
590         Thread.sleep(10000);
591         List<Node> ovsdbNodes = org.opendaylight.ovsdb.openstack.netvirt.MdsalUtils.readOvsdbTopologyNodes();
592         for (Node node : ovsdbNodes) {
593             LOG.info(">>>>> node: {}", node);
594         }
595     }
596 }