diff --git a/core/src/main/java/org/elasticsearch/action/support/AutoCreateIndex.java b/core/src/main/java/org/elasticsearch/action/support/AutoCreateIndex.java index c8f04852452..cbc087e4477 100644 --- a/core/src/main/java/org/elasticsearch/action/support/AutoCreateIndex.java +++ b/core/src/main/java/org/elasticsearch/action/support/AutoCreateIndex.java @@ -25,6 +25,7 @@ import org.elasticsearch.common.Booleans; import org.elasticsearch.common.Strings; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.regex.Regex; +import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.index.mapper.MapperService; @@ -40,30 +41,30 @@ public final class AutoCreateIndex { private final String[] matches; private final String[] matches2; private final IndexNameExpressionResolver resolver; + public static final Setting AUTO_CREATE_INDEX_SETTING = new Setting<>("action.auto_create_index", "true", AutoCreate::new, false, Setting.Scope.CLUSTER); @Inject public AutoCreateIndex(Settings settings, IndexNameExpressionResolver resolver) { this.resolver = resolver; dynamicMappingDisabled = !MapperService.INDEX_MAPPER_DYNAMIC_SETTING.get(settings); - String value = settings.get("action.auto_create_index"); - if (value == null || Booleans.isExplicitTrue(value)) { + final AutoCreate autoCreate = AUTO_CREATE_INDEX_SETTING.get(settings); + if (autoCreate.autoCreateIndex) { needToCheck = true; globallyDisabled = false; - matches = null; - matches2 = null; - } else if (Booleans.isExplicitFalse(value)) { + matches = autoCreate.indices; + if (matches != null) { + matches2 = new String[matches.length]; + for (int i = 0; i < matches.length; i++) { + matches2[i] = matches[i].substring(1); + } + } else { + matches2 = null; + } + } else { needToCheck = false; globallyDisabled = true; matches = null; matches2 = null; - } else { - needToCheck = true; - globallyDisabled = false; - matches = Strings.commaDelimitedListToStringArray(value); - matches2 = new String[matches.length]; - for (int i = 0; i < matches.length; i++) { - matches2[i] = matches[i].substring(1); - } } } @@ -110,4 +111,32 @@ public final class AutoCreateIndex { } return false; } + + public static class AutoCreate { + private final boolean autoCreateIndex; + private final String[] indices; + + public AutoCreate(String value) { + boolean autoCreateIndex; + String[] indices = null; + try { + autoCreateIndex = Booleans.parseBooleanExact(value); + } catch (IllegalArgumentException ex) { + try { + indices = Strings.commaDelimitedListToStringArray(value); + for (String string : indices) { + if (string == null || string.length() == 0) { + throw new IllegalArgumentException("Can't parse [" + value + "] for setting [action.auto_create_index] must be either [true, false, or a comma seperated list of index patterns]"); + } + } + autoCreateIndex = true; + } catch (IllegalArgumentException ex1) { + ex1.addSuppressed(ex); + throw ex1; + } + } + this.indices = indices; + this.autoCreateIndex = autoCreateIndex; + } + } } diff --git a/core/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeReadAction.java b/core/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeReadAction.java index 681b9f0a648..ed08e5bdba3 100644 --- a/core/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeReadAction.java +++ b/core/src/main/java/org/elasticsearch/action/support/master/TransportMasterNodeReadAction.java @@ -23,6 +23,7 @@ import org.elasticsearch.action.ActionResponse; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.cluster.ClusterService; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; +import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; @@ -36,22 +37,19 @@ import java.util.function.Supplier; public abstract class TransportMasterNodeReadAction, Response extends ActionResponse> extends TransportMasterNodeAction { - public static final String FORCE_LOCAL_SETTING = "action.master.force_local"; + public static final Setting FORCE_LOCAL_SETTING = Setting.boolSetting("action.master.force_local", false, false, Setting.Scope.CLUSTER); - private Boolean forceLocal; + private final boolean forceLocal; protected TransportMasterNodeReadAction(Settings settings, String actionName, TransportService transportService, ClusterService clusterService, ThreadPool threadPool, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver, Supplier request) { super(settings, actionName, transportService, clusterService, threadPool, actionFilters, indexNameExpressionResolver,request); - this.forceLocal = settings.getAsBoolean(FORCE_LOCAL_SETTING, null); + this.forceLocal = FORCE_LOCAL_SETTING.get(settings); } @Override protected final boolean localExecute(Request request) { - if (forceLocal != null) { - return forceLocal; - } - return request.local(); + return forceLocal || request.local(); } } diff --git a/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java b/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java index bcf49eda02f..be7bf50bba0 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java +++ b/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java @@ -19,7 +19,9 @@ package org.elasticsearch.common.settings; import org.elasticsearch.action.admin.indices.close.TransportCloseIndexAction; +import org.elasticsearch.action.support.AutoCreateIndex; import org.elasticsearch.action.support.DestructiveOperations; +import org.elasticsearch.action.support.master.TransportMasterNodeReadAction; import org.elasticsearch.client.transport.TransportClientNodesService; import org.elasticsearch.cluster.ClusterModule; import org.elasticsearch.cluster.InternalClusterInfoService; @@ -261,6 +263,8 @@ public final class ClusterSettings extends AbstractScopedSettings { URLRepository.REPOSITORIES_LIST_DIRECTORIES_SETTING, URLRepository.REPOSITORIES_URL_SETTING, URLRepository.SUPPORTED_PROTOCOLS_SETTING, + TransportMasterNodeReadAction.FORCE_LOCAL_SETTING, + AutoCreateIndex.AUTO_CREATE_INDEX_SETTING, ClusterModule.SHARDS_ALLOCATOR_TYPE_SETTING, EsExecutors.PROCESSORS_SETTING))); } diff --git a/core/src/test/java/org/elasticsearch/action/support/AutoCreateIndexTests.java b/core/src/test/java/org/elasticsearch/action/support/AutoCreateIndexTests.java new file mode 100644 index 00000000000..816e1a110e5 --- /dev/null +++ b/core/src/test/java/org/elasticsearch/action/support/AutoCreateIndexTests.java @@ -0,0 +1,80 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.action.support; + +import org.elasticsearch.Version; +import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.metadata.IndexMetaData; +import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; +import org.elasticsearch.cluster.metadata.MetaData; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.test.ESTestCase; + +public class AutoCreateIndexTests extends ESTestCase { + + public void testBasic() { + { + AutoCreateIndex autoCreateIndex = new AutoCreateIndex(Settings.EMPTY, new IndexNameExpressionResolver(Settings.EMPTY)); + ClusterState cs = buildClusterState("foo"); + assertFalse("already exists", autoCreateIndex.shouldAutoCreate("foo", cs)); + assertTrue(autoCreateIndex.shouldAutoCreate("foobar", cs)); + } + { + AutoCreateIndex autoCreateIndex = new AutoCreateIndex(Settings.builder().put("action.auto_create_index", "-foo,+b*").build(), new IndexNameExpressionResolver(Settings.EMPTY)); + ClusterState cs = buildClusterState("foobar", "baz"); + assertFalse(autoCreateIndex.shouldAutoCreate("foo", cs)); + assertTrue(autoCreateIndex.shouldAutoCreate("bar", cs)); + assertFalse("already exists", autoCreateIndex.shouldAutoCreate("baz", cs)); + } + + { + AutoCreateIndex autoCreateIndex = new AutoCreateIndex(Settings.builder().put("action.auto_create_index", "-foo,+b*").put("index.mapper.dynamic", false).build(), new IndexNameExpressionResolver(Settings.EMPTY)); + ClusterState cs = buildClusterState("foobar", "baz"); + assertFalse(autoCreateIndex.shouldAutoCreate("foo", cs)); + assertFalse(autoCreateIndex.shouldAutoCreate("bar", cs)); + assertFalse("already exists", autoCreateIndex.shouldAutoCreate("baz", cs)); + } + + { + AutoCreateIndex autoCreateIndex = new AutoCreateIndex(Settings.builder().put("action.auto_create_index", false).put("index.mapper.dynamic", false).build(), new IndexNameExpressionResolver(Settings.EMPTY)); + ClusterState cs = buildClusterState("foobar", "baz"); + assertFalse(autoCreateIndex.shouldAutoCreate("foo", cs)); + assertFalse(autoCreateIndex.shouldAutoCreate("bar", cs)); + assertFalse("already exists", autoCreateIndex.shouldAutoCreate("baz", cs)); + } + } + + public void testParseFailed() { + try { + new AutoCreateIndex(Settings.builder().put("action.auto_create_index", ",,,").build(), new IndexNameExpressionResolver(Settings.EMPTY)); + }catch (IllegalArgumentException ex) { + assertEquals("Can't parse [,,,] for setting [action.auto_create_index] must be either [true, false, or a comma seperated list of index patterns]", ex.getMessage()); + } + + } + + public ClusterState buildClusterState(String... indices) { + MetaData.Builder metaData = MetaData.builder(); + for (String index : indices) { + metaData.put(IndexMetaData.builder(index).settings(settings(Version.CURRENT)).numberOfShards(1).numberOfReplicas(1)); + } + return ClusterState.builder(org.elasticsearch.cluster.ClusterName.DEFAULT).metaData(metaData).build(); + } +}