Search in sources :

Example 11 with ShardRouting

use of org.elasticsearch.cluster.routing.ShardRouting 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)

Example 12 with ShardRouting

use of org.elasticsearch.cluster.routing.ShardRouting in project elasticsearch by elastic.

the class ReplicationOperationTests method testDemotedPrimary.

public void testDemotedPrimary() throws Exception {
    final String index = "test";
    final ShardId shardId = new ShardId(index, "_na_", 0);
    ClusterState state = stateWithActivePrimary(index, true, 1 + randomInt(2), randomInt(2));
    IndexMetaData indexMetaData = state.getMetaData().index(index);
    final long primaryTerm = indexMetaData.primaryTerm(0);
    ShardRouting primaryShard = state.getRoutingTable().shardRoutingTable(shardId).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 in-sync allocation id that doesn't have a corresponding routing entry
    state = ClusterState.builder(state).metaData(MetaData.builder(state.metaData()).put(IndexMetaData.builder(indexMetaData).putInSyncAllocationIds(0, Sets.union(indexMetaData.inSyncAllocationIds(0), Sets.newHashSet(randomAsciiOfLength(10)))))).build();
    final Set<ShardRouting> expectedReplicas = getExpectedReplicas(shardId, state);
    final Map<ShardRouting, Exception> expectedFailures = new HashMap<>();
    final ShardRouting failedReplica = randomFrom(new ArrayList<>(expectedReplicas));
    expectedFailures.put(failedReplica, new CorruptIndexException("simulated", (String) null));
    Request request = new Request(shardId);
    PlainActionFuture<TestPrimary.Result> listener = new PlainActionFuture<>();
    final ClusterState finalState = state;
    final boolean testPrimaryDemotedOnStaleShardCopies = randomBoolean();
    final TestReplicaProxy replicasProxy = new TestReplicaProxy(expectedFailures) {

        @Override
        public void failShardIfNeeded(ShardRouting replica, long primaryTerm, String message, Exception exception, Runnable onSuccess, Consumer<Exception> onPrimaryDemoted, Consumer<Exception> onIgnoredFailure) {
            if (testPrimaryDemotedOnStaleShardCopies) {
                super.failShardIfNeeded(replica, primaryTerm, message, exception, onSuccess, onPrimaryDemoted, onIgnoredFailure);
            } else {
                assertThat(replica, equalTo(failedReplica));
                onPrimaryDemoted.accept(new ElasticsearchException("the king is dead"));
            }
        }

        @Override
        public void markShardCopyAsStaleIfNeeded(ShardId shardId, String allocationId, long primaryTerm, Runnable onSuccess, Consumer<Exception> onPrimaryDemoted, Consumer<Exception> onIgnoredFailure) {
            if (testPrimaryDemotedOnStaleShardCopies) {
                onPrimaryDemoted.accept(new ElasticsearchException("the king is dead"));
            } else {
                super.markShardCopyAsStaleIfNeeded(shardId, allocationId, primaryTerm, onSuccess, onPrimaryDemoted, onIgnoredFailure);
            }
        }
    };
    AtomicBoolean primaryFailed = new AtomicBoolean();
    final TestPrimary primary = new TestPrimary(primaryShard, primaryTerm) {

        @Override
        public void failShard(String message, Exception exception) {
            assertTrue(primaryFailed.compareAndSet(false, true));
        }
    };
    final TestReplicationOperation op = new TestReplicationOperation(request, primary, listener, replicasProxy, () -> finalState);
    op.execute();
    assertThat("request was not processed on primary", request.processedOnPrimary.get(), equalTo(true));
    assertTrue("listener is not marked as done", listener.isDone());
    assertTrue(primaryFailed.get());
    assertListenerThrows("should throw exception to trigger retry", listener, ReplicationOperation.RetryOnPrimaryException.class);
}
Also used : HashMap(java.util.HashMap) ElasticsearchException(org.elasticsearch.ElasticsearchException) ShardId(org.elasticsearch.index.shard.ShardId) Consumer(java.util.function.Consumer) ClusterState(org.elasticsearch.cluster.ClusterState) 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) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) PlainActionFuture(org.elasticsearch.action.support.PlainActionFuture) ShardRouting(org.elasticsearch.cluster.routing.ShardRouting)

