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

com.yahoo.vespa.config.server.session.Session Maven / Gradle / Ivy

There is a newer version: 8.441.21
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.config.server.session;

import com.yahoo.component.Version;
import com.yahoo.config.FileReference;
import com.yahoo.config.application.api.ApplicationFile;
import com.yahoo.config.application.api.ApplicationMetaData;
import com.yahoo.config.application.api.ApplicationPackage;
import com.yahoo.config.model.api.Quota;
import com.yahoo.config.model.api.TenantSecretStore;
import com.yahoo.config.provision.AllocatedHosts;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.AthenzDomain;
import com.yahoo.config.provision.CloudAccount;
import com.yahoo.config.provision.DataplaneToken;
import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.TenantName;
import com.yahoo.path.Path;
import com.yahoo.transaction.Transaction;
import com.yahoo.vespa.config.server.application.ApplicationVersions;
import com.yahoo.vespa.config.server.tenant.TenantRepository;
import java.security.cert.X509Certificate;
import java.time.Instant;
import java.util.List;
import java.util.Optional;

/**
 * A session represents an instance of an application that can be edited, prepared and activated. This
 * class represents the common stuff between sessions working on the local file
 * system ({@link LocalSession}s) and sessions working on zookeeper ({@link RemoteSession}s).
 *
 * @author Ulf Lilleengen
 * @author hmusum
 */
public abstract class Session implements Comparable  {

    protected final long sessionId;
    protected final TenantName tenant;
    protected final SessionZooKeeperClient sessionZooKeeperClient;
    protected final Optional applicationPackage;

    protected Session(TenantName tenant, long sessionId, SessionZooKeeperClient sessionZooKeeperClient) {
        this(tenant, sessionId, sessionZooKeeperClient, Optional.empty());
    }

    protected Session(TenantName tenant, long sessionId, SessionZooKeeperClient sessionZooKeeperClient,
                      ApplicationPackage applicationPackage) {
        this(tenant, sessionId, sessionZooKeeperClient, Optional.of(applicationPackage));
    }

    private Session(TenantName tenant, long sessionId, SessionZooKeeperClient sessionZooKeeperClient,
                    Optional applicationPackage) {
        this.tenant = tenant;
        this.sessionId = sessionId;
        this.sessionZooKeeperClient = sessionZooKeeperClient;
        this.applicationPackage = applicationPackage;
    }

    public final long getSessionId() { return sessionId; }

    public Session.Status getStatus() {
        return sessionZooKeeperClient.readStatus();
    }

    @Override
    public String toString() {
        return "Session,id=" + sessionId + ",status=" + getStatus();
    }

    public long getActiveSessionAtCreate() {
        return getMetaData().getPreviousActiveGeneration();
    }

    /**
     * The status of this session.
     */
    public enum Status {
        NEW, PREPARE, ACTIVATE, DEACTIVATE, UNKNOWN, DELETE;

        public static Status parse(String data) {
            for (Status status : Status.values()) {
                if (status.name().equals(data)) {
                    return status;
                }
            }
            return Status.NEW;
        }
    }

    public TenantName getTenantName() { return tenant; }

    /**
     * Helper to provide a log message preamble for code dealing with sessions
     * @return log preamble
     */
    public String logPre() {
        Optional applicationId = getOptionalApplicationId();

        // We might not be able to read application id from zookeeper
        // e.g. when the app has been deleted. Use tenant name in that case.
        return applicationId
                .filter(appId -> ! appId.equals(ApplicationId.defaultId()))
                .map(TenantRepository::logPre)
                .orElse(TenantRepository.logPre(getTenantName()));
    }

    public Instant getCreateTime() {
        return sessionZooKeeperClient.readCreateTime();
    }

    public Instant getActivatedTime() {
        return sessionZooKeeperClient.readActivatedTime();
    }

    /** Returns application id read from ZooKeeper. Will throw RuntimeException if not found */
    public ApplicationId getApplicationId() { return sessionZooKeeperClient.readApplicationId(); }

    /** Returns application id read from ZooKeeper. Will return Optional.empty() if not found */
    public Optional getOptionalApplicationId() {
        try {
            return Optional.of(getApplicationId());
        } catch (RuntimeException e) {
            return Optional.empty();
        }
    }

    public Optional getApplicationPackageReference() { return sessionZooKeeperClient.readApplicationPackageReference(); }

    public Optional getDockerImageRepository() { return sessionZooKeeperClient.readDockerImageRepository(); }

    public Version getVespaVersion() { return sessionZooKeeperClient.readVespaVersion(); }

    public Optional getAthenzDomain() { return sessionZooKeeperClient.readAthenzDomain(); }

    public Optional getQuota() { return sessionZooKeeperClient.readQuota(); }

    public AllocatedHosts getAllocatedHosts() {
        return sessionZooKeeperClient.getAllocatedHosts();
    }

    public Transaction createDeactivateTransaction() {
        return createSetStatusTransaction(Status.DEACTIVATE);
    }

    public List getTenantSecretStores() {
        return sessionZooKeeperClient.readTenantSecretStores();
    }

    public List getOperatorCertificates() {
        return sessionZooKeeperClient.readOperatorCertificates();
    }

    public Optional getCloudAccount() {
        return sessionZooKeeperClient.readCloudAccount();
    }

    public List getDataplaneTokens() {
        return sessionZooKeeperClient.readDataplaneTokens();
    }

    public ActivationTriggers getActivationTriggers() {
        return sessionZooKeeperClient.readActivationTriggers();
    }

    public SessionZooKeeperClient getSessionZooKeeperClient() { return sessionZooKeeperClient; }

    private Transaction createSetStatusTransaction(Status status) {
        return sessionZooKeeperClient.createWriteStatusTransaction(status);
    }

    // Note: Assumes monotonically increasing session ids
    public boolean isNewerThan(long sessionId) { return getSessionId() > sessionId; }

    public ApplicationMetaData getMetaData() {
        return applicationPackage.isPresent()
                ? applicationPackage.get().getMetaData()
                : sessionZooKeeperClient.loadApplicationPackage().getMetaData();
    }

    public ApplicationPackage getApplicationPackage() {
        return applicationPackage.orElseThrow(() -> new RuntimeException("No application package found for " + this));
    }

    public ApplicationFile getApplicationFile(Path relativePath, LocalSession.Mode mode) {
        if (mode.equals(Session.Mode.WRITE)) {
            markSessionEdited();
        }
        return getApplicationPackage().getFile(relativePath);
    }

    Optional applicationVersions() { return Optional.empty(); }

    private void markSessionEdited() {
        setStatus(Session.Status.NEW);
    }

    void setStatus(Session.Status newStatus) {
        sessionZooKeeperClient.writeStatus(newStatus);
    }

    @Override
    public int compareTo(Session rhs) {
        Long lhsId = getSessionId();
        Long rhsId = rhs.getSessionId();
        return lhsId.compareTo(rhsId);
    }

    public enum Mode {
        READ, WRITE
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy