Fixup minor net-virt-it exceptions
[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.composite;
12 import static org.ops4j.pax.exam.CoreOptions.maven;
13 import static org.ops4j.pax.exam.CoreOptions.vmOption;
14 import static org.ops4j.pax.exam.CoreOptions.when;
15 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
16 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.features;
17 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration;
18 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
19
20 import com.google.common.collect.ImmutableBiMap;
21 import com.google.common.collect.Lists;
22 import com.google.common.collect.ObjectArrays;
23
24 import java.io.File;
25 import java.net.InetAddress;
26 import java.net.NetworkInterface;
27 import java.net.UnknownHostException;
28 import java.util.ArrayList;
29 import java.util.Enumeration;
30 import java.util.List;
31 import java.util.Properties;
32 import java.util.concurrent.atomic.AtomicBoolean;
33 import javax.inject.Inject;
34 import org.junit.Assert;
35 import org.junit.Before;
36 import org.junit.Ignore;
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
40 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
41 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
42 import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
43 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.*;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntryBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
56 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
57 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
58 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
59 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
60 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
61 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
62 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
63 import org.ops4j.pax.exam.Configuration;
64 import org.ops4j.pax.exam.Option;
65 import org.ops4j.pax.exam.junit.PaxExam;
66 import org.ops4j.pax.exam.karaf.options.KarafDistributionOption;
67 import org.ops4j.pax.exam.karaf.options.LogLevelOption;
68 import org.ops4j.pax.exam.options.MavenUrlReference;
69 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
70 import org.ops4j.pax.exam.spi.reactors.PerClass;
71 import org.osgi.framework.Bundle;
72 import org.osgi.framework.BundleContext;
73 import org.slf4j.Logger;
74 import org.slf4j.LoggerFactory;
75
76 /**
77  * Integration tests for netvirt
78  *
79  * @author Sam Hague (shague@redhat.com)
80  */
81 @RunWith(PaxExam.class)
82 @ExamReactorStrategy(PerClass.class)
83 public class NetvirtIT extends AbstractMdsalTestBase {
84     private static final Logger LOG = LoggerFactory.getLogger(NetvirtIT.class);
85     private static final int OVSDB_UPDATE_TIMEOUT = 1000;
86     private static DataBroker dataBroker = null;
87     private static String addressStr;
88     private static String portStr;
89     private static String connectionType;
90     private static AtomicBoolean setup = new AtomicBoolean(false);
91     private static MdsalUtils mdsalUtils = null;
92     private static Southbound southbound = null;
93     private static final String NETVIRT = "org.opendaylight.ovsdb.openstack.net-virt";
94     private static final String NETVIRTPROVIDERS = "org.opendaylight.ovsdb.openstack.net-virt-providers";
95
96     // TODO Constants copied frmo AbstractConfigTestBase, need to be removed (see TODO below)
97     private static final String PAX_EXAM_UNPACK_DIRECTORY = "target/exam";
98     private static final String KARAF_DEBUG_PORT = "5005";
99     private static final String KARAF_DEBUG_PROP = "karaf.debug";
100     private static final String KEEP_UNPACK_DIRECTORY_PROP = "karaf.keep.unpack";
101
102     @Inject
103     private BundleContext bundleContext;
104
105     @Configuration
106     public Option[] config() {
107         // TODO Figure out how to use the parent Karaf setup, then just use super.config()
108         Option[] options = new Option[] {
109                 when(Boolean.getBoolean(KARAF_DEBUG_PROP))
110                         .useOptions(KarafDistributionOption.debugConfiguration(KARAF_DEBUG_PORT, true)),
111                 karafDistributionConfiguration().frameworkUrl(getKarafDistro())
112                         .unpackDirectory(new File(PAX_EXAM_UNPACK_DIRECTORY))
113                         .useDeployFolder(false),
114                 when(Boolean.getBoolean(KEEP_UNPACK_DIRECTORY_PROP)).useOptions(keepRuntimeFolder()),
115                 // Works only if we don't specify the feature repo and name
116                 getLoggingOption()};
117         Option[] propertyOptions = getPropertiesOptions();
118         Option[] otherOptions = getOtherOptions();
119         Option[] combinedOptions = new Option[options.length + propertyOptions.length + otherOptions.length];
120         System.arraycopy(options, 0, combinedOptions, 0, options.length);
121         System.arraycopy(propertyOptions, 0, combinedOptions, options.length, propertyOptions.length);
122         System.arraycopy(otherOptions, 0, combinedOptions, options.length + propertyOptions.length,
123                 otherOptions.length);
124         return combinedOptions;
125     }
126
127     private Option[] getOtherOptions() {
128         return new Option[] {
129                 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
130                 keepRuntimeFolder()
131         };
132     }
133
134     @Override
135     public String getKarafDistro() {
136         return maven()
137                 .groupId("org.opendaylight.ovsdb")
138                 .artifactId("karaf")
139                 .versionAsInProject()
140                 .type("zip")
141                 .getURL();
142     }
143
144     @Override
145     public String getModuleName() {
146         return "netvirt-providers-impl";
147     }
148
149     @Override
150     public String getInstanceName() {
151         return "netvirt-providers-default";
152     }
153
154     @Override
155     public MavenUrlReference getFeatureRepo() {
156         return maven()
157                 .groupId("org.opendaylight.ovsdb")
158                 .artifactId("features-ovsdb")
159                 .classifier("features")
160                 .type("xml")
161                 .versionAsInProject();
162     }
163
164     @Override
165     public String getFeatureName() {
166         return "odl-ovsdb-openstack";
167     }
168
169     protected String usage() {
170         return "Integration Test needs a valid connection configuration as follows :\n"
171                 + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
172                 + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
173     }
174
175     @Override
176     public Option getLoggingOption() {
177         return composite(
178                 editConfigurationFilePut(NetvirtITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
179                         "log4j.logger.org.opendaylight.ovsdb",
180                         LogLevelOption.LogLevel.TRACE.name()),
181                 editConfigurationFilePut(NetvirtITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
182                         "log4j.logger.org.opendaylight.ovsdb.lib",
183                         LogLevelOption.LogLevel.INFO.name()),
184                 super.getLoggingOption());
185     }
186
187     private Option[] getPropertiesOptions() {
188         Properties props = new Properties(System.getProperties());
189         String addressStr = props.getProperty(NetvirtITConstants.SERVER_IPADDRESS,
190                 NetvirtITConstants.DEFAULT_SERVER_IPADDRESS);
191         String portStr = props.getProperty(NetvirtITConstants.SERVER_PORT,
192                 NetvirtITConstants.DEFAULT_SERVER_PORT);
193         String connectionType = props.getProperty(NetvirtITConstants.CONNECTION_TYPE,
194                 NetvirtITConstants.CONNECTION_TYPE_ACTIVE);
195
196         LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}",
197                 connectionType, addressStr, portStr);
198
199         Option[] options = new Option[] {
200                 editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
201                         NetvirtITConstants.SERVER_IPADDRESS, addressStr),
202                 editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
203                         NetvirtITConstants.SERVER_PORT, portStr),
204                 editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
205                         NetvirtITConstants.CONNECTION_TYPE, connectionType),
206         };
207         return options;
208     }
209
210     @Before
211     @Override
212     public void setup() throws InterruptedException {
213         if (setup.get()) {
214             LOG.info("Skipping setUp, already initialized");
215             return;
216         }
217
218         try {
219             super.setup();
220         } catch (Exception e) {
221             e.printStackTrace();
222         }
223
224         addressStr = bundleContext.getProperty(NetvirtITConstants.SERVER_IPADDRESS);
225         portStr = bundleContext.getProperty(NetvirtITConstants.SERVER_PORT);
226         connectionType = bundleContext.getProperty(NetvirtITConstants.CONNECTION_TYPE);
227
228         LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
229                 connectionType, addressStr, portStr);
230         if (connectionType.equalsIgnoreCase(NetvirtITConstants.CONNECTION_TYPE_ACTIVE)) {
231             if (addressStr == null) {
232                 fail(usage());
233             }
234         }
235
236         isBundleReady(bundleContext, NETVIRT);
237         isBundleReady(bundleContext, NETVIRTPROVIDERS);
238
239         //dataBroker = getSession().getSALService(DataBroker.class);
240         //Thread.sleep(3000);
241         //dataBroker = OvsdbInventoryServiceImpl.getDataBroker();
242         for (int i=0; i<20; i++) {
243             southbound = (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
244             if (southbound != null) {
245                 dataBroker = southbound.getDatabroker();
246                 if (dataBroker != null) {
247                     break;
248                 }
249             }
250             LOG.warn("NetvirtIT: dataBroker is null");
251             Thread.sleep(5000);
252         }
253         Assert.assertNotNull("dataBroker should not be null", dataBroker);
254         Thread.sleep(5000);
255
256         mdsalUtils = new MdsalUtils(dataBroker);
257         setup.set(true);
258     }
259
260     /**
261      * Test passive connection mode. The southbound starts in a listening mode waiting for connections on port
262      * 6640. This test will wait for incoming connections for {@link NetvirtITConstants.CONNECTION_INIT_TIMEOUT} ms.
263      *
264      * @throws InterruptedException
265      */
266     @Test
267     public void testPassiveNode() throws InterruptedException {
268         if (connectionType.equalsIgnoreCase(NetvirtITConstants.CONNECTION_TYPE_PASSIVE)) {
269             //Wait for CONNECTION_INIT_TIMEOUT for the Passive connection to be initiated by the ovsdb-server.
270             Thread.sleep(NetvirtITConstants.CONNECTION_INIT_TIMEOUT);
271         }
272     }
273
274     private ConnectionInfo getConnectionInfo(final String addressStr, final String portStr) {
275         InetAddress inetAddress = null;
276         try {
277             inetAddress = InetAddress.getByName(addressStr);
278         } catch (UnknownHostException e) {
279             fail("Could not allocate InetAddress: " + e);
280         }
281
282         IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
283         PortNumber port = new PortNumber(Integer.parseInt(portStr));
284
285         LOG.info("connectionInfo: {}", new ConnectionInfoBuilder()
286                 .setRemoteIp(address)
287                 .setRemotePort(port)
288                 .build());
289         return new ConnectionInfoBuilder()
290                        .setRemoteIp(address)
291                        .setRemotePort(port)
292                        .build();
293     }
294
295     private String connectionInfoToString(final ConnectionInfo connectionInfo) {
296         return new String(connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
297     }
298
299     private boolean addOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
300         boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
301                 SouthboundMapper.createInstanceIdentifier(connectionInfo),
302                 SouthboundMapper.createNode(connectionInfo));
303         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
304         return result;
305     }
306
307     private Node getOvsdbNode(final ConnectionInfo connectionInfo) {
308         Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
309                 SouthboundMapper.createInstanceIdentifier(connectionInfo));
310         return node;
311     }
312
313     private boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
314         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
315                 SouthboundMapper.createInstanceIdentifier(connectionInfo));
316         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
317         return result;
318     }
319
320     private Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
321         Assert.assertTrue(addOvsdbNode(connectionInfo));
322         Node node = getOvsdbNode(connectionInfo);
323         Assert.assertNotNull("Should find OVSDB node after connect", node);
324         LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
325         return node;
326     }
327
328     private boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
329         Assert.assertTrue(deleteOvsdbNode(connectionInfo));
330         Node node = getOvsdbNode(connectionInfo);
331         Assert.assertNull("Should not find OVSDB node after disconnect", node);
332         //Assume.assumeNotNull(node); // Using assumeNotNull because there is no assumeNull
333         LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
334         return true;
335     }
336
337     private String getLocalControllerHostIpAddress() {
338         String ipaddress = null;
339         try{
340             for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
341                  ifaces.hasMoreElements();) {
342                 NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
343
344                 for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
345                     InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
346                     if (!inetAddr.isLoopbackAddress()) {
347                         if (inetAddr.isSiteLocalAddress()) {
348                             ipaddress = inetAddr.getHostAddress();
349                             break;
350                         }
351                     }
352                 }
353             }
354         }catch (Exception e){
355             LOG.warn("Exception while fetching local host ip address ",e);
356         }
357         return ipaddress;
358     }
359
360     private String getControllerTarget(Node ovsdbNode) {
361         String target = null;
362         String ipAddr = null;
363         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
364         ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
365         LOG.info("connectionInfo: {}", connectionInfo);
366         if (connectionInfo != null && connectionInfo.getLocalIp() != null) {
367             ipAddr = new String(connectionInfo.getLocalIp().getValue());
368         }
369         if (ipAddr == null) {
370             ipAddr = getLocalControllerHostIpAddress();
371         }
372
373         if (ipAddr != null) {
374             target = NetvirtITConstants.OPENFLOW_CONNECTION_PROTOCOL + ":"
375                     + ipAddr + ":" + NetvirtITConstants.DEFAULT_OPENFLOW_PORT;
376         }
377
378         return target;
379     }
380
381     //@Ignore//
382     @Test
383     public void testAddDeleteOvsdbNode() throws InterruptedException {
384         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
385         connectOvsdbNode(connectionInfo);
386         ControllerEntry controllerEntry;
387         for (int i = 0; i < 10; i++) {
388             Node ovsdbNode = getOvsdbNode(connectionInfo);
389             Assert.assertNotNull("ovsdb node not found", ovsdbNode);
390             String controllerTarget = getControllerTarget(ovsdbNode);
391             Assert.assertNotNull("Failed to get controller target", controllerTarget);
392             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME);
393             Assert.assertNotNull(bridge);
394             Assert.assertNotNull(bridge.getControllerEntry());
395             controllerEntry = bridge.getControllerEntry().iterator().next();
396             Assert.assertEquals(controllerTarget, controllerEntry.getTarget().getValue());
397             if (controllerEntry.isIsConnected()) {
398                 Assert.assertTrue(controllerEntry.isIsConnected());
399                 break;
400             }
401             Thread.sleep(1000);
402         }
403
404         Assert.assertTrue(deleteBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME));
405         Thread.sleep(1000);
406         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
407     }
408
409     @Ignore
410     @Test
411     public void testOpenVSwitchOtherConfig() throws InterruptedException {
412         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
413         Node ovsdbNode = connectOvsdbNode(connectionInfo);
414         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
415         Assert.assertNotNull(ovsdbNodeAugmentation);
416         List<OpenvswitchOtherConfigs> otherConfigsList = ovsdbNodeAugmentation.getOpenvswitchOtherConfigs();
417         if (otherConfigsList != null) {
418             for (OpenvswitchOtherConfigs otherConfig : otherConfigsList) {
419                 if (otherConfig.getOtherConfigKey().equals("local_ip")) {
420                     LOG.info("local_ip: {}", otherConfig.getOtherConfigValue());
421                     break;
422                 } else {
423                     LOG.info("other_config {}:{}", otherConfig.getOtherConfigKey(), otherConfig.getOtherConfigValue());
424                 }
425             }
426         } else {
427             LOG.info("other_config is not present");
428         }
429         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
430         //Assume.assumeTrue(disconnectOvsdbNode(connectionInfo));
431     }
432
433     private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
434                               final ConnectionInfo connectionInfo) {
435         InstanceIdentifier<Node> connectionNodePath = SouthboundMapper.createInstanceIdentifier(connectionInfo);
436         ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
437     }
438
439     private List<ProtocolEntry> createMdsalProtocols() {
440         List<ProtocolEntry> protocolList = new ArrayList<ProtocolEntry>();
441         ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
442                 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
443         protocolList.add(new ProtocolEntryBuilder().
444                 setProtocol((Class<? extends OvsdbBridgeProtocolBase>) mapper.get("OpenFlow13")).build());
445         return protocolList;
446     }
447
448     private OvsdbTerminationPointAugmentationBuilder createGenericOvsdbTerminationPointAugmentationBuilder() {
449         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder =
450                 new OvsdbTerminationPointAugmentationBuilder();
451         ovsdbTerminationPointAugmentationBuilder.setInterfaceType(
452                 new InterfaceTypeEntryBuilder()
453                         .setInterfaceType(
454                                 SouthboundMapper.createInterfaceType("internal"))
455                         .build().getInterfaceType());
456         return ovsdbTerminationPointAugmentationBuilder;
457     }
458
459     private boolean addTerminationPoint(final NodeId bridgeNodeId, final String portName,
460             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder)
461         throws InterruptedException {
462
463         InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(bridgeNodeId);
464         NodeBuilder portNodeBuilder = new NodeBuilder();
465         NodeId portNodeId = SouthboundMapper.createManagedNodeId(portIid);
466         portNodeBuilder.setNodeId(portNodeId);
467         TerminationPointBuilder entry = new TerminationPointBuilder();
468         entry.setKey(new TerminationPointKey(new TpId(portName)));
469         entry.addAugmentation(
470                 OvsdbTerminationPointAugmentation.class,
471                 ovsdbTerminationPointAugmentationBuilder.build());
472         portNodeBuilder.setTerminationPoint(Lists.newArrayList(entry.build()));
473         boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
474                 portIid, portNodeBuilder.build());
475         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
476         return result;
477     }
478
479     /*
480      * base method for adding test bridges.  Other helper methods used to create bridges should utilize this method.
481      *
482      * @param connectionInfo
483      * @param bridgeIid if passed null, one is created
484      * @param bridgeName cannot be null
485      * @param bridgeNodeId if passed null, one is created based on <code>bridgeIid</code>
486      * @param setProtocolEntries toggles whether default protocol entries are set for the bridge
487      * @param failMode toggles whether default fail mode is set for the bridge
488      * @param setManagedBy toggles whether to setManagedBy for the bridge
489      * @param dpType if passed null, this parameter is ignored
490      * @param externalIds if passed null, this parameter is ignored
491      * @param otherConfig if passed null, this parameter is ignored
492      * @return success of bridge addition
493      * @throws InterruptedException
494      */
495     private boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
496             final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
497             final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
498             final Class<? extends DatapathTypeBase> dpType,
499             final List<BridgeExternalIds> externalIds,
500             final List<BridgeOtherConfigs> otherConfigs) throws InterruptedException {
501
502         NodeBuilder bridgeNodeBuilder = new NodeBuilder();
503         if (bridgeIid == null) {
504             bridgeIid = SouthboundMapper.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
505         }
506         if (bridgeNodeId == null) {
507             bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
508         }
509         bridgeNodeBuilder.setNodeId(bridgeNodeId);
510         OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
511         ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
512         if (setProtocolEntries) {
513             ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
514         }
515         if (failMode != null) {
516             ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
517         }
518         if (setManagedBy) {
519             setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
520         }
521         if (dpType != null) {
522             ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
523         }
524         if (externalIds != null) {
525             ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
526         }
527         if (otherConfigs != null) {
528             ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
529         }
530         bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
531         LOG.debug("Built with the intent to store bridge data {}",
532                 ovsdbBridgeAugmentationBuilder.toString());
533         boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
534                 bridgeIid, bridgeNodeBuilder.build());
535         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
536         return result;
537     }
538
539     private boolean addBridge(final ConnectionInfo connectionInfo, final String bridgeName)
540         throws InterruptedException {
541
542         return addBridge(connectionInfo, null, bridgeName, null, true,
543                 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null);
544     }
545
546     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo) {
547         return getBridge(connectionInfo, NetvirtITConstants.BRIDGE_NAME);
548     }
549
550     /**
551      * Extract the <code>store</code> type data store contents for the particular bridge identified by
552      * <code>bridgeName</code>.
553      *
554      * @param connectionInfo
555      * @param bridgeName
556      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
557      * @return <code>store</code> type data store contents
558      */
559     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
560             LogicalDatastoreType store) {
561         Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
562         Assert.assertNotNull(bridgeNode);
563         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
564         Assert.assertNotNull(ovsdbBridgeAugmentation);
565         return ovsdbBridgeAugmentation;
566     }
567
568     /**
569      * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
570      * identified by <code>bridgeName</code>
571      *
572      * @param connectionInfo
573      * @param bridgeName
574      * @see <code>NetvirtIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
575      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
576      */
577     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
578         return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
579     }
580
581     /**
582      * Extract the node contents from <code>store</code> type data store for the
583      * bridge identified by <code>bridgeName</code>
584      *
585      * @param connectionInfo
586      * @param bridgeName
587      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
588      * @return <code>store</code> type data store contents
589      */
590     private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
591         InstanceIdentifier<Node> bridgeIid =
592                 SouthboundMapper.createInstanceIdentifier(connectionInfo,
593                     new OvsdbBridgeName(bridgeName));
594         return mdsalUtils.read(store, bridgeIid);
595     }
596
597     /**
598      * Extract the node contents from <code>LogicalDataStoreType.OPERATIONAL</code> data store for the
599      * bridge identified by <code>bridgeName</code>
600      *
601      * @param connectionInfo
602      * @param bridgeName
603      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
604      */
605     private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName) {
606         return getBridgeNode(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
607     }
608
609     private boolean deleteBridge(ConnectionInfo connectionInfo) throws InterruptedException {
610         return deleteBridge(connectionInfo, NetvirtITConstants.BRIDGE_NAME);
611     }
612
613     private boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName)
614         throws InterruptedException {
615
616         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
617                 SouthboundMapper.createInstanceIdentifier(connectionInfo,
618                         new OvsdbBridgeName(bridgeName)));
619         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
620         return result;
621     }
622
623     private InstanceIdentifier<Node> getTpIid(ConnectionInfo connectionInfo, OvsdbBridgeAugmentation bridge) {
624         return SouthboundMapper.createInstanceIdentifier(connectionInfo,
625             bridge.getBridgeName());
626     }
627
628     /**
629      * isBundleReady is used to check if the requested bundle is Active
630      */
631     public void isBundleReady(BundleContext bundleContext, String bundleName) throws InterruptedException {
632         boolean ready = false;
633
634         while (!ready) {
635             int state = Bundle.UNINSTALLED;
636             Bundle[] bundles = bundleContext.getBundles();
637             for (Bundle element : bundles) {
638                 if (element.getSymbolicName().equals(bundleName)) {
639                     state = element.getState();
640                     LOG.info(">>>>> bundle is ready {}", bundleName);
641                     break;
642                 }
643             }
644             if (state != Bundle.ACTIVE) {
645                 LOG.info(">>>>> bundle not ready {}", bundleName);
646                 Thread.sleep(5000);
647             } else {
648                 ready = true;
649             }
650         }
651     }
652
653     private void netVirtAddPort(ConnectionInfo connectionInfo) throws InterruptedException {
654         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME);
655         Assert.assertNotNull(bridge);
656         NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier(
657                 connectionInfo, bridge.getBridgeName()));
658         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
659                 createGenericOvsdbTerminationPointAugmentationBuilder();
660         String portName = NetvirtITConstants.PORT_NAME;
661         ovsdbTerminationBuilder.setName(portName);
662         Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
663         InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
664         Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
665         Assert.assertNotNull(terminationPointNode);
666     }
667
668     /**
669      * Test for basic southbound events to netvirt.
670      * <pre>The test will:
671      * - connect to an OVSDB node and verify it is added to operational
672      * - then verify that br-int was created on the node and stored in operational
673      * - a port is then added to the bridge to verify that it is ignored by netvirt
674      * - remove the bridge
675      * - remove the node and verify it is not in operational
676      * </pre>
677      * @throws InterruptedException
678      */
679     // TODO add verification of flows
680     //@Ignore //
681     @Test
682     public void testNetVirt() throws InterruptedException {
683         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
684         connectOvsdbNode(connectionInfo);
685         Thread.sleep(10000);
686         netVirtAddPort(connectionInfo);
687         Thread.sleep(10000);
688         Assert.assertTrue(deleteBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME));
689         Thread.sleep(10000);
690         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
691     }
692
693     @Ignore
694     @Test
695     public void testNetVirt2() throws InterruptedException {
696         Thread.sleep(60000);
697     }
698
699     @Test
700     public void testReadOvsdbTopologyNodes() throws InterruptedException {
701         Thread.sleep(10000);
702         List<Node> ovsdbNodes = southbound.readOvsdbTopologyNodes();
703         for (Node node : ovsdbNodes) {
704             LOG.info(">>>>> node: {}", node);
705         }
706     }
707 }