/*
* 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)
);
}
}