2 * Copyright (C) 2014 Red Hat, Inc.
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
8 * Authors : Dave Tucker
11 package org.opendaylight.ovsdb.integrationtest.northbound;
13 import static org.junit.Assert.assertEquals;
14 import static org.junit.Assert.assertFalse;
15 import static org.junit.Assert.assertNotNull;
16 import static org.junit.Assert.assertTrue;
17 import static org.junit.Assert.fail;
18 import static org.ops4j.pax.exam.CoreOptions.junitBundles;
19 import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
20 import static org.ops4j.pax.exam.CoreOptions.options;
21 import static org.ops4j.pax.exam.CoreOptions.propagateSystemProperty;
22 import static org.ops4j.pax.exam.CoreOptions.systemProperty;
24 import java.io.FileNotFoundException;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.util.List;
30 import javax.inject.Inject;
32 import org.junit.Before;
33 import org.junit.Test;
34 import org.junit.runner.RunWith;
35 import org.junit.runners.Parameterized;
36 import org.opendaylight.controller.sal.core.Node;
37 import org.opendaylight.controller.usermanager.IUserManager;
38 import org.opendaylight.ovsdb.integrationtest.ConfigurationBundles;
39 import org.opendaylight.ovsdb.integrationtest.OvsdbIntegrationTestBase;
40 import org.ops4j.pax.exam.Configuration;
41 import org.ops4j.pax.exam.Option;
42 import org.ops4j.pax.exam.junit.PaxExamParameterized;
43 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
44 import org.ops4j.pax.exam.spi.reactors.PerClass;
45 import org.ops4j.pax.exam.util.PathUtils;
46 import org.osgi.framework.Bundle;
47 import org.osgi.framework.BundleContext;
48 import org.osgi.framework.ServiceReference;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51 import org.yaml.snakeyaml.Yaml;
53 import com.fasterxml.jackson.databind.JsonNode;
54 import com.fasterxml.jackson.databind.ObjectMapper;
55 import com.google.common.collect.Lists;
56 import com.sun.jersey.api.client.Client;
57 import com.sun.jersey.api.client.ClientResponse;
58 import com.sun.jersey.api.client.WebResource;
59 import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
61 @RunWith(PaxExamParameterized.class)
62 @ExamReactorStrategy(PerClass.class)
63 public class OvsdbNorthboundIT extends OvsdbIntegrationTestBase {
65 private Logger log = LoggerFactory.getLogger(OvsdbNorthboundIT.class);
66 public static final String USERNAME = "admin";
67 public static final String PASSWORD = "admin";
68 public static final String BASE_URI = "http://localhost:8888";
69 public static final String MEDIA_TYPE_JSON = "application/json";
70 public static final String NODE_ID_REPLACEMENT_PATTERN = "${node}";
71 public static final String UUID_REPLACEMENT_PATTERN = "${uuid}";
72 public static final String BRIDGE_UUID_REPLACEMENT_PATTERN = "${bridge_uuid}";
73 public static final String PORT_UUID_REPLACEMENT_PATTERN = "${port_uuid}";
74 public static final String QOS_UUID_REPLACEMENT_PATTERN = "${qos_uuid}";
75 public static final String OVS_UUID_REPLACEMENT_PATTERN = "${ovs_uuid}";
78 private BundleContext bc;
79 private Node node = null;
80 private IUserManager userManager;
82 @Parameterized.Parameters(name = "ApiTest{index}:{0}")
83 public static List<Object[]> getData() throws FileNotFoundException {
84 ClassLoader classloader = OvsdbNorthboundIT.class.getClassLoader();
85 InputStream input = classloader.getResourceAsStream("northbound.yaml");
86 Yaml yaml = new Yaml();
87 List<Map<String, Object>> object = (List<Map<String, Object>>) yaml.load(input);
88 List<Object[]> parameters = Lists.newArrayList();
90 for (Map<String, Object> o : object){
91 Object[] l = o.values().toArray();
99 private String fTestCase;
100 private String fOperation;
101 private String fPath;
102 private String fJson;
103 private int fExpectedStatusCode;
105 public OvsdbNorthboundIT(String testCase, String operation, String path, String json, int expectedStatusCode){
106 fTestCase = testCase;
107 fOperation = operation;
110 fExpectedStatusCode = expectedStatusCode;
114 public void testApi() {
115 System.out.println("Running " + fTestCase + "...\n");
117 Client client = Client.create();
118 client.addFilter(new HTTPBasicAuthFilter(USERNAME , PASSWORD));
119 String uri = BASE_URI + fPath;
120 WebResource webResource = client.resource(expand(uri));
121 ClientResponse response = null;
123 switch (fOperation) {
125 response = webResource.accept(MEDIA_TYPE_JSON)
126 .get(ClientResponse.class);
129 response = webResource.accept(MEDIA_TYPE_JSON)
130 .header("Content-Type", MEDIA_TYPE_JSON)
131 .post(ClientResponse.class, expand(fJson));
132 UuidHelper.setUuid(response.getEntity(String.class));
136 response = webResource.accept(MEDIA_TYPE_JSON)
137 .header("Content-Type", MEDIA_TYPE_JSON)
138 .put(ClientResponse.class, fJson);
141 response = webResource.delete(ClientResponse.class);
142 UuidHelper.setUuid("");
145 fail("Unsupported operation");
147 assertEquals(fExpectedStatusCode, response.getStatus());
150 private String expand(String content){
151 if (content.contains(NODE_ID_REPLACEMENT_PATTERN)) {
152 content = content.replace(NODE_ID_REPLACEMENT_PATTERN,
153 node.getNodeIDString());
155 if (content.contains(UUID_REPLACEMENT_PATTERN)) {
156 content = content.replace(UUID_REPLACEMENT_PATTERN,
157 UuidHelper.getUuid());
159 if (content.contains(BRIDGE_UUID_REPLACEMENT_PATTERN)) {
160 content = content.replace(BRIDGE_UUID_REPLACEMENT_PATTERN,
161 UuidHelper.getBridgeUuid());
163 if (content.contains(PORT_UUID_REPLACEMENT_PATTERN)) {
164 content = content.replace(PORT_UUID_REPLACEMENT_PATTERN,
165 UuidHelper.getPortUuid());
167 if (content.contains(QOS_UUID_REPLACEMENT_PATTERN)) {
168 content = content.replace(QOS_UUID_REPLACEMENT_PATTERN,
169 UuidHelper.getQosUuid());
171 if (content.contains(OVS_UUID_REPLACEMENT_PATTERN)) {
172 content = content.replace(OVS_UUID_REPLACEMENT_PATTERN,
178 private void saveUuid(String path){
179 if (path.contains("bridge")) {
180 UuidHelper.setBridgeUuid(UuidHelper.getUuid());
182 if (path.contains("port")) {
183 UuidHelper.setPortUuid(UuidHelper.getUuid());
185 if (path.contains("qos")) {
186 UuidHelper.setQosUuid(UuidHelper.getUuid());
190 private String getOvsUuid() {
191 if (UuidHelper.getOvsUuid() == null) {
192 Client client = Client.create();
193 client.addFilter(new HTTPBasicAuthFilter(USERNAME, PASSWORD));
194 String uri = OvsdbNorthboundIT.BASE_URI + "/ovsdb/nb/v2/node/OVS/${node}/tables/open_vswitch/rows";
195 WebResource webResource = client.resource(expand(uri));
196 ClientResponse response = webResource.accept(MEDIA_TYPE_JSON)
197 .get(ClientResponse.class);
199 assertEquals(200, response.getStatus());
201 String row = response.getEntity(String.class);
205 ObjectMapper objectMapper = new ObjectMapper();
206 JsonNode rowsNode = objectMapper.readTree(row).get("rows");
207 assertNotNull(rowsNode);
208 // The first fieldName is the UUID
209 String uuid = rowsNode.fieldNames().next();
211 UuidHelper.setOvsUuid(uuid);
212 } catch (IOException e) {
213 fail("Cannot get the UUID for the Open_vSwitch table");
217 return UuidHelper.getOvsUuid();
220 private String stateToString(int state) {
224 case Bundle.INSTALLED:
226 case Bundle.RESOLVED:
228 case Bundle.UNINSTALLED:
229 return "UNINSTALLED";
231 return "Not CONVERTED";
236 public void areWeReady() throws InterruptedException {
238 boolean debugit = false;
239 Bundle b[] = bc.getBundles();
240 for (Bundle element : b) {
241 int state = element.getState();
242 if (state != Bundle.ACTIVE && state != Bundle.RESOLVED) {
243 log.info("Bundle:" + element.getSymbolicName() + " state:"
244 + stateToString(state));
249 log.debug("Do some debugging because some bundle is unresolved");
252 // Fail if true, if false we are good to go!
253 assertFalse(debugit);
255 ServiceReference r = bc.getServiceReference(IUserManager.class.getName());
257 this.userManager = (IUserManager) bc.getService(r);
259 // If UserManager is null, cannot login to run tests.
260 assertTrue(this.userManager != null);
263 node = getPluginTestConnection();
264 } catch (Exception e) {
265 fail("Exception : "+e.getMessage());
268 // Wait before making a REST call to avoid overloading Tomcat
274 public static Option[] configuration() {
277 systemProperty("logback.configurationFile").value(
278 PathUtils.getBaseDir() + "/src/test/resources/logback.xml"
281 systemProperty("org.eclipse.gemini.web.tomcat.config.path").value(
282 PathUtils.getBaseDir() + "/src/test/resources/tomcat-server.xml"),
284 // To start OSGi console for inspection remotely
285 systemProperty("osgi.console").value("2401"),
287 propagateSystemProperty("ovsdbserver.ipaddress"),
288 propagateSystemProperty("ovsdbserver.port"),
290 ConfigurationBundles.controllerBundles(),
291 ConfigurationBundles.controllerNorthboundBundles(),
292 ConfigurationBundles.ovsdbLibraryBundles(),
293 ConfigurationBundles.ovsdbDefaultSchemaBundles(),
294 mavenBundle("org.opendaylight.ovsdb", "ovsdb_plugin").versionAsInProject(),
295 mavenBundle("org.opendaylight.ovsdb", "ovsdb_northbound").versionAsInProject(),