All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.yahoo.vespa.hosted.controller.api.integration.stubs.LoggingDeploymentIssues Maven / Gradle / Ivy

There is a newer version: 8.253.3
Show newest version
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

package com.yahoo.vespa.hosted.controller.api.integration.stubs;

import com.yahoo.component.annotation.Inject;
import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.vespa.hosted.controller.api.integration.organization.AccountId;
import com.yahoo.vespa.hosted.controller.api.integration.organization.Contact;
import com.yahoo.vespa.hosted.controller.api.integration.organization.DeploymentIssues;
import com.yahoo.vespa.hosted.controller.api.integration.organization.IssueId;
import com.yahoo.vespa.hosted.controller.api.integration.organization.User;

import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Logger;

/**
 * A memory backed implementation of the Issues API which logs changes and does nothing else.
 * 
 * @author bratseth
 * @author jonmv
 */
public class LoggingDeploymentIssues implements DeploymentIssues {

    private static final Logger log = Logger.getLogger(LoggingDeploymentIssues.class.getName());
    
    /** Whether the platform is currently broken. */
    protected final AtomicBoolean platformIssue = new AtomicBoolean(false);
    /** Last updates for each issue -- used to determine if issues are already logged and when to escalate. */
    protected final Map issueUpdates = new HashMap<>();

    /** Used to fabricate unique issue ids. */
    private final AtomicLong issueIdSequence = new AtomicLong(0);

    private final Clock clock;

    @SuppressWarnings("unused") // Created by dependency injection.
    @Inject
    public LoggingDeploymentIssues() {
        this(Clock.systemUTC());
    }

    protected LoggingDeploymentIssues(Clock clock) {
        this.clock = clock;
    }

    @Override
    public IssueId fileUnlessOpen(Optional issueId, ApplicationId applicationId, AccountId assigneeId, User assignee, Contact contact) {
        return fileUnlessPresent(issueId, applicationId);
    }

    @Override
    public IssueId fileUnlessOpen(Collection applicationIds, Version version) {
        if ( ! platformIssue.get())
            log.info("These applications are all failing deployment to version " + version + ":\n" + applicationIds);

        platformIssue.set(true);
        return null;
    }

    @Override
    public void escalateIfInactive(IssueId issueId, Duration maxInactivity, Optional contact) {
        if (issueUpdates.containsKey(issueId) && issueUpdates.get(issueId).isBefore(clock.instant().minus(maxInactivity)))
            escalateIssue(issueId);
    }

    protected void escalateIssue(IssueId issueId) {
        issueUpdates.put(issueId, clock.instant());
        log.info("Deployment issue " + issueId + " should be escalated.");
    }

    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;
    }

    private IssueId fileUnlessPresent(Optional issueId, ApplicationId applicationId) {
        platformIssue.set(false);
        return issueId.filter(issueUpdates::containsKey).orElseGet(() -> fileIssue(applicationId));
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy