Search in sources :

Example 6 with PlainActionFuture

use of org.elasticsearch.action.support.PlainActionFuture in project elasticsearch by elastic.

the class TransportReplicationActionTests method testBlocks.

public void testBlocks() throws ExecutionException, InterruptedException {
    Request request = new Request();
    PlainActionFuture<TestResponse> listener = new PlainActionFuture<>();
    ReplicationTask task = maybeTask();
    TestAction action = new TestAction(Settings.EMPTY, "testActionWithBlocks", transportService, clusterService, shardStateAction, threadPool) {

        @Override
        protected ClusterBlockLevel globalBlockLevel() {
            return ClusterBlockLevel.WRITE;
        }
    };
    ClusterBlocks.Builder block = ClusterBlocks.builder().addGlobalBlock(new ClusterBlock(1, "non retryable", false, true, RestStatus.SERVICE_UNAVAILABLE, ClusterBlockLevel.ALL));
    setState(clusterService, ClusterState.builder(clusterService.state()).blocks(block));
    TestAction.ReroutePhase reroutePhase = action.new ReroutePhase(task, request, listener);
    reroutePhase.run();
    assertListenerThrows("primary phase should fail operation", listener, ClusterBlockException.class);
    assertPhase(task, "failed");
    block = ClusterBlocks.builder().addGlobalBlock(new ClusterBlock(1, "retryable", true, true, RestStatus.SERVICE_UNAVAILABLE, ClusterBlockLevel.ALL));
    setState(clusterService, ClusterState.builder(clusterService.state()).blocks(block));
    listener = new PlainActionFuture<>();
    reroutePhase = action.new ReroutePhase(task, new Request().timeout("5ms"), listener);
    reroutePhase.run();
    assertListenerThrows("failed to timeout on retryable block", listener, ClusterBlockException.class);
    assertPhase(task, "failed");
    assertFalse(request.isRetrySet.get());
    listener = new PlainActionFuture<>();
    reroutePhase = action.new ReroutePhase(task, request = new Request(), listener);
    reroutePhase.run();
    assertFalse("primary phase should wait on retryable block", listener.isDone());
    assertPhase(task, "waiting_for_retry");
    assertTrue(request.isRetrySet.get());
    block = ClusterBlocks.builder().addGlobalBlock(new ClusterBlock(1, "non retryable", false, true, RestStatus.SERVICE_UNAVAILABLE, ClusterBlockLevel.ALL));
    setState(clusterService, ClusterState.builder(clusterService.state()).blocks(block));
    assertListenerThrows("primary phase should fail operation when moving from a retryable block to a non-retryable one", listener, ClusterBlockException.class);
    assertIndexShardUninitialized();
    action = new TestAction(Settings.EMPTY, "testActionWithNoBlocks", transportService, clusterService, shardStateAction, threadPool) {

        @Override
        protected ClusterBlockLevel globalBlockLevel() {
            return null;
        }
    };
    listener = new PlainActionFuture<>();
    reroutePhase = action.new ReroutePhase(task, new Request().timeout("5ms"), listener);
    reroutePhase.run();
    assertListenerThrows("should fail with an IndexNotFoundException when no blocks checked", listener, IndexNotFoundException.class);
}
Also used : ClusterBlocks(org.elasticsearch.cluster.block.ClusterBlocks) TransportRequest(org.elasticsearch.transport.TransportRequest) CloseIndexRequest(org.elasticsearch.action.admin.indices.close.CloseIndexRequest) ClusterBlock(org.elasticsearch.cluster.block.ClusterBlock) ClusterBlockLevel(org.elasticsearch.cluster.block.ClusterBlockLevel) PlainActionFuture(org.elasticsearch.action.support.PlainActionFuture)

Example 7 with PlainActionFuture

use of org.elasticsearch.action.support.PlainActionFuture in project elasticsearch by elastic.

the class TransportReplicationActionTests method testUnknownIndexOrShardOnReroute.