Example 13 with ShardRouting

use of org.elasticsearch.cluster.routing.ShardRouting in project elasticsearch by elastic.

the class TransportReplicationActionTests method testCounterOnPrimary.

public void testCounterOnPrimary() throws Exception {
    final String index = "test";
    final ShardId shardId = new ShardId(index, "_na_", 0);
    // no replica, we only want to test on primary
    final ClusterState state = state(index, true, ShardRoutingState.STARTED);
    setState(clusterService, state);
    logger.debug("--> using initial state:\n{}", clusterService.state());
    final ShardRouting primaryShard = state.routingTable().shardRoutingTable(shardId).primaryShard();
    Request request = new Request(shardId);
    PlainActionFuture<TestResponse> listener = new PlainActionFuture<>();
    ReplicationTask task = maybeTask();
    int i = randomInt(3);
    final boolean throwExceptionOnCreation = i == 1;
    final boolean throwExceptionOnRun = i == 2;
    final boolean respondWithError = i == 3;
    action.new AsyncPrimaryAction(request, primaryShard.allocationId().getId(), createTransportChannel(listener), task) {

        @Override
        protected ReplicationOperation<Request, Request, TransportReplicationAction.PrimaryResult<Request, TestResponse>> createReplicatedOperation(Request request, ActionListener<TransportReplicationAction.PrimaryResult<Request, TestResponse>> actionListener, TransportReplicationAction<Request, Request, TestResponse>.PrimaryShardReference<Request, Request, TestResponse> primaryShardReference, boolean executeOnReplicas) {
            assertIndexShardCounter(1);
            if (throwExceptionOnCreation) {
                throw new ElasticsearchException("simulated exception, during createReplicatedOperation");
            }
            return new NoopReplicationOperation(request, actionListener) {

                @Override
                public void execute() throws Exception {
                    assertIndexShardCounter(1);
                    assertPhase(task, "primary");
                    if (throwExceptionOnRun) {
                        throw new ElasticsearchException("simulated exception, during performOnPrimary");
                    } else if (respondWithError) {
                        this.resultListener.onFailure(new ElasticsearchException("simulated exception, as a response"));
                    } else {
                        super.execute();
                    }
                }
            };
        }
    }.run();
    assertIndexShardCounter(0);
    assertTrue(listener.isDone());
    assertPhase(task, "finished");
    try {
        listener.get();
    } catch (ExecutionException e) {
        if (throwExceptionOnCreation || throwExceptionOnRun || respondWithError) {
            Throwable cause = e.getCause();
            assertThat(cause, instanceOf(ElasticsearchException.class));
            assertThat(cause.getMessage(), containsString("simulated"));
        } else {
            throw e;
        }
    }
}
Also used : ClusterState(org.elasticsearch.cluster.ClusterState) 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) ElasticsearchException(org.elasticsearch.ElasticsearchException) ElasticsearchException(org.elasticsearch.ElasticsearchException) AlreadyClosedException(org.apache.lucene.store.AlreadyClosedException) IndexClosedException(org.elasticsearch.indices.IndexClosedException) NodeClosedException(org.elasticsearch.node.NodeClosedException) ShardNotFoundException(org.elasticsearch.index.shard.ShardNotFoundException) IndexNotFoundException(org.elasticsearch.index.IndexNotFoundException) NoNodeAvailableException(org.elasticsearch.client.transport.NoNodeAvailableException) TransportException(org.elasticsearch.transport.TransportException) IndexShardClosedException(org.elasticsearch.index.shard.IndexShardClosedException) ClusterBlockException(org.elasticsearch.cluster.block.ClusterBlockException) IOException(java.io.IOException) UnavailableShardsException(org.elasticsearch.action.UnavailableShardsException) ExecutionException(java.util.concurrent.ExecutionException) ShardId(org.elasticsearch.index.shard.ShardId) PlainActionFuture(org.elasticsearch.action.support.PlainActionFuture) TestShardRouting(org.elasticsearch.cluster.routing.TestShardRouting) ShardRouting(org.elasticsearch.cluster.routing.ShardRouting) ExecutionException(java.util.concurrent.ExecutionException)

Example 14 with ShardRouting

