From 67d2470f211b600708788cde56e5cd48518ba4e8 Mon Sep 17 00:00:00 2001 From: Valerij Fredriksen Date: Tue, 22 Feb 2022 16:19:57 +0100 Subject: Add API to download submitted tests --- .../restapi/application/ApplicationApiHandler.java | 55 ++++++++++------------ .../restapi/application/ApplicationApiTest.java | 13 +++++ 2 files changed, 38 insertions(+), 30 deletions(-) (limited to 'controller-server') 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 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) -- cgit v1.2.3