public void testUnknownIndexOrShardOnReroute() throws InterruptedException {
    final String index = "test";
    // no replicas in oder to skip the replication part
    setState(clusterService, state(index, true, randomBoolean() ? ShardRoutingState.INITIALIZING : ShardRoutingState.UNASSIGNED));
    logger.debug("--> using initial state:\n{}", clusterService.state());
    Request request = new Request(new ShardId("unknown_index", "_na_", 0)).timeout("1ms");
    PlainActionFuture<TestResponse> listener = new PlainActionFuture<>();
    ReplicationTask task = maybeTask();
    TestAction.ReroutePhase reroutePhase = action.new ReroutePhase(task, request, listener);
    reroutePhase.run();
    assertListenerThrows("must throw index not found exception", listener, IndexNotFoundException.class);
    assertPhase(task, "failed");
    assertTrue(request.isRetrySet.get());
    request = new Request(new ShardId(index, "_na_", 10)).timeout("1ms");
    listener = new PlainActionFuture<>();
    reroutePhase = action.new ReroutePhase(null, request, listener);
    reroutePhase.run();
    assertListenerThrows("must throw shard not found exception", listener, ShardNotFoundException.class);
    //TODO I'd have expected this to be true but we fail too early?
    assertFalse(request.isRetrySet.get());
}
Also used : ShardId(org.elasticsearch.index.shard.ShardId) PlainActionFuture(org.elasticsearch.action.support.PlainActionFuture) TransportRequest(org.elasticsearch.transport.TransportRequest) CloseIndexRequest(org.elasticsearch.action.admin.indices.close.CloseIndexRequest) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) Matchers.anyString(org.mockito.Matchers.anyString)

Example 8 with PlainActionFuture

use of org.elasticsearch.action.support.PlainActionFuture in project elasticsearch by elastic.

the class ReplicationOperationTests method testWaitForActiveShards.

public void testWaitForActiveShards() throws Exception {
    final String index = "test";
    final ShardId shardId = new ShardId(index, "_na_", 0);
    final int assignedReplicas = randomInt(2);
    final int unassignedReplicas = randomInt(2);
    final int totalShards = 1 + assignedReplicas + unassignedReplicas;
    final int activeShardCount = randomIntBetween(0, totalShards);
    Request request = new Request(shardId).waitForActiveShards(activeShardCount == totalShards ? ActiveShardCount.ALL : ActiveShardCount.from(activeShardCount));
    final boolean passesActiveShardCheck = activeShardCount <= assignedReplicas + 1;
    ShardRoutingState[] replicaStates = new ShardRoutingState[assignedReplicas + unassignedReplicas];
    for (int i = 0; i < assignedReplicas; i++) {
        replicaStates[i] = randomFrom(ShardRoutingState.STARTED, ShardRoutingState.RELOCATING);
    }
    for (int i = assignedReplicas; i < replicaStates.length; i++) {
        replicaStates[i] = ShardRoutingState.UNASSIGNED;
    }
    final ClusterState state = state(index, true, ShardRoutingState.STARTED, replicaStates);
    logger.debug("using active shard count of [{}], assigned shards [{}], total shards [{}]." + " expecting op to [{}]. using state: \n{}", request.waitForActiveShards(), 1 + assignedReplicas, 1 + assignedReplicas + unassignedReplicas, passesActiveShardCheck ? "succeed" : "retry", state);
    final long primaryTerm = state.metaData().index(index).primaryTerm(shardId.id());
    final IndexShardRoutingTable shardRoutingTable = state.routingTable().index(index).shard(shardId.id());
    PlainActionFuture<TestPrimary.Result> listener = new PlainActionFuture<>();
    final ShardRouting primaryShard = shardRoutingTable.primaryShard();
    final TestReplicationOperation op = new TestReplicationOperation(request, new TestPrimary(primaryShard, primaryTerm), listener, randomBoolean(), new TestReplicaProxy(), () -> state, logger, "test");
    if (passesActiveShardCheck) {
        assertThat(op.checkActiveShardCount(), nullValue());
        op.execute();
        assertTrue("operations should have been performed, active shard count is met", request.processedOnPrimary.get());
    } else {
        assertThat(op.checkActiveShardCount(), notNullValue());
        op.execute();
        assertFalse("operations should not have been perform, active shard count is *NOT* met", request.processedOnPrimary.get());
        assertListenerThrows("should throw exception to trigger retry", listener, UnavailableShardsException.class);
    }
}
Also used : ClusterState(org.elasticsearch.cluster.ClusterState) IndexShardRoutingTable(org.elasticsearch.cluster.routing.IndexShardRoutingTable) ShardRoutingState(org.elasticsearch.cluster.routing.ShardRoutingState) ShardId(org.elasticsearch.index.shard.ShardId) PlainActionFuture(org.elasticsearch.action.support.PlainActionFuture) ShardRouting(org.elasticsearch.cluster.routing.ShardRouting)

