summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorØyvind Grønnesby <oyving@verizonmedia.com>2020-10-12 14:10:08 +0200
committerGitHub <noreply@github.com>2020-10-12 14:10:08 +0200
commitd1059fed419e8c8b0b033966cfabbf4568bbcca6 (patch)
treed6a23bdc41a7e8038e2eab1147e0402385f31a47
parent9e74c7bfd20b32283fd9c078d3604bb44bacc02c (diff)
parente8f8420eab675350e61260578bd10228645c51f1 (diff)
Merge pull request #14654 from vespa-engine/ogronnesby/quota-decimal-controller
Quota as BigDecimals in the controller
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/MockBillingController.java2
-rw-r--r--controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/Quota.java53
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/BigDecimalFlag.java15
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/Flags.java11
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/UnboundBigDecimalFlag.java18
5 files changed, 71 insertions, 28 deletions
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/MockBillingController.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/MockBillingController.java
index 5db89ccc656..19dfe0d9dcc 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/MockBillingController.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/MockBillingController.java
@@ -33,7 +33,7 @@ public class MockBillingController implements BillingController {
@Override
public Optional<Quota> getQuota(TenantName tenant, Environment environment) {
- return Optional.of(new Quota(5));
+ return Optional.of(Quota.unlimited().withMaxClusterSize(5));
}
@Override
diff --git a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/Quota.java b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/Quota.java
index 4e1efc1b6d9..511d7bf1d09 100644
--- a/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/Quota.java
+++ b/controller-api/src/main/java/com/yahoo/vespa/hosted/controller/api/integration/billing/Quota.java
@@ -1,57 +1,60 @@
// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.controller.api.integration.billing;
+import java.math.BigDecimal;
import java.util.Objects;
import java.util.Optional;
+import java.util.OptionalInt;
/**
- * Quota information transmitted to the configserver on deploy.
+ * Quota information transmitted to the configserver on deploy. All limits are represented
+ * with an Optional type where the empty optional means unlimited resource use.
*
* @author andreer
* @author ogronnesby
*/
public class Quota {
- private static final Quota UNLIMITED = new Quota(Optional.empty(), Optional.empty());
- private static final Quota ZERO = new Quota(0, 0);
+ private static final Quota UNLIMITED = new Quota(OptionalInt.empty(), Optional.empty());
+ private static final Quota ZERO = new Quota(OptionalInt.of(0), Optional.of(BigDecimal.ZERO));
- private final Optional<Integer> maxClusterSize;
- private final Optional<Integer> budget; // in USD/hr, as calculated by NodeResources
+ private final OptionalInt maxClusterSize;
+ private final Optional<BigDecimal> budget; // in USD/hr, as calculated by NodeResources
- public Quota(int maxClusterSize) {
- this(Optional.of(maxClusterSize), Optional.empty());
- }
-
- public Quota(int maxClusterSize, int dollarsPerHour) {
- this(Optional.of(maxClusterSize), Optional.of(dollarsPerHour));
- }
-
- public Quota(Optional<Integer> maxClusterSize, Optional<Integer> budget) {
+ private Quota(OptionalInt maxClusterSize, Optional<BigDecimal> budget) {
this.maxClusterSize = Objects.requireNonNull(maxClusterSize);
this.budget = Objects.requireNonNull(budget);
}
- public Optional<Integer> maxClusterSize() {
- return maxClusterSize;
+ public Quota withMaxClusterSize(int clusterSize) {
+ return new Quota(OptionalInt.of(clusterSize), budget);
}
- public Optional<Integer> budget() {
- return budget;
+ /** Construct a Quota that allows zero resource usage */
+ public static Quota zero() {
+ return ZERO;
}
- public Quota withMaxClusterSize(int clusterSize) {
- return new Quota(Optional.of(clusterSize), budget);
+ /** Construct a Quota that allows unlimited resource usage */
+ public static Quota unlimited() {
+ return UNLIMITED;
+ }
+
+ public Quota withBudget(BigDecimal budget) {
+ return new Quota(maxClusterSize, Optional.ofNullable(budget));
}
public Quota withBudget(int budget) {
- return new Quota(maxClusterSize, Optional.of(budget));
+ return withBudget(BigDecimal.valueOf(budget));
}
- public static Quota zero() {
- return ZERO;
+ /** Maximum number of nodes in a cluster in a Vespa deployment */
+ public OptionalInt maxClusterSize() {
+ return maxClusterSize;
}
- public static Quota unlimited() {
- return UNLIMITED;
+ /** Maximum $/hour run-rate for the Vespa deployment */
+ public Optional<BigDecimal> budget() {
+ return budget;
}
@Override
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/BigDecimalFlag.java b/flags/src/main/java/com/yahoo/vespa/flags/BigDecimalFlag.java
new file mode 100644
index 00000000000..f5273719275
--- /dev/null
+++ b/flags/src/main/java/com/yahoo/vespa/flags/BigDecimalFlag.java
@@ -0,0 +1,15 @@
+// Copyright 2020 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.flags;
+
+import java.math.BigDecimal;
+
+/**
+ * @author ogronnesby
+ */
+public class BigDecimalFlag extends FlagImpl<BigDecimal, BigDecimalFlag> {
+ public BigDecimalFlag(FlagId id, BigDecimal defaultValue, FetchVector fetchVector, FlagSerializer<BigDecimal> serializer, FlagSource source) {
+ super(id, defaultValue, fetchVector, serializer, source, BigDecimalFlag::new);
+ }
+
+ public BigDecimal value() { return 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 c7e171e4e06..448e493408a 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
@@ -5,6 +5,7 @@ import com.yahoo.component.Vtag;
import com.yahoo.vespa.defaults.Defaults;
import com.yahoo.vespa.flags.custom.HostCapacity;
+import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
import java.util.TreeMap;
@@ -302,8 +303,8 @@ public class Flags {
APPLICATION_ID
);
- public static final UnboundIntFlag TENANT_BUDGET_QUOTA = defineIntFlag(
- "tenant-budget-quota", 5,
+ public static final UnboundBigDecimalFlag TENANT_BUDGET_QUOTA = defineBigDecimalFlag(
+ "tenant-budget-quota", new BigDecimal("5.00"),
"The budget in $/hr a tenant is allowed spend per instance, as calculated by NodeResources",
"Only takes effect on next deployment, if set to a value other than the default for flag!",
APPLICATION_ID
@@ -405,6 +406,12 @@ public class Flags {
}
/** WARNING: public for testing: All flags should be defined in {@link Flags}. */
+ public static UnboundBigDecimalFlag defineBigDecimalFlag(String flagId, BigDecimal defaultValue, String description,
+ String modificationEffect, FetchVector.Dimension... dimensions) {
+ return define(UnboundBigDecimalFlag::new, flagId, defaultValue, 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, String description,
String modificationEffect, FetchVector.Dimension... dimensions) {
return define((id2, defaultValue2, vector2) -> new UnboundJacksonFlag<>(id2, defaultValue2, vector2, jacksonClass),
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/UnboundBigDecimalFlag.java b/flags/src/main/java/com/yahoo/vespa/flags/UnboundBigDecimalFlag.java
new file mode 100644
index 00000000000..0b26046c777
--- /dev/null
+++ b/flags/src/main/java/com/yahoo/vespa/flags/UnboundBigDecimalFlag.java
@@ -0,0 +1,18 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.flags;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.DecimalNode;
+
+import java.math.BigDecimal;
+
+/**
+ * @author ogronnesby
+ */
+public class UnboundBigDecimalFlag extends UnboundFlagImpl<BigDecimal, BigDecimalFlag, UnboundBigDecimalFlag> {
+ public UnboundBigDecimalFlag(FlagId id, BigDecimal defaultValue, FetchVector defaultFetchVector) {
+ super(id, defaultValue, defaultFetchVector,
+ new SimpleFlagSerializer<>(DecimalNode::valueOf, JsonNode::isBigDecimal, JsonNode::decimalValue),
+ UnboundBigDecimalFlag::new, BigDecimalFlag::new);
+ }
+}