use of com.yahoo.vespa.hosted.controller.api.identifiers.TenantId in project vespa by vespa-engine.
the class ApplicationController method deleteApplication.
/**
* Deletes the the given application. All known instances of the applications will be deleted,
* including PR instances.
*
* @throws IllegalArgumentException if the application has deployments or the caller is not authorized
* @throws NotExistsException if no instances of the application exist
*/
public void deleteApplication(ApplicationId applicationId, Optional<NToken> token) {
// Find all instances of the application
List<ApplicationId> instances = controller.applications().asList(applicationId.tenant()).stream().map(Application::id).filter(id -> id.application().equals(applicationId.application()) && id.tenant().equals(applicationId.tenant())).collect(Collectors.toList());
if (instances.isEmpty()) {
throw new NotExistsException("Could not delete application '" + applicationId + "': Application not found");
}
// TODO: Make this one transaction when database is moved to ZooKeeper
instances.forEach(id -> lockOrThrow(id, application -> {
if (!application.deployments().isEmpty())
throw new IllegalArgumentException("Could not delete '" + application + "': It has active deployments");
Tenant tenant = controller.tenants().tenant(new TenantId(id.tenant().value())).get();
if (tenant.isAthensTenant() && !token.isPresent())
throw new IllegalArgumentException("Could not delete '" + application + "': No NToken provided");
// Only delete in Athenz once
if (id.instance().isDefault() && tenant.isAthensTenant()) {
zmsClientFactory.createZmsClientWithAuthorizedServiceToken(token.get()).deleteApplication(tenant.getAthensDomain().get(), new com.yahoo.vespa.hosted.controller.api.identifiers.ApplicationId(id.application().value()));
}
db.deleteApplication(id);
log.info("Deleted " + application);
}));
}
use of com.yahoo.vespa.hosted.controller.api.identifiers.TenantId in project vespa by vespa-engine.
the class DeploymentTriggerTest method testHandleMultipleNotificationsFromLastJob.
@Test
public void testHandleMultipleNotificationsFromLastJob() {
DeploymentTester tester = new DeploymentTester();
DeploymentQueue deploymentQueue = tester.deploymentQueue();
TenantId tenant = tester.controllerTester().createTenant("tenant1", "domain1", 1L);
Application application = tester.controllerTester().createApplication(tenant, "app1", "default", 1L);
ApplicationPackage applicationPackage = new ApplicationPackageBuilder().environment(Environment.prod).region("corp-us-east-1").build();
// Component job finishes
tester.jobCompletion(component).application(application).uploadArtifact(applicationPackage).submit();
// Application is deployed to all test environments and declared zones
tester.deployAndNotify(application, applicationPackage, true, JobType.systemTest);
tester.deployAndNotify(application, applicationPackage, true, JobType.stagingTest);
tester.deployAndNotify(application, applicationPackage, true, JobType.productionCorpUsEast1);
// Extra notification for last job
tester.jobCompletion(JobType.productionCorpUsEast1).application(application).submit();
assertFalse("Change has been deployed", tester.applications().require(application.id()).change().isPresent());
assertTrue("All jobs consumed", deploymentQueue.jobs().isEmpty());
}
use of com.yahoo.vespa.hosted.controller.api.identifiers.TenantId in project vespa by vespa-engine.
the class DeploymentTriggerTest method testSuccessfulDeploymentApplicationPackageChanged.
@Test
public void testSuccessfulDeploymentApplicationPackageChanged() {
DeploymentTester tester = new DeploymentTester();
DeploymentQueue deploymentQueue = tester.deploymentQueue();
TenantId tenant = tester.controllerTester().createTenant("tenant1", "domain1", 1L);
Application application = tester.controllerTester().createApplication(tenant, "app1", "default", 1L);
ApplicationPackage previousApplicationPackage = new ApplicationPackageBuilder().environment(Environment.prod).region("corp-us-east-1").region("us-central-1").region("us-west-1").build();
ApplicationPackage newApplicationPackage = new ApplicationPackageBuilder().environment(Environment.prod).region("corp-us-east-1").region("us-central-1").region("us-west-1").region("eu-west-1").build();
// Component job finishes
tester.jobCompletion(component).application(application).uploadArtifact(newApplicationPackage).submit();
// Application is deployed to all test environments and declared zones
tester.deployAndNotify(application, newApplicationPackage, true, JobType.systemTest);
tester.deploy(JobType.stagingTest, application, previousApplicationPackage, true);
tester.deployAndNotify(application, newApplicationPackage, true, JobType.stagingTest);
tester.deployAndNotify(application, newApplicationPackage, true, JobType.productionCorpUsEast1);
tester.deployAndNotify(application, newApplicationPackage, true, JobType.productionUsCentral1);
tester.deployAndNotify(application, newApplicationPackage, true, JobType.productionUsWest1);
tester.deployAndNotify(application, newApplicationPackage, true, JobType.productionEuWest1);
assertTrue("All jobs consumed", deploymentQueue.jobs().isEmpty());
}
use of com.yahoo.vespa.hosted.controller.api.identifiers.TenantId in project vespa by vespa-engine.
the class ApplicationOwnershipConfirmerTest method testConfirmation.
@Test
public void testConfirmation() {
TenantId property = tester.controllerTester().createTenant("property", "domain", 1L);
tester.createAndDeploy(property, "application", 1, "default");
Supplier<Application> propertyApp = () -> tester.controller().applications().require(ApplicationId.from("property", "application", "default"));
TenantId user = new TenantId("by-user");
tester.controller().tenants().createUserTenant("user");
tester.createAndDeploy(user, "application", 2, "default");
Supplier<Application> userApp = () -> tester.controller().applications().require(ApplicationId.from("by-user", "application", "default"));
assertFalse("No issue is initially stored for a new application.", propertyApp.get().ownershipIssueId().isPresent());
assertFalse("No issue is initially stored for a new application.", userApp.get().ownershipIssueId().isPresent());
assertFalse("No escalation has been attempted for a new application", issues.escalatedForProperty || issues.escalatedForUser);
// Set response from the issue mock, which will be obtained by the maintainer on issue filing.
Optional<IssueId> issueId = Optional.of(IssueId.from("1"));
issues.response = issueId;
confirmer.maintain();
confirmer.maintain();
assertEquals("Confirmation issue has been filed for property owned application.", issueId, propertyApp.get().ownershipIssueId());
assertEquals("Confirmation issue has been filed for user owned application.", issueId, userApp.get().ownershipIssueId());
assertTrue("Both applications have had their responses ensured.", issues.escalatedForProperty && issues.escalatedForUser);
// No new issue is created, so return empty now.
issues.response = Optional.empty();
confirmer.maintain();
confirmer.maintain();
assertEquals("Confirmation issue reference is not updated when no issue id is returned.", issueId, propertyApp.get().ownershipIssueId());
assertEquals("Confirmation issue reference is not updated when no issue id is returned.", issueId, userApp.get().ownershipIssueId());
// The user deletes all production deployments — see that the issue is forgotten.
assertEquals("Confirmation issue for user is sitll open.", issueId, userApp.get().ownershipIssueId());
tester.controller().applications().deactivate(userApp.get(), userApp.get().productionDeployments().keySet().stream().findAny().get());
tester.controller().applications().deactivate(userApp.get(), userApp.get().productionDeployments().keySet().stream().findAny().get());
assertTrue("No production deployments are listed for user.", userApp.get().productionDeployments().isEmpty());
confirmer.maintain();
confirmer.maintain();
// Time has passed, and a new confirmation issue is in order for the property which is still in production.
Optional<IssueId> issueId2 = Optional.of(IssueId.from("2"));
issues.response = issueId2;
confirmer.maintain();
confirmer.maintain();
assertEquals("A new confirmation issue id is stored when something is returned to the maintainer.", issueId2, propertyApp.get().ownershipIssueId());
assertEquals("Confirmation issue for application without production deployments has not been filed.", issueId, userApp.get().ownershipIssueId());
}
use of com.yahoo.vespa.hosted.controller.api.identifiers.TenantId in project vespa by vespa-engine.
the class ConfigServerClientMock method prepare.
@Override
public PreparedApplication prepare(DeploymentId deployment, DeployOptions deployOptions, Set<String> rotationCnames, Set<String> rotationNames, byte[] content) {
lastPrepareVersion = deployOptions.vespaVersion.map(Version::new).orElse(null);
if (prepareException != null) {
RuntimeException prepareException = this.prepareException;
this.prepareException = null;
throw prepareException;
}
applicationActivated.put(deployment.applicationId(), false);
applicationInstances.put(deployment.applicationId(), UUID.randomUUID() + ":4080");
return new PreparedApplication() {
@Override
public void activate() {
applicationActivated.put(deployment.applicationId(), true);
}
@Override
public List<Log> messages() {
Log warning = new Log();
warning.level = "WARNING";
warning.time = 1;
warning.message = "The warning";
Log info = new Log();
info.level = "INFO";
info.time = 2;
info.message = "The info";
return Arrays.asList(warning, info);
}
@Override
public PrepareResponse prepareResponse() {
PrepareResponse prepareResponse = new PrepareResponse();
prepareResponse.message = "foo";
prepareResponse.configChangeActions = new ConfigChangeActions(Collections.emptyList(), Collections.emptyList());
prepareResponse.tenant = new TenantId("tenant");
return prepareResponse;
}
};
}
Aggregations