Example 9 with PlainActionFuture

use of org.elasticsearch.action.support.PlainActionFuture in project elasticsearch by elastic.

the class ReplicationOperationTests method testReplication.

public void testReplication() throws Exception {
    final String index = "test";
    final ShardId shardId = new ShardId(index, "_na_", 0);
    ClusterState state = stateWithActivePrimary(index, true, randomInt(5));
    IndexMetaData indexMetaData = state.getMetaData().index(index);
    final long primaryTerm = indexMetaData.primaryTerm(0);
    final IndexShardRoutingTable indexShardRoutingTable = state.getRoutingTable().shardRoutingTable(shardId);
    ShardRouting primaryShard = indexShardRoutingTable.primaryShard();
    if (primaryShard.relocating() && randomBoolean()) {
        // simulate execution of the replication phase on the relocation target node after relocation source was marked as relocated
        state = ClusterState.builder(state).nodes(DiscoveryNodes.builder(state.nodes()).localNodeId(primaryShard.relocatingNodeId())).build();
        primaryShard = primaryShard.getTargetRelocatingShard();
    }
    // add a few in-sync allocation ids that don't have corresponding routing entries
    Set<String> staleAllocationIds = Sets.newHashSet(generateRandomStringArray(4, 10, false));
    state = ClusterState.builder(state).metaData(MetaData.builder(state.metaData()).put(IndexMetaData.builder(indexMetaData).putInSyncAllocationIds(0, Sets.union(indexMetaData.inSyncAllocationIds(0), staleAllocationIds)))).build();
    final Set<ShardRouting> expectedReplicas = getExpectedReplicas(shardId, state);
    final Map<ShardRouting, Exception> expectedFailures = new HashMap<>();
    final Set<ShardRouting> expectedFailedShards = new HashSet<>();
    for (ShardRouting replica : expectedReplicas) {
        if (randomBoolean()) {
            Exception t;
            boolean criticalFailure = randomBoolean();
            if (criticalFailure) {
                t = new CorruptIndexException("simulated", (String) null);
            } else {
                t = new IndexShardNotStartedException(shardId, IndexShardState.RECOVERING);
            }
            logger.debug("--> simulating failure on {} with [{}]", replica, t.getClass().getSimpleName());
            expectedFailures.put(replica, t);
            if (criticalFailure) {
                expectedFailedShards.add(replica);
            }
        }
    }
    Request request = new Request(shardId);
    PlainActionFuture<TestPrimary.Result> listener = new PlainActionFuture<>();
    final ClusterState finalState = state;
    final TestReplicaProxy replicasProxy = new TestReplicaProxy(expectedFailures);
    final TestPrimary primary = new TestPrimary(primaryShard, primaryTerm);
    final TestReplicationOperation op = new TestReplicationOperation(request, primary, listener, replicasProxy, () -> finalState);
    op.execute();
    assertThat(request.primaryTerm(), equalTo(primaryTerm));
    assertThat("request was not processed on primary", request.processedOnPrimary.get(), equalTo(true));
    assertThat(request.processedOnReplicas, equalTo(expectedReplicas));
    assertThat(replicasProxy.failedReplicas, equalTo(expectedFailedShards));
    assertThat(replicasProxy.markedAsStaleCopies, equalTo(staleAllocationIds));
    assertTrue("listener is not marked as done", listener.isDone());
    ShardInfo shardInfo = listener.actionGet().getShardInfo();
    assertThat(shardInfo.getFailed(), equalTo(expectedFailedShards.size()));
    assertThat(shardInfo.getFailures(), arrayWithSize(expectedFailedShards.size()));
    assertThat(shardInfo.getSuccessful(), equalTo(1 + expectedReplicas.size() - expectedFailures.size()));
    final List<ShardRouting> unassignedShards = indexShardRoutingTable.shardsWithState(ShardRoutingState.UNASSIGNED);
    final int totalShards = 1 + expectedReplicas.size() + unassignedShards.size();
    assertThat(shardInfo.getTotal(), equalTo(totalShards));
    assertThat(primary.knownLocalCheckpoints.remove(primaryShard.allocationId().getId()), equalTo(primary.localCheckpoint));
    assertThat(primary.knownLocalCheckpoints, equalTo(replicasProxy.generatedLocalCheckpoints));
}
Also used : IndexShardRoutingTable(org.elasticsearch.cluster.routing.IndexShardRoutingTable) HashMap(java.util.HashMap) ShardId(org.elasticsearch.index.shard.ShardId) HashSet(java.util.HashSet) ShardInfo(org.elasticsearch.action.support.replication.ReplicationResponse.ShardInfo) ClusterState(org.elasticsearch.cluster.ClusterState) IndexShardNotStartedException(org.elasticsearch.index.shard.IndexShardNotStartedException) CorruptIndexException(org.apache.lucene.index.CorruptIndexException) ElasticsearchException(org.elasticsearch.ElasticsearchException) CorruptIndexException(org.apache.lucene.index.CorruptIndexException) IndexShardNotStartedException(org.elasticsearch.index.shard.IndexShardNotStartedException) UnavailableShardsException(org.elasticsearch.action.UnavailableShardsException) ExecutionException(java.util.concurrent.ExecutionException) IndexMetaData(org.elasticsearch.cluster.metadata.IndexMetaData) PlainActionFuture(org.elasticsearch.action.support.PlainActionFuture) ShardRouting(org.elasticsearch.cluster.routing.ShardRouting)

