diff --git a/server/src/main/java/org/elasticsearch/cluster/metadata/MetaDataIndexStateService.java b/server/src/main/java/org/elasticsearch/cluster/metadata/MetaDataIndexStateService.java index 0781cab1fe757..3e9143320c53c 100644 --- a/server/src/main/java/org/elasticsearch/cluster/metadata/MetaDataIndexStateService.java +++ b/server/src/main/java/org/elasticsearch/cluster/metadata/MetaDataIndexStateService.java @@ -410,14 +410,16 @@ static ClusterState closeRoutingTable(final ClusterState currentState, } logger.debug("closing index {} succeeded", index); - blocks.removeIndexBlockWithId(index.getName(), INDEX_CLOSED_BLOCK_ID).addIndexBlock(index.getName(), INDEX_CLOSED_BLOCK); metadata.put(IndexMetaData.builder(indexMetaData).state(IndexMetaData.State.CLOSE)); - routingTable.remove(index.getName()); + blocks.removeIndexBlockWithId(index.getName(), INDEX_CLOSED_BLOCK_ID); + blocks.addIndexBlock(index.getName(), INDEX_CLOSED_BLOCK); + routingTable.addAsFromOpenToClose(metadata.getSafe(index)); closedIndices.add(index.getName()); } catch (final IndexNotFoundException e) { logger.debug("index {} has been deleted since it was blocked before closing, ignoring", index); } } + logger.info("completed closing of indices {}", closedIndices); return ClusterState.builder(currentState).blocks(blocks).metaData(metadata).routingTable(routingTable.build()).build(); } diff --git a/server/src/main/java/org/elasticsearch/cluster/routing/IndexRoutingTable.java b/server/src/main/java/org/elasticsearch/cluster/routing/IndexRoutingTable.java index cf1235c8f2158..195ae2cce25b8 100644 --- a/server/src/main/java/org/elasticsearch/cluster/routing/IndexRoutingTable.java +++ b/server/src/main/java/org/elasticsearch/cluster/routing/IndexRoutingTable.java @@ -358,6 +358,13 @@ public Builder initializeAsFromCloseToOpen(IndexMetaData indexMetaData) { return initializeEmpty(indexMetaData, new UnassignedInfo(UnassignedInfo.Reason.INDEX_REOPENED, null)); } + /** + * Initializes a new empty index, as as a result of closing an opened index. + */ + public Builder initializeAsFromOpenToClose(IndexMetaData indexMetaData) { + return initializeEmpty(indexMetaData, new UnassignedInfo(UnassignedInfo.Reason.INDEX_CLOSED, null)); + } + /** * Initializes a new empty index, to be restored from a snapshot */ diff --git a/server/src/main/java/org/elasticsearch/cluster/routing/RoutingTable.java b/server/src/main/java/org/elasticsearch/cluster/routing/RoutingTable.java index 0d5ee132ffa9b..0c6080029895b 100644 --- a/server/src/main/java/org/elasticsearch/cluster/routing/RoutingTable.java +++ b/server/src/main/java/org/elasticsearch/cluster/routing/RoutingTable.java @@ -540,6 +540,13 @@ public Builder addAsFromCloseToOpen(IndexMetaData indexMetaData) { return this; } + public Builder addAsFromOpenToClose(IndexMetaData indexMetaData) { + assert indexMetaData.getState() == IndexMetaData.State.CLOSE; + IndexRoutingTable.Builder indexRoutingBuilder = new IndexRoutingTable.Builder(indexMetaData.getIndex()) + .initializeAsFromOpenToClose(indexMetaData); + return add(indexRoutingBuilder); + } + public Builder addAsRestore(IndexMetaData indexMetaData, SnapshotRecoverySource recoverySource) { IndexRoutingTable.Builder indexRoutingBuilder = new IndexRoutingTable.Builder(indexMetaData.getIndex()) .initializeAsRestore(indexMetaData, recoverySource); diff --git a/server/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java b/server/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java index f8afbeb449361..ec7b053764afc 100644 --- a/server/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java +++ b/server/src/main/java/org/elasticsearch/cluster/routing/UnassignedInfo.java @@ -118,7 +118,11 @@ public enum Reason { /** * Forced manually to allocate */ - MANUAL_ALLOCATION + MANUAL_ALLOCATION, + /** + * Unassigned as a result of closing an index. + */ + INDEX_CLOSED } /** @@ -269,6 +273,8 @@ public UnassignedInfo(StreamInput in) throws IOException { public void writeTo(StreamOutput out) throws IOException { if (out.getVersion().before(Version.V_6_0_0_beta2) && reason == Reason.MANUAL_ALLOCATION) { out.writeByte((byte) Reason.ALLOCATION_FAILED.ordinal()); + } else if (out.getVersion().before(Version.V_7_0_0) && reason == Reason.INDEX_CLOSED) { + out.writeByte((byte) Reason.REINITIALIZED.ordinal()); } else { out.writeByte((byte) reason.ordinal()); } diff --git a/server/src/main/java/org/elasticsearch/index/engine/NoOpEngine.java b/server/src/main/java/org/elasticsearch/index/engine/NoOpEngine.java index 8eec141975312..fe1ad7a1a144f 100644 --- a/server/src/main/java/org/elasticsearch/index/engine/NoOpEngine.java +++ b/server/src/main/java/org/elasticsearch/index/engine/NoOpEngine.java @@ -44,8 +44,7 @@ public NoOpEngine(EngineConfig config) { protected DirectoryReader open(final IndexCommit commit) throws IOException { final Directory directory = commit.getDirectory(); final List indexCommits = DirectoryReader.listCommits(directory); - assert indexCommits.size() == 1 : "expected only one commit point"; - IndexCommit indexCommit = indexCommits.get(indexCommits.size() - 1); + final IndexCommit indexCommit = indexCommits.get(indexCommits.size() - 1); return new DirectoryReader(directory, new LeafReader[0]) { @Override protected DirectoryReader doOpenIfChanged() throws IOException { diff --git a/server/src/main/java/org/elasticsearch/indices/cluster/IndicesClusterStateService.java b/server/src/main/java/org/elasticsearch/indices/cluster/IndicesClusterStateService.java index 57ec87d1c6493..c0fbd1272b973 100644 --- a/server/src/main/java/org/elasticsearch/indices/cluster/IndicesClusterStateService.java +++ b/server/src/main/java/org/elasticsearch/indices/cluster/IndicesClusterStateService.java @@ -98,6 +98,7 @@ import static org.elasticsearch.indices.cluster.IndicesClusterStateService.AllocatedIndices.IndexRemovalReason.DELETED; import static org.elasticsearch.indices.cluster.IndicesClusterStateService.AllocatedIndices.IndexRemovalReason.FAILURE; import static org.elasticsearch.indices.cluster.IndicesClusterStateService.AllocatedIndices.IndexRemovalReason.NO_LONGER_ASSIGNED; +import static org.elasticsearch.indices.cluster.IndicesClusterStateService.AllocatedIndices.IndexRemovalReason.REOPENED; public class IndicesClusterStateService extends AbstractLifecycleComponent implements ClusterStateApplier { private static final Logger logger = LogManager.getLogger(IndicesClusterStateService.class); @@ -240,7 +241,7 @@ public synchronized void applyClusterState(final ClusterChangedEvent event) { deleteIndices(event); // also deletes shards of deleted indices - removeUnallocatedIndices(event); // also removes shards of removed indices + removeIndices(event); // also removes shards of removed indices failMissingShards(state); @@ -352,17 +353,18 @@ protected void doRun() throws Exception { } /** - * Removes indices that have no shards allocated to this node. This does not delete the shard data as we wait for enough - * shard copies to exist in the cluster before deleting shard data (triggered by {@link org.elasticsearch.indices.store.IndicesStore}). + * Removes indices that have no shards allocated to this node or indices whose state has changed. This does not delete the shard data + * as we wait for enough shard copies to exist in the cluster before deleting shard data (triggered by + * {@link org.elasticsearch.indices.store.IndicesStore}). * * @param event the cluster changed event */ - private void removeUnallocatedIndices(final ClusterChangedEvent event) { + private void removeIndices(final ClusterChangedEvent event) { final ClusterState state = event.state(); final String localNodeId = state.nodes().getLocalNodeId(); assert localNodeId != null; - Set indicesWithShards = new HashSet<>(); + final Set indicesWithShards = new HashSet<>(); RoutingNode localRoutingNode = state.getRoutingNodes().node(localNodeId); if (localRoutingNode != null) { // null e.g. if we are not a data node for (ShardRouting shardRouting : localRoutingNode) { @@ -371,20 +373,27 @@ private void removeUnallocatedIndices(final ClusterChangedEvent event) { } for (AllocatedIndex indexService : indicesService) { - Index index = indexService.index(); - if (indicesWithShards.contains(index) == false) { + final Index index = indexService.index(); + final IndexMetaData indexMetaData = state.metaData().index(index); + final IndexMetaData existingMetaData = indexService.getIndexSettings().getIndexMetaData(); + + AllocatedIndices.IndexRemovalReason reason = null; + if (indexMetaData != null && indexMetaData.getState() != existingMetaData.getState()) { + reason = indexMetaData.getState() == IndexMetaData.State.CLOSE ? CLOSED : REOPENED; + } else if (indicesWithShards.contains(index) == false) { // if the cluster change indicates a brand new cluster, we only want // to remove the in-memory structures for the index and not delete the // contents on disk because the index will later be re-imported as a // dangling index - final IndexMetaData indexMetaData = state.metaData().index(index); assert indexMetaData != null || event.isNewCluster() : "index " + index + " does not exist in the cluster state, it should either " + "have been deleted or the cluster must be new"; - final AllocatedIndices.IndexRemovalReason reason = - indexMetaData != null && indexMetaData.getState() == IndexMetaData.State.CLOSE ? CLOSED : NO_LONGER_ASSIGNED; - logger.debug("{} removing index, [{}]", index, reason); - indicesService.removeIndex(index, reason, "removing index (no shards allocated)"); + reason = indexMetaData != null && indexMetaData.getState() == IndexMetaData.State.CLOSE ? CLOSED : NO_LONGER_ASSIGNED; + } + + if (reason != null) { + logger.debug("{} removing index ({})", index, reason); + indicesService.removeIndex(index, reason, "removing index (" + reason + ")"); } } } @@ -595,7 +604,7 @@ private void updateShard(DiscoveryNodes nodes, ShardRouting shardRouting, Shard ClusterState clusterState) { final ShardRouting currentRoutingEntry = shard.routingEntry(); assert currentRoutingEntry.isSameAllocation(shardRouting) : - "local shard has a different allocation id but wasn't cleaning by removeShards. " + "local shard has a different allocation id but wasn't cleaned by removeShards. " + "cluster state: " + shardRouting + " local: " + currentRoutingEntry; final long primaryTerm; @@ -730,7 +739,7 @@ private void failAndRemoveShard(ShardRouting shardRouting, boolean sendShardFail private void sendFailShard(ShardRouting shardRouting, String message, @Nullable Exception failure, ClusterState state) { try { logger.warn(() -> new ParameterizedMessage( - "[{}] marking and sending shard failed due to [{}]", shardRouting.shardId(), message), failure); + "{} marking and sending shard failed due to [{}]", shardRouting.shardId(), message), failure); failedShardsCache.put(shardRouting.shardId(), shardRouting); shardStateAction.localShardFailed(shardRouting, message, failure, SHARD_STATE_ACTION_LISTENER, state); } catch (Exception inner) { @@ -931,7 +940,7 @@ enum IndexRemovalReason { DELETED, /** - * The index have been closed. The index should be removed and all associated resources released. Persistent parts of the index + * The index has been closed. The index should be removed and all associated resources released. Persistent parts of the index * like the shards files, state and transaction logs are kept around in the case of a disaster recovery. */ CLOSED, @@ -941,7 +950,13 @@ enum IndexRemovalReason { * Persistent parts of the index like the shards files, state and transaction logs are kept around in the * case of a disaster recovery. */ - FAILURE + FAILURE, + + /** + * The index has been reopened. The index should be removed and all associated resources released. Persistent parts of the index + * like the shards files, state and transaction logs are kept around in the case of a disaster recovery. + */ + REOPENED, } } } diff --git a/server/src/main/java/org/elasticsearch/search/SearchService.java b/server/src/main/java/org/elasticsearch/search/SearchService.java index a14b4a328775c..b8bde4e4f5213 100644 --- a/server/src/main/java/org/elasticsearch/search/SearchService.java +++ b/server/src/main/java/org/elasticsearch/search/SearchService.java @@ -268,7 +268,7 @@ public void afterIndexRemoved(Index index, IndexSettings indexSettings, IndexRem // it's fine to keep the contexts open if the index is still "alive" // unfortunately we don't have a clear way to signal today why an index is closed. // to release memory and let references to the filesystem go etc. - if (reason == IndexRemovalReason.DELETED || reason == IndexRemovalReason.CLOSED) { + if (reason == IndexRemovalReason.DELETED || reason == IndexRemovalReason.CLOSED || reason == IndexRemovalReason.REOPENED) { freeAllContextForIndex(index); } diff --git a/server/src/test/java/org/elasticsearch/cluster/metadata/MetaDataIndexStateServiceTests.java b/server/src/test/java/org/elasticsearch/cluster/metadata/MetaDataIndexStateServiceTests.java index 56ee25ee5febb..4108c542d0cc5 100644 --- a/server/src/test/java/org/elasticsearch/cluster/metadata/MetaDataIndexStateServiceTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/metadata/MetaDataIndexStateServiceTests.java @@ -35,6 +35,7 @@ import org.elasticsearch.cluster.routing.RoutingTable; import org.elasticsearch.cluster.routing.ShardRouting; import org.elasticsearch.cluster.routing.ShardRoutingState; +import org.elasticsearch.cluster.routing.UnassignedInfo; import org.elasticsearch.cluster.shards.ClusterShardLimitIT; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.ValidationException; @@ -210,7 +211,14 @@ public void testAddIndexClosedBlocks() { for (Index index : indices) { assertTrue(blockedIndices.containsKey(index)); if (mixedVersions) { - assertIsClosed(index.getName(), updatedState); + assertThat(updatedState.metaData().index(index).getState(), is(IndexMetaData.State.CLOSE)); + assertTrue(updatedState.blocks().hasIndexBlock(index.getName(), MetaDataIndexStateService.INDEX_CLOSED_BLOCK)); + assertThat("Index " + index + " must have only 1 block with id=" + MetaDataIndexStateService.INDEX_CLOSED_BLOCK_ID, + updatedState.blocks().indices().getOrDefault(index.getName(), emptySet()).stream().filter(clusterBlock -> + clusterBlock.id() == MetaDataIndexStateService.INDEX_CLOSED_BLOCK_ID).count(), equalTo(1L)); + + final IndexRoutingTable indexRoutingTable = updatedState.routingTable().index(index); + assertThat(indexRoutingTable, nullValue()); } else { assertHasBlock(index.getName(), updatedState, blockedIndices.get(index)); } @@ -346,19 +354,18 @@ private static ClusterState addIndex(final ClusterState currentState, final ClusterState.Builder clusterStateBuilder = ClusterState.builder(currentState); clusterStateBuilder.metaData(MetaData.builder(currentState.metaData()).put(indexMetaData, true)); - if (state == IndexMetaData.State.OPEN) { - final IndexRoutingTable.Builder indexRoutingTable = IndexRoutingTable.builder(indexMetaData.getIndex()); - for (int j = 0; j < indexMetaData.getNumberOfShards(); j++) { - ShardId shardId = new ShardId(indexMetaData.getIndex(), j); - IndexShardRoutingTable.Builder indexShardRoutingBuilder = new IndexShardRoutingTable.Builder(shardId); - indexShardRoutingBuilder.addShard(newShardRouting(shardId, randomAlphaOfLength(10), true, ShardRoutingState.STARTED)); - for (int k = 0; k < indexMetaData.getNumberOfReplicas(); k++) { - indexShardRoutingBuilder.addShard(newShardRouting(shardId, randomAlphaOfLength(10), false, ShardRoutingState.STARTED)); - } - indexRoutingTable.addIndexShard(indexShardRoutingBuilder.build()); + final IndexRoutingTable.Builder indexRoutingTable = IndexRoutingTable.builder(indexMetaData.getIndex()); + for (int j = 0; j < indexMetaData.getNumberOfShards(); j++) { + ShardId shardId = new ShardId(indexMetaData.getIndex(), j); + IndexShardRoutingTable.Builder indexShardRoutingBuilder = new IndexShardRoutingTable.Builder(shardId); + indexShardRoutingBuilder.addShard(newShardRouting(shardId, randomAlphaOfLength(10), true, ShardRoutingState.STARTED)); + for (int k = 0; k < indexMetaData.getNumberOfReplicas(); k++) { + indexShardRoutingBuilder.addShard(newShardRouting(shardId, randomAlphaOfLength(10), false, ShardRoutingState.STARTED)); } - clusterStateBuilder.routingTable(RoutingTable.builder(currentState.routingTable()).add(indexRoutingTable).build()); + indexRoutingTable.addIndexShard(indexShardRoutingBuilder.build()); } + clusterStateBuilder.routingTable(RoutingTable.builder(currentState.routingTable()).add(indexRoutingTable).build()); + if (block != null) { clusterStateBuilder.blocks(ClusterBlocks.builder().blocks(currentState.blocks()).addIndexBlock(index, block)); } @@ -372,11 +379,19 @@ private static void assertIsOpened(final String indexName, final ClusterState cl private static void assertIsClosed(final String indexName, final ClusterState clusterState) { assertThat(clusterState.metaData().index(indexName).getState(), is(IndexMetaData.State.CLOSE)); - assertThat(clusterState.routingTable().index(indexName), nullValue()); assertThat(clusterState.blocks().hasIndexBlock(indexName, MetaDataIndexStateService.INDEX_CLOSED_BLOCK), is(true)); assertThat("Index " + indexName + " must have only 1 block with [id=" + MetaDataIndexStateService.INDEX_CLOSED_BLOCK_ID + "]", clusterState.blocks().indices().getOrDefault(indexName, emptySet()).stream() .filter(clusterBlock -> clusterBlock.id() == MetaDataIndexStateService.INDEX_CLOSED_BLOCK_ID).count(), equalTo(1L)); + + final IndexRoutingTable indexRoutingTable = clusterState.routingTable().index(indexName); + assertThat(indexRoutingTable, notNullValue()); + + for(IndexShardRoutingTable shardRoutingTable : indexRoutingTable) { + assertThat(shardRoutingTable.shards().stream().allMatch(ShardRouting::unassigned), is(true)); + assertThat(shardRoutingTable.shards().stream().map(ShardRouting::unassignedInfo).map(UnassignedInfo::getReason) + .allMatch(info -> info == UnassignedInfo.Reason.INDEX_CLOSED), is(true)); + } } private static void assertHasBlock(final String indexName, final ClusterState clusterState, final ClusterBlock closingBlock) { diff --git a/server/src/test/java/org/elasticsearch/cluster/routing/UnassignedInfoTests.java b/server/src/test/java/org/elasticsearch/cluster/routing/UnassignedInfoTests.java index 16cde1a990907..bc3191c14dfba 100644 --- a/server/src/test/java/org/elasticsearch/cluster/routing/UnassignedInfoTests.java +++ b/server/src/test/java/org/elasticsearch/cluster/routing/UnassignedInfoTests.java @@ -40,6 +40,7 @@ import org.elasticsearch.index.Index; import org.elasticsearch.snapshots.Snapshot; import org.elasticsearch.snapshots.SnapshotId; +import org.elasticsearch.test.VersionUtils; import java.io.IOException; import java.nio.ByteBuffer; @@ -54,6 +55,7 @@ import static org.hamcrest.Matchers.nullValue; public class UnassignedInfoTests extends ESAllocationTestCase { + public void testReasonOrdinalOrder() { UnassignedInfo.Reason[] order = new UnassignedInfo.Reason[]{ UnassignedInfo.Reason.INDEX_CREATED, @@ -70,7 +72,8 @@ public void testReasonOrdinalOrder() { UnassignedInfo.Reason.REALLOCATED_REPLICA, UnassignedInfo.Reason.PRIMARY_FAILED, UnassignedInfo.Reason.FORCED_EMPTY_PRIMARY, - UnassignedInfo.Reason.MANUAL_ALLOCATION,}; + UnassignedInfo.Reason.MANUAL_ALLOCATION, + UnassignedInfo.Reason.INDEX_CLOSED,}; for (int i = 0; i < order.length; i++) { assertThat(order[i].ordinal(), equalTo(i)); } @@ -95,6 +98,21 @@ public void testSerialization() throws Exception { assertThat(read.getNumFailedAllocations(), equalTo(meta.getNumFailedAllocations())); } + public void testBwcSerialization() throws Exception { + final UnassignedInfo unassignedInfo = new UnassignedInfo(UnassignedInfo.Reason.INDEX_CLOSED, "message"); + BytesStreamOutput out = new BytesStreamOutput(); + out.setVersion(VersionUtils.randomVersionBetween(random(), Version.V_6_0_0, VersionUtils.getPreviousVersion(Version.V_7_0_0))); + unassignedInfo.writeTo(out); + out.close(); + + UnassignedInfo read = new UnassignedInfo(out.bytes().streamInput()); + assertThat(read.getReason(), equalTo(UnassignedInfo.Reason.REINITIALIZED)); + assertThat(read.getUnassignedTimeInMillis(), equalTo(unassignedInfo.getUnassignedTimeInMillis())); + assertThat(read.getMessage(), equalTo(unassignedInfo.getMessage())); + assertThat(read.getDetails(), equalTo(unassignedInfo.getDetails())); + assertThat(read.getNumFailedAllocations(), equalTo(unassignedInfo.getNumFailedAllocations())); + } + public void testIndexCreated() { MetaData metaData = MetaData.builder() .put(IndexMetaData.builder("test").settings(settings(Version.CURRENT)) diff --git a/server/src/test/java/org/elasticsearch/gateway/GatewayIndexStateIT.java b/server/src/test/java/org/elasticsearch/gateway/GatewayIndexStateIT.java index ebdae985a39c7..541a24247473a 100644 --- a/server/src/test/java/org/elasticsearch/gateway/GatewayIndexStateIT.java +++ b/server/src/test/java/org/elasticsearch/gateway/GatewayIndexStateIT.java @@ -54,9 +54,11 @@ import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE; import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; @ClusterScope(scope = Scope.TEST, numDataNodes = 0) @@ -113,11 +115,11 @@ public void testSimpleOpenClose() throws Exception { client().prepareIndex("test", "type1", "1").setSource("field1", "value1").get(); logger.info("--> closing test index..."); - client().admin().indices().prepareClose("test").get(); + assertAcked(client().admin().indices().prepareClose("test")); stateResponse = client().admin().cluster().prepareState().execute().actionGet(); assertThat(stateResponse.getState().metaData().index("test").getState(), equalTo(IndexMetaData.State.CLOSE)); - assertThat(stateResponse.getState().routingTable().index("test"), nullValue()); + assertThat(stateResponse.getState().routingTable().index("test"), notNullValue()); logger.info("--> verifying that the state is green"); ensureGreen(); @@ -136,7 +138,7 @@ public void testSimpleOpenClose() throws Exception { ensureGreen(); logger.info("--> opening the first index again..."); - client().admin().indices().prepareOpen("test").execute().actionGet(); + assertAcked(client().admin().indices().prepareOpen("test")); logger.info("--> verifying that the state is green"); ensureGreen(); @@ -152,10 +154,10 @@ public void testSimpleOpenClose() throws Exception { assertThat(getResponse.isExists(), equalTo(true)); logger.info("--> closing test index..."); - client().admin().indices().prepareClose("test").execute().actionGet(); + assertAcked(client().admin().indices().prepareClose("test")); stateResponse = client().admin().cluster().prepareState().execute().actionGet(); assertThat(stateResponse.getState().metaData().index("test").getState(), equalTo(IndexMetaData.State.CLOSE)); - assertThat(stateResponse.getState().routingTable().index("test"), nullValue()); + assertThat(stateResponse.getState().routingTable().index("test"), notNullValue()); logger.info("--> restarting nodes..."); internalCluster().fullRestart(); @@ -252,11 +254,11 @@ public void testTwoNodesSingleDoc() throws Exception { } logger.info("--> closing test index..."); - client().admin().indices().prepareClose("test").execute().actionGet(); + assertAcked(client().admin().indices().prepareClose("test")); ClusterStateResponse stateResponse = client().admin().cluster().prepareState().execute().actionGet(); assertThat(stateResponse.getState().metaData().index("test").getState(), equalTo(IndexMetaData.State.CLOSE)); - assertThat(stateResponse.getState().routingTable().index("test"), nullValue()); + assertThat(stateResponse.getState().routingTable().index("test"), notNullValue()); logger.info("--> opening the index..."); client().admin().indices().prepareOpen("test").execute().actionGet(); diff --git a/server/src/test/java/org/elasticsearch/index/shard/IndexShardIT.java b/server/src/test/java/org/elasticsearch/index/shard/IndexShardIT.java index 250af071cf6fe..71b5da28274aa 100644 --- a/server/src/test/java/org/elasticsearch/index/shard/IndexShardIT.java +++ b/server/src/test/java/org/elasticsearch/index/shard/IndexShardIT.java @@ -276,6 +276,8 @@ public void testExpectedShardSizeIsPresent() throws InterruptedException { assertTrue(test > 0); } + // NORELEASE This test need to be adapted for replicated closed indices + @AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/33888") public void testIndexCanChangeCustomDataPath() throws Exception { Environment env = getInstanceFromNode(Environment.class); Path idxPath = env.sharedDataFile().resolve(randomAlphaOfLength(10)); @@ -922,27 +924,17 @@ public void testNoOpEngineFactoryTakesPrecedence() throws IOException { createIndex(indexName, Settings.builder().put("index.number_of_shards", 1).put("index.number_of_replicas", 0).build()); ensureGreen(); - client().admin().indices().prepareClose(indexName).get(); + assertAcked(client().admin().indices().prepareClose(indexName)); final ClusterService clusterService = getInstanceFromNode(ClusterService.class); final ClusterState clusterState = clusterService.state(); - IndexMetaData indexMetaData = clusterState.metaData().index(indexName); + final IndexMetaData indexMetaData = clusterState.metaData().index(indexName); final IndicesService indicesService = getInstanceFromNode(IndicesService.class); - - final ShardId shardId = new ShardId(indexMetaData.getIndex(), 0); - final DiscoveryNode node = clusterService.localNode(); - final ShardRouting routing = - newShardRouting(shardId, node.getId(), true, ShardRoutingState.INITIALIZING, RecoverySource.EmptyStoreRecoverySource.INSTANCE); - final IndexService indexService = indicesService.createIndex(indexMetaData, Collections.emptyList()); - try { - final IndexShard indexShard = indexService.createShard(routing, id -> {}, (s, leases, listener) -> {}); - indexShard.markAsRecovering("store", new RecoveryState(indexShard.routingEntry(), node, null)); - indexShard.recoverFromStore(); + + for (IndexShard indexShard : indexService) { assertThat(indexShard.getEngine(), instanceOf(NoOpEngine.class)); - } finally { - indexService.close("test terminated", true); } } } diff --git a/server/src/test/java/org/elasticsearch/indices/IndicesServiceTests.java b/server/src/test/java/org/elasticsearch/indices/IndicesServiceTests.java index 1aa042edacd67..8ee47f50a7417 100644 --- a/server/src/test/java/org/elasticsearch/indices/IndicesServiceTests.java +++ b/server/src/test/java/org/elasticsearch/indices/IndicesServiceTests.java @@ -271,6 +271,8 @@ public void testDeleteIndexStore() throws Exception { ensureGreen("test"); } + // NORELEASE This test need to be adapted for replicated closed indices + @AwaitsFix(bugUrl = "https://github.com/elastic/elasticsearch/issues/33888") public void testPendingTasks() throws Exception { IndicesService indicesService = getIndicesService(); IndexService test = createIndex("test"); diff --git a/server/src/test/java/org/elasticsearch/indices/state/CloseIndexIT.java b/server/src/test/java/org/elasticsearch/indices/state/CloseIndexIT.java index 1d32283c6cb94..ca3f6e694097d 100644 --- a/server/src/test/java/org/elasticsearch/indices/state/CloseIndexIT.java +++ b/server/src/test/java/org/elasticsearch/indices/state/CloseIndexIT.java @@ -49,7 +49,6 @@ import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.nullValue; public class CloseIndexIT extends ESIntegTestCase { @@ -310,7 +309,7 @@ static void assertIndexIsClosed(final String... indices) { final ClusterState clusterState = client().admin().cluster().prepareState().get().getState(); for (String index : indices) { assertThat(clusterState.metaData().indices().get(index).getState(), is(IndexMetaData.State.CLOSE)); - assertThat(clusterState.routingTable().index(index), nullValue()); + assertThat(clusterState.routingTable().index(index), notNullValue()); assertThat(clusterState.blocks().hasIndexBlock(index, MetaDataIndexStateService.INDEX_CLOSED_BLOCK), is(true)); assertThat("Index " + index + " must have only 1 block with [id=" + MetaDataIndexStateService.INDEX_CLOSED_BLOCK_ID + "]", clusterState.blocks().indices().getOrDefault(index, emptySet()).stream() diff --git a/server/src/test/java/org/elasticsearch/indices/state/SimpleIndexStateIT.java b/server/src/test/java/org/elasticsearch/indices/state/SimpleIndexStateIT.java index 1cc2d3e68e2ae..050d77a223101 100644 --- a/server/src/test/java/org/elasticsearch/indices/state/SimpleIndexStateIT.java +++ b/server/src/test/java/org/elasticsearch/indices/state/SimpleIndexStateIT.java @@ -36,7 +36,7 @@ import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.Matchers.notNullValue; @ESIntegTestCase.ClusterScope(minNumDataNodes = 2) public class SimpleIndexStateIT extends ESIntegTestCase { @@ -65,7 +65,7 @@ public void testSimpleOpenClose() { stateResponse = client().admin().cluster().prepareState().get(); assertThat(stateResponse.getState().metaData().index("test").getState(), equalTo(IndexMetaData.State.CLOSE)); - assertThat(stateResponse.getState().routingTable().index("test"), nullValue()); + assertThat(stateResponse.getState().routingTable().index("test"), notNullValue()); logger.info("--> trying to index into a closed index ..."); try { diff --git a/server/src/test/java/org/elasticsearch/search/scroll/SearchScrollIT.java b/server/src/test/java/org/elasticsearch/search/scroll/SearchScrollIT.java index 9fb05af2040b3..e0ae78dff3466 100644 --- a/server/src/test/java/org/elasticsearch/search/scroll/SearchScrollIT.java +++ b/server/src/test/java/org/elasticsearch/search/scroll/SearchScrollIT.java @@ -521,11 +521,10 @@ public void testStringSortMissingAscTerminates() throws Exception { assertThat(response.getHits().getHits().length, equalTo(0)); } - public void testCloseAndReopenOrDeleteWithActiveScroll() throws IOException { + public void testCloseAndReopenOrDeleteWithActiveScroll() { createIndex("test"); for (int i = 0; i < 100; i++) { - client().prepareIndex("test", "type1", Integer.toString(i)).setSource(jsonBuilder().startObject().field("field", i).endObject()) - .get(); + client().prepareIndex("test", "type1", Integer.toString(i)).setSource("field", i).get(); } refresh(); SearchResponse searchResponse = client().prepareSearch() @@ -541,11 +540,11 @@ public void testCloseAndReopenOrDeleteWithActiveScroll() throws IOException { assertThat(((Number) hit.getSortValues()[0]).longValue(), equalTo(counter++)); } if (randomBoolean()) { - client().admin().indices().prepareClose("test").get(); - client().admin().indices().prepareOpen("test").get(); + assertAcked(client().admin().indices().prepareClose("test")); + assertAcked(client().admin().indices().prepareOpen("test")); ensureGreen("test"); } else { - client().admin().indices().prepareDelete("test").get(); + assertAcked(client().admin().indices().prepareDelete("test")); } } diff --git a/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java b/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java index 78892516c4ade..68def650b6d4b 100644 --- a/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java +++ b/server/src/test/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java @@ -1550,7 +1550,7 @@ public void testSnapshotClosedIndex() throws Exception { assertAcked(client.admin().indices().prepareClose("test-idx-closed")); ClusterStateResponse stateResponse = client.admin().cluster().prepareState().get(); assertThat(stateResponse.getState().metaData().index("test-idx-closed").getState(), equalTo(IndexMetaData.State.CLOSE)); - assertThat(stateResponse.getState().routingTable().index("test-idx-closed"), nullValue()); + assertThat(stateResponse.getState().routingTable().index("test-idx-closed"), notNullValue()); logger.info("--> snapshot"); CreateSnapshotResponse createSnapshotResponse = client.admin().cluster().prepareCreateSnapshot("test-repo", "test-snap") @@ -3749,7 +3749,7 @@ public void testRestoreIncreasesPrimaryTerms() { final IndexMetaData restoredIndexMetaData = client().admin().cluster().prepareState().clear().setIndices(indexName) .setMetaData(true).get().getState().metaData().index(indexName); for (int shardId = 0; shardId < numPrimaries; shardId++) { - assertThat(restoredIndexMetaData.primaryTerm(shardId), equalTo(primaryTerms.get(shardId) + 1)); + assertThat(restoredIndexMetaData.primaryTerm(shardId), greaterThan(primaryTerms.get(shardId))); } }