diff options
author | jonmv <venstad@gmail.com> | 2022-04-11 21:34:42 +0200 |
---|---|---|
committer | jonmv <venstad@gmail.com> | 2022-04-11 21:38:00 +0200 |
commit | 683c74c6baa349be93c3d878638214458b8e2bb4 (patch) | |
tree | 6fca498336b09a95a7d897b614e5f79567d4a6b0 /controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api | |
parent | 27af44b14a95177126ec4c1cd3deaf9a1fb4c6e5 (diff) |
Use RevisionId instead of ApplicationVersion as keys
Diffstat (limited to 'controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api')
3 files changed, 55 insertions, 80 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/ApplicationStore.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/ApplicationStore.java index fef95155440..c4db0de539e 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/ApplicationStore.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/ApplicationStore.java @@ -16,8 +16,8 @@ import java.util.Optional; */ public interface ApplicationStore { - /** Returns the tenant application package of the given version. */ - byte[] get(DeploymentId deploymentId, ApplicationVersion applicationVersion); + /** Returns the application package of the given revision. */ + byte[] get(DeploymentId deploymentId, RevisionId revisionId); /** Returns the application package diff, compared to the previous build, for the given tenant, application and build number */ Optional<byte[]> getDiff(TenantName tenantName, ApplicationName applicationName, long buildNumber); @@ -34,16 +34,16 @@ public interface ApplicationStore { } /** Stores the given tenant application and test packages of the given revision, and diff since previous version. */ - void put(TenantName tenant, ApplicationName application, ApplicationVersion applicationVersion, byte[] applicationPackage, byte[] testPackage, byte[] diff); + void put(TenantName tenant, ApplicationName application, RevisionId revision, byte[] applicationPackage, byte[] testPackage, byte[] diff); - /** Removes application and test packages older than the given version, for the given application. */ - void prune(TenantName tenant, ApplicationName application, ApplicationVersion olderThanVersion); + /** Removes application and test packages older than the given revision, for the given application. */ + void prune(TenantName tenant, ApplicationName application, RevisionId revision); /** Removes all application and test packages for the given application, including any development package. */ void removeAll(TenantName tenant, ApplicationName application); - /** Returns the tester application package of the given version. Does NOT contain the services.xml. */ - byte[] getTester(TenantName tenant, ApplicationName application, ApplicationVersion applicationVersion); + /** Returns the tester application package of the given revision. Does NOT contain the services.xml. */ + byte[] getTester(TenantName tenant, ApplicationName application, RevisionId revision); /** Returns the application package diff, compared to the previous build, for the given deployment and build number */ Optional<byte[]> getDevDiff(DeploymentId deploymentId, long buildNumber); @@ -51,8 +51,8 @@ public interface ApplicationStore { /** Removes diffs for dev packages before the given build number */ void pruneDevDiffs(DeploymentId deploymentId, long beforeBuildNumber); - /** Stores the given application package as the development package for the given deployment and version and diff since previous version. */ - void putDev(DeploymentId deploymentId, ApplicationVersion version, byte[] applicationPackage, byte[] diff); + /** Stores the given application package as the development package for the given deployment and revision and diff since previous version. */ + void putDev(DeploymentId deploymentId, RevisionId revision, byte[] applicationPackage, byte[] diff); /** Stores the given application metadata with the current time as part of the path. */ void putMeta(TenantName tenant, ApplicationName application, Instant now, byte[] metaZip); diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/ApplicationVersion.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/ApplicationVersion.java index 29d7005ddc7..445ca0435d4 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/ApplicationVersion.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/ApplicationVersion.java @@ -20,36 +20,26 @@ import static ai.vespa.validation.Validation.requireAtLeast; */ public class ApplicationVersion implements Comparable<ApplicationVersion> { - /** Should not be used, but may still exist in serialized data :S */ - public static final ApplicationVersion unknown = new ApplicationVersion(Optional.empty(), OptionalLong.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), true, Optional.empty(), false, true, Optional.empty(), 0); - // This never changes and is only used to create a valid semantic version number, as required by application bundles private static final String majorVersion = "1.0"; + private final RevisionId id; private final Optional<SourceRevision> source; private final Optional<String> authorEmail; - private final OptionalLong buildNumber; private final Optional<Version> compileVersion; private final Optional<Instant> buildTime; private final Optional<String> sourceUrl; private final Optional<String> commit; - private final boolean deployedDirectly; private final Optional<String> bundleHash; private final boolean hasPackage; private final boolean shouldSkip; private final Optional<String> description; private final int risk; - public ApplicationVersion(Optional<SourceRevision> source, OptionalLong buildNumber, Optional<String> authorEmail, + public ApplicationVersion(RevisionId id, Optional<SourceRevision> source, Optional<String> authorEmail, Optional<Version> compileVersion, Optional<Instant> buildTime, Optional<String> sourceUrl, - Optional<String> commit, boolean deployedDirectly, Optional<String> bundleHash, + Optional<String> commit, Optional<String> bundleHash, boolean hasPackage, boolean shouldSkip, Optional<String> description, int risk) { - if (buildNumber.isEmpty() && ( source.isPresent() || authorEmail.isPresent() || compileVersion.isPresent() - || buildTime.isPresent() || sourceUrl.isPresent() || commit.isPresent())) - throw new IllegalArgumentException("Build number must be present if any other attribute is"); - - if (buildNumber.isPresent() && buildNumber.getAsLong() <= 0) - throw new IllegalArgumentException("Build number must be > 0"); if (commit.isPresent() && commit.get().length() > 128) throw new IllegalArgumentException("Commit may not be longer than 128 characters"); @@ -60,14 +50,13 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> { if (compileVersion.isPresent() && compileVersion.get().equals(Version.emptyVersion)) throw new IllegalArgumentException("The empty version is not a legal compile version."); + this.id = id; this.source = source; - this.buildNumber = buildNumber; this.authorEmail = authorEmail; this.compileVersion = compileVersion; this.buildTime = buildTime; this.sourceUrl = Objects.requireNonNull(sourceUrl, "sourceUrl cannot be null"); this.commit = Objects.requireNonNull(commit, "commit cannot be null"); - this.deployedDirectly = deployedDirectly; this.bundleHash = bundleHash; this.hasPackage = hasPackage; this.shouldSkip = shouldSkip; @@ -76,44 +65,39 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> { } public RevisionId id() { - return isDeployedDirectly() ? RevisionId.forDevelopment(buildNumber().orElse(0)) - : RevisionId.forProduction(buildNumber().orElseThrow()); + return id; } /** Create an application package version from a completed build, without an author email */ - public static ApplicationVersion from(SourceRevision source, long buildNumber) { - return new ApplicationVersion(Optional.of(source), OptionalLong.of(buildNumber), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), false, Optional.empty(), true, false, Optional.empty(), 0); + public static ApplicationVersion from(RevisionId id, SourceRevision source) { + return new ApplicationVersion(id, Optional.of(source), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), true, false, Optional.empty(), 0); } /** Creates a version from a completed build, an author email, and build metadata. */ - public static ApplicationVersion from(SourceRevision source, long buildNumber, String authorEmail, - Version compileVersion, Instant buildTime) { - return new ApplicationVersion(Optional.of(source), OptionalLong.of(buildNumber), Optional.of(authorEmail), Optional.of(compileVersion), Optional.of(buildTime), Optional.empty(), Optional.empty(), false, Optional.empty(), true, false, Optional.empty(), 0); + public static ApplicationVersion from(RevisionId id, SourceRevision source, String authorEmail, Version compileVersion, Instant buildTime) { + return new ApplicationVersion(id, Optional.of(source), Optional.of(authorEmail), Optional.of(compileVersion), Optional.of(buildTime), Optional.empty(), Optional.empty(), Optional.empty(), true, false, Optional.empty(), 0); } /** Creates a minimal version for a development build. */ - public static ApplicationVersion forDevelopment(long buildNumber, Optional<Version> compileVersion) { - return new ApplicationVersion(Optional.empty(), OptionalLong.of(buildNumber), Optional.empty(), compileVersion, Optional.empty(), Optional.empty(), Optional.empty(), true, Optional.empty(), true, false, Optional.empty(), 0); + public static ApplicationVersion forDevelopment(RevisionId id, Optional<Version> compileVersion) { + return new ApplicationVersion(id, Optional.empty(), Optional.empty(), compileVersion, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), true, false, Optional.empty(), 0); } /** Creates a version from a completed build, an author email, and build metadata. */ - public static ApplicationVersion forProduction(Optional<SourceRevision> source, long buildNumber, Optional<String> authorEmail, - Optional<Version> compileVersion, Optional<Instant> buildTime, - Optional<String> sourceUrl, Optional<String> commit, boolean deployedDirectly, - Optional<String> bundleHash, Optional<String> description, int risk) { - return new ApplicationVersion(source, OptionalLong.of(buildNumber), authorEmail, compileVersion, buildTime, - sourceUrl, commit, deployedDirectly, bundleHash, true, false, description, risk); + public static ApplicationVersion forProduction(RevisionId id, Optional<SourceRevision> source, Optional<String> authorEmail, + Optional<Version> compileVersion, Optional<Instant> buildTime, Optional<String> sourceUrl, + Optional<String> commit, Optional<String> bundleHash, Optional<String> description, int risk) { + return new ApplicationVersion(id, source, authorEmail, compileVersion, buildTime, + sourceUrl, commit, bundleHash, true, false, description, risk); } /** Returns a unique identifier for this version or "unknown" if version is not known */ // TODO jonmv: kill public String stringId() { - if (isUnknown()) return "unknown"; - return source.map(SourceRevision::commit).map(ApplicationVersion::abbreviateCommit) .or(this::commit) - .map(commit -> String.format("%s.%d-%s", majorVersion, buildNumber.getAsLong(), commit)) - .orElseGet(() -> majorVersion + "." + buildNumber.getAsLong()); + .map(commit -> String.format("%s.%d-%s", majorVersion, buildNumber().getAsLong(), commit)) + .orElseGet(() -> majorVersion + "." + buildNumber().getAsLong()); } /** @@ -123,7 +107,7 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> { public Optional<SourceRevision> source() { return source; } /** Returns the build number that built this version */ - public OptionalLong buildNumber() { return buildNumber; } + public OptionalLong buildNumber() { return OptionalLong.of(id.number()); } /** Returns the email of the author of commit of this version, if known */ public Optional<String> authorEmail() { return authorEmail; } @@ -154,19 +138,14 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> { /** Returns the commit name of this application version. */ public Optional<String> commit() { return commit.or(() -> source.map(SourceRevision::commit)); } - /** Returns whether this is unknown */ - public boolean isUnknown() { - return this.equals(unknown); - } - /** Returns whether the application package for this version was deployed directly to zone */ public boolean isDeployedDirectly() { - return deployedDirectly; + return ! id.isProduction(); } /** Returns a copy of this without a package stored. */ public ApplicationVersion withoutPackage() { - return new ApplicationVersion(source, buildNumber, authorEmail, compileVersion, buildTime, sourceUrl, commit, deployedDirectly, bundleHash, false, shouldSkip, description, risk); + return new ApplicationVersion(id, source, authorEmail, compileVersion, buildTime, sourceUrl, commit, bundleHash, false, shouldSkip, description, risk); } /** Whether we still have the package for this revision. */ @@ -176,7 +155,7 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> { /** Returns a copy of this which will not be rolled out to production. */ public ApplicationVersion skipped() { - return new ApplicationVersion(source, buildNumber, authorEmail, compileVersion, buildTime, sourceUrl, commit, deployedDirectly, bundleHash, hasPackage, true, description, risk); + return new ApplicationVersion(id, source, authorEmail, compileVersion, buildTime, sourceUrl, commit, bundleHash, hasPackage, true, description, risk); } /** Whether we still have the package for this revision. */ @@ -204,23 +183,21 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> { if (this == o) return true; if ( ! (o instanceof ApplicationVersion)) return false; ApplicationVersion that = (ApplicationVersion) o; - return Objects.equals(buildNumber, that.buildNumber) - && Objects.equals(commit(), that.commit()) - && deployedDirectly == that.deployedDirectly; + return id.equals(that.id); } @Override public int hashCode() { - return Objects.hash(buildNumber, commit(), deployedDirectly); + return id.hashCode(); } @Override public String toString() { - return "Application package version: " + stringId() - + source.map(s -> ", " + s.toString()).orElse("") - + authorEmail.map(e -> ", by " + e).orElse("") - + compileVersion.map(v -> ", built against " + v).orElse("") - + buildTime.map(t -> " at " + t).orElse("") ; + return id + + source.map(s -> ", " + s).orElse("") + + authorEmail.map(e -> ", by " + e).orElse("") + + compileVersion.map(v -> ", built against " + v).orElse("") + + buildTime.map(t -> " at " + t).orElse("") ; } /** Abbreviate given commit hash to 9 characters */ @@ -230,13 +207,7 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> { @Override public int compareTo(ApplicationVersion o) { - if (buildNumber().isEmpty() || o.buildNumber().isEmpty()) - return Boolean.compare(buildNumber().isPresent(), o.buildNumber.isPresent()); // Unknown version sorts first - - if (deployedDirectly != o.deployedDirectly) - return Boolean.compare( ! deployedDirectly, ! o.deployedDirectly); // Directly deployed versions sort first - - return Long.compare(buildNumber().getAsLong(), o.buildNumber().getAsLong()); + return id.compareTo(o.id); } } diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/RevisionId.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/RevisionId.java index 1e9f412d4da..2ab419b5388 100644 --- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/RevisionId.java +++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/deployment/RevisionId.java @@ -12,48 +12,52 @@ import static ai.vespa.validation.Validation.requireAtLeast; public class RevisionId implements Comparable<RevisionId> { private final long number; - private final boolean production; + private final JobId job; - private RevisionId(long number, boolean production) { + private RevisionId(long number, JobId job) { this.number = number; - this.production = production; + this.job = job; } public static RevisionId forProduction(long number) { - return new RevisionId(requireAtLeast(number, "build number", 1L), true); + return new RevisionId(requireAtLeast(number, "build number", 1L), null); } - public static RevisionId forDevelopment(long number) { - return new RevisionId(requireAtLeast(number, "build number", 0L), false); + public static RevisionId forDevelopment(long number, JobId job) { + return new RevisionId(requireAtLeast(number, "build number", 0L), job); } public long number() { return number; } - public boolean isProduction() { return production; } + public boolean isProduction() { return job == null; } + + /** Returns the job for this, if a development revision, or throws if this is a production revision. */ + public JobId job() { return Objects.requireNonNull(job, "production revisions have no associated job"); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; RevisionId that = (RevisionId) o; - return number == that.number && production == that.production; + return number == that.number && Objects.equals(job, that.job); } @Override public int hashCode() { - return Objects.hash(number, production); + return Objects.hash(number, job); } /** Unknown, manual builds sort first, then known manual builds, then production builds, by increasing build number */ @Override public int compareTo(RevisionId o) { - return production != o.production ? Boolean.compare(production, o.production) - : Long.compare(number, o.number); + return isProduction() != o.isProduction() ? Boolean.compare(isProduction(), o.isProduction()) + : Long.compare(number, o.number); } @Override public String toString() { - return (production ? "prod" : "dev") + " build " + number; + return isProduction() ? "build " + number + : "dev build " + number + " for " + job.type() + " of " + job.application().instance(); } } |