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