diff options
50 files changed, 854 insertions, 441 deletions
diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/MapEvaluationTypeContext.java b/config-model/src/main/java/com/yahoo/searchdefinition/MapEvaluationTypeContext.java index 7c4edd4cdfb..301aa1faa83 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/MapEvaluationTypeContext.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/MapEvaluationTypeContext.java @@ -21,6 +21,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.SortedSet; +import java.util.TreeSet; import java.util.stream.Collectors; /** @@ -42,19 +44,28 @@ public class MapEvaluationTypeContext extends FunctionReferenceContext implement /** For invocation loop detection */ private final Deque<Reference> currentResolutionCallStack; + private final SortedSet<Reference> queryFeaturesNotDeclared; + private boolean tensorsAreUsed; + MapEvaluationTypeContext(Collection<ExpressionFunction> functions, Map<Reference, TensorType> featureTypes) { super(functions); this.featureTypes.putAll(featureTypes); this.currentResolutionCallStack = new ArrayDeque<>(); + this.queryFeaturesNotDeclared = new TreeSet<>(); + tensorsAreUsed = false; } private MapEvaluationTypeContext(Map<String, ExpressionFunction> functions, Map<String, String> bindings, Map<Reference, TensorType> featureTypes, - Deque<Reference> currentResolutionCallStack) { + Deque<Reference> currentResolutionCallStack, + SortedSet<Reference> queryFeaturesNotDeclared, + boolean tensorsAreUsed) { super(functions, bindings); this.featureTypes.putAll(featureTypes); this.currentResolutionCallStack = currentResolutionCallStack; + this.queryFeaturesNotDeclared = queryFeaturesNotDeclared; + this.tensorsAreUsed = tensorsAreUsed; } public void setType(Reference reference, TensorType type) { @@ -63,7 +74,7 @@ public class MapEvaluationTypeContext extends FunctionReferenceContext implement @Override public TensorType getType(String reference) { - throw new UnsupportedOperationException("Not able to parse gereral references from string form"); + throw new UnsupportedOperationException("Not able to parse general references from string form"); } public void forgetResolvedTypes() { @@ -80,6 +91,8 @@ public class MapEvaluationTypeContext extends FunctionReferenceContext implement if (resolvedType == null) return defaultTypeOf(reference); // Don't store fallback to default as we may know more later resolvedTypes.put(reference, resolvedType); + if (resolvedType.rank() > 0) + tensorsAreUsed = true; return resolvedType; } @@ -142,8 +155,10 @@ public class MapEvaluationTypeContext extends FunctionReferenceContext implement public TensorType defaultTypeOf(Reference reference) { if ( ! FeatureNames.isSimpleFeature(reference)) throw new IllegalArgumentException("This can only be called for simple references, not " + reference); - if (reference.name().equals("query")) // we do not require all query features to be declared, only non-doubles + if (reference.name().equals("query")) { // we do not require all query features to be declared, only non-doubles + queryFeaturesNotDeclared.add(reference); return TensorType.empty; + } return null; } @@ -215,9 +230,26 @@ public class MapEvaluationTypeContext extends FunctionReferenceContext implement return Collections.unmodifiableMap(featureTypes); } + /** + * Returns an unmodifiable view of the query features which was requested but for which we have no type info + * (such that they default to TensorType.empty), shared between all instances of this + * involved in resolving a particular rank profile. + */ + public SortedSet<Reference> queryFeaturesNotDeclared() { + return Collections.unmodifiableSortedSet(queryFeaturesNotDeclared); + } + + /** Returns true if any feature across all instances involved in resolving this rank profile resolves to a tensor */ + public boolean tensorsAreUsed() { return tensorsAreUsed; } + @Override public MapEvaluationTypeContext withBindings(Map<String, String> bindings) { - return new MapEvaluationTypeContext(functions(), bindings, featureTypes, currentResolutionCallStack); + return new MapEvaluationTypeContext(functions(), + bindings, + featureTypes, + currentResolutionCallStack, + queryFeaturesNotDeclared, + tensorsAreUsed); } } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java b/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java index 1283da20395..f6aed1e5abc 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/RankProfile.java @@ -755,7 +755,6 @@ public class RankProfile implements Cloneable { * referable from this rank profile. */ public MapEvaluationTypeContext typeContext(QueryProfileRegistry queryProfiles) { - return typeContext(queryProfiles, collectFeatureTypes()); } diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/SearchBuilder.java b/config-model/src/main/java/com/yahoo/searchdefinition/SearchBuilder.java index bf1939e2c3d..949539ff99f 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/SearchBuilder.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/SearchBuilder.java @@ -187,9 +187,8 @@ public class SearchBuilder { * @throws IllegalArgumentException if the given search object has already been processed. */ public String importRawSearch(Search rawSearch) { - if (rawSearch.getName() == null) { + if (rawSearch.getName() == null) throw new IllegalArgumentException("Search has no name."); - } String rawName = rawSearch.getName(); for (Search search : searchList) { if (rawName.equals(search.getName())) { diff --git a/config-model/src/main/java/com/yahoo/searchdefinition/processing/RankingExpressionTypeResolver.java b/config-model/src/main/java/com/yahoo/searchdefinition/processing/RankingExpressionTypeResolver.java index 3d1ef48c9dd..8fad8695e88 100644 --- a/config-model/src/main/java/com/yahoo/searchdefinition/processing/RankingExpressionTypeResolver.java +++ b/config-model/src/main/java/com/yahoo/searchdefinition/processing/RankingExpressionTypeResolver.java @@ -3,6 +3,7 @@ package com.yahoo.searchdefinition.processing; import com.yahoo.config.application.api.DeployLogger; import com.yahoo.search.query.profile.QueryProfileRegistry; +import com.yahoo.searchdefinition.MapEvaluationTypeContext; import com.yahoo.searchdefinition.RankProfile; import com.yahoo.searchdefinition.RankProfileRegistry; import com.yahoo.searchdefinition.Search; @@ -15,6 +16,7 @@ import com.yahoo.tensor.evaluation.TypeContext; import com.yahoo.vespa.model.container.search.QueryProfiles; import java.util.Map; +import java.util.logging.Level; /** * Resolves and assigns types to all functions in a ranking expression, and @@ -59,7 +61,7 @@ public class RankingExpressionTypeResolver extends Processor { * @throws IllegalArgumentException if validate is true and the given rank profile does not produce valid types */ private void resolveTypesIn(RankProfile profile, boolean validate) { - TypeContext<Reference> context = profile.typeContext(queryProfiles); + MapEvaluationTypeContext context = profile.typeContext(queryProfiles); for (Map.Entry<String, RankProfile.RankingExpressionFunction> function : profile.getFunctions().entrySet()) { if (hasUntypedArguments(function.getValue().function())) continue; TensorType type = resolveType(function.getValue().function().getBody(), @@ -72,6 +74,11 @@ public class RankingExpressionTypeResolver extends Processor { profile.getSummaryFeatures().forEach(f -> resolveType(f, "summary feature " + f, context)); ensureValidDouble(profile.getFirstPhaseRanking(), "first-phase expression", context); ensureValidDouble(profile.getSecondPhaseRanking(), "second-phase expression", context); + if ( context.tensorsAreUsed() && ! context.queryFeaturesNotDeclared().isEmpty()) { + deployLogger.log(Level.WARNING, "The following query features are not declared in query profile " + + "types and will be interpreted as scalars, not tensors: " + + context.queryFeaturesNotDeclared()); + } } } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/HttpBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/HttpBuilder.java index 8cf430741f0..3aebe26b456 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/HttpBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/http/xml/HttpBuilder.java @@ -45,9 +45,13 @@ public class HttpBuilder extends VespaDomBuilder.DomConfigProducerBuilder<Http> Element accessControlElem = XML.getChild(filteringElem, "access-control"); if (accessControlElem != null) { - accessControl = buildAccessControl(deployState, ancestor, accessControlElem); - bindings.addAll(accessControl.getBindings()); - filterChains.add(new Chain<>(FilterChains.emptyChainSpec(ACCESS_CONTROL_CHAIN_ID))); + if (deployState.isHosted()) { + accessControl = buildAccessControl(deployState, ancestor, accessControlElem); + bindings.addAll(accessControl.getBindings()); + filterChains.add(new Chain<>(FilterChains.emptyChainSpec(ACCESS_CONTROL_CHAIN_ID))); + } else { + deployState.getDeployLogger().log(LogLevel.WARNING, "The 'access-control' element is only supported in hosted Vespa."); + } } } else { filterChains = new FilterChainsBuilder().newChainsInstance(ancestor); diff --git a/config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionTypeResolverTestCase.java b/config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionTypeResolverTestCase.java index 3b3ce712387..f0a0e389086 100644 --- a/config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionTypeResolverTestCase.java +++ b/config-model/src/test/java/com/yahoo/searchdefinition/processing/RankingExpressionTypeResolverTestCase.java @@ -1,6 +1,8 @@ // Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.searchdefinition.processing; +import com.yahoo.collections.Pair; +import com.yahoo.config.application.api.DeployLogger; import com.yahoo.searchdefinition.RankProfile; import com.yahoo.searchdefinition.RankProfileRegistry; import com.yahoo.searchdefinition.SearchBuilder; @@ -9,11 +11,17 @@ import com.yahoo.tensor.TensorType; import com.yahoo.yolean.Exceptions; import org.junit.Test; +import java.util.ArrayList; +import java.util.List; import java.util.Map; +import java.util.logging.Level; import java.util.stream.Collectors; import static com.yahoo.config.model.test.TestUtil.joinLines; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** @@ -218,23 +226,77 @@ public class RankingExpressionTypeResolverTestCase { @Test public void undeclaredQueryFeaturesAreAccepted() throws Exception { + InspectableDeployLogger logger = new InspectableDeployLogger(); SearchBuilder builder = new SearchBuilder(); builder.importString(joinLines( "search test {", " document test { ", + " field anyfield type double {" + + " indexing: attribute", + " }", " }", " rank-profile my_rank_profile {", " first-phase {", - " expression: query(foo)", + " expression: query(foo) + f() + sum(attribute(anyfield))", + " }", + " function f() {", + " expression: query(bar) + query(baz)", " }", " }", "}" - )); - builder.build(); + ), logger); + builder.build(true, logger); + String message = logger.findMessage("The following query features"); + assertNull(message); + } + + @Test + public void undeclaredQueryFeaturesAreAcceptedWithWarningWhenUsingTensors() throws Exception { + InspectableDeployLogger logger = new InspectableDeployLogger(); + SearchBuilder builder = new SearchBuilder(); + builder.importString(joinLines( + "search test {", + " document test { ", + " field anyfield type tensor(d[2]) {", + " indexing: attribute", + " }", + " }", + " rank-profile my_rank_profile {", + " first-phase {", + " expression: query(foo) + f() + sum(attribute(anyfield))", + " }", + " function f() {", + " expression: query(bar) + query(baz)", + " }", + " }", + "}" + ), logger); + builder.build(true, logger); + String message = logger.findMessage("The following query features"); + assertNotNull(message); + assertEquals("WARNING: The following query features are not declared in query profile types and " + + "will be interpreted as scalars, not tensors: [query(bar), query(baz), query(foo)]", + message); } private Map<String, ReferenceNode> summaryFeatures(RankProfile profile) { return profile.getSummaryFeatures().stream().collect(Collectors.toMap(f -> f.toString(), f -> f)); } + private static class InspectableDeployLogger implements DeployLogger { + + private List<String> messages = new ArrayList<>(); + + @Override + public void log(Level level, String message) { + messages.add(level + ": " + message); + } + + /** Returns the first message containing the given string, or null if none */ + public String findMessage(String substring) { + return messages.stream().filter(message -> message.contains(substring)).findFirst().orElse(null); + } + + } + } diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/AccessControlTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/AccessControlTest.java index 7cd26b2f1e6..1ffb3743b4c 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/AccessControlTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/AccessControlTest.java @@ -7,8 +7,8 @@ import com.yahoo.config.model.builder.xml.test.DomBuilderTest; import com.yahoo.container.jdisc.state.StateHandler; import com.yahoo.vespa.model.container.ContainerCluster; import com.yahoo.vespa.model.container.http.AccessControl; -import com.yahoo.vespa.model.container.http.Http; import com.yahoo.vespa.model.container.http.Binding; +import com.yahoo.vespa.model.container.http.Http; import com.yahoo.vespa.model.container.http.xml.HttpBuilder; import com.yahoo.vespa.model.container.jersey.Jersey2Servlet; import org.junit.Test; @@ -44,6 +44,11 @@ public class AccessControlTest extends ContainerModelBuilderTestBase { StateHandler.STATE_API_ROOT, ContainerCluster.ROOT_HANDLER_PATH); + public AccessControlTest() { + // Note: isHosted is assigned in the constructor as it is used by a @Before annotated method in the super class. + isHosted = true; + } + @Test public void access_control_filter_chain_is_set_up() { Element clusterElem = DomBuilderTest.parse( diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTestBase.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTestBase.java index 9e02572737e..8eac7406059 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTestBase.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTestBase.java @@ -5,6 +5,8 @@ import com.yahoo.collections.Pair; import com.yahoo.component.ComponentId; import com.yahoo.config.application.api.DeployLogger; import com.yahoo.config.model.deploy.DeployState; +import com.yahoo.config.model.deploy.TestProperties; +import com.yahoo.config.model.test.MockApplicationPackage; import com.yahoo.config.model.test.MockRoot; import com.yahoo.container.ComponentsConfig; import com.yahoo.vespa.model.VespaModel; @@ -50,6 +52,7 @@ public abstract class ContainerModelBuilderTestBase { " </nodes>"; protected MockRoot root; + protected boolean isHosted = false; public static void createModel(MockRoot root, DeployState deployState, VespaModel vespaModel, Element... containerElems) { for (Element containerElem : containerElems) { @@ -62,7 +65,7 @@ public abstract class ContainerModelBuilderTestBase { } public static void createModel(MockRoot root, Element... containerElems) { - createModel(root, DeployState.createTestState(), null, containerElems); + createModel(root, root.getDeployState(), null, containerElems); } public static void createModel(MockRoot root, DeployLogger testLogger, Element... containerElems) { @@ -77,7 +80,11 @@ public abstract class ContainerModelBuilderTestBase { @Before public void prepareTest() { - root = new MockRoot("root"); + root = new MockRoot("root", + new DeployState.Builder() + .applicationPackage(new MockApplicationPackage.Builder().build()) + .properties(new TestProperties().setHostedVespa(isHosted)) + .build()); } protected ComponentsConfig componentsConfig() { diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/Flavor.java b/config-provisioning/src/main/java/com/yahoo/config/provision/Flavor.java index 69510c9ccdd..2711406c216 100644 --- a/config-provisioning/src/main/java/com/yahoo/config/provision/Flavor.java +++ b/config-provisioning/src/main/java/com/yahoo/config/provision/Flavor.java @@ -28,13 +28,10 @@ public class Flavor { private final Optional<FlavorOverrides> flavorOverrides; - private static final double cpuSpeedupRolloutFactor = 2.0/3.0; // TODO: Increase to 1 on a later release - /** Creates a *host* flavor from configuration */ public Flavor(FlavorsConfig.Flavor flavorConfig) { this(flavorConfig.name(), - new NodeResources(flavorConfig.minCpuCores() * - (1 + (flavorConfig.cpuSpeedup() - 1) * cpuSpeedupRolloutFactor), + new NodeResources(flavorConfig.minCpuCores() * flavorConfig.cpuSpeedup(), flavorConfig.minMainMemoryAvailableGb(), flavorConfig.minDiskAvailableGb(), flavorConfig.bandwidth() / 1000, diff --git a/config-provisioning/src/test/java/com/yahoo/config/provision/NodeFlavorsTest.java b/config-provisioning/src/test/java/com/yahoo/config/provision/NodeFlavorsTest.java index 233a1472d8e..31eec77de6b 100644 --- a/config-provisioning/src/test/java/com/yahoo/config/provision/NodeFlavorsTest.java +++ b/config-provisioning/src/test/java/com/yahoo/config/provision/NodeFlavorsTest.java @@ -35,7 +35,7 @@ public class NodeFlavorsTest { Flavor banana = nodeFlavors.getFlavor("banana").get(); assertEquals(3, banana.cost()); assertEquals(10, banana.getMinCpuCores(), delta); - assertEquals("10 * (1 + 2*(1.3 - 1)/3", 12, banana.resources().vcpu(), delta); + assertEquals("10 * 1.3", 13, banana.resources().vcpu(), delta); } } diff --git a/configserver/src/main/sh/start-logd b/configserver/src/main/sh/start-logd index d8ed068537e..0a9a84a21dc 100644 --- a/configserver/src/main/sh/start-logd +++ b/configserver/src/main/sh/start-logd @@ -78,7 +78,7 @@ ROOT=${VESPA_HOME%/} export VESPA_CONFIG_ID="file:$VESPA_HOME/conf/logd/logd.cfg" -if [ "$cloudconfig_server__multitenant" = "true" ]; then +if [ "$cloudconfig_server__multitenant" = "true" || "$VESPA_CONFIGSERVER_MULTITENANT" = "true" ]; then PIDFILE_LOGD=var/run/logd.pid VESPA_SERVICE_NAME=logd export VESPA_SERVICE_NAME diff --git a/configserver/src/main/sh/stop-configserver b/configserver/src/main/sh/stop-configserver index 007ff7cdd62..c24e6ffa347 100755 --- a/configserver/src/main/sh/stop-configserver +++ b/configserver/src/main/sh/stop-configserver @@ -91,8 +91,7 @@ PIDFILE_LOGD=var/run/logd.pid VESPA_LOG_TARGET="file:${ROOT}/logs/vespa/vespa.log" export VESPA_LOG_TARGET -multitenant=$cloudconfig_server__multitenant -if [ "$multitenant" = "true" ]; then +if [ "$cloudconfig_server__multitenant" = "true" || "$VESPA_CONFIGSERVER_MULTITENANT" = "true" ]; then vespa-run-as-vespa-user vespa-runserver -s logd -p $PIDFILE_LOGD -S fi 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 fb9745d90cb..7f61632ea4e 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 @@ -21,7 +21,8 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> { * environment) */ public static final ApplicationVersion unknown = new ApplicationVersion(Optional.empty(), OptionalLong.empty(), - Optional.empty(), Optional.empty(), Optional.empty()); + Optional.empty(), Optional.empty(), Optional.empty(), + Optional.empty(), Optional.empty()); // 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"; @@ -31,9 +32,13 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> { 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 ApplicationVersion(Optional<SourceRevision> source, OptionalLong buildNumber, Optional<String> authorEmail, - Optional<Version> compileVersion, Optional<Instant> buildTime) { + /** Public for serialisation only. */ + public ApplicationVersion(Optional<SourceRevision> source, OptionalLong buildNumber, Optional<String> authorEmail, + Optional<Version> compileVersion, Optional<Instant> buildTime, Optional<String> sourceUrl, + Optional<String> commit) { Objects.requireNonNull(source, "source cannot be null"); Objects.requireNonNull(buildNumber, "buildNumber cannot be null"); Objects.requireNonNull(authorEmail, "author cannot be null"); @@ -57,25 +62,34 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> { 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"); } /** 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(), Optional.empty(), Optional.empty()); } /** Creates an version from a completed build and an author email. */ public static ApplicationVersion from(SourceRevision source, long buildNumber, String authorEmail) { - return new ApplicationVersion(Optional.of(source), OptionalLong.of(buildNumber), - Optional.of(authorEmail), Optional.empty(), Optional.empty()); + return new ApplicationVersion(Optional.of(source), OptionalLong.of(buildNumber), Optional.of(authorEmail), + Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty()); } /** Creates an version from a completed build, an author email, and build meta data. */ 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.of(compileVersion), Optional.of(buildTime), Optional.empty(), Optional.empty()); + } + + /** Creates an version from a completed build, an author email, and build meta data. */ + public static ApplicationVersion from(SourceRevision source, long buildNumber, String authorEmail, Version compileVersion, + Instant buildTime, Optional<String> sourceUrl, Optional<String> commit) { + return new ApplicationVersion(Optional.of(source), OptionalLong.of(buildNumber), Optional.of(authorEmail), + Optional.of(compileVersion), Optional.of(buildTime), sourceUrl, commit); } /** Returns an unique identifier for this version or "unknown" if version is not known */ @@ -83,7 +97,12 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> { if (isUnknown()) { return "unknown"; } - return String.format("%s.%d-%s", majorVersion, buildNumber.getAsLong(), abbreviateCommit(source.get().commit())); + return String.format("%s.%d-%s", + majorVersion, + buildNumber.getAsLong(), + source.map(SourceRevision::commit).map(commit -> abbreviateCommit(commit)) + .or(this::commit) + .orElse("unknown")); } /** @@ -104,6 +123,21 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> { /** Returns the time this package was built, if known. */ public Optional<Instant> buildTime() { return buildTime; } + /** Returns the source URL for this application version. */ + public Optional<String> sourceUrl() { + return sourceUrl.or(() -> source.map(source -> { + String repository = source.repository(); + if (repository.startsWith("git@")) + repository = "https://" + repository.substring(4).replace(':', '/'); + if (repository.endsWith(".git")) + repository = repository.substring(0, repository.length() - 4); + return repository + "/tree/" + source.commit(); + })); + } + + /** 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); @@ -144,4 +178,5 @@ public class ApplicationVersion implements Comparable<ApplicationVersion> { return Long.compare(buildNumber().getAsLong(), o.buildNumber().getAsLong()); } + } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java index f9ad2ebf553..c6f54b1fe5c 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/JobController.java @@ -296,22 +296,31 @@ public class JobController { /** Returns the deployment status of the given application. */ public DeploymentStatus deploymentStatus(Application application) { + return deploymentStatus(application, controller.systemVersion()); + } + + private DeploymentStatus deploymentStatus(Application application, Version systemVersion) { return new DeploymentStatus(application, DeploymentStatus.jobsFor(application, controller.system()).stream() .collect(toUnmodifiableMap(job -> job, job -> jobStatus(job))), controller.system(), - controller.systemVersion(), + systemVersion, controller.clock().instant()); } /** Adds deployment status to each of the given applications. */ - public DeploymentStatusList deploymentStatuses(ApplicationList applications) { + public DeploymentStatusList deploymentStatuses(ApplicationList applications, Version systemVersion) { return DeploymentStatusList.from(applications.asList().stream() - .map(this::deploymentStatus) + .map(application -> deploymentStatus(application, systemVersion)) .collect(toUnmodifiableList())); } + /** Adds deployment status to each of the given applications. Calling this will do an implicit read of the controller's version status */ + public DeploymentStatusList deploymentStatuses(ApplicationList applications) { + return deploymentStatuses(applications, controller.systemVersion()); + } + /** Changes the status of the given step, for the given run, provided it is still active. */ public void update(RunId id, RunStatus status, LockedStep step) { locked(id, run -> run.with(status, step)); @@ -359,8 +368,9 @@ public class JobController { /** * Accepts and stores a new application package and test jar pair under a generated application version key. */ - public ApplicationVersion submit(TenantAndApplicationId id, SourceRevision revision, String authorEmail, long projectId, - ApplicationPackage applicationPackage, byte[] testPackageBytes) { + public ApplicationVersion submit(TenantAndApplicationId id, SourceRevision revision, String authorEmail, + Optional<String> sourceUrl, Optional<String> commit, + long projectId, ApplicationPackage applicationPackage, byte[] testPackageBytes) { AtomicReference<ApplicationVersion> version = new AtomicReference<>(); controller.applications().lockApplicationOrThrow(id, application -> { long run = 1 + application.get().latestVersion() @@ -369,7 +379,9 @@ public class JobController { if (applicationPackage.compileVersion().isPresent() && applicationPackage.buildTime().isPresent()) version.set(ApplicationVersion.from(revision, run, authorEmail, applicationPackage.compileVersion().get(), - applicationPackage.buildTime().get())); + applicationPackage.buildTime().get(), + sourceUrl, + commit)); else version.set(ApplicationVersion.from(revision, run, authorEmail)); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java index acbae53ad2c..b730b63d426 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializer.java @@ -115,6 +115,7 @@ public class ApplicationSerializer { private static final String authorEmailField = "authorEmailField"; private static final String compileVersionField = "compileVersion"; private static final String buildTimeField = "buildTime"; + private static final String sourceUrlField = "sourceUrl"; private static final String lastQueriedField = "lastQueried"; private static final String lastWrittenField = "lastWritten"; private static final String lastQueriesPerSecondField = "lastQueriesPerSecond"; @@ -263,6 +264,8 @@ public class ApplicationSerializer { applicationVersion.authorEmail().ifPresent(email -> object.setString(authorEmailField, email)); applicationVersion.compileVersion().ifPresent(version -> object.setString(compileVersionField, version.toString())); applicationVersion.buildTime().ifPresent(time -> object.setLong(buildTimeField, time.toEpochMilli())); + applicationVersion.sourceUrl().ifPresent(url -> object.setString(sourceUrlField, url)); + applicationVersion.commit().ifPresent(commit -> object.setString(commitField, commit)); } } @@ -478,6 +481,8 @@ public class ApplicationSerializer { Optional<String> authorEmail = Serializers.optionalString(object.field(authorEmailField)); Optional<Version> compileVersion = Serializers.optionalString(object.field(compileVersionField)).map(Version::fromString); Optional<Instant> buildTime = Serializers.optionalInstant(object.field(buildTimeField)); + Optional<String> sourceUrl = Serializers.optionalString(object.field(sourceUrlField)); + Optional<String> commit = Serializers.optionalString(object.field(commitField)); if (authorEmail.isEmpty()) return ApplicationVersion.from(sourceRevision.get(), applicationBuildNumber.getAsLong()); @@ -485,8 +490,7 @@ public class ApplicationSerializer { if (compileVersion.isEmpty() || buildTime.isEmpty()) return ApplicationVersion.from(sourceRevision.get(), applicationBuildNumber.getAsLong(), authorEmail.get()); - return ApplicationVersion.from(sourceRevision.get(), applicationBuildNumber.getAsLong(), authorEmail.get(), - compileVersion.get(), buildTime.get()); + return new ApplicationVersion(sourceRevision, applicationBuildNumber, authorEmail, compileVersion, buildTime, sourceUrl, commit); } private Optional<SourceRevision> sourceRevisionFromSlime(Inspector object) { diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java index b777d6f52ed..8f2b274401c 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializer.java @@ -25,6 +25,7 @@ import java.time.temporal.ChronoUnit; import java.util.EnumMap; import java.util.NavigableMap; import java.util.Optional; +import java.util.OptionalLong; import java.util.TreeMap; import static com.yahoo.vespa.hosted.controller.deployment.RunStatus.aborted; @@ -84,6 +85,7 @@ class RunSerializer { private static final String authorEmailField = "authorEmail"; private static final String compileVersionField = "compileVersion"; private static final String buildTimeField = "buildTime"; + private static final String sourceUrlField = "sourceUrl"; private static final String buildField = "build"; private static final String sourceField = "source"; private static final String lastTestRecordField = "lastTestRecord"; @@ -158,16 +160,14 @@ class RunSerializer { versionObject.field(branchField).asString(), versionObject.field(commitField).asString()); long buildNumber = versionObject.field(buildField).asLong(); - - if ( ! versionObject.field(authorEmailField).valid()) - return ApplicationVersion.from(revision, buildNumber); - - if ( ! versionObject.field(compileVersionField).valid() || ! versionObject.field(buildTimeField).valid()) - return ApplicationVersion.from(revision, buildNumber, versionObject.field(authorEmailField).asString()); - - return ApplicationVersion.from(revision, buildNumber, versionObject.field(authorEmailField).asString(), - Version.fromString(versionObject.field(compileVersionField).asString()), - Instant.ofEpochMilli(versionObject.field(buildTimeField).asLong())); + Optional<String> authorEmail = Serializers.optionalString(versionObject.field(authorEmailField)); + Optional<Version> compileVersion = Serializers.optionalString(versionObject.field(compileVersionField)).map(Version::fromString); + Optional<Instant> buildTime = Serializers.optionalInstant(versionObject.field(buildTimeField)); + Optional<String> sourceUrl = Serializers.optionalString(versionObject.field(sourceUrlField)); + Optional<String> commit = Serializers.optionalString(versionObject.field(commitField)); + + return new ApplicationVersion(Optional.of(revision), OptionalLong.of(buildNumber), authorEmail, + compileVersion, buildTime, sourceUrl, commit); } Slime toSlime(Iterable<Run> runs) { @@ -224,6 +224,8 @@ class RunSerializer { applicationVersion.authorEmail().ifPresent(email -> versionsObject.setString(authorEmailField, email)); applicationVersion.compileVersion().ifPresent(version -> versionsObject.setString(compileVersionField, version.toString())); applicationVersion.buildTime().ifPresent(time -> versionsObject.setLong(buildTimeField, time.toEpochMilli())); + applicationVersion.sourceUrl().ifPresent(url -> versionsObject.setString(sourceUrlField, url)); + applicationVersion.commit().ifPresent(commit -> versionsObject.setString(commitField, commit)); } static String valueOf(Step step) { diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/VersionStatusSerializer.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/VersionStatusSerializer.java index 366e2c9af4b..53f2d467e2d 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/VersionStatusSerializer.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/persistence/VersionStatusSerializer.java @@ -44,7 +44,6 @@ public class VersionStatusSerializer { private static final String isReleasedField = "isReleased"; private static final String deploymentStatisticsField = "deploymentStatistics"; private static final String confidenceField = "confidence"; - private static final String configServersField = "configServerHostnames"; // NodeVersions fields private static final String nodeVersionsField = "nodeVersions"; diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java index 0445b6c6230..5c5955cbe4f 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/ApplicationApiHandler.java @@ -854,7 +854,11 @@ public class ApplicationApiHandler extends LoggingRequestHandler { "/instance/" + instance.id().instance().value() + "/job/", request.getUri()).toString()); - application.latestVersion().ifPresent(version -> sourceRevisionToSlime(version.source(), object.setObject("source"))); + application.latestVersion().ifPresent(version -> { + sourceRevisionToSlime(version.source(), object.setObject("source")); + version.sourceUrl().ifPresent(url -> object.setString("sourceUrl", url)); + version.commit().ifPresent(commit -> object.setString("commit", commit)); + }); application.projectId().ifPresent(id -> object.setLong("projectId", id)); @@ -1077,6 +1081,8 @@ public class ApplicationApiHandler extends LoggingRequestHandler { object.setLong("buildNumber", applicationVersion.buildNumber().getAsLong()); object.setString("hash", applicationVersion.id()); sourceRevisionToSlime(applicationVersion.source(), object.setObject("source")); + applicationVersion.sourceUrl().ifPresent(url -> object.setString("sourceUrl", url)); + applicationVersion.commit().ifPresent(commit -> object.setString("commit", commit)); } } @@ -1948,6 +1954,8 @@ public class ApplicationApiHandler extends LoggingRequestHandler { SourceRevision sourceRevision = toSourceRevision(submitOptions); String authorEmail = submitOptions.field("authorEmail").asString(); long projectId = Math.max(1, submitOptions.field("projectId").asLong()); + Optional<String> commit = submitOptions.field("commit").valid() ? Optional.of(submitOptions.field("commit").asString()) : Optional.empty(); + Optional<String> sourceUrl = submitOptions.field("sourceUrl").valid() ? Optional.of(submitOptions.field("sourceUrl").asString()) : Optional.empty(); ApplicationPackage applicationPackage = new ApplicationPackage(dataParts.get(EnvironmentResource.APPLICATION_ZIP), true); @@ -1960,6 +1968,8 @@ public class ApplicationApiHandler extends LoggingRequestHandler { application, sourceRevision, authorEmail, + sourceUrl, + commit, projectId, applicationPackage, dataParts.get(EnvironmentResource.APPLICATION_TEST_ZIP)); diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java index 33038e3ea69..8c82308e894 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/application/JobControllerApiHandlerHelper.java @@ -416,6 +416,8 @@ class JobControllerApiHandlerHelper { sourceObject.setString("gitRepository", version.source().get().repository()); sourceObject.setString("gitBranch", version.source().get().branch()); sourceObject.setString("gitCommit", version.source().get().commit()); + version.sourceUrl().ifPresent(url -> versionObject.setString("sourceUrl", url)); + version.commit().ifPresent(commit -> versionObject.setString("commit", commit)); } /** @@ -472,11 +474,14 @@ class JobControllerApiHandlerHelper { * @return Response with the new application version */ static HttpResponse submitResponse(JobController jobController, String tenant, String application, - SourceRevision sourceRevision, String authorEmail, long projectId, + SourceRevision sourceRevision, String authorEmail, Optional<String> sourceUrl, + Optional<String> commit, long projectId, ApplicationPackage applicationPackage, byte[] testPackage) { ApplicationVersion version = jobController.submit(TenantAndApplicationId.from(tenant, application), sourceRevision, authorEmail, + sourceUrl, + commit, projectId, applicationPackage, testPackage); @@ -601,8 +606,9 @@ class JobControllerApiHandlerHelper { private static void toSlime(Cursor versionObject, ApplicationVersion version) { version.buildNumber().ifPresent(id -> versionObject.setLong("id", id)); version.source().ifPresent(source -> versionObject.setString("commit", source.commit())); - version.source().flatMap(source -> toUrl(source)).ifPresent(source -> versionObject.setString("source", source.toString())); version.compileVersion().ifPresent(platform -> versionObject.setString("compileVersion", platform.toFullString())); + version.sourceUrl().ifPresent(url -> versionObject.setString("sourceUrl", url)); + version.commit().ifPresent(commit -> versionObject.setString("commit", commit)); } private static void toSlime(Cursor versionsObject, Versions versions) { @@ -612,20 +618,5 @@ class JobControllerApiHandlerHelper { versions.sourceApplication().ifPresent(application -> toSlime(versionsObject.setObject("sourceApplication"), application)); } - // TODO jonmv: Remove this when source url is stored instead of SourceRevision. - private static Optional<URI> toUrl(SourceRevision source) { - try { - String repository = source.repository(); - if (repository.startsWith("git@")) - repository = "https://" + repository.substring(4); - if (repository.endsWith(".git")) - repository = repository.substring(0, repository.length() - 4); - return Optional.of(URI.create(repository + "/tree/" + source.commit())); - } - catch (RuntimeException e) { - return Optional.empty(); - } - } - } diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiHandler.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiHandler.java index 1f1dcbb8001..600ad322f84 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiHandler.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/restapi/deployment/DeploymentApiHandler.java @@ -2,6 +2,7 @@ package com.yahoo.vespa.hosted.controller.restapi.deployment; import com.yahoo.component.Version; +import com.yahoo.component.Vtag; import com.yahoo.config.application.api.DeploymentInstanceSpec; import com.yahoo.config.application.api.DeploymentSpec; import com.yahoo.config.provision.ApplicationId; @@ -86,11 +87,13 @@ public class DeploymentApiHandler extends LoggingRequestHandler { Slime slime = new Slime(); Cursor root = slime.setObject(); Cursor platformArray = root.setArray("versions"); - Map<ApplicationId, JobList> jobs = controller.jobController().deploymentStatuses(ApplicationList.from(controller.applications().asList())) + var versionStatus = controller.versionStatus(); + var systemVersion = versionStatus.systemVersion().map(VespaVersion::versionNumber).orElse(Vtag.currentVersion); + Map<ApplicationId, JobList> jobs = controller.jobController().deploymentStatuses(ApplicationList.from(controller.applications().asList()), systemVersion) .asList().stream() .flatMap(status -> status.instanceJobs().entrySet().stream()) .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue)); - for (VespaVersion version : controller.versionStatus().versions()) { + for (VespaVersion version : versionStatus.versions()) { Cursor versionObject = platformArray.addObject(); versionObject.setString("version", version.versionNumber().toString()); versionObject.setString("confidence", version.confidence().name()); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentContext.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentContext.java index 120b9bad468..035b6127b41 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentContext.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentContext.java @@ -211,7 +211,7 @@ public class DeploymentContext { .requireApplication(applicationId) .projectId() .orElse(1000); // These are really set through submission, so just pick one if it hasn't been set. - lastSubmission = jobs.submit(applicationId, sourceRevision, "a@b", projectId, applicationPackage, new byte[0]); + lastSubmission = jobs.submit(applicationId, sourceRevision, "a@b", Optional.empty(), Optional.empty(), projectId, applicationPackage, new byte[0]); return this; } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/JobRunnerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/JobRunnerTest.java index 51da78c835e..bdab81b3948 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/JobRunnerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/maintenance/JobRunnerTest.java @@ -87,7 +87,7 @@ public class JobRunnerTest { TenantAndApplicationId appId = tester.createApplication("tenant", "real", "default").id(); ApplicationId id = appId.defaultInstance(); - jobs.submit(appId, versions.targetApplication().source().get(), "a@b", 2, applicationPackage, new byte[0]); + jobs.submit(appId, versions.targetApplication().source().get(), "a@b", Optional.empty(), Optional.empty(), 2, applicationPackage, new byte[0]); jobs.start(id, systemTest, versions); try { @@ -119,7 +119,7 @@ public class JobRunnerTest { TenantAndApplicationId appId = tester.createApplication("tenant", "real", "default").id(); ApplicationId id = appId.defaultInstance(); - jobs.submit(appId, versions.targetApplication().source().get(), "a@b", 2, applicationPackage, new byte[0]); + jobs.submit(appId, versions.targetApplication().source().get(), "a@b", Optional.empty(), Optional.empty(), 2, applicationPackage, new byte[0]); Supplier<Run> run = () -> jobs.last(id, systemTest).get(); jobs.start(id, systemTest, versions); @@ -227,7 +227,7 @@ public class JobRunnerTest { TenantAndApplicationId appId = tester.createApplication("tenant", "real", "default").id(); ApplicationId id = appId.defaultInstance(); - jobs.submit(appId, versions.targetApplication().source().get(), "a@b", 2, applicationPackage, new byte[0]); + jobs.submit(appId, versions.targetApplication().source().get(), "a@b", Optional.empty(), Optional.empty(), 2, applicationPackage, new byte[0]); RunId runId = new RunId(id, systemTest, 1); jobs.start(id, systemTest, versions); @@ -265,7 +265,7 @@ public class JobRunnerTest { TenantAndApplicationId appId = tester.createApplication("tenant", "real", "default").id(); ApplicationId instanceId = appId.defaultInstance(); JobId jobId = new JobId(instanceId, systemTest); - jobs.submit(appId, versions.targetApplication().source().get(), "a@b", 2, applicationPackage, new byte[0]); + jobs.submit(appId, versions.targetApplication().source().get(), "a@b", Optional.empty(), Optional.empty(), 2, applicationPackage, new byte[0]); assertFalse(jobs.lastSuccess(jobId).isPresent()); for (int i = 0; i < jobs.historyLength(); i++) { @@ -343,7 +343,7 @@ public class JobRunnerTest { TenantAndApplicationId appId = tester.createApplication("tenant", "real", "default").id(); ApplicationId id = appId.defaultInstance(); - jobs.submit(appId, versions.targetApplication().source().get(), "a@b", 2, applicationPackage, new byte[0]); + jobs.submit(appId, versions.targetApplication().source().get(), "a@b", Optional.empty(), Optional.empty(), 2, applicationPackage, new byte[0]); jobs.start(id, systemTest, versions); tester.clock().advance(JobRunner.jobTimeout.plus(Duration.ofSeconds(1))); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java index e485e60815b..c4cb01f8164 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/ApplicationSerializerTest.java @@ -84,7 +84,15 @@ public class ApplicationSerializerTest { OptionalLong projectId = OptionalLong.of(123L); List<Deployment> deployments = new ArrayList<>(); - ApplicationVersion applicationVersion1 = ApplicationVersion.from(new SourceRevision("repo1", "branch1", "commit1"), 31); + ApplicationVersion applicationVersion1 = new ApplicationVersion(Optional.of(new SourceRevision("git@github:org/repo.git", "branch1", "commit1")), + OptionalLong.of(31), + Optional.of("william@shakespeare"), + Optional.of(Version.fromString("1.2.3")), + Optional.of(Instant.ofEpochMilli(666)), + Optional.empty(), + Optional.of("best commit")); + assertEquals("https://github/org/repo/tree/commit1", applicationVersion1.sourceUrl().get()); + ApplicationVersion applicationVersion2 = ApplicationVersion .from(new SourceRevision("repo1", "branch1", "commit1"), 32, "a@b", Version.fromString("6.3.1"), Instant.ofEpochMilli(496)); @@ -138,6 +146,10 @@ public class ApplicationSerializerTest { assertEquals(original.id(), serialized.id()); assertEquals(original.createdAt(), serialized.createdAt()); assertEquals(original.latestVersion(), serialized.latestVersion()); + assertEquals(original.latestVersion().get().authorEmail(), serialized.latestVersion().get().authorEmail()); + assertEquals(original.latestVersion().get().buildTime(), serialized.latestVersion().get().buildTime()); + assertEquals(original.latestVersion().get().sourceUrl(), serialized.latestVersion().get().sourceUrl()); + assertEquals(original.latestVersion().get().commit(), serialized.latestVersion().get().commit()); assertEquals(original.deploymentSpec().xmlForm(), serialized.deploymentSpec().xmlForm()); assertEquals(original.validationOverrides().xmlForm(), serialized.validationOverrides().xmlForm()); diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializerTest.java index 1cd361b4d74..c1f8e2f0ffb 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/persistence/RunSerializerTest.java @@ -77,14 +77,19 @@ public class RunSerializerTest { assertEquals(running, run.status()); assertEquals(3, run.lastTestLogEntry()); assertEquals(new Version(1, 2, 3), run.versions().targetPlatform()); - assertEquals(ApplicationVersion.from(new SourceRevision("git@github.com:user/repo.git", - "master", - "f00bad"), - 123, - "a@b", - Version.fromString("6.3.1"), - Instant.ofEpochMilli(100)), - run.versions().targetApplication()); + ApplicationVersion applicationVersion = ApplicationVersion.from(new SourceRevision("git@github.com:user/repo.git", + "master", + "f00bad"), + 123, + "a@b", + Version.fromString("6.3.1"), + Instant.ofEpochMilli(100)); + assertEquals(applicationVersion, run.versions().targetApplication()); + assertEquals(applicationVersion.authorEmail(), run.versions().targetApplication().authorEmail()); + assertEquals(applicationVersion.buildTime(), run.versions().targetApplication().buildTime()); + assertEquals(applicationVersion.compileVersion(), run.versions().targetApplication().compileVersion()); + assertEquals("f00bad", run.versions().targetApplication().commit().get()); + assertEquals("https://github.com/user/repo/tree/f00bad", run.versions().targetApplication().sourceUrl().get()); assertEquals(new Version(1, 2, 2), run.versions().sourcePlatform().get()); assertEquals(ApplicationVersion.from(new SourceRevision("git@github.com:user/repo.git", "master", diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application2-with-patches.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application2-with-patches.json index 16a5529a2ad..7b84780d64e 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application2-with-patches.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application2-with-patches.json @@ -9,7 +9,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "projectId": 1000, "compileVersion": "6.1.0", @@ -33,7 +35,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" } }, "deploymentJobs": [ @@ -50,7 +54,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -69,7 +75,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -88,7 +96,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application2.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application2.json index 6382824175d..3242fd343de 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application2.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/application2.json @@ -9,7 +9,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "projectId": 1000, "compileVersion": "6.1.0", @@ -32,7 +34,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" } }, "deploymentJobs": [ @@ -49,7 +53,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -68,7 +74,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -87,7 +95,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-overview-2.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-overview-2.json index 8f68bde1a21..62d83ffe8e3 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-overview-2.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-overview-2.json @@ -21,7 +21,7 @@ "targetApplication": { "commit": "commit1", "id": 3, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "sourcePlatform": "6.1.0", @@ -29,7 +29,7 @@ "sourceApplication": { "commit": "commit1", "id": 2, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" } }, @@ -86,7 +86,7 @@ "targetApplication": { "commit": "commit1", "id": 2, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "sourcePlatform": "6.1.0", @@ -94,7 +94,7 @@ "sourceApplication": { "commit": "commit1", "id": 1, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" } }, @@ -151,7 +151,7 @@ "targetApplication": { "commit": "commit1", "id": 1, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "targetPlatform": "6.1.0" @@ -221,7 +221,7 @@ "targetApplication": { "commit": "commit1", "id": 3, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "sourcePlatform": "6.1.0", @@ -229,7 +229,7 @@ "sourceApplication": { "commit": "commit1", "id": 1, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" } }, @@ -244,7 +244,7 @@ "targetApplication": { "commit": "commit1", "id": 3, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "sourcePlatform": "6.1.0", @@ -252,7 +252,7 @@ "sourceApplication": { "commit": "commit1", "id": 1, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" } }, @@ -317,7 +317,7 @@ "targetApplication": { "commit": "commit1", "id": 3, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "sourcePlatform": "6.1.0", @@ -325,7 +325,7 @@ "sourceApplication": { "commit": "commit1", "id": 1, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" } }, @@ -390,7 +390,7 @@ "targetApplication": { "commit": "commit1", "id": 3, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "sourcePlatform": "6.1.0", @@ -398,7 +398,7 @@ "sourceApplication": { "commit": "commit1", "id": 2, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" } }, @@ -463,7 +463,7 @@ "targetApplication": { "commit": "commit1", "id": 2, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "sourcePlatform": "6.1.0", @@ -471,7 +471,7 @@ "sourceApplication": { "commit": "commit1", "id": 1, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" } }, @@ -536,7 +536,7 @@ "targetApplication": { "commit": "commit1", "id": 1, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "targetPlatform": "6.1.0" @@ -611,7 +611,7 @@ "currentApplication": { "commit": "commit1", "id": 3, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "type": "deployment", @@ -622,7 +622,7 @@ "targetApplication": { "commit": "commit1", "id": 3, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "sourcePlatform": "6.1.0", @@ -630,7 +630,7 @@ "sourceApplication": { "commit": "commit1", "id": 2, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" } }, @@ -678,7 +678,7 @@ "targetApplication": { "commit": "commit1", "id": 2, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "sourcePlatform": "6.1.0", @@ -686,7 +686,7 @@ "sourceApplication": { "commit": "commit1", "id": 1, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" } }, @@ -735,7 +735,7 @@ "targetApplication": { "commit": "commit1", "id": 1, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "targetPlatform": "6.1.0" @@ -798,7 +798,7 @@ "targetApplication": { "commit": "commit1", "id": 3, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "sourcePlatform": "6.1.0", @@ -806,7 +806,7 @@ "sourceApplication": { "commit": "commit1", "id": 3, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" } } @@ -820,7 +820,7 @@ "targetApplication": { "commit": "commit1", "id": 2, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "sourcePlatform": "6.1.0", @@ -828,7 +828,7 @@ "sourceApplication": { "commit": "commit1", "id": 2, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" } }, @@ -869,7 +869,7 @@ "targetApplication": { "commit": "commit1", "id": 1, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "sourcePlatform": "6.1.0", @@ -877,7 +877,7 @@ "sourceApplication": { "commit": "commit1", "id": 1, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" } }, @@ -931,7 +931,7 @@ "targetApplication": { "commit": "commit1", "id": 3, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "sourcePlatform": "6.1.0", @@ -939,7 +939,7 @@ "sourceApplication": { "commit": "commit1", "id": 2, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" } } @@ -948,7 +948,7 @@ "currentApplication": { "commit": "commit1", "id": 2, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "type": "deployment", @@ -959,7 +959,7 @@ "targetApplication": { "commit": "commit1", "id": 2, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "sourcePlatform": "6.1.0", @@ -967,7 +967,7 @@ "sourceApplication": { "commit": "commit1", "id": 1, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" } }, @@ -1016,7 +1016,7 @@ "targetApplication": { "commit": "commit1", "id": 1, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "targetPlatform": "6.1.0" @@ -1079,7 +1079,7 @@ "targetApplication": { "commit": "commit1", "id": 3, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "sourcePlatform": "6.1.0", @@ -1087,7 +1087,7 @@ "sourceApplication": { "commit": "commit1", "id": 1, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" } } @@ -1096,7 +1096,7 @@ "currentApplication": { "commit": "commit1", "id": 1, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "type": "deployment", @@ -1107,7 +1107,7 @@ "targetApplication": { "commit": "commit1", "id": 2, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "sourcePlatform": "6.1.0", @@ -1115,7 +1115,7 @@ "sourceApplication": { "commit": "commit1", "id": 1, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" } }, @@ -1164,7 +1164,7 @@ "targetApplication": { "commit": "commit1", "id": 1, - "source": "repository1/tree/commit1", + "sourceUrl": "repository1/tree/commit1", "compileVersion": "6.1.0" }, "targetPlatform": "6.1.0" diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-overview.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-overview.json index ba41468be24..baace75bf6c 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-overview.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/deployment-overview.json @@ -29,8 +29,8 @@ "targetApplication": { "id": 4, "commit": "commit1", - "source": "repository1/tree/commit1", - "compileVersion": "6.1.0" + "compileVersion": "6.1.0", + "sourceUrl": "repository1/tree/commit1" } }, "steps": [ @@ -87,8 +87,8 @@ "targetApplication": { "id": 1, "commit": "commit1", - "source": "repository1/tree/commit1", - "compileVersion": "6.1.0" + "compileVersion": "6.1.0", + "sourceUrl": "repository1/tree/commit1" } }, "steps": [ @@ -157,8 +157,8 @@ "targetApplication": { "id": 4, "commit": "commit1", - "source": "repository1/tree/commit1", - "compileVersion": "6.1.0" + "compileVersion": "6.1.0", + "sourceUrl": "repository1/tree/commit1" } }, "steps": [ @@ -223,8 +223,8 @@ "targetApplication": { "id": 1, "commit": "commit1", - "source": "repository1/tree/commit1", - "compileVersion": "6.1.0" + "compileVersion": "6.1.0", + "sourceUrl": "repository1/tree/commit1" } }, "steps": [ @@ -298,8 +298,8 @@ "targetApplication": { "id": 4, "commit": "commit1", - "source": "repository1/tree/commit1", - "compileVersion": "6.1.0" + "compileVersion": "6.1.0", + "sourceUrl": "repository1/tree/commit1" } } } @@ -316,8 +316,8 @@ "targetApplication": { "id": 1, "commit": "commit1", - "source": "repository1/tree/commit1", - "compileVersion": "6.1.0" + "compileVersion": "6.1.0", + "sourceUrl": "repository1/tree/commit1" } }, "steps": [ @@ -375,8 +375,8 @@ "targetApplication": { "id": 4, "commit": "commit1", - "source": "repository1/tree/commit1", - "compileVersion": "6.1.0" + "compileVersion": "6.1.0", + "sourceUrl": "repository1/tree/commit1" } } } @@ -392,7 +392,7 @@ "targetApplication": { "id": 1, "commit": "commit1", - "source": "repository1/tree/commit1" + "sourceUrl": "repository1/tree/commit1" } }, "steps": [ @@ -450,8 +450,8 @@ "targetApplication": { "id": 4, "commit": "commit1", - "source": "repository1/tree/commit1", - "compileVersion": "6.1.0" + "compileVersion": "6.1.0", + "sourceUrl": "repository1/tree/commit1" } } } @@ -467,8 +467,8 @@ "targetApplication": { "id": 1, "commit": "commit1", - "source": "repository1/tree/commit1", - "compileVersion": "6.1.0" + "compileVersion": "6.1.0", + "sourceUrl": "repository1/tree/commit1" } }, "steps": [ @@ -559,8 +559,8 @@ "targetApplication": { "id": 4, "commit": "commit1", - "source": "repository1/tree/commit1", - "compileVersion": "6.1.0" + "compileVersion": "6.1.0", + "sourceUrl": "repository1/tree/commit1" } } } @@ -585,8 +585,8 @@ "targetApplication": { "id": 4, "commit": "commit1", - "source": "repository1/tree/commit1", - "compileVersion": "6.1.0" + "compileVersion": "6.1.0", + "sourceUrl": "repository1/tree/commit1" } } } @@ -611,8 +611,8 @@ "targetApplication": { "id": 4, "commit": "commit1", - "source": "repository1/tree/commit1", - "compileVersion": "6.1.0" + "compileVersion": "6.1.0", + "sourceUrl": "repository1/tree/commit1" } } } @@ -621,4 +621,3 @@ } ] } - diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-with-routing-policy.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-with-routing-policy.json index ff3bf084069..18f5127718f 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-with-routing-policy.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-with-routing-policy.json @@ -8,6 +8,8 @@ "gitBranch": "master", "gitCommit": "commit1" }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1", "projectId": 1000, "deploymentJobs": [ { @@ -23,7 +25,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -38,7 +42,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -53,7 +59,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -72,7 +80,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -87,7 +97,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -102,7 +114,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -121,7 +135,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -136,7 +152,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -151,7 +169,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-without-change-multiple-deployments.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-without-change-multiple-deployments.json index 79bb0333aa3..259fe814146 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-without-change-multiple-deployments.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance-without-change-multiple-deployments.json @@ -8,6 +8,8 @@ "gitBranch": "master", "gitCommit": "commit1" }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1", "projectId": 1000, "deploymentJobs": [ { @@ -23,7 +25,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -38,7 +42,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -53,7 +59,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -72,7 +80,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -87,7 +97,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -102,7 +114,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -121,7 +135,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -136,7 +152,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -151,7 +169,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -170,7 +190,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -185,7 +207,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -200,7 +224,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance.json index e064c9e60de..d1197be4392 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance.json @@ -8,6 +8,8 @@ "gitBranch": "master", "gitCommit": "commit1" }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1", "projectId": 123, "deploying": { "revision": { @@ -17,7 +19,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" } }, "deploymentJobs": [ @@ -34,7 +38,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -49,7 +55,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -64,7 +72,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -83,7 +93,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -98,7 +110,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -113,7 +127,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -132,7 +148,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -147,7 +165,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -162,7 +182,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -181,7 +203,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance1-recursive.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance1-recursive.json index 8259bd611ff..fb77cfef270 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance1-recursive.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/instance1-recursive.json @@ -8,6 +8,8 @@ "gitBranch": "master", "gitCommit": "commit1" }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1", "projectId": 123, "deploying": { "revision": { @@ -17,7 +19,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" } }, "deploymentJobs": [ @@ -34,7 +38,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -49,7 +55,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -64,7 +72,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -83,7 +93,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -98,7 +110,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -113,7 +127,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -132,7 +148,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -147,7 +165,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -162,7 +182,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" @@ -181,7 +203,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "reason": "unknown reason", "at": "(ignore)" diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/jobs.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/jobs.json index b73c36c804b..32031563d89 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/jobs.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/jobs.json @@ -13,7 +13,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "at": "(ignore)", "deploying": "0 of 3 complete" @@ -27,7 +29,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" } }, "deployments": [ @@ -49,7 +53,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "unfinished", @@ -79,7 +85,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "succeeded", @@ -117,7 +125,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "unfinished", @@ -149,7 +159,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "succeeded", @@ -187,7 +199,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "tasks": { "system-test": "running", @@ -207,7 +221,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "succeeded", @@ -243,7 +259,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "unfinished", @@ -275,7 +293,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "unfinished", diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/overview-user-instance.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/overview-user-instance.json index 6d5a1f3812b..cf47e8671b0 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/overview-user-instance.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/overview-user-instance.json @@ -37,6 +37,8 @@ "gitCommit": "commit1", "gitBranch": "master" }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1", "hash": "1.0.3-commit1" }, "completed": "0 of 0 complete" diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/overview.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/overview.json index 6a7ea87d6a8..b6a1bade306 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/overview.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/overview.json @@ -13,7 +13,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "at": 1000, "deploying": "0 of 3 complete" @@ -27,7 +29,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" } }, "deployments": [ @@ -42,7 +46,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "verified": false, "status": "verifying" @@ -59,7 +65,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "verified": false, "status": "pending" @@ -74,7 +82,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "verified": true, "status": "pending" @@ -97,7 +107,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "currentPlatform": "6.1", "currentApplication": { @@ -107,7 +119,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "succeeded", @@ -141,7 +155,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "currentPlatform": "6.1", "currentApplication": { @@ -151,7 +167,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "succeeded", @@ -185,7 +203,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "succeeded", @@ -221,7 +241,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "currentPlatform": "6.1", "currentApplication": { @@ -231,7 +253,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "tasks": { "cooldown": "failed" @@ -251,7 +275,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "currentPlatform": "6.1", "currentApplication": { @@ -261,7 +287,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "succeeded", @@ -293,7 +321,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "currentPlatform": "6.1", "currentApplication": { @@ -303,7 +333,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "succeeded", @@ -335,7 +367,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "currentPlatform": "6.1", "currentApplication": { @@ -345,7 +379,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "succeeded", @@ -381,7 +417,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "currentPlatform": "6.1", "currentApplication": { @@ -391,7 +429,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "succeeded", @@ -427,7 +467,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "succeeded", @@ -467,7 +509,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "currentPlatform": "6.1", "currentApplication": { @@ -477,7 +521,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "succeeded", @@ -508,7 +554,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "currentPlatform": "6.1", "currentApplication": { @@ -518,7 +566,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "succeeded", @@ -550,7 +600,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "succeeded", @@ -584,7 +636,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "currentPlatform": "6.1", "currentApplication": { @@ -594,7 +648,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "tasks": { "us-central-1": "running", @@ -615,7 +671,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "currentPlatform": "6.1", "currentApplication": { @@ -625,7 +683,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "succeeded", @@ -653,7 +713,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "currentPlatform": "6.1", "currentApplication": { @@ -663,7 +725,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "succeeded", @@ -693,7 +757,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "currentPlatform": "6.1", "currentApplication": { @@ -703,7 +769,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "tasks": { "us-central-1": "running" @@ -722,7 +790,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "currentPlatform": "6.1", "currentApplication": { @@ -732,7 +802,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "succeeded", @@ -764,7 +836,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "succeeded", @@ -798,7 +872,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "currentPlatform": "6.1", "currentApplication": { @@ -808,7 +884,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "tasks": { "staging-test": "failed", @@ -828,7 +906,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "currentPlatform": "6.1", "currentApplication": { @@ -838,7 +918,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "failed", @@ -866,7 +948,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "succeeded", diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/staging-runs.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/staging-runs.json index fbc480d6b03..856dff7f9f8 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/staging-runs.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/staging-runs.json @@ -1,214 +1,232 @@ { "1": { - "id": 1, - "status": "success", - "start": 0, - "end": 0, "wantedPlatform": "6.1", + "log": "https://some.url:43/root/run/1", "wantedApplication": { - "hash": "1.0.1-commit1", + "sourceUrl": "repository1/tree/commit1", "build": 1, + "commit": "commit1", "source": { "gitRepository": "repository1", - "gitBranch": "master", - "gitCommit": "commit1" - } + "gitCommit": "commit1", + "gitBranch": "master" + }, + "hash": "1.0.1-commit1" }, + "start": 0, + "end": 0, + "id": 1, "steps": { "deployInitialReal": "succeeded", "installInitialReal": "succeeded", - "deployReal": "succeeded", - "installReal": "succeeded", + "startTests": "succeeded", "deployTester": "succeeded", + "report": "succeeded", "installTester": "succeeded", - "startTests": "succeeded", + "deployReal": "succeeded", + "installReal": "succeeded", + "deactivateTester": "succeeded", "endTests": "succeeded", "copyVespaLogs": "succeeded", - "deactivateReal": "succeeded", - "deactivateTester": "succeeded", - "report": "succeeded" + "deactivateReal": "succeeded" }, "tasks": { - "deploy": "succeeded", + "test": "succeeded", "install": "succeeded", - "test": "succeeded" + "deploy": "succeeded" }, - "log": "https://some.url:43/root/run/1" + "status": "success" }, "2": { - "id": 2, - "status": "success", - "start": 1000, - "end": 1000, "wantedPlatform": "6.1", + "currentPlatform": "6.1", + "log": "https://some.url:43/root/run/2", "wantedApplication": { - "hash": "1.0.2-commit1", + "sourceUrl": "repository1/tree/commit1", "build": 2, + "commit": "commit1", "source": { "gitRepository": "repository1", - "gitBranch": "master", - "gitCommit": "commit1" - } + "gitCommit": "commit1", + "gitBranch": "master" + }, + "hash": "1.0.2-commit1" }, - "currentPlatform": "6.1", "currentApplication": { - "hash": "1.0.1-commit1", + "sourceUrl": "repository1/tree/commit1", "build": 1, + "commit": "commit1", "source": { "gitRepository": "repository1", - "gitBranch": "master", - "gitCommit": "commit1" - } + "gitCommit": "commit1", + "gitBranch": "master" + }, + "hash": "1.0.1-commit1" }, + "start": 1000, + "end": 1000, + "id": 2, "steps": { "deployInitialReal": "succeeded", "installInitialReal": "succeeded", - "deployReal": "succeeded", - "installReal": "succeeded", + "startTests": "succeeded", "deployTester": "succeeded", + "report": "succeeded", "installTester": "succeeded", - "startTests": "succeeded", + "deployReal": "succeeded", + "installReal": "succeeded", + "deactivateTester": "succeeded", "endTests": "succeeded", "copyVespaLogs": "succeeded", - "deactivateReal": "succeeded", - "deactivateTester": "succeeded", - "report": "succeeded" + "deactivateReal": "succeeded" }, "tasks": { - "deploy": "succeeded", + "test": "succeeded", "install": "succeeded", - "test": "succeeded" + "deploy": "succeeded" }, - "log": "https://some.url:43/root/run/2" + "status": "success" }, "3": { - "id": 3, - "status": "success", - "start": 2000, - "end": 2000, "wantedPlatform": "6.1", + "currentPlatform": "6.1", + "log": "https://some.url:43/root/run/3", "wantedApplication": { - "hash": "1.0.3-commit1", + "sourceUrl": "repository1/tree/commit1", "build": 3, + "commit": "commit1", "source": { "gitRepository": "repository1", - "gitBranch": "master", - "gitCommit": "commit1" - } + "gitCommit": "commit1", + "gitBranch": "master" + }, + "hash": "1.0.3-commit1" }, - "currentPlatform": "6.1", "currentApplication": { - "hash": "1.0.2-commit1", + "sourceUrl": "repository1/tree/commit1", "build": 2, + "commit": "commit1", "source": { "gitRepository": "repository1", - "gitBranch": "master", - "gitCommit": "commit1" - } + "gitCommit": "commit1", + "gitBranch": "master" + }, + "hash": "1.0.2-commit1" }, + "start": 2000, + "end": 2000, + "id": 3, "steps": { "deployInitialReal": "succeeded", "installInitialReal": "succeeded", - "deployReal": "succeeded", - "installReal": "succeeded", + "startTests": "succeeded", "deployTester": "succeeded", + "report": "succeeded", "installTester": "succeeded", - "startTests": "succeeded", + "deployReal": "succeeded", + "installReal": "succeeded", + "deactivateTester": "succeeded", "endTests": "succeeded", "copyVespaLogs": "succeeded", - "deactivateReal": "succeeded", - "deactivateTester": "succeeded", - "report": "succeeded" + "deactivateReal": "succeeded" }, "tasks": { - "deploy": "succeeded", + "test": "succeeded", "install": "succeeded", - "test": "succeeded" + "deploy": "succeeded" }, - "log": "https://some.url:43/root/run/3" + "status": "success" }, "4": { - "id": 4, - "status": "installationFailed", - "start": 2000, - "end": 2000, "wantedPlatform": "6.1", + "currentPlatform": "6.1", + "log": "https://some.url:43/root/run/4", "wantedApplication": { - "hash": "1.0.3-commit1", + "sourceUrl": "repository1/tree/commit1", "build": 3, + "commit": "commit1", "source": { "gitRepository": "repository1", - "gitBranch": "master", - "gitCommit": "commit1" - } + "gitCommit": "commit1", + "gitBranch": "master" + }, + "hash": "1.0.3-commit1" }, - "currentPlatform": "6.1", "currentApplication": { - "hash": "1.0.1-commit1", + "sourceUrl": "repository1/tree/commit1", "build": 1, + "commit": "commit1", "source": { "gitRepository": "repository1", - "gitBranch": "master", - "gitCommit": "commit1" - } + "gitCommit": "commit1", + "gitBranch": "master" + }, + "hash": "1.0.1-commit1" }, + "start": 2000, + "end": 2000, + "id": 4, "steps": { "deployInitialReal": "succeeded", "installInitialReal": "failed", - "deployReal": "unfinished", - "installReal": "unfinished", + "startTests": "unfinished", "deployTester": "succeeded", + "report": "succeeded", "installTester": "unfinished", - "startTests": "unfinished", + "deployReal": "unfinished", + "installReal": "unfinished", + "deactivateTester": "succeeded", "endTests": "unfinished", "copyVespaLogs": "succeeded", - "deactivateReal": "succeeded", - "deactivateTester": "succeeded", - "report": "succeeded" + "deactivateReal": "succeeded" }, "tasks": {}, - "log": "https://some.url:43/root/run/4" + "status": "installationFailed" }, "5": { - "id": 5, - "status": "installationFailed", - "start": 102000, - "end": 102000, "wantedPlatform": "6.1", + "currentPlatform": "6.1", + "log": "https://some.url:43/root/run/5", "wantedApplication": { - "hash": "1.0.3-commit1", + "sourceUrl": "repository1/tree/commit1", "build": 3, + "commit": "commit1", "source": { "gitRepository": "repository1", - "gitBranch": "master", - "gitCommit": "commit1" - } + "gitCommit": "commit1", + "gitBranch": "master" + }, + "hash": "1.0.3-commit1" }, - "currentPlatform": "6.1", "currentApplication": { - "hash": "1.0.1-commit1", + "sourceUrl": "repository1/tree/commit1", "build": 1, + "commit": "commit1", "source": { "gitRepository": "repository1", - "gitBranch": "master", - "gitCommit": "commit1" - } + "gitCommit": "commit1", + "gitBranch": "master" + }, + "hash": "1.0.1-commit1" }, + "start": 102000, + "end": 102000, + "id": 5, "steps": { "deployInitialReal": "succeeded", "installInitialReal": "failed", - "deployReal": "unfinished", - "installReal": "unfinished", + "startTests": "unfinished", "deployTester": "succeeded", + "report": "succeeded", "installTester": "unfinished", - "startTests": "unfinished", + "deployReal": "unfinished", + "installReal": "unfinished", + "deactivateTester": "succeeded", "endTests": "unfinished", "copyVespaLogs": "succeeded", - "deactivateReal": "succeeded", - "deactivateTester": "succeeded", - "report": "succeeded" + "deactivateReal": "succeeded" }, "tasks": {}, - "log": "https://some.url:43/root/run/5" + "status": "installationFailed" } } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/system-test-job.json b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/system-test-job.json index a572fa04781..2c12db0036b 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/system-test-job.json +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/restapi/application/responses/system-test-job.json @@ -12,7 +12,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "succeeded", @@ -45,7 +47,9 @@ "gitRepository": "repository1", "gitBranch": "master", "gitCommit": "commit1" - } + }, + "sourceUrl": "repository1/tree/commit1", + "commit": "commit1" }, "steps": { "deployTester": "unfinished", diff --git a/default_build_settings.cmake b/default_build_settings.cmake index 244883f01f4..ba961f39be8 100644 --- a/default_build_settings.cmake +++ b/default_build_settings.cmake @@ -32,16 +32,12 @@ endfunction() function(setup_vespa_default_build_settings_darwin) message("-- Setting up default build settings for darwin") - if(VESPA_COMPILER_VARIANT STREQUAL "gcc") - set(DEFAULT_VESPA_LLVM_VERSION "8" PARENT_SCOPE) - elseif(VESPA_COMPILER_VARIANT STREQUAL "clang") - set(DEFAULT_LLVM_INCLUDE_DIRECTORY "/usr/local/opt/llvm/include") - set(DEFAULT_LLVM_LINK_DIRECTORY "/usr/local/opt/llvm/lib") - set(DEFAULT_VESPA_LLVM_VERSION "9" PARENT_SCOPE) - elseif(VESPA_COMPILER_VARIANT STREQUAL "appleclang") + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") set(DEFAULT_LLVM_INCLUDE_DIRECTORY "/usr/local/opt/llvm/include") set(DEFAULT_LLVM_LINK_DIRECTORY "/usr/local/opt/llvm/lib") set(DEFAULT_VESPA_LLVM_VERSION "9" PARENT_SCOPE) + else() + set(DEFAULT_VESPA_LLVM_VERSION "8" PARENT_SCOPE) endif() set(DEFAULT_CMAKE_PREFIX_PATH "${VESPA_DEPS}" "/usr/local/opt/bison" "/usr/local/opt/flex" "/usr/local/opt/openssl@1.1" PARENT_SCOPE) set(DEFAULT_EXTRA_LINK_DIRECTORY "${VESPA_DEPS}/lib" "/usr/local/opt/bison/lib" "/usr/local/opt/flex/lib" "/usr/local/opt/icu4c/lib" "/usr/local/opt/openssl@1.1/lib") @@ -118,9 +114,9 @@ function(vespa_use_default_build_settings) set(DEFAULT_VESPA_USER "$ENV{USER}") endif() if(APPLE) - if(VESPA_COMPILER_VARIANT STREQUAL "clang") + if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") set(VESPA_DEPS "/opt/vespa-deps-clang") - elseif(VESPA_COMPILER_VARIANT STREQUAL "appleclang") + elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") set(VESPA_DEPS "/opt/vespa-deps-appleclang") endif() endif() @@ -244,11 +240,7 @@ function(vespa_use_default_cxx_compiler) endif() unset(DEFAULT_CMAKE_C_COMPILER) unset(DEFAULT_CMAKE_CXX_COMPILER) - if(NOT DEFINED VESPA_COMPILER_VARIANT) - set(VESPA_COMPILER_VARIANT "gcc") - set(VESPA_COMPILER_VARIANT "gcc" PARENT_SCOPE) - endif() - if(VESPA_COMPILER_VARIANT STREQUAL "gcc") + if(NOT DEFINED VESPA_COMPILER_VARIANT OR VESPA_COMPILER_VARIANT STREQUAL "gcc") if(APPLE) set(DEFAULT_CMAKE_C_COMPILER "/usr/local/bin/gcc-9") set(DEFAULT_CMAKE_CXX_COMPILER "/usr/local/bin/g++-9") diff --git a/hosted-api/src/main/java/ai/vespa/hosted/api/ControllerHttpClient.java b/hosted-api/src/main/java/ai/vespa/hosted/api/ControllerHttpClient.java index c5626f7d690..4559deddeda 100644 --- a/hosted-api/src/main/java/ai/vespa/hosted/api/ControllerHttpClient.java +++ b/hosted-api/src/main/java/ai/vespa/hosted/api/ControllerHttpClient.java @@ -291,6 +291,7 @@ public abstract class ControllerHttpClient { rootObject.setString("repository", submission.repository()); rootObject.setString("branch", submission.branch()); rootObject.setString("commit", submission.commit()); + submission.sourceUrl().ifPresent(url -> rootObject.setString("sourceUrl", url)); rootObject.setString("authorEmail", submission.authorEmail()); submission.projectId().ifPresent(projectId -> rootObject.setLong("projectId", projectId)); return toJson(slime); diff --git a/hosted-api/src/main/java/ai/vespa/hosted/api/Submission.java b/hosted-api/src/main/java/ai/vespa/hosted/api/Submission.java index fe2dbaf977e..6f392de86e7 100644 --- a/hosted-api/src/main/java/ai/vespa/hosted/api/Submission.java +++ b/hosted-api/src/main/java/ai/vespa/hosted/api/Submission.java @@ -2,6 +2,7 @@ package ai.vespa.hosted.api; import java.nio.file.Path; +import java.util.Optional; import java.util.OptionalLong; /** @@ -14,15 +15,18 @@ public class Submission { private final String repository; private final String branch; private final String commit; + private final Optional<String> sourceUrl; private final String authorEmail; private final Path applicationZip; private final Path applicationTestZip; private final OptionalLong projectId; - public Submission(String repository, String branch, String commit, String authorEmail, Path applicationZip, Path applicationTestZip, OptionalLong projectId) { + public Submission(String repository, String branch, String commit, Optional<String> sourceUrl, String authorEmail, + Path applicationZip, Path applicationTestZip, OptionalLong projectId) { this.repository = repository; this.branch = branch; this.commit = commit; + this.sourceUrl = sourceUrl; this.authorEmail = authorEmail; this.applicationZip = applicationZip; this.applicationTestZip = applicationTestZip; @@ -32,6 +36,7 @@ public class Submission { public String repository() { return repository; } public String branch() { return branch; } public String commit() { return commit; } + public Optional<String> sourceUrl() { return sourceUrl; } public String authorEmail() { return authorEmail; } public Path applicationZip() { return applicationZip; } public Path applicationTestZip() { return applicationTestZip; } diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericJsonModel.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericJsonModel.java index a1df38296ac..bd17a238607 100644 --- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericJsonModel.java +++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericJsonModel.java @@ -19,9 +19,11 @@ import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_ABSENT; */ @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(NON_ABSENT) -@JsonPropertyOrder({ "node", "services" }) +@JsonPropertyOrder({ "name", "node", "services" }) public class GenericJsonModel { - private static Logger log = Logger.getLogger(GenericJsonModel.class.getName()); + + @JsonProperty("name") + public String name; @JsonProperty("node") public GenericNode node; diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericJsonUtil.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericJsonUtil.java index 642081e3c8f..a2125abb6a9 100644 --- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericJsonUtil.java +++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericJsonUtil.java @@ -72,7 +72,7 @@ public class GenericJsonUtil { .get(); if (VESPA_NODE_SERVICE_ID.equals(serviceId)) { jsonModel.node = new GenericNode(genericService.timestamp, genericService.metrics); - jsonModel.node.name = nodeName; + jsonModel.name = nodeName; } else { genericServices.add(genericService); diff --git a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericNode.java b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericNode.java index 5b45ed6cdfc..4ed09d4bf69 100644 --- a/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericNode.java +++ b/metrics-proxy/src/main/java/ai/vespa/metricsproxy/metric/model/json/GenericNode.java @@ -18,9 +18,6 @@ import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_ABSENT; @JsonPropertyOrder({ "name", "timestamp", "metrics" }) public class GenericNode { - @JsonProperty("name") - public String name; - @JsonProperty("timestamp") public Long timestamp; diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/application/ApplicationMetricsHandlerTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/application/ApplicationMetricsHandlerTest.java index 2d12930bd0a..d1224e79e45 100644 --- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/application/ApplicationMetricsHandlerTest.java +++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/http/application/ApplicationMetricsHandlerTest.java @@ -117,7 +117,7 @@ public class ApplicationMetricsHandlerTest { assertEquals(1, jsonModel.nodes.size()); GenericJsonModel nodeModel = jsonModel.nodes.get(0); - assertEquals(MOCK_METRICS_PATH, nodeModel.node.name); + assertEquals(MOCK_METRICS_PATH, nodeModel.name); assertEquals(2, nodeModel.node.metrics.size()); assertEquals(16.222, nodeModel.node.metrics.get(0).values.get(CPU_METRIC), 0.0001d); } diff --git a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/GenericApplicationModelTest.java b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/GenericApplicationModelTest.java index 47d91fb57a3..c0abc3efb86 100644 --- a/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/GenericApplicationModelTest.java +++ b/metrics-proxy/src/test/java/ai/vespa/metricsproxy/metric/model/json/GenericApplicationModelTest.java @@ -33,7 +33,7 @@ public class GenericApplicationModelTest { // Do some sanity checking assertEquals(2, model.nodes.size()); GenericJsonModel node0Model = model.nodes.get(0); - assertEquals("node0", node0Model.node.name); + assertEquals("node0", node0Model.name); assertEquals(1, node0Model.services.size()); GenericService service = node0Model.services.get(0); assertEquals(1, service.metrics.size()); @@ -41,7 +41,7 @@ public class GenericApplicationModelTest { GenericJsonModel node1Model = model.nodes.get(1); GenericNode node1 = node1Model.node; - assertEquals("node1", node1.name); + assertEquals("node1", node1Model.name); assertEquals(32.444, node1.metrics.get(0).values.get("cpu.util"), 0.001d); assertThatSerializedModelEqualsTestFile(model); @@ -69,7 +69,7 @@ public class GenericApplicationModelTest { GenericJsonModel nodeModel = model.nodes.get(0); assertNotNull(nodeModel.node); - assertEquals("node0", nodeModel.node.name); + assertEquals("node0", nodeModel.name); assertEquals(1, nodeModel.node.metrics.size()); GenericMetrics nodeMetrics = nodeModel.node.metrics.get(0); assertEquals(1.234, nodeMetrics.values.get("node-metric"), 0.001d); diff --git a/metrics-proxy/src/test/resources/generic-application.json b/metrics-proxy/src/test/resources/generic-application.json index 231f86a9b3b..5ddd11962be 100644 --- a/metrics-proxy/src/test/resources/generic-application.json +++ b/metrics-proxy/src/test/resources/generic-application.json @@ -1,8 +1,8 @@ { "nodes": [ { + "name": "node0", "node": { - "name": "node0", "timestamp": 1234, "metrics": [ { @@ -36,8 +36,8 @@ ] }, { + "name": "node1", "node": { - "name": "node1", "timestamp": 1234, "metrics": [ { diff --git a/searchlib/abi-spec.json b/searchlib/abi-spec.json index 79752c5feaf..d058104bf1b 100644 --- a/searchlib/abi-spec.json +++ b/searchlib/abi-spec.json @@ -343,7 +343,9 @@ }, "com.yahoo.searchlib.rankingexpression.Reference": { "superClass": "com.yahoo.tensor.evaluation.Name", - "interfaces": [], + "interfaces": [ + "java.lang.Comparable" + ], "attributes": [ "public" ], @@ -362,7 +364,9 @@ "public boolean equals(java.lang.Object)", "public int hashCode()", "public java.lang.String toString()", - "public java.lang.StringBuilder toString(java.lang.StringBuilder, com.yahoo.searchlib.rankingexpression.rule.SerializationContext, java.util.Deque, com.yahoo.searchlib.rankingexpression.rule.CompositeNode)" + "public java.lang.StringBuilder toString(java.lang.StringBuilder, com.yahoo.searchlib.rankingexpression.rule.SerializationContext, java.util.Deque, com.yahoo.searchlib.rankingexpression.rule.CompositeNode)", + "public int compareTo(com.yahoo.searchlib.rankingexpression.Reference)", + "public bridge synthetic int compareTo(java.lang.Object)" ], "fields": [] }, diff --git a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/Reference.java b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/Reference.java index 3c537b53e9d..4622fb2c933 100644 --- a/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/Reference.java +++ b/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/Reference.java @@ -18,7 +18,7 @@ import java.util.Optional; * * @author bratseth */ -public class Reference extends Name { +public class Reference extends Name implements Comparable<Reference> { private final int hashCode; @@ -163,4 +163,9 @@ public class Reference extends Name { return b; } + @Override + public int compareTo(Reference o) { + return this.toString().compareTo(o.toString()); + } + } diff --git a/staging_vespalib/src/vespa/vespalib/metrics/bucket.cpp b/staging_vespalib/src/vespa/vespalib/metrics/bucket.cpp index fdca2b1a9cc..e212df5748f 100644 --- a/staging_vespalib/src/vespa/vespalib/metrics/bucket.cpp +++ b/staging_vespalib/src/vespa/vespalib/metrics/bucket.cpp @@ -2,6 +2,8 @@ #include "bucket.h" #include <assert.h> #include <map> +#include <vespa/vespalib/util/overload.h> +#include <vespa/vespalib/util/visit_ranges.h> namespace vespalib { namespace metrics { @@ -34,37 +36,24 @@ mergeFromSamples(const StableStore<typename T::sample_type> &source) } template<typename T> +struct IdxComparator { + bool operator() (const T& a, const T& b) { return a.idx < b.idx; } +}; + +template<typename T> std::vector<T> mergeVectors(const std::vector<T> &a, const std::vector<T> &b) { std::vector<T> result; - auto a_iter = a.begin(); - auto b_iter = b.begin(); - while (a_iter != a.end() && - b_iter != b.end()) - { - if (a_iter->idx < b_iter->idx) { - result.push_back(*a_iter); - ++a_iter; - } else if (b_iter->idx < a_iter->idx) { - result.push_back(*b_iter); - ++b_iter; - } else { - result.push_back(*a_iter); - result.back().merge(*b_iter); - ++a_iter; - ++b_iter; - } - } - while (a_iter != a.end()) { - result.push_back(*a_iter); - ++a_iter; - } - while (b_iter != b.end()) { - result.push_back(*b_iter); - ++b_iter; - } + visit_ranges(overload + { + [&result](visit_ranges_either, const T& x) { result.push_back(x); }, + [&result](visit_ranges_both, const T& x, const T& y) { + result.push_back(x); + result.back().merge(y); + } + }, a.begin(), a.end(), b.begin(), b.end(), IdxComparator<T>()); return result; } @@ -74,29 +63,18 @@ findMissing(const std::vector<T> &already, const std::vector<T> &complete) { std::vector<T> result; - auto a_iter = already.begin(); - auto c_iter = complete.begin(); - while (a_iter != already.end() && - c_iter != complete.end()) - { - if (a_iter->idx < c_iter->idx) { - // missing from "complete", should not happen - ++a_iter; - } else if (c_iter->idx < a_iter->idx) { - // missing this - result.push_back(*c_iter); - ++c_iter; - } else { - // already have this - ++a_iter; - ++c_iter; - } - } - while (c_iter != complete.end()) { - // missing this - result.push_back(*c_iter); - ++c_iter; - } + visit_ranges(overload + { + // missing from "complete", should not happen: + [&result](visit_ranges_first, const T&) { }, + // missing this: + [&result](visit_ranges_second, const T& x) { result.push_back(x); }, + // already have this: + [&result](visit_ranges_both, const T&, const T&) { } + }, + already.begin(), already.end(), + complete.begin(), complete.end(), + IdxComparator<T>()); return result; } diff --git a/vespa-maven-plugin/src/main/java/ai/vespa/hosted/plugin/SubmitMojo.java b/vespa-maven-plugin/src/main/java/ai/vespa/hosted/plugin/SubmitMojo.java index 3aee3a5ce96..80655cf1d36 100644 --- a/vespa-maven-plugin/src/main/java/ai/vespa/hosted/plugin/SubmitMojo.java +++ b/vespa-maven-plugin/src/main/java/ai/vespa/hosted/plugin/SubmitMojo.java @@ -6,6 +6,7 @@ import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import java.nio.file.Paths; +import java.util.Optional; import java.util.OptionalLong; /** @@ -34,6 +35,9 @@ public class SubmitMojo extends AbstractVespaMojo { @Parameter(property = "commit", defaultValue = "unknown") private String commit; + @Parameter(property = "sourceUrl") + private String sourceUrl; + @Parameter(property = "projectId") private Long projectId; @@ -41,7 +45,7 @@ public class SubmitMojo extends AbstractVespaMojo { public void doExecute() { applicationZip = firstNonBlank(applicationZip, projectPathOf("target", "application.zip")); applicationTestZip = firstNonBlank(applicationTestZip, projectPathOf("target", "application-test.zip")); - Submission submission = new Submission(repository, branch, commit, authorEmail, + Submission submission = new Submission(repository, branch, commit, Optional.ofNullable(sourceUrl), authorEmail, Paths.get(applicationZip), Paths.get(applicationTestZip), projectId == null ? OptionalLong.empty() : OptionalLong.of(projectId)); |