summaryrefslogtreecommitdiffstats
path: root/controller-server
diff options
context:
space:
mode:
authorValerij Fredriksen <valerijf@yahooinc.com>2022-02-22 16:19:57 +0100
committerValerij Fredriksen <valerijf@yahooinc.com>2022-02-22 16:19:57 +0100
commit67d2470f211b600708788cde56e5cd48518ba4e8 (patch)
tree192b442d85ec86ff6a7c323ea86131e90e333f99 /controller-server
parentf859f58e988c61b0c16f4ed4eb9aaa5daca1661d (diff)
Add API to download submitted tests
Diffstat (limited to 'controller-server')
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java55
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java13
2 files changed, 38 insertions, 30 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 6210241cc31..13c5f978298 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
@@ -144,12 +144,10 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
-import java.util.OptionalLong;
import java.util.Scanner;
+import java.util.SortedSet;
import java.util.StringJoiner;
import java.util.function.Function;
-import java.util.function.Predicate;
-import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -708,33 +706,30 @@ public class ApplicationApiHandler extends AuditLoggingRequestHandler {
private HttpResponse applicationPackage(String tenantName, String applicationName, HttpRequest request) {
var tenantAndApplication = TenantAndApplicationId.from(tenantName, applicationName);
-
- long buildNumber;
- var requestedBuild = Optional.ofNullable(request.getProperty("build")).map(build -> {
- try {
- return Long.parseLong(build);
- } catch (NumberFormatException e) {
- throw new IllegalArgumentException("Invalid build number", e);
- }
- });
- if (requestedBuild.isEmpty()) { // Fall back to latest build
- var application = controller.applications().requireApplication(tenantAndApplication);
- var latestBuild = application.latestVersion().map(ApplicationVersion::buildNumber).orElse(OptionalLong.empty());
- if (latestBuild.isEmpty()) {
- throw new NotExistsException("No application package has been submitted for '" + tenantAndApplication + "'");
- }
- buildNumber = latestBuild.getAsLong();
- } else {
- buildNumber = requestedBuild.get();
- }
- var applicationPackage = controller.applications().applicationStore().find(tenantAndApplication.tenant(), tenantAndApplication.application(), buildNumber);
- var filename = tenantAndApplication + "-build" + buildNumber + ".zip";
- if (applicationPackage.isEmpty()) {
- throw new NotExistsException("No application package found for '" +
- tenantAndApplication +
- "' with build number " + buildNumber);
- }
- return new ZipResponse(filename, applicationPackage.get());
+ SortedSet<ApplicationVersion> versions = controller.applications().requireApplication(tenantAndApplication).versions();
+ if (versions.isEmpty())
+ throw new NotExistsException("No application package has been submitted for '" + tenantAndApplication + "'");
+
+ ApplicationVersion version = Optional.ofNullable(request.getProperty("build"))
+ .map(build -> {
+ try {
+ return Long.parseLong(build);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid build number", e);
+ }
+ })
+ .map(build -> versions.stream()
+ .filter(ver -> ver.buildNumber().orElse(-1) == build)
+ .findFirst()
+ .orElseThrow(() -> new NotExistsException("No application package found for '" + tenantAndApplication + "' with build number " + build)))
+ .orElseGet(versions::last);
+
+ boolean tests = request.getBooleanProperty("tests");
+ byte[] applicationPackage = tests ?
+ controller.applications().applicationStore().getTester(tenantAndApplication.tenant(), tenantAndApplication.application(), version) :
+ controller.applications().applicationStore().get(new DeploymentId(tenantAndApplication.defaultInstance(), ZoneId.defaultId()), version);
+ String filename = tenantAndApplication + (tests ? "-tests" : "-build") + version.buildNumber().getAsLong() + ".zip";
+ return new ZipResponse(filename, applicationPackage);
}
private HttpResponse applicationPackageDiff(String tenant, String application, String number) {
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 32999d24a03..9a8fced2288 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
@@ -787,6 +787,12 @@ public class ApplicationApiTest extends ControllerContainerTest {
assertArrayEquals(packageWithService.zippedContent(), response.getBody());
},
200);
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/package", GET).userIdentity(HOSTED_VESPA_OPERATOR).properties(Map.of("tests", "true")),
+ (response) -> {
+ assertEquals("attachment; filename=\"tenant1.application1-tests2.zip\"", response.getHeaders().getFirst("Content-Disposition"));
+ assertArrayEquals("content".getBytes(UTF_8), response.getBody());
+ },
+ 200);
// GET application package for previous build
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/package", GET)
@@ -1201,11 +1207,18 @@ public class ApplicationApiTest extends ControllerContainerTest {
404);
// GET non-existent application package of specific build
+ addScrewdriverUserToDeployRole(SCREWDRIVER_ID, ATHENZ_TENANT_DOMAIN, ApplicationName.from("application1"));
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/submit", POST)
+ .screwdriverIdentity(SCREWDRIVER_ID)
+ .data(createApplicationSubmissionData(applicationPackageInstance1, 1000)),
+ "{\"message\":\"Application package version: 1.0.1-commit1, source revision of repository 'repository1', branch 'master' with commit 'commit1', by a@b, built against 6.1 at 1970-01-01T00:00:01Z\"}");
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/package", GET)
.properties(Map.of("build", "42"))
.userIdentity(HOSTED_VESPA_OPERATOR),
"{\"error-code\":\"NOT_FOUND\",\"message\":\"No application package found for 'tenant1.application1' with build number 42\"}",
404);
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/deployment", DELETE).userIdentity(USER_ID).oAuthCredentials(OKTA_CREDENTIALS),
+ "{\"message\":\"All deployments removed\"}");
// GET non-existent application package of invalid build
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/package", GET)