Fix sonar integration test reporting
[ovsdb.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 "openstack.net-virt-providers";
147     }
148
149     @Override
150     public String getInstanceName() {
151         return "net-virt-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.DEBUG.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             /*editConfigurationFilePut(NetvirtITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
186                     "log4j.logger.org.opendaylight.ovsdb.openstack.net-virt",
187                     LogLevelOption.LogLevel.DEBUG.name())*/
188     }
189
190     private Option[] getPropertiesOptions() {
191         Properties props = new Properties(System.getProperties());
192         String addressStr = props.getProperty(NetvirtITConstants.SERVER_IPADDRESS,
193                 NetvirtITConstants.DEFAULT_SERVER_IPADDRESS);
194         String portStr = props.getProperty(NetvirtITConstants.SERVER_PORT,
195                 NetvirtITConstants.DEFAULT_SERVER_PORT);
196         String connectionType = props.getProperty(NetvirtITConstants.CONNECTION_TYPE,
197                 NetvirtITConstants.CONNECTION_TYPE_ACTIVE);
198
199         LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}",
200                 connectionType, addressStr, portStr);
201
202         Option[] options = new Option[] {
203                 editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
204                         NetvirtITConstants.SERVER_IPADDRESS, addressStr),
205                 editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
206                         NetvirtITConstants.SERVER_PORT, portStr),
207                 editConfigurationFilePut(NetvirtITConstants.CUSTOM_PROPERTIES,
208                         NetvirtITConstants.CONNECTION_TYPE, connectionType),
209         };
210         return options;
211     }
212
213     @Before
214     @Override
215     public void setup() throws InterruptedException {
216         if (setup.get()) {
217             LOG.info("Skipping setUp, already initialized");
218             return;
219         }
220
221         try {
222             super.setup();
223         } catch (Exception e) {
224             e.printStackTrace();
225         }
226
227         addressStr = bundleContext.getProperty(NetvirtITConstants.SERVER_IPADDRESS);
228         portStr = bundleContext.getProperty(NetvirtITConstants.SERVER_PORT);
229         connectionType = bundleContext.getProperty(NetvirtITConstants.CONNECTION_TYPE);
230
231         LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
232                 connectionType, addressStr, portStr);
233         if (connectionType.equalsIgnoreCase(NetvirtITConstants.CONNECTION_TYPE_ACTIVE)) {
234             if (addressStr == null) {
235                 fail(usage());
236             }
237         }
238
239         isBundleReady(bundleContext, NETVIRT);
240         isBundleReady(bundleContext, NETVIRTPROVIDERS);
241
242         //dataBroker = getSession().getSALService(DataBroker.class);
243         //Thread.sleep(3000);
244         //dataBroker = OvsdbInventoryServiceImpl.getDataBroker();
245         for (int i=0; i<20; i++) {
246             southbound = (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
247             if (southbound != null) {
248                 dataBroker = southbound.getDatabroker();
249                 if (dataBroker != null) {
250                     break;
251                 }
252             }
253             LOG.warn("NetvirtIT: dataBroker is null");
254             Thread.sleep(5000);
255         }
256         Assert.assertNotNull("dataBroker should not be null", dataBroker);
257         Thread.sleep(5000);
258
259         mdsalUtils = new MdsalUtils(dataBroker);
260         setup.set(true);
261     }
262
263     /**
264      * Test passive connection mode. The southbound starts in a listening mode waiting for connections on port
265      * 6640. This test will wait for incoming connections for {@link NetvirtITConstants.CONNECTION_INIT_TIMEOUT} ms.
266      *
267      * @throws InterruptedException
268      */
269     @Test
270     public void testPassiveNode() throws InterruptedException {
271         if (connectionType.equalsIgnoreCase(NetvirtITConstants.CONNECTION_TYPE_PASSIVE)) {
272             //Wait for CONNECTION_INIT_TIMEOUT for the Passive connection to be initiated by the ovsdb-server.
273             Thread.sleep(NetvirtITConstants.CONNECTION_INIT_TIMEOUT);
274         }
275     }
276
277     private ConnectionInfo getConnectionInfo(final String addressStr, final String portStr) {
278         InetAddress inetAddress = null;
279         try {
280             inetAddress = InetAddress.getByName(addressStr);
281         } catch (UnknownHostException e) {
282             fail("Could not allocate InetAddress: " + e);
283         }
284
285         IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
286         PortNumber port = new PortNumber(Integer.parseInt(portStr));
287
288         LOG.info("connectionInfo: {}", new ConnectionInfoBuilder()
289                 .setRemoteIp(address)
290                 .setRemotePort(port)
291                 .build());
292         return new ConnectionInfoBuilder()
293                        .setRemoteIp(address)
294                        .setRemotePort(port)
295                        .build();
296     }
297
298     private String connectionInfoToString(final ConnectionInfo connectionInfo) {
299         return new String(connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
300     }
301
302     private boolean addOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
303         boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
304                 SouthboundMapper.createInstanceIdentifier(connectionInfo),
305                 SouthboundMapper.createNode(connectionInfo));
306         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
307         return result;
308     }
309
310     private Node getOvsdbNode(final ConnectionInfo connectionInfo) {
311         Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
312                 SouthboundMapper.createInstanceIdentifier(connectionInfo));
313         return node;
314     }
315
316     private boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
317         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
318                 SouthboundMapper.createInstanceIdentifier(connectionInfo));
319         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
320         return result;
321     }
322
323     private Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
324         Assert.assertTrue(addOvsdbNode(connectionInfo));
325         Node node = getOvsdbNode(connectionInfo);
326         Assert.assertNotNull("Should find OVSDB node after connect", node);
327         LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
328         return node;
329     }
330
331     private boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
332         Assert.assertTrue(deleteOvsdbNode(connectionInfo));
333         Node node = getOvsdbNode(connectionInfo);
334         Assert.assertNull("Should not find OVSDB node after disconnect", node);
335         //Assume.assumeNotNull(node); // Using assumeNotNull because there is no assumeNull
336         LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
337         return true;
338     }
339
340     private String getLocalControllerHostIpAddress() {
341         String ipaddress = null;
342         try{
343             for (Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
344                  ifaces.hasMoreElements();) {
345                 NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
346
347                 for (Enumeration<InetAddress> inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
348                     InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
349                     if (!inetAddr.isLoopbackAddress()) {
350                         if (inetAddr.isSiteLocalAddress()) {
351                             ipaddress = inetAddr.getHostAddress();
352                             break;
353                         }
354                     }
355                 }
356             }
357         }catch (Exception e){
358             LOG.warn("Exception while fetching local host ip address ",e);
359         }
360         return ipaddress;
361     }
362
363     private String getControllerTarget(Node ovsdbNode) {
364         String target = null;
365         String ipAddr = null;
366         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
367         ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
368         LOG.info("connectionInfo: {}", connectionInfo);
369         if (connectionInfo != null && connectionInfo.getLocalIp() != null) {
370             ipAddr = new String(connectionInfo.getLocalIp().getValue());
371         }
372         if (ipAddr == null) {
373             ipAddr = getLocalControllerHostIpAddress();
374         }
375
376         if (ipAddr != null) {
377             target = NetvirtITConstants.OPENFLOW_CONNECTION_PROTOCOL + ":"
378                     + ipAddr + ":" + NetvirtITConstants.DEFAULT_OPENFLOW_PORT;
379         }
380
381         return target;
382     }
383
384     //@Ignore//
385     @Test
386     public void testAddDeleteOvsdbNode() throws InterruptedException {
387         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
388         connectOvsdbNode(connectionInfo);
389         ControllerEntry controllerEntry;
390         for (int i = 0; i < 10; i++) {
391             Node ovsdbNode = getOvsdbNode(connectionInfo);
392             Assert.assertNotNull("ovsdb node not found", ovsdbNode);
393             String controllerTarget = getControllerTarget(ovsdbNode);
394             Assert.assertNotNull("Failed to get controller target", controllerTarget);
395             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME);
396             Assert.assertNotNull(bridge);
397             Assert.assertNotNull(bridge.getControllerEntry());
398             controllerEntry = bridge.getControllerEntry().iterator().next();
399             Assert.assertEquals(controllerTarget, controllerEntry.getTarget().getValue());
400             if (controllerEntry.isIsConnected()) {
401                 Assert.assertTrue(controllerEntry.isIsConnected());
402                 break;
403             }
404             Thread.sleep(1000);
405         }
406
407         Assert.assertTrue(deleteBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME));
408         Thread.sleep(1000);
409         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
410     }
411
412     @Ignore
413     @Test
414     public void testOpenVSwitchOtherConfig() throws InterruptedException {
415         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
416         Node ovsdbNode = connectOvsdbNode(connectionInfo);
417         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
418         Assert.assertNotNull(ovsdbNodeAugmentation);
419         List<OpenvswitchOtherConfigs> otherConfigsList = ovsdbNodeAugmentation.getOpenvswitchOtherConfigs();
420         if (otherConfigsList != null) {
421             for (OpenvswitchOtherConfigs otherConfig : otherConfigsList) {
422                 if (otherConfig.getOtherConfigKey().equals("local_ip")) {
423                     LOG.info("local_ip: {}", otherConfig.getOtherConfigValue());
424                     break;
425                 } else {
426                     LOG.info("other_config {}:{}", otherConfig.getOtherConfigKey(), otherConfig.getOtherConfigValue());
427                 }
428             }
429         } else {
430             LOG.info("other_config is not present");
431         }
432         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
433         //Assume.assumeTrue(disconnectOvsdbNode(connectionInfo));
434     }
435
436     private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
437                               final ConnectionInfo connectionInfo) {
438         InstanceIdentifier<Node> connectionNodePath = SouthboundMapper.createInstanceIdentifier(connectionInfo);
439         ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
440     }
441
442     private List<ProtocolEntry> createMdsalProtocols() {
443         List<ProtocolEntry> protocolList = new ArrayList<ProtocolEntry>();
444         ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
445                 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
446         protocolList.add(new ProtocolEntryBuilder().
447                 setProtocol((Class<? extends OvsdbBridgeProtocolBase>) mapper.get("OpenFlow13")).build());
448         return protocolList;
449     }
450
451     private OvsdbTerminationPointAugmentationBuilder createGenericOvsdbTerminationPointAugmentationBuilder() {
452         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder =
453                 new OvsdbTerminationPointAugmentationBuilder();
454         ovsdbTerminationPointAugmentationBuilder.setInterfaceType(
455                 new InterfaceTypeEntryBuilder()
456                         .setInterfaceType(
457                                 SouthboundMapper.createInterfaceType("internal"))
458                         .build().getInterfaceType());
459         return ovsdbTerminationPointAugmentationBuilder;
460     }
461
462     private boolean addTerminationPoint(final NodeId bridgeNodeId, final String portName,
463             final OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder)
464         throws InterruptedException {
465
466         InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(bridgeNodeId);
467         NodeBuilder portNodeBuilder = new NodeBuilder();
468         NodeId portNodeId = SouthboundMapper.createManagedNodeId(portIid);
469         portNodeBuilder.setNodeId(portNodeId);
470         TerminationPointBuilder entry = new TerminationPointBuilder();
471         entry.setKey(new TerminationPointKey(new TpId(portName)));
472         entry.addAugmentation(
473                 OvsdbTerminationPointAugmentation.class,
474                 ovsdbTerminationPointAugmentationBuilder.build());
475         portNodeBuilder.setTerminationPoint(Lists.newArrayList(entry.build()));
476         boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
477                 portIid, portNodeBuilder.build());
478         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
479         return result;
480     }
481
482     /*
483      * base method for adding test bridges.  Other helper methods used to create bridges should utilize this method.
484      *
485      * @param connectionInfo
486      * @param bridgeIid if passed null, one is created
487      * @param bridgeName cannot be null
488      * @param bridgeNodeId if passed null, one is created based on <code>bridgeIid</code>
489      * @param setProtocolEntries toggles whether default protocol entries are set for the bridge
490      * @param failMode toggles whether default fail mode is set for the bridge
491      * @param setManagedBy toggles whether to setManagedBy for the bridge
492      * @param dpType if passed null, this parameter is ignored
493      * @param externalIds if passed null, this parameter is ignored
494      * @param otherConfig if passed null, this parameter is ignored
495      * @return success of bridge addition
496      * @throws InterruptedException
497      */
498     private boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
499             final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
500             final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
501             final Class<? extends DatapathTypeBase> dpType,
502             final List<BridgeExternalIds> externalIds,
503             final List<BridgeOtherConfigs> otherConfigs) throws InterruptedException {
504
505         NodeBuilder bridgeNodeBuilder = new NodeBuilder();
506         if (bridgeIid == null) {
507             bridgeIid = SouthboundMapper.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
508         }
509         if (bridgeNodeId == null) {
510             bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
511         }
512         bridgeNodeBuilder.setNodeId(bridgeNodeId);
513         OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
514         ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
515         if (setProtocolEntries) {
516             ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
517         }
518         if (failMode != null) {
519             ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
520         }
521         if (setManagedBy) {
522             setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
523         }
524         if (dpType != null) {
525             ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
526         }
527         if (externalIds != null) {
528             ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
529         }
530         if (otherConfigs != null) {
531             ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
532         }
533         bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
534         LOG.debug("Built with the intent to store bridge data {}",
535                 ovsdbBridgeAugmentationBuilder.toString());
536         boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
537                 bridgeIid, bridgeNodeBuilder.build());
538         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
539         return result;
540     }
541
542     private boolean addBridge(final ConnectionInfo connectionInfo, final String bridgeName)
543         throws InterruptedException {
544
545         return addBridge(connectionInfo, null, bridgeName, null, true,
546                 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null);
547     }
548
549     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo) {
550         return getBridge(connectionInfo, NetvirtITConstants.BRIDGE_NAME);
551     }
552
553     /**
554      * Extract the <code>store</code> type data store contents for the particular bridge identified by
555      * <code>bridgeName</code>.
556      *
557      * @param connectionInfo
558      * @param bridgeName
559      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
560      * @return <code>store</code> type data store contents
561      */
562     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
563             LogicalDatastoreType store) {
564         Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
565         Assert.assertNotNull(bridgeNode);
566         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
567         Assert.assertNotNull(ovsdbBridgeAugmentation);
568         return ovsdbBridgeAugmentation;
569     }
570
571     /**
572      * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
573      * identified by <code>bridgeName</code>
574      *
575      * @param connectionInfo
576      * @param bridgeName
577      * @see <code>NetvirtIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
578      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
579      */
580     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
581         return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
582     }
583
584     /**
585      * Extract the node contents from <code>store</code> type data store for the
586      * bridge identified by <code>bridgeName</code>
587      *
588      * @param connectionInfo
589      * @param bridgeName
590      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
591      * @return <code>store</code> type data store contents
592      */
593     private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
594         InstanceIdentifier<Node> bridgeIid =
595                 SouthboundMapper.createInstanceIdentifier(connectionInfo,
596                     new OvsdbBridgeName(bridgeName));
597         return mdsalUtils.read(store, bridgeIid);
598     }
599
600     /**
601      * Extract the node contents from <code>LogicalDataStoreType.OPERATIONAL</code> data store for the
602      * bridge identified by <code>bridgeName</code>
603      *
604      * @param connectionInfo
605      * @param bridgeName
606      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
607      */
608     private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName) {
609         return getBridgeNode(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
610     }
611
612     private boolean deleteBridge(ConnectionInfo connectionInfo) throws InterruptedException {
613         return deleteBridge(connectionInfo, NetvirtITConstants.BRIDGE_NAME);
614     }
615
616     private boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName)
617         throws InterruptedException {
618
619         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
620                 SouthboundMapper.createInstanceIdentifier(connectionInfo,
621                         new OvsdbBridgeName(bridgeName)));
622         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
623         return result;
624     }
625
626     private InstanceIdentifier<Node> getTpIid(ConnectionInfo connectionInfo, OvsdbBridgeAugmentation bridge) {
627         return SouthboundMapper.createInstanceIdentifier(connectionInfo,
628             bridge.getBridgeName());
629     }
630
631     /**
632      * isBundleReady is used to check if the requested bundle is Active
633      */
634     public void isBundleReady(BundleContext bundleContext, String bundleName) throws InterruptedException {
635         boolean ready = false;
636
637         while (!ready) {
638             int state = Bundle.UNINSTALLED;
639             Bundle[] bundles = bundleContext.getBundles();
640             for (Bundle element : bundles) {
641                 if (element.getSymbolicName().equals(bundleName)) {
642                     state = element.getState();
643                     LOG.info(">>>>> bundle is ready {}", bundleName);
644                     break;
645                 }
646             }
647             if (state != Bundle.ACTIVE) {
648                 LOG.info(">>>>> bundle not ready {}", bundleName);
649                 Thread.sleep(5000);
650             } else {
651                 ready = true;
652             }
653         }
654     }
655
656     private void netVirtAddPort(ConnectionInfo connectionInfo) throws InterruptedException {
657         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME);
658         Assert.assertNotNull(bridge);
659         NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundMapper.createInstanceIdentifier(
660                 connectionInfo, bridge.getBridgeName()));
661         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
662                 createGenericOvsdbTerminationPointAugmentationBuilder();
663         String portName = NetvirtITConstants.PORT_NAME;
664         ovsdbTerminationBuilder.setName(portName);
665         Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
666         InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
667         Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
668         Assert.assertNotNull(terminationPointNode);
669     }
670
671     /**
672      * Test for basic southbound events to netvirt.
673      * <pre>The test will:
674      * - connect to an OVSDB node and verify it is added to operational
675      * - then verify that br-int was created on the node and stored in operational
676      * - a port is then added to the bridge to verify that it is ignored by netvirt
677      * - remove the bridge
678      * - remove the node and verify it is not in operational
679      * </pre>
680      * @throws InterruptedException
681      */
682     // TODO add verification of flows
683     //@Ignore //
684     @Test
685     public void testNetVirt() throws InterruptedException {
686         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
687         connectOvsdbNode(connectionInfo);
688         Thread.sleep(10000);
689         netVirtAddPort(connectionInfo);
690         Thread.sleep(10000);
691         Assert.assertTrue(deleteBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME));
692         Thread.sleep(10000);
693         Assert.assertTrue(disconnectOvsdbNode(connectionInfo));
694     }
695
696     @Ignore
697     @Test
698     public void testNetVirt2() throws InterruptedException {
699         Thread.sleep(60000);
700     }
701
702     @Test
703     public void testReadOvsdbTopologyNodes() throws InterruptedException {
704         Thread.sleep(10000);
705         List<Node> ovsdbNodes = southbound.readOvsdbTopologyNodes();
706         for (Node node : ovsdbNodes) {
707             LOG.info(">>>>> node: {}", node);
708         }
709     }
710 }