*/
package org.opendaylight.ovsdb.openstack.netvirt.it;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import static org.ops4j.pax.exam.CoreOptions.composite;
import static org.ops4j.pax.exam.CoreOptions.maven;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
import static org.ops4j.pax.exam.CoreOptions.vmOption;
import static org.ops4j.pax.exam.CoreOptions.when;
+import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
+import static org.ops4j.pax.exam.MavenUtils.asInProject;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.karafDistributionConfiguration;
import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
+import java.util.Map;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.inject.Inject;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
+import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.PipelineOrchestrator;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.FlowUtils;
import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.*;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
private Option[] getOtherOptions() {
return new Option[] {
+ wrappedBundle(
+ mavenBundle("org.opendaylight.ovsdb", "utils.mdsal-openflow")
+ .version(asInProject())
+ .type("jar")),
vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
keepRuntimeFolder()
};
@Test
public void testNetVirt() throws InterruptedException {
ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portStr);
- connectOvsdbNode(connectionInfo);
+ Node ovsdbNode = connectOvsdbNode(connectionInfo);
+
Thread.sleep(10000);
+ // Verify the pipeline flows were installed
+ PipelineOrchestrator pipelineOrchestrator =
+ (PipelineOrchestrator) ServiceHelper.getGlobalInstance(PipelineOrchestrator.class, this);
+ assertNotNull("Could not find PipelineOrchestrator Service", pipelineOrchestrator);
+ Node bridgeNode = southbound.getBridgeNode(ovsdbNode, NetvirtITConstants.INTEGRATION_BRIDGE_NAME);
+ assertNotNull("bridge " + NetvirtITConstants.INTEGRATION_BRIDGE_NAME + " was not found", bridgeNode);
+ long datapathId = southbound.getDataPathId(bridgeNode);
+ org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder nodeBuilder =
+ FlowUtils.createNodeBuilder(datapathId);
+
+ List<Service> staticPipeline = pipelineOrchestrator.getStaticPipeline();
+ List<Service> staticPipelineFound = Lists.newArrayList();
+ for (Service service : pipelineOrchestrator.getServiceRegistry().keySet()) {
+ if (staticPipeline.contains(service)) {
+ staticPipelineFound.add(service);
+ }
+ FlowBuilder flowBuilder = FlowUtils.getPipelineFlow(service.getTable(), (short)0);
+ Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
+ assertNotNull("Could not find flow in config", flow);
+ flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
+ assertNotNull("Could not find flow in operational", flow);
+ }
+ assertEquals("did not find all expected flows in static pipeline",
+ staticPipeline.size(), staticPipelineFound.size());
+
netVirtAddPort(connectionInfo);
Thread.sleep(10000);
Assert.assertTrue(deleteBridge(connectionInfo, NetvirtITConstants.INTEGRATION_BRIDGE_NAME));
LOG.info(">>>>> node: {}", node);
}
}
+
+ private Flow getFlow (
+ FlowBuilder flowBuilder,
+ org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder nodeBuilder,
+ LogicalDatastoreType store)
+ throws InterruptedException {
+
+ Flow flow = null;
+ for (int i = 0; i < 10; i++) {
+ flow = FlowUtils.getFlow(flowBuilder, nodeBuilder, dataBroker.newReadOnlyTransaction(), store);
+ if (flow != null) {
+ LOG.info("getFlow: flow({}): {}", store, flow);
+ break;
+ }
+ Thread.sleep(1000);
+ }
+ return flow;
+ }
}
<Embed-Dependency>utils.config,utils.mdsal-openflow;type=!pom;inline=false</Embed-Dependency>
<Embed-Transitive>true</Embed-Transitive>
<Export-Package>
- org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.*
+ org.opendaylight.ovsdb.openstack.netvirt.providers,
+ org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13
</Export-Package>
</instructions>
</configuration>
package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13;
+import java.util.List;
+import java.util.Map;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.osgi.framework.ServiceReference;
public interface PipelineOrchestrator {
Service getNextServiceInPipeline(Service service);
AbstractServiceInstance getServiceInstance(Service service);
+ Map<Service, AbstractServiceInstance> getServiceRegistry();
+ List<Service> getStaticPipeline();
void enqueue(Node node);
void registerService(final ServiceReference ref, AbstractServiceInstance serviceInstance);
void unregisterService(final ServiceReference ref);
package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
public class PipelineOrchestratorImpl implements ConfigInterface, NodeCacheListener, PipelineOrchestrator {
private static final Logger LOG = LoggerFactory.getLogger(PipelineOrchestratorImpl.class);
+
+ public List<Service> getStaticPipeline() {
+ return staticPipeline;
+ }
+
private List<Service> staticPipeline = Lists.newArrayList(
Service.CLASSIFIER,
Service.ARP_RESPONDER,
Service.OUTBOUND_NAT,
Service.L2_FORWARDING
);
+
+ public Map<Service, AbstractServiceInstance> getServiceRegistry() {
+ return serviceRegistry;
+ }
+
Map<Service, AbstractServiceInstance> serviceRegistry = Maps.newConcurrentMap();
private volatile BlockingQueue<Node> queue;
private ExecutorService eventHandler;
Service service = (Service)ref.getProperty(AbstractServiceInstance.SERVICE_PROPERTY);
LOG.info("registerService {} - {}", serviceInstance, service);
serviceRegistry.put(service, serviceInstance);
+ // insert the service if not already there. The list is ordered based of table ID.
+ if (!staticPipeline.contains(service) && !isTableInPipeline(service.getTable())) {
+ staticPipeline.add(service);
+ Collections.sort(staticPipeline, Service.insertComparator);
+ }
+ LOG.info("registerService: {}", staticPipeline);
+ }
+
+ private boolean isTableInPipeline (short tableId) {
+ boolean found = false;
+ for (Service service : staticPipeline) {
+ if (service.getTable() == tableId) {
+ found = true;
+ break;
+ }
+ }
+ return found;
}
public void unregisterService(final ServiceReference ref) {
package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13;
+import java.util.Comparator;
+
public enum Service {
CLASSIFIER ((short) 0, "Classifier"),
GATEWAY_RESOLVER((short) 0, "External Network Gateway Resolver"),
DIRECTOR ((short) 10, "Director"),
+ SFC_CLASSIFIER ((short) 10, "SFC Classifier"),
ARP_RESPONDER ((short) 20, "Distributed ARP Responder"),
INBOUND_NAT ((short) 30, "DNAT for inbound floating-ip traffic"),
EGRESS_ACL ((short) 40, "Egress Acces-control"),
public String getDescription() {
return description;
}
+
+ public static Comparator<Service> insertComparator = new Comparator<Service>() {
+
+ @Override
+ public int compare(Service service1, Service service2) {
+ return service1.getTable() - service2.getTable();
+ }
+ };
}
<properties>
<networkconfig.neutron.version>0.6.0-SNAPSHOT</networkconfig.neutron.version>
<openflowplugin.version>0.2.0-SNAPSHOT</openflowplugin.version>
+ <powermock.version>1.5.2</powermock.version>
<sonar.jacoco.itReportPath>../it/target/jacoco-it.exec</sonar.jacoco.itReportPath>
<sfc.project.version>0.2.0-SNAPSHOT</sfc.project.version>
</properties>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-common-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller.model</groupId>
+ <artifactId>model-inventory</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.openflowplugin</groupId>
+ <artifactId>openflowplugin-extension-nicira</artifactId>
+ <version>${openflowplugin.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.openflowplugin</groupId>
+ <artifactId>openflowjava-extension-nicira</artifactId>
+ <version>${openflowplugin.version}</version>
+ </dependency>
<dependency>
<groupId>org.opendaylight.openflowplugin.model</groupId>
<artifactId>model-flow-base</artifactId>
<artifactId>sfc-model</artifactId>
<version>${sfc.project.version}</version>
</dependency>
- <dependency>
- <groupId>org.opendaylight.sfc</groupId>
- <artifactId>sfc-ovs</artifactId>
- <version>${sfc.project.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.sfc</groupId>
<artifactId>sfc-provider</artifactId>
<artifactId>mockito-all</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-core</artifactId>
+ <version>${powermock.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-module-junit4</artifactId>
+ <version>${powermock.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-api-mockito</artifactId>
+ <version>${powermock.version}</version>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.codehaus.sonar-plugins.java</groupId>
<artifactId>sonar-jacoco-listeners</artifactId>
package org.opendaylight.ovsdb.openstack.netvirt.sfc;
+import java.util.Dictionary;
+import java.util.Hashtable;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.OF13Provider;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.openflow13.INetvirtSfcOF13Provider;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.openflow13.NetvirtSfcOF13Provider;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.openflow13.services.SfcClassifierService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private NetvirtSfcAclListener aclListener;
private NetvirtSfcClassifierListener classfierListener;
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ LOG.info("bundleContext is: {}", bundleContext);
+ }
+
+ private BundleContext bundleContext;
+
+ public NetvirtSfcProvider(BundleContext bundleContext) {
+ LOG.info("NetvirtSfcProvider: bundleContext: {}", bundleContext);
+ this.bundleContext = bundleContext;
+ }
+
@Override
public void onSessionInitiated(ProviderContext session) {
LOG.info("NetvirtSfcProvider Session Initiated");
INetvirtSfcOF13Provider provider = new NetvirtSfcOF13Provider(dataBroker);
aclListener = new NetvirtSfcAclListener(provider, dataBroker);
classfierListener = new NetvirtSfcClassifierListener(provider, dataBroker);
+
+ addToPipeline();
}
@Override
aclListener.close();
classfierListener.close();
}
+
+ private void addToPipeline() {
+ SfcClassifierService sfcClassifierService = new SfcClassifierService();
+ registerService(bundleContext, SfcClassifierService.class.getName(),
+ sfcClassifierService, Service.SFC_CLASSIFIER);
+ sfcClassifierService.setDependencies(bundleContext, null);
+ }
+
+ private ServiceRegistration<?> registerService(BundleContext bundleContext, String[] interfaces,
+ Dictionary<String, Object> properties, Object impl) {
+ ServiceRegistration<?> serviceRegistration = bundleContext.registerService(interfaces, impl, properties);
+ return serviceRegistration;
+ }
+
+ private ServiceRegistration<?> registerService(BundleContext bundleContext, String interfaceClassName,
+ Object impl, Object serviceProperty) {
+ Dictionary<String, Object> properties = new Hashtable<>();
+ properties.put(AbstractServiceInstance.SERVICE_PROPERTY, serviceProperty);
+ properties.put(Constants.PROVIDER_NAME_PROPERTY, OF13Provider.NAME);
+ return registerService(bundleContext,
+ new String[] {AbstractServiceInstance.class.getName(),
+ interfaceClassName}, properties, impl);
+ }
}
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.matches.ace.type.ace.ip.ace.ip.version.AceIpv4;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.acl.rev150105.RedirectToSfc;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.Bridges;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.bridges.Bridge;
--- /dev/null
+/*
+ * Copyright © 2015 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.sfc.openflow13.services;
+
+import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+public class SfcClassifierService extends AbstractServiceInstance implements ConfigInterface {
+ public SfcClassifierService(Service service) {
+ super(service);
+ }
+
+ public SfcClassifierService() {
+ super(Service.SFC_CLASSIFIER);
+ }
+
+ @Override
+ public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+ super.setDependencies(bundleContext.getServiceReference(SfcClassifierService.class.getName()), this);
+ }
+
+ @Override
+ public void setDependencies(Object impl) {}
+}
+/*
+ * Copyright © 2015 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev141210;
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.ModuleIdentifier;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.NetvirtSfcProvider;
+import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class NetvirtSfcModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev141210.AbstractNetvirtSfcModule {
-
+public class NetvirtSfcModule extends AbstractNetvirtSfcModule {
private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcModule.class);
+ private BundleContext bundleContext;
- public NetvirtSfcModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ public NetvirtSfcModule(ModuleIdentifier identifier, DependencyResolver dependencyResolver) {
super(identifier, dependencyResolver);
}
- public NetvirtSfcModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev141210.NetvirtSfcModule oldModule, java.lang.AutoCloseable oldInstance) {
+ public NetvirtSfcModule(ModuleIdentifier identifier, DependencyResolver dependencyResolver,
+ NetvirtSfcModule oldModule, java.lang.AutoCloseable oldInstance) {
super(identifier, dependencyResolver, oldModule, oldInstance);
}
@Override
public java.lang.AutoCloseable createInstance() {
LOG.info("Netvirt SFC module initialization.");
- NetvirtSfcProvider sfcProvider = new NetvirtSfcProvider();
+ NetvirtSfcProvider sfcProvider = new NetvirtSfcProvider(bundleContext);
getBrokerDependency().registerProvider(sfcProvider);
return sfcProvider;
}
+
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
}
/*
-* Generated file
-*
-* Generated from: yang module name: netvirt-sfc yang module local name: netvirt-sfc
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Wed Sep 23 15:18:24 EDT 2015
-*
-* Do not modify this file unless it is present under src/main directory
-*/
+ * Copyright © 2015 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev141210;
-public class NetvirtSfcModuleFactory extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev141210.AbstractNetvirtSfcModuleFactory {
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.osgi.framework.BundleContext;
+
+public class NetvirtSfcModuleFactory extends AbstractNetvirtSfcModuleFactory {
+ @Override
+ public NetvirtSfcModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
+ BundleContext bundleContext) {
+ NetvirtSfcModule module = super.instantiateModule(instanceName, dependencyResolver, bundleContext);
+ module.setBundleContext(bundleContext);
+ return module;
+ }
+
+ @Override
+ public NetvirtSfcModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
+ NetvirtSfcModule oldModule, AutoCloseable oldInstance,
+ BundleContext bundleContext) {
+ NetvirtSfcModule module = super.instantiateModule(instanceName, dependencyResolver,
+ oldModule, oldInstance, bundleContext);
+ module.setBundleContext(bundleContext);
+ return module;
+ }
}
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
+
package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev141210;
+import java.util.Dictionary;
import org.junit.Test;
+import org.junit.runner.RunWith;
import org.opendaylight.controller.config.api.DependencyResolver;
import org.opendaylight.controller.config.api.JmxAttribute;
import org.opendaylight.controller.config.api.ModuleIdentifier;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.PipelineOrchestrator;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.NetvirtSfcProvider;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import javax.management.ObjectName;
+import org.opendaylight.ovsdb.openstack.netvirt.sfc.openflow13.services.SfcClassifierService;
+import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+@PrepareForTest(ServiceHelper.class)
+@RunWith(PowerMockRunner.class)
public class NetvirtSfcModuleTest {
@Test
public void testCustomValidation() {
module.customValidation();
}
+ @SuppressWarnings("unchecked")
@Test
public void testCreateInstance() throws Exception {
// configure mocks
BindingAwareBroker broker = mock(BindingAwareBroker.class);
ProviderContext session = mock(ProviderContext.class);
DataBroker dataBroker = mock(DataBroker.class);
- when(dependencyResolver.resolveInstance(eq(BindingAwareBroker.class), any(ObjectName.class), any(JmxAttribute.class))).thenReturn(broker);
+ when(dependencyResolver.resolveInstance(eq(BindingAwareBroker.class),
+ any(ObjectName.class), any(JmxAttribute.class))).thenReturn(broker);
when(session.getSALService(eq(DataBroker.class))).thenReturn(dataBroker);
// create instance of module with injected mocks
NetvirtSfcModule module = new NetvirtSfcModule(mock(ModuleIdentifier.class), dependencyResolver);
// getInstance calls resolveInstance to get the broker dependency and then calls createInstance
+ BundleContext bundleContext = mock(BundleContext.class);
+ PowerMockito.mockStatic(ServiceHelper.class);
+ PipelineOrchestrator pipelineOrchestrator = mock(PipelineOrchestrator.class);
+ PowerMockito.when(ServiceHelper.getGlobalInstance(eq(PipelineOrchestrator.class), any(AbstractServiceInstance.class)))
+ .thenReturn(pipelineOrchestrator);
+ PowerMockito.when(ServiceHelper.getGlobalInstance(eq(Southbound.class), any(AbstractServiceInstance.class)))
+ .thenReturn(mock(Southbound.class));
+
+ doNothing().when(pipelineOrchestrator).registerService(any(ServiceReference.class),
+ any(AbstractServiceInstance.class));
+ when(bundleContext.registerService(
+ eq(new String[]{AbstractServiceInstance.class.getName(), SfcClassifierService.class.getName()}),
+ any(),
+ any(Dictionary.class)))
+ .thenReturn(mock(ServiceRegistration.class));
+ when(bundleContext.getServiceReference(SfcClassifierService.class.getName()))
+ .thenReturn(mock(ServiceReference.class));
AutoCloseable closeable = module.getInstance();
+ ((NetvirtSfcProvider)closeable).setBundleContext(bundleContext);
((NetvirtSfcProvider)closeable).onSessionInitiated(session);
// verify that the module registered the returned provider with the broker
verify(broker).registerProvider((NetvirtSfcProvider)closeable);
import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.PipelineOrchestrator;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.openflow13.NshUtils;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.openflow13.SfcClassifier;
import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.AclUtils;
import org.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.karaf.options.LogLevelOption;
import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel;
import org.ops4j.pax.exam.options.MavenUrlReference;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
"log4j.logger.org.opendaylight.ovsdb.openstack.netvirt.sfc",
LogLevel.TRACE.name()),
- /*editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
+ editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
"log4j.logger.org.opendaylight.ovsdb",
- LogLevelOption.LogLevel.TRACE.name()),*/
+ LogLevelOption.LogLevel.TRACE.name()),
super.getLoggingOption());
}
* and program the pipeline flows.
*/
@Test
- public void testDoIt() throws InterruptedException {
+ public void testNetvirtSfc() throws InterruptedException {
String bridgeName = INTEGRATION_BRIDGE_NAME;
ConnectionInfo connectionInfo = southboundUtils.getConnectionInfo(addressStr, portStr);
assertNotNull("connection failed", southboundUtils.connectOvsdbNode(connectionInfo));
for (int i = 0; i < 10; i++) {
ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
assertNotNull("ovsdb node not found", ovsdbNode);
- String controllerTarget = "tcp:192.168.50.1:6653";//SouthboundUtil.getControllerTarget(ovsdbNode);
+ String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
assertNotNull("Failed to get controller target", controllerTarget);
OvsdbBridgeAugmentation bridge = southboundUtils.getBridge(connectionInfo, bridgeName);
- assertNotNull(bridge);
- assertNotNull(bridge.getControllerEntry());
- controllerEntry = bridge.getControllerEntry().iterator().next();
- assertEquals(controllerTarget, controllerEntry.getTarget().getValue());
- if (controllerEntry.isIsConnected()) {
- Assert.assertTrue(controllerEntry.isIsConnected());
- break;
+ if (bridge != null) {
+ assertNotNull("Failed to read bridge", bridge);
+ assertNotNull("Failed to extract controllerEntry", bridge.getControllerEntry());
+ controllerEntry = bridge.getControllerEntry().iterator().next();
+ assertEquals(controllerTarget, controllerEntry.getTarget().getValue());
+ if (controllerEntry.isIsConnected()) {
+ Assert.assertTrue("switch is not connected to the controller", controllerEntry.isIsConnected());
+ break;
+ }
}
Thread.sleep(1000);
}
+ Node bridgeNode = southbound.getBridgeNode(ovsdbNode, bridgeName);
+ assertNotNull("bridge " + bridgeName + " was not found", bridgeNode);
+ long datapathId = southbound.getDataPathId(bridgeNode);
+
/* TODO: add code to write to mdsal to exercise the sfc dataChangeListener */
/* allow some time to let the impl code do it's work to push flows */
/* or just comment out below lines and just manually verify on the bridges and reset them */
//Thread.sleep(10000);
+ NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
+ FlowBuilder flowBuilder = FlowUtils.getPipelineFlow(Service.SFC_CLASSIFIER.getTable(), (short)0);
+ Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
+ assertNotNull("Could not find flow in config", flow);
+ flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
+ assertNotNull("Could not find flow in operational", flow);
+
assertTrue(southboundUtils.deleteBridge(connectionInfo, bridgeName));
Thread.sleep(1000);
assertTrue(southboundUtils.disconnectOvsdbNode(connectionInfo));
for (int i = 0; i < 10; i++) {
flow = FlowUtils.getFlow(flowBuilder, nodeBuilder, dataBroker.newReadOnlyTransaction(), store);
if (flow != null) {
- LOG.info("flow({}): {}", store, flow);
+ LOG.info("getFlow: flow({}): {}", store, flow);
break;
}
Thread.sleep(1000);
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
LOG.info("Cannot find data for Flow {}", flowBuilder.getFlowName());
return null;
}
+
+ public static FlowBuilder getPipelineFlow(short table, short gotoTable) {
+ FlowBuilder flowBuilder = new FlowBuilder();
+ flowBuilder.setMatch(new MatchBuilder().build());
+
+ String flowId = "DEFAULT_PIPELINE_FLOW_" + table;
+ flowBuilder.setId(new FlowId(flowId));
+ FlowKey key = new FlowKey(new FlowId(flowId));
+ flowBuilder.setStrict(true);
+ flowBuilder.setBarrier(false);
+ flowBuilder.setTableId(table);
+ flowBuilder.setKey(key);
+ flowBuilder.setFlowName(flowId);
+ flowBuilder.setHardTimeout(0);
+ flowBuilder.setIdleTimeout(0);
+ flowBuilder.setPriority(0);
+ return flowBuilder;
+ }
}