summaryrefslogtreecommitdiffstats
path: root/config-model/src/main/java/com/yahoo/vespa/model/application/validation/QuotaValidator.java
diff options
context:
space:
mode:
Diffstat (limited to 'config-model/src/main/java/com/yahoo/vespa/model/application/validation/QuotaValidator.java')
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/QuotaValidator.java30
1 files changed, 18 insertions, 12 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/QuotaValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/QuotaValidator.java
index 4ea74147aaf..f0c29c74705 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/QuotaValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/QuotaValidator.java
@@ -6,7 +6,9 @@ import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterResources;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.NodeResources;
+import com.yahoo.config.provision.QuotaExceededException;
import com.yahoo.config.provision.SystemName;
+import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.model.VespaModel;
import java.math.BigDecimal;
@@ -31,11 +33,10 @@ public class QuotaValidator extends Validator {
public void validate(VespaModel model, DeployState deployState) {
var quota = deployState.getProperties().quota();
quota.maxClusterSize().ifPresent(maxClusterSize -> validateMaxClusterSize(maxClusterSize, model));
- quota.budgetAsDecimal().ifPresent(budget -> validateBudget(budget, model, deployState.getProperties().zone().system()));
+ quota.budgetAsDecimal().ifPresent(budget -> validateBudget(budget, model, deployState.getProperties().zone()));
}
- private void validateBudget(BigDecimal budget, VespaModel model, SystemName systemName) {
-
+ private void validateBudget(BigDecimal budget, VespaModel model, Zone zone) {
var maxSpend = model.allClusters().stream()
.filter(id -> !adminClusterIds(model).contains(id))
.map(id -> model.provisioned().all().getOrDefault(id, zeroCapacity))
@@ -52,9 +53,10 @@ public class QuotaValidator extends Validator {
return;
}
- throwIfBudgetNegative(actualSpend, budget, systemName);
- throwIfBudgetExceeded(actualSpend, budget, systemName);
- throwIfBudgetExceeded(maxSpend, budget, systemName);
+ throwIfBudgetNegative(actualSpend, budget, zone.system());
+ throwIfBudgetExceeded(actualSpend, budget, zone.system(), true);
+ if ( ! zone.environment().isTest()) // Usage is constant after deploy in test zones
+ throwIfBudgetExceeded(maxSpend, budget, zone.system(), false);
}
private Set<ClusterSpec.Id> adminClusterIds(VespaModel model) {
@@ -80,24 +82,28 @@ public class QuotaValidator extends Validator {
if (!invalidClusters.isEmpty()) {
var clusterNames = String.join(", ", invalidClusters);
- throw new IllegalArgumentException("Clusters " + clusterNames + " exceeded max cluster size of " + maxClusterSize);
+ throw new QuotaExceededException("Clusters " + clusterNames + " exceeded max cluster size of " + maxClusterSize);
}
}
private static void throwIfBudgetNegative(double spend, BigDecimal budget, SystemName systemName) {
if (budget.doubleValue() < 0) {
- throw new IllegalArgumentException(quotaMessage("Please free up some capacity.", systemName, spend, budget));
+ throw new QuotaExceededException(quotaMessage("Please free up some capacity.", systemName, spend, budget, true));
}
}
- private static void throwIfBudgetExceeded(double spend, BigDecimal budget, SystemName systemName) {
+ private static void throwIfBudgetExceeded(double spend, BigDecimal budget, SystemName systemName, boolean actual) {
if (budget.doubleValue() < spend) {
- throw new IllegalArgumentException(quotaMessage("Contact support to upgrade your plan.", systemName, spend, budget));
+ throw new QuotaExceededException(quotaMessage("Contact support to upgrade your plan.", systemName, spend, budget, actual));
}
}
- private static String quotaMessage(String message, SystemName system, double spend, BigDecimal budget) {
- String quotaDescription = String.format(Locale.ENGLISH, "The max resources specified cost $%.2f but your quota is $%.2f", spend, budget);
+ private static String quotaMessage(String message, SystemName system, double spend, BigDecimal budget, boolean actual) {
+ String quotaDescription = String.format(Locale.ENGLISH,
+ "The %s cost $%.2f but your quota is $%.2f",
+ actual ? "resources used" : "max resources specified",
+ spend,
+ budget);
return (system == SystemName.Public ? "" : system.value() + ": ") + quotaDescription + ": " + message;
}