aboutsummaryrefslogtreecommitdiffstats
path: root/flags/src/main/java/com/yahoo/vespa/flags
diff options
context:
space:
mode:
Diffstat (limited to 'flags/src/main/java/com/yahoo/vespa/flags')
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/Flag.java64
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/Flags.java56
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java16
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/custom/SharedHost.java14
4 files changed, 115 insertions, 35 deletions
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 7ca5066969f..4d49d52fa73 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/Flag.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/Flag.java
@@ -1,6 +1,20 @@
// 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.component.Version;
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.CloudAccount;
+import com.yahoo.config.provision.CloudName;
+import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.Environment;
+import com.yahoo.config.provision.NodeResources.Architecture;
+import com.yahoo.config.provision.NodeType;
+import com.yahoo.config.provision.SystemName;
+import com.yahoo.config.provision.TenantName;
+import com.yahoo.config.provision.Zone;
+import com.yahoo.config.provision.zone.ZoneApi;
+import com.yahoo.config.provision.zone.ZoneId;
+
import java.util.Optional;
/**
@@ -10,7 +24,7 @@ import java.util.Optional;
* @param <F> The concrete subclass type of the flag
* @author hakonhall
*/
-public interface Flag<T, F> {
+public interface Flag<T, F extends Flag<T, F>> {
/** The flag ID. */
FlagId id();
@@ -28,6 +42,54 @@ public interface Flag<T, F> {
return dimensionValue.map(value -> with(dimension, value)).orElse(self());
}
+ /** Sets the tenant, application, and instance dimensions. */
+ default F with(ApplicationId applicationId) {
+ return with(Dimension.TENANT_ID, applicationId.tenant().value())
+ .with(Dimension.APPLICATION, applicationId.toSerializedFormWithoutInstance())
+ .with(Dimension.INSTANCE_ID, applicationId.serializedForm());
+ }
+
+ /** architecture MUST NOT be 'any'. */
+ default F with(Architecture architecture) { return with(Dimension.ARCHITECTURE, architecture.name()); }
+ /**
+ * Sets the cloud-account dimension ONLY IF it is an enclave account.<br/>
+ * Sets the clave dimension to "enclave" if it is an enclave account, otherwise "noclave".
+ */
+ default F with(CloudAccount cloudAccount, Zone zone) {
+ return cloudAccount.isEnclave(zone)
+ ? with(Dimension.CLOUD_ACCOUNT, Optional.of(cloudAccount).map(CloudAccount::value))
+ .with(Dimension.CLAVE, "enclave")
+ : with(Dimension.CLAVE, "noclave");
+ }
+ default F with(CloudName cloud) { return with(Dimension.CLOUD, cloud.value()); }
+ default F with(ClusterSpec.Id clusterId) { return with(Dimension.CLUSTER_ID, clusterId.value()); }
+ default F with(ClusterSpec.Type clusterType) { return with(Dimension.CLUSTER_TYPE, clusterType.name()); }
+ default F with(Environment environment) { return with(Dimension.ENVIRONMENT, environment.value()); }
+ default F with(NodeType nodeType) { return with(Dimension.NODE_TYPE, nodeType.name()); }
+ default F with(SystemName systemName) { return with(Dimension.SYSTEM, systemName.value()); }
+ default F with(TenantName tenantName) { return with(Dimension.TENANT_ID, tenantName.value()); }
+ default F with(Version vespaVersion) { return with(Dimension.VESPA_VERSION, vespaVersion.toFullString()); }
+ default F with(ZoneId zoneId) { return with(Dimension.ZONE_ID, zoneId.value()); }
+ default F with(Zone zone) { return with(Dimension.ZONE_ID, zone.systemLocalValue()); }
+ default F with(ZoneApi zoneApi) { return with(zoneApi.getVirtualId()); }
+
+ /** Sets the tenant, application, and instance dimensions. */
+ default F withApplicationId(Optional<ApplicationId> applicationId) { return applicationId.map(this::with).orElse(self()); }
+ /** architecture MUST NOT be 'any'. */
+ default F withArchitecture(Optional<Architecture> architecture) { return architecture.map(this::with).orElse(self()); }
+ default F withCloudAccount(Optional<CloudAccount> cloudAccount, Zone zone) { return cloudAccount.map(account -> with(account, zone)).orElse(self()); }
+ default F withCloudName(Optional<CloudName> cloud) { return cloud.map(this::with).orElse(self()); }
+ default F withClusterId(Optional<ClusterSpec.Id> clusterId) { return clusterId.map(this::with).orElse(self()); }
+ default F withClusterType(Optional<ClusterSpec.Type> clusterType) { return clusterType.map(this::with).orElse(self()); }
+ default F withEnvironment(Optional<Environment> environment) { return environment.map(this::with).orElse(self()); }
+ default F withNodeType(Optional<NodeType> nodeType) { return nodeType.map(this::with).orElse(self()); }
+ default F withSystemName(Optional<SystemName> systemName) { return systemName.map(this::with).orElse(self()); }
+ default F withTenantName(Optional<TenantName> tenantName) { return tenantName.map(this::with).orElse(self()); }
+ default F withVersion(Optional<Version> vespaVersion) { return vespaVersion.map(this::with).orElse(self()); }
+ default F withZoneId(Optional<ZoneId> zoneId) { return zoneId.map(this::with).orElse(self()); }
+ default F withZone(Optional<Zone> zone) { return zone.map(this::with).orElse(self()); }
+ default F withZoneApi(Optional<ZoneApi> zoneApi) { return zoneApi.map(this::with).orElse(self()); }
+
/** Returns the value, boxed if the flag wraps a primitive type. */
T boxedValue();
}
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 a3fe010c65b..abff6fcd4c6 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
@@ -84,18 +84,6 @@ public class Flags {
"Takes effect at redeployment",
INSTANCE_ID);
- public static final UnboundBooleanFlag NEW_RESOURCES_FORMULA = defineFeatureFlag(
- "new-resources-formula", true,
- List.of("hakonhall"), "2024-04-25", "2024-05-25",
- "Use an easier to understand formula for calculating the memory and disk resources",
- "Takes effect on next deployment of an applications.");
-
- public static final UnboundBooleanFlag FIX_CONFIG_SERVER_HEAP = defineFeatureFlag(
- "fix-config-server-heap", false,
- List.of("hakonhall"), "2024-04-23", "2024-05-23",
- "Base the calculation of the config server JVM heap size on the amount of memory available to the container.",
- "Takes effect on start of config server Podman container");
-
public static final UnboundStringFlag RESPONSE_SEQUENCER_TYPE = defineStringFlag(
"response-sequencer-type", "ADAPTIVE",
List.of("baldersheim"), "2020-12-02", "2024-12-31",
@@ -243,13 +231,6 @@ public class Flags {
"Takes effect on next tick.",
NODE_TYPE);
- public static final UnboundStringFlag DIST_HOST = defineStringFlag(
- "dist-host", "",
- List.of("freva"), "2024-04-15", "2024-05-31",
- "Sets dist_host YUM variable, empty means old behavior. Only effective in Public.",
- "Provisioning of instance or next host-admin tick",
- HOSTNAME, NODE_TYPE, CLOUD_ACCOUNT);
-
public static final UnboundBooleanFlag ENABLED_HORIZON_DASHBOARD = defineFeatureFlag(
"enabled-horizon-dashboard", false,
List.of("olaa"), "2021-09-13", "2024-09-01",
@@ -336,14 +317,14 @@ public class Flags {
public static final UnboundBooleanFlag SORT_BLUEPRINTS_BY_COST = defineFeatureFlag(
"sort-blueprints-by-cost", false,
- List.of("baldersheim"), "2023-12-19", "2024-05-31",
+ List.of("baldersheim"), "2023-12-19", "2024-10-31",
"If true blueprints are sorted based on cost estimate, rather that absolute estimated hits",
"Takes effect at redeployment",
INSTANCE_ID);
public static final UnboundBooleanFlag ALWAYS_MARK_PHRASE_EXPENSIVE = defineFeatureFlag(
"always-mark-phrase-expensive", false,
- List.of("baldersheim"), "2023-11-20", "2024-05-31",
+ List.of("baldersheim"), "2023-11-20", "2024-10-31",
"If true all phrases will be marked expensive, independent of parents",
"Takes effect at redeployment",
INSTANCE_ID);
@@ -418,13 +399,13 @@ public class Flags {
public static UnboundBooleanFlag CALYPSO_ENABLED = defineFeatureFlag(
"calypso-enabled", true,
- List.of("mortent"), "2024-02-19", "2024-05-01",
+ List.of("mortent"), "2024-02-19", "2024-08-01",
"Whether to enable calypso for host",
"Takes effect immediately", HOSTNAME);
public static UnboundBooleanFlag ATHENZ_PROVIDER = defineFeatureFlag(
"athenz-provider", false,
- List.of("mortent"), "2024-02-19", "2024-05-01",
+ List.of("mortent"), "2024-02-19", "2024-08-01",
"Whether to use athenz as node identity provider",
"Takes effect on next identity refresh", HOSTNAME);
@@ -435,7 +416,7 @@ public class Flags {
"Takes effect immediately");
public static final UnboundIntFlag PERSISTENCE_THREAD_MAX_FEED_OP_BATCH_SIZE = defineIntFlag(
- "persistence-thread-max-feed-op-batch-size", 1,
+ "persistence-thread-max-feed-op-batch-size", 64,
List.of("vekterli"), "2024-04-12", "2025-01-01",
"Maximum number of enqueued feed operations (put/update/remove) bound "+
"towards the same bucket that can be async dispatched as part of the " +
@@ -449,6 +430,33 @@ public class Flags {
"Whether logserver container should run otel agent",
"Takes effect at redeployment", INSTANCE_ID);
+ public static UnboundBooleanFlag HUBSPOT_SYNC_TENANTS = defineFeatureFlag(
+ "hubspot-sync-tenants", false,
+ List.of("bjorncs"), "2024-05-07", "2025-01-01",
+ "Whether to sync tenants to HubSpot",
+ "Takes effect immediately");
+
+ public static final UnboundBooleanFlag REMOVE_ORPHANED_DNS_RECORDS = defineFeatureFlag(
+ "remove-orphaned-dns-records", false,
+ List.of("mpolden"), "2024-05-07", "2024-10-01",
+ "Whether EndpointDnsMaintainer should remove orphaned records instead of logging them",
+ "Takes effect on next maintenance run");
+
+ public static final UnboundBooleanFlag SYMMETRIC_PUT_AND_ACTIVATE_REPLICA_SELECTION = defineFeatureFlag(
+ "symmetric-put-and-activate-replica-selection", false,
+ List.of("vekterli"), "2024-05-23", "2024-08-01",
+ "Iff true there will be an 1-1 symmetry between the replicas chosen as feed targets " +
+ "for Put operations and the replica selection logic for bucket activation. If false, " +
+ "legacy feed behavior is used.",
+ "Takes effect immediately",
+ INSTANCE_ID);
+
+ public static final UnboundBooleanFlag HUBSPOT_SYNC_CONTACTS = defineFeatureFlag(
+ "hubspot-sync-contacts", false,
+ List.of("bjorncs"), "2024-05-27", "2025-01-01",
+ "Whether to sync contacts to HubSpot",
+ "Takes effect immediately");
+
/** 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,
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 3b73d9d6013..1b1e74c0b1e 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java
@@ -18,12 +18,12 @@ import static com.yahoo.vespa.flags.Dimension.ARCHITECTURE;
import static com.yahoo.vespa.flags.Dimension.CERTIFICATE_PROVIDER;
import static com.yahoo.vespa.flags.Dimension.CLAVE;
import static com.yahoo.vespa.flags.Dimension.CLOUD_ACCOUNT;
-import static com.yahoo.vespa.flags.Dimension.FLAVOR;
-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.FLAVOR;
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.TENANT_ID;
import static com.yahoo.vespa.flags.Dimension.VESPA_VERSION;
@@ -178,7 +178,7 @@ public class PermanentFlags {
HOSTNAME, NODE_TYPE, TENANT_ID, INSTANCE_ID, CLUSTER_TYPE, CLUSTER_ID, VESPA_VERSION);
public static final UnboundStringFlag ZOOKEEPER_SERVER_VERSION = defineStringFlag(
- "zookeeper-server-version", "3.9.1",
+ "zookeeper-server-version", "3.9.2",
"ZooKeeper server version, a jar file zookeeper-server-<ZOOKEEPER_SERVER_VERSION>-jar-with-dependencies.jar must exist",
"Takes effect on restart of Docker container",
NODE_TYPE, INSTANCE_ID, HOSTNAME);
@@ -196,8 +196,8 @@ public class PermanentFlags {
);
public static final UnboundBooleanFlag JVM_OMIT_STACK_TRACE_IN_FAST_THROW = defineFeatureFlag(
- "jvm-omit-stack-trace-in-fast-throw", true,
- "Controls JVM option OmitStackTraceInFastThrow (default feature flag value is true, which is the default JVM option value as well)",
+ "jvm-omit-stack-trace-in-fast-throw", false,
+ "Controls JVM option OmitStackTraceInFastThrow (the default JVM option corresponds to feature flag being false )",
"takes effect on JVM restart",
CLUSTER_TYPE, INSTANCE_ID);
@@ -404,6 +404,12 @@ public class PermanentFlags {
"Takes effect immediately",
INSTANCE_ID);
+ public static final UnboundBooleanFlag AUTOSCALING_DETAILED_LOGGING = defineFeatureFlag(
+ "autoscaling-detailed-logging", false,
+ "Whether to log autoscaling decision data",
+ "Takes effect immediately",
+ INSTANCE_ID);
+
public static final UnboundIntFlag MAX_HOSTS_PER_HOUR = defineIntFlag(
"max-hosts-per-hour", 40,
"The number of hosts that can be provisioned per hour in a zone, before throttling is " +
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/custom/SharedHost.java b/flags/src/main/java/com/yahoo/vespa/flags/custom/SharedHost.java
index 66356d979a4..3f229862d7a 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/custom/SharedHost.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/custom/SharedHost.java
@@ -7,6 +7,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
+import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.SharedHosts;
import com.yahoo.vespa.flags.PermanentFlags;
import java.util.List;
@@ -19,7 +21,7 @@ import java.util.Objects;
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(value = JsonInclude.Include.NON_NULL)
-public class SharedHost {
+public class SharedHost implements SharedHosts {
private final List<HostResources> resources;
@@ -43,14 +45,16 @@ public class SharedHost {
/** Whether there are any shared hosts specifically for the given cluster type, or without a cluster type restriction. */
@JsonIgnore
- public boolean supportsClusterType(String clusterType) {
- return resources.stream().anyMatch(resource -> resource.clusterType().map(clusterType::equalsIgnoreCase).orElse(true));
+ @Override
+ public boolean supportsClusterType(ClusterSpec.Type clusterType) {
+ return resources.stream().anyMatch(resource -> resource.clusterType().map(type -> clusterType.name().equalsIgnoreCase(type)).orElse(true));
}
/** Whether there are any shared hosts specifically for the given cluster type. */
@JsonIgnore
- public boolean hasClusterType(String clusterType) {
- return resources.stream().anyMatch(resource -> resource.clusterType().map(clusterType::equalsIgnoreCase).orElse(false));
+ @Override
+ public boolean hasClusterType(ClusterSpec.Type clusterType) {
+ return resources.stream().anyMatch(resource -> resource.clusterType().map(type -> clusterType.name().equalsIgnoreCase(type)).orElse(false));
}
@JsonIgnore