use of org.elasticsearch.cluster.routing.ShardRouting in project elasticsearch by elastic.

the class TransportReplicationActionTests method testRetryOnReplica.

/**
     * test throwing a {@link org.elasticsearch.action.support.replication.TransportReplicationAction.RetryOnReplicaException}
     * causes a retry
     */
public void testRetryOnReplica() throws Exception {
    final ShardId shardId = new ShardId("test", "_na_", 0);
    ClusterState state = state(shardId.getIndexName(), true, ShardRoutingState.STARTED, ShardRoutingState.STARTED);
    final ShardRouting replica = state.getRoutingTable().shardRoutingTable(shardId).replicaShards().get(0);
    // simulate execution of the node holding the replica
    state = ClusterState.builder(state).nodes(DiscoveryNodes.builder(state.nodes()).localNodeId(replica.currentNodeId())).build();
    setState(clusterService, state);
    AtomicBoolean throwException = new AtomicBoolean(true);
    final ReplicationTask task = maybeTask();
    TestAction action = new TestAction(Settings.EMPTY, "testActionWithExceptions", transportService, clusterService, shardStateAction, threadPool) {

        @Override
        protected ReplicaResult shardOperationOnReplica(Request request, IndexShard replica) {
            assertPhase(task, "replica");
            if (throwException.get()) {
                throw new RetryOnReplicaException(shardId, "simulation");
            }
            return new ReplicaResult();
        }
    };
    final TestAction.ReplicaOperationTransportHandler replicaOperationTransportHandler = action.new ReplicaOperationTransportHandler();
    final PlainActionFuture<TestResponse> listener = new PlainActionFuture<>();
    final Request request = new Request().setShardId(shardId);
    request.primaryTerm(state.metaData().getIndexSafe(shardId.getIndex()).primaryTerm(shardId.id()));
    replicaOperationTransportHandler.messageReceived(new TransportReplicationAction.ConcreteShardRequest<>(request, replica.allocationId().getId()), createTransportChannel(listener), task);
    if (listener.isDone()) {
        // fail with the exception if there
        listener.get();
        fail("listener shouldn't be done");
    }
    // no retry yet
    List<CapturingTransport.CapturedRequest> capturedRequests = transport.getCapturedRequestsByTargetNodeAndClear().get(replica.currentNodeId());
    assertThat(capturedRequests, nullValue());
    // release the waiting
    throwException.set(false);
    setState(clusterService, state);
    capturedRequests = transport.getCapturedRequestsByTargetNodeAndClear().get(replica.currentNodeId());
    assertThat(capturedRequests, notNullValue());
    assertThat(capturedRequests.size(), equalTo(1));
    final CapturingTransport.CapturedRequest capturedRequest = capturedRequests.get(0);
    assertThat(capturedRequest.action, equalTo("testActionWithExceptions[r]"));
    assertThat(capturedRequest.request, instanceOf(TransportReplicationAction.ConcreteShardRequest.class));
    assertConcreteShardRequest(capturedRequest.request, request, replica.allocationId());
}
Also used : ClusterState(org.elasticsearch.cluster.ClusterState) IndexShard(org.elasticsearch.index.shard.IndexShard) CapturingTransport(org.elasticsearch.test.transport.CapturingTransport) TransportRequest(org.elasticsearch.transport.TransportRequest) CloseIndexRequest(org.elasticsearch.action.admin.indices.close.CloseIndexRequest) ShardId(org.elasticsearch.index.shard.ShardId) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) PlainActionFuture(org.elasticsearch.action.support.PlainActionFuture) TestShardRouting(org.elasticsearch.cluster.routing.TestShardRouting) ShardRouting(org.elasticsearch.cluster.routing.ShardRouting)

Example 15 with ShardRouting

use of org.elasticsearch.cluster.routing.ShardRouting in project elasticsearch by elastic.

the class TransportWriteActionTests method mockIndexShard.

