|
@@ -11,6 +11,7 @@ package org.elasticsearch.action.admin.indices.rollover;
|
|
|
|
|
|
import org.elasticsearch.action.ActionListener;
|
|
|
import org.elasticsearch.action.ActionRequest;
|
|
|
+import org.elasticsearch.action.IndicesRequest;
|
|
|
import org.elasticsearch.action.admin.indices.stats.CommonStats;
|
|
|
import org.elasticsearch.action.admin.indices.stats.IndexStats;
|
|
|
import org.elasticsearch.action.admin.indices.stats.IndicesStatsAction;
|
|
@@ -19,11 +20,14 @@ import org.elasticsearch.action.admin.indices.stats.IndicesStatsTests;
|
|
|
import org.elasticsearch.action.admin.indices.stats.ShardStats;
|
|
|
import org.elasticsearch.action.datastreams.autosharding.DataStreamAutoShardingService;
|
|
|
import org.elasticsearch.action.support.ActionFilters;
|
|
|
+import org.elasticsearch.action.support.IndicesOptions;
|
|
|
import org.elasticsearch.action.support.PlainActionFuture;
|
|
|
import org.elasticsearch.action.support.master.AcknowledgedResponse;
|
|
|
import org.elasticsearch.client.internal.Client;
|
|
|
import org.elasticsearch.cluster.ClusterName;
|
|
|
import org.elasticsearch.cluster.ClusterState;
|
|
|
+import org.elasticsearch.cluster.block.ClusterBlockException;
|
|
|
+import org.elasticsearch.cluster.block.ClusterBlocks;
|
|
|
import org.elasticsearch.cluster.metadata.AliasMetadata;
|
|
|
import org.elasticsearch.cluster.metadata.DataStream;
|
|
|
import org.elasticsearch.cluster.metadata.IndexMetadata;
|
|
@@ -43,6 +47,7 @@ import org.elasticsearch.common.UUIDs;
|
|
|
import org.elasticsearch.common.settings.Settings;
|
|
|
import org.elasticsearch.common.unit.ByteSizeValue;
|
|
|
import org.elasticsearch.core.TimeValue;
|
|
|
+import org.elasticsearch.index.Index;
|
|
|
import org.elasticsearch.index.IndexMode;
|
|
|
import org.elasticsearch.index.IndexVersion;
|
|
|
import org.elasticsearch.index.cache.query.QueryCacheStats;
|
|
@@ -578,6 +583,223 @@ public class TransportRolloverActionTests extends ESTestCase {
|
|
|
assertThat(illegalStateException.getMessage(), containsString("Aliases to data streams cannot be rolled over."));
|
|
|
}
|
|
|
|
|
|
+ public void testCheckBlockForIndices() {
|
|
|
+ final TransportRolloverAction transportRolloverAction = new TransportRolloverAction(
|
|
|
+ mock(TransportService.class),
|
|
|
+ mockClusterService,
|
|
|
+ mockThreadPool,
|
|
|
+ mockActionFilters,
|
|
|
+ mockIndexNameExpressionResolver,
|
|
|
+ rolloverService,
|
|
|
+ mockClient,
|
|
|
+ mockAllocationService,
|
|
|
+ mockMetadataDataStreamService,
|
|
|
+ dataStreamAutoShardingService
|
|
|
+ );
|
|
|
+ final IndexMetadata.Builder indexMetadata1 = IndexMetadata.builder("my-index-1")
|
|
|
+ .putAlias(AliasMetadata.builder("my-alias").writeIndex(true).build())
|
|
|
+ .settings(settings(IndexVersion.current()))
|
|
|
+ .numberOfShards(1)
|
|
|
+ .numberOfReplicas(1);
|
|
|
+ final IndexMetadata indexMetadata2 = IndexMetadata.builder("my-index-2")
|
|
|
+ .settings(settings(IndexVersion.current()).put(IndexMetadata.INDEX_READ_ONLY_SETTING.getKey(), true))
|
|
|
+ .numberOfShards(1)
|
|
|
+ .numberOfReplicas(1)
|
|
|
+ .build();
|
|
|
+ final ClusterState stateBefore = ClusterState.builder(ClusterName.DEFAULT)
|
|
|
+ .metadata(Metadata.builder().put(indexMetadata1).put(indexMetadata2, false))
|
|
|
+ .blocks(ClusterBlocks.builder().addBlocks(indexMetadata2))
|
|
|
+ .build();
|
|
|
+ {
|
|
|
+ RolloverRequest rolloverRequest = new RolloverRequest("my-alias", "my-new-index");
|
|
|
+ when(mockIndexNameExpressionResolver.concreteIndexNames(any(), any(), (IndicesRequest) any())).thenReturn(
|
|
|
+ new String[] { "my-index-1" }
|
|
|
+ );
|
|
|
+ assertNull(transportRolloverAction.checkBlock(rolloverRequest, stateBefore));
|
|
|
+ }
|
|
|
+ {
|
|
|
+ RolloverRequest rolloverRequest = new RolloverRequest("my-index-2", "my-new-index");
|
|
|
+ when(mockIndexNameExpressionResolver.concreteIndexNames(any(), any(), (IndicesRequest) any())).thenReturn(
|
|
|
+ new String[] { "my-index-2" }
|
|
|
+ );
|
|
|
+ assertNotNull(transportRolloverAction.checkBlock(rolloverRequest, stateBefore));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testCheckBlockForDataStreams() {
|
|
|
+ final TransportRolloverAction transportRolloverAction = new TransportRolloverAction(
|
|
|
+ mock(TransportService.class),
|
|
|
+ mockClusterService,
|
|
|
+ mockThreadPool,
|
|
|
+ mockActionFilters,
|
|
|
+ mockIndexNameExpressionResolver,
|
|
|
+ rolloverService,
|
|
|
+ mockClient,
|
|
|
+ mockAllocationService,
|
|
|
+ mockMetadataDataStreamService,
|
|
|
+ dataStreamAutoShardingService
|
|
|
+ );
|
|
|
+ String dataStreamName = randomAlphaOfLength(20);
|
|
|
+ {
|
|
|
+ // First, make sure checkBlock returns null when there are no blocks
|
|
|
+ final ClusterState clusterState = createDataStream(
|
|
|
+ dataStreamName,
|
|
|
+ false,
|
|
|
+ false,
|
|
|
+ randomBoolean(),
|
|
|
+ randomBoolean(),
|
|
|
+ randomBoolean()
|
|
|
+ );
|
|
|
+ RolloverRequest rolloverRequest = new RolloverRequest(dataStreamName, null);
|
|
|
+ assertNull(transportRolloverAction.checkBlock(rolloverRequest, clusterState));
|
|
|
+ }
|
|
|
+ {
|
|
|
+ // Make sure checkBlock returns null when indices other than the write index have blocks
|
|
|
+ final ClusterState clusterState = createDataStream(
|
|
|
+ dataStreamName,
|
|
|
+ false,
|
|
|
+ true,
|
|
|
+ randomBoolean(),
|
|
|
+ randomBoolean(),
|
|
|
+ randomBoolean()
|
|
|
+ );
|
|
|
+ RolloverRequest rolloverRequest = new RolloverRequest(dataStreamName, null);
|
|
|
+ assertNull(transportRolloverAction.checkBlock(rolloverRequest, clusterState));
|
|
|
+ }
|
|
|
+ {
|
|
|
+ // Make sure checkBlock returns null when indices other than the write index have blocks and we use "::data"
|
|
|
+ final ClusterState clusterState = createDataStream(
|
|
|
+ dataStreamName,
|
|
|
+ false,
|
|
|
+ true,
|
|
|
+ randomBoolean(),
|
|
|
+ randomBoolean(),
|
|
|
+ randomBoolean()
|
|
|
+ );
|
|
|
+ RolloverRequest rolloverRequest = new RolloverRequest(dataStreamName + "::data", null);
|
|
|
+ assertNull(transportRolloverAction.checkBlock(rolloverRequest, clusterState));
|
|
|
+ }
|
|
|
+ {
|
|
|
+ // Make sure checkBlock returns an exception when the write index has a block
|
|
|
+ ClusterState clusterState = createDataStream(
|
|
|
+ dataStreamName,
|
|
|
+ true,
|
|
|
+ randomBoolean(),
|
|
|
+ randomBoolean(),
|
|
|
+ randomBoolean(),
|
|
|
+ randomBoolean()
|
|
|
+ );
|
|
|
+ RolloverRequest rolloverRequest = new RolloverRequest(dataStreamName, null);
|
|
|
+ if (randomBoolean()) {
|
|
|
+ rolloverRequest.setIndicesOptions(IndicesOptions.lenientExpandOpenNoSelectors());
|
|
|
+ }
|
|
|
+ ClusterBlockException e = transportRolloverAction.checkBlock(rolloverRequest, clusterState);
|
|
|
+ assertNotNull(e);
|
|
|
+ }
|
|
|
+ {
|
|
|
+ // Make sure checkBlock returns an exception when the write index has a block and we use "::data"
|
|
|
+ ClusterState clusterState = createDataStream(
|
|
|
+ dataStreamName,
|
|
|
+ true,
|
|
|
+ randomBoolean(),
|
|
|
+ randomBoolean(),
|
|
|
+ randomBoolean(),
|
|
|
+ randomBoolean()
|
|
|
+ );
|
|
|
+ RolloverRequest rolloverRequest = new RolloverRequest(dataStreamName + "::data", null);
|
|
|
+ ClusterBlockException e = transportRolloverAction.checkBlock(rolloverRequest, clusterState);
|
|
|
+ assertNotNull(e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void testCheckBlockForDataStreamFailureStores() {
|
|
|
+ final TransportRolloverAction transportRolloverAction = new TransportRolloverAction(
|
|
|
+ mock(TransportService.class),
|
|
|
+ mockClusterService,
|
|
|
+ mockThreadPool,
|
|
|
+ mockActionFilters,
|
|
|
+ mockIndexNameExpressionResolver,
|
|
|
+ rolloverService,
|
|
|
+ mockClient,
|
|
|
+ mockAllocationService,
|
|
|
+ mockMetadataDataStreamService,
|
|
|
+ dataStreamAutoShardingService
|
|
|
+ );
|
|
|
+ String dataStreamName = randomAlphaOfLength(20);
|
|
|
+ {
|
|
|
+ // Make sure checkBlock returns no exception when there is no failure store block
|
|
|
+ ClusterState clusterState = createDataStream(dataStreamName, randomBoolean(), randomBoolean(), true, false, false);
|
|
|
+ RolloverRequest rolloverRequest = new RolloverRequest(dataStreamName + "::failures", null);
|
|
|
+ assertNull(transportRolloverAction.checkBlock(rolloverRequest, clusterState));
|
|
|
+ }
|
|
|
+ {
|
|
|
+ // Make sure checkBlock returns an exception when the failure store write index has a block
|
|
|
+ ClusterState clusterState = createDataStream(dataStreamName, randomBoolean(), randomBoolean(), true, true, randomBoolean());
|
|
|
+ RolloverRequest rolloverRequest = new RolloverRequest(dataStreamName + "::failures", null);
|
|
|
+ assertNotNull(transportRolloverAction.checkBlock(rolloverRequest, clusterState));
|
|
|
+ }
|
|
|
+ {
|
|
|
+ // Make sure checkBlock returns no exception when failure store non-write indices have a block
|
|
|
+ ClusterState clusterState = createDataStream(dataStreamName, randomBoolean(), randomBoolean(), true, false, true);
|
|
|
+ RolloverRequest rolloverRequest = new RolloverRequest(dataStreamName + "::failures", null);
|
|
|
+ assertNull(transportRolloverAction.checkBlock(rolloverRequest, clusterState));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private ClusterState createDataStream(
|
|
|
+ String dataStreamName,
|
|
|
+ boolean blockOnWriteIndex,
|
|
|
+ boolean blocksOnNonWriteIndices,
|
|
|
+ boolean includeFailureStore,
|
|
|
+ boolean blockOnFailureStoreWriteIndex,
|
|
|
+ boolean blockOnFailureStoreNonWriteIndices
|
|
|
+ ) {
|
|
|
+ ClusterState.Builder clusterStateBuilder = ClusterState.builder(ClusterName.DEFAULT);
|
|
|
+ Metadata.Builder metadataBuilder = Metadata.builder();
|
|
|
+ ClusterBlocks.Builder clusterBlocksBuilder = ClusterBlocks.builder();
|
|
|
+ List<Index> indices = new ArrayList<>();
|
|
|
+ int totalIndices = randomIntBetween(1, 20);
|
|
|
+ for (int i = 0; i < totalIndices; i++) {
|
|
|
+ Settings.Builder settingsBuilder = settings(IndexVersion.current());
|
|
|
+ if ((blockOnWriteIndex && i == totalIndices - 1) || (blocksOnNonWriteIndices && i != totalIndices - 1)) {
|
|
|
+ settingsBuilder.put(IndexMetadata.INDEX_READ_ONLY_SETTING.getKey(), true);
|
|
|
+ }
|
|
|
+ final IndexMetadata backingIndexMetadata = IndexMetadata.builder(".ds-logs-ds-00000" + (i + 1))
|
|
|
+ .settings(settingsBuilder)
|
|
|
+ .numberOfShards(1)
|
|
|
+ .numberOfReplicas(1)
|
|
|
+ .build();
|
|
|
+ metadataBuilder.put(backingIndexMetadata, false);
|
|
|
+ indices.add(backingIndexMetadata.getIndex());
|
|
|
+ clusterBlocksBuilder.addBlocks(backingIndexMetadata);
|
|
|
+ }
|
|
|
+
|
|
|
+ DataStream.Builder dataStreamBuilder = DataStream.builder(dataStreamName, indices)
|
|
|
+ .setMetadata(Map.of())
|
|
|
+ .setIndexMode(randomFrom(IndexMode.values()));
|
|
|
+ if (includeFailureStore) {
|
|
|
+ List<Index> failureStoreIndices = new ArrayList<>();
|
|
|
+ int totalFailureStoreIndices = randomIntBetween(1, 20);
|
|
|
+ for (int i = 0; i < totalFailureStoreIndices; i++) {
|
|
|
+ Settings.Builder settingsBuilder = settings(IndexVersion.current());
|
|
|
+ if ((blockOnFailureStoreWriteIndex && i == totalFailureStoreIndices - 1)
|
|
|
+ || (blockOnFailureStoreNonWriteIndices && i != totalFailureStoreIndices - 1)) {
|
|
|
+ settingsBuilder.put(IndexMetadata.INDEX_READ_ONLY_SETTING.getKey(), true);
|
|
|
+ }
|
|
|
+ final IndexMetadata failureStoreIndexMetadata = IndexMetadata.builder(
|
|
|
+ DataStream.getDefaultFailureStoreName(dataStreamName, i + 1, randomMillisUpToYear9999())
|
|
|
+ ).settings(settingsBuilder).numberOfShards(1).numberOfReplicas(1).build();
|
|
|
+ failureStoreIndices.add(failureStoreIndexMetadata.getIndex());
|
|
|
+ clusterBlocksBuilder.addBlocks(failureStoreIndexMetadata);
|
|
|
+ }
|
|
|
+ dataStreamBuilder.setFailureIndices(DataStream.DataStreamIndices.failureIndicesBuilder(failureStoreIndices).build());
|
|
|
+ }
|
|
|
+ clusterStateBuilder.blocks(clusterBlocksBuilder);
|
|
|
+ final DataStream dataStream = dataStreamBuilder.build();
|
|
|
+ metadataBuilder.put(dataStream);
|
|
|
+ return clusterStateBuilder.metadata(metadataBuilder).build();
|
|
|
+ }
|
|
|
+
|
|
|
private IndicesStatsResponse createIndicesStatResponse(String indexName, long totalDocs, long primariesDocs) {
|
|
|
final CommonStats primaryStats = mock(CommonStats.class);
|
|
|
when(primaryStats.getDocs()).thenReturn(new DocsStats(primariesDocs, 0, between(1, 10000)));
|