Example 10 with PlainActionFuture

use of org.elasticsearch.action.support.PlainActionFuture in project elasticsearch by elastic.

the class ReplicationOperationTests method testClusterStateChangeAfterPrimaryOperation.

private void testClusterStateChangeAfterPrimaryOperation(final ShardId shardId, final ClusterState initialState, final ClusterState changedState) throws Exception {
    AtomicReference<ClusterState> state = new AtomicReference<>(initialState);
    logger.debug("--> using initial state:\n{}", state.get());
    final long primaryTerm = initialState.getMetaData().index(shardId.getIndexName()).primaryTerm(shardId.id());
    final ShardRouting primaryShard = state.get().routingTable().shardRoutingTable(shardId).primaryShard();
    final TestPrimary primary = new TestPrimary(primaryShard, primaryTerm) {

        @Override
        public Result perform(Request request) throws Exception {
            Result result = super.perform(request);
            state.set(changedState);
            logger.debug("--> state after primary operation:\n{}", state.get());
            return result;
        }
    };
    Request request = new Request(shardId);
    PlainActionFuture<TestPrimary.Result> listener = new PlainActionFuture<>();
    final TestReplicationOperation op = new TestReplicationOperation(request, primary, listener, new TestReplicaProxy(), state::get);
    op.execute();
    assertThat("request was not processed on primary", request.processedOnPrimary.get(), equalTo(true));
    Set<ShardRouting> expectedReplicas = getExpectedReplicas(shardId, state.get());
    assertThat(request.processedOnReplicas, equalTo(expectedReplicas));
}
Also used : ClusterState(org.elasticsearch.cluster.ClusterState) AtomicReference(java.util.concurrent.atomic.AtomicReference) PlainActionFuture(org.elasticsearch.action.support.PlainActionFuture) ClusterStateCreationUtils.state(org.elasticsearch.action.support.replication.ClusterStateCreationUtils.state) ShardRouting(org.elasticsearch.cluster.routing.ShardRouting)

Aggregations

PlainActionFuture (org.elasticsearch.action.support.PlainActionFuture)82 ShardId (org.elasticsearch.index.shard.ShardId)37 ClusterState (org.elasticsearch.cluster.ClusterState)28 ExecutionException (java.util.concurrent.ExecutionException)27 ShardRouting (org.elasticsearch.cluster.routing.ShardRouting)25 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)21 IOException (java.io.IOException)20 ArrayList (java.util.ArrayList)20 Test (org.junit.Test)20 IndexShardRoutingTable (org.elasticsearch.cluster.routing.IndexShardRoutingTable)18 ElasticsearchException (org.elasticsearch.ElasticsearchException)17 TransportRequest (org.elasticsearch.transport.TransportRequest)17 Matchers.anyString (org.mockito.Matchers.anyString)17 HashSet (java.util.HashSet)16 List (java.util.List)16 CloseIndexRequest (org.elasticsearch.action.admin.indices.close.CloseIndexRequest)16 IndexShard (org.elasticsearch.index.shard.IndexShard)16 CoreMatchers.containsString (org.hamcrest.CoreMatchers.containsString)16 DiscoveryNode (org.elasticsearch.cluster.node.DiscoveryNode)15 ClusterBlockException (org.elasticsearch.cluster.block.ClusterBlockException)13