summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Marius Venstad <venstad@gmail.com>2019-10-08 13:42:27 +0200
committerJon Marius Venstad <venstad@gmail.com>2019-10-08 13:42:27 +0200
commitd9e221b7895959ba6895c9d48489ebba91badb35 (patch)
tree473cc94ff89e36961982af38b48026313e35ba61
parentdf1d373b31761d1fcf9bccfbdbab35a99da03d2c (diff)
Aggregate over instances in application response
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java156
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiTest.java30
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-list.json3
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application2-with-patches.json70
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application2.json63
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-list.json3
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-reference-2.json (renamed from controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-reference-2.json)0
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-reference-default.json (renamed from controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-reference-default.json)0
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-reference.json (renamed from controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-reference.json)0
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-with-routing-policy.json (renamed from controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-with-routing-policy.json)11
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-without-change-multiple-deployments.json (renamed from controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-without-change-multiple-deployments.json)12
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance.json (renamed from controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application.json)10
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance1-metering.json (renamed from controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application1-metering.json)0
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance1-recursive.json (renamed from controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application1-recursive.json)10
-rw-r--r--controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant1-recursive.json2
15 files changed, 284 insertions, 86 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 16eaa44aa74..6a2ad3ba504 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
@@ -199,12 +199,12 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
if (path.matches("/application/v4/tenant")) return tenants(request);
if (path.matches("/application/v4/tenant/{tenant}")) return tenant(path.get("tenant"), request);
if (path.matches("/application/v4/tenant/{tenant}/application")) return applications(path.get("tenant"), Optional.empty(), request);
- if (path.matches("/application/v4/tenant/{tenant}/application/{application}")) return application(path.get("tenant"), path.get("application"), "default", request);
+ if (path.matches("/application/v4/tenant/{tenant}/application/{application}")) return application(path.get("tenant"), path.get("application"), request);
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/deploying")) return deploying(path.get("tenant"), path.get("application"), "default", request);
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/deploying/pin")) return deploying(path.get("tenant"), path.get("application"), "default", request);
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/metering")) return metering(path.get("tenant"), path.get("application"), request);
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance")) return applications(path.get("tenant"), Optional.of(path.get("application")), request);
- if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}")) return application(path.get("tenant"), path.get("application"), path.get("instance"), request);
+ if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}")) return instance(path.get("tenant"), path.get("application"), path.get("instance"), request);
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/deploying")) return deploying(path.get("tenant"), path.get("application"), path.get("instance"), request);
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/deploying/pin")) return deploying(path.get("tenant"), path.get("application"), path.get("instance"), request);
if (path.matches("/application/v4/tenant/{tenant}/application/{application}/instance/{instance}/job")) return JobControllerApiHandlerHelper.jobTypeResponse(controller, appIdFromPath(path), request.getUri());
@@ -366,10 +366,16 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
return new SlimeJsonResponse(slime);
}
- private HttpResponse application(String tenantName, String applicationName, String instanceName, HttpRequest request) {
+ private HttpResponse application(String tenantName, String applicationName, HttpRequest request) {
+ Slime slime = new Slime();
+ toSlime(slime.setObject(), getApplication(tenantName, applicationName), request);
+ return new SlimeJsonResponse(slime);
+ }
+
+ private HttpResponse instance(String tenantName, String applicationName, String instanceName, HttpRequest request) {
Slime slime = new Slime();
toSlime(slime.setObject(), getInstance(tenantName, applicationName, instanceName),
- getApplication(tenantName, applicationName, instanceName), request);
+ getApplication(tenantName, applicationName), request);
return new SlimeJsonResponse(slime);
}
@@ -466,8 +472,8 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
return new MessageResponse(messageBuilder.toString());
}
- private Application getApplication(String tenantName, String applicationName, String instanceName) {
- ApplicationId applicationId = ApplicationId.from(tenantName, applicationName, instanceName);
+ private Application getApplication(String tenantName, String applicationName) {
+ TenantAndApplicationId applicationId = TenantAndApplicationId.from(tenantName, applicationName);
return controller.applications().getApplication(applicationId)
.orElseThrow(() -> new NotExistsException(applicationId + " not found"));
}
@@ -562,6 +568,138 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
return new MessageResponse(type.jobName() + " for " + id + " paused for " + DeploymentTrigger.maxPause);
}
+ private void toSlime(Cursor object, Application application, HttpRequest request) {
+ object.setString("tenant", application.id().tenant().value());
+ object.setString("application", application.id().application().value());
+ object.setString("deployments", withPath("/application/v4" +
+ "/tenant/" + application.id().tenant().value() +
+ "/application/" + application.id().application().value() +
+ "/job/",
+ request.getUri()).toString());
+
+ application.latestVersion().ifPresent(version -> toSlime(version, object.setObject("latestVersion")));
+
+ application.projectId().ifPresent(id -> object.setLong("projectId", id));
+
+ // Currently deploying change
+ if ( ! application.change().isEmpty())
+ toSlime(object.setObject("deploying"), application.change());
+
+ // Outstanding change
+ if ( ! application.outstandingChange().isEmpty())
+ toSlime(object.setObject("outstandingChange"), application.outstandingChange());
+
+ // Compile version. The version that should be used when building an application
+ object.setString("compileVersion", compileVersion(application.id()).toFullString());
+
+ application.majorVersion().ifPresent(majorVersion -> object.setLong("majorVersion", majorVersion));
+
+ Cursor instancesArray = object.setArray("instances");
+ for (Instance instance : application.instances().values())
+ toSlime(instancesArray.addObject(), instance, application.deploymentSpec(), request);
+
+ application.deployKeys().stream().map(KeyUtils::toPem).forEach(object.setArray("pemDeployKeys")::addString);
+
+ // Metrics
+ Cursor metricsObject = object.setObject("metrics");
+ metricsObject.setDouble("queryServiceQuality", application.metrics().queryServiceQuality());
+ metricsObject.setDouble("writeServiceQuality", application.metrics().writeServiceQuality());
+
+ // Activity
+ Cursor activity = object.setObject("activity");
+ application.activity().lastQueried().ifPresent(instant -> activity.setLong("lastQueried", instant.toEpochMilli()));
+ application.activity().lastWritten().ifPresent(instant -> activity.setLong("lastWritten", instant.toEpochMilli()));
+ application.activity().lastQueriesPerSecond().ifPresent(value -> activity.setDouble("lastQueriesPerSecond", value));
+ application.activity().lastWritesPerSecond().ifPresent(value -> activity.setDouble("lastWritesPerSecond", value));
+
+ application.ownershipIssueId().ifPresent(issueId -> object.setString("ownershipIssueId", issueId.value()));
+ application.owner().ifPresent(owner -> object.setString("owner", owner.username()));
+ application.deploymentIssueId().ifPresent(issueId -> object.setString("deploymentIssueId", issueId.value()));
+ }
+
+ private void toSlime(Cursor object, Instance instance, DeploymentSpec deploymentSpec, HttpRequest request) {
+ object.setString("instance", instance.name().value());
+ // Jobs sorted according to deployment spec
+ List<JobStatus> jobStatus = controller.applications().deploymentTrigger()
+ .steps(deploymentSpec)
+ .sortedJobs(instance.deploymentJobs().jobStatus().values());
+
+
+ Cursor deploymentJobsArray = object.setArray("deploymentJobs");
+ for (JobStatus job : jobStatus) {
+ Cursor jobObject = deploymentJobsArray.addObject();
+ jobObject.setString("type", job.type().jobName());
+ jobObject.setBool("success", job.isSuccess());
+ job.lastTriggered().ifPresent(jobRun -> toSlime(jobRun, jobObject.setObject("lastTriggered")));
+ job.lastCompleted().ifPresent(jobRun -> toSlime(jobRun, jobObject.setObject("lastCompleted")));
+ job.firstFailing().ifPresent(jobRun -> toSlime(jobRun, jobObject.setObject("firstFailing")));
+ job.lastSuccess().ifPresent(jobRun -> toSlime(jobRun, jobObject.setObject("lastSuccess")));
+ }
+
+ // Change blockers
+ Cursor changeBlockers = object.setArray("changeBlockers");
+ deploymentSpec.changeBlocker().forEach(changeBlocker -> {
+ Cursor changeBlockerObject = changeBlockers.addObject();
+ changeBlockerObject.setBool("versions", changeBlocker.blocksVersions());
+ changeBlockerObject.setBool("revisions", changeBlocker.blocksRevisions());
+ changeBlockerObject.setString("timeZone", changeBlocker.window().zone().getId());
+ Cursor days = changeBlockerObject.setArray("days");
+ changeBlocker.window().days().stream().map(DayOfWeek::getValue).forEach(days::addLong);
+ Cursor hours = changeBlockerObject.setArray("hours");
+ changeBlocker.window().hours().forEach(hours::addLong);
+ });
+
+ // Rotation
+ Cursor globalRotationsArray = object.setArray("globalRotations");
+ instance.endpointsIn(controller.system())
+ .scope(Endpoint.Scope.global)
+ .legacy(false) // Hide legacy names
+ .asList().stream()
+ .map(Endpoint::url)
+ .map(URI::toString)
+ .forEach(globalRotationsArray::addString);
+
+ instance.rotations().stream()
+ .map(AssignedRotation::rotationId)
+ .findFirst()
+ .ifPresent(rotation -> object.setString("rotationId", rotation.asString()));
+
+ // Per-cluster rotations
+ Set<RoutingPolicy> routingPolicies = controller.applications().routingPolicies().get(instance.id());
+ for (RoutingPolicy policy : routingPolicies) {
+ policy.rotationEndpointsIn(controller.system()).asList().stream()
+ .map(Endpoint::url)
+ .map(URI::toString)
+ .forEach(globalRotationsArray::addString);
+ }
+
+ // Deployments sorted according to deployment spec
+ List<Deployment> deployments = controller.applications().deploymentTrigger()
+ .steps(deploymentSpec)
+ .sortedDeployments(instance.deployments().values());
+
+ Cursor deploymentsArray = object.setArray("deployments");
+ for (Deployment deployment : deployments) {
+ Cursor deploymentObject = deploymentsArray.addObject();
+
+ // Rotation status for this deployment
+ if (deployment.zone().environment() == Environment.prod && ! instance.rotations().isEmpty())
+ toSlime(instance.rotations(), instance.rotationStatus(), deployment, deploymentObject);
+
+ if (recurseOverDeployments(request)) // List full deployment information when recursive.
+ toSlime(deploymentObject, new DeploymentId(instance.id(), deployment.zone()), deployment, request);
+ else {
+ deploymentObject.setString("environment", deployment.zone().environment().value());
+ deploymentObject.setString("region", deployment.zone().region().value());
+ deploymentObject.setString("url", withPath(request.getUri().getPath() +
+ "/instance/" + instance.name().value() +
+ "/environment/" + deployment.zone().environment().value() +
+ "/region/" + deployment.zone().region().value(),
+ request.getUri()).toString());
+ }
+ }
+ }
+
private void toSlime(Cursor object, Instance instance, Application application, HttpRequest request) {
object.setString("tenant", instance.id().tenant().value());
object.setString("application", instance.id().application().value());
@@ -677,8 +815,7 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
deploymentObject.setString("instance", instance.id().instance().value()); // pointless
deploymentObject.setString("url", withPath(request.getUri().getPath() +
"/environment/" + deployment.zone().environment().value() +
- "/region/" + deployment.zone().region().value() +
- ( request.getUri().getPath().contains("/instance/") ? "" : "/instance/" + instance.id().instance().value()),
+ "/region/" + deployment.zone().region().value(),
request.getUri()).toString());
}
}
@@ -790,7 +927,8 @@ public class ApplicationApiHandler extends LoggingRequestHandler {
}
private void toSlime(ApplicationVersion applicationVersion, Cursor object) {
- if (!applicationVersion.isUnknown()) {
+ if ( ! applicationVersion.isUnknown()) {
+ object.setLong("buildNumber", applicationVersion.buildNumber().getAsLong());
object.setString("hash", applicationVersion.id());
sourceRevisionToSlime(applicationVersion.source(), object.setObject("source"));
}
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 83972fbcd79..c41d60bd0cb 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
@@ -206,17 +206,17 @@ public class ApplicationApiTest extends ControllerContainerTest {
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", POST)
.userIdentity(USER_ID)
.oktaAccessToken(OKTA_AT),
- new File("application-reference.json"));
+ new File("instance-reference.json"));
// GET a tenant
tester.assertResponse(request("/application/v4/tenant/tenant1", GET).userIdentity(USER_ID),
new File("tenant-with-application.json"));
// GET tenant applications
tester.assertResponse(request("/application/v4/tenant/tenant1/application/", GET).userIdentity(USER_ID),
- new File("application-list.json"));
+ new File("instance-list.json"));
// GET tenant applications (instances of "application1" only)
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/", GET).userIdentity(USER_ID),
- new File("application-list.json"));
+ new File("instance-list.json"));
addUserToHostedOperatorRole(HostedAthenzIdentities.from(HOSTED_VESPA_OPERATOR));
@@ -312,7 +312,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
tester.assertResponse(request("/application/v4/tenant/tenant2/application/application2/instance/default", POST)
.userIdentity(USER_ID)
.oktaAccessToken(OKTA_AT),
- new File("application-reference-2.json"));
+ new File("instance-reference-2.json"));
ApplicationId app2 = ApplicationId.from("tenant2", "application2", "default");
long screwdriverProjectId2 = 456;
@@ -394,7 +394,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
// GET tenant application deployments
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", GET)
.userIdentity(USER_ID),
- new File("application.json"));
+ new File("instance.json"));
// GET an application deployment
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-central-1/instance/instance1", GET)
.userIdentity(USER_ID),
@@ -420,7 +420,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", GET)
.userIdentity(USER_ID)
.recursive("true"),
- new File("application1-recursive.json"));
+ new File("instance1-recursive.json"));
// GET nodes
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-central-1/instance/instance1/nodes", GET)
@@ -845,7 +845,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", POST)
.userIdentity(USER_ID)
.oktaAccessToken(OKTA_AT),
- new File("application-reference.json"));
+ new File("instance-reference.json"));
// Grant deploy access
addScrewdriverUserToDeployRole(SCREWDRIVER_ID,
@@ -936,7 +936,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
setDeploymentMaintainedInfo(controllerTester);
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", GET)
.userIdentity(USER_ID),
- new File("application-without-change-multiple-deployments.json"));
+ new File("instance-without-change-multiple-deployments.json"));
}
@Test
@@ -958,7 +958,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
tester.assertResponse(request("/application/v4/tenant/doesnotexist/application/doesnotexist/metering", GET)
.userIdentity(USER_ID)
.oktaAccessToken(OKTA_AT),
- new File("application1-metering.json"));
+ new File("instance1-metering.json"));
}
@Test
@@ -1043,7 +1043,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", POST)
.userIdentity(USER_ID)
.oktaAccessToken(OKTA_AT),
- new File("application-reference.json"));
+ new File("instance-reference.json"));
// Create the same application again
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", POST)
@@ -1172,7 +1172,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", POST)
.userIdentity(authorizedUser)
.oktaAccessToken(OKTA_AT),
- new File("application-reference.json"),
+ new File("instance-reference.json"),
200);
// Deploy to an authorized zone by a user tenant is disallowed
@@ -1193,7 +1193,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/default", POST)
.userIdentity(authorizedUser)
.oktaAccessToken(OKTA_AT),
- new File("application-reference-default.json"),
+ new File("instance-reference-default.json"),
200);
// Deleting the application when more than one instance is present is forbidden
@@ -1538,9 +1538,9 @@ public class ApplicationApiTest extends ControllerContainerTest {
tester.controller().curator().writeRoutingPolicies(app.id().defaultInstance(), Set.of(policy));
// GET application
- tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1", GET)
+ tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/default", GET)
.userIdentity(USER_ID),
- new File("application-with-routing-policy.json"));
+ new File("instance-with-routing-policy.json"));
// GET deployment
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default", GET)
@@ -1670,7 +1670,7 @@ public class ApplicationApiTest extends ControllerContainerTest {
tester.assertResponse(request("/application/v4/tenant/tenant1/application/application1/instance/instance1", POST)
.userIdentity(USER_ID)
.oktaAccessToken(OKTA_AT),
- new File("application-reference.json"));
+ new File("instance-reference.json"));
addScrewdriverUserToDeployRole(SCREWDRIVER_ID, ATHENZ_TENANT_DOMAIN,
new com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId("application1"));
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-list.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-list.json
deleted file mode 100644
index ecee1c8dbde..00000000000
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-list.json
+++ /dev/null
@@ -1,3 +0,0 @@
-[
- @include(application-reference.json)
-] \ No newline at end of file
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application2-with-patches.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application2-with-patches.json
index ddadf7af8f1..ad86fa34cde 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application2-with-patches.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application2-with-patches.json
@@ -1,12 +1,15 @@
{
"tenant": "tenant2",
"application": "application2",
- "instance": "default",
- "deployments": "http://localhost:8080/application/v4/tenant/tenant2/application/application2/instance/default/job/",
- "source": {
- "gitRepository": "repository1",
- "gitBranch": "master",
- "gitCommit": "commit1"
+ "deployments": "http://localhost:8080/application/v4/tenant/tenant2/application/application2/job/",
+ "latestVersion": {
+ "buildNumber": 42,
+ "hash": "1.0.42-commit1",
+ "source": {
+ "gitRepository": "repository1",
+ "gitBranch": "master",
+ "gitCommit": "commit1"
+ }
},
"projectId": 456,
"deploying": {
@@ -14,6 +17,7 @@
},
"outstandingChange": {
"revision": {
+ "buildNumber": 42,
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -22,34 +26,40 @@
}
}
},
- "deployedInternally": false,
- "deploymentJobs": [
+ "compileVersion": "6.1.0",
+ "majorVersion": 7,
+ "instances": [
{
- "type": "system-test",
- "success": false,
- "lastTriggered": {
- "id": -1,
- "version": "7.0.0",
- "revision": {
- "hash": "1.0.42-commit1",
- "source": {
- "gitRepository": "repository1",
- "gitBranch": "master",
- "gitCommit": "commit1"
+ "instance": "default",
+ "deploymentJobs": [
+ {
+ "type": "system-test",
+ "success": false,
+ "lastTriggered": {
+ "id": -1,
+ "version": "7.0.0",
+ "revision": {
+ "buildNumber": 42,
+ "hash": "1.0.42-commit1",
+ "source": {
+ "gitRepository": "repository1",
+ "gitBranch": "master",
+ "gitCommit": "commit1"
+ }
+ },
+ "reason": "Testing last changes outside prod",
+ "at": "(ignore)"
}
- },
- "reason": "Testing last changes outside prod",
- "at": "(ignore)"
- }
+ }
+ ],
+ "changeBlockers": [],
+ "globalRotations": [],
+ "deployments": []
}
],
- "changeBlockers": [],
- "compileVersion": "6.1.0",
- "majorVersion": 7,
- "globalRotations": [],
- "instances": [],
- "pemDeployKey": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuKVFA8dXk43kVfYKzkUqhEY2rDT9\nz/4jKSTHwbYR8wdsOSrJGVEUPbS2nguIJ64OJH7gFnxM6sxUVj+Nm2HlXw==\n-----END PUBLIC KEY-----\n",
- "pemDeployKeys": ["-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuKVFA8dXk43kVfYKzkUqhEY2rDT9\nz/4jKSTHwbYR8wdsOSrJGVEUPbS2nguIJ64OJH7gFnxM6sxUVj+Nm2HlXw==\n-----END PUBLIC KEY-----\n"],
+ "pemDeployKeys": [
+ "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuKVFA8dXk43kVfYKzkUqhEY2rDT9\nz/4jKSTHwbYR8wdsOSrJGVEUPbS2nguIJ64OJH7gFnxM6sxUVj+Nm2HlXw==\n-----END PUBLIC KEY-----\n"
+ ],
"metrics": {
"queryServiceQuality": 0.0,
"writeServiceQuality": 0.0
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application2.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application2.json
index 9ab4e13814b..6d89fa4ee20 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application2.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application2.json
@@ -1,12 +1,15 @@
{
"tenant": "tenant2",
"application": "application2",
- "instance": "default",
- "deployments": "http://localhost:8080/application/v4/tenant/tenant2/application/application2/instance/default/job/",
- "source": {
- "gitRepository": "repository1",
- "gitBranch": "master",
- "gitCommit": "commit1"
+ "deployments": "http://localhost:8080/application/v4/tenant/tenant2/application/application2/job/",
+ "latestVersion": {
+ "buildNumber": 42,
+ "hash": "1.0.42-commit1",
+ "source": {
+ "gitRepository": "repository1",
+ "gitBranch": "master",
+ "gitCommit": "commit1"
+ }
},
"projectId": 456,
"deploying": {
@@ -14,6 +17,7 @@
},
"outstandingChange": {
"revision": {
+ "buildNumber": 42,
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -22,31 +26,36 @@
}
}
},
- "deployedInternally": false,
- "deploymentJobs": [
+ "compileVersion": "6.1.0",
+ "instances": [
{
- "type": "system-test",
- "success": false,
- "lastTriggered": {
- "id": -1,
- "version": "7.0.0",
- "revision": {
- "hash": "1.0.42-commit1",
- "source": {
- "gitRepository": "repository1",
- "gitBranch": "master",
- "gitCommit": "commit1"
+ "instance": "default",
+ "deploymentJobs": [
+ {
+ "type": "system-test",
+ "success": false,
+ "lastTriggered": {
+ "id": -1,
+ "version": "7.0.0",
+ "revision": {
+ "buildNumber": 42,
+ "hash": "1.0.42-commit1",
+ "source": {
+ "gitRepository": "repository1",
+ "gitBranch": "master",
+ "gitCommit": "commit1"
+ }
+ },
+ "reason": "Testing last changes outside prod",
+ "at": "(ignore)"
}
- },
- "reason": "Testing last changes outside prod",
- "at": "(ignore)"
- }
+ }
+ ],
+ "changeBlockers": [],
+ "globalRotations": [],
+ "deployments": []
}
],
- "changeBlockers": [],
- "compileVersion": "6.1.0",
- "globalRotations": [],
- "instances": [],
"pemDeployKeys": [],
"metrics": {
"queryServiceQuality": 0.0,
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-list.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-list.json
new file mode 100644
index 00000000000..024ca11dbe3
--- /dev/null
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-list.json
@@ -0,0 +1,3 @@
+[
+ @include(instance-reference.json)
+] \ No newline at end of file
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-reference-2.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-reference-2.json
index 0c9dc2ca1e7..0c9dc2ca1e7 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-reference-2.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-reference-2.json
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-reference-default.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-reference-default.json
index 7117cc22507..7117cc22507 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-reference-default.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-reference-default.json
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-reference.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-reference.json
index 60243633614..60243633614 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-reference.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-reference.json
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-with-routing-policy.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-with-routing-policy.json
index 7bb1d398641..91356bc83bf 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-with-routing-policy.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-with-routing-policy.json
@@ -18,6 +18,7 @@
"id": -1,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "1.0.42-commit1",
"source": {
"gitRepository": "repository1",
@@ -32,6 +33,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "1.0.42-commit1",
"source": {
"gitRepository": "repository1",
@@ -46,6 +48,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "1.0.42-commit1",
"source": {
"gitRepository": "repository1",
@@ -64,6 +67,7 @@
"id": -1,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "1.0.42-commit1",
"source": {
"gitRepository": "repository1",
@@ -78,6 +82,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "1.0.42-commit1",
"source": {
"gitRepository": "repository1",
@@ -92,6 +97,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "1.0.42-commit1",
"source": {
"gitRepository": "repository1",
@@ -110,6 +116,7 @@
"id": -1,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "1.0.42-commit1",
"source": {
"gitRepository": "repository1",
@@ -124,6 +131,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "1.0.42-commit1",
"source": {
"gitRepository": "repository1",
@@ -138,6 +146,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "1.0.42-commit1",
"source": {
"gitRepository": "repository1",
@@ -160,7 +169,7 @@
"environment": "prod",
"region": "us-west-1",
"instance": "default",
- "url": "http://localhost:8080/application/v4/tenant/tenant1/application/application1/environment/prod/region/us-west-1/instance/default"
+ "url": "http://localhost:8080/application/v4/tenant/tenant1/application/application1/instance/default/environment/prod/region/us-west-1"
}
],
"pemDeployKeys": [],
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-without-change-multiple-deployments.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-without-change-multiple-deployments.json
index 6f571c223bd..bcda7992d81 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application-without-change-multiple-deployments.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-without-change-multiple-deployments.json
@@ -18,6 +18,7 @@
"id": -1,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -32,6 +33,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -46,6 +48,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -64,6 +67,7 @@
"id": -1,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -78,6 +82,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -92,6 +97,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -110,6 +116,7 @@
"id": -1,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -124,6 +131,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -138,6 +146,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -156,6 +165,7 @@
"id": -1,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -170,6 +180,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -184,6 +195,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance.json
index 4a9d0369e39..009d6c74dd1 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance.json
@@ -11,6 +11,7 @@
"projectId": 123,
"deploying": {
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -28,6 +29,7 @@
"id": -1,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -42,6 +44,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -56,6 +59,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -74,6 +78,7 @@
"id": -1,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -88,6 +93,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -102,6 +108,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -120,6 +127,7 @@
"id": -1,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -134,6 +142,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -148,6 +157,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application1-metering.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance1-metering.json
index 2e07a7e8a96..2e07a7e8a96 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application1-metering.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance1-metering.json
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application1-recursive.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance1-recursive.json
index 93efbdf3fa0..afa506d1e48 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application1-recursive.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance1-recursive.json
@@ -11,6 +11,7 @@
"projectId": 123,
"deploying": {
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -28,6 +29,7 @@
"id": -1,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -42,6 +44,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -56,6 +59,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -74,6 +78,7 @@
"id": -1,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -88,6 +93,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -102,6 +108,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -120,6 +127,7 @@
"id": -1,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -134,6 +142,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
@@ -148,6 +157,7 @@
"id": 42,
"version": "(ignore)",
"revision": {
+ "buildNumber": "(ignore)",
"hash": "(ignore)",
"source": {
"gitRepository": "repository1",
diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant1-recursive.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant1-recursive.json
index 309177e6285..16b963a190e 100644
--- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant1-recursive.json
+++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/tenant1-recursive.json
@@ -4,6 +4,6 @@
"athensDomain": "domain1",
"property": "property1",
"applications": [
- @include(application1-recursive.json)
+ @include(instance1-recursive.json)
]
}