diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/support/SecurityIndexManagerTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/support/SecurityIndexManagerTests.java index 70986309c7c41..f256b8c7d9412 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/support/SecurityIndexManagerTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/support/SecurityIndexManagerTests.java @@ -125,6 +125,7 @@ public void testIndexWithUpToDateMappingAndTemplate() { assertThat(manager.indexExists(), Matchers.equalTo(true)); assertThat(manager.isAvailableForSearch(), Matchers.equalTo(true)); assertThat(manager.isAvailableForWrite(), Matchers.equalTo(true)); + assertThat(manager.isAvailableForRealTimeGet(), Matchers.equalTo(true)); assertThat(manager.isMappingUpToDate(), Matchers.equalTo(true)); } @@ -165,6 +166,99 @@ public void testIndexWithoutPrimaryShards() { assertIndexUpToDateButNotAvailable(); } + public void testIndexAvailability() { + assertInitialState(); + final ClusterState cs = createClusterState( + TestRestrictedIndices.INTERNAL_SECURITY_MAIN_INDEX_7, + SecuritySystemIndices.SECURITY_MAIN_ALIAS + ).build(); + Index index = cs.metadata().index(TestRestrictedIndices.INTERNAL_SECURITY_MAIN_INDEX_7).getIndex(); + ShardId shardId = new ShardId(index, 0); + ShardRouting primary = ShardRouting.newUnassigned( + shardId, + true, + RecoverySource.ExistingStoreRecoverySource.INSTANCE, + new UnassignedInfo(UnassignedInfo.Reason.INDEX_CREATED, ""), + ShardRouting.Role.INDEX_ONLY + ); + ShardRouting replica = ShardRouting.newUnassigned( + shardId, + false, + RecoverySource.PeerRecoverySource.INSTANCE, + new UnassignedInfo(UnassignedInfo.Reason.REPLICA_ADDED, null), + ShardRouting.Role.SEARCH_ONLY + ); + String nodeId = ESTestCase.randomAlphaOfLength(8); + String nodeId2 = ESTestCase.randomAlphaOfLength(8); + + // primary/index unavailable, replica/search unavailable + IndexShardRoutingTable.Builder indxShardRoutingTableBuilder = IndexShardRoutingTable.builder(shardId) + .addShard( + primary.initialize(nodeId, null, primary.getExpectedShardSize()) + .moveToUnassigned(new UnassignedInfo(UnassignedInfo.Reason.ALLOCATION_FAILED, "")) + ) + .addShard( + replica.initialize(nodeId2, null, replica.getExpectedShardSize()) + .moveToUnassigned(new UnassignedInfo(UnassignedInfo.Reason.ALLOCATION_FAILED, "")) + ); + IndexRoutingTable.Builder indexRoutingTableBuilder = IndexRoutingTable.builder(index).addIndexShard(indxShardRoutingTableBuilder); + RoutingTable routingTable = RoutingTable.builder().add(indexRoutingTableBuilder.build()).build(); + ClusterState.Builder clusterStateBuilder = ClusterState.builder(cs); + clusterStateBuilder.routingTable(routingTable); + ClusterState clusterState = clusterStateBuilder.build(); + manager.clusterChanged(event(clusterState)); + assertThat(manager.indexExists(), Matchers.equalTo(true)); + assertThat(manager.isAvailableForSearch(), Matchers.equalTo(false)); + assertThat(manager.isAvailableForWrite(), Matchers.equalTo(false)); + assertThat(manager.isAvailableForRealTimeGet(), Matchers.equalTo(false)); + assertThat(manager.isMappingUpToDate(), Matchers.equalTo(true)); + assertThat(manager.isStateRecovered(), Matchers.equalTo(true)); + + // primary/index available, replica/search available + indxShardRoutingTableBuilder = IndexShardRoutingTable.builder(shardId) + .addShard( + primary.initialize(nodeId, null, primary.getExpectedShardSize()).moveToStarted(ShardRouting.UNAVAILABLE_EXPECTED_SHARD_SIZE) + ) + .addShard( + replica.initialize(nodeId2, null, replica.getExpectedShardSize()) + .moveToStarted(ShardRouting.UNAVAILABLE_EXPECTED_SHARD_SIZE) // start replica + ); + indexRoutingTableBuilder = IndexRoutingTable.builder(index).addIndexShard(indxShardRoutingTableBuilder); + routingTable = RoutingTable.builder().add(indexRoutingTableBuilder.build()).build(); + clusterStateBuilder = ClusterState.builder(cs); + clusterStateBuilder.routingTable(routingTable); + clusterState = clusterStateBuilder.build(); + manager.clusterChanged(event(clusterState)); + assertThat(manager.indexExists(), Matchers.equalTo(true)); + assertThat(manager.isAvailableForSearch(), Matchers.equalTo(true)); + assertThat(manager.isAvailableForWrite(), Matchers.equalTo(true)); + assertThat(manager.isAvailableForRealTimeGet(), Matchers.equalTo(true)); + assertThat(manager.isMappingUpToDate(), Matchers.equalTo(true)); + assertThat(manager.isStateRecovered(), Matchers.equalTo(true)); + + // primary/index available, replica/search unavailable + indxShardRoutingTableBuilder = IndexShardRoutingTable.builder(shardId) + .addShard( + primary.initialize(nodeId, null, primary.getExpectedShardSize()).moveToStarted(ShardRouting.UNAVAILABLE_EXPECTED_SHARD_SIZE) + ) + .addShard(replica.initialize(nodeId2, null, replica.getExpectedShardSize())); // initialized, but not started + indexRoutingTableBuilder = IndexRoutingTable.builder(index).addIndexShard(indxShardRoutingTableBuilder); + routingTable = RoutingTable.builder().add(indexRoutingTableBuilder.build()).build(); + clusterStateBuilder = ClusterState.builder(cs); + clusterStateBuilder.routingTable(routingTable); + clusterState = clusterStateBuilder.build(); + manager.clusterChanged(event(clusterState)); + assertThat(manager.indexExists(), Matchers.equalTo(true)); + assertThat(manager.isAvailableForSearch(), Matchers.equalTo(false)); + assertThat(manager.isAvailableForWrite(), Matchers.equalTo(true)); + assertThat(manager.isAvailableForRealTimeGet(), Matchers.equalTo(true)); + assertThat(manager.isMappingUpToDate(), Matchers.equalTo(true)); + assertThat(manager.isStateRecovered(), Matchers.equalTo(true)); + + // primary/index unavailable, replica/search available + // it is not currently possibly to have unassigned primaries with assigned replicas + } + private ClusterChangedEvent event(ClusterState clusterState) { return new ClusterChangedEvent("test-event", clusterState, EMPTY_CLUSTER_STATE); } @@ -422,6 +516,7 @@ public void testProcessClosedIndexState() { assertThat(manager.indexExists(), is(true)); assertThat(manager.isAvailableForSearch(), is(true)); assertThat(manager.isAvailableForWrite(), is(true)); + assertThat(manager.isAvailableForRealTimeGet(), is(true)); // Now close it ClusterState.Builder indexClosed = createClusterState( @@ -440,12 +535,14 @@ public void testProcessClosedIndexState() { assertThat(manager.indexExists(), is(true)); assertThat(manager.isAvailableForSearch(), is(false)); assertThat(manager.isAvailableForWrite(), is(false)); + assertThat(manager.isAvailableForRealTimeGet(), is(false)); } private void assertInitialState() { assertThat(manager.indexExists(), Matchers.equalTo(false)); assertThat(manager.isAvailableForSearch(), Matchers.equalTo(false)); assertThat(manager.isAvailableForWrite(), Matchers.equalTo(false)); + assertThat(manager.isAvailableForRealTimeGet(), Matchers.equalTo(false)); assertThat(manager.isMappingUpToDate(), Matchers.equalTo(false)); assertThat(manager.isStateRecovered(), Matchers.equalTo(false)); } @@ -454,6 +551,7 @@ private void assertIndexUpToDateButNotAvailable() { assertThat(manager.indexExists(), Matchers.equalTo(true)); assertThat(manager.isAvailableForSearch(), Matchers.equalTo(false)); assertThat(manager.isAvailableForWrite(), Matchers.equalTo(false)); + assertThat(manager.isAvailableForRealTimeGet(), Matchers.equalTo(false)); assertThat(manager.isMappingUpToDate(), Matchers.equalTo(true)); assertThat(manager.isStateRecovered(), Matchers.equalTo(true)); }