|
21 | 21 |
|
22 | 22 | import org.elasticsearch.action.admin.indices.alias.Alias;
|
23 | 23 | import org.elasticsearch.action.index.IndexRequestBuilder;
|
| 24 | +import org.elasticsearch.cluster.ClusterInfoService; |
| 25 | +import org.elasticsearch.cluster.InternalClusterInfoService; |
| 26 | +import org.elasticsearch.cluster.routing.allocation.DiskThresholdSettings; |
24 | 27 | import org.elasticsearch.common.settings.Settings;
|
| 28 | +import org.elasticsearch.common.unit.TimeValue; |
25 | 29 | import org.elasticsearch.index.IndexNotFoundException;
|
26 | 30 | import org.elasticsearch.index.query.QueryBuilders;
|
27 | 31 | import org.elasticsearch.plugins.Plugin;
|
28 | 32 | import org.elasticsearch.search.sort.SortOrder;
|
29 | 33 | import org.elasticsearch.test.InternalSettingsPlugin;
|
| 34 | +import org.elasticsearch.test.InternalTestCluster; |
| 35 | +import org.elasticsearch.threadpool.ThreadPool; |
30 | 36 |
|
31 | 37 | import java.util.ArrayList;
|
32 | 38 | import java.util.Collection;
|
@@ -214,18 +220,65 @@ public void testDeleteByQueryOnReadOnlyIndex() throws Exception {
|
214 | 220 | }
|
215 | 221 | indexRandom(true, true, true, builders);
|
216 | 222 |
|
217 |
| - String block = randomFrom(SETTING_READ_ONLY, SETTING_READ_ONLY_ALLOW_DELETE); |
218 | 223 | try {
|
219 |
| - enableIndexBlock("test", block); |
| 224 | + enableIndexBlock("test", SETTING_READ_ONLY); |
220 | 225 | assertThat(deleteByQuery().source("test").filter(QueryBuilders.matchAllQuery()).refresh(true).get(),
|
221 |
| - matcher().deleted(0).failures(docs)); |
| 226 | + matcher().deleted(0).failures(docs)); |
222 | 227 | } finally {
|
223 |
| - disableIndexBlock("test", block); |
| 228 | + disableIndexBlock("test", SETTING_READ_ONLY); |
224 | 229 | }
|
225 | 230 |
|
226 | 231 | assertHitCount(client().prepareSearch("test").setSize(0).get(), docs);
|
227 | 232 | }
|
228 | 233 |
|
| 234 | + public void testDeleteByQueryOnReadOnlyAllowDeleteIndex() throws Exception { |
| 235 | + createIndex("test"); |
| 236 | + |
| 237 | + final int docs = randomIntBetween(1, 50); |
| 238 | + List<IndexRequestBuilder> builders = new ArrayList<>(); |
| 239 | + for (int i = 0; i < docs; i++) { |
| 240 | + builders.add(client().prepareIndex("test").setId(Integer.toString(i)).setSource("field", 1)); |
| 241 | + } |
| 242 | + indexRandom(true, true, true, builders); |
| 243 | + |
| 244 | + // Because the index level read_only_allow_delete block can be automatically released by disk allocation decider, |
| 245 | + // so we should test both case of disk allocation decider is enabled and disabled |
| 246 | + boolean diskAllocationDeciderEnabled = randomBoolean(); |
| 247 | + try { |
| 248 | + // When a read_only_allow_delete block is set on the index, |
| 249 | + // it will trigger a retry policy in the delete by query request because the rest status of the block is 429 |
| 250 | + enableIndexBlock("test", SETTING_READ_ONLY_ALLOW_DELETE); |
| 251 | + if (diskAllocationDeciderEnabled) { |
| 252 | + InternalTestCluster internalTestCluster = internalCluster(); |
| 253 | + InternalClusterInfoService infoService = (InternalClusterInfoService) internalTestCluster |
| 254 | + .getInstance(ClusterInfoService.class, internalTestCluster.getMasterName()); |
| 255 | + ThreadPool threadPool = internalTestCluster.getInstance(ThreadPool.class, internalTestCluster.getMasterName()); |
| 256 | + // Refresh the cluster info after a random delay to check the disk threshold and release the block on the index |
| 257 | + threadPool.schedule(infoService::refresh, TimeValue.timeValueMillis(randomIntBetween(1, 100)), ThreadPool.Names.MANAGEMENT); |
| 258 | + // The delete by query request will be executed successfully because the block will be released |
| 259 | + assertThat(deleteByQuery().source("test").filter(QueryBuilders.matchAllQuery()).refresh(true).get(), |
| 260 | + matcher().deleted(docs)); |
| 261 | + } else { |
| 262 | + // Disable the disk allocation decider to ensure the read_only_allow_delete block cannot be released |
| 263 | + setDiskAllocationDeciderEnabled(false); |
| 264 | + // The delete by query request will not be executed successfully because the block cannot be released |
| 265 | + assertThat(deleteByQuery().source("test").filter(QueryBuilders.matchAllQuery()).refresh(true) |
| 266 | + .setMaxRetries(2).setRetryBackoffInitialTime(TimeValue.timeValueMillis(50)).get(), |
| 267 | + matcher().deleted(0).failures(docs)); |
| 268 | + } |
| 269 | + } finally { |
| 270 | + disableIndexBlock("test", SETTING_READ_ONLY_ALLOW_DELETE); |
| 271 | + if (diskAllocationDeciderEnabled == false) { |
| 272 | + setDiskAllocationDeciderEnabled(true); |
| 273 | + } |
| 274 | + } |
| 275 | + if (diskAllocationDeciderEnabled) { |
| 276 | + assertHitCount(client().prepareSearch("test").setSize(0).get(), 0); |
| 277 | + } else { |
| 278 | + assertHitCount(client().prepareSearch("test").setSize(0).get(), docs); |
| 279 | + } |
| 280 | + } |
| 281 | + |
229 | 282 | public void testSlices() throws Exception {
|
230 | 283 | indexRandom(true,
|
231 | 284 | client().prepareIndex("test").setId("1").setSource("foo", "a"),
|
@@ -315,4 +368,12 @@ public void testMissingSources() {
|
315 | 368 | assertThat(response, matcher().deleted(0).slices(hasSize(0)));
|
316 | 369 | }
|
317 | 370 |
|
| 371 | + /** Enables or disables the cluster disk allocation decider **/ |
| 372 | + private void setDiskAllocationDeciderEnabled(boolean value) { |
| 373 | + Settings settings = value ? Settings.builder().putNull( |
| 374 | + DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_DISK_THRESHOLD_ENABLED_SETTING.getKey()).build() : |
| 375 | + Settings.builder().put( |
| 376 | + DiskThresholdSettings.CLUSTER_ROUTING_ALLOCATION_DISK_THRESHOLD_ENABLED_SETTING.getKey(), value).build(); |
| 377 | + assertAcked(client().admin().cluster().prepareUpdateSettings().setTransientSettings(settings).get()); |
| 378 | + } |
318 | 379 | }
|
0 commit comments