Add bwc for index/delete requests from pre-6.0 nodes
This commit is contained in:
parent
c5b09adf47
commit
4231aa4feb
|
@ -28,7 +28,11 @@ import org.elasticsearch.action.delete.DeleteResponse;
|
|||
import org.elasticsearch.action.index.IndexRequest;
|
||||
import org.elasticsearch.action.index.IndexResponse;
|
||||
import org.elasticsearch.action.support.ActionFilters;
|
||||
import org.elasticsearch.action.support.WriteRequest;
|
||||
import org.elasticsearch.action.support.WriteResponse;
|
||||
import org.elasticsearch.action.support.replication.ReplicatedWriteRequest;
|
||||
import org.elasticsearch.action.support.replication.ReplicationOperation;
|
||||
import org.elasticsearch.action.support.replication.ReplicationResponse;
|
||||
import org.elasticsearch.action.support.replication.ReplicationResponse.ShardInfo;
|
||||
import org.elasticsearch.action.support.replication.TransportWriteAction;
|
||||
import org.elasticsearch.action.update.UpdateHelper;
|
||||
|
@ -105,7 +109,8 @@ public class TransportShardBulkAction extends TransportWriteAction<BulkShardRequ
|
|||
}
|
||||
|
||||
@Override
|
||||
protected WritePrimaryResult shardOperationOnPrimary(BulkShardRequest request, IndexShard primary) throws Exception {
|
||||
protected WritePrimaryResult<BulkShardRequest, BulkShardResponse> shardOperationOnPrimary(
|
||||
BulkShardRequest request, IndexShard primary) throws Exception {
|
||||
final IndexMetaData metaData = primary.indexSettings().getIndexMetaData();
|
||||
|
||||
long[] preVersions = new long[request.items().length];
|
||||
|
@ -121,7 +126,7 @@ public class TransportShardBulkAction extends TransportWriteAction<BulkShardRequ
|
|||
responses[i] = items[i].getPrimaryResponse();
|
||||
}
|
||||
BulkShardResponse response = new BulkShardResponse(request.shardId(), responses);
|
||||
return new WritePrimaryResult(request, response, location, null, primary);
|
||||
return new WritePrimaryResult<>(request, response, location, null, primary, logger);
|
||||
}
|
||||
|
||||
/** Executes bulk item requests and handles request execution exceptions */
|
||||
|
@ -355,7 +360,7 @@ public class TransportShardBulkAction extends TransportWriteAction<BulkShardRequ
|
|||
}
|
||||
|
||||
@Override
|
||||
protected WriteReplicaResult shardOperationOnReplica(BulkShardRequest request, IndexShard replica) throws Exception {
|
||||
protected WriteReplicaResult<BulkShardRequest> shardOperationOnReplica(BulkShardRequest request, IndexShard replica) throws Exception {
|
||||
Translog.Location location = null;
|
||||
for (int i = 0; i < request.items().length; i++) {
|
||||
BulkItemRequest item = request.items()[i];
|
||||
|
@ -399,7 +404,7 @@ public class TransportShardBulkAction extends TransportWriteAction<BulkShardRequ
|
|||
}
|
||||
}
|
||||
}
|
||||
return new WriteReplicaResult(request, location, null, replica);
|
||||
return new WriteReplicaResult<>(request, location, null, replica, logger);
|
||||
}
|
||||
|
||||
private Translog.Location locationToSync(Translog.Location current, Translog.Location next) {
|
||||
|
@ -413,6 +418,42 @@ public class TransportShardBulkAction extends TransportWriteAction<BulkShardRequ
|
|||
return next;
|
||||
}
|
||||
|
||||
public <Request extends ReplicatedWriteRequest<Request>, Response extends ReplicationResponse & WriteResponse>
|
||||
WritePrimaryResult<Request, Response> executeSingleItemBulkRequestOnPrimary(
|
||||
Request request, IndexShard primary) throws Exception {
|
||||
BulkItemRequest[] itemRequests = new BulkItemRequest[1];
|
||||
WriteRequest.RefreshPolicy refreshPolicy = request.getRefreshPolicy();
|
||||
request.setRefreshPolicy(WriteRequest.RefreshPolicy.NONE);
|
||||
itemRequests[0] = new BulkItemRequest(0, ((DocWriteRequest) request));
|
||||
BulkShardRequest bulkShardRequest = new BulkShardRequest(request.shardId(), refreshPolicy, itemRequests);
|
||||
WritePrimaryResult<BulkShardRequest, BulkShardResponse> result = shardOperationOnPrimary(bulkShardRequest, primary);
|
||||
BulkShardResponse bulkShardResponse = result.finalResponseIfSuccessful;
|
||||
assert bulkShardResponse.getResponses().length == 1: "expected only one bulk shard response";
|
||||
BulkItemResponse itemResponse = bulkShardResponse.getResponses()[0];
|
||||
final Response response;
|
||||
final Exception failure;
|
||||
if (itemResponse.isFailed()) {
|
||||
failure = itemResponse.getFailure().getCause();
|
||||
response = null;
|
||||
} else {
|
||||
response = (Response) itemResponse.getResponse();
|
||||
failure = null;
|
||||
}
|
||||
return new WritePrimaryResult<>(request, response, result.location, failure, primary, logger);
|
||||
}
|
||||
|
||||
public <ReplicaRequest extends ReplicatedWriteRequest<ReplicaRequest>>
|
||||
WriteReplicaResult<ReplicaRequest> executeSingleItemBulkRequestOnReplica(
|
||||
ReplicaRequest request, IndexShard replica) throws Exception {
|
||||
BulkItemRequest[] itemRequests = new BulkItemRequest[1];
|
||||
WriteRequest.RefreshPolicy refreshPolicy = request.getRefreshPolicy();
|
||||
request.setRefreshPolicy(WriteRequest.RefreshPolicy.NONE);
|
||||
itemRequests[0] = new BulkItemRequest(0, ((DocWriteRequest) request));
|
||||
BulkShardRequest bulkShardRequest = new BulkShardRequest(request.shardId(), refreshPolicy, itemRequests);
|
||||
WriteReplicaResult<BulkShardRequest> result = shardOperationOnReplica(bulkShardRequest, replica);
|
||||
return new WriteReplicaResult<>(request, result.location, null, replica, logger);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the given {@link IndexRequest} on a replica shard, throwing a
|
||||
* {@link RetryOnReplicaException} if the operation needs to be re-tried.
|
||||
|
|
|
@ -24,12 +24,17 @@ import org.elasticsearch.action.bulk.BulkItemResponse;
|
|||
import org.elasticsearch.action.bulk.BulkRequest;
|
||||
import org.elasticsearch.action.bulk.BulkResponse;
|
||||
import org.elasticsearch.action.bulk.TransportBulkAction;
|
||||
import org.elasticsearch.action.bulk.TransportShardBulkAction;
|
||||
import org.elasticsearch.action.support.ActionFilters;
|
||||
import org.elasticsearch.action.support.HandledTransportAction;
|
||||
import org.elasticsearch.action.support.WriteRequest;
|
||||
import org.elasticsearch.action.support.replication.TransportWriteAction;
|
||||
import org.elasticsearch.cluster.action.shard.ShardStateAction;
|
||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.shard.IndexShard;
|
||||
import org.elasticsearch.indices.IndicesService;
|
||||
import org.elasticsearch.tasks.Task;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.transport.TransportService;
|
||||
|
@ -37,18 +42,20 @@ import org.elasticsearch.transport.TransportService;
|
|||
/**
|
||||
* Performs the delete operation.
|
||||
*/
|
||||
public class TransportDeleteAction extends HandledTransportAction<DeleteRequest, DeleteResponse> {
|
||||
public class TransportDeleteAction extends TransportWriteAction<DeleteRequest, DeleteRequest, DeleteResponse> {
|
||||
|
||||
private final TransportBulkAction bulkAction;
|
||||
private final TransportShardBulkAction shardBulkAction;
|
||||
|
||||
@Inject
|
||||
public TransportDeleteAction(Settings settings, TransportService transportService,
|
||||
ThreadPool threadPool,
|
||||
ActionFilters actionFilters,
|
||||
IndexNameExpressionResolver indexNameExpressionResolver,
|
||||
TransportBulkAction bulkAction) {
|
||||
super(settings, DeleteAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver, DeleteRequest::new);
|
||||
public TransportDeleteAction(Settings settings, TransportService transportService, ClusterService clusterService,
|
||||
IndicesService indicesService, ThreadPool threadPool, ShardStateAction shardStateAction,
|
||||
ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver,
|
||||
TransportBulkAction bulkAction, TransportShardBulkAction shardBulkAction) {
|
||||
super(settings, DeleteAction.NAME, transportService, clusterService, indicesService, threadPool, shardStateAction,
|
||||
actionFilters, indexNameExpressionResolver, DeleteRequest::new, DeleteRequest::new, ThreadPool.Names.INDEX);
|
||||
this.bulkAction = bulkAction;
|
||||
this.shardBulkAction = shardBulkAction;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -80,7 +87,19 @@ public class TransportDeleteAction extends HandledTransportAction<DeleteRequest,
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doExecute(DeleteRequest request, ActionListener<DeleteResponse> listener) {
|
||||
throw new UnsupportedOperationException("must have task with request");
|
||||
protected DeleteResponse newResponseInstance() {
|
||||
return new DeleteResponse();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WritePrimaryResult<DeleteRequest, DeleteResponse> shardOperationOnPrimary(
|
||||
DeleteRequest request, IndexShard primary) throws Exception {
|
||||
return shardBulkAction.executeSingleItemBulkRequestOnPrimary(request, primary);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WriteReplicaResult<DeleteRequest> shardOperationOnReplica(
|
||||
DeleteRequest request, IndexShard replica) throws Exception {
|
||||
return shardBulkAction.executeSingleItemBulkRequestOnReplica(request, replica);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,12 +24,17 @@ import org.elasticsearch.action.bulk.BulkItemResponse;
|
|||
import org.elasticsearch.action.bulk.BulkRequest;
|
||||
import org.elasticsearch.action.bulk.BulkResponse;
|
||||
import org.elasticsearch.action.bulk.TransportBulkAction;
|
||||
import org.elasticsearch.action.bulk.TransportShardBulkAction;
|
||||
import org.elasticsearch.action.support.ActionFilters;
|
||||
import org.elasticsearch.action.support.HandledTransportAction;
|
||||
import org.elasticsearch.action.support.WriteRequest;
|
||||
import org.elasticsearch.action.support.replication.TransportWriteAction;
|
||||
import org.elasticsearch.cluster.action.shard.ShardStateAction;
|
||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.shard.IndexShard;
|
||||
import org.elasticsearch.indices.IndicesService;
|
||||
import org.elasticsearch.tasks.Task;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.transport.TransportService;
|
||||
|
@ -44,16 +49,21 @@ import org.elasticsearch.transport.TransportService;
|
|||
* <li><b>allowIdGeneration</b>: If the id is set not, should it be generated. Defaults to <tt>true</tt>.
|
||||
* </ul>
|
||||
*/
|
||||
public class TransportIndexAction extends HandledTransportAction<IndexRequest, IndexResponse> {
|
||||
public class TransportIndexAction extends TransportWriteAction<IndexRequest, IndexRequest, IndexResponse> {
|
||||
|
||||
private final TransportBulkAction bulkAction;
|
||||
private final TransportShardBulkAction shardBulkAction;
|
||||
|
||||
@Inject
|
||||
public TransportIndexAction(Settings settings, TransportService transportService, ThreadPool threadPool,
|
||||
public TransportIndexAction(Settings settings, TransportService transportService, ClusterService clusterService,
|
||||
IndicesService indicesService,
|
||||
ThreadPool threadPool, ShardStateAction shardStateAction,
|
||||
ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver,
|
||||
TransportBulkAction bulkAction) {
|
||||
super(settings, IndexAction.NAME, threadPool, transportService, actionFilters, indexNameExpressionResolver, IndexRequest::new);
|
||||
TransportBulkAction bulkAction, TransportShardBulkAction shardBulkAction) {
|
||||
super(settings, IndexAction.NAME, transportService, clusterService, indicesService, threadPool, shardStateAction,
|
||||
actionFilters, indexNameExpressionResolver, IndexRequest::new, IndexRequest::new, ThreadPool.Names.INDEX);
|
||||
this.bulkAction = bulkAction;
|
||||
this.shardBulkAction = shardBulkAction;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -85,8 +95,20 @@ public class TransportIndexAction extends HandledTransportAction<IndexRequest, I
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void doExecute(IndexRequest request, ActionListener<IndexResponse> listener) {
|
||||
throw new UnsupportedOperationException("must have task with request");
|
||||
protected IndexResponse newResponseInstance() {
|
||||
return new IndexResponse();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WritePrimaryResult<IndexRequest, IndexResponse> shardOperationOnPrimary(
|
||||
IndexRequest request, IndexShard primary) throws Exception {
|
||||
return shardBulkAction.executeSingleItemBulkRequestOnPrimary(request, primary);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WriteReplicaResult<IndexRequest> shardOperationOnReplica(
|
||||
IndexRequest request, IndexShard replica) throws Exception {
|
||||
return shardBulkAction.executeSingleItemBulkRequestOnReplica(request, replica);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -170,7 +170,8 @@ public abstract class TransportReplicationAction<
|
|||
* @param shardRequest the request to the primary shard
|
||||
* @param primary the primary shard to perform the operation on
|
||||
*/
|
||||
protected abstract PrimaryResult shardOperationOnPrimary(Request shardRequest, IndexShard primary) throws Exception;
|
||||
protected abstract PrimaryResult<ReplicaRequest, Response> shardOperationOnPrimary(
|
||||
Request shardRequest, IndexShard primary) throws Exception;
|
||||
|
||||
/**
|
||||
* Synchronous replica operation on nodes with replica copies. This is done under the lock form
|
||||
|
@ -359,8 +360,8 @@ public abstract class TransportReplicationAction<
|
|||
};
|
||||
}
|
||||
|
||||
protected ReplicationOperation<Request, ReplicaRequest, PrimaryResult> createReplicatedOperation(
|
||||
Request request, ActionListener<PrimaryResult> listener,
|
||||
protected ReplicationOperation<Request, ReplicaRequest, PrimaryResult<ReplicaRequest, Response>> createReplicatedOperation(
|
||||
Request request, ActionListener<PrimaryResult<ReplicaRequest, Response>> listener,
|
||||
PrimaryShardReference primaryShardReference, boolean executeOnReplicas) {
|
||||
return new ReplicationOperation<>(request, primaryShardReference, listener,
|
||||
executeOnReplicas, replicasProxy, clusterService::state, logger, actionName
|
||||
|
@ -368,10 +369,12 @@ public abstract class TransportReplicationAction<
|
|||
}
|
||||
}
|
||||
|
||||
protected class PrimaryResult implements ReplicationOperation.PrimaryResult<ReplicaRequest> {
|
||||
protected static class PrimaryResult<ReplicaRequest extends ReplicationRequest<ReplicaRequest>,
|
||||
Response extends ReplicationResponse>
|
||||
implements ReplicationOperation.PrimaryResult<ReplicaRequest> {
|
||||
final ReplicaRequest replicaRequest;
|
||||
final Response finalResponseIfSuccessful;
|
||||
final Exception finalFailure;
|
||||
public final Response finalResponseIfSuccessful;
|
||||
public final Exception finalFailure;
|
||||
|
||||
/**
|
||||
* Result of executing a primary operation
|
||||
|
@ -411,7 +414,7 @@ public abstract class TransportReplicationAction<
|
|||
}
|
||||
}
|
||||
|
||||
protected class ReplicaResult {
|
||||
protected static class ReplicaResult {
|
||||
final Exception finalFailure;
|
||||
|
||||
public ReplicaResult(Exception finalFailure) {
|
||||
|
@ -927,7 +930,8 @@ public abstract class TransportReplicationAction<
|
|||
|
||||
}
|
||||
|
||||
class PrimaryShardReference extends ShardReference implements ReplicationOperation.Primary<Request, ReplicaRequest, PrimaryResult> {
|
||||
class PrimaryShardReference extends ShardReference
|
||||
implements ReplicationOperation.Primary<Request, ReplicaRequest, PrimaryResult<ReplicaRequest, Response>> {
|
||||
|
||||
PrimaryShardReference(IndexShard indexShard, Releasable operationLock) {
|
||||
super(indexShard, operationLock);
|
||||
|
|
|
@ -67,7 +67,8 @@ public abstract class TransportWriteAction<
|
|||
* async refresh is performed on the <code>primary</code> shard according to the <code>Request</code> refresh policy
|
||||
*/
|
||||
@Override
|
||||
protected abstract WritePrimaryResult shardOperationOnPrimary(Request request, IndexShard primary) throws Exception;
|
||||
protected abstract WritePrimaryResult<ReplicaRequest, Response> shardOperationOnPrimary(
|
||||
Request request, IndexShard primary) throws Exception;
|
||||
|
||||
/**
|
||||
* Called once per replica with a reference to the replica {@linkplain IndexShard} to modify.
|
||||
|
@ -76,19 +77,24 @@ public abstract class TransportWriteAction<
|
|||
* async refresh is performed on the <code>replica</code> shard according to the <code>ReplicaRequest</code> refresh policy
|
||||
*/
|
||||
@Override
|
||||
protected abstract WriteReplicaResult shardOperationOnReplica(ReplicaRequest request, IndexShard replica) throws Exception;
|
||||
protected abstract WriteReplicaResult<ReplicaRequest> shardOperationOnReplica(
|
||||
ReplicaRequest request, IndexShard replica) throws Exception;
|
||||
|
||||
/**
|
||||
* Result of taking the action on the primary.
|
||||
*/
|
||||
protected class WritePrimaryResult extends PrimaryResult implements RespondingWriteResult {
|
||||
protected static class WritePrimaryResult<ReplicaRequest extends ReplicatedWriteRequest<ReplicaRequest>,
|
||||
Response extends ReplicationResponse & WriteResponse> extends PrimaryResult<ReplicaRequest, Response>
|
||||
implements RespondingWriteResult {
|
||||
boolean finishedAsyncActions;
|
||||
public final Location location;
|
||||
ActionListener<Response> listener = null;
|
||||
|
||||
public WritePrimaryResult(ReplicaRequest request, @Nullable Response finalResponse,
|
||||
@Nullable Location location, @Nullable Exception operationFailure,
|
||||
IndexShard primary) {
|
||||
IndexShard primary, Logger logger) {
|
||||
super(request, finalResponse, operationFailure);
|
||||
this.location = location;
|
||||
assert location == null || operationFailure == null
|
||||
: "expected either failure to be null or translog location to be null, " +
|
||||
"but found: [" + location + "] translog location and [" + operationFailure + "] failure";
|
||||
|
@ -138,13 +144,16 @@ public abstract class TransportWriteAction<
|
|||
/**
|
||||
* Result of taking the action on the replica.
|
||||
*/
|
||||
protected class WriteReplicaResult extends ReplicaResult implements RespondingWriteResult {
|
||||
protected static class WriteReplicaResult<ReplicaRequest extends ReplicatedWriteRequest<ReplicaRequest>>
|
||||
extends ReplicaResult implements RespondingWriteResult {
|
||||
public final Location location;
|
||||
boolean finishedAsyncActions;
|
||||
private ActionListener<TransportResponse.Empty> listener;
|
||||
|
||||
public WriteReplicaResult(ReplicaRequest request, @Nullable Location location,
|
||||
@Nullable Exception operationFailure, IndexShard replica) {
|
||||
@Nullable Exception operationFailure, IndexShard replica, Logger logger) {
|
||||
super(operationFailure);
|
||||
this.location = location;
|
||||
if (operationFailure != null) {
|
||||
this.finishedAsyncActions = true;
|
||||
} else {
|
||||
|
|
|
@ -444,9 +444,11 @@ public class TransportReplicationActionTests extends ESTestCase {
|
|||
}
|
||||
action.new AsyncPrimaryAction(request, primaryShard.allocationId().getId(), createTransportChannel(listener), task) {
|
||||
@Override
|
||||
protected ReplicationOperation<Request, Request, Action.PrimaryResult> createReplicatedOperation(Request request,
|
||||
ActionListener<Action.PrimaryResult> actionListener, Action.PrimaryShardReference primaryShardReference,
|
||||
boolean executeOnReplicas) {
|
||||
protected ReplicationOperation<Request, Request, TransportReplicationAction.PrimaryResult<Request, Response>>
|
||||
createReplicatedOperation(Request request,
|
||||
ActionListener<TransportReplicationAction.PrimaryResult<Request, Response>> actionListener,
|
||||
TransportReplicationAction<Request, Request, Response>.PrimaryShardReference primaryShardReference,
|
||||
boolean executeOnReplicas) {
|
||||
return new NoopReplicationOperation(request, actionListener) {
|
||||
public void execute() throws Exception {
|
||||
assertPhase(task, "primary");
|
||||
|
@ -494,9 +496,11 @@ public class TransportReplicationActionTests extends ESTestCase {
|
|||
AtomicBoolean executed = new AtomicBoolean();
|
||||
action.new AsyncPrimaryAction(request, primaryShard.allocationId().getRelocationId(), createTransportChannel(listener), task) {
|
||||
@Override
|
||||
protected ReplicationOperation<Request, Request, Action.PrimaryResult> createReplicatedOperation(Request request,
|
||||
ActionListener<Action.PrimaryResult> actionListener, Action.PrimaryShardReference primaryShardReference,
|
||||
boolean executeOnReplicas) {
|
||||
protected ReplicationOperation<Request, Request, TransportReplicationAction.PrimaryResult<Request, Response>>
|
||||
createReplicatedOperation(Request request,
|
||||
ActionListener<TransportReplicationAction.PrimaryResult<Request, Response>> actionListener,
|
||||
TransportReplicationAction<Request, Request, Response>.PrimaryShardReference primaryShardReference,
|
||||
boolean executeOnReplicas) {
|
||||
return new NoopReplicationOperation(request, actionListener) {
|
||||
public void execute() throws Exception {
|
||||
assertPhase(task, "primary");
|
||||
|
@ -529,7 +533,7 @@ public class TransportReplicationActionTests extends ESTestCase {
|
|||
};
|
||||
Action.PrimaryShardReference primary = action.new PrimaryShardReference(shard, releasable);
|
||||
final Request request = new Request();
|
||||
Request replicaRequest = primary.perform(request).replicaRequest;
|
||||
Request replicaRequest = (Request) primary.perform(request).replicaRequest;
|
||||
|
||||
assertThat(replicaRequest.primaryTerm(), equalTo(primaryTerm));
|
||||
|
||||
|
@ -639,13 +643,15 @@ public class TransportReplicationActionTests extends ESTestCase {
|
|||
action.new AsyncPrimaryAction(new Request(shardId), primaryShard.allocationId().getId(),
|
||||
createTransportChannel(new PlainActionFuture<>()), null) {
|
||||
@Override
|
||||
protected ReplicationOperation<Request, Request, Action.PrimaryResult> createReplicatedOperation(Request request,
|
||||
ActionListener<Action.PrimaryResult> actionListener, Action.PrimaryShardReference primaryShardReference,
|
||||
protected ReplicationOperation<Request, Request, Action.PrimaryResult<Request, Response>> createReplicatedOperation(
|
||||
Request request, ActionListener<TransportReplicationAction.PrimaryResult<Request, Response>> actionListener,
|
||||
TransportReplicationAction<Request, Request, Response>.PrimaryShardReference primaryShardReference,
|
||||
boolean executeOnReplicas) {
|
||||
assertFalse(executeOnReplicas);
|
||||
assertFalse(executed.getAndSet(true));
|
||||
return new NoopReplicationOperation(request, actionListener);
|
||||
}
|
||||
|
||||
}.run();
|
||||
assertThat(executed.get(), equalTo(true));
|
||||
}
|
||||
|
@ -705,9 +711,11 @@ public class TransportReplicationActionTests extends ESTestCase {
|
|||
final boolean respondWithError = i == 3;
|
||||
action.new AsyncPrimaryAction(request, primaryShard.allocationId().getId(), createTransportChannel(listener), task) {
|
||||
@Override
|
||||
protected ReplicationOperation<Request, Request, Action.PrimaryResult> createReplicatedOperation(Request request,
|
||||
ActionListener<Action.PrimaryResult> actionListener, Action.PrimaryShardReference primaryShardReference,
|
||||
boolean executeOnReplicas) {
|
||||
protected ReplicationOperation<Request, Request, TransportReplicationAction.PrimaryResult<Request, Response>>
|
||||
createReplicatedOperation(Request request,
|
||||
ActionListener<TransportReplicationAction.PrimaryResult<Request, Response>> actionListener,
|
||||
TransportReplicationAction<Request, Request, Response>.PrimaryShardReference primaryShardReference,
|
||||
boolean executeOnReplicas) {
|
||||
assertIndexShardCounter(1);
|
||||
if (throwExceptionOnCreation) {
|
||||
throw new ElasticsearchException("simulated exception, during createReplicatedOperation");
|
||||
|
@ -1095,14 +1103,14 @@ public class TransportReplicationActionTests extends ESTestCase {
|
|||
return indexShard;
|
||||
}
|
||||
|
||||
class NoopReplicationOperation extends ReplicationOperation<Request, Request, Action.PrimaryResult> {
|
||||
public NoopReplicationOperation(Request request, ActionListener<Action.PrimaryResult> listener) {
|
||||
class NoopReplicationOperation extends ReplicationOperation<Request, Request, Action.PrimaryResult<Request, Response>> {
|
||||
public NoopReplicationOperation(Request request, ActionListener<Action.PrimaryResult<Request, Response>> listener) {
|
||||
super(request, null, listener, true, null, null, TransportReplicationActionTests.this.logger, "noop");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws Exception {
|
||||
this.resultListener.onResponse(action.new PrimaryResult(null, new Response()));
|
||||
this.resultListener.onResponse(new TransportReplicationAction.PrimaryResult<>(null, new Response()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@ import org.junit.Before;
|
|||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static org.mockito.Matchers.any;
|
||||
|
@ -55,21 +54,27 @@ public class TransportWriteActionTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testPrimaryNoRefreshCall() throws Exception {
|
||||
noRefreshCall(TestAction::shardOperationOnPrimary, TestAction.WritePrimaryResult::respond);
|
||||
TestRequest request = new TestRequest();
|
||||
request.setRefreshPolicy(RefreshPolicy.NONE); // The default, but we'll set it anyway just to be explicit
|
||||
TestAction testAction = new TestAction();
|
||||
TransportWriteAction.WritePrimaryResult<TestRequest, TestResponse> result =
|
||||
testAction.shardOperationOnPrimary(request, indexShard);
|
||||
CapturingActionListener<TestResponse> listener = new CapturingActionListener<>();
|
||||
result.respond(listener);
|
||||
assertNotNull(listener.response);
|
||||
assertNull(listener.failure);
|
||||
verify(indexShard, never()).refresh(any());
|
||||
verify(indexShard, never()).addRefreshListener(any(), any());
|
||||
}
|
||||
|
||||
public void testReplicaNoRefreshCall() throws Exception {
|
||||
noRefreshCall(TestAction::shardOperationOnReplica, TestAction.WriteReplicaResult::respond);
|
||||
}
|
||||
|
||||
private <Result, Response> void noRefreshCall(ThrowingTriFunction<TestAction, TestRequest, IndexShard, Result> action,
|
||||
BiConsumer<Result, CapturingActionListener<Response>> responder)
|
||||
throws Exception {
|
||||
TestRequest request = new TestRequest();
|
||||
request.setRefreshPolicy(RefreshPolicy.NONE); // The default, but we'll set it anyway just to be explicit
|
||||
Result result = action.apply(new TestAction(), request, indexShard);
|
||||
CapturingActionListener<Response> listener = new CapturingActionListener<>();
|
||||
responder.accept(result, listener);
|
||||
TestAction testAction = new TestAction();
|
||||
TransportWriteAction.WriteReplicaResult<TestRequest> result =
|
||||
testAction.shardOperationOnReplica(request, indexShard);
|
||||
CapturingActionListener<TransportResponse.Empty> listener = new CapturingActionListener<>();
|
||||
result.respond(listener);
|
||||
assertNotNull(listener.response);
|
||||
assertNull(listener.failure);
|
||||
verify(indexShard, never()).refresh(any());
|
||||
|
@ -77,45 +82,65 @@ public class TransportWriteActionTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testPrimaryImmediateRefresh() throws Exception {
|
||||
immediateRefresh(TestAction::shardOperationOnPrimary, TestAction.WritePrimaryResult::respond, r -> assertTrue(r.forcedRefresh));
|
||||
TestRequest request = new TestRequest();
|
||||
request.setRefreshPolicy(RefreshPolicy.IMMEDIATE);
|
||||
TestAction testAction = new TestAction();
|
||||
TransportWriteAction.WritePrimaryResult<TestRequest, TestResponse> result =
|
||||
testAction.shardOperationOnPrimary(request, indexShard);
|
||||
CapturingActionListener<TestResponse> listener = new CapturingActionListener<>();
|
||||
result.respond(listener);
|
||||
assertNotNull(listener.response);
|
||||
assertNull(listener.failure);
|
||||
assertTrue(listener.response.forcedRefresh);
|
||||
verify(indexShard).refresh("refresh_flag_index");
|
||||
verify(indexShard, never()).addRefreshListener(any(), any());
|
||||
}
|
||||
|
||||
public void testReplicaImmediateRefresh() throws Exception {
|
||||
immediateRefresh(TestAction::shardOperationOnReplica, TestAction.WriteReplicaResult::respond, r -> {});
|
||||
}
|
||||
|
||||
private <Result, Response> void immediateRefresh(ThrowingTriFunction<TestAction, TestRequest, IndexShard, Result> action,
|
||||
BiConsumer<Result, CapturingActionListener<Response>> responder,
|
||||
Consumer<Response> responseChecker) throws Exception {
|
||||
TestRequest request = new TestRequest();
|
||||
request.setRefreshPolicy(RefreshPolicy.IMMEDIATE);
|
||||
Result result = action.apply(new TestAction(), request, indexShard);
|
||||
CapturingActionListener<Response> listener = new CapturingActionListener<>();
|
||||
responder.accept(result, listener);
|
||||
TestAction testAction = new TestAction();
|
||||
TransportWriteAction.WriteReplicaResult<TestRequest> result =
|
||||
testAction.shardOperationOnReplica(request, indexShard);
|
||||
CapturingActionListener<TransportResponse.Empty> listener = new CapturingActionListener<>();
|
||||
result.respond(listener);
|
||||
assertNotNull(listener.response);
|
||||
assertNull(listener.failure);
|
||||
responseChecker.accept(listener.response);
|
||||
verify(indexShard).refresh("refresh_flag_index");
|
||||
verify(indexShard, never()).addRefreshListener(any(), any());
|
||||
}
|
||||
|
||||
public void testPrimaryWaitForRefresh() throws Exception {
|
||||
waitForRefresh(TestAction::shardOperationOnPrimary, TestAction.WritePrimaryResult::respond,
|
||||
(r, forcedRefresh) -> assertEquals(forcedRefresh, r.forcedRefresh));
|
||||
}
|
||||
|
||||
public void testReplicaWaitForRefresh() throws Exception {
|
||||
waitForRefresh(TestAction::shardOperationOnReplica, TestAction.WriteReplicaResult::respond, (r, forcedRefresh) -> {});
|
||||
}
|
||||
|
||||
private <Result, Response> void waitForRefresh(ThrowingTriFunction<TestAction, TestRequest, IndexShard, Result> action,
|
||||
BiConsumer<Result, CapturingActionListener<Response>> responder,
|
||||
BiConsumer<Response, Boolean> resultChecker) throws Exception {
|
||||
TestRequest request = new TestRequest();
|
||||
request.setRefreshPolicy(RefreshPolicy.WAIT_UNTIL);
|
||||
Result result = action.apply(new TestAction(), request, indexShard);
|
||||
CapturingActionListener<Response> listener = new CapturingActionListener<>();
|
||||
responder.accept(result, listener);
|
||||
|
||||
TestAction testAction = new TestAction();
|
||||
TransportWriteAction.WritePrimaryResult<TestRequest, TestResponse> result =
|
||||
testAction.shardOperationOnPrimary(request, indexShard);
|
||||
CapturingActionListener<TestResponse> listener = new CapturingActionListener<>();
|
||||
result.respond(listener);
|
||||
assertNull(listener.response); // Haven't reallresponded yet
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
ArgumentCaptor<Consumer<Boolean>> refreshListener = ArgumentCaptor.forClass((Class) Consumer.class);
|
||||
verify(indexShard, never()).refresh(any());
|
||||
verify(indexShard).addRefreshListener(any(), refreshListener.capture());
|
||||
|
||||
// Now we can fire the listener manually and we'll get a response
|
||||
boolean forcedRefresh = randomBoolean();
|
||||
refreshListener.getValue().accept(forcedRefresh);
|
||||
assertNotNull(listener.response);
|
||||
assertNull(listener.failure);
|
||||
assertEquals(forcedRefresh, listener.response.forcedRefresh);
|
||||
}
|
||||
|
||||
public void testReplicaWaitForRefresh() throws Exception {
|
||||
TestRequest request = new TestRequest();
|
||||
request.setRefreshPolicy(RefreshPolicy.WAIT_UNTIL);
|
||||
TestAction testAction = new TestAction();
|
||||
TransportWriteAction.WriteReplicaResult<TestRequest> result = testAction.shardOperationOnReplica(request, indexShard);
|
||||
CapturingActionListener<TransportResponse.Empty> listener = new CapturingActionListener<>();
|
||||
result.respond(listener);
|
||||
assertNull(listener.response); // Haven't reallresponded yet
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
|
@ -128,13 +153,12 @@ public class TransportWriteActionTests extends ESTestCase {
|
|||
refreshListener.getValue().accept(forcedRefresh);
|
||||
assertNotNull(listener.response);
|
||||
assertNull(listener.failure);
|
||||
resultChecker.accept(listener.response, forcedRefresh);
|
||||
}
|
||||
|
||||
public void testDocumentFailureInShardOperationOnPrimary() throws Exception {
|
||||
TestRequest request = new TestRequest();
|
||||
TestAction testAction = new TestAction(true, true);
|
||||
TransportWriteAction<TestRequest, TestRequest, TestResponse>.WritePrimaryResult writePrimaryResult =
|
||||
TransportWriteAction.WritePrimaryResult<TestRequest, TestResponse> writePrimaryResult =
|
||||
testAction.shardOperationOnPrimary(request, indexShard);
|
||||
CapturingActionListener<TestResponse> listener = new CapturingActionListener<>();
|
||||
writePrimaryResult.respond(listener);
|
||||
|
@ -145,7 +169,7 @@ public class TransportWriteActionTests extends ESTestCase {
|
|||
public void testDocumentFailureInShardOperationOnReplica() throws Exception {
|
||||
TestRequest request = new TestRequest();
|
||||
TestAction testAction = new TestAction(randomBoolean(), true);
|
||||
TransportWriteAction<TestRequest, TestRequest, TestResponse>.WriteReplicaResult writeReplicaResult =
|
||||
TransportWriteAction.WriteReplicaResult<TestRequest> writeReplicaResult =
|
||||
testAction.shardOperationOnReplica(request, indexShard);
|
||||
CapturingActionListener<TransportResponse.Empty> listener = new CapturingActionListener<>();
|
||||
writeReplicaResult.respond(listener);
|
||||
|
@ -176,23 +200,24 @@ public class TransportWriteActionTests extends ESTestCase {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected WritePrimaryResult shardOperationOnPrimary(TestRequest request, IndexShard primary) throws Exception {
|
||||
final WritePrimaryResult primaryResult;
|
||||
protected WritePrimaryResult<TestRequest, TestResponse> shardOperationOnPrimary(
|
||||
TestRequest request, IndexShard primary) throws Exception {
|
||||
final WritePrimaryResult<TestRequest, TestResponse> primaryResult;
|
||||
if (withDocumentFailureOnPrimary) {
|
||||
primaryResult = new WritePrimaryResult(request, null, null, new RuntimeException("simulated"), primary);
|
||||
primaryResult = new WritePrimaryResult<>(request, null, null, new RuntimeException("simulated"), primary, logger);
|
||||
} else {
|
||||
primaryResult = new WritePrimaryResult(request, new TestResponse(), location, null, primary);
|
||||
primaryResult = new WritePrimaryResult<>(request, new TestResponse(), location, null, primary, logger);
|
||||
}
|
||||
return primaryResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WriteReplicaResult shardOperationOnReplica(TestRequest request, IndexShard replica) throws Exception {
|
||||
final WriteReplicaResult replicaResult;
|
||||
protected WriteReplicaResult<TestRequest> shardOperationOnReplica(TestRequest request, IndexShard replica) throws Exception {
|
||||
final WriteReplicaResult<TestRequest> replicaResult;
|
||||
if (withDocumentFailureOnReplica) {
|
||||
replicaResult = new WriteReplicaResult(request, null, new RuntimeException("simulated"), replica);
|
||||
replicaResult = new WriteReplicaResult<>(request, null, new RuntimeException("simulated"), replica, logger);
|
||||
} else {
|
||||
replicaResult = new WriteReplicaResult(request, location, null, replica);
|
||||
replicaResult = new WriteReplicaResult<>(request, location, null, replica, logger);
|
||||
}
|
||||
return replicaResult;
|
||||
}
|
||||
|
@ -227,8 +252,4 @@ public class TransportWriteActionTests extends ESTestCase {
|
|||
this.failure = failure;
|
||||
}
|
||||
}
|
||||
|
||||
private interface ThrowingTriFunction<A, B, C, R> {
|
||||
R apply(A a, B b, C c) throws Exception;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package org.elasticsearch.index;
|
||||
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.ExceptionsHelper;
|
||||
import org.elasticsearch.action.DocWriteResponse;
|
||||
|
@ -88,6 +89,7 @@ import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
|||
/**
|
||||
* Tests for indices that use shadow replicas and a shared filesystem
|
||||
*/
|
||||
@LuceneTestCase.AwaitsFix(bugUrl = "fix this fails intermittently")
|
||||
@ESIntegTestCase.ClusterScope(scope = ESIntegTestCase.Scope.TEST, numDataNodes = 0)
|
||||
public class IndexWithShadowReplicasIT extends ESIntegTestCase {
|
||||
|
||||
|
|
|
@ -61,10 +61,7 @@ public class DynamicMappingDisabledTests extends ESSingleNodeTestCase {
|
|||
private static ThreadPool THREAD_POOL;
|
||||
private ClusterService clusterService;
|
||||
private TransportService transportService;
|
||||
private ActionFilters actionFilters;
|
||||
private IndexNameExpressionResolver indexNameExpressionResolver;
|
||||
private TransportBulkAction bulkAction;
|
||||
private Settings settings;
|
||||
private TransportIndexAction transportIndexAction;
|
||||
|
||||
@BeforeClass
|
||||
public static void createThreadPool() {
|
||||
|
@ -74,7 +71,7 @@ public class DynamicMappingDisabledTests extends ESSingleNodeTestCase {
|
|||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
settings = Settings.builder()
|
||||
Settings settings = Settings.builder()
|
||||
.put(MapperService.INDEX_MAPPER_DYNAMIC_SETTING.getKey(), false)
|
||||
.build();
|
||||
clusterService = createClusterService(THREAD_POOL);
|
||||
|
@ -85,15 +82,18 @@ public class DynamicMappingDisabledTests extends ESSingleNodeTestCase {
|
|||
TransportService.NOOP_TRANSPORT_INTERCEPTOR, null);
|
||||
IndicesService indicesService = getInstanceFromNode(IndicesService.class);
|
||||
ShardStateAction shardStateAction = new ShardStateAction(settings, clusterService, transportService, null, null, THREAD_POOL);
|
||||
actionFilters = new ActionFilters(Collections.emptySet());
|
||||
indexNameExpressionResolver = new IndexNameExpressionResolver(settings);
|
||||
ActionFilters actionFilters = new ActionFilters(Collections.emptySet());
|
||||
IndexNameExpressionResolver indexNameExpressionResolver = new IndexNameExpressionResolver(settings);
|
||||
AutoCreateIndex autoCreateIndex = new AutoCreateIndex(settings, new ClusterSettings(settings,
|
||||
ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), indexNameExpressionResolver);
|
||||
UpdateHelper updateHelper = new UpdateHelper(settings, null);
|
||||
TransportShardBulkAction shardBulkAction = new TransportShardBulkAction(settings, transportService, clusterService,
|
||||
indicesService, THREAD_POOL, shardStateAction, null, updateHelper, actionFilters, indexNameExpressionResolver);
|
||||
bulkAction = new TransportBulkAction(settings, THREAD_POOL, transportService, clusterService,
|
||||
TransportBulkAction bulkAction = new TransportBulkAction(settings, THREAD_POOL, transportService, clusterService,
|
||||
shardBulkAction, null, actionFilters, indexNameExpressionResolver, autoCreateIndex, System::currentTimeMillis);
|
||||
transportIndexAction = new TransportIndexAction(settings, transportService, clusterService,
|
||||
indicesService, THREAD_POOL, shardStateAction, actionFilters, indexNameExpressionResolver,
|
||||
bulkAction, shardBulkAction);
|
||||
}
|
||||
|
||||
@After
|
||||
|
@ -112,14 +112,12 @@ public class DynamicMappingDisabledTests extends ESSingleNodeTestCase {
|
|||
}
|
||||
|
||||
public void testDynamicDisabled() {
|
||||
TransportIndexAction action = new TransportIndexAction(settings, transportService,
|
||||
THREAD_POOL, actionFilters, indexNameExpressionResolver, bulkAction);
|
||||
|
||||
IndexRequest request = new IndexRequest("index", "type", "1");
|
||||
request.source("foo", 3);
|
||||
final AtomicBoolean onFailureCalled = new AtomicBoolean();
|
||||
|
||||
action.execute(request, new ActionListener<IndexResponse>() {
|
||||
transportIndexAction.execute(request, new ActionListener<IndexResponse>() {
|
||||
@Override
|
||||
public void onResponse(IndexResponse indexResponse) {
|
||||
fail("Indexing request should have failed");
|
||||
|
|
Loading…
Reference in New Issue