aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHåkon Hallingstad <hakon@yahooinc.com>2023-11-29 14:59:00 +0100
committerHåkon Hallingstad <hakon@yahooinc.com>2023-11-29 14:59:00 +0100
commit11941a9408e44cd57333a661177a56f2dd705443 (patch)
tree1e547e6b78e1dbd21c0fac093ddfe592bf5da914
parent6359834bc232523a4d8686e16f411fa148a649c2 (diff)
Define nessus-agent-group flag and make Dimension top-level class
-rw-r--r--configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/DefinedFlag.java3
-rw-r--r--configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/db/FlagsDbImplTest.java7
-rw-r--r--configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/http/FlagsHandlerTest.java6
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/application/TenantApplications.java2
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java36
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java2
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/Dimension.java120
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/FetchVector.java78
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/Flag.java6
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/FlagDefinition.java20
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/FlagImpl.java2
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/Flags.java55
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java34
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/UnboundFlag.java2
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/UnboundFlagImpl.java2
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/json/Condition.java11
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/json/DimensionHelper.java64
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/json/FetchVectorHelper.java7
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/json/ListCondition.java7
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/json/RelationalCondition.java11
-rw-r--r--flags/src/test/java/com/yahoo/vespa/flags/DimensionTest.java25
-rw-r--r--flags/src/test/java/com/yahoo/vespa/flags/FlagsTest.java20
-rw-r--r--flags/src/test/java/com/yahoo/vespa/flags/file/FlagDbFileTest.java3
-rw-r--r--flags/src/test/java/com/yahoo/vespa/flags/json/ConditionTest.java23
-rw-r--r--flags/src/test/java/com/yahoo/vespa/flags/json/FlagDataTest.java45
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java4
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainer.java4
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java8
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java8
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java16
31 files changed, 328 insertions, 305 deletions
diff --git a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/DefinedFlag.java b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/DefinedFlag.java
index 84ba451ac7f..c6e51e530b1 100644
--- a/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/DefinedFlag.java
+++ b/configserver-flags/src/main/java/com/yahoo/vespa/configserver/flags/http/DefinedFlag.java
@@ -8,7 +8,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
import com.yahoo.container.jdisc.HttpResponse;
import com.yahoo.jdisc.Response;
import com.yahoo.vespa.flags.FlagDefinition;
-import com.yahoo.vespa.flags.json.DimensionHelper;
import java.io.IOException;
import java.io.OutputStream;
@@ -42,7 +41,7 @@ public class DefinedFlag extends HttpResponse {
definitionNode.put("createdAt", flagDefinition.getCreatedAt().toString());
definitionNode.put("expiresAt", flagDefinition.getExpiresAt().toString());
ArrayNode dimensionsNode = definitionNode.putArray("dimensions");
- flagDefinition.getDimensions().forEach(dimension -> dimensionsNode.add(DimensionHelper.toWire(dimension)));
+ flagDefinition.getDimensions().forEach(dimension -> dimensionsNode.add(dimension.toWire()));
}
@Override
diff --git a/configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/db/FlagsDbImplTest.java b/configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/db/FlagsDbImplTest.java
index a82a6f7c599..c9c11e2b0e2 100644
--- a/configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/db/FlagsDbImplTest.java
+++ b/configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/db/FlagsDbImplTest.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.configserver.flags.db;
import com.yahoo.vespa.curator.mock.MockCurator;
+import com.yahoo.vespa.flags.Dimension;
import com.yahoo.vespa.flags.FetchVector;
import com.yahoo.vespa.flags.FlagId;
import com.yahoo.vespa.flags.JsonNodeRawFlag;
@@ -28,11 +29,11 @@ public class FlagsDbImplTest {
MockCurator curator = new MockCurator();
FlagsDbImpl db = new FlagsDbImpl(curator);
- var params = new Condition.CreateParams(FetchVector.Dimension.HOSTNAME).withValues("host1");
+ var params = new Condition.CreateParams(Dimension.HOSTNAME).withValues("host1");
Condition condition1 = WhitelistCondition.create(params);
Rule rule1 = new Rule(Optional.of(JsonNodeRawFlag.fromJson("13")), condition1);
FlagId flagId = new FlagId("id");
- FlagData data = new FlagData(flagId, new FetchVector().with(FetchVector.Dimension.ZONE_ID, "zone-a"), rule1);
+ FlagData data = new FlagData(flagId, new FetchVector().with(Dimension.ZONE_ID, "zone-a"), rule1);
db.setValue(flagId, data);
Optional<FlagData> dataCopy = db.getValue(flagId);
@@ -43,7 +44,7 @@ public class FlagsDbImplTest {
dataCopy.get().serializeToJson());
FlagId flagId2 = new FlagId("id2");
- FlagData data2 = new FlagData(flagId2, new FetchVector().with(FetchVector.Dimension.ZONE_ID, "zone-a"), rule1);
+ FlagData data2 = new FlagData(flagId2, new FetchVector().with(Dimension.ZONE_ID, "zone-a"), rule1);
db.setValue(flagId2, data2);
Map<FlagId, FlagData> flags = db.getAllFlagData();
assertEquals(flags.size(), 2);
diff --git a/configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/http/FlagsHandlerTest.java b/configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/http/FlagsHandlerTest.java
index 3d37117c002..1e477a6da6e 100644
--- a/configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/http/FlagsHandlerTest.java
+++ b/configserver-flags/src/test/java/com/yahoo/vespa/configserver/flags/http/FlagsHandlerTest.java
@@ -8,7 +8,7 @@ import com.yahoo.text.Utf8;
import com.yahoo.vespa.configserver.flags.FlagsDb;
import com.yahoo.vespa.configserver.flags.db.FlagsDbImpl;
import com.yahoo.vespa.curator.mock.MockCurator;
-import com.yahoo.vespa.flags.FetchVector;
+import com.yahoo.vespa.flags.Dimension;
import com.yahoo.vespa.flags.FlagId;
import com.yahoo.vespa.flags.Flags;
import com.yahoo.vespa.flags.UnboundBooleanFlag;
@@ -34,7 +34,7 @@ public class FlagsHandlerTest {
"id1", false, List.of("joe"), "2010-01-01", "2030-01-01", "desc1", "mod1");
private static final UnboundBooleanFlag FLAG2 = Flags.defineFeatureFlag(
"id2", true, List.of("joe"), "2010-01-01", "2030-01-01", "desc2", "mod2",
- FetchVector.Dimension.HOSTNAME, FetchVector.Dimension.INSTANCE_ID);
+ Dimension.HOSTNAME, Dimension.INSTANCE_ID);
private final FlagsDb flagsDb = new FlagsDbImpl(new MockCurator());
private final FlagsHandler handler = new FlagsHandler(FlagsHandler.testContext(), flagsDb);
@@ -54,7 +54,7 @@ public class FlagsHandlerTest {
void testDefined() {
try (Flags.Replacer replacer = Flags.clearFlagsForTesting()) {
fixUnusedWarning(replacer);
- Flags.defineFeatureFlag("id", false, List.of("joe"), "2010-01-01", "2030-01-01", "desc", "mod", FetchVector.Dimension.HOSTNAME);
+ Flags.defineFeatureFlag("id", false, List.of("joe"), "2010-01-01", "2030-01-01", "desc", "mod", Dimension.HOSTNAME);
verifySuccessfulRequest(Method.GET, "/defined", "",
"{\"id\":{\"description\":\"desc\",\"modification-effect\":\"mod\",\"owners\":[\"joe\"],\"createdAt\":\"2010-01-01T00:00:00Z\",\"expiresAt\":\"2030-01-01T00:00:00Z\",\"dimensions\":[\"hostname\"]}}");
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/application/TenantApplications.java b/configserver/src/main/java/com/yahoo/vespa/config/server/application/TenantApplications.java
index 5ac1b685b97..b83a8290cac 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/application/TenantApplications.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/application/TenantApplications.java
@@ -48,7 +48,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import static com.yahoo.vespa.curator.Curator.CompletionWaiter;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.INSTANCE_ID;
+import static com.yahoo.vespa.flags.Dimension.INSTANCE_ID;
import static java.util.stream.Collectors.toSet;
/**
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java
index 76af53eba90..59266dfffaf 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java
@@ -28,7 +28,7 @@ import com.yahoo.config.provision.HostName;
import com.yahoo.config.provision.Zone;
import com.yahoo.container.jdisc.secretstore.SecretStore;
import com.yahoo.vespa.config.server.tenant.SecretStoreExternalIdRetriever;
-import com.yahoo.vespa.flags.FetchVector;
+import com.yahoo.vespa.flags.Dimension;
import com.yahoo.vespa.flags.FlagSource;
import com.yahoo.vespa.flags.Flags;
import com.yahoo.vespa.flags.PermanentFlags;
@@ -46,7 +46,7 @@ import java.util.concurrent.ExecutorService;
import java.util.function.Predicate;
import static com.yahoo.vespa.config.server.ConfigServerSpec.fromConfig;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.CLUSTER_TYPE;
+import static com.yahoo.vespa.flags.Dimension.CLUSTER_TYPE;
/**
* Implementation of {@link ModelContext} for configserver.
@@ -307,10 +307,10 @@ public class ModelContextImpl implements ModelContext {
private static <V> V flagValue(FlagSource source, ApplicationId appId, Version vespaVersion, UnboundFlag<? extends V, ?, ?> flag) {
return flag.bindTo(source)
- .with(FetchVector.Dimension.INSTANCE_ID, appId.serializedForm())
- .with(FetchVector.Dimension.APPLICATION, appId.toSerializedFormWithoutInstance())
- .with(FetchVector.Dimension.VESPA_VERSION, vespaVersion.toFullString())
- .with(FetchVector.Dimension.TENANT_ID, appId.tenant().value())
+ .with(Dimension.INSTANCE_ID, appId.serializedForm())
+ .with(Dimension.APPLICATION, appId.toSerializedFormWithoutInstance())
+ .with(Dimension.VESPA_VERSION, vespaVersion.toFullString())
+ .with(Dimension.TENANT_ID, appId.tenant().value())
.boxedValue();
}
@@ -320,10 +320,10 @@ public class ModelContextImpl implements ModelContext {
ClusterSpec.Type clusterType,
UnboundFlag<? extends V, ?, ?> flag) {
return flag.bindTo(source)
- .with(FetchVector.Dimension.INSTANCE_ID, appId.serializedForm())
- .with(FetchVector.Dimension.APPLICATION, appId.toSerializedFormWithoutInstance())
- .with(FetchVector.Dimension.CLUSTER_TYPE, clusterType.name())
- .with(FetchVector.Dimension.VESPA_VERSION, vespaVersion.toFullString())
+ .with(Dimension.INSTANCE_ID, appId.serializedForm())
+ .with(Dimension.APPLICATION, appId.toSerializedFormWithoutInstance())
+ .with(Dimension.CLUSTER_TYPE, clusterType.name())
+ .with(Dimension.VESPA_VERSION, vespaVersion.toFullString())
.boxedValue();
}
@@ -333,10 +333,10 @@ public class ModelContextImpl implements ModelContext {
ClusterSpec.Id clusterId,
UnboundFlag<? extends V, ?, ?> flag) {
return flag.bindTo(source)
- .with(FetchVector.Dimension.INSTANCE_ID, appId.serializedForm())
- .with(FetchVector.Dimension.APPLICATION, appId.toSerializedFormWithoutInstance())
- .with(FetchVector.Dimension.CLUSTER_ID, clusterId.value())
- .with(FetchVector.Dimension.VESPA_VERSION, vespaVersion.toFullString())
+ .with(Dimension.INSTANCE_ID, appId.serializedForm())
+ .with(Dimension.APPLICATION, appId.toSerializedFormWithoutInstance())
+ .with(Dimension.CLUSTER_ID, clusterId.value())
+ .with(Dimension.VESPA_VERSION, vespaVersion.toFullString())
.boxedValue();
}
@@ -411,8 +411,8 @@ public class ModelContextImpl implements ModelContext {
this.tenantSecretStores = tenantSecretStores;
this.secretStore = secretStore;
this.jvmGCOptionsFlag = PermanentFlags.JVM_GC_OPTIONS.bindTo(flagSource)
- .with(FetchVector.Dimension.INSTANCE_ID, applicationId.serializedForm())
- .with(FetchVector.Dimension.APPLICATION, applicationId.toSerializedFormWithoutInstance());
+ .with(Dimension.INSTANCE_ID, applicationId.serializedForm())
+ .with(Dimension.APPLICATION, applicationId.toSerializedFormWithoutInstance());
this.allowDisableMtls = flagValue(flagSource, applicationId, PermanentFlags.ALLOW_DISABLE_MTLS);
this.operatorCertificates = operatorCertificates;
this.tlsCiphersOverride = flagValue(flagSource, applicationId, PermanentFlags.TLS_CIPHERS_OVERRIDE);
@@ -523,8 +523,8 @@ public class ModelContextImpl implements ModelContext {
private static <V> V flagValue(FlagSource source, ApplicationId appId, UnboundFlag<? extends V, ?, ?> flag) {
return flag.bindTo(source)
- .with(FetchVector.Dimension.INSTANCE_ID, appId.serializedForm())
- .with(FetchVector.Dimension.APPLICATION, appId.toSerializedFormWithoutInstance())
+ .with(Dimension.INSTANCE_ID, appId.serializedForm())
+ .with(Dimension.APPLICATION, appId.toSerializedFormWithoutInstance())
.boxedValue();
}
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java
index 99d5d23a87c..47b8215b52d 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionRepository.java
@@ -83,7 +83,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import static com.yahoo.vespa.curator.Curator.CompletionWaiter;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.INSTANCE_ID;
+import static com.yahoo.vespa.flags.Dimension.INSTANCE_ID;
import static java.nio.file.Files.readAttributes;
/**
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/Dimension.java b/flags/src/main/java/com/yahoo/vespa/flags/Dimension.java
new file mode 100644
index 00000000000..0f81fd4640b
--- /dev/null
+++ b/flags/src/main/java/com/yahoo/vespa/flags/Dimension.java
@@ -0,0 +1,120 @@
+// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.flags;
+
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * Flag dimensions.
+ *
+ * <ol>
+ * <li>A flag definition declares the dimensions it supports.*</li>
+ * <li>To <em>get</em> the value of a flag, a {@link FetchVector} should be built with the same set of dimensions.*</li>
+ * <li>To <em>set</em> the value of a flag, add a flag data <em>rule</em> with that value. The rule may be
+ * contain conditions that refer to these dimension.</li>
+ * </ol>
+ *
+ * <p>*) The system, cloud, environment, and zone dimensions are special: A flag should NOT list them in the
+ * flag definition (1),** and the dimensions are automatically set (2),**. These dimensions may always be referred to
+ * when overriding values, either as dimensions (3) or in dedicated files.</p>
+ * <p>**) The controller may want different flag values depending on cloud, environment, and/or zone.
+ * Disregard (*) for those dimensions: The relevant dimensions should be declared in the flag definition (1),
+ * and specified when getting the value (2).</p>
+ *
+ * @author hakonhall
+ */
+public enum Dimension {
+ /**
+ * Application from ApplicationId::toSerializedFormWithoutInstance() of the form tenant:applicationName.
+ * <p><em>WARNING: NOT ApplicationId</em> - see {@link #INSTANCE_ID}.</p>
+ */
+ APPLICATION("application"),
+
+ /** Machine architecture: either arm64 or x86_64. */
+ ARCHITECTURE("architecture"),
+
+ /** Whether "enclave" (or "inclave" or "exclave"), or not ("noclave"). */
+ CLAVE("clave"),
+
+ /**
+ * Cloud from com.yahoo.config.provision.CloudName::value, e.g. yahoo, aws, gcp.
+ *
+ * <p><em>Eager resolution</em>: This dimension is resolved before putting the flag data to the config server
+ * or controller, unless controller and the flag has declared this dimension.
+ */
+ CLOUD("cloud"),
+
+ /** Cloud account ID from com.yahoo.config.provision.CloudAccount::value, e.g. aws:123456789012 */
+ CLOUD_ACCOUNT("cloud-account"),
+
+ /** Cluster ID from com.yahoo.config.provision.ClusterSpec.Id::value, e.g. cluster-controllers, logserver. */
+ CLUSTER_ID("cluster-id"),
+
+ /** Cluster type from com.yahoo.config.provision.ClusterSpec.Type::name, e.g. content, container, admin */
+ CLUSTER_TYPE("cluster-type"),
+
+ /** Email address of user - provided by auth0 in console. */
+ CONSOLE_USER_EMAIL("console-user-email"),
+
+ /** Hosted Vespa environment from com.yahoo.config.provision.Environment::value, e.g. prod, staging, test. */
+ ENVIRONMENT("environment"),
+
+ /**
+ * Fully qualified hostname.
+ *
+ * <p>NOTE: There is seldom any need to set HOSTNAME, as it is always set implicitly (in {@link Flags})
+ * from {@code Defaults.getDefaults().vespaHostname()}. The hostname may e.g. be overridden when
+ * fetching flag value for a Docker container node.
+ */
+ HOSTNAME("hostname"),
+
+ /** Value from ApplicationId::serializedForm of the form tenant:applicationName:instance. */
+ INSTANCE_ID("instance"),
+
+ /** Node type from com.yahoo.config.provision.NodeType::name, e.g. tenant, host, confighost, controller, etc. */
+ NODE_TYPE("node-type"),
+
+ /**
+ * Hosted Vespa system from com.yahoo.config.provision.SystemName::value, e.g. main, cd, public, publiccd.
+ * <em>Eager resolution</em>, see {@link #CLOUD}.
+ */
+ SYSTEM("system"),
+
+ /** Value from TenantName::value, e.g. vespa-team */
+ TENANT_ID("tenant"),
+
+ /**
+ * Vespa version from Version::toFullString of the form Major.Minor.Micro.
+ *
+ * <p>NOTE: There is seldom any need to set VESPA_VERSION, as it is always set implicitly
+ * (in {@link Flags}) from {@link com.yahoo.component.Vtag#currentVersion}. The version COULD e.g.
+ * be overridden when fetching flag value for a Docker container node.
+ */
+ VESPA_VERSION("vespa-version"),
+
+ /**
+ * Virtual zone ID from com.yahoo.config.provision.zone.ZoneId::value of the form environment.region,
+ * see com.yahoo.config.provision.zone.ZoneApi::getVirtualId. <em>Eager resolution</em>, see {@link #CLOUD}.
+ */
+ ZONE_ID("zone");
+
+ private final String wireName;
+
+ private static final Map<String, Dimension> dimensionsByWireName =
+ Stream.of(values()).collect(Collectors.toMap(x -> x.wireName, Function.identity()));
+
+ public static Dimension fromWire(String wireName) {
+ Dimension dimension = dimensionsByWireName.get(wireName);
+ if (dimension == null) {
+ throw new IllegalArgumentException("Unknown serialized dimension: '" + wireName + "'");
+ }
+
+ return dimension;
+ }
+
+ Dimension(String wireName) { this.wireName = wireName; }
+
+ public String toWire() { return wireName; }
+}
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/FetchVector.java b/flags/src/main/java/com/yahoo/vespa/flags/FetchVector.java
index b5a944430f3..5639cbc0143 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/FetchVector.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/FetchVector.java
@@ -1,8 +1,6 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.flags;
-import com.yahoo.vespa.flags.json.DimensionHelper;
-
import java.util.Collection;
import java.util.EnumMap;
import java.util.Map;
@@ -18,80 +16,6 @@ import java.util.function.Consumer;
* @author hakonhall
*/
public class FetchVector {
- /**
- * Note: If this enum is changed, you must also change {@link DimensionHelper}.
- */
- public enum Dimension {
- /**
- * Application from ApplicationId::toSerializedFormWithoutInstance() of the form tenant:applicationName.
- * <p><em>WARNING: NOT ApplicationId</em> - see {@link #INSTANCE_ID}.</p>
- */
- APPLICATION,
-
- /**
- * Cloud from com.yahoo.config.provision.CloudName::value, e.g. yahoo, aws, gcp.
- *
- * <p><em>Eager resolution</em>: This dimension is resolved before putting the flag data to the config server
- * or controller, unless controller and the flag has declared this dimension.
- */
- CLOUD,
-
- /**
- * Cloud account ID from com.yahoo.config.provision.CloudAccount::value, e.g. aws:123456789012
- */
- CLOUD_ACCOUNT,
-
- /** Cluster ID from com.yahoo.config.provision.ClusterSpec.Id::value, e.g. cluster-controllers, logserver. */
- CLUSTER_ID,
-
- /** Cluster type from com.yahoo.config.provision.ClusterSpec.Type::name, e.g. content, container, admin */
- CLUSTER_TYPE,
-
- /** Email address of user - provided by auth0 in console. */
- CONSOLE_USER_EMAIL,
-
- /** Hosted Vespa environment from com.yahoo.config.provision.Environment::value, e.g. prod, staging, test. */
- ENVIRONMENT,
-
- /**
- * Fully qualified hostname.
- *
- * <p>NOTE: There is seldom any need to set HOSTNAME, as it is always set implicitly (in {@link Flags})
- * from {@code Defaults.getDefaults().vespaHostname()}. The hostname may e.g. be overridden when
- * fetching flag value for a Docker container node.
- */
- HOSTNAME,
-
- /** Value from ApplicationId::serializedForm of the form tenant:applicationName:instance. */
- INSTANCE_ID,
-
- /** Node type from com.yahoo.config.provision.NodeType::name, e.g. tenant, host, confighost, controller, etc. */
- NODE_TYPE,
-
- /**
- * Hosted Vespa system from com.yahoo.config.provision.SystemName::value, e.g. main, cd, public, publiccd.
- * <em>Eager resolution</em>, see {@link #CLOUD}.
- */
- SYSTEM,
-
- /** Value from TenantName::value, e.g. vespa-team */
- TENANT_ID,
-
- /**
- * Vespa version from Version::toFullString of the form Major.Minor.Micro.
- *
- * <p>NOTE: There is seldom any need to set VESPA_VERSION, as it is always set implicitly
- * (in {@link Flags}) from {@link com.yahoo.component.Vtag#currentVersion}. The version COULD e.g.
- * be overridden when fetching flag value for a Docker container node.
- */
- VESPA_VERSION,
-
- /**
- * Virtual zone ID from com.yahoo.config.provision.zone.ZoneId::value of the form environment.region,
- * see com.yahoo.config.provision.zone.ZoneApi::getVirtualId. <em>Eager resolution</em>, see {@link #CLOUD}.
- */
- ZONE_ID
- }
private final Map<Dimension, String> map;
@@ -115,7 +39,7 @@ public class FetchVector {
public boolean isEmpty() { return map.isEmpty(); }
- public boolean hasDimension(FetchVector.Dimension dimension) { return map.containsKey(dimension);}
+ public boolean hasDimension(Dimension dimension) { return map.containsKey(dimension);}
public Set<Dimension> dimensions() { return map.keySet(); }
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/Flag.java b/flags/src/main/java/com/yahoo/vespa/flags/Flag.java
index 0ca9dbb4cf7..7ca5066969f 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/Flag.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/Flag.java
@@ -21,10 +21,10 @@ public interface Flag<T, F> {
FlagSerializer<T> serializer();
/** Returns an immutable clone of the current object, except with the dimension set accordingly. */
- F with(FetchVector.Dimension dimension, String dimensionValue);
+ F with(Dimension dimension, String dimensionValue);
- /** Same as {@link #with(FetchVector.Dimension, String)} if value is present, and otherwise returns {@code this}. */
- default F with(FetchVector.Dimension dimension, Optional<String> dimensionValue) {
+ /** Same as {@link #with(Dimension, String)} if value is present, and otherwise returns {@code this}. */
+ default F with(Dimension dimension, Optional<String> dimensionValue) {
return dimensionValue.map(value -> with(dimension, value)).orElse(self());
}
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/FlagDefinition.java b/flags/src/main/java/com/yahoo/vespa/flags/FlagDefinition.java
index 837bc3b6e11..181c7ebd066 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/FlagDefinition.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/FlagDefinition.java
@@ -16,7 +16,7 @@ public class FlagDefinition {
private final Instant expiresAt;
private final String description;
private final String modificationEffect;
- private final List<FetchVector.Dimension> dimensions;
+ private final List<Dimension> dimensions;
public FlagDefinition(
UnboundFlag<?, ?, ?> unboundFlag,
@@ -25,7 +25,7 @@ public class FlagDefinition {
Instant expiresAt,
String description,
String modificationEffect,
- FetchVector.Dimension... dimensions) {
+ Dimension... dimensions) {
this.unboundFlag = unboundFlag;
this.owners = owners;
this.createdAt = createdAt;
@@ -40,7 +40,7 @@ public class FlagDefinition {
return unboundFlag;
}
- public List<FetchVector.Dimension> getDimensions() {
+ public List<Dimension> getDimensions() {
return dimensions;
}
@@ -58,7 +58,7 @@ public class FlagDefinition {
public Instant getExpiresAt() { return expiresAt; }
- private static void validate(List<String> owners, Instant createdAt, Instant expiresAt, List<FetchVector.Dimension> dimensions) {
+ private static void validate(List<String> owners, Instant createdAt, Instant expiresAt, List<Dimension> dimensions) {
if (expiresAt.isBefore(createdAt)) {
throw new IllegalArgumentException(
String.format(
@@ -74,14 +74,14 @@ public class FlagDefinition {
throw new IllegalArgumentException("Owner(s) must be specified");
}
- if (dimensions.contains(FetchVector.Dimension.CONSOLE_USER_EMAIL)) {
- Set<FetchVector.Dimension> disallowedCombinations = EnumSet.allOf(FetchVector.Dimension.class);
- disallowedCombinations.remove(FetchVector.Dimension.CONSOLE_USER_EMAIL);
- disallowedCombinations.remove(FetchVector.Dimension.INSTANCE_ID);
- disallowedCombinations.remove(FetchVector.Dimension.TENANT_ID);
+ if (dimensions.contains(Dimension.CONSOLE_USER_EMAIL)) {
+ Set<Dimension> disallowedCombinations = EnumSet.allOf(Dimension.class);
+ disallowedCombinations.remove(Dimension.CONSOLE_USER_EMAIL);
+ disallowedCombinations.remove(Dimension.INSTANCE_ID);
+ disallowedCombinations.remove(Dimension.TENANT_ID);
disallowedCombinations.retainAll(dimensions);
if (!disallowedCombinations.isEmpty())
- throw new IllegalArgumentException("Dimension " + FetchVector.Dimension.CONSOLE_USER_EMAIL + " cannot be combined with " + disallowedCombinations);
+ throw new IllegalArgumentException("Dimension " + Dimension.CONSOLE_USER_EMAIL + " cannot be combined with " + disallowedCombinations);
}
}
}
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/FlagImpl.java b/flags/src/main/java/com/yahoo/vespa/flags/FlagImpl.java
index 1b0464be7c6..496217c1e58 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/FlagImpl.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/FlagImpl.java
@@ -31,7 +31,7 @@ public abstract class FlagImpl<T, F extends FlagImpl<T, F>> implements Flag<T, F
}
@Override
- public F with(FetchVector.Dimension dimension, String dimensionValue) {
+ public F with(Dimension dimension, String dimensionValue) {
return factory.create(id, defaultValue, fetchVector.with(dimension, dimensionValue), serializer, source);
}
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
index f4096cc343f..acf70eb3e38 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
@@ -13,14 +13,18 @@ import java.util.Optional;
import java.util.TreeMap;
import java.util.function.Predicate;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.APPLICATION;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.CLOUD_ACCOUNT;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.CONSOLE_USER_EMAIL;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.HOSTNAME;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.INSTANCE_ID;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.NODE_TYPE;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.TENANT_ID;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.VESPA_VERSION;
+import static com.yahoo.vespa.flags.Dimension.APPLICATION;
+import static com.yahoo.vespa.flags.Dimension.ARCHITECTURE;
+import static com.yahoo.vespa.flags.Dimension.CLAVE;
+import static com.yahoo.vespa.flags.Dimension.CLOUD;
+import static com.yahoo.vespa.flags.Dimension.CLOUD_ACCOUNT;
+import static com.yahoo.vespa.flags.Dimension.CONSOLE_USER_EMAIL;
+import static com.yahoo.vespa.flags.Dimension.HOSTNAME;
+import static com.yahoo.vespa.flags.Dimension.INSTANCE_ID;
+import static com.yahoo.vespa.flags.Dimension.NODE_TYPE;
+import static com.yahoo.vespa.flags.Dimension.SYSTEM;
+import static com.yahoo.vespa.flags.Dimension.TENANT_ID;
+import static com.yahoo.vespa.flags.Dimension.VESPA_VERSION;
/**
* Definitions of feature flags.
@@ -34,8 +38,8 @@ import static com.yahoo.vespa.flags.FetchVector.Dimension.VESPA_VERSION;
* an unbound flag to a flag source produces a (bound) flag, e.g. {@link BooleanFlag} and {@link StringFlag}.</li>
* <li>If you would like your flag value to be dependent on e.g. the application ID, then 1. you should
* declare this in the unbound flag definition in this file (referring to
- * {@link FetchVector.Dimension#INSTANCE_ID}), and 2. specify the application ID when retrieving the value, e.g.
- * {@link BooleanFlag#with(FetchVector.Dimension, String)}. See {@link FetchVector} for more info.</li>
+ * {@link Dimension#INSTANCE_ID}), and 2. specify the application ID when retrieving the value, e.g.
+ * {@link BooleanFlag#with(Dimension, String)}. See {@link FetchVector} for more info.</li>
* </ol>
*
* <p>Once the code is in place, you can override the flag value. This depends on the flag source, but typically
@@ -76,6 +80,15 @@ public class Flags {
"Takes effect at redeployment (requires restart)",
INSTANCE_ID);
+ public static final UnboundStringFlag NESSUS_AGENT_GROUP = defineStringFlag(
+ "nessus-agent-group", "All",
+ List.of("hakonhall"), "2023-11-29", "2023-12-29",
+ "Either run nessusagent as before (All), or link against \"vespa-ci\"," +
+ " or disable the nessusagent (empty string \"\")",
+ "Takes effect after host admin restart",
+ (String value) -> value.equals("All") || value.equals("vespa-ci") || value.isEmpty(),
+ ARCHITECTURE, CLAVE);
+
public static final UnboundIntFlag MAX_UNCOMMITTED_MEMORY = defineIntFlag(
"max-uncommitted-memory", 130000,
List.of("geirst, baldersheim"), "2021-10-21", "2023-12-31",
@@ -410,14 +423,14 @@ public class Flags {
/** WARNING: public for testing: All flags should be defined in {@link Flags}. */
public static UnboundBooleanFlag defineFeatureFlag(String flagId, boolean defaultValue, List<String> owners,
String createdAt, String expiresAt, String description,
- String modificationEffect, FetchVector.Dimension... dimensions) {
+ String modificationEffect, Dimension... dimensions) {
return define(UnboundBooleanFlag::new, flagId, defaultValue, owners, createdAt, expiresAt, description, modificationEffect, dimensions);
}
/** WARNING: public for testing: All flags should be defined in {@link Flags}. */
public static UnboundStringFlag defineStringFlag(String flagId, String defaultValue, List<String> owners,
String createdAt, String expiresAt, String description,
- String modificationEffect, FetchVector.Dimension... dimensions) {
+ String modificationEffect, Dimension... dimensions) {
return defineStringFlag(flagId, defaultValue, owners,
createdAt, expiresAt, description,
modificationEffect, value -> true,
@@ -428,7 +441,7 @@ public class Flags {
public static UnboundStringFlag defineStringFlag(String flagId, String defaultValue, List<String> owners,
String createdAt, String expiresAt, String description,
String modificationEffect, Predicate<String> validator,
- FetchVector.Dimension... dimensions) {
+ Dimension... dimensions) {
return define((i, d, v) -> new UnboundStringFlag(i, d, v, validator),
flagId, defaultValue, owners, createdAt, expiresAt, description, modificationEffect, dimensions);
}
@@ -436,28 +449,28 @@ public class Flags {
/** WARNING: public for testing: All flags should be defined in {@link Flags}. */
public static UnboundIntFlag defineIntFlag(String flagId, int defaultValue, List<String> owners,
String createdAt, String expiresAt, String description,
- String modificationEffect, FetchVector.Dimension... dimensions) {
+ String modificationEffect, Dimension... dimensions) {
return define(UnboundIntFlag::new, flagId, defaultValue, owners, createdAt, expiresAt, description, modificationEffect, dimensions);
}
/** WARNING: public for testing: All flags should be defined in {@link Flags}. */
public static UnboundLongFlag defineLongFlag(String flagId, long defaultValue, List<String> owners,
String createdAt, String expiresAt, String description,
- String modificationEffect, FetchVector.Dimension... dimensions) {
+ String modificationEffect, Dimension... dimensions) {
return define(UnboundLongFlag::new, flagId, defaultValue, owners, createdAt, expiresAt, description, modificationEffect, dimensions);
}
/** WARNING: public for testing: All flags should be defined in {@link Flags}. */
public static UnboundDoubleFlag defineDoubleFlag(String flagId, double defaultValue, List<String> owners,
String createdAt, String expiresAt, String description,
- String modificationEffect, FetchVector.Dimension... dimensions) {
+ String modificationEffect, Dimension... dimensions) {
return define(UnboundDoubleFlag::new, flagId, defaultValue, owners, createdAt, expiresAt, description, modificationEffect, dimensions);
}
/** WARNING: public for testing: All flags should be defined in {@link Flags}. */
public static <T> UnboundJacksonFlag<T> defineJacksonFlag(String flagId, T defaultValue, Class<T> jacksonClass, List<String> owners,
String createdAt, String expiresAt, String description,
- String modificationEffect, FetchVector.Dimension... dimensions) {
+ String modificationEffect, Dimension... dimensions) {
return define((id2, defaultValue2, vector2) -> new UnboundJacksonFlag<>(id2, defaultValue2, vector2, jacksonClass),
flagId, defaultValue, owners, createdAt, expiresAt, description, modificationEffect, dimensions);
}
@@ -465,7 +478,7 @@ public class Flags {
/** WARNING: public for testing: All flags should be defined in {@link Flags}. */
public static <T> UnboundListFlag<T> defineListFlag(String flagId, List<T> defaultValue, Class<T> elementClass,
List<String> owners, String createdAt, String expiresAt,
- String description, String modificationEffect, FetchVector.Dimension... dimensions) {
+ String description, String modificationEffect, Dimension... dimensions) {
return define((fid, dval, fvec) -> new UnboundListFlag<>(fid, dval, elementClass, fvec),
flagId, defaultValue, owners, createdAt, expiresAt, description, modificationEffect, dimensions);
}
@@ -500,8 +513,8 @@ public class Flags {
* use them in the controller in this way.
* @param <T> The boxed type of the flag value, e.g. Boolean for flags guarding features.
* @param <U> The type of the unbound flag, e.g. UnboundBooleanFlag.
- * @return An unbound flag with {@link FetchVector.Dimension#HOSTNAME HOSTNAME} and
- * {@link FetchVector.Dimension#VESPA_VERSION VESPA_VERSION} already set. The ZONE environment
+ * @return An unbound flag with {@link Dimension#HOSTNAME HOSTNAME} and
+ * {@link Dimension#VESPA_VERSION VESPA_VERSION} already set. The ZONE environment
* is typically implicit.
*/
private static <T, U extends UnboundFlag<?, ?, ?>> U define(TypedUnboundFlagFactory<T, U> factory,
@@ -512,7 +525,7 @@ public class Flags {
String expiresAt,
String description,
String modificationEffect,
- FetchVector.Dimension[] dimensions) {
+ Dimension[] dimensions) {
FlagId id = new FlagId(flagId);
FetchVector vector = new FetchVector()
.with(HOSTNAME, Defaults.getDefaults().vespaHostname())
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java b/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java
index 1c50cc54964..acebca05fdb 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java
@@ -13,15 +13,15 @@ import java.util.Set;
import java.util.function.Predicate;
import java.util.regex.Pattern;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.INSTANCE_ID;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.CLUSTER_ID;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.CLUSTER_TYPE;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.CONSOLE_USER_EMAIL;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.HOSTNAME;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.NODE_TYPE;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.TENANT_ID;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.VESPA_VERSION;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.ZONE_ID;
+import static com.yahoo.vespa.flags.Dimension.INSTANCE_ID;
+import static com.yahoo.vespa.flags.Dimension.CLUSTER_ID;
+import static com.yahoo.vespa.flags.Dimension.CLUSTER_TYPE;
+import static com.yahoo.vespa.flags.Dimension.CONSOLE_USER_EMAIL;
+import static com.yahoo.vespa.flags.Dimension.HOSTNAME;
+import static com.yahoo.vespa.flags.Dimension.NODE_TYPE;
+import static com.yahoo.vespa.flags.Dimension.TENANT_ID;
+import static com.yahoo.vespa.flags.Dimension.VESPA_VERSION;
+import static com.yahoo.vespa.flags.Dimension.ZONE_ID;
/**
* Definition for permanent feature flags
@@ -417,42 +417,42 @@ public class PermanentFlags {
private PermanentFlags() {}
private static UnboundBooleanFlag defineFeatureFlag(
- String flagId, boolean defaultValue, String description, String modificationEffect, FetchVector.Dimension... dimensions) {
+ String flagId, boolean defaultValue, String description, String modificationEffect, Dimension... dimensions) {
return Flags.defineFeatureFlag(flagId, defaultValue, OWNERS, toString(CREATED_AT), toString(EXPIRES_AT), description, modificationEffect, dimensions);
}
private static UnboundStringFlag defineStringFlag(
- String flagId, String defaultValue, String description, String modificationEffect, FetchVector.Dimension... dimensions) {
+ String flagId, String defaultValue, String description, String modificationEffect, Dimension... dimensions) {
return Flags.defineStringFlag(flagId, defaultValue, OWNERS, toString(CREATED_AT), toString(EXPIRES_AT), description, modificationEffect, dimensions);
}
private static UnboundStringFlag defineStringFlag(
- String flagId, String defaultValue, String description, String modificationEffect, Predicate<String> validator, FetchVector.Dimension... dimensions) {
+ String flagId, String defaultValue, String description, String modificationEffect, Predicate<String> validator, Dimension... dimensions) {
return Flags.defineStringFlag(flagId, defaultValue, OWNERS, toString(CREATED_AT), toString(EXPIRES_AT), description, modificationEffect, validator, dimensions);
}
private static UnboundIntFlag defineIntFlag(
- String flagId, int defaultValue, String description, String modificationEffect, FetchVector.Dimension... dimensions) {
+ String flagId, int defaultValue, String description, String modificationEffect, Dimension... dimensions) {
return Flags.defineIntFlag(flagId, defaultValue, OWNERS, toString(CREATED_AT), toString(EXPIRES_AT), description, modificationEffect, dimensions);
}
private static UnboundLongFlag defineLongFlag(
- String flagId, long defaultValue, String description, String modificationEffect, FetchVector.Dimension... dimensions) {
+ String flagId, long defaultValue, String description, String modificationEffect, Dimension... dimensions) {
return Flags.defineLongFlag(flagId, defaultValue, OWNERS, toString(CREATED_AT), toString(EXPIRES_AT), description, modificationEffect, dimensions);
}
private static UnboundDoubleFlag defineDoubleFlag(
- String flagId, double defaultValue, String description, String modificationEffect, FetchVector.Dimension... dimensions) {
+ String flagId, double defaultValue, String description, String modificationEffect, Dimension... dimensions) {
return Flags.defineDoubleFlag(flagId, defaultValue, OWNERS, toString(CREATED_AT), toString(EXPIRES_AT), description, modificationEffect, dimensions);
}
private static <T> UnboundJacksonFlag<T> defineJacksonFlag(
- String flagId, T defaultValue, Class<T> jacksonClass, String description, String modificationEffect, FetchVector.Dimension... dimensions) {
+ String flagId, T defaultValue, Class<T> jacksonClass, String description, String modificationEffect, Dimension... dimensions) {
return Flags.defineJacksonFlag(flagId, defaultValue, jacksonClass, OWNERS, toString(CREATED_AT), toString(EXPIRES_AT), description, modificationEffect, dimensions);
}
private static <T> UnboundListFlag<T> defineListFlag(
- String flagId, List<T> defaultValue, Class<T> elementClass, String description, String modificationEffect, FetchVector.Dimension... dimensions) {
+ String flagId, List<T> defaultValue, Class<T> elementClass, String description, String modificationEffect, Dimension... dimensions) {
return Flags.defineListFlag(flagId, defaultValue, elementClass, OWNERS, toString(CREATED_AT), toString(EXPIRES_AT), description, modificationEffect, dimensions);
}
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/UnboundFlag.java b/flags/src/main/java/com/yahoo/vespa/flags/UnboundFlag.java
index edde650adc9..f6d4e080e82 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/UnboundFlag.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/UnboundFlag.java
@@ -18,7 +18,7 @@ public interface UnboundFlag<T, F extends Flag<T, F>, U extends UnboundFlag<T, F
FlagSerializer<T> serializer();
/** Returns a clone of the unbound flag, but with the dimension set accordingly. */
- U with(FetchVector.Dimension dimension, String dimensionValue);
+ U with(Dimension dimension, String dimensionValue);
/** Binds to a flag source, returning a (bound) flag. */
F bindTo(FlagSource source);
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/UnboundFlagImpl.java b/flags/src/main/java/com/yahoo/vespa/flags/UnboundFlagImpl.java
index a079bf734d7..d8936e17395 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/UnboundFlagImpl.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/UnboundFlagImpl.java
@@ -42,7 +42,7 @@ public abstract class UnboundFlagImpl<T, F extends Flag<T, F>, U extends Unbound
}
@Override
- public U with(FetchVector.Dimension dimension, String dimensionValue) {
+ public U with(Dimension dimension, String dimensionValue) {
return unboundFlagFactory.create(id, defaultValue, defaultFetchVector.with(dimension, dimensionValue));
}
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/json/Condition.java b/flags/src/main/java/com/yahoo/vespa/flags/json/Condition.java
index 2881e9ab9ad..247987e68f4 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/json/Condition.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/json/Condition.java
@@ -1,6 +1,7 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.flags.json;
+import com.yahoo.vespa.flags.Dimension;
import com.yahoo.vespa.flags.FetchVector;
import com.yahoo.vespa.flags.json.wire.WireCondition;
@@ -32,11 +33,11 @@ public interface Condition extends Predicate<FetchVector> {
}
class CreateParams {
- private final FetchVector.Dimension dimension;
+ private final Dimension dimension;
private List<String> values = List.of();
private Optional<String> predicate = Optional.empty();
- public CreateParams(FetchVector.Dimension dimension) { this.dimension = Objects.requireNonNull(dimension); }
+ public CreateParams(Dimension dimension) { this.dimension = Objects.requireNonNull(dimension); }
public CreateParams withValues(String... values) { return withValues(List.of(values)); }
public CreateParams withValues(List<String> values) {
@@ -49,7 +50,7 @@ public interface Condition extends Predicate<FetchVector> {
return this;
}
- public FetchVector.Dimension dimension() { return dimension; }
+ public Dimension dimension() { return dimension; }
public List<String> values() { return values; }
public Optional<String> predicate() { return predicate; }
@@ -69,7 +70,7 @@ public interface Condition extends Predicate<FetchVector> {
Condition.Type type = Condition.Type.fromWire(wireCondition.type);
Objects.requireNonNull(wireCondition.dimension);
- FetchVector.Dimension dimension = DimensionHelper.fromWire(wireCondition.dimension);
+ Dimension dimension = Dimension.fromWire(wireCondition.dimension);
var params = new CreateParams(dimension);
if (wireCondition.values != null) {
@@ -85,7 +86,7 @@ public interface Condition extends Predicate<FetchVector> {
Condition.Type type();
- FetchVector.Dimension dimension();
+ Dimension dimension();
CreateParams toCreateParams();
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/json/DimensionHelper.java b/flags/src/main/java/com/yahoo/vespa/flags/json/DimensionHelper.java
deleted file mode 100644
index 7298f090be2..00000000000
--- a/flags/src/main/java/com/yahoo/vespa/flags/json/DimensionHelper.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.flags.json;
-
-import com.yahoo.vespa.flags.FetchVector;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-/**
- * @author hakonhall
- */
-public class DimensionHelper {
-
- private static final Map<FetchVector.Dimension, String> serializedDimensions = new HashMap<>();
-
- static {
- // WARNING: If you ever change the serialized form of a dimension, ensure the new serialized
- // flag data are pushed out everywhere before removing support for old format, see VESPA-27760.
- serializedDimensions.put(FetchVector.Dimension.APPLICATION, "application");
- serializedDimensions.put(FetchVector.Dimension.CLOUD, "cloud");
- serializedDimensions.put(FetchVector.Dimension.CLOUD_ACCOUNT, "cloud-account");
- serializedDimensions.put(FetchVector.Dimension.CLUSTER_ID, "cluster-id");
- serializedDimensions.put(FetchVector.Dimension.CLUSTER_TYPE, "cluster-type");
- serializedDimensions.put(FetchVector.Dimension.CONSOLE_USER_EMAIL, "console-user-email");
- serializedDimensions.put(FetchVector.Dimension.ENVIRONMENT, "environment");
- serializedDimensions.put(FetchVector.Dimension.HOSTNAME, "hostname");
- serializedDimensions.put(FetchVector.Dimension.INSTANCE_ID, "instance");
- serializedDimensions.put(FetchVector.Dimension.NODE_TYPE, "node-type");
- serializedDimensions.put(FetchVector.Dimension.SYSTEM, "system");
- serializedDimensions.put(FetchVector.Dimension.TENANT_ID, "tenant");
- serializedDimensions.put(FetchVector.Dimension.VESPA_VERSION, "vespa-version");
- serializedDimensions.put(FetchVector.Dimension.ZONE_ID, "zone");
-
- if (serializedDimensions.size() != FetchVector.Dimension.values().length) {
- throw new IllegalStateException(FetchVectorHelper.class.getName() + " is not in sync with " +
- FetchVector.Dimension.class.getName());
- }
- }
-
- private static final Map<String, FetchVector.Dimension> deserializedDimensions = serializedDimensions.
- entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
-
- public static String toWire(FetchVector.Dimension dimension) {
- String serializedDimension = serializedDimensions.get(dimension);
- if (serializedDimension == null) {
- throw new IllegalArgumentException("Unsupported dimension (please add it): '" + dimension + "'");
- }
-
- return serializedDimension;
- }
-
- public static FetchVector.Dimension fromWire(String serializedDimension) {
- FetchVector.Dimension dimension = deserializedDimensions.get(serializedDimension);
- if (dimension == null) {
- throw new IllegalArgumentException("Unknown serialized dimension: '" + serializedDimension + "'");
- }
-
- return dimension;
- }
-
- private DimensionHelper() { }
-
-}
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/json/FetchVectorHelper.java b/flags/src/main/java/com/yahoo/vespa/flags/json/FetchVectorHelper.java
index 31ba0e1e6cf..97ea4695481 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/json/FetchVectorHelper.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/json/FetchVectorHelper.java
@@ -1,6 +1,7 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.flags.json;
+import com.yahoo.vespa.flags.Dimension;
import com.yahoo.vespa.flags.FetchVector;
import java.util.Map;
@@ -12,17 +13,17 @@ import java.util.stream.Collectors;
public class FetchVectorHelper {
public static Map<String, String> toWire(FetchVector vector) {
- Map<FetchVector.Dimension, String> map = vector.toMap();
+ Map<Dimension, String> map = vector.toMap();
if (map.isEmpty()) return null;
return map.entrySet().stream().collect(Collectors.toMap(
- entry -> DimensionHelper.toWire(entry.getKey()),
+ entry -> entry.getKey().toWire(),
Map.Entry::getValue));
}
public static FetchVector fromWire(Map<String, String> wireMap) {
if (wireMap == null) return new FetchVector();
return FetchVector.fromMap(wireMap.entrySet().stream().collect(Collectors.toMap(
- entry -> DimensionHelper.fromWire(entry.getKey()),
+ entry -> Dimension.fromWire(entry.getKey()),
Map.Entry::getValue)));
}
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/json/ListCondition.java b/flags/src/main/java/com/yahoo/vespa/flags/json/ListCondition.java
index 12a10298787..7e71bb10a46 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/json/ListCondition.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/json/ListCondition.java
@@ -1,6 +1,7 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.flags.json;
+import com.yahoo.vespa.flags.Dimension;
import com.yahoo.vespa.flags.FetchVector;
import com.yahoo.vespa.flags.json.wire.WireCondition;
@@ -12,7 +13,7 @@ import java.util.Objects;
*/
public abstract class ListCondition implements Condition {
private final Condition.Type type;
- private final FetchVector.Dimension dimension;
+ private final Dimension dimension;
private final List<String> values;
private final boolean isWhitelist;
@@ -33,7 +34,7 @@ public abstract class ListCondition implements Condition {
}
@Override
- public FetchVector.Dimension dimension() {
+ public Dimension dimension() {
return dimension;
}
@@ -52,7 +53,7 @@ public abstract class ListCondition implements Condition {
public WireCondition toWire() {
var condition = new WireCondition();
condition.type = type.toWire();
- condition.dimension = DimensionHelper.toWire(dimension);
+ condition.dimension = dimension.toWire();
condition.values = values.isEmpty() ? null : values;
return condition;
}
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/json/RelationalCondition.java b/flags/src/main/java/com/yahoo/vespa/flags/json/RelationalCondition.java
index 49dc7c75752..18d1052d43c 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/json/RelationalCondition.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/json/RelationalCondition.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.flags.json;
import com.yahoo.component.Version;
+import com.yahoo.vespa.flags.Dimension;
import com.yahoo.vespa.flags.FetchVector;
import com.yahoo.vespa.flags.json.wire.WireCondition;
@@ -14,7 +15,7 @@ import java.util.function.Predicate;
public class RelationalCondition implements Condition {
private final RelationalPredicate relationalPredicate;
private final Predicate<String> predicate;
- private final FetchVector.Dimension dimension;
+ private final Dimension dimension;
public static RelationalCondition create(CreateParams params) {
if (!params.values().isEmpty()) {
@@ -37,12 +38,12 @@ public class RelationalCondition implements Condition {
return new RelationalCondition(relationalPredicate, p, params.dimension());
default:
throw new IllegalArgumentException(RelationalCondition.class.getSimpleName() +
- " not supported for dimension " + FetchVector.Dimension.VESPA_VERSION.name());
+ " not supported for dimension " + Dimension.VESPA_VERSION.name());
}
}
private RelationalCondition(RelationalPredicate relationalPredicate, Predicate<String> predicate,
- FetchVector.Dimension dimension) {
+ Dimension dimension) {
this.relationalPredicate = relationalPredicate;
this.predicate = predicate;
this.dimension = dimension;
@@ -54,7 +55,7 @@ public class RelationalCondition implements Condition {
}
@Override
- public FetchVector.Dimension dimension() {
+ public Dimension dimension() {
return dimension;
}
@@ -76,7 +77,7 @@ public class RelationalCondition implements Condition {
public WireCondition toWire() {
var condition = new WireCondition();
condition.type = Condition.Type.RELATIONAL.toWire();
- condition.dimension = DimensionHelper.toWire(dimension);
+ condition.dimension = dimension.toWire();
condition.predicate = relationalPredicate.toWire();
return condition;
}
diff --git a/flags/src/test/java/com/yahoo/vespa/flags/DimensionTest.java b/flags/src/test/java/com/yahoo/vespa/flags/DimensionTest.java
new file mode 100644
index 00000000000..11687265a05
--- /dev/null
+++ b/flags/src/test/java/com/yahoo/vespa/flags/DimensionTest.java
@@ -0,0 +1,25 @@
+// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.flags;
+
+/**
+ * @author hakonhall
+ */
+class DimensionTest {
+ /**
+ * A compile-time test: If this breaks you have most likely added (or removed) a dimension?
+ * If so you need to update the following:</p>
+ *
+ * <ul>
+ * <li>Dimension validation in SystemFlagsDataArchive</li>
+ * <li>Flag edit documenting dimension list in EditFlagDataCommandTest</li>
+ * </ul>
+ */
+ @SuppressWarnings("unused")
+ public String remember_to_update_SystemFlagsDataArchive(Dimension dimension) {
+ return switch (dimension) {
+ case APPLICATION, ARCHITECTURE, CLAVE, CLOUD, CLOUD_ACCOUNT, CLUSTER_ID, CLUSTER_TYPE,
+ CONSOLE_USER_EMAIL, ENVIRONMENT, HOSTNAME, INSTANCE_ID, NODE_TYPE, SYSTEM, TENANT_ID,
+ VESPA_VERSION, ZONE_ID -> dimension.toWire();
+ };
+ }
+} \ No newline at end of file
diff --git a/flags/src/test/java/com/yahoo/vespa/flags/FlagsTest.java b/flags/src/test/java/com/yahoo/vespa/flags/FlagsTest.java
index d3a5406bead..d48e8ec9c8b 100644
--- a/flags/src/test/java/com/yahoo/vespa/flags/FlagsTest.java
+++ b/flags/src/test/java/com/yahoo/vespa/flags/FlagsTest.java
@@ -32,8 +32,8 @@ public class FlagsTest {
final boolean defaultValue = false;
FlagSource source = mock(FlagSource.class);
BooleanFlag booleanFlag = Flags.defineFeatureFlag("id", defaultValue, List.of("owner"), "1970-01-01", "2100-01-01", "description",
- "modification effect", FetchVector.Dimension.ZONE_ID, FetchVector.Dimension.HOSTNAME)
- .with(FetchVector.Dimension.ZONE_ID, "a-zone")
+ "modification effect", Dimension.ZONE_ID, Dimension.HOSTNAME)
+ .with(Dimension.ZONE_ID, "a-zone")
.bindTo(source);
assertThat(booleanFlag.id().toString(), equalTo("id"));
@@ -44,31 +44,31 @@ public class FlagsTest {
ArgumentCaptor<FetchVector> vector = ArgumentCaptor.forClass(FetchVector.class);
verify(source).fetch(any(), vector.capture());
// hostname is set by default
- Optional<String> hostname = vector.getValue().getValue(FetchVector.Dimension.HOSTNAME);
+ Optional<String> hostname = vector.getValue().getValue(Dimension.HOSTNAME);
assertTrue(hostname.isPresent());
assertFalse(hostname.get().isEmpty());
// zone is set because it was set on the unbound flag above
- assertThat(vector.getValue().getValue(FetchVector.Dimension.ZONE_ID), is(Optional.of("a-zone")));
+ assertThat(vector.getValue().getValue(Dimension.ZONE_ID), is(Optional.of("a-zone")));
// application and node type are not set
- assertThat(vector.getValue().getValue(FetchVector.Dimension.INSTANCE_ID), is(Optional.empty()));
- assertThat(vector.getValue().getValue(FetchVector.Dimension.NODE_TYPE), is(Optional.empty()));
+ assertThat(vector.getValue().getValue(Dimension.INSTANCE_ID), is(Optional.empty()));
+ assertThat(vector.getValue().getValue(Dimension.NODE_TYPE), is(Optional.empty()));
RawFlag rawFlag = mock(RawFlag.class);
when(source.fetch(eq(new FlagId("id")), any())).thenReturn(Optional.of(rawFlag));
when(rawFlag.asJsonNode()).thenReturn(BooleanNode.getTrue());
// raw flag deserializes to true
- assertThat(booleanFlag.with(FetchVector.Dimension.INSTANCE_ID, "an-app").value(), equalTo(true));
+ assertThat(booleanFlag.with(Dimension.INSTANCE_ID, "an-app").value(), equalTo(true));
verify(source, times(2)).fetch(any(), vector.capture());
// application was set on the (bound) flag.
- assertThat(vector.getValue().getValue(FetchVector.Dimension.INSTANCE_ID), is(Optional.of("an-app")));
+ assertThat(vector.getValue().getValue(Dimension.INSTANCE_ID), is(Optional.of("an-app")));
}
@Test
void testString() {
testGeneric(Flags.defineStringFlag("string-id", "default value", List.of("owner"), "1970-01-01", "2100-01-01", "description",
- "modification effect", FetchVector.Dimension.ZONE_ID, FetchVector.Dimension.HOSTNAME),
+ "modification effect", Dimension.ZONE_ID, Dimension.HOSTNAME),
"other value");
}
@@ -100,7 +100,7 @@ public class FlagsTest {
instance.string = "foo";
testGeneric(Flags.defineJacksonFlag("jackson-id", defaultInstance, ExampleJacksonClass.class,
- List.of("owner"), "1970-01-01", "2100-01-01", "description", "modification effect", FetchVector.Dimension.HOSTNAME),
+ List.of("owner"), "1970-01-01", "2100-01-01", "description", "modification effect", Dimension.HOSTNAME),
instance);
testGeneric(Flags.defineListFlag("jackson-list-id", List.of(defaultInstance), ExampleJacksonClass.class, List.of("owner"), "1970-01-01", "2100-01-01", "desc", "mod"),
diff --git a/flags/src/test/java/com/yahoo/vespa/flags/file/FlagDbFileTest.java b/flags/src/test/java/com/yahoo/vespa/flags/file/FlagDbFileTest.java
index 8bf0014cbfe..4ea4f8ab638 100644
--- a/flags/src/test/java/com/yahoo/vespa/flags/file/FlagDbFileTest.java
+++ b/flags/src/test/java/com/yahoo/vespa/flags/file/FlagDbFileTest.java
@@ -1,6 +1,7 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.flags.file;
+import com.yahoo.vespa.flags.Dimension;
import com.yahoo.vespa.flags.FetchVector;
import com.yahoo.vespa.flags.FlagId;
import com.yahoo.vespa.flags.json.FlagData;
@@ -55,7 +56,7 @@ public class FlagDbFileTest {
// Changing value of id1, removing id2, adding id3
dataMap.remove(id2);
- FlagData newData1 = new FlagData(id1, new FetchVector().with(FetchVector.Dimension.HOSTNAME, "h1"));
+ FlagData newData1 = new FlagData(id1, new FetchVector().with(Dimension.HOSTNAME, "h1"));
dataMap.put(id1, newData1);
FlagId id3 = new FlagId("id3");
FlagData data3 = new FlagData(id3, new FetchVector());
diff --git a/flags/src/test/java/com/yahoo/vespa/flags/json/ConditionTest.java b/flags/src/test/java/com/yahoo/vespa/flags/json/ConditionTest.java
index a1cc2e99cbc..b283cfef0a5 100644
--- a/flags/src/test/java/com/yahoo/vespa/flags/json/ConditionTest.java
+++ b/flags/src/test/java/com/yahoo/vespa/flags/json/ConditionTest.java
@@ -1,6 +1,7 @@
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.flags.json;
+import com.yahoo.vespa.flags.Dimension;
import com.yahoo.vespa.flags.FetchVector;
import org.junit.jupiter.api.Test;
@@ -15,23 +16,23 @@ public class ConditionTest {
@Test
void testWhitelist() {
String hostname1 = "host1";
- var params = new Condition.CreateParams(FetchVector.Dimension.HOSTNAME).withValues(hostname1);
+ var params = new Condition.CreateParams(Dimension.HOSTNAME).withValues(hostname1);
Condition condition = WhitelistCondition.create(params);
assertFalse(condition.test(new FetchVector()));
- assertFalse(condition.test(new FetchVector().with(FetchVector.Dimension.INSTANCE_ID, "foo")));
- assertFalse(condition.test(new FetchVector().with(FetchVector.Dimension.HOSTNAME, "bar")));
- assertTrue(condition.test(new FetchVector().with(FetchVector.Dimension.HOSTNAME, hostname1)));
+ assertFalse(condition.test(new FetchVector().with(Dimension.INSTANCE_ID, "foo")));
+ assertFalse(condition.test(new FetchVector().with(Dimension.HOSTNAME, "bar")));
+ assertTrue(condition.test(new FetchVector().with(Dimension.HOSTNAME, hostname1)));
}
@Test
void testBlacklist() {
String hostname1 = "host1";
- var params = new Condition.CreateParams(FetchVector.Dimension.HOSTNAME).withValues(hostname1);
+ var params = new Condition.CreateParams(Dimension.HOSTNAME).withValues(hostname1);
Condition condition = BlacklistCondition.create(params);
assertTrue(condition.test(new FetchVector()));
- assertTrue(condition.test(new FetchVector().with(FetchVector.Dimension.INSTANCE_ID, "foo")));
- assertTrue(condition.test(new FetchVector().with(FetchVector.Dimension.HOSTNAME, "bar")));
- assertFalse(condition.test(new FetchVector().with(FetchVector.Dimension.HOSTNAME, hostname1)));
+ assertTrue(condition.test(new FetchVector().with(Dimension.INSTANCE_ID, "foo")));
+ assertTrue(condition.test(new FetchVector().with(Dimension.HOSTNAME, "bar")));
+ assertFalse(condition.test(new FetchVector().with(Dimension.HOSTNAME, hostname1)));
}
@Test
@@ -44,7 +45,7 @@ public class ConditionTest {
// Test with empty fetch vector along vespa version dimension (this should never happen as the
// version is always available through Vtag, although Vtag has a dummy version number for e.g.
// locally run unit tests that hasn't set the release Vespa version).
- var params = new Condition.CreateParams(FetchVector.Dimension.VESPA_VERSION).withPredicate(">=7.1.2");
+ var params = new Condition.CreateParams(Dimension.VESPA_VERSION).withPredicate(">=7.1.2");
Condition condition = RelationalCondition.create(params);
assertFalse(condition.test(new FetchVector()));
}
@@ -56,8 +57,8 @@ public class ConditionTest {
}
private boolean vespaVersionCondition(String vespaVersion, String predicate) {
- var params = new Condition.CreateParams(FetchVector.Dimension.VESPA_VERSION).withPredicate(predicate);
+ var params = new Condition.CreateParams(Dimension.VESPA_VERSION).withPredicate(predicate);
Condition condition = RelationalCondition.create(params);
- return condition.test(new FetchVector().with(FetchVector.Dimension.VESPA_VERSION, vespaVersion));
+ return condition.test(new FetchVector().with(Dimension.VESPA_VERSION, vespaVersion));
}
}
diff --git a/flags/src/test/java/com/yahoo/vespa/flags/json/FlagDataTest.java b/flags/src/test/java/com/yahoo/vespa/flags/json/FlagDataTest.java
index 98c99231237..d19d262e593 100644
--- a/flags/src/test/java/com/yahoo/vespa/flags/json/FlagDataTest.java
+++ b/flags/src/test/java/com/yahoo/vespa/flags/json/FlagDataTest.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.flags.json;
import com.yahoo.text.JSON;
+import com.yahoo.vespa.flags.Dimension;
import com.yahoo.vespa.flags.FetchVector;
import com.yahoo.vespa.flags.RawFlag;
import org.junit.jupiter.api.Test;
@@ -61,27 +62,27 @@ public class FlagDataTest {
// First rule matches only if both conditions match
verify(Optional.of("false"), vector
- .with(FetchVector.Dimension.HOSTNAME, "host1")
- .with(FetchVector.Dimension.INSTANCE_ID, "app2"));
+ .with(Dimension.HOSTNAME, "host1")
+ .with(Dimension.INSTANCE_ID, "app2"));
verify(Optional.of("true"), vector
- .with(FetchVector.Dimension.HOSTNAME, "host1")
- .with(FetchVector.Dimension.INSTANCE_ID, "app3"));
+ .with(Dimension.HOSTNAME, "host1")
+ .with(Dimension.INSTANCE_ID, "app3"));
// Verify unsetting a dimension with null works.
verify(Optional.of("true"), vector
- .with(FetchVector.Dimension.HOSTNAME, "host1")
- .with(FetchVector.Dimension.INSTANCE_ID, "app3")
- .with(FetchVector.Dimension.INSTANCE_ID, null));
+ .with(Dimension.HOSTNAME, "host1")
+ .with(Dimension.INSTANCE_ID, "app3")
+ .with(Dimension.INSTANCE_ID, null));
// No rules apply if zone is overridden to an unknown zone
- verify(Optional.empty(), vector.with(FetchVector.Dimension.ZONE_ID, "unknown zone"));
+ verify(Optional.empty(), vector.with(Dimension.ZONE_ID, "unknown zone"));
}
@Test
void testPartialResolve() {
FlagData data = FlagData.deserialize(json);
assertEquals(data.partialResolve(vector), data);
- assertEquals(data.partialResolve(vector.with(FetchVector.Dimension.INSTANCE_ID, "app1")),
+ assertEquals(data.partialResolve(vector.with(Dimension.INSTANCE_ID, "app1")),
FlagData.deserialize("""
{
"id": "id1",
@@ -102,7 +103,7 @@ public class FlagDataTest {
}
}"""));
- assertEquals(data.partialResolve(vector.with(FetchVector.Dimension.INSTANCE_ID, "app1")),
+ assertEquals(data.partialResolve(vector.with(Dimension.INSTANCE_ID, "app1")),
FlagData.deserialize("""
{
"id": "id1",
@@ -123,7 +124,7 @@ public class FlagDataTest {
}
}"""));
- assertEquals(data.partialResolve(vector.with(FetchVector.Dimension.INSTANCE_ID, "app3")),
+ assertEquals(data.partialResolve(vector.with(Dimension.INSTANCE_ID, "app3")),
FlagData.deserialize("""
{
"id": "id1",
@@ -154,8 +155,8 @@ public class FlagDataTest {
}
}"""));
- assertEquals(data.partialResolve(vector.with(FetchVector.Dimension.INSTANCE_ID, "app3")
- .with(FetchVector.Dimension.HOSTNAME, "host1")),
+ assertEquals(data.partialResolve(vector.with(Dimension.INSTANCE_ID, "app3")
+ .with(Dimension.HOSTNAME, "host1")),
FlagData.deserialize("""
{
"id": "id1",
@@ -169,8 +170,8 @@ public class FlagDataTest {
}
}"""));
- assertEquals(data.partialResolve(vector.with(FetchVector.Dimension.INSTANCE_ID, "app3")
- .with(FetchVector.Dimension.HOSTNAME, "host3")),
+ assertEquals(data.partialResolve(vector.with(Dimension.INSTANCE_ID, "app3")
+ .with(Dimension.HOSTNAME, "host3")),
FlagData.deserialize("""
{
"id": "id1",
@@ -191,9 +192,9 @@ public class FlagDataTest {
}
}"""));
- assertEquals(data.partialResolve(vector.with(FetchVector.Dimension.INSTANCE_ID, "app3")
- .with(FetchVector.Dimension.HOSTNAME, "host3")
- .with(FetchVector.Dimension.ZONE_ID, "zone2")),
+ assertEquals(data.partialResolve(vector.with(Dimension.INSTANCE_ID, "app3")
+ .with(Dimension.HOSTNAME, "host3")
+ .with(Dimension.ZONE_ID, "zone2")),
FlagData.deserialize("""
{
"id": "id1",
@@ -204,9 +205,9 @@ public class FlagDataTest {
]
}"""));
- FlagData fullyResolved = data.partialResolve(vector.with(FetchVector.Dimension.INSTANCE_ID, "app3")
- .with(FetchVector.Dimension.HOSTNAME, "host3")
- .with(FetchVector.Dimension.ZONE_ID, "zone3"));
+ FlagData fullyResolved = data.partialResolve(vector.with(Dimension.INSTANCE_ID, "app3")
+ .with(Dimension.HOSTNAME, "host3")
+ .with(Dimension.ZONE_ID, "zone3"));
assertEquals(fullyResolved, FlagData.deserialize("""
{
"id": "id1"
@@ -265,7 +266,7 @@ public class FlagDataTest {
}""";
FlagData data = FlagData.deserialize(json);
assertTrue(JSON.equals(data.serializeToJson(), json));
- FlagData flagData = data.partialResolve(vector.with(FetchVector.Dimension.CLOUD, "gcp"));
+ FlagData flagData = data.partialResolve(vector.with(Dimension.CLOUD, "gcp"));
assertEquals(flagData, new FlagData(data.id(), new FetchVector(), List.of()));
assertTrue(flagData.isEmpty());
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java
index 620026c4ac6..b29bfd9af62 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/AutoscalingMaintainer.java
@@ -8,7 +8,7 @@ import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Deployer;
import com.yahoo.jdisc.Metric;
import com.yahoo.vespa.flags.BooleanFlag;
-import com.yahoo.vespa.flags.FetchVector;
+import com.yahoo.vespa.flags.Dimension;
import com.yahoo.vespa.flags.PermanentFlags;
import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.NodeList;
@@ -59,7 +59,7 @@ public class AutoscalingMaintainer extends NodeRepositoryMaintainer {
int failures = 0;
outer:
for (var applicationNodes : activeNodesByApplication().entrySet()) {
- boolean enabled = enabledFlag.with(FetchVector.Dimension.INSTANCE_ID,
+ boolean enabled = enabledFlag.with(Dimension.INSTANCE_ID,
applicationNodes.getKey().serializedForm()).value();
if (!enabled) continue;
for (var clusterNodes : nodesByCluster(applicationNodes.getValue()).entrySet()) {
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainer.java
index 3cec8483a45..bdff94e011d 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/PeriodicApplicationMaintainer.java
@@ -5,7 +5,7 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Deployer;
import com.yahoo.jdisc.Metric;
import com.yahoo.vespa.flags.BooleanFlag;
-import com.yahoo.vespa.flags.FetchVector;
+import com.yahoo.vespa.flags.Dimension;
import com.yahoo.vespa.flags.FlagSource;
import com.yahoo.vespa.flags.PermanentFlags;
import com.yahoo.vespa.hosted.provision.Node;
@@ -66,7 +66,7 @@ public class PeriodicApplicationMaintainer extends ApplicationMaintainer {
private boolean shouldMaintain(ApplicationId id) {
BooleanFlag skipMaintenanceDeployment = PermanentFlags.SKIP_MAINTENANCE_DEPLOYMENT.bindTo(flagSource)
- .with(FetchVector.Dimension.INSTANCE_ID, id.serializedForm());
+ .with(Dimension.INSTANCE_ID, id.serializedForm());
return ! skipMaintenanceDeployment.value();
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java
index 1e9adea4e95..b2db5977109 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java
@@ -19,7 +19,7 @@ import java.util.Map;
import java.util.TreeMap;
import static com.yahoo.config.provision.NodeResources.Architecture;
-import static com.yahoo.vespa.flags.FetchVector.Dimension.INSTANCE_ID;
+import static com.yahoo.vespa.flags.Dimension.INSTANCE_ID;
import static java.util.Objects.requireNonNull;
/**
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java
index e6f2dc0fbfe..239b962360b 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisioner.java
@@ -7,7 +7,6 @@ import com.yahoo.config.provision.ApplicationTransaction;
import com.yahoo.config.provision.CloudAccount;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.HostName;
-import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.ZoneEndpoint;
@@ -15,7 +14,7 @@ import com.yahoo.config.provision.exception.LoadBalancerServiceException;
import com.yahoo.transaction.NestedTransaction;
import com.yahoo.vespa.curator.Lock;
import com.yahoo.vespa.flags.BooleanFlag;
-import com.yahoo.vespa.flags.FetchVector;
+import com.yahoo.vespa.flags.Dimension;
import com.yahoo.vespa.flags.Flags;
import com.yahoo.vespa.flags.IntFlag;
import com.yahoo.vespa.flags.PermanentFlags;
@@ -45,7 +44,6 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
-import static com.yahoo.vespa.applicationmodel.TenantId.HOSTED_VESPA;
import static com.yahoo.vespa.hosted.provision.lb.LoadBalancerSpec.preProvisionOwner;
import static com.yahoo.vespa.hosted.provision.lb.LoadBalancerSpec.preProvisionSpec;
import static java.util.stream.Collectors.groupingBy;
@@ -369,7 +367,7 @@ public class LoadBalancerProvisioner {
LoadBalancer currentLoadBalancer,
ZoneEndpoint zoneEndpoint,
CloudAccount cloudAccount) {
- boolean shouldDeactivateRouting = deactivateRouting.with(FetchVector.Dimension.INSTANCE_ID,
+ boolean shouldDeactivateRouting = deactivateRouting.with(Dimension.INSTANCE_ID,
id.application().serializedForm())
.value();
Set<Real> reals = shouldDeactivateRouting ? Set.of() : realsOf(nodes, cloudAccount);
@@ -427,7 +425,7 @@ public class LoadBalancerProvisioner {
/** Find IP addresses reachable by the load balancer service */
private Set<String> reachableIpAddresses(Node node, CloudAccount cloudAccount) {
Set<String> reachable = new LinkedHashSet<>(node.ipConfig().primary());
- boolean forceIpv6 = ipv6AwsTargetGroups.with(FetchVector.Dimension.CLOUD_ACCOUNT, cloudAccount.account()).value();
+ boolean forceIpv6 = ipv6AwsTargetGroups.with(Dimension.CLOUD_ACCOUNT, cloudAccount.account()).value();
var protocol = forceIpv6 ? LoadBalancerService.Protocol.ipv6 :
service.protocol(node.cloudAccount().isExclave(nodeRepository.zone()));
// Remove addresses unreachable by the load balancer service
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java
index dcf4e3160d4..8c52f389daf 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java
@@ -9,7 +9,7 @@ import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.SystemName;
import com.yahoo.net.HostName;
-import com.yahoo.vespa.flags.FetchVector;
+import com.yahoo.vespa.flags.Dimension;
import com.yahoo.vespa.flags.PermanentFlags;
import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.NodeList;
@@ -94,9 +94,9 @@ class NodeAllocation {
this.nextIndex = nextIndex;
this.nodeRepository = nodeRepository;
this.requiredHostFlavor = Optional.of(PermanentFlags.HOST_FLAVOR.bindTo(nodeRepository.flagSource())
- .with(FetchVector.Dimension.INSTANCE_ID, application.serializedForm())
- .with(FetchVector.Dimension.CLUSTER_TYPE, cluster.type().name())
- .with(FetchVector.Dimension.CLUSTER_ID, cluster.id().value())
+ .with(Dimension.INSTANCE_ID, application.serializedForm())
+ .with(Dimension.CLUSTER_TYPE, cluster.type().name())
+ .with(Dimension.CLUSTER_ID, cluster.id().value())
.value())
.filter(s -> !s.isBlank());
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java
index dd6b0b5a6df..5c379fb1608 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/NodesResponse.java
@@ -13,7 +13,7 @@ import com.yahoo.config.provision.serialization.NetworkPortsSerializer;
import com.yahoo.container.jdisc.HttpRequest;
import com.yahoo.restapi.SlimeJsonResponse;
import com.yahoo.slime.Cursor;
-import com.yahoo.vespa.flags.FetchVector;
+import com.yahoo.vespa.flags.Dimension;
import com.yahoo.vespa.flags.PermanentFlags;
import com.yahoo.vespa.flags.StringFlag;
import com.yahoo.vespa.hosted.provision.Node;
@@ -199,13 +199,13 @@ class NodesResponse extends SlimeJsonResponse {
private Version resolveVersionFlag(StringFlag flag, Node node, Allocation allocation) {
String value = flag
- .with(FetchVector.Dimension.HOSTNAME, node.hostname())
- .with(FetchVector.Dimension.NODE_TYPE, node.type().name())
- .with(FetchVector.Dimension.TENANT_ID, allocation.owner().tenant().value())
- .with(FetchVector.Dimension.INSTANCE_ID, allocation.owner().serializedForm())
- .with(FetchVector.Dimension.CLUSTER_TYPE, allocation.membership().cluster().type().name())
- .with(FetchVector.Dimension.CLUSTER_ID, allocation.membership().cluster().id().value())
- .with(FetchVector.Dimension.VESPA_VERSION, allocation.membership().cluster().vespaVersion().toFullString())
+ .with(Dimension.HOSTNAME, node.hostname())
+ .with(Dimension.NODE_TYPE, node.type().name())
+ .with(Dimension.TENANT_ID, allocation.owner().tenant().value())
+ .with(Dimension.INSTANCE_ID, allocation.owner().serializedForm())
+ .with(Dimension.CLUSTER_TYPE, allocation.membership().cluster().type().name())
+ .with(Dimension.CLUSTER_ID, allocation.membership().cluster().id().value())
+ .with(Dimension.VESPA_VERSION, allocation.membership().cluster().vespaVersion().toFullString())
.value();
return value.isEmpty() ?