private IndexShard mockIndexShard(ShardId shardId, ClusterService clusterService) {
    final IndexShard indexShard = mock(IndexShard.class);
    doAnswer(invocation -> {
        ActionListener<Releasable> callback = (ActionListener<Releasable>) invocation.getArguments()[0];
        count.incrementAndGet();
        callback.onResponse(count::decrementAndGet);
        return null;
    }).when(indexShard).acquirePrimaryOperationLock(any(ActionListener.class), anyString());
    doAnswer(invocation -> {
        long term = (Long) invocation.getArguments()[0];
        ActionListener<Releasable> callback = (ActionListener<Releasable>) invocation.getArguments()[1];
        final long primaryTerm = indexShard.getPrimaryTerm();
        if (term < primaryTerm) {
            throw new IllegalArgumentException(String.format(Locale.ROOT, "%s operation term [%d] is too old (current [%d])", shardId, term, primaryTerm));
        }
        count.incrementAndGet();
        callback.onResponse(count::decrementAndGet);
        return null;
    }).when(indexShard).acquireReplicaOperationLock(anyLong(), any(ActionListener.class), anyString());
    when(indexShard.routingEntry()).thenAnswer(invocationOnMock -> {
        final ClusterState state = clusterService.state();
        final RoutingNode node = state.getRoutingNodes().node(state.nodes().getLocalNodeId());
        final ShardRouting routing = node.getByShardId(shardId);
        if (routing == null) {
            throw new ShardNotFoundException(shardId, "shard is no longer assigned to current node");
        }
        return routing;
    });
    when(indexShard.state()).thenAnswer(invocationOnMock -> isRelocated.get() ? IndexShardState.RELOCATED : IndexShardState.STARTED);
    doThrow(new AssertionError("failed shard is not supported")).when(indexShard).failShard(anyString(), any(Exception.class));
    when(indexShard.getPrimaryTerm()).thenAnswer(i -> clusterService.state().metaData().getIndexSafe(shardId.getIndex()).primaryTerm(shardId.id()));
    return indexShard;
}
Also used : ClusterState(org.elasticsearch.cluster.ClusterState) IndexShard(org.elasticsearch.index.shard.IndexShard) ElasticsearchException(org.elasticsearch.ElasticsearchException) NodeClosedException(org.elasticsearch.node.NodeClosedException) ShardNotFoundException(org.elasticsearch.index.shard.ShardNotFoundException) NoNodeAvailableException(org.elasticsearch.client.transport.NoNodeAvailableException) TransportException(org.elasticsearch.transport.TransportException) ExecutionException(java.util.concurrent.ExecutionException) ActionListener(org.elasticsearch.action.ActionListener) RoutingNode(org.elasticsearch.cluster.routing.RoutingNode) ShardNotFoundException(org.elasticsearch.index.shard.ShardNotFoundException) Matchers.anyLong(org.mockito.Matchers.anyLong) Releasable(org.elasticsearch.common.lease.Releasable) TestShardRouting(org.elasticsearch.cluster.routing.TestShardRouting) ShardRouting(org.elasticsearch.cluster.routing.ShardRouting)

Aggregations

ShardRouting (org.elasticsearch.cluster.routing.ShardRouting)372 ClusterState (org.elasticsearch.cluster.ClusterState)162 ShardId (org.elasticsearch.index.shard.ShardId)104 IndexShardRoutingTable (org.elasticsearch.cluster.routing.IndexShardRoutingTable)92 DiscoveryNode (org.elasticsearch.cluster.node.DiscoveryNode)79 RoutingNode (org.elasticsearch.cluster.routing.RoutingNode)75 TestShardRouting (org.elasticsearch.cluster.routing.TestShardRouting)75 RoutingTable (org.elasticsearch.cluster.routing.RoutingTable)74 IndexMetaData (org.elasticsearch.cluster.metadata.IndexMetaData)71 Index (org.elasticsearch.index.Index)50 HashSet (java.util.HashSet)49 UnassignedInfo (org.elasticsearch.cluster.routing.UnassignedInfo)49 ArrayList (java.util.ArrayList)48 IndexShard (org.elasticsearch.index.shard.IndexShard)48 Settings (org.elasticsearch.common.settings.Settings)46 MetaData (org.elasticsearch.cluster.metadata.MetaData)45 IndexRoutingTable (org.elasticsearch.cluster.routing.IndexRoutingTable)44 IOException (java.io.IOException)43 HashMap (java.util.HashMap)41 RoutingNodes (org.elasticsearch.cluster.routing.RoutingNodes)41