diff options
author | Håkon Hallingstad <hakon@yahooinc.com> | 2023-11-29 14:59:00 +0100 |
---|---|---|
committer | Håkon Hallingstad <hakon@yahooinc.com> | 2023-11-29 14:59:00 +0100 |
commit | 11941a9408e44cd57333a661177a56f2dd705443 (patch) | |
tree | 1e547e6b78e1dbd21c0fac093ddfe592bf5da914 | |
parent | 6359834bc232523a4d8686e16f411fa148a649c2 (diff) |
Define nessus-agent-group flag and make Dimension top-level class
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() ? |