use of com.yahoo.vespa.hosted.controller.Application in project vespa by vespa-engine.
the class ApplicationApiHandler method toSlime.
private void toSlime(Cursor object, Application application, HttpRequest request) {
object.setString("application", application.id().application().value());
object.setString("instance", application.id().instance().value());
// Currently deploying change
if (application.change().isPresent()) {
Cursor deployingObject = object.setObject("deploying");
application.change().platform().ifPresent(v -> deployingObject.setString("version", v.toString()));
application.change().application().filter(v -> v != ApplicationVersion.unknown).ifPresent(v -> toSlime(v, deployingObject.setObject("revision")));
}
// Jobs sorted according to deployment spec
List<JobStatus> jobStatus = controller.applications().deploymentTrigger().deploymentOrder().sortBy(application.deploymentSpec(), application.deploymentJobs().jobStatus().values());
Cursor deploymentsArray = object.setArray("deploymentJobs");
for (JobStatus job : jobStatus) {
Cursor jobObject = deploymentsArray.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");
application.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);
});
// Compile version. The version that should be used when building an application
object.setString("compileVersion", application.oldestDeployedVersion().orElse(controller.systemVersion()).toFullString());
// Rotation
Cursor globalRotationsArray = object.setArray("globalRotations");
application.rotation().ifPresent(rotation -> {
globalRotationsArray.addString(rotation.url().toString());
globalRotationsArray.addString(rotation.secureUrl().toString());
object.setString("rotationId", rotation.id().asString());
});
// Deployments sorted according to deployment spec
List<Deployment> deployments = controller.applications().deploymentTrigger().deploymentOrder().sortBy(application.deploymentSpec().zones(), application.deployments().values());
Cursor instancesArray = object.setArray("instances");
for (Deployment deployment : deployments) {
Cursor deploymentObject = instancesArray.addObject();
deploymentObject.setString("environment", deployment.zone().environment().value());
deploymentObject.setString("region", deployment.zone().region().value());
// pointless
deploymentObject.setString("instance", application.id().instance().value());
if (application.rotation().isPresent()) {
Map<String, RotationStatus> rotationHealthStatus = application.rotation().map(rotation -> controller.getHealthStatus(rotation.dnsName())).orElse(Collections.emptyMap());
setRotationStatus(deployment, rotationHealthStatus, deploymentObject);
}
if (// List full deployment information when recursive.
recurseOverDeployments(request))
toSlime(deploymentObject, new DeploymentId(application.id(), deployment.zone()), deployment, request);
else
deploymentObject.setString("url", withPath(request.getUri().getPath() + "/environment/" + deployment.zone().environment().value() + "/region/" + deployment.zone().region().value() + "/instance/" + application.id().instance().value(), request.getUri()).toString());
}
// Metrics
Cursor metricsObject = object.setObject("metrics");
metricsObject.setDouble("queryServiceQuality", application.metrics().queryServiceQuality());
metricsObject.setDouble("writeServiceQuality", application.metrics().writeServiceQuality());
application.ownershipIssueId().ifPresent(issueId -> object.setString("ownershipIssueId", issueId.value()));
application.deploymentJobs().issueId().ifPresent(issueId -> object.setString("deploymentIssueId", issueId.value()));
}
use of com.yahoo.vespa.hosted.controller.Application in project vespa by vespa-engine.
the class ApplicationApiHandler method toSlime.
private void toSlime(Cursor object, Tenant tenant, HttpRequest request, boolean listApplications) {
object.setString("tenant", tenant.getId().id());
object.setString("type", tenant.tenantType().name());
tenant.getAthensDomain().ifPresent(a -> object.setString("athensDomain", a.getName()));
tenant.getProperty().ifPresent(p -> object.setString("property", p.id()));
tenant.getPropertyId().ifPresent(p -> object.setString("propertyId", p.toString()));
Cursor applicationArray = object.setArray("applications");
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 (recurseOverApplications(request))
toSlime(applicationArray.addObject(), application, request);
else
toSlime(application, applicationArray.addObject(), request);
}
}
}
tenant.getPropertyId().ifPresent(propertyId -> {
try {
object.setString("propertyUrl", controller.organization().propertyUri(propertyId).toString());
object.setString("contactsUrl", controller.organization().contactsUri(propertyId).toString());
object.setString("issueCreationUrl", controller.organization().issueCreationUri(propertyId).toString());
Cursor lists = object.setArray("contacts");
for (List<? extends User> contactList : controller.organization().contactsFor(propertyId)) {
Cursor list = lists.addArray();
for (User contact : contactList) list.addString(contact.displayName());
}
} catch (RuntimeException e) {
log.log(Level.WARNING, "Error fetching property info for " + tenant + " with propertyId " + propertyId + ": " + Exceptions.toMessageString(e));
}
});
}
use of com.yahoo.vespa.hosted.controller.Application in project vespa by vespa-engine.
the class ApplicationApiHandler method createApplication.
private HttpResponse createApplication(String tenantName, String applicationName, HttpRequest request) {
Application application;
try {
application = controller.applications().createApplication(ApplicationId.from(tenantName, applicationName, "default"), getUserPrincipal(request).getNToken());
} catch (ZmsException e) {
// TODO: Push conversion down
if (e.getCode() == com.yahoo.jdisc.Response.Status.FORBIDDEN)
throw new ForbiddenException("Not authorized to create application", e);
else
throw e;
}
Slime slime = new Slime();
toSlime(application, slime.setObject(), request);
return new SlimeJsonResponse(slime);
}
use of com.yahoo.vespa.hosted.controller.Application in project vespa by vespa-engine.
the class ApplicationApiHandler method tenantPipelines.
/**
* Lists the screwdriver project id for each application
*/
private HttpResponse tenantPipelines() {
Slime slime = new Slime();
Cursor response = slime.setObject();
Cursor pipelinesArray = response.setArray("tenantPipelines");
for (Application application : controller.applications().asList()) {
if (!application.deploymentJobs().projectId().isPresent())
continue;
Cursor pipelineObject = pipelinesArray.addObject();
pipelineObject.setString("screwdriverId", String.valueOf(application.deploymentJobs().projectId().get()));
pipelineObject.setString("tenant", application.id().tenant().value());
pipelineObject.setString("application", application.id().application().value());
pipelineObject.setString("instance", application.id().instance().value());
}
// not used but may need to be present
response.setArray("brokenTenantPipelines");
return new SlimeJsonResponse(slime);
}
use of com.yahoo.vespa.hosted.controller.Application in project vespa by vespa-engine.
the class ApplicationApiHandler method toSlime.
private void toSlime(Cursor response, DeploymentId deploymentId, Deployment deployment, HttpRequest request) {
Cursor serviceUrlArray = response.setArray("serviceUrls");
controller.applications().getDeploymentEndpoints(deploymentId).ifPresent(endpoints -> endpoints.forEach(endpoint -> serviceUrlArray.addString(endpoint.toString())));
response.setString("nodes", withPath("/zone/v2/" + deploymentId.zoneId().environment() + "/" + deploymentId.zoneId().region() + "/nodes/v2/node/?&recursive=true&application=" + deploymentId.applicationId().tenant() + "." + deploymentId.applicationId().application() + "." + deploymentId.applicationId().instance(), request.getUri()).toString());
controller.zoneRegistry().getLogServerUri(deploymentId).ifPresent(elkUrl -> response.setString("elkUrl", elkUrl.toString()));
response.setString("yamasUrl", monitoringSystemUri(deploymentId).toString());
response.setString("version", deployment.version().toFullString());
response.setString("revision", deployment.applicationVersion().id());
response.setLong("deployTimeEpochMs", deployment.at().toEpochMilli());
controller.zoneRegistry().getDeploymentTimeToLive(deploymentId.zoneId()).ifPresent(deploymentTimeToLive -> response.setLong("expiryTimeEpochMs", deployment.at().plus(deploymentTimeToLive).toEpochMilli()));
controller.applications().get(deploymentId.applicationId()).flatMap(application -> application.deploymentJobs().projectId()).ifPresent(i -> response.setString("screwdriverId", String.valueOf(i)));
sourceRevisionToSlime(deployment.applicationVersion().source(), response);
// Cost
DeploymentCost appCost = deployment.calculateCost();
Cursor costObject = response.setObject("cost");
toSlime(appCost, costObject);
// Metrics
DeploymentMetrics metrics = deployment.metrics();
Cursor metricsObject = response.setObject("metrics");
metricsObject.setDouble("queriesPerSecond", metrics.queriesPerSecond());
metricsObject.setDouble("writesPerSecond", metrics.writesPerSecond());
metricsObject.setDouble("documentCount", metrics.documentCount());
metricsObject.setDouble("queryLatencyMillis", metrics.queryLatencyMillis());
metricsObject.setDouble("writeLatencyMillis", metrics.writeLatencyMillis());
}
Aggregations