Add setting controller for sfc it
[netvirt.git] / openstack / net-virt-sfc / it / src / test / java / org / opendaylight / ovsdb / openstack / netvirt / sfc / NetvirtSfcIT.java
1 /*
2  * Copyright © 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
9 package org.opendaylight.ovsdb.openstack.netvirt.sfc;
10
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertNull;
13 import static org.junit.Assert.assertTrue;
14 import static org.junit.Assert.fail;
15 import static org.ops4j.pax.exam.CoreOptions.composite;
16 import static org.ops4j.pax.exam.CoreOptions.maven;
17 import static org.ops4j.pax.exam.CoreOptions.propagateSystemProperties;
18 import static org.ops4j.pax.exam.CoreOptions.vmOption;
19 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
20 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
21
22 import java.util.List;
23 import java.util.Properties;
24 import java.util.concurrent.atomic.AtomicBoolean;
25 import org.junit.Assert;
26 import org.junit.Before;
27 import org.junit.Test;
28 import org.junit.runner.RunWith;
29 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
30 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
31 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
32 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
33 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.AclUtils;
34 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.ClassifierUtils;
35 import org.opendaylight.ovsdb.openstack.netvirt.sfc.utils.SfcUtils;
36 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
37 import org.opendaylight.ovsdb.southbound.SouthboundUtil;
38 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
39 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.AccessLists;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.AccessListsBuilder;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.AccessListBuilder;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.AccessListEntriesBuilder;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.AccessListEntryBuilder;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.ActionsBuilder;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev141010.access.lists.access.list.access.list.entries.access.list.entry.MatchesBuilder;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.Classifiers;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.ClassifiersBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.ClassifierBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.SffsBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.classifier.rev150105.classifiers.classifier.sffs.SffBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105.Sfc;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.netvirt.sfc.rev150105.SfcBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
58 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
59 import org.opendaylight.yangtools.concepts.Builder;
60 import org.opendaylight.yangtools.yang.binding.DataObject;
61 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
62
63 import org.ops4j.pax.exam.Configuration;
64 import org.ops4j.pax.exam.Option;
65 import org.ops4j.pax.exam.junit.PaxExam;
66 import org.ops4j.pax.exam.karaf.options.LogLevelOption.LogLevel;
67 import org.ops4j.pax.exam.options.MavenUrlReference;
68 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
69 import org.ops4j.pax.exam.spi.reactors.PerClass;
70 import org.slf4j.Logger;
71 import org.slf4j.LoggerFactory;
72
73 @RunWith(PaxExam.class)
74 @ExamReactorStrategy(PerClass.class)
75 public class NetvirtSfcIT extends AbstractMdsalTestBase {
76     private static final Logger LOG = LoggerFactory.getLogger(NetvirtSfcIT.class);
77     private static AclUtils aclUtils = new AclUtils();
78     private static ClassifierUtils classifierUtils = new ClassifierUtils();
79     private static SfcUtils sfcUtils = new SfcUtils();
80     private static MdsalUtils mdsalUtils;
81     private static AtomicBoolean setup = new AtomicBoolean(false);
82     private static SouthboundUtils southboundUtils;
83     private static String addressStr;
84     private static String portStr;
85     private static String connectionType;
86     public static final String SERVER_IPADDRESS = "ovsdbserver.ipaddress";
87     public static final String SERVER_PORT = "ovsdbserver.port";
88     public static final String CONNECTION_TYPE = "ovsdbserver.connection";
89     public static final String CONNECTION_TYPE_ACTIVE = "active";
90     public static final String CONNECTION_TYPE_PASSIVE = "passive";
91     public static final String DEFAULT_SERVER_PORT = "6640";
92     public static final String BRIDGE_NAME = "brtest";
93
94     @Override
95     public String getModuleName() {
96         return "netvirt-sfc";
97     }
98
99     @Override
100     public String getInstanceName() {
101         return "netvirt-sfc-default";
102     }
103
104     @Override
105     public MavenUrlReference getFeatureRepo() {
106         return maven()
107                 .groupId("org.opendaylight.ovsdb")
108                 .artifactId("openstack.net-virt-sfc-features")
109                 .classifier("features")
110                 .type("xml")
111                 .versionAsInProject();
112     }
113
114     @Override
115     public String getFeatureName() {
116         return "odl-ovsdb-sfc-ui";
117     }
118
119     @Configuration
120     @Override
121     public Option[] config() {
122         Option[] parentOptions = super.config();
123         Option[] propertiesOptions = getPropertiesOptions();
124         Option[] otherOptions = getOtherOptions();
125         Option[] options = new Option[parentOptions.length + propertiesOptions.length + otherOptions.length];
126         System.arraycopy(parentOptions, 0, options, 0, parentOptions.length);
127         System.arraycopy(propertiesOptions, 0, options, parentOptions.length, propertiesOptions.length);
128         System.arraycopy(otherOptions, 0, options, parentOptions.length + propertiesOptions.length,
129                 otherOptions.length);
130         return options;
131     }
132
133     private Option[] getOtherOptions() {
134         return new Option[] {
135                 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
136                 keepRuntimeFolder()
137         };
138     }
139
140     public Option[] getPropertiesOptions() {
141         return new Option[] {
142                 propagateSystemProperties(SERVER_IPADDRESS, SERVER_PORT, CONNECTION_TYPE),
143         };
144     }
145
146     @Override
147     public Option getLoggingOption() {
148         Option option = editConfigurationFilePut(ORG_OPS4J_PAX_LOGGING_CFG,
149                 logConfiguration(NetvirtSfcIT.class),
150                 LogLevel.INFO.name());
151         option = composite(option, super.getLoggingOption());
152         return option;
153     }
154
155     protected String usage() {
156         return "Integration Test needs a valid connection configuration as follows :\n"
157                 + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
158                 + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
159     }
160
161     private void getProperties() {
162         Properties props = System.getProperties();
163         addressStr = props.getProperty(SERVER_IPADDRESS);
164         portStr = props.getProperty(SERVER_PORT, DEFAULT_SERVER_PORT);
165         connectionType = props.getProperty(CONNECTION_TYPE, "active");
166         LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
167                 connectionType, addressStr, portStr);
168         if (connectionType.equalsIgnoreCase(CONNECTION_TYPE_ACTIVE)) {
169             if (addressStr == null) {
170                 fail(usage());
171             }
172         }
173     }
174
175     @Before
176     @Override
177     public void setup() {
178         if (setup.get()) {
179             LOG.info("Skipping setUp, already initialized");
180             return;
181         }
182
183         try {
184             super.setup();
185         } catch (Exception e) {
186             e.printStackTrace();
187         }
188
189         DataBroker dataBroker = getDatabroker(getProviderContext());
190         mdsalUtils = new MdsalUtils(dataBroker);
191         assertNotNull("mdsalUtils should not be null", mdsalUtils);
192         southboundUtils = new SouthboundUtils(mdsalUtils);
193         getProperties();
194         setup.set(true);
195     }
196
197     private ProviderContext getProviderContext() {
198         ProviderContext providerContext = null;
199         for (int i=0; i < 20; i++) {
200             providerContext = getSession();
201             if (providerContext != null) {
202                 break;
203             } else {
204                 try {
205                     Thread.sleep(1000);
206                 } catch (InterruptedException e) {
207                     e.printStackTrace();
208                 }
209             }
210         }
211         assertNotNull("providercontext should not be null", providerContext);
212         /* One more second to let the provider finish initialization */
213         try {
214             Thread.sleep(1000);
215         } catch (InterruptedException e) {
216             e.printStackTrace();
217         }
218         return providerContext;
219     }
220
221     private DataBroker getDatabroker(ProviderContext providerContext) {
222         DataBroker dataBroker = providerContext.getSALService(DataBroker.class);
223         assertNotNull("dataBroker should not be null", dataBroker);
224         return dataBroker;
225     }
226
227     @Test
228     public void testNetvirtSfcFeatureLoad() {
229         assertTrue(true);
230     }
231
232     private AccessListsBuilder setAccessLists () {
233         MatchesBuilder matchesBuilder = aclUtils.createMatches(new MatchesBuilder(), 80);
234         ActionsBuilder actionsBuilder = aclUtils.createActions(new ActionsBuilder(), Boolean.TRUE);
235         AccessListEntryBuilder accessListEntryBuilder = aclUtils.createAccessListEntryBuilder(
236                 new AccessListEntryBuilder(), "http", matchesBuilder, actionsBuilder);
237         AccessListEntriesBuilder accessListEntriesBuilder = aclUtils.createAccessListEntries(
238                 new AccessListEntriesBuilder(), accessListEntryBuilder);
239         AccessListBuilder accessListBuilder = aclUtils.createAccessList(new AccessListBuilder(),
240                 "http", accessListEntriesBuilder);
241         AccessListsBuilder accessListsBuilder = aclUtils.createAccessLists(new AccessListsBuilder(),
242                 accessListBuilder);
243         LOG.info("AccessLists: {}", accessListsBuilder.build());
244         return accessListsBuilder;
245     }
246
247     @Test
248     public void testAccessLists() {
249         testModel(setAccessLists(), AccessLists.class);
250     }
251
252     private ClassifiersBuilder setClassifiers() {
253         SffBuilder sffBuilder = classifierUtils.createSff(new SffBuilder(), "sffname");
254         SffsBuilder sffsBuilder = classifierUtils.createSffs(new SffsBuilder(), sffBuilder);
255         ClassifierBuilder classifierBuilder = classifierUtils.createClassifier(new ClassifierBuilder(),
256                 "classifierName", "aclName", sffsBuilder);
257         ClassifiersBuilder classifiersBuilder = classifierUtils.createClassifiers(new ClassifiersBuilder(),
258                 classifierBuilder);
259         LOG.info("Classifiers: {}", classifiersBuilder.build());
260         return classifiersBuilder;
261     }
262
263     @Test
264     public void testClassifiers() {
265         testModel(setClassifiers(), Classifiers.class);
266     }
267
268     private SfcBuilder setSfc() {
269         SfcBuilder sfcBuilder = sfcUtils.createSfc(new SfcBuilder(), "sfc");
270         return sfcBuilder;
271     }
272
273     @Test
274     public void testSfc() {
275         testModel(setSfc(), Sfc.class);
276     }
277
278     private <T extends DataObject> void testModel(Builder<T> builder, Class<T> clazz) {
279         InstanceIdentifier<T> path = InstanceIdentifier.create(clazz);
280         assertTrue(mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, path, builder.build()));
281         T result = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
282         assertNotNull(clazz.getSimpleName() + " should not be null", result);
283         assertTrue("Failed to remove " + clazz.getSimpleName(),
284                 mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, path));
285         result = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
286         assertNull(clazz.getSimpleName() + " should be null", result);
287     }
288
289     @Test
290     public void testDoIt() throws InterruptedException {
291         ConnectionInfo connectionInfo = southboundUtils.getConnectionInfo(addressStr, portStr);
292         Node ovsdbNode = southboundUtils.connectOvsdbNode(connectionInfo);
293
294         String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
295         assertNotNull("Failed to get controller target", controllerTarget);
296         List<ControllerEntry> setControllerEntry = southboundUtils.createControllerEntry(controllerTarget);
297         Uri setUri = new Uri(controllerTarget);
298         Assert.assertTrue(southboundUtils.addBridge(connectionInfo, null, BRIDGE_NAME, null, true,
299                 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null,
300                 setControllerEntry, null));
301         OvsdbBridgeAugmentation bridge = southboundUtils.getBridge(connectionInfo, BRIDGE_NAME);
302         Assert.assertNotNull("bridge was not found: " + BRIDGE_NAME,  bridge);
303         Assert.assertNotNull("ControllerEntry was not found: " + setControllerEntry.iterator().next(),
304                 bridge.getControllerEntry());
305         List<ControllerEntry> getControllerEntries = bridge.getControllerEntry();
306         for (ControllerEntry entry : getControllerEntries) {
307             if (entry.getTarget() != null) {
308                 Assert.assertEquals(setUri.toString(), entry.getTarget().toString());
309             }
310         }
311
312         /* TODO: add code to write to mdsal to exercise the sfc dataChangeListener */
313         /* allow some time to let the impl code do it's work to push flows */
314         /* or just comment out below lines and just manually verify on the bridges and reset them */
315         Thread.sleep(10000);
316
317         Assert.assertTrue(southboundUtils.deleteBridge(connectionInfo, BRIDGE_NAME));
318         southboundUtils.disconnectOvsdbNode(connectionInfo);
319     }
320 }