|
11 | 11 |
|
12 | 12 | import org.elasticsearch.action.ActionListener; |
13 | 13 | import org.elasticsearch.action.ActionRequest; |
| 14 | +import org.elasticsearch.action.IndicesRequest; |
14 | 15 | import org.elasticsearch.action.admin.indices.stats.CommonStats; |
15 | 16 | import org.elasticsearch.action.admin.indices.stats.IndexStats; |
16 | 17 | import org.elasticsearch.action.admin.indices.stats.IndicesStatsAction; |
|
19 | 20 | import org.elasticsearch.action.admin.indices.stats.ShardStats; |
20 | 21 | import org.elasticsearch.action.datastreams.autosharding.DataStreamAutoShardingService; |
21 | 22 | import org.elasticsearch.action.support.ActionFilters; |
| 23 | +import org.elasticsearch.action.support.IndicesOptions; |
22 | 24 | import org.elasticsearch.action.support.PlainActionFuture; |
23 | 25 | import org.elasticsearch.action.support.master.AcknowledgedResponse; |
24 | 26 | import org.elasticsearch.client.internal.Client; |
25 | 27 | import org.elasticsearch.cluster.ClusterName; |
26 | 28 | import org.elasticsearch.cluster.ClusterState; |
| 29 | +import org.elasticsearch.cluster.block.ClusterBlockException; |
| 30 | +import org.elasticsearch.cluster.block.ClusterBlocks; |
27 | 31 | import org.elasticsearch.cluster.metadata.AliasMetadata; |
28 | 32 | import org.elasticsearch.cluster.metadata.DataStream; |
29 | 33 | import org.elasticsearch.cluster.metadata.IndexMetadata; |
|
43 | 47 | import org.elasticsearch.common.settings.Settings; |
44 | 48 | import org.elasticsearch.common.unit.ByteSizeValue; |
45 | 49 | import org.elasticsearch.core.TimeValue; |
| 50 | +import org.elasticsearch.index.Index; |
46 | 51 | import org.elasticsearch.index.IndexMode; |
47 | 52 | import org.elasticsearch.index.IndexVersion; |
48 | 53 | import org.elasticsearch.index.cache.query.QueryCacheStats; |
@@ -578,6 +583,223 @@ public void testRolloverAliasToDataStreamFails() throws Exception { |
578 | 583 | assertThat(illegalStateException.getMessage(), containsString("Aliases to data streams cannot be rolled over.")); |
579 | 584 | } |
580 | 585 |
|
| 586 | + public void testCheckBlockForIndices() { |
| 587 | + final TransportRolloverAction transportRolloverAction = new TransportRolloverAction( |
| 588 | + mock(TransportService.class), |
| 589 | + mockClusterService, |
| 590 | + mockThreadPool, |
| 591 | + mockActionFilters, |
| 592 | + mockIndexNameExpressionResolver, |
| 593 | + rolloverService, |
| 594 | + mockClient, |
| 595 | + mockAllocationService, |
| 596 | + mockMetadataDataStreamService, |
| 597 | + dataStreamAutoShardingService |
| 598 | + ); |
| 599 | + final IndexMetadata.Builder indexMetadata1 = IndexMetadata.builder("my-index-1") |
| 600 | + .putAlias(AliasMetadata.builder("my-alias").writeIndex(true).build()) |
| 601 | + .settings(settings(IndexVersion.current())) |
| 602 | + .numberOfShards(1) |
| 603 | + .numberOfReplicas(1); |
| 604 | + final IndexMetadata indexMetadata2 = IndexMetadata.builder("my-index-2") |
| 605 | + .settings(settings(IndexVersion.current()).put(IndexMetadata.INDEX_READ_ONLY_SETTING.getKey(), true)) |
| 606 | + .numberOfShards(1) |
| 607 | + .numberOfReplicas(1) |
| 608 | + .build(); |
| 609 | + final ClusterState stateBefore = ClusterState.builder(ClusterName.DEFAULT) |
| 610 | + .metadata(Metadata.builder().put(indexMetadata1).put(indexMetadata2, false)) |
| 611 | + .blocks(ClusterBlocks.builder().addBlocks(indexMetadata2)) |
| 612 | + .build(); |
| 613 | + { |
| 614 | + RolloverRequest rolloverRequest = new RolloverRequest("my-alias", "my-new-index"); |
| 615 | + when(mockIndexNameExpressionResolver.concreteIndexNames(any(), any(), (IndicesRequest) any())).thenReturn( |
| 616 | + new String[] { "my-index-1" } |
| 617 | + ); |
| 618 | + assertNull(transportRolloverAction.checkBlock(rolloverRequest, stateBefore)); |
| 619 | + } |
| 620 | + { |
| 621 | + RolloverRequest rolloverRequest = new RolloverRequest("my-index-2", "my-new-index"); |
| 622 | + when(mockIndexNameExpressionResolver.concreteIndexNames(any(), any(), (IndicesRequest) any())).thenReturn( |
| 623 | + new String[] { "my-index-2" } |
| 624 | + ); |
| 625 | + assertNotNull(transportRolloverAction.checkBlock(rolloverRequest, stateBefore)); |
| 626 | + } |
| 627 | + } |
| 628 | + |
| 629 | + public void testCheckBlockForDataStreams() { |
| 630 | + final TransportRolloverAction transportRolloverAction = new TransportRolloverAction( |
| 631 | + mock(TransportService.class), |
| 632 | + mockClusterService, |
| 633 | + mockThreadPool, |
| 634 | + mockActionFilters, |
| 635 | + mockIndexNameExpressionResolver, |
| 636 | + rolloverService, |
| 637 | + mockClient, |
| 638 | + mockAllocationService, |
| 639 | + mockMetadataDataStreamService, |
| 640 | + dataStreamAutoShardingService |
| 641 | + ); |
| 642 | + String dataStreamName = randomAlphaOfLength(20); |
| 643 | + { |
| 644 | + // First, make sure checkBlock returns null when there are no blocks |
| 645 | + final ClusterState clusterState = createDataStream( |
| 646 | + dataStreamName, |
| 647 | + false, |
| 648 | + false, |
| 649 | + randomBoolean(), |
| 650 | + randomBoolean(), |
| 651 | + randomBoolean() |
| 652 | + ); |
| 653 | + RolloverRequest rolloverRequest = new RolloverRequest(dataStreamName, null); |
| 654 | + assertNull(transportRolloverAction.checkBlock(rolloverRequest, clusterState)); |
| 655 | + } |
| 656 | + { |
| 657 | + // Make sure checkBlock returns null when indices other than the write index have blocks |
| 658 | + final ClusterState clusterState = createDataStream( |
| 659 | + dataStreamName, |
| 660 | + false, |
| 661 | + true, |
| 662 | + randomBoolean(), |
| 663 | + randomBoolean(), |
| 664 | + randomBoolean() |
| 665 | + ); |
| 666 | + RolloverRequest rolloverRequest = new RolloverRequest(dataStreamName, null); |
| 667 | + assertNull(transportRolloverAction.checkBlock(rolloverRequest, clusterState)); |
| 668 | + } |
| 669 | + { |
| 670 | + // Make sure checkBlock returns null when indices other than the write index have blocks and we use "::data" |
| 671 | + final ClusterState clusterState = createDataStream( |
| 672 | + dataStreamName, |
| 673 | + false, |
| 674 | + true, |
| 675 | + randomBoolean(), |
| 676 | + randomBoolean(), |
| 677 | + randomBoolean() |
| 678 | + ); |
| 679 | + RolloverRequest rolloverRequest = new RolloverRequest(dataStreamName + "::data", null); |
| 680 | + assertNull(transportRolloverAction.checkBlock(rolloverRequest, clusterState)); |
| 681 | + } |
| 682 | + { |
| 683 | + // Make sure checkBlock returns an exception when the write index has a block |
| 684 | + ClusterState clusterState = createDataStream( |
| 685 | + dataStreamName, |
| 686 | + true, |
| 687 | + randomBoolean(), |
| 688 | + randomBoolean(), |
| 689 | + randomBoolean(), |
| 690 | + randomBoolean() |
| 691 | + ); |
| 692 | + RolloverRequest rolloverRequest = new RolloverRequest(dataStreamName, null); |
| 693 | + if (randomBoolean()) { |
| 694 | + rolloverRequest.setIndicesOptions(IndicesOptions.lenientExpandOpenNoSelectors()); |
| 695 | + } |
| 696 | + ClusterBlockException e = transportRolloverAction.checkBlock(rolloverRequest, clusterState); |
| 697 | + assertNotNull(e); |
| 698 | + } |
| 699 | + { |
| 700 | + // Make sure checkBlock returns an exception when the write index has a block and we use "::data" |
| 701 | + ClusterState clusterState = createDataStream( |
| 702 | + dataStreamName, |
| 703 | + true, |
| 704 | + randomBoolean(), |
| 705 | + randomBoolean(), |
| 706 | + randomBoolean(), |
| 707 | + randomBoolean() |
| 708 | + ); |
| 709 | + RolloverRequest rolloverRequest = new RolloverRequest(dataStreamName + "::data", null); |
| 710 | + ClusterBlockException e = transportRolloverAction.checkBlock(rolloverRequest, clusterState); |
| 711 | + assertNotNull(e); |
| 712 | + } |
| 713 | + } |
| 714 | + |
| 715 | + public void testCheckBlockForDataStreamFailureStores() { |
| 716 | + final TransportRolloverAction transportRolloverAction = new TransportRolloverAction( |
| 717 | + mock(TransportService.class), |
| 718 | + mockClusterService, |
| 719 | + mockThreadPool, |
| 720 | + mockActionFilters, |
| 721 | + mockIndexNameExpressionResolver, |
| 722 | + rolloverService, |
| 723 | + mockClient, |
| 724 | + mockAllocationService, |
| 725 | + mockMetadataDataStreamService, |
| 726 | + dataStreamAutoShardingService |
| 727 | + ); |
| 728 | + String dataStreamName = randomAlphaOfLength(20); |
| 729 | + { |
| 730 | + // Make sure checkBlock returns no exception when there is no failure store block |
| 731 | + ClusterState clusterState = createDataStream(dataStreamName, randomBoolean(), randomBoolean(), true, false, false); |
| 732 | + RolloverRequest rolloverRequest = new RolloverRequest(dataStreamName + "::failures", null); |
| 733 | + assertNull(transportRolloverAction.checkBlock(rolloverRequest, clusterState)); |
| 734 | + } |
| 735 | + { |
| 736 | + // Make sure checkBlock returns an exception when the failure store write index has a block |
| 737 | + ClusterState clusterState = createDataStream(dataStreamName, randomBoolean(), randomBoolean(), true, true, randomBoolean()); |
| 738 | + RolloverRequest rolloverRequest = new RolloverRequest(dataStreamName + "::failures", null); |
| 739 | + assertNotNull(transportRolloverAction.checkBlock(rolloverRequest, clusterState)); |
| 740 | + } |
| 741 | + { |
| 742 | + // Make sure checkBlock returns no exception when failure store non-write indices have a block |
| 743 | + ClusterState clusterState = createDataStream(dataStreamName, randomBoolean(), randomBoolean(), true, false, true); |
| 744 | + RolloverRequest rolloverRequest = new RolloverRequest(dataStreamName + "::failures", null); |
| 745 | + assertNull(transportRolloverAction.checkBlock(rolloverRequest, clusterState)); |
| 746 | + } |
| 747 | + } |
| 748 | + |
| 749 | + private ClusterState createDataStream( |
| 750 | + String dataStreamName, |
| 751 | + boolean blockOnWriteIndex, |
| 752 | + boolean blocksOnNonWriteIndices, |
| 753 | + boolean includeFailureStore, |
| 754 | + boolean blockOnFailureStoreWriteIndex, |
| 755 | + boolean blockOnFailureStoreNonWriteIndices |
| 756 | + ) { |
| 757 | + ClusterState.Builder clusterStateBuilder = ClusterState.builder(ClusterName.DEFAULT); |
| 758 | + Metadata.Builder metadataBuilder = Metadata.builder(); |
| 759 | + ClusterBlocks.Builder clusterBlocksBuilder = ClusterBlocks.builder(); |
| 760 | + List<Index> indices = new ArrayList<>(); |
| 761 | + int totalIndices = randomIntBetween(1, 20); |
| 762 | + for (int i = 0; i < totalIndices; i++) { |
| 763 | + Settings.Builder settingsBuilder = settings(IndexVersion.current()); |
| 764 | + if ((blockOnWriteIndex && i == totalIndices - 1) || (blocksOnNonWriteIndices && i != totalIndices - 1)) { |
| 765 | + settingsBuilder.put(IndexMetadata.INDEX_READ_ONLY_SETTING.getKey(), true); |
| 766 | + } |
| 767 | + final IndexMetadata backingIndexMetadata = IndexMetadata.builder(".ds-logs-ds-00000" + (i + 1)) |
| 768 | + .settings(settingsBuilder) |
| 769 | + .numberOfShards(1) |
| 770 | + .numberOfReplicas(1) |
| 771 | + .build(); |
| 772 | + metadataBuilder.put(backingIndexMetadata, false); |
| 773 | + indices.add(backingIndexMetadata.getIndex()); |
| 774 | + clusterBlocksBuilder.addBlocks(backingIndexMetadata); |
| 775 | + } |
| 776 | + |
| 777 | + DataStream.Builder dataStreamBuilder = DataStream.builder(dataStreamName, indices) |
| 778 | + .setMetadata(Map.of()) |
| 779 | + .setIndexMode(randomFrom(IndexMode.values())); |
| 780 | + if (includeFailureStore) { |
| 781 | + List<Index> failureStoreIndices = new ArrayList<>(); |
| 782 | + int totalFailureStoreIndices = randomIntBetween(1, 20); |
| 783 | + for (int i = 0; i < totalFailureStoreIndices; i++) { |
| 784 | + Settings.Builder settingsBuilder = settings(IndexVersion.current()); |
| 785 | + if ((blockOnFailureStoreWriteIndex && i == totalFailureStoreIndices - 1) |
| 786 | + || (blockOnFailureStoreNonWriteIndices && i != totalFailureStoreIndices - 1)) { |
| 787 | + settingsBuilder.put(IndexMetadata.INDEX_READ_ONLY_SETTING.getKey(), true); |
| 788 | + } |
| 789 | + final IndexMetadata failureStoreIndexMetadata = IndexMetadata.builder( |
| 790 | + DataStream.getDefaultFailureStoreName(dataStreamName, i + 1, randomMillisUpToYear9999()) |
| 791 | + ).settings(settingsBuilder).numberOfShards(1).numberOfReplicas(1).build(); |
| 792 | + failureStoreIndices.add(failureStoreIndexMetadata.getIndex()); |
| 793 | + clusterBlocksBuilder.addBlocks(failureStoreIndexMetadata); |
| 794 | + } |
| 795 | + dataStreamBuilder.setFailureIndices(DataStream.DataStreamIndices.failureIndicesBuilder(failureStoreIndices).build()); |
| 796 | + } |
| 797 | + clusterStateBuilder.blocks(clusterBlocksBuilder); |
| 798 | + final DataStream dataStream = dataStreamBuilder.build(); |
| 799 | + metadataBuilder.put(dataStream); |
| 800 | + return clusterStateBuilder.metadata(metadataBuilder).build(); |
| 801 | + } |
| 802 | + |
581 | 803 | private IndicesStatsResponse createIndicesStatResponse(String indexName, long totalDocs, long primariesDocs) { |
582 | 804 | final CommonStats primaryStats = mock(CommonStats.class); |
583 | 805 | when(primaryStats.getDocs()).thenReturn(new DocsStats(primariesDocs, 0, between(1, 10000))); |
|
0 commit comments