add undocumented kill switch, to disable requiring units on byte size and time settings

This commit is contained in:
Michael McCandless 2015-05-30 17:36:58 -04:00 committed by mikemccand
parent 062dbee955
commit 54a2ab9c03
6 changed files with 66 additions and 5 deletions

View File

@ -84,7 +84,7 @@ public class Booleans {
* @return true/false
* throws exception if string cannot be parsed to boolean
*/
public static Boolean parseBooleanExact(String value){
public static Boolean parseBooleanExact(String value) {
boolean isFalse = isExplicitFalse(value);
if (isFalse) {

View File

@ -61,7 +61,20 @@ import static org.elasticsearch.common.unit.TimeValue.parseTimeValue;
public final class Settings implements ToXContent {
public static final Settings EMPTY = new Builder().build();
private final static Pattern ARRAY_PATTERN = Pattern.compile("(.*)\\.\\d+$");
private static final Pattern ARRAY_PATTERN = Pattern.compile("(.*)\\.\\d+$");
/** Name of the setting to use to disable required units for byte size, time settings. */
public static final String SETTINGS_REQUIRE_UNITS = "settings_require_units";
private static boolean settingsRequireUnits = true;
public static void setSettingsRequireUnits(boolean v) {
settingsRequireUnits = v;
}
public static boolean getSettingsRequireUnits() {
return settingsRequireUnits;
}
private ImmutableMap<String, String> settings;
private final ImmutableMap<String, String> forcedUnderscoreSettings;

View File

@ -25,6 +25,7 @@ import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Streamable;
import org.elasticsearch.common.settings.Settings;
import java.io.IOException;
import java.io.Serializable;
@ -213,7 +214,12 @@ public class ByteSizeValue implements Serializable, Streamable {
bytes = 0;
} else {
// Missing units:
throw new ElasticsearchParseException("Failed to parse setting [" + settingName + "] with value [" + sValue + "] as a size in bytes: unit is missing or unrecognized") ;
if (Settings.getSettingsRequireUnits()) {
throw new ElasticsearchParseException("Failed to parse setting [" + settingName + "] with value [" + sValue + "] as a size in bytes: unit is missing or unrecognized") ;
} else {
// Leniency default to bytes:
bytes = Long.parseLong(sValue);
}
}
} catch (NumberFormatException e) {
throw new ElasticsearchParseException("Failed to parse [" + sValue + "]", e);

View File

@ -25,6 +25,7 @@ import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Streamable;
import org.elasticsearch.common.settings.Settings;
import org.joda.time.Period;
import org.joda.time.PeriodType;
import org.joda.time.format.PeriodFormat;
@ -256,8 +257,13 @@ public class TimeValue implements Serializable, Streamable {
// Allow this special value to be unit-less:
millis = 0;
} else {
// Missing units:
throw new ElasticsearchParseException("Failed to parse setting [" + settingName + "] with value [" + sValue + "] as a time value: unit is missing or unrecognized");
if (Settings.getSettingsRequireUnits()) {
// Missing units:
throw new ElasticsearchParseException("Failed to parse setting [" + settingName + "] with value [" + sValue + "] as a time value: unit is missing or unrecognized");
} else {
// Leniency default to msec for bwc:
millis = Long.parseLong(sValue);
}
}
return new TimeValue(millis, TimeUnit.MILLISECONDS);
} catch (NumberFormatException e) {

View File

@ -20,6 +20,7 @@
package org.elasticsearch.node.internal;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.common.Booleans;
import org.elasticsearch.common.Names;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.Tuple;
@ -129,6 +130,10 @@ public class InternalSettingsPreparer {
settingsBuilder.put(ClusterName.SETTING, ClusterName.DEFAULT.value());
}
String v = settingsBuilder.get(Settings.SETTINGS_REQUIRE_UNITS);
if (v != null) {
Settings.setSettingsRequireUnits(Booleans.parseBoolean(v, true));
}
Settings v1 = settingsBuilder.build();
environment = new Environment(v1);

View File

@ -21,10 +21,13 @@ package org.elasticsearch.cluster.settings;
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequestBuilder;
import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsResponse;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.routing.allocation.decider.DisableAllocationDecider;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.ByteSizeUnit;
import org.elasticsearch.common.util.concurrent.EsExecutors;
import org.elasticsearch.discovery.DiscoverySettings;
import org.elasticsearch.indices.store.IndicesStore;
import org.elasticsearch.test.ElasticsearchIntegrationTest;
@ -189,4 +192,32 @@ public class ClusterSettingsTests extends ElasticsearchIntegrationTest {
// Should fail (missing units for refresh_interval):
client().admin().indices().prepareUpdateSettings("test").setSettings(Settings.builder().put("index.refresh_interval", "10")).execute().actionGet();
}
@Test
public void testMissingUnitsLenient() {
try {
createNode(Settings.builder().put(Settings.SETTINGS_REQUIRE_UNITS, "false").build());
assertAcked(prepareCreate("test"));
client().admin().indices().prepareUpdateSettings("test").setSettings(Settings.builder().put("index.refresh_interval", "10")).execute().actionGet();
} finally {
// Restore the default so subsequent tests require units:
assertFalse(Settings.getSettingsRequireUnits());
Settings.setSettingsRequireUnits(true);
}
}
private void createNode(Settings settings) {
internalCluster().startNode(Settings.builder()
.put(ClusterName.SETTING, "ClusterSettingsTests")
.put("node.name", "ClusterSettingsTests")
.put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)
.put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)
.put(EsExecutors.PROCESSORS, 1) // limit the number of threads created
.put("http.enabled", false)
.put("index.store.type", "ram")
.put("config.ignore_system_properties", true) // make sure we get what we set :)
.put("gateway.type", "none")
.put("indices.memory.interval", "100ms")
.put(settings)
);
}
}