2 * Copyright © 2015 Red Hat, Inc. and others. All rights reserved.
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
9 package org.opendaylight.ovsdb.openstack.netvirt.sfc;
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertNull;
14 import static org.junit.Assert.assertTrue;
15 import static org.junit.Assert.fail;
16 import static org.ops4j.pax.exam.CoreOptions.composite;
17 import static org.ops4j.pax.exam.CoreOptions.maven;
18 import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
19 import static org.ops4j.pax.exam.CoreOptions.propagateSystemProperties;
20 import static org.ops4j.pax.exam.CoreOptions.vmOption;
21 import static org.ops4j.pax.exam.CoreOptions.when;
22 import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
23 import static org.ops4j.pax.exam.MavenUtils.asInProject;
24 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.configureConsole;
25 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
26 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
28 import java.math.BigInteger;
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.Properties;
32 import java.util.concurrent.atomic.AtomicBoolean;
33 import org.junit.Assert;
34 import org.junit.Before;
35 import org.junit.Ignore;
36 import org.junit.Test;
37 import org.junit.runner.RunWith;
38 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
39 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
40 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
41 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
42 import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound;
43 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
44 import org.opendaylight.ovsdb.openstack.netvirt.sfc.standalone.openflow13.SfcClassifier;
45 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.AclUtils;
46 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ClassifierUtils;
47 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.SfcUtils;
48 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ServiceFunctionForwarderUtils;
49 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ServiceFunctionUtils;
50 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
51 import org.opendaylight.ovsdb.southbound.SouthboundUtil;
52 import org.opendaylight.ovsdb.utils.mdsal.openflow.FlowUtils;
53 import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
54 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
55 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
56 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
57 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.ServiceFunctions;
58 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.ServiceFunctionsBuilder;
59 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.function.entry.SfDataPlaneLocator;
60 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.function.entry.SfDataPlaneLocatorBuilder;
61 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunction;
62 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sf.rev140701.service.functions.ServiceFunctionBuilder;
63 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.ServiceFunctionForwarders;
64 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.ServiceFunctionForwardersBuilder;
65 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
66 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarderBuilder;
67 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.ServiceFunctionDictionary;
68 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.ServiceFunctionDictionaryBuilder;
69 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.SffDataPlaneLocator;
70 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.SffDataPlaneLocatorBuilder;
71 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.service.function.dictionary.SffSfDataPlaneLocatorBuilder;
72 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.service.function.forwarder.sff.data.plane.locator.DataPlaneLocatorBuilder;
73 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sft.rev140701.Dpi;
74 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sft.rev140701.Firewall;
75 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.AccessLists;
76 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.AccessListsBuilder;
77 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.AclBuilder;
78 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.AccessListEntriesBuilder;
79 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.AceBuilder;
80 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.ActionsBuilder;
81 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;
82 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev150317.access.lists.acl.access.list.entries.ace.MatchesBuilder;
83 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
84 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
85 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.Classifiers;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.ClassifiersBuilder;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.ClassifierBuilder;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.SffsBuilder;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.SffBuilder;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105.Sfc;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105.SfcBuilder;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
102 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
103 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
104 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
105 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
106 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
107 import org.opendaylight.yangtools.concepts.Builder;
108 import org.opendaylight.yangtools.yang.binding.DataObject;
109 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
111 import org.ops4j.pax.exam.Configuration;
112 import org.ops4j.pax.exam.Option;
113 import org.ops4j.pax.exam.junit.PaxExam;
114 import org.ops4j.pax.exam.karaf.options.LogLevelOption;
115 import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel;
116 import org.ops4j.pax.exam.options.MavenUrlReference;
117 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
118 import org.ops4j.pax.exam.spi.reactors.PerClass;
119 import org.slf4j.Logger;
120 import org.slf4j.LoggerFactory;
122 @RunWith(PaxExam.class)
123 @ExamReactorStrategy(PerClass.class)
124 public class NetvirtSfcIT extends AbstractMdsalTestBase {
125 private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcIT.class);
126 private static AclUtils aclUtils = new AclUtils();
127 private static ClassifierUtils classifierUtils = new ClassifierUtils();
128 private static SfcUtils sfcUtils = new SfcUtils();
129 private static ServiceFunctionUtils serviceFunctionUtils = new ServiceFunctionUtils();
130 private static ServiceFunctionForwarderUtils serviceFunctionForwarderUtils = new ServiceFunctionForwarderUtils();
131 private static MdsalUtils mdsalUtils;
132 private static AtomicBoolean setup = new AtomicBoolean(false);
133 private static SouthboundUtils southboundUtils;
134 private static String addressStr;
135 private static String portStr;
136 private static String connectionType;
137 private static Southbound southbound;
138 private static DataBroker dataBroker;
139 public static final String CONTROLLER_IPADDRESS = "ovsdb.controller.address";
140 public static final String SERVER_IPADDRESS = "ovsdbserver.ipaddress";
141 public static final String SERVER_PORT = "ovsdbserver.port";
142 public static final String CONNECTION_TYPE = "ovsdbserver.connection";
143 public static final String CONNECTION_TYPE_ACTIVE = "active";
144 public static final String CONNECTION_TYPE_PASSIVE = "passive";
145 public static final String DEFAULT_SERVER_PORT = "6640";
146 public static final String INTEGRATION_BRIDGE_NAME = "br-int";
147 private static final String NETVIRT_TOPOLOGY_ID = "netvirt:1";
148 private static final String OVSDB_TRACE = "ovsdb.trace";
151 public String getModuleName() {
152 return "netvirt-sfc";
156 public String getInstanceName() {
157 return "netvirt-sfc-default";
161 public MavenUrlReference getFeatureRepo() {
163 .groupId("org.opendaylight.ovsdb")
164 .artifactId("openstack.net-virt-sfc-features-test")
165 .classifier("features")
167 .versionAsInProject();
171 public String getFeatureName() {
172 return "odl-ovsdb-sfc-test";
177 public Option[] config() {
178 Option[] parentOptions = super.config();
179 Option[] propertiesOptions = getPropertiesOptions();
180 Option[] otherOptions = getOtherOptions();
181 Option[] options = new Option[parentOptions.length + propertiesOptions.length + otherOptions.length];
182 System.arraycopy(parentOptions, 0, options, 0, parentOptions.length);
183 System.arraycopy(propertiesOptions, 0, options, parentOptions.length, propertiesOptions.length);
184 System.arraycopy(otherOptions, 0, options, parentOptions.length + propertiesOptions.length,
185 otherOptions.length);
189 private Option[] getOtherOptions() {
190 return new Option[] {
192 mavenBundle("org.opendaylight.ovsdb", "utils.mdsal-openflow")
193 .version(asInProject())
195 configureConsole().startLocalConsole(),
196 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
201 public Option[] getPropertiesOptions() {
202 return new Option[] {
203 propagateSystemProperties(SERVER_IPADDRESS, SERVER_PORT, CONNECTION_TYPE,
204 CONTROLLER_IPADDRESS, OVSDB_TRACE),
209 public Option getLoggingOption() {
211 when(Boolean.getBoolean(OVSDB_TRACE)).useOptions(
212 editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
213 "log4j.logger.org.opendaylight.ovsdb",
214 LogLevelOption.LogLevel.TRACE.name())),
215 editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
216 logConfiguration(NetvirtSfcIT.class),
217 LogLevel.INFO.name()),
218 editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
219 "log4j.logger.org.opendaylight.ovsdb.openstack.netvirt.sfc",
220 LogLevel.TRACE.name()),
221 editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
222 "log4j.logger.org.opendaylight.ovsdb.sfc",
223 LogLevel.TRACE.name()),
224 super.getLoggingOption());
227 protected String usage() {
228 return "Integration Test needs a valid connection configuration as follows :\n"
229 + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
230 + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
233 private void getProperties() {
234 Properties props = System.getProperties();
235 addressStr = props.getProperty(SERVER_IPADDRESS);
236 portStr = props.getProperty(SERVER_PORT, DEFAULT_SERVER_PORT);
237 connectionType = props.getProperty(CONNECTION_TYPE, "active");
238 LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
239 connectionType, addressStr, portStr);
240 if (connectionType.equalsIgnoreCase(CONNECTION_TYPE_ACTIVE)) {
241 if (addressStr == null) {
245 LOG.info("getProperties {}: {}", OVSDB_TRACE, props.getProperty(OVSDB_TRACE));
250 public void setup() {
252 LOG.info("Skipping setUp, already initialized");
259 } catch (Exception e) {
265 dataBroker = getDatabroker(getProviderContext());
266 mdsalUtils = new MdsalUtils(dataBroker);
267 assertNotNull("mdsalUtils should not be null", mdsalUtils);
268 southboundUtils = new SouthboundUtils(mdsalUtils);
269 assertTrue("Did not find " + NETVIRT_TOPOLOGY_ID, getNetvirtTopology());
270 southbound = (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this);
271 assertNotNull("southbound should not be null", southbound);
275 private ProviderContext getProviderContext() {
276 ProviderContext providerContext = null;
277 for (int i=0; i < 60; i++) {
278 providerContext = getSession();
279 if (providerContext != null) {
284 } catch (InterruptedException e) {
289 assertNotNull("providercontext should not be null", providerContext);
290 /* One more second to let the provider finish initialization */
293 } catch (InterruptedException e) {
296 return providerContext;
299 private DataBroker getDatabroker(ProviderContext providerContext) {
300 DataBroker dataBroker = providerContext.getSALService(DataBroker.class);
301 assertNotNull("dataBroker should not be null", dataBroker);
305 private Boolean getNetvirtTopology() {
306 LOG.info("getNetvirtTopology: looking for {}...", NETVIRT_TOPOLOGY_ID);
307 Boolean found = false;
308 final TopologyId topologyId = new TopologyId(new Uri(NETVIRT_TOPOLOGY_ID));
309 InstanceIdentifier<Topology> path =
310 InstanceIdentifier.create(NetworkTopology.class).child(Topology.class, new TopologyKey(topologyId));
311 for (int i = 0; i < 60; i++) {
312 Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
313 if (topology != null) {
314 LOG.info("getNetvirtTopology: found {}...", NETVIRT_TOPOLOGY_ID);
318 LOG.info("getNetvirtTopology: still looking ({})...", i);
321 } catch (InterruptedException e) {
330 public void testNetvirtSfcFeatureLoad() {
334 private AccessListsBuilder setAccessLists () {
335 MatchesBuilder matchesBuilder = aclUtils.matchesBuilder(new MatchesBuilder(), 80);
336 ActionsBuilder actionsBuilder = aclUtils.actionsBuilder(new ActionsBuilder(), Boolean.TRUE);
337 AceBuilder accessListEntryBuilder = aclUtils.aceBuilder(
338 new AceBuilder(), "http", matchesBuilder, actionsBuilder);
339 AccessListEntriesBuilder accessListEntriesBuilder = aclUtils.accessListEntriesBuidler(
340 new AccessListEntriesBuilder(), accessListEntryBuilder);
341 AclBuilder accessListBuilder = aclUtils.aclBuilder(new AclBuilder(),
342 "http", accessListEntriesBuilder);
343 AccessListsBuilder accessListsBuilder = aclUtils.accessListsBuidler(new AccessListsBuilder(),
345 LOG.info("AccessLists: {}", accessListsBuilder.build());
346 return accessListsBuilder;
350 public void testAccessLists() throws InterruptedException {
351 testModel(setAccessLists(), AccessLists.class, 0);
354 private ClassifiersBuilder setClassifiers() {
355 SffBuilder sffBuilder = classifierUtils.sffBuilder(new SffBuilder(), "sffname");
356 SffsBuilder sffsBuilder = classifierUtils.sffsBuilder(new SffsBuilder(), sffBuilder);
357 ClassifierBuilder classifierBuilder = classifierUtils.classifierBuilder(new ClassifierBuilder(),
358 "classifierName", "aclName", sffsBuilder);
359 ClassifiersBuilder classifiersBuilder = classifierUtils.ClassifiersBuilder(new ClassifiersBuilder(),
361 LOG.info("Classifiers: {}", classifiersBuilder.build());
362 return classifiersBuilder;
366 public void testClassifiers() throws InterruptedException {
367 testModel(setClassifiers(), Classifiers.class, 0);
370 private SfcBuilder netvirtSfcBuilder() {
371 return sfcUtils.sfcBuilder(new SfcBuilder(), "sfc");
375 public void testNetvirtSfcModel() throws InterruptedException {
376 testModel(netvirtSfcBuilder(), Sfc.class, 0);
379 private <T extends DataObject> void testModel(Builder<T> builder, Class<T> clazz, long wait)
380 throws InterruptedException {
381 InstanceIdentifier<T> path = InstanceIdentifier.create(clazz);
382 assertTrue(mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, path, builder.build()));
383 T result = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
384 assertNotNull(clazz.getSimpleName() + " should not be null", result);
386 assertTrue("Failed to remove " + clazz.getSimpleName(),
387 mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, path));
388 result = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
389 assertNull(clazz.getSimpleName() + " should be null", result);
392 private ServiceFunctionsBuilder serviceFunctionsBuilder() {
393 SfDataPlaneLocatorBuilder sfDataPlaneLocator =
394 serviceFunctionUtils.sfDataPlaneLocatorBuilder(new SfDataPlaneLocatorBuilder(),
395 "192.168.120.31", 6633, "testDpl1-1234-uuid", "testSff1");
396 List<SfDataPlaneLocator> sfDataPlaneLocatorList = serviceFunctionUtils.list(
397 new ArrayList<SfDataPlaneLocator>(), sfDataPlaneLocator);
398 ServiceFunctionBuilder serviceFunctionBuilder =
399 serviceFunctionUtils.serviceFunctionBuidler(new ServiceFunctionBuilder(),
400 "192.168.120.31", "testSf", sfDataPlaneLocatorList, Firewall.class);
401 List<ServiceFunction> serviceFunctionList = serviceFunctionUtils.list(
402 new ArrayList<ServiceFunction>(), serviceFunctionBuilder);
405 serviceFunctionUtils.sfDataPlaneLocatorBuilder(new SfDataPlaneLocatorBuilder(),
406 "192.168.120.32", 6633, "testDpl2-1234-uuid", "testSff2");
407 sfDataPlaneLocatorList = serviceFunctionUtils.list(
408 new ArrayList<SfDataPlaneLocator>(), sfDataPlaneLocator);
409 serviceFunctionBuilder =
410 serviceFunctionUtils.serviceFunctionBuidler(new ServiceFunctionBuilder(),
411 "192.168.120.32", "testSf2", sfDataPlaneLocatorList, Dpi.class);
412 serviceFunctionList = serviceFunctionUtils.list(
413 serviceFunctionList, serviceFunctionBuilder);
415 ServiceFunctionsBuilder serviceFunctionsBuilder =
416 serviceFunctionUtils.serviceFunctionsBuilder(new ServiceFunctionsBuilder(),
417 serviceFunctionList);
418 LOG.info("ServiceFunctions: {}", serviceFunctionsBuilder.build());
419 return serviceFunctionsBuilder;
422 private ServiceFunctionForwardersBuilder serviceFunctionForwardersBuilder() {
423 String sf1Name = "firewall-72";
424 String sff1Ip = "192.168.120.31";
425 String sff1Name = "SFF1";
426 String sffDpl1Name = "sfc-tun2";
427 String sn1Name = "OVSDB2";
428 String bridge1Name= "sw2";
431 DataPlaneLocatorBuilder dataPlaneLocatorBuilder =
432 serviceFunctionForwarderUtils.dataPlaneLocatorBuilder(
433 new DataPlaneLocatorBuilder(), sff1Ip, port);
434 SffDataPlaneLocatorBuilder sffDataPlaneLocatorBuilder =
435 serviceFunctionForwarderUtils.sffDataPlaneLocatorBuilder(
436 new SffDataPlaneLocatorBuilder(), dataPlaneLocatorBuilder, sffDpl1Name);
437 List<SffDataPlaneLocator> sffDataPlaneLocatorList = serviceFunctionForwarderUtils.list(
438 new ArrayList<SffDataPlaneLocator>(), sffDataPlaneLocatorBuilder);
440 SffSfDataPlaneLocatorBuilder sffSfDataPlaneLocatorBuilder =
441 serviceFunctionForwarderUtils.sffSfDataPlaneLocatorBuilder(
442 new SffSfDataPlaneLocatorBuilder(), sff1Ip, port);
443 ServiceFunctionDictionaryBuilder serviceFunctionDictionaryBuilder =
444 serviceFunctionForwarderUtils.serviceFunctionDictionaryBuilder(
445 new ServiceFunctionDictionaryBuilder(), sf1Name, Firewall.class,
446 sffSfDataPlaneLocatorBuilder);
447 List<ServiceFunctionDictionary> serviceFunctionDictionaryList = serviceFunctionForwarderUtils.list(
448 new ArrayList<ServiceFunctionDictionary>(), serviceFunctionDictionaryBuilder);
450 ServiceFunctionForwarderBuilder serviceFunctionForwarderBuilder =
451 serviceFunctionForwarderUtils.serviceFunctionForwarderBuilder(
452 new ServiceFunctionForwarderBuilder(), sff1Name, sn1Name, bridge1Name,
453 sffDataPlaneLocatorList, serviceFunctionDictionaryList);
454 List<ServiceFunctionForwarder> serviceFunctionForwarderList = serviceFunctionForwarderUtils.list(
455 new ArrayList<ServiceFunctionForwarder>(), serviceFunctionForwarderBuilder);
456 ServiceFunctionForwardersBuilder serviceFunctionForwardersBuilder =
457 serviceFunctionForwarderUtils.serviceFunctionForwardersBuilder(
458 new ServiceFunctionForwardersBuilder(), serviceFunctionForwarderList);
459 LOG.info("ServiceFunctionForwarders: {}", serviceFunctionForwardersBuilder.build());
460 return serviceFunctionForwardersBuilder;
464 public void testSfcModel() throws InterruptedException {
465 testModel(serviceFunctionsBuilder(), ServiceFunctions.class, 3000);
466 testModel(serviceFunctionForwardersBuilder(), ServiceFunctionForwarders.class, 3000);
470 * Connect to an ovsdb node. Netvirt should add br-int, add the controller address
471 * and program the pipeline flows.
474 public void testNetvirtSfc() throws InterruptedException {
475 String bridgeName = INTEGRATION_BRIDGE_NAME;
476 ConnectionInfo connectionInfo = southboundUtils.getConnectionInfo(addressStr, portStr);
477 assertNotNull("connection failed", southboundUtils.connectOvsdbNode(connectionInfo));
478 Node ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
479 assertNotNull("node is not connected", ovsdbNode);
480 ControllerEntry controllerEntry;
481 // Loop 10s checking if the controller was added
482 for (int i = 0; i < 10; i++) {
483 ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
484 assertNotNull("ovsdb node not found", ovsdbNode);
485 String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
486 assertNotNull("Failed to get controller target", controllerTarget);
487 OvsdbBridgeAugmentation bridge = southboundUtils.getBridge(connectionInfo, bridgeName);
488 if (bridge != null) {
489 assertNotNull("Failed to read bridge", bridge);
490 assertNotNull("Failed to extract controllerEntry", bridge.getControllerEntry());
491 controllerEntry = bridge.getControllerEntry().iterator().next();
492 assertEquals(controllerTarget, controllerEntry.getTarget().getValue());
493 if (controllerEntry.isIsConnected()) {
494 Assert.assertTrue("switch is not connected to the controller", controllerEntry.isIsConnected());
501 Node bridgeNode = southbound.getBridgeNode(ovsdbNode, bridgeName);
502 assertNotNull("bridge " + bridgeName + " was not found", bridgeNode);
503 long datapathId = southbound.getDataPathId(bridgeNode);
505 //Thread.sleep(10000);
507 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
508 FlowBuilder flowBuilder = FlowUtils.getPipelineFlow(Service.SFC_CLASSIFIER.getTable(), (short)0);
509 Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
510 assertNotNull("Could not find flow in config", flow);
511 flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
512 assertNotNull("Could not find flow in operational", flow);
514 assertTrue(southboundUtils.deleteBridge(connectionInfo, bridgeName));
516 assertTrue(southboundUtils.disconnectOvsdbNode(connectionInfo));
521 public void testStandalone() throws InterruptedException {
522 String bridgeName = "sw1";
523 ConnectionInfo connectionInfo = southboundUtils.getConnectionInfo(addressStr, portStr);
524 assertNotNull("connection failed", southboundUtils.connectOvsdbNode(connectionInfo));
525 Node ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
526 assertNotNull("node is not connected", ovsdbNode);
527 String controllerTarget = "tcp:192.168.50.1:6653";
528 List<ControllerEntry> setControllerEntry = southboundUtils.createControllerEntry(controllerTarget);
529 Assert.assertTrue(southboundUtils.addBridge(connectionInfo, null, bridgeName, null, true,
530 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null,
531 setControllerEntry, null, "00:00:00:00:00:00:00:01"));
532 // Loop 10s checking if the controller was added
533 for (int i = 0; i < 10; i++) {
534 ovsdbNode = southboundUtils.getOvsdbNode(connectionInfo);
535 assertNotNull("ovsdb node not found", ovsdbNode);
536 assertNotNull("Failed to get controller target", controllerTarget);
537 OvsdbBridgeAugmentation bridge = southboundUtils.getBridge(connectionInfo, bridgeName);
538 assertNotNull(bridge);
539 assertNotNull(bridge.getControllerEntry());
540 ControllerEntry controllerEntry = bridge.getControllerEntry().iterator().next();
541 assertEquals(controllerTarget, controllerEntry.getTarget().getValue());
542 if (controllerEntry.isIsConnected()) {
543 Assert.assertTrue(controllerEntry.isIsConnected());
549 Node bridgeNode = southbound.getBridgeNode(ovsdbNode, bridgeName);
550 assertNotNull("bridge " + bridgeName + " was not found", bridgeNode);
551 long datapathId = southbound.getDataPathId(bridgeNode);
553 SfcClassifier sfcClassifier = new SfcClassifier(dataBroker, southbound, mdsalUtils);
554 //sfcClassifier.programLocalInPort(datapathId, "4096", (long)1, (short)0, (short)50, true);
556 NshUtils nshUtils = new NshUtils(new Ipv4Address("192.168.50.71"), new PortNumber(6633),
557 (long)10, (short)255, (long)4096, (long)4096);
558 MatchesBuilder matchesBuilder = aclUtils.matchesBuilder(new MatchesBuilder(), 80);
559 sfcClassifier.programSfcClassiferFlows(datapathId, (short)0, "test", matchesBuilder.build(),
560 nshUtils, (long)2, true);
562 nshUtils = new NshUtils(null, null, (long)10, (short)253, 0, 0);
563 //sfcClassifier.programEgressSfcClassiferFlows(datapathId, (short)0, "test", null,
564 // nshUtils, (long)2, (long)3, true);
568 //} catch (IOException e) {
569 // e.printStackTrace();
572 //NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
573 //FlowBuilder flowBuilder = getLocalInPortFlow(datapathId, "4096", (long) 1, (short) 0);
574 //Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
575 //assertNotNull("Could not find flow in config", flow);
576 //flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
577 //assertNotNull("Could not find flow in operational", flow);
579 MatchBuilder matchBuilder = sfcClassifier.buildMatch(matchesBuilder.build());
580 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
581 FlowBuilder flowBuilder = getSfcClassifierFlow(datapathId, (short) 0, "test", null,
582 nshUtils, (long) 2, matchBuilder);
583 Flow flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
584 assertNotNull("Could not find flow in config", flow);
585 flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
586 assertNotNull("Could not find flow in operational", flow);
588 //nodeBuilder = FlowUtils.createNodeBuilder(datapathId);
589 //flowBuilder = getEgressSfcClassifierFlow(datapathId, (short) 0, "test", nshUtils, (long) 2);
590 //flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.CONFIGURATION);
591 //assertNotNull("Could not find flow in config", flow);
592 //flow = getFlow(flowBuilder, nodeBuilder, LogicalDatastoreType.OPERATIONAL);
593 //assertNotNull("Could not find flow in operational", flow);
595 LOG.info("***** Go look for flows *****");
597 assertTrue(southboundUtils.deleteBridge(connectionInfo, bridgeName));
599 assertTrue(southboundUtils.deleteBridge(connectionInfo, INTEGRATION_BRIDGE_NAME));
601 assertTrue(southboundUtils.disconnectOvsdbNode(connectionInfo));
604 private FlowBuilder getLocalInPortFlow(long dpidLong, String segmentationId, long inPort, short writeTable) {
605 MatchBuilder matchBuilder = new MatchBuilder();
607 FlowBuilder flowBuilder = new FlowBuilder();
609 flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dpidLong, inPort).build());
610 String flowId = "sfcIngress_" + segmentationId + "_" + inPort;
611 flowBuilder.setId(new FlowId(flowId));
612 FlowKey key = new FlowKey(new FlowId(flowId));
613 flowBuilder.setStrict(true);
614 flowBuilder.setBarrier(false);
615 flowBuilder.setTableId(writeTable);
616 flowBuilder.setKey(key);
617 flowBuilder.setFlowName(flowId);
618 flowBuilder.setHardTimeout(0);
619 flowBuilder.setIdleTimeout(0);
623 public FlowBuilder getSfcClassifierFlow(long dpidLong, short writeTable, String ruleName, Matches match,
624 NshUtils nshHeader, long tunnelOfPort, MatchBuilder matchBuilder) {
625 FlowBuilder flowBuilder = new FlowBuilder();
627 flowBuilder.setMatch(matchBuilder.build());
629 String flowId = "sfcClass_" + ruleName + "_" + nshHeader.getNshNsp();
630 flowBuilder.setId(new FlowId(flowId));
631 FlowKey key = new FlowKey(new FlowId(flowId));
632 flowBuilder.setBarrier(true);
633 flowBuilder.setTableId(writeTable);
634 flowBuilder.setKey(key);
635 flowBuilder.setFlowName(flowId);
636 flowBuilder.setHardTimeout(0);
637 flowBuilder.setIdleTimeout(0);
641 private FlowBuilder getEgressSfcClassifierFlow(long dpidLong, short writeTable, String ruleName,
642 NshUtils nshHeader, long tunnelOfPort) {
643 FlowBuilder flowBuilder = new FlowBuilder();
645 MatchBuilder matchBuilder = new MatchBuilder();
646 flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dpidLong, tunnelOfPort).build());
647 flowBuilder.setMatch(
648 MatchUtils.createTunnelIDMatch(matchBuilder, BigInteger.valueOf(nshHeader.getNshNsp())).build());
649 flowBuilder.setMatch(MatchUtils.addNxNspMatch(matchBuilder, nshHeader.getNshNsp()).build());
650 flowBuilder.setMatch(MatchUtils.addNxNsiMatch(matchBuilder, nshHeader.getNshNsi()).build());
652 String flowId = "egressSfcClass_" + ruleName + "_" + nshHeader.getNshNsp() + "_" + nshHeader.getNshNsi();
653 flowBuilder.setId(new FlowId(flowId));
654 FlowKey key = new FlowKey(new FlowId(flowId));
655 flowBuilder.setStrict(true);
656 flowBuilder.setBarrier(false);
657 flowBuilder.setTableId(writeTable);
658 flowBuilder.setKey(key);
659 flowBuilder.setFlowName(flowId);
660 flowBuilder.setHardTimeout(0);
661 flowBuilder.setIdleTimeout(0);
665 private Flow getFlow (FlowBuilder flowBuilder, NodeBuilder nodeBuilder, LogicalDatastoreType store)
666 throws InterruptedException {
668 for (int i = 0; i < 10; i++) {
669 flow = FlowUtils.getFlow(flowBuilder, nodeBuilder, dataBroker.newReadOnlyTransaction(), store);
671 LOG.info("getFlow: flow({}): {}", store, flow);