/* * 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.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.ESIntegTestCase; import org.hamcrest.Matchers; import org.junit.Test; import static org.elasticsearch.common.settings.Settings.settingsBuilder; import static org.elasticsearch.test.ESIntegTestCase.ClusterScope; import static org.elasticsearch.test.ESIntegTestCase.Scope.TEST; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertBlocked; import static org.hamcrest.Matchers.*; @ClusterScope(scope = TEST) public class ClusterSettingsIT extends ESIntegTestCase { @Test public void clusterNonExistingSettingsUpdate() { String key1 = "no_idea_what_you_are_talking_about"; int value1 = 10; ClusterUpdateSettingsResponse response = client().admin().cluster() .prepareUpdateSettings() .setTransientSettings(Settings.builder().put(key1, value1).build()) .get(); assertAcked(response); assertThat(response.getTransientSettings().getAsMap().entrySet(), Matchers.emptyIterable()); } @Test public void clusterSettingsUpdateResponse() { String key1 = IndicesStore.INDICES_STORE_THROTTLE_MAX_BYTES_PER_SEC; int value1 = 10; String key2 = DisableAllocationDecider.CLUSTER_ROUTING_ALLOCATION_DISABLE_ALLOCATION; boolean value2 = true; Settings transientSettings1 = Settings.builder().put(key1, value1, ByteSizeUnit.BYTES).build(); Settings persistentSettings1 = Settings.builder().put(key2, value2).build(); ClusterUpdateSettingsResponse response1 = client().admin().cluster() .prepareUpdateSettings() .setTransientSettings(transientSettings1) .setPersistentSettings(persistentSettings1) .execute() .actionGet(); assertAcked(response1); assertThat(response1.getTransientSettings().get(key1), notNullValue()); assertThat(response1.getTransientSettings().get(key2), nullValue()); assertThat(response1.getPersistentSettings().get(key1), nullValue()); assertThat(response1.getPersistentSettings().get(key2), notNullValue()); Settings transientSettings2 = Settings.builder().put(key1, value1, ByteSizeUnit.BYTES).put(key2, value2).build(); Settings persistentSettings2 = Settings.EMPTY; ClusterUpdateSettingsResponse response2 = client().admin().cluster() .prepareUpdateSettings() .setTransientSettings(transientSettings2) .setPersistentSettings(persistentSettings2) .execute() .actionGet(); assertAcked(response2); assertThat(response2.getTransientSettings().get(key1), notNullValue()); assertThat(response2.getTransientSettings().get(key2), notNullValue()); assertThat(response2.getPersistentSettings().get(key1), nullValue()); assertThat(response2.getPersistentSettings().get(key2), nullValue()); Settings transientSettings3 = Settings.EMPTY; Settings persistentSettings3 = Settings.builder().put(key1, value1, ByteSizeUnit.BYTES).put(key2, value2).build(); ClusterUpdateSettingsResponse response3 = client().admin().cluster() .prepareUpdateSettings() .setTransientSettings(transientSettings3) .setPersistentSettings(persistentSettings3) .execute() .actionGet(); assertAcked(response3); assertThat(response3.getTransientSettings().get(key1), nullValue()); assertThat(response3.getTransientSettings().get(key2), nullValue()); assertThat(response3.getPersistentSettings().get(key1), notNullValue()); assertThat(response3.getPersistentSettings().get(key2), notNullValue()); } @Test public void testUpdateDiscoveryPublishTimeout() { DiscoverySettings discoverySettings = internalCluster().getInstance(DiscoverySettings.class); assertThat(discoverySettings.getPublishTimeout(), equalTo(DiscoverySettings.DEFAULT_PUBLISH_TIMEOUT)); ClusterUpdateSettingsResponse response = client().admin().cluster() .prepareUpdateSettings() .setTransientSettings(Settings.builder().put(DiscoverySettings.PUBLISH_TIMEOUT, "1s").build()) .get(); assertAcked(response); assertThat(response.getTransientSettings().getAsMap().get(DiscoverySettings.PUBLISH_TIMEOUT), equalTo("1s")); assertThat(discoverySettings.getPublishTimeout().seconds(), equalTo(1l)); response = client().admin().cluster() .prepareUpdateSettings() .setTransientSettings(Settings.builder().put(DiscoverySettings.PUBLISH_TIMEOUT, "whatever").build()) .get(); assertAcked(response); assertThat(response.getTransientSettings().getAsMap().entrySet(), Matchers.emptyIterable()); assertThat(discoverySettings.getPublishTimeout().seconds(), equalTo(1l)); response = client().admin().cluster() .prepareUpdateSettings() .setTransientSettings(Settings.builder().put(DiscoverySettings.PUBLISH_TIMEOUT, -1).build()) .get(); assertAcked(response); assertThat(response.getTransientSettings().getAsMap().entrySet(), Matchers.emptyIterable()); assertThat(discoverySettings.getPublishTimeout().seconds(), equalTo(1l)); } @Test public void testClusterUpdateSettingsWithBlocks() { String key1 = "cluster.routing.allocation.enable"; Settings transientSettings = Settings.builder().put(key1, false).build(); String key2 = "cluster.routing.allocation.node_concurrent_recoveries"; Settings persistentSettings = Settings.builder().put(key2, "5").build(); ClusterUpdateSettingsRequestBuilder request = client().admin().cluster().prepareUpdateSettings() .setTransientSettings(transientSettings) .setPersistentSettings(persistentSettings); // Cluster settings updates are blocked when the cluster is read only try { setClusterReadOnly(true); assertBlocked(request, MetaData.CLUSTER_READ_ONLY_BLOCK); // But it's possible to update the settings to update the "cluster.blocks.read_only" setting Settings settings = settingsBuilder().put(MetaData.SETTING_READ_ONLY, false).build(); assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(settings).get()); } finally { setClusterReadOnly(false); } // It should work now ClusterUpdateSettingsResponse response = request.execute().actionGet(); assertAcked(response); assertThat(response.getTransientSettings().get(key1), notNullValue()); assertThat(response.getTransientSettings().get(key2), nullValue()); assertThat(response.getPersistentSettings().get(key1), nullValue()); assertThat(response.getPersistentSettings().get(key2), notNullValue()); } @Test(expected = IllegalArgumentException.class) public void testMissingUnits() { assertAcked(prepareCreate("test")); // 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")); ensureGreen(); 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, "ClusterSettingsIT") .put("node.name", "ClusterSettingsIT") .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("config.ignore_system_properties", true) // make sure we get what we set :) .put(settings) ); } }