aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Marius Venstad <jvenstad@yahoo-inc.com>2017-11-20 11:50:30 +0100
committerJon Marius Venstad <jvenstad@yahoo-inc.com>2017-11-20 11:50:30 +0100
commit7bac10e56fe6cedcda52885ec29490fa239188f9 (patch)
tree5da1584f10242e4ee1b4f45b4fb4d9ee84baf0a3
parentfcb20ca2177d09f23cb518a04e85eb7af3f55d49 (diff)
Allow limited recursive, test it and use Builder for test requests
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java20
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerTester.java17
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java520
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/recursive-until-tenant-root.json47
4 files changed, 315 insertions, 289 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
index 56d7406b080..b986c91826c 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.hosted.controller.restapi.application;
import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableSet;
import com.google.inject.Inject;
import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
@@ -231,7 +232,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
}
private HttpResponse root(HttpRequest request) {
- return request.getBooleanProperty("recursive")
+ return recurseOverTenants(request)
? recursiveRoot(request)
: new ResourceResponse(request, "user", "tenant", "tenant-pipeline", "athensDomain", "property", "cookiefreshness");
}
@@ -397,7 +398,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
if ( ! rotations.isEmpty())
setRotationStatus(deployment, rotationHealthStatus, deploymentObject);
- if (request.getBooleanProperty("recursive")) // List full deployment information when recursive.
+ if (recurseOverDeployments(request)) // List full deployment information when recursive.
toSlime(deploymentObject, new DeploymentId(application.id(), deployment.zone()), deployment, request);
else
deploymentObject.setString("url", withPath(request.getUri().getPath() +
@@ -891,7 +892,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
if (listApplications) { // This cludge is needed because we call this after deleting the tenant. As this call makes another tenant lookup it will fail. TODO is to support lookup on tenant
for (Application application : controller.applications().asList(TenantName.from(tenant.getId().id()))) {
if (application.id().instance().isDefault()) {// TODO: Skip non-default applications until supported properly
- if (request.getBooleanProperty("recursive"))
+ if (recurseOverApplications(request))
toSlime(applicationArray.addObject(), application, request);
else
toSlime(application, applicationArray.addObject(), request);
@@ -1161,4 +1162,17 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
return name;
}
+
+ private static boolean recurseOverTenants(HttpRequest request) {
+ return recurseOverApplications(request) || "tenant".equals(request.getProperty("recursive"));
+ }
+
+ private static boolean recurseOverApplications(HttpRequest request) {
+ return recurseOverDeployments(request) || "application".equals(request.getProperty("recursive"));
+ }
+
+ private static boolean recurseOverDeployments(HttpRequest request) {
+ return ImmutableSet.of("all", "true", "deployment").contains(request.getProperty("recursive"));
+ }
+
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerTester.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerTester.java
index b55ee9a195f..c0e8b48f821 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerTester.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/ContainerTester.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.function.Supplier;
import static org.junit.Assert.assertEquals;
@@ -52,10 +53,18 @@ public class ContainerTester {
controller.updateVersionStatus(VersionStatus.compute(controller, version));
}
+ public void assertResponse(Supplier<Request> request, File responseFile) throws IOException {
+ assertResponse(request.get(), responseFile);
+ }
+
public void assertResponse(Request request, File responseFile) throws IOException {
assertResponse(request, responseFile, 200);
}
+ public void assertResponse(Supplier<Request> request, File responseFile, int expectedStatusCode) throws IOException {
+ assertResponse(request.get(), responseFile, expectedStatusCode);
+ }
+
public void assertResponse(Request request, File responseFile, int expectedStatusCode) throws IOException {
String expectedResponse = IOUtils.readFile(new File(responseFilePath + responseFile.toString()));
expectedResponse = include(expectedResponse);
@@ -72,10 +81,18 @@ public class ContainerTester {
replace(new String(SlimeUtils.toJsonBytes(responseSlime), StandardCharsets.UTF_8), replaceStrings));
}
+ public void assertResponse(Supplier<Request> request, String expectedResponse) throws IOException {
+ assertResponse(request.get(), expectedResponse, 200);
+ }
+
public void assertResponse(Request request, String expectedResponse) throws IOException {
assertResponse(request, expectedResponse, 200);
}
+ public void assertResponse(Supplier<Request> request, String expectedResponse, int expectedStatusCode) throws IOException {
+ assertResponse(request.get(), expectedResponse, expectedStatusCode);
+ }
+
public void assertResponse(Request request, String expectedResponse, int expectedStatusCode) throws IOException {
Response response = container.handleRequest(request);
assertEquals(expectedResponse, response.getBodyAsString());
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
index c3c0a67ff00..23a50f0c645 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java
@@ -47,6 +47,12 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.function.Supplier;
+
+import static com.yahoo.application.container.handler.Request.Method.DELETE;
+import static com.yahoo.application.container.handler.Request.Method.GET;
+import static com.yahoo.application.container.handler.Request.Method.POST;
+import static com.yahoo.application.container.handler.Request.Method.PUT;
/**
* @author bratseth
@@ -72,32 +78,30 @@ public class ApplicationApiTest extends ControllerContainerTest {
addTenantAthenzDomain(athenzUserDomain, "mytenant"); // (Necessary but not provided in this API)
// GET API root
- tester.assertResponse(request("/application/v4/", "", Request.Method.GET),
+ tester.assertResponse(request("/application/v4/", GET),
new File("root.json"));
// GET athens domains
- tester.assertResponse(request("/application/v4/athensDomain/", "", Request.Method.GET),
+ tester.assertResponse(request("/application/v4/athensDomain/", GET),
new File("athensDomain-list.json"));
// GET OpsDB properties
- tester.assertResponse(request("/application/v4/property/", "", Request.Method.GET),
+ tester.assertResponse(request("/application/v4/property/", GET),
new File("property-list.json"));
// GET cookie freshness
- tester.assertResponse(request("/application/v4/cookiefreshness/", "", Request.Method.GET),
+ tester.assertResponse(request("/application/v4/cookiefreshness/", GET),
new File("cookiefreshness.json"));
// POST (add) a tenant without property ID
- tester.assertResponse(request("/application/v4/tenant/tenant1",
- "{\"athensDomain\":\"domain1\", \"property\":\"property1\"}",
- Request.Method.POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
new File("tenant-without-applications.json"));
// PUT (modify) a tenant
- tester.assertResponse(request("/application/v4/tenant/tenant1",
- "{\"athensDomain\":\"domain1\", \"property\":\"property1\"}",
- Request.Method.PUT),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", PUT)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
new File("tenant-without-applications.json"));
// GET the authenticated user (with associated tenants)
- tester.assertResponse(request("/application/v4/user", "", Request.Method.GET),
+ tester.assertResponse(request("/application/v4/user", GET),
new File("user.json"));
// GET all tenants
- tester.assertResponse(request("/application/v4/tenant/", "", Request.Method.GET),
+ tester.assertResponse(request("/application/v4/tenant/", GET),
new File("tenant-list.json"));
@@ -106,61 +110,55 @@ public class ApplicationApiTest extends ControllerContainerTest {
// Add property info for that property id, as well, in the mock organization.
addPropertyData((MockOrganization) controllerTester.controller().organization(), "1234");
// POST (add) a tenant with property ID
- tester.assertResponse(request("/application/v4/tenant/tenant2",
- "{\"athensDomain\":\"domain2\", \"property\":\"property2\", \"propertyId\":\"1234\"}",
- Request.Method.POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant2", POST)
+ .data("{\"athensDomain\":\"domain2\", \"property\":\"property2\", \"propertyId\":\"1234\"}"),
new File("tenant-without-applications-with-id.json"));
// PUT (modify) a tenant with property ID
- tester.assertResponse(request("/application/v4/tenant/tenant2",
- "{\"athensDomain\":\"domain2\", \"property\":\"property2\", \"propertyId\":\"1234\"}",
- Request.Method.PUT),
+ tester.assertResponse(request("/application/v4/tenant/tenant2", PUT)
+ .data("{\"athensDomain\":\"domain2\", \"property\":\"property2\", \"propertyId\":\"1234\"}"),
new File("tenant-without-applications-with-id.json"));
// GET a tenant with property ID
- tester.assertResponse(request("/application/v4/tenant/tenant2", "", Request.Method.GET),
+ tester.assertResponse(request("/application/v4/tenant/tenant2", GET),
new File("tenant-without-applications-with-id.json"));
// Test legacy OpsDB tenants
// POST (add) an OpsDB tenant with property ID
- tester.assertResponse(request("/application/v4/tenant/tenant3",
- "{\"userGroup\":\"group1\",\"property\":\"property1\",\"propertyId\":\"1234\"}",
- Request.Method.POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant3", POST)
+ .data("{\"userGroup\":\"group1\",\"property\":\"property1\",\"propertyId\":\"1234\"}"),
new File("opsdb-tenant-with-id-without-applications.json"));
// PUT (modify) the OpsDB tenant to set another property
- tester.assertResponse(request("/application/v4/tenant/tenant3",
- "{\"userGroup\":\"group1\",\"property\":\"property2\",\"propertyId\":\"4321\"}",
- Request.Method.PUT),
+ tester.assertResponse(request("/application/v4/tenant/tenant3", PUT)
+ .data("{\"userGroup\":\"group1\",\"property\":\"property2\",\"propertyId\":\"4321\"}"),
new File("opsdb-tenant-with-new-id-without-applications.json"));
// POST (create) an application
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1",
- "",
- Request.Method.POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST),
new File("application-reference.json"));
// GET a tenant
- tester.assertResponse(request("/application/v4/tenant/tenant1", "", Request.Method.GET),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", GET),
new File("tenant-with-application.json"));
// GET tenant applications
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/", "", Request.Method.GET),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/", GET),
new File("application-list.json"));
// POST triggering of a full deployment to an application (if version is omitted, current system version is used)
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/deploying", "6.1.0", Request.Method.POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/deploying", POST)
+ .data("6.1.0"),
new File("application-deployment.json"));
// DELETE (cancel) ongoing change
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/deploying", "", Request.Method.DELETE),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/deploying", DELETE),
new File("application-deployment-cancelled.json"));
// DELETE (cancel) again is a no-op
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/deploying", "", Request.Method.DELETE),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/deploying", DELETE),
new File("application-deployment-cancelled-no-op.json"));
// POST (deploy) an application to a zone - manual user deployment
HttpEntity entity = createApplicationDeployData(applicationPackage, Optional.empty());
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/dev/region/us-west-1/instance/default/deploy",
- entity,
- Request.Method.POST,
- athenzUserDomain, "mytenant"),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/dev/region/us-west-1/instance/default/deploy", POST)
+ .data(entity)
+ .domain(athenzUserDomain).user("mytenant"),
new File("deploy-result.json"));
// POST (deploy) an application to a zone. This simulates calls done by our tenant pipeline.
@@ -170,150 +168,136 @@ public class ApplicationApiTest extends ControllerContainerTest {
addScrewdriverUserToDomain("screwdriveruser1", "domain1"); // (Necessary but not provided in this API)
// Trigger deployment
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/deploying", "6.1.0", Request.Method.POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/deploying", POST)
+ .data("6.1.0"),
new File("application-deployment.json"));
// ... systemtest
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/test/region/us-east-1/instance/default/",
- createApplicationDeployData(applicationPackage, Optional.of(screwdriverProjectId)),
- Request.Method.POST,
- athenzScrewdriverDomain, "screwdriveruser1"),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/test/region/us-east-1/instance/default/", POST)
+ .data(createApplicationDeployData(applicationPackage, Optional.of(screwdriverProjectId)))
+ .domain(athenzScrewdriverDomain).user("screwdriveruser1"),
new File("deploy-result.json"));
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/test/region/us-east-1/instance/default",
- "",
- Request.Method.DELETE),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/test/region/us-east-1/instance/default", DELETE),
"Deactivated tenant/tenant1/application/application1/environment/test/region/us-east-1/instance/default");
controllerTester.notifyJobCompletion(id, screwdriverProjectId, true, DeploymentJobs.JobType.systemTest); // Called through the separate screwdriver/v1 API
// ... staging
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/staging/region/us-east-3/instance/default/",
- createApplicationDeployData(applicationPackage, Optional.of(screwdriverProjectId)),
- Request.Method.POST,
- athenzScrewdriverDomain, "screwdriveruser1"),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/staging/region/us-east-3/instance/default/", POST)
+ .data(createApplicationDeployData(applicationPackage, Optional.of(screwdriverProjectId)))
+ .domain(athenzScrewdriverDomain).user("screwdriveruser1"),
new File("deploy-result.json"));
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/staging/region/us-east-3/instance/default",
- "",
- Request.Method.DELETE),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/staging/region/us-east-3/instance/default", DELETE),
"Deactivated tenant/tenant1/application/application1/environment/staging/region/us-east-3/instance/default");
controllerTester.notifyJobCompletion(id, screwdriverProjectId, true, DeploymentJobs.JobType.stagingTest);
// ... prod zone
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default/",
- createApplicationDeployData(applicationPackage, Optional.of(screwdriverProjectId)),
- Request.Method.POST,
- athenzScrewdriverDomain, "screwdriveruser1"),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default/", POST)
+ .data(createApplicationDeployData(applicationPackage, Optional.of(screwdriverProjectId)))
+ .domain(athenzScrewdriverDomain).user("screwdriveruser1"),
new File("deploy-result.json"));
controllerTester.notifyJobCompletion(id, screwdriverProjectId, false, DeploymentJobs.JobType.productionCorpUsEast1);
// GET tenant screwdriver projects
- tester.assertResponse(request("/application/v4/tenant-pipeline/", "", Request.Method.GET),
+ tester.assertResponse(request("/application/v4/tenant-pipeline/", GET),
new File("tenant-pipelines.json"));
// GET tenant application deployments
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", "", Request.Method.GET),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", GET),
new File("application.json"));
// GET an application deployment
setDeploymentMaintainedInfo(controllerTester);
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default", "", Request.Method.GET),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default", GET),
new File("deployment.json"));
- // GET at root, with "&recursive=true", returns info about all tenants, their applications and their deployments
- tester.assertResponse(request("/application/v4/",
- "",
- Request.Method.GET,
- "domain1", "mytenant&recursive=true"),
+ // GET at root, with "&recursive=deployment", returns info about all tenants, their applications and their deployments
+ tester.assertResponse(request("/application/v4/", GET)
+ .domain("domain1").user("mytenant")
+ .recursive("deployment"),
new File("recursive-root.json"));
+ // GET at root, with "&recursive=tenant", returns info about all tenants, with limmited info about their applications.
+ tester.assertResponse(request("/application/v4/", GET)
+ .domain("domain1").user("mytenant")
+ .recursive("tenant"),
+ new File("recursive-until-tenant-root.json"));
// GET at a tenant, with "&recursive=true", returns full info about their applications and their deployments
- tester.assertResponse(request("/application/v4/tenant/tenant1/",
- "",
- Request.Method.GET,
- "domain1", "mytenant&recursive=true"),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/", GET)
+ .domain("domain1").user("mytenant")
+ .recursive("true"),
new File("tenant1.json"));
// GET at an application, with "&recursive=true", returns full info about its deployments
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/",
- "",
- Request.Method.GET,
- "domain1", "mytenant&recursive=true"),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/", GET)
+ .domain("domain1").user("mytenant")
+ .recursive("true"),
new File("application1.json"));
// POST a 'restart application' command
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default/restart",
- "",
- Request.Method.POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default/restart", POST),
"Requested restart of tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default");
// POST a 'restart application' command with a host filter (other filters not supported yet)
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default/restart?hostname=host1",
- "",
- Request.Method.POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default/restart?hostname=host1", POST),
"Requested restart of tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default");
// POST a 'log' command
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default/log",
- "",
- Request.Method.POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default/log", POST),
new File("log-response.json")); // Proxied to config server, not sure about the expected return format
// GET (wait for) convergence
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default/converge", "", Request.Method.GET),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default/converge", GET),
new File("convergence.json"));
// GET services
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default/service", "", Request.Method.GET),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default/service", GET),
new File("services.json"));
// GET service
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default/service/storagenode-awe3slno6mmq2fye191y324jl/state/v1/", "", Request.Method.GET),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default/service/storagenode-awe3slno6mmq2fye191y324jl/state/v1/", GET),
new File("service.json"));
// DELETE (deactivate) a deployment - dev
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/dev/region/us-west-1/instance/default",
- "",
- Request.Method.DELETE),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/dev/region/us-west-1/instance/default", DELETE),
"Deactivated tenant/tenant1/application/application1/environment/dev/region/us-west-1/instance/default");
// DELETE (deactivate) a deployment - prod
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default",
- "",
- Request.Method.DELETE),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default", DELETE),
"Deactivated tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default");
// DELETE (deactivate) a deployment is idempotent
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default",
- "",
- Request.Method.DELETE),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default", DELETE),
"Deactivated tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default");
// DELETE an application
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", "", Request.Method.DELETE),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", DELETE),
"");
// DELETE a tenant
- tester.assertResponse(request("/application/v4/tenant/tenant1", "", Request.Method.DELETE),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE),
new File("tenant-without-applications.json"));
// PUT (create) the authenticated user
- tester.assertResponse(request("/application/v4/user?user=newuser&domain=by",
- new byte[0],
- Request.Method.PUT,
- athenzUserDomain, "newuser", "application/json"),
+ byte[] data = new byte[0];
+ tester.assertResponse(request("/application/v4/user?user=newuser&domain=by", PUT)
+ .data(data)
+ .domain(athenzUserDomain).user("newuser"),
new File("create-user-response.json"));
// OPTIONS return 200 OK
- tester.assertResponse(request("/application/v4/", "", Request.Method.OPTIONS),
+ tester.assertResponse(request("/application/v4/", Request.Method.OPTIONS),
"");
// GET global rotation status
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/global-rotation", "", Request.Method.GET),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/global-rotation", GET),
new File("global-rotation.json"));
// GET global rotation override status
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/global-rotation/override", "", Request.Method.GET),
- new File("global-rotation-get.json"));
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/global-rotation/override", GET),
+ new File("global-rotation-get.json"));
// SET global rotation override status
- tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2/environment/prod/region/us-west-1/instance/default/global-rotation/override", "{\"reason\":\"because i can\"}", Request.Method.PUT),
- new File("global-rotation-put.json"));
+ tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2/environment/prod/region/us-west-1/instance/default/global-rotation/override", PUT)
+ .data("{\"reason\":\"because i can\"}"),
+ new File("global-rotation-put.json"));
// DELETE global rotation override status
- tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2/environment/prod/region/us-west-1/instance/default/global-rotation/override", "{\"reason\":\"because i can\"}", Request.Method.DELETE),
- new File("global-rotation-delete.json"));
+ tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2/environment/prod/region/us-west-1/instance/default/global-rotation/override", DELETE)
+ .data("{\"reason\":\"because i can\"}"),
+ new File("global-rotation-delete.json"));
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/promote", "", Request.Method.POST),
- "{\"message\":\"Successfully copied environment hosted-verified-prod to hosted-instance_tenant1_application1_placeholder_component_default\"}");
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/promote", "", Request.Method.POST),
- "{\"message\":\"Successfully copied environment hosted-instance_tenant1_application1_placeholder_component_default to hosted-instance_tenant1_application1_us-west-1_prod_default\"}");
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/promote", POST),
+ "{\"message\":\"Successfully copied environment hosted-verified-prod to hosted-instance_tenant1_application1_placeholder_component_default\"}");
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/promote", POST),
+ "{\"message\":\"Successfully copied environment hosted-instance_tenant1_application1_placeholder_component_default to hosted-instance_tenant1_application1_us-west-1_prod_default\"}");
controllerTester.controller().deconstruct();
}
@@ -328,23 +312,19 @@ public class ApplicationApiTest extends ControllerContainerTest {
addScrewdriverUserToDomain("screwdriveruser1", "domain1");
// Create tenant
- tester.assertResponse(request("/application/v4/tenant/tenant1",
- "{\"athensDomain\":\"domain1\", \"property\":\"property1\"}",
- Request.Method.POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
new File("tenant-without-applications.json"));
// Create application
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1",
- "",
- Request.Method.POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST),
new File("application-reference.json"));
// POST (deploy) an application to a prod zone - allowed when project ID is not specified
HttpEntity entity = createApplicationDeployData(applicationPackage, Optional.empty());
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default/deploy",
- entity,
- Request.Method.POST,
- athenzScrewdriverDomain, "screwdriveruser1"),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/corp-us-east-1/instance/default/deploy", POST)
+ .data(entity)
+ .domain(athenzScrewdriverDomain).user("screwdriveruser1"),
new File("deploy-result.json"));
}
@@ -358,15 +338,12 @@ public class ApplicationApiTest extends ControllerContainerTest {
addScrewdriverUserToDomain("screwdriveruser1", "domain1");
// Create tenant
- tester.assertResponse(request("/application/v4/tenant/tenant1",
- "{\"athensDomain\":\"domain1\", \"property\":\"property1\"}",
- Request.Method.POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
new File("tenant-without-applications.json"));
// Create application
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1",
- "",
- Request.Method.POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST),
new File("application-reference.json"));
// Deploy
@@ -380,10 +357,9 @@ public class ApplicationApiTest extends ControllerContainerTest {
startAndTestChange(controllerTester, id, projectId, deployData);
// us-east-3
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-east-3/instance/default/deploy",
- deployData,
- Request.Method.POST,
- athenzScrewdriverDomain, "screwdriveruser1"),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-east-3/instance/default/deploy", POST)
+ .data(deployData)
+ .domain(athenzScrewdriverDomain).user("screwdriveruser1"),
new File("deploy-result.json"));
controllerTester.notifyJobCompletion(id, projectId, true, DeploymentJobs.JobType.productionUsEast3);
@@ -397,22 +373,19 @@ public class ApplicationApiTest extends ControllerContainerTest {
startAndTestChange(controllerTester, id, projectId, deployData);
// us-west-1
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/deploy",
- deployData,
- Request.Method.POST,
- athenzScrewdriverDomain, "screwdriveruser1"),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/deploy", POST)
+ .data(deployData)
+ .domain(athenzScrewdriverDomain).user("screwdriveruser1"),
new File("deploy-result.json"));
controllerTester.notifyJobCompletion(id, projectId, true, DeploymentJobs.JobType.productionUsWest1);
// us-east-3
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-east-3/instance/default/deploy",
- deployData,
- Request.Method.POST,
- athenzScrewdriverDomain, "screwdriveruser1"),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-east-3/instance/default/deploy", POST)
+ .data(deployData).domain(athenzScrewdriverDomain).user("screwdriveruser1"),
new File("deploy-result.json"));
controllerTester.notifyJobCompletion(id, projectId, true, DeploymentJobs.JobType.productionUsEast3);
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", "", Request.Method.GET),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", GET),
new File("application-without-change-multiple-deployments.json"));
}
@@ -423,63 +396,49 @@ public class ApplicationApiTest extends ControllerContainerTest {
addTenantAthenzDomain("domain1", "mytenant");
// PUT (update) non-existing tenant
- tester.assertResponse(request("/application/v4/tenant/tenant1",
- "{\"athensDomain\":\"domain1\", \"property\":\"property1\"}",
- Request.Method.PUT),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", PUT)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
"{\"error-code\":\"NOT_FOUND\",\"message\":\"Tenant 'tenant1' does not exist\"}",
404);
// GET non-existing tenant
- tester.assertResponse(request("/application/v4/tenant/tenant1",
- "",
- Request.Method.GET),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", GET),
"{\"error-code\":\"NOT_FOUND\",\"message\":\"Tenant 'tenant1' does not exist\"}",
404);
// GET non-existing application
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1",
- "",
- Request.Method.GET),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", GET),
"{\"error-code\":\"NOT_FOUND\",\"message\":\"tenant1.application1 not found\"}",
404);
// GET non-existing deployment
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-east/instance/default",
- "",
- Request.Method.GET),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-east/instance/default", GET),
"{\"error-code\":\"NOT_FOUND\",\"message\":\"tenant1.application1 not found\"}",
404);
// POST (add) a tenant
- tester.assertResponse(request("/application/v4/tenant/tenant1",
- "{\"athensDomain\":\"domain1\", \"property\":\"property1\"}",
- Request.Method.POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
new File("tenant-without-applications.json"));
// POST (add) another tenant under the same domain
- tester.assertResponse(request("/application/v4/tenant/tenant2",
- "{\"athensDomain\":\"domain1\", \"property\":\"property1\"}",
- Request.Method.POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant2", POST)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
"{\"error-code\":\"BAD_REQUEST\",\"message\":\"Could not create tenant 'tenant2': The Athens domain 'domain1' is already connected to tenant 'tenant1'\"}",
400);
// Add the same tenant again
- tester.assertResponse(request("/application/v4/tenant/tenant1",
- "{\"athensDomain\":\"domain1\", \"property\":\"property1\"}",
- Request.Method.POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}"),
"{\"error-code\":\"BAD_REQUEST\",\"message\":\"Tenant 'tenant1' already exists\"}",
400);
// POST (create) an (empty) application
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1",
- "",
- Request.Method.POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST),
new File("application-reference.json"));
// Create the same application again
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1",
- "",
- Request.Method.POST),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST),
"{\"error-code\":\"BAD_REQUEST\",\"message\":\"An application with id 'tenant1.application1' already exists\"}",
400);
@@ -488,64 +447,56 @@ public class ApplicationApiTest extends ControllerContainerTest {
// POST (deploy) an application with an invalid application package
HttpEntity entity = createApplicationDeployData(applicationPackage, Optional.empty());
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/dev/region/us-west-1/instance/default/deploy",
- entity,
- Request.Method.POST,
- athenzUserDomain, "mytenant"),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/dev/region/us-west-1/instance/default/deploy", POST)
+ .data(entity)
+ .domain(athenzUserDomain).user("mytenant"),
new File("deploy-failure.json"), 400);
// POST (deploy) an application without available capacity
configServer.throwOnNextPrepare(new ConfigServerException(new URI("server-url"), "Failed to prepare application", ConfigServerException.ErrorCode.OUT_OF_CAPACITY, null));
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/dev/region/us-west-1/instance/default/deploy",
- entity,
- Request.Method.POST,
- athenzUserDomain, "mytenant"),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/dev/region/us-west-1/instance/default/deploy", POST)
+ .data(entity)
+ .domain(athenzUserDomain).user("mytenant"),
new File("deploy-out-of-capacity.json"), 400);
// POST (deploy) an application where activation fails
configServer.throwOnNextPrepare(new ConfigServerException(new URI("server-url"), "Failed to activate application", ConfigServerException.ErrorCode.ACTIVATION_CONFLICT, null));
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/dev/region/us-west-1/instance/default/deploy",
- entity,
- Request.Method.POST,
- athenzUserDomain, "mytenant"),
- new File("deploy-activation-conflict.json"), 409);
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/dev/region/us-west-1/instance/default/deploy", POST)
+ .data(entity)
+ .domain(athenzUserDomain).user("mytenant"),
+ new File("deploy-activation-conflict.json"), 409);
// POST (deploy) an application where we get an internal server error
configServer.throwOnNextPrepare(new ConfigServerException(new URI("server-url"), "Internal server error", ConfigServerException.ErrorCode.INTERNAL_SERVER_ERROR, null));
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/dev/region/us-west-1/instance/default/deploy",
- entity,
- Request.Method.POST,
- athenzUserDomain, "mytenant"),
- new File("deploy-internal-server-error.json"), 500);
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/dev/region/us-west-1/instance/default/deploy", POST)
+ .data(entity)
+ .domain(athenzUserDomain).user("mytenant"),
+ new File("deploy-internal-server-error.json"), 500);
// DELETE tenant which has an application
- tester.assertResponse(request("/application/v4/tenant/tenant1", "", Request.Method.DELETE),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE),
"{\"error-code\":\"BAD_REQUEST\",\"message\":\"Could not delete tenant 'tenant1': This tenant has active applications\"}",
400);
// DELETE application
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1",
- "",
- Request.Method.DELETE),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", DELETE),
"");
// DELETE application again - should produce 404
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1",
- "",
- Request.Method.DELETE),
- "{\"error-code\":\"NOT_FOUND\",\"message\":\"Could not delete application 'tenant1.application1': Application not found\"}",
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", DELETE),
+ "{\"error-code\":\"NOT_FOUND\",\"message\":\"Could not delete application 'tenant1.application1': Application not found\"}",
404);
// DELETE tenant
- tester.assertResponse(request("/application/v4/tenant/tenant1", "", Request.Method.DELETE),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE),
new File("tenant-without-applications.json"));
// DELETE tenant again - should produce 404
- tester.assertResponse(request("/application/v4/tenant/tenant1", "", Request.Method.DELETE),
- "{\"error-code\":\"NOT_FOUND\",\"message\":\"Could not delete tenant 'tenant1': Tenant not found\"}",
+ tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE),
+ "{\"error-code\":\"NOT_FOUND\",\"message\":\"Could not delete tenant 'tenant1': Tenant not found\"}",
404);
// Promote application chef env for nonexistent tenant/application
- tester.assertResponse(request("/application/v4/tenant/dontexist/application/dontexist/environment/prod/region/us-west-1/instance/default/promote", "", Request.Method.POST),
- "{\"error-code\":\"INTERNAL_SERVER_ERROR\",\"message\":\"Unable to promote Chef environments for application\"}",
- 500);
+ tester.assertResponse(request("/application/v4/tenant/dontexist/application/dontexist/environment/prod/region/us-west-1/instance/default/promote", POST),
+ "{\"error-code\":\"INTERNAL_SERVER_ERROR\",\"message\":\"Unable to promote Chef environments for application\"}",
+ 500);
}
@Test
@@ -555,102 +506,85 @@ public class ApplicationApiTest extends ControllerContainerTest {
String unauthorizedUser = "othertenant";
// Mutation without an authorized user is disallowed
- tester.assertResponse(request("/application/v4/tenant/tenant1",
- "{\"athensDomain\":\"domain1\", \"property\":\"property1\"}",
- Request.Method.POST,
- "domain1", null),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
+ .domain("domain1").user(null),
"{\"error-code\":\"FORBIDDEN\",\"message\":\"User is not authenticated\"}",
403);
// ... but read methods are allowed
- tester.assertResponse(request("/application/v4/tenant/",
- "{\"athensDomain\":\"domain1\", \"property\":\"property1\"}",
- Request.Method.GET,
- "domain1", null),
+ tester.assertResponse(request("/application/v4/tenant/", GET)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
+ .domain("domain1").user(null),
"[]",
200);
addTenantAthenzDomain("domain1", "mytenant");
// Creating a tenant for an Athens domain the user is not admin for is disallowed
- tester.assertResponse(request("/application/v4/tenant/tenant1",
- "{\"athensDomain\":\"domain1\", \"property\":\"property1\"}",
- Request.Method.POST,
- "domain1", unauthorizedUser),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
+ .domain("domain1").user(unauthorizedUser),
"{\"error-code\":\"FORBIDDEN\",\"message\":\"The user 'othertenant' is not admin in Athenz domain 'domain1'\"}",
403);
// (Create it with the right tenant id)
- tester.assertResponse(request("/application/v4/tenant/tenant1",
- "{\"athensDomain\":\"domain1\", \"property\":\"property1\"}",
- Request.Method.POST,
- "domain1", authorizedUser),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", POST)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
+ .domain("domain1").user(authorizedUser),
new File("tenant-without-applications.json"),
200);
// Creating an application for an Athens domain the user is not admin for is disallowed
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1",
- "",
- Request.Method.POST,
- "domain1", unauthorizedUser),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST)
+ .domain("domain1").user(unauthorizedUser),
"{\"error-code\":\"FORBIDDEN\",\"message\":\"User othertenant does not have write access to tenant tenant1\"}",
403);
// (Create it with the right tenant id)
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1",
- "",
- Request.Method.POST,
- "domain1", authorizedUser),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", POST)
+ .domain("domain1").user(authorizedUser),
new File("application-reference.json"),
200);
// Deploy to an authorized zone by a user tenant is disallowed
HttpEntity entity = createApplicationDeployData(applicationPackage, Optional.empty());
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/deploy",
- entity,
- Request.Method.POST,
- athenzUserDomain, "mytenant"),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default/deploy", POST)
+ .data(entity)
+ .domain(athenzUserDomain).user("mytenant"),
"{\"error-code\":\"FORBIDDEN\",\"message\":\"Principal 'mytenant' is not a Screwdriver principal. Excepted principal with Athenz domain 'cd.screwdriver.project', got 'domain1'.\"}",
403);
// Deleting an application for an Athens domain the user is not admin for is disallowed
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1",
- "",
- Request.Method.DELETE,
- "domain1", unauthorizedUser),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", DELETE)
+ .domain("domain1").user(unauthorizedUser),
"{\"error-code\":\"FORBIDDEN\",\"message\":\"User othertenant does not have write access to tenant tenant1\"}",
403);
// (Deleting it with the right tenant id)
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1",
- "",
- Request.Method.DELETE,
- "domain1", authorizedUser),
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", DELETE)
+ .domain("domain1").user(authorizedUser),
"",
200);
// Updating a tenant for an Athens domain the user is not admin for is disallowed
- tester.assertResponse(request("/application/v4/tenant/tenant1",
- "{\"athensDomain\":\"domain1\", \"property\":\"property1\"}",
- Request.Method.PUT,
- "domain1", unauthorizedUser),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", PUT)
+ .data("{\"athensDomain\":\"domain1\", \"property\":\"property1\"}")
+ .domain("domain1").user(unauthorizedUser),
"{\"error-code\":\"FORBIDDEN\",\"message\":\"User othertenant does not have write access to tenant tenant1\"}",
403);
// Change Athens domain
addTenantAthenzDomain("domain2", "mytenant");
- tester.assertResponse(request("/application/v4/tenant/tenant1",
- "{\"athensDomain\":\"domain2\", \"property\":\"property1\"}",
- Request.Method.PUT,
- "domain1", authorizedUser),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", PUT)
+ .data("{\"athensDomain\":\"domain2\", \"property\":\"property1\"}")
+ .domain("domain1").user(authorizedUser),
"{\"tenant\":\"tenant1\",\"type\":\"ATHENS\",\"athensDomain\":\"domain2\",\"property\":\"property1\",\"applications\":[]}",
200);
// Deleting a tenant for an Athens domain the user is not admin for is disallowed
- tester.assertResponse(request("/application/v4/tenant/tenant1",
- "",
- Request.Method.DELETE,
- "domain1", unauthorizedUser),
+ tester.assertResponse(request("/application/v4/tenant/tenant1", DELETE)
+ .domain("domain1").user(unauthorizedUser),
"{\"error-code\":\"FORBIDDEN\",\"message\":\"User othertenant does not have write access to tenant tenant1\"}",
403);
}
@@ -685,33 +619,53 @@ public class ApplicationApiTest extends ControllerContainerTest {
"}";
}
-
- /** Make a request with (athens) user domain1.mytenant1 */
- private Request request(String path, String data, Request.Method method) {
- return request(path, data.getBytes(StandardCharsets.UTF_8), method, "domain1", "mytenant", "application/json");
- }
- private Request request(String path, String data, Request.Method method, String domain, String user) {
- return request(path, data.getBytes(StandardCharsets.UTF_8), method, domain, user, "application/json");
- }
+ private static class RequestBuilder implements Supplier<Request> {
- private Request request(String path, byte[] data, Request.Method method, String domain, String user, String contentType) {
- // user and domain parameters are translated to a Principal by MockAuthorizer as we do not run HTTP filters
- Request request = new Request("http://localhost:8080" + path + "?domain=" + domain +
- (user != null ? "&user=" + user : ""),
- data, method);
- request.getHeaders().put("Content-Type", contentType);
- return request;
- }
+ private final String path;
+ private final Request.Method method;
+ private byte[] data = new byte[0];
+ private String domain = "domain1";
+ private String user = "mytenant";
+ private String contentType = "application/json";
+ private String recursive;
- private Request request(String path, HttpEntity data, Request.Method method, String domain, String user) {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- try {
- data.writeTo(out);
- } catch (IOException e) {
- throw new UncheckedIOException(e);
+ private RequestBuilder(String path, Request.Method method) {
+ this.path = path;
+ this.method = method;
}
- return request(path, out.toByteArray(), method, domain, user, data.getContentType().getValue());
+
+ private RequestBuilder data(byte[] data) { this.data = data; return this; }
+ private RequestBuilder data(String data) { return data(data.getBytes(StandardCharsets.UTF_8)); }
+ private RequestBuilder data(HttpEntity data) {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try {
+ data.writeTo(out);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ return data(out.toByteArray()).contentType(data.getContentType().getValue());
+ }
+ private RequestBuilder domain(String domain) { this.domain = domain; return this; }
+ private RequestBuilder user(String user) { this.user = user; return this; }
+ private RequestBuilder contentType(String contentType) { this.contentType = contentType; return this; }
+ private RequestBuilder recursive(String recursive) { this.recursive = recursive; return this; }
+
+ @Override
+ public Request get() {
+ Request request = new Request("http://localhost:8080" + path +
+ // user and domain parameters are translated to a Principal by MockAuthorizer as we do not run HTTP filters
+ "?domain=" + domain + (user == null ? "" : "&user=" + user) +
+ (recursive == null ? "" : "&recursive=" + recursive),
+ data, method);
+ request.getHeaders().put("Content-Type", contentType);
+ return request;
+ }
+ }
+
+ /** Make a request with (athens) user domain1.mytenant */
+ private RequestBuilder request(String path, Request.Method method) {
+ return new RequestBuilder(path, method);
}
/**
@@ -750,28 +704,22 @@ public class ApplicationApiTest extends ControllerContainerTest {
// system-test
String testPath = String.format("/application/v4/tenant/%s/application/%s/environment/test/region/us-east-1/instance/default",
application.tenant().value(), application.application().value());
- tester.assertResponse(request(testPath,
- deployData,
- Request.Method.POST,
- athenzScrewdriverDomain, "screwdriveruser1"),
- new File("deploy-result.json"));
- tester.assertResponse(request(testPath,
- "",
- Request.Method.DELETE),
+ tester.assertResponse(request(testPath, POST)
+ .data(deployData)
+ .domain(athenzScrewdriverDomain).user("screwdriveruser1"),
+ new File("deploy-result.json"));
+ tester.assertResponse(request(testPath, DELETE),
"Deactivated " + testPath.replaceFirst("/application/v4/", ""));
controllerTester.notifyJobCompletion(application, projectId, true, DeploymentJobs.JobType.systemTest);
// staging
String stagingPath = String.format("/application/v4/tenant/%s/application/%s/environment/staging/region/us-east-3/instance/default",
application.tenant().value(), application.application().value());
- tester.assertResponse(request(stagingPath,
- deployData,
- Request.Method.POST,
- athenzScrewdriverDomain, "screwdriveruser1"),
- new File("deploy-result.json"));
- tester.assertResponse(request(stagingPath,
- "",
- Request.Method.DELETE),
+ tester.assertResponse(request(stagingPath, POST)
+ .data(deployData)
+ .domain(athenzScrewdriverDomain).user("screwdriveruser1"),
+ new File("deploy-result.json"));
+ tester.assertResponse(request(stagingPath, DELETE),
"Deactivated " + stagingPath.replaceFirst("/application/v4/", ""));
controllerTester.notifyJobCompletion(application, projectId, true, DeploymentJobs.JobType.stagingTest);
}
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/recursive-until-tenant-root.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/recursive-until-tenant-root.json
new file mode 100644
index 00000000000..2b3a5b3122a
--- /dev/null
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/recursive-until-tenant-root.json
@@ -0,0 +1,47 @@
+[
+ {
+ "tenant": "tenant2",
+ "type": "ATHENS",
+ "athensDomain": "domain2",
+ "property": "property2",
+ "propertyId": "1234",
+ "applications": [],
+ "propertyUrl": "www.properties.tld/1234",
+ "contactsUrl": "www.contacts.tld/1234",
+ "issueCreationUrl": "www.issues.tld/1234",
+ "contacts": [
+ [
+ "alice"
+ ],
+ [
+ "bob"
+ ]
+ ]
+ },
+ {
+ "tenant": "tenant3",
+ "type": "OPSDB",
+ "property": "property2",
+ "propertyId": "4321",
+ "userGroup": "group1",
+ "applications": [],
+ "propertyUrl": "www.properties.tld/4321",
+ "contactsUrl": "www.contacts.tld/4321",
+ "issueCreationUrl": "www.issues.tld/4321",
+ "contacts": []
+ },
+ {
+ "tenant": "tenant1",
+ "type": "ATHENS",
+ "athensDomain": "domain1",
+ "property": "property1",
+ "applications": [
+ {
+ "application": "application1",
+ "instance": "default",
+ "url": "http://localhost:8080/application/v4/tenant/tenant1/application/application1"
+ }
+ ]
+ }
+]
+