package com.sixsq.slipstream.run;
/*
* +=================================================================+
* SlipStream Server (WAR)
* =====
* Copyright (C) 2013 SixSq Sarl (sixsq.com)
* =====
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* -=================================================================-
*/
import com.sixsq.slipstream.connector.local.LocalConnector;
import com.sixsq.slipstream.connector.local.LocalUserParametersFactory;
import com.sixsq.slipstream.event.Event;
import com.sixsq.slipstream.exceptions.AbortException;
import com.sixsq.slipstream.exceptions.ConfigurationException;
import com.sixsq.slipstream.exceptions.NotFoundException;
import com.sixsq.slipstream.exceptions.ValidationException;
import com.sixsq.slipstream.persistence.*;
import com.sixsq.slipstream.util.CommonTestUtil;
import com.sixsq.slipstream.util.ResourceTestBase;
import com.sixsq.slipstream.util.XmlUtil;
import org.junit.*;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.data.Form;
import org.restlet.data.Status;
import org.restlet.representation.Representation;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
public class RunListResourceTest extends ResourceTestBase {
private static final String NODE_NAME = "n1";
private static final String PARAMETER_NAME = "parameter_name";
static protected ImageModule baseImage = null;
@BeforeClass
public static void setupClass() throws ValidationException,
ConfigurationException, InstantiationException,
IllegalAccessException, InvocationTargetException,
NoSuchMethodException, ClassNotFoundException {
resetAndLoadConnector(com.sixsq.slipstream.connector.local.LocalConnector.class);
UserParameter keyParameter = new UserParameter(
new LocalUserParametersFactory()
.constructKey(LocalUserParametersFactory.KEY_PARAMETER_NAME), "value", "desc");
user.setParameter(keyParameter);
UserParameter secretParameter = new UserParameter(
new LocalUserParametersFactory()
.constructKey(LocalUserParametersFactory.SECRET_PARAMETER_NAME), "value", "desc");
user.setParameter(secretParameter);
Event.muteForTests();
CommonTestUtil.addSshKeys(user);
user.setDefaultCloudServiceName(LocalConnector.CLOUD_SERVICE_NAME);
user = user.store();
}
private static void listAllRuns(String msg) throws ConfigurationException, ValidationException {
System.out.println("::: " + msg);
System.out.println("DEBUG: Listing runs.");
int n = 0;
for (Run r : Run.listAll()) {
System.out.println(" - RUN: " + r.getName());
n++;
}
System.out.println(" total: " + n);
}
private static void removeAllRuns() throws ConfigurationException, ValidationException {
for (Run r : Run.listAll()) {
try {
r.remove();
} catch (Exception ex) {
}
}
}
@AfterClass
public static void teardownClass() throws ConfigurationException,
ValidationException {
removeAllRuns();
}
@Before
public void setup() throws ValidationException, ConfigurationException,
InstantiationException, IllegalAccessException,
InvocationTargetException, NoSuchMethodException,
ClassNotFoundException {
baseImage = new ImageModule("RuntimeParameterResourceTestBaseImage");
baseImage.setImageId("1234", cloudServiceName);
baseImage.setIsBase(true);
baseImage.setAuthz(new Authz(user.getName(),baseImage));
baseImage = baseImage.store();
user = User.loadByName(user.getName());
createModules("overrideParmeters");
}
@After
public void tearDown() throws ValidationException {
baseImage.remove();
try {
image.remove();
} catch (Exception ex) {
}
try {
deployment.remove();
} catch (Exception ex) {
}
}
@Test
public void testPagination() throws ValidationException, SAXException, ParserConfigurationException, IOException {
listAllRuns("Runs before test.");
removeAllRuns();
Response resp = getRunList(null, null, null);
assertEquals(Status.SUCCESS_OK, resp.getStatus());
Document runs = XmlUtil.stringToDom(resp.getEntityAsText());
assertEquals(0, runs.getDocumentElement().getElementsByTagName("item").getLength());
listAllRuns("Runs after explicit cleanup.");
Set<String> cloudServiceNamesA = new HashSet<String>();
cloudServiceNamesA.add("CloudA");
Set<String> cloudServiceNamesB = new HashSet<String>();
cloudServiceNamesB.add("CloudA");
cloudServiceNamesB.add("CloudB");
Set<String> cloudServiceNamesC = new HashSet<String>();
cloudServiceNamesC.add("CloudA");
cloudServiceNamesC.add("CloudB");
cloudServiceNamesC.add("CloudC");
(new Run(deployment, RunType.Orchestration, cloudServiceNamesA, user)).store();
(new Run(deployment, RunType.Orchestration, cloudServiceNamesB, user)).store();
(new Run(deployment, RunType.Orchestration, cloudServiceNamesC, user)).store();
(new Run(deployment, RunType.Orchestration, cloudServiceNamesC, user)).store();
(new Run(deployment, RunType.Orchestration, cloudServiceNamesC, user)).store();
listAllRuns("Runs after creation of 5 runs.");
resp = getRunList(null, null, null);
assertEquals(Status.SUCCESS_OK, resp.getStatus());
runs = XmlUtil.stringToDom(resp.getEntityAsText());
assertEquals(5, runs.getDocumentElement().getElementsByTagName("item").getLength());
assertEquals("5", runs.getDocumentElement().getAttribute("count"));
assertEquals("5", runs.getDocumentElement().getAttribute("totalCount"));
assertEquals("0", runs.getDocumentElement().getAttribute("offset"));
assertEquals("20", runs.getDocumentElement().getAttribute("limit"));
resp = getRunList(null, 10, "CloudB");
assertEquals(Status.SUCCESS_OK, resp.getStatus());
runs = XmlUtil.stringToDom(resp.getEntityAsText());
assertEquals(4, runs.getDocumentElement().getElementsByTagName("item").getLength());
assertEquals("4", runs.getDocumentElement().getAttribute("count"));
assertEquals("4", runs.getDocumentElement().getAttribute("totalCount"));
assertEquals("10", runs.getDocumentElement().getAttribute("limit"));
resp = getRunList(1, 4, null);
assertEquals(Status.SUCCESS_OK, resp.getStatus());
runs = XmlUtil.stringToDom(resp.getEntityAsText());
assertEquals(4, runs.getDocumentElement().getElementsByTagName("item").getLength());
assertEquals("4", runs.getDocumentElement().getAttribute("count"));
assertEquals("5", runs.getDocumentElement().getAttribute("totalCount"));
assertEquals("1", runs.getDocumentElement().getAttribute("offset"));
assertEquals("4", runs.getDocumentElement().getAttribute("limit"));
resp = getRunList(null, null, "CloudC");
assertEquals(Status.SUCCESS_OK, resp.getStatus());
runs = XmlUtil.stringToDom(resp.getEntityAsText());
assertEquals(3, runs.getDocumentElement().getElementsByTagName("item").getLength());
assertEquals("3", runs.getDocumentElement().getAttribute("count"));
assertEquals("3", runs.getDocumentElement().getAttribute("totalCount"));
resp = getRunList(-1, null, null);
assertEquals(Status.CLIENT_ERROR_BAD_REQUEST, resp.getStatus());
resp = getRunList(null, 10000 + 1, null);
assertEquals(Status.CLIENT_ERROR_BAD_REQUEST, resp.getStatus());
}
@Test
public void createImageRun() throws ConfigurationException,
NotFoundException, AbortException, ValidationException {
Form form = new Form();
form.add(RunListResource.REFQNAME, baseImage.getResourceUri());
Request request = createPostRequest(form.getWebRepresentation());
Response response = executeRequest(request);
assertEquals(Status.SUCCESS_CREATED, response.getStatus());
assertThat(response.getLocationRef().getPath(), startsWith("/run/"));
}
@Test
public void createDeploymentRun() throws ConfigurationException,
NotFoundException, AbortException, ValidationException {
Form form = new Form();
form.add(RunListResource.REFQNAME, deployment.getResourceUri());
Request request = createPostRequest(form.getWebRepresentation());
Response response = executeRequest(request);
assertEquals(Status.SUCCESS_CREATED, response.getStatus());
assertThat(response.getLocationRef().getPath(), startsWith("/run/"));
}
@Test
public void createImageRunWithRedirect() throws ConfigurationException,
NotFoundException, AbortException, ValidationException {
Form form = new Form();
form.add(RunListResource.REFQNAME, baseImage.getResourceUri());
form.add(RunListResource.REDIRECT_TO_DASHBOARD, "true");
Request request = createPostRequest(form.getWebRepresentation());
Response response = executeRequest(request);
assertEquals(Status.SUCCESS_CREATED, response.getStatus());
assertThat(response.getLocationRef().getPath(), is("/dashboard"));
}
private Request createPostRequest(String moduleUri) throws ConfigurationException,
ValidationException {
Form form = new Form();
form.add(RunListResource.REFQNAME, moduleUri);
Request request = createPostRequest(form.getWebRepresentation());
addUserToRequest(user, request);
return request;
}
private void assertMultiplicityOverride(Integer multiplicityOverride,
Response response) {
String multiplicityParameterName = NODE_NAME
+ RuntimeParameter.NODE_MULTIPLICITY_INDEX_SEPARATOR
+ multiplicityOverride.toString()
+ RuntimeParameter.NODE_PROPERTY_SEPARATOR
+ RuntimeParameter.MULTIPLICITY_PARAMETER_NAME;
String uuid = response.getLocationRef().getLastSegment();
RuntimeParameter multiplicity = RuntimeParameter.loadFromUuidAndKey(
uuid, multiplicityParameterName);
assertThat(multiplicity.getValue(),
is(String.valueOf(multiplicityOverride.toString())));
}
private void assertParameterOverride(String parameterName,
Response response, String overrideValue) {
String processedParameterName = NODE_NAME
+ RuntimeParameter.NODE_MULTIPLICITY_INDEX_SEPARATOR
+ RuntimeParameter.MULTIPLICITY_NODE_START_INDEX
+ RuntimeParameter.NODE_PROPERTY_SEPARATOR + parameterName;
String uuid = response.getLocationRef().getLastSegment();
RuntimeParameter parameter = RuntimeParameter.loadFromUuidAndKey(uuid,
processedParameterName);
assertThat(parameter.getValue(), is(overrideValue));
}
private void createModules(String moduleName) throws ValidationException {
image = new ImageModule(moduleName);
image.setModuleReference(baseImage);
image.setImageId("123", cloudServiceName);
image.setParameter(new ModuleParameter(PARAMETER_NAME, "default value",
""));
image.setImageId("abc", LocalConnector.CLOUD_SERVICE_NAME);
image.setAuthz(new Authz(user.getName(), image));
image = image.store();
Node node = new Node(NODE_NAME, image);
node.setMultiplicity(1);
node.setParameter(new NodeParameter(PARAMETER_NAME, "'default value'"));
deployment = new DeploymentModule(moduleName + "Deployment");
deployment.setNode(node);
deployment.setAuthz(new Authz(user.getName(), deployment));
deployment = (DeploymentModule) deployment.store();
}
private Request createPostRequest(List<NodeParameter> parameters,
int multiplicity, String moduleUri) throws ConfigurationException,
ValidationException {
Form form = createRunForm(parameters, multiplicity);
form.add(RunListResource.REFQNAME, moduleUri);
return createPostRequest(form.getWebRepresentation());
}
private Form createRunForm(List<NodeParameter> parameters,
Integer muliplicity) {
Form form = new Form();
for (NodeParameter np : parameters) {
String name = buildNodeName(NODE_NAME, np.getName());
String value = np.getValue();
form.add(name, value);
}
form.add(
buildNodeName(NODE_NAME,
RuntimeParameter.MULTIPLICITY_PARAMETER_NAME),
muliplicity.toString());
return form;
}
protected String buildNodeName(String nodeName, String parameterName) {
return "parameter--node--" + nodeName + "--" + parameterName;
}
private Request createPostRequest(Representation entity)
throws ConfigurationException, ValidationException {
Request request = createPostRequest(new HashMap<String, Object>(), entity);
addUserToRequest(user, request);
return request;
}
private Response getRunList(Integer offset, Integer limit, String cloudServiceName)
throws ConfigurationException, ValidationException {
Map<String, Object> attributes = new HashMap<String, Object>();
attributes.put(User.REQUEST_KEY, user);
Form queryString = new Form();
if (offset != null) queryString.set("offset", offset.toString());
if (limit != null) queryString.set("limit", limit.toString());
if (cloudServiceName != null) queryString.set("cloud", cloudServiceName);
Request req = createGetRequest("?" + queryString.getQueryString(), attributes);
return executeRequest(req);
}
private Response executeRequest(Request request) {
return executeRequest(request, new RunListResource());
}
}