use of com.yahoo.vespa.hosted.controller.Application in project vespa by vespa-engine.
the class ApplicationApiHandler method application.
private HttpResponse application(String tenantName, String applicationName, HttpRequest request) {
ApplicationId applicationId = ApplicationId.from(tenantName, applicationName, "default");
Application application = controller.applications().get(applicationId).orElseThrow(() -> new NotExistsException(applicationId + " not found"));
Slime slime = new Slime();
toSlime(slime.setObject(), application, request);
return new SlimeJsonResponse(slime);
}
use of com.yahoo.vespa.hosted.controller.Application in project vespa by vespa-engine.
the class ApplicationApiHandler method applications.
private HttpResponse applications(String tenantName, HttpRequest request) {
TenantName tenant = TenantName.from(tenantName);
Slime slime = new Slime();
Cursor array = slime.setArray();
for (Application application : controller.applications().asList(tenant)) toSlime(application, array.addObject(), request);
return new SlimeJsonResponse(slime);
}
use of com.yahoo.vespa.hosted.controller.Application in project vespa by vespa-engine.
the class DeploymentIssueReporterTest method testDeploymentFailureReporting.
@Test
public void testDeploymentFailureReporting() {
// All applications deploy from unique build projects.
Long projectId1 = 10L;
Long projectId2 = 20L;
Long projectId3 = 30L;
Long propertyId1 = 1L;
Long propertyId2 = 2L;
Long propertyId3 = 3L;
tester.updateVersionStatus(Version.fromString("5.1"));
// Create and deploy one application for each of three tenants.
Application app1 = tester.createApplication("application1", "tenant1", projectId1, propertyId1);
Application app2 = tester.createApplication("application2", "tenant2", projectId2, propertyId2);
Application app3 = tester.createApplication("application3", "tenant3", projectId3, propertyId3);
// NOTE: All maintenance should be idempotent within a small enough time interval, so maintain is called twice in succession throughout.
// apps 1 and 3 have one failure each.
tester.jobCompletion(component).application(app1).uploadArtifact(applicationPackage).submit();
tester.deployAndNotify(app1, applicationPackage, true, systemTest);
tester.deployAndNotify(app1, applicationPackage, false, stagingTest);
// app2 is successful, but will fail later.
tester.deployCompletely(app2, canaryPackage);
tester.jobCompletion(component).application(app3).uploadArtifact(applicationPackage).submit();
tester.deployAndNotify(app3, applicationPackage, true, systemTest);
tester.deployAndNotify(app3, applicationPackage, true, stagingTest);
tester.deployAndNotify(app3, applicationPackage, false, productionCorpUsEast1);
reporter.maintain();
reporter.maintain();
assertEquals("No deployments are detected as failing for a long time initially.", 0, issues.size());
// Advance to where deployment issues should be detected.
tester.clock().advance(maxFailureAge.plus(Duration.ofDays(1)));
reporter.maintain();
reporter.maintain();
assertTrue("One issue is produced for app1.", issues.isOpenFor(app1.id()));
assertFalse("No issues are produced for app2.", issues.isOpenFor(app2.id()));
assertTrue("One issue is produced for app3.", issues.isOpenFor(app3.id()));
// app3 closes their issue prematurely; see that it is refiled.
issues.closeFor(app3.id());
assertFalse("No issue is open for app3.", issues.isOpenFor(app3.id()));
reporter.maintain();
reporter.maintain();
assertTrue("Issue is re-filed for app3.", issues.isOpenFor(app3.id()));
// Some time passes; tenant1 leaves her issue unattended, while tenant3 starts work and updates the issue.
tester.clock().advance(maxInactivity.plus(maxFailureAge));
issues.touchFor(app3.id());
reporter.maintain();
reporter.maintain();
assertEquals("The issue for app1 is escalated once.", 1, issues.escalationLevelFor(app1.id()));
// app3 fixes their problems, but the ticket for app3 is left open; see the resolved ticket is not escalated when another escalation period has passed.
tester.deployAndNotify(app3, applicationPackage, true, productionCorpUsEast1);
tester.clock().advance(maxInactivity.plus(Duration.ofDays(1)));
reporter.maintain();
reporter.maintain();
assertFalse("We no longer have a platform issue.", issues.platformIssue());
assertEquals("The issue for app1 is escalated once more.", 2, issues.escalationLevelFor(app1.id()));
assertEquals("The issue for app3 is not escalated.", 0, issues.escalationLevelFor(app3.id()));
// app3 now has a new failure past max failure age; see that a new issue is filed.
tester.jobCompletion(component).application(app3).nextBuildNumber().uploadArtifact(applicationPackage).submit();
tester.deployAndNotify(app3, applicationPackage, false, systemTest);
tester.clock().advance(maxInactivity.plus(maxFailureAge));
reporter.maintain();
reporter.maintain();
assertTrue("A new issue is filed for app3.", issues.isOpenFor(app3.id()));
// Bump system version to 5.2 to upgrade canary app2.
Version version = Version.fromString("5.2");
tester.updateVersionStatus(version);
assertEquals(version, tester.controller().versionStatus().systemVersion().get().versionNumber());
tester.upgrader().maintain();
tester.readyJobTrigger().maintain();
tester.completeUpgradeWithError(app2, version, canaryPackage, systemTest);
tester.updateVersionStatus(version);
assertEquals(VespaVersion.Confidence.broken, tester.controller().versionStatus().systemVersion().get().confidence());
assertFalse("We have no platform issues initially.", issues.platformIssue());
reporter.maintain();
reporter.maintain();
assertFalse("We have no platform issue before the grace period is out for the failing canary.", issues.platformIssue());
tester.clock().advance(upgradeGracePeriod.plus(upgradeGracePeriod));
reporter.maintain();
reporter.maintain();
assertTrue("We get a platform issue when confidence is broken", issues.platformIssue());
assertFalse("No deployment issue is filed for app2, which has a version upgrade failure.", issues.isOpenFor(app2.id()));
}
use of com.yahoo.vespa.hosted.controller.Application in project vespa by vespa-engine.
the class DnsMaintainerTest method removes_record_for_unassigned_rotation.
@Test
public void removes_record_for_unassigned_rotation() {
DeploymentTester tester = new DeploymentTester();
Application application = tester.createApplication("app1", "tenant1", 1, 1L);
DnsMaintainer dnsMaintainer = new DnsMaintainer(tester.controller(), Duration.ofHours(12), new JobControl(new MockCuratorDb()), tester.controllerTester().nameService());
ApplicationPackage applicationPackage = new ApplicationPackageBuilder().environment(Environment.prod).globalServiceId("foo").region("us-west-1").region("us-central-1").build();
// Deploy application
tester.deployCompletely(application, applicationPackage);
assertEquals(2, tester.controllerTester().nameService().records().size());
Optional<Record> record = tester.controllerTester().nameService().findRecord(Record.Type.CNAME, RecordName.from("app1--tenant1.global.vespa.yahooapis.com"));
assertTrue(record.isPresent());
assertEquals("app1--tenant1.global.vespa.yahooapis.com", record.get().name().asString());
assertEquals("rotation-fqdn-01.", record.get().data().asString());
record = tester.controllerTester().nameService().findRecord(Record.Type.CNAME, RecordName.from("app1.tenant1.global.vespa.yahooapis.com"));
assertTrue(record.isPresent());
assertEquals("app1.tenant1.global.vespa.yahooapis.com", record.get().name().asString());
assertEquals("rotation-fqdn-01.", record.get().data().asString());
// DnsMaintainer does nothing
dnsMaintainer.maintain();
assertTrue("DNS record is not removed", tester.controllerTester().nameService().findRecord(Record.Type.CNAME, RecordName.from("app1--tenant1.global.vespa.yahooapis.com")).isPresent());
assertTrue("DNS record is not removed", tester.controllerTester().nameService().findRecord(Record.Type.CNAME, RecordName.from("app1.tenant1.global.vespa.yahooapis.com")).isPresent());
// Remove application
applicationPackage = new ApplicationPackageBuilder().environment(Environment.prod).allow(ValidationId.deploymentRemoval).build();
tester.jobCompletion(component).application(application).nextBuildNumber().uploadArtifact(applicationPackage).submit();
tester.deployAndNotify(application, applicationPackage, true, systemTest);
tester.applications().deactivate(application, ZoneId.from(Environment.test, RegionName.from("us-east-1")));
tester.applications().deactivate(application, ZoneId.from(Environment.staging, RegionName.from("us-east-3")));
tester.applications().deleteApplication(application.id(), Optional.of(new NToken("ntoken")));
// DnsMaintainer removes records
dnsMaintainer.maintain();
assertFalse("DNS record removed", tester.controllerTester().nameService().findRecord(Record.Type.CNAME, RecordName.from("app1--tenant1.global.vespa.yahooapis.com")).isPresent());
dnsMaintainer.maintain();
assertFalse("DNS record removed", tester.controllerTester().nameService().findRecord(Record.Type.CNAME, RecordName.from("app1.tenant1.global.vespa.yahooapis.com")).isPresent());
}
use of com.yahoo.vespa.hosted.controller.Application in project vespa by vespa-engine.
the class DeploymentTester method completeDeployment.
private void completeDeployment(Application application, ApplicationPackage applicationPackage, Optional<JobType> failOnJob, boolean includingProductionZones) {
DeploymentOrder order = new DeploymentOrder(controller());
List<JobType> jobs = order.jobsFrom(applicationPackage.deploymentSpec());
if (!includingProductionZones)
jobs = jobs.stream().filter(job -> !job.isProduction()).collect(Collectors.toList());
for (JobType job : jobs) {
boolean failJob = failOnJob.map(j -> j.equals(job)).orElse(false);
deployAndNotify(application, applicationPackage, !failJob, false, job);
if (failJob) {
break;
}
}
if (failOnJob.isPresent()) {
assertTrue(applications().require(application.id()).change().isPresent());
assertTrue(applications().require(application.id()).deploymentJobs().hasFailures());
} else if (includingProductionZones) {
assertFalse(applications().require(application.id()).change().isPresent());
} else {
assertTrue(applications().require(application.id()).change().isPresent());
}
}
Aggregations