diff options
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.java | 30 |
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; } |