diff --git a/src/main/java/org/elasticsearch/cluster/settings/ClusterDynamicSettingsModule.java b/src/main/java/org/elasticsearch/cluster/settings/ClusterDynamicSettingsModule.java
index 4322b209485..200855dfe08 100644
--- a/src/main/java/org/elasticsearch/cluster/settings/ClusterDynamicSettingsModule.java
+++ b/src/main/java/org/elasticsearch/cluster/settings/ClusterDynamicSettingsModule.java
@@ -27,10 +27,10 @@ import org.elasticsearch.cluster.routing.allocation.decider.*;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.discovery.zen.elect.ElectMasterService;
import org.elasticsearch.indices.cache.filter.IndicesFilterCache;
+import org.elasticsearch.indices.fielddata.breaker.InternalCircuitBreakerService;
import org.elasticsearch.indices.recovery.RecoverySettings;
import org.elasticsearch.indices.store.IndicesStore;
import org.elasticsearch.indices.ttl.IndicesTTLService;
-import org.elasticsearch.indices.fielddata.breaker.InternalCircuitBreakerService;
import org.elasticsearch.threadpool.ThreadPool;
/**
@@ -78,7 +78,7 @@ public class ClusterDynamicSettingsModule extends AbstractModule {
clusterDynamicSettings.addDynamicSetting(DiskThresholdDecider.CLUSTER_ROUTING_ALLOCATION_DISK_THRESHOLD_ENABLED);
clusterDynamicSettings.addDynamicSetting(InternalClusterInfoService.INTERNAL_CLUSTER_INFO_UPDATE_INTERVAL, Validator.TIME);
clusterDynamicSettings.addDynamicSetting(SnapshotInProgressAllocationDecider.CLUSTER_ROUTING_ALLOCATION_SNAPSHOT_RELOCATION_ENABLED);
- clusterDynamicSettings.addDynamicSetting(InternalCircuitBreakerService.CIRCUIT_BREAKER_MAX_BYTES_SETTING, Validator.BYTES_SIZE);
+ clusterDynamicSettings.addDynamicSetting(InternalCircuitBreakerService.CIRCUIT_BREAKER_MAX_BYTES_SETTING, Validator.MEMORY_SIZE);
clusterDynamicSettings.addDynamicSetting(InternalCircuitBreakerService.CIRCUIT_BREAKER_OVERHEAD_SETTING, Validator.NON_NEGATIVE_DOUBLE);
clusterDynamicSettings.addDynamicSetting(DestructiveOperations.REQUIRES_NAME);
}
diff --git a/src/main/java/org/elasticsearch/cluster/settings/Validator.java b/src/main/java/org/elasticsearch/cluster/settings/Validator.java
index b3a2a0842b0..ef37b21352f 100644
--- a/src/main/java/org/elasticsearch/cluster/settings/Validator.java
+++ b/src/main/java/org/elasticsearch/cluster/settings/Validator.java
@@ -24,6 +24,8 @@ import org.elasticsearch.common.Booleans;
import org.elasticsearch.common.unit.TimeValue;
import static org.elasticsearch.common.unit.ByteSizeValue.parseBytesSizeValue;
+import static org.elasticsearch.common.unit.MemorySizeValue.parseBytesSizeValueOrHeapRatio;
+
/**
* Validates a setting, returning a failure message if applicable.
@@ -184,7 +186,19 @@ public interface Validator {
return null;
}
};
-
+
+ public static final Validator MEMORY_SIZE = new Validator() {
+ @Override
+ public String validate(String setting, String value) {
+ try {
+ parseBytesSizeValueOrHeapRatio(value);
+ } catch (ElasticsearchParseException ex) {
+ return ex.getMessage();
+ }
+ return null;
+ }
+ };
+
public static final Validator BOOLEAN = new Validator() {
@Override
public String validate(String setting, String value) {
diff --git a/src/main/java/org/elasticsearch/common/unit/MemorySizeValue.java b/src/main/java/org/elasticsearch/common/unit/MemorySizeValue.java
index 42293b4ed47..81a293459f2 100644
--- a/src/main/java/org/elasticsearch/common/unit/MemorySizeValue.java
+++ b/src/main/java/org/elasticsearch/common/unit/MemorySizeValue.java
@@ -19,6 +19,7 @@
package org.elasticsearch.common.unit;
+import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.monitor.jvm.JvmInfo;
import static org.elasticsearch.common.unit.ByteSizeValue.parseBytesSizeValue;
@@ -32,8 +33,16 @@ public enum MemorySizeValue {
* the heap is 1G, 10% will be parsed as 100mb. */
public static ByteSizeValue parseBytesSizeValueOrHeapRatio(String sValue) {
if (sValue.endsWith("%")) {
- double percent = Double.parseDouble(sValue.substring(0, sValue.length() - 1));
- return new ByteSizeValue((long) ((percent / 100) * JvmInfo.jvmInfo().getMem().getHeapMax().bytes()), ByteSizeUnit.BYTES);
+ final String percentAsString = sValue.substring(0, sValue.length() - 1);
+ try {
+ final double percent = Double.parseDouble(percentAsString);
+ if (percent < 0 || percent > 100) {
+ throw new ElasticsearchParseException("Percentage should be in [0-100], got " + percentAsString);
+ }
+ return new ByteSizeValue((long) ((percent / 100) * JvmInfo.jvmInfo().getMem().getHeapMax().bytes()), ByteSizeUnit.BYTES);
+ } catch (NumberFormatException e) {
+ throw new ElasticsearchParseException("Failed to parse [" + percentAsString + "] as a double", e);
+ }
} else {
return parseBytesSizeValue(sValue);
}
diff --git a/src/main/java/org/elasticsearch/indices/fielddata/breaker/InternalCircuitBreakerService.java b/src/main/java/org/elasticsearch/indices/fielddata/breaker/InternalCircuitBreakerService.java
index 24fe6cb1a1f..c5ac6e5f936 100644
--- a/src/main/java/org/elasticsearch/indices/fielddata/breaker/InternalCircuitBreakerService.java
+++ b/src/main/java/org/elasticsearch/indices/fielddata/breaker/InternalCircuitBreakerService.java
@@ -24,7 +24,6 @@ import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.ByteSizeValue;
-import org.elasticsearch.monitor.jvm.JvmInfo;
import org.elasticsearch.node.settings.NodeSettingsService;
/**
@@ -39,9 +38,7 @@ public class InternalCircuitBreakerService extends AbstractLifecycleComponent