use of com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId in project vespa by vespa-engine.
the class DeploymentIssueReporter method fileDeploymentIssueFor.
/**
* File an issue for applicationId, if it doesn't already have an open issue associated with it.
*/
private void fileDeploymentIssueFor(ApplicationId applicationId) {
try {
Tenant tenant = ownerOf(applicationId);
Optional<IssueId> ourIssueId = controller().applications().require(applicationId).deploymentJobs().issueId();
IssueId issueId = tenant.tenantType() == TenantType.USER ? deploymentIssues.fileUnlessOpen(ourIssueId, applicationId, userFor(tenant)) : deploymentIssues.fileUnlessOpen(ourIssueId, applicationId, propertyIdFor(tenant));
store(applicationId, issueId);
} catch (RuntimeException e) {
// Catch errors due to wrong data in the controller, or issues client timeout.
log.log(Level.WARNING, "Exception caught when attempting to file an issue for " + applicationId, e);
}
}
use of com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId in project vespa by vespa-engine.
the class ApplicationSerializer method fromSlime.
// ------------------ Deserialization
public Application fromSlime(Slime slime) {
Inspector root = slime.get();
ApplicationId id = ApplicationId.fromSerializedForm(root.field(idField).asString());
DeploymentSpec deploymentSpec = DeploymentSpec.fromXml(root.field(deploymentSpecField).asString(), false);
ValidationOverrides validationOverrides = ValidationOverrides.fromXml(root.field(validationOverridesField).asString());
List<Deployment> deployments = deploymentsFromSlime(root.field(deploymentsField));
DeploymentJobs deploymentJobs = deploymentJobsFromSlime(root.field(deploymentJobsField));
Change deploying = changeFromSlime(root.field(deployingField));
Change outstandingChange = changeFromSlime(root.field(outstandingChangeField));
Optional<IssueId> ownershipIssueId = optionalString(root.field(ownershipIssueIdField)).map(IssueId::from);
ApplicationMetrics metrics = new ApplicationMetrics(root.field(queryQualityField).asDouble(), root.field(writeQualityField).asDouble());
Optional<RotationId> rotation = rotationFromSlime(root.field(rotationField));
return new Application(id, deploymentSpec, validationOverrides, deployments, deploymentJobs, deploying, outstandingChange, ownershipIssueId, metrics, rotation);
}
use of com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId in project vespa by vespa-engine.
the class ApplicationOwnershipConfirmer method confirmApplicationOwnerships.
/**
* File an ownership issue with the owners of all applications we know about.
*/
private void confirmApplicationOwnerships() {
ApplicationList.from(controller().applications().asList()).notPullRequest().hasProductionDeployment().asList().forEach(application -> {
try {
Tenant tenant = ownerOf(application.id());
Optional<IssueId> ourIssueId = application.ownershipIssueId();
ourIssueId = tenant.tenantType() == TenantType.USER ? ownershipIssues.confirmOwnership(ourIssueId, application.id(), userFor(tenant)) : ownershipIssues.confirmOwnership(ourIssueId, application.id(), propertyIdFor(tenant));
ourIssueId.ifPresent(issueId -> store(issueId, application.id()));
} catch (RuntimeException e) {
// Catch errors due to wrong data in the controller, or issues client timeout.
log.log(Level.WARNING, "Exception caught when attempting to file an issue for " + application.id(), e);
}
});
}
use of com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId in project vespa by vespa-engine.
the class LoggingDeploymentIssues method fileIssue.
protected IssueId fileIssue(ApplicationId applicationId) {
IssueId issueId = IssueId.from("" + issueIdSequence.incrementAndGet());
issueUpdates.put(issueId, clock.instant());
log.info("Deployment issue " + issueId + ": " + applicationId + " has failing deployments.");
return issueId;
}
use of com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId 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());
}
Aggregations