/** finishes the execution of the current request, with the response that should be returned to the user */ public void markAsCompleted(BulkItemResponse translatedResponse) { assertInvariants(ItemProcessingState.EXECUTED); assert executionResult != null && translatedResponse.getItemId() == executionResult.getItemId(); assert translatedResponse.getItemId() == getCurrentItem().id(); if (translatedResponse.isFailed() == false && requestToExecute != null && requestToExecute != getCurrent()) { request.items()[currentIndex] = new BulkItemRequest(request.items()[currentIndex].id(), requestToExecute); } getCurrentItem().setPrimaryResponse(translatedResponse); currentItemState = ItemProcessingState.COMPLETED; advance(); }
@Override public void onFailure(Exception e) { // create failures for all relevant requests for (BulkItemRequest request : requests) { final String indexName = concreteIndices.getConcreteIndex(request.index()).getName(); DocWriteRequest docWriteRequest = request.request(); responses.set(request.id(), new BulkItemResponse(request.id(), docWriteRequest.opType(), new BulkItemResponse.Failure(indexName, docWriteRequest.type(), docWriteRequest.id(), e))); } if (counter.decrementAndGet() == 0) { finishHim(); } }
/** * Determines whether a bulk item request should be executed on the replica. * * @return {@link ReplicaItemExecutionMode#NORMAL} upon normal primary execution with no failures * {@link ReplicaItemExecutionMode#FAILURE} upon primary execution failure after sequence no generation * {@link ReplicaItemExecutionMode#NOOP} upon primary execution failure before sequence no generation or * when primary execution resulted in noop (only possible for write requests from pre-6.0 nodes) */ static ReplicaItemExecutionMode replicaItemExecutionMode(final BulkItemRequest request, final int index) { final BulkItemResponse primaryResponse = request.getPrimaryResponse(); assert primaryResponse != null : "expected primary response to be set for item [" + index + "] request [" + request.request() + "]"; if (primaryResponse.isFailed()) { return primaryResponse.getFailure().getSeqNo() != SequenceNumbers.UNASSIGNED_SEQ_NO ? ReplicaItemExecutionMode.FAILURE // we have a seq no generated with the failure, replicate as no-op : ReplicaItemExecutionMode.NOOP; // no seq no generated, ignore replication } else { // TODO: once we know for sure that every operation that has been processed on the primary is assigned a seq# // (i.e., all nodes on the cluster are on v6.0.0 or higher) we can use the existence of a seq# to indicate whether // an operation should be processed or be treated as a noop. This means we could remove this method and the // ReplicaItemExecutionMode enum and have a simple boolean check for seq != UNASSIGNED_SEQ_NO which will work for // both failures and indexing operations. return primaryResponse.getResponse().getResult() != DocWriteResponse.Result.NOOP ? ReplicaItemExecutionMode.NORMAL // execution successful on primary : ReplicaItemExecutionMode.NOOP; // ignore replication } }
public static BulkItemRequest readBulkItem(StreamInput in) throws IOException { BulkItemRequest item = new BulkItemRequest(); item.readFrom(in); return item; }
/** completes the operation without doing anything on the primary */ public void markOperationAsNoOp(DocWriteResponse response) { assertInvariants(ItemProcessingState.INITIAL); executionResult = new BulkItemResponse(getCurrentItem().id(), getCurrentItem().request().opType(), response); currentItemState = ItemProcessingState.EXECUTED; assertInvariants(ItemProcessingState.EXECUTED); }
BulkShardRequest bsr = (BulkShardRequest) request; for (BulkItemRequest bir : bsr.items()) { requestTypes.add(bir.request().type());
for (int requestIndex = 0; requestIndex < request.items().length; requestIndex++) { BulkItemRequest item = request.items()[requestIndex]; item.request().copyContextAndHeadersFrom(request); if (item.request() instanceof IndexRequest) { IndexRequest indexRequest = (IndexRequest) item.request(); preVersions[requestIndex] = indexRequest.version(); preVersionTypes[requestIndex] = indexRequest.versionType(); setResponse(item, new BulkItemResponse(item.id(), indexRequest.opType().lowercase(), indexResponse)); } catch (Throwable e) { if (item.getPrimaryResponse() != null && isConflictException(e)) { setResponse(item, item.getPrimaryResponse()); } else { setResponse(item, new BulkItemResponse(item.id(), indexRequest.opType().lowercase(), new BulkItemResponse.Failure(request.index(), indexRequest.type(), indexRequest.id(), e))); } else if (item.request() instanceof DeleteRequest) { DeleteRequest deleteRequest = (DeleteRequest) item.request(); preVersions[requestIndex] = deleteRequest.version(); preVersionTypes[requestIndex] = deleteRequest.versionType(); DeleteResponse deleteResponse = writeResult.response(); location = locationToSync(location, writeResult.location); setResponse(item, new BulkItemResponse(item.id(), OP_TYPE_DELETE, deleteResponse)); } catch (Throwable e) { if (item.getPrimaryResponse() != null && isConflictException(e)) { setResponse(item, item.getPrimaryResponse());
long[] preVersions, VersionType[] preVersionTypes, Translog.Location location, int requestIndex) throws Exception { final DocWriteRequest itemRequest = request.items()[requestIndex].request(); preVersions[requestIndex] = itemRequest.version(); preVersionTypes[requestIndex] = itemRequest.versionType(); assert response.getResult() == DocWriteResponse.Result.NOOP : "only noop update can have null operation"; replicaRequest.setIgnoreOnReplica(); replicaRequest.setPrimaryResponse(new BulkItemResponse(replicaRequest.id(), opType, response)); } else if (operationResult.hasFailure() == false) { BulkItemResponse primaryResponse = new BulkItemResponse(replicaRequest.id(), opType, response); replicaRequest.setPrimaryResponse(primaryResponse); DocWriteRequest docWriteRequest = replicaRequest.request(); Exception failure = operationResult.getFailure(); if (isConflictException(failure)) { if (replicaRequest.getPrimaryResponse() == null || isConflictException(failure) == false) { replicaRequest.setIgnoreOnReplica(); replicaRequest.setPrimaryResponse(new BulkItemResponse(replicaRequest.id(), docWriteRequest.opType(), new BulkItemResponse.Failure(request.index(), docWriteRequest.type(), docWriteRequest.id(), failure))); assert replicaRequest.getPrimaryResponse() != null; assert preVersionTypes[requestIndex] != null; } catch (Exception e) { DocWriteRequest docWriteRequest = request.items()[j].request();
@Override protected WriteReplicaResult<Request> shardOperationOnReplica( Request replicaRequest, IndexShard replica) throws Exception { BulkItemRequest[] itemRequests = new BulkItemRequest[1]; WriteRequest.RefreshPolicy refreshPolicy = replicaRequest.getRefreshPolicy(); itemRequests[0] = new BulkItemRequest(0, ((DocWriteRequest) replicaRequest)); BulkShardRequest bulkShardRequest = new BulkShardRequest(replicaRequest.shardId(), refreshPolicy, itemRequests); WriteReplicaResult<BulkShardRequest> result = shardBulkAction.shardOperationOnReplica(bulkShardRequest, replica); // a replica operation can never throw a document-level failure, // as the same document has been already indexed successfully in the primary return new WriteReplicaResult<>(replicaRequest, result.location, null, replica, logger); }
/** returns any primary response that was set by a previous primary */ public BulkItemResponse getPreviousPrimaryResponse() { return getCurrentItem().getPrimaryResponse(); }
@Override public String[] indices() { List<String> indices = new ArrayList<>(); for (BulkItemRequest item : items) { if (item != null) { indices.add(item.index()); } } return indices.toArray(new String[indices.size()]); }
@Override public void onFailure(Exception e) { // create failures for all relevant requests for (BulkItemRequest request : requests) { final String indexName = concreteIndices.getConcreteIndex(request.index()).getName(); DocWriteRequest docWriteRequest = request.request(); responses.set(request.id(), new BulkItemResponse(request.id(), docWriteRequest.opType(), new BulkItemResponse.Failure(indexName, docWriteRequest.type(), docWriteRequest.id(), e))); } if (counter.decrementAndGet() == 0) { finishHim(); } }
for (int i = 0; i < request.items().length; i++) { BulkItemRequest item = request.items()[i]; if (item == null || item.isIgnoreOnReplica()) { continue; if (item.request() instanceof IndexRequest) { IndexRequest indexRequest = (IndexRequest) item.request(); try { Engine.IndexingOperation operation = TransportIndexAction.executeIndexRequestOnReplica(indexRequest, indexShard); } else if (item.request() instanceof DeleteRequest) { DeleteRequest deleteRequest = (DeleteRequest) item.request(); try { Engine.Delete delete = TransportDeleteAction.executeDeleteRequestOnReplica(deleteRequest, indexShard); throw new IllegalStateException("Unexpected index operation: " + item.request());
replicaRequest = new BulkItemRequest(request.items()[requestIndex].id(), updateIndexRequest); break; case DELETE: translate.updateSourceContentType(), null)); replicaRequest = new BulkItemRequest(request.items()[requestIndex].id(), updateDeleteRequest); break; default: throw new IllegalStateException("Illegal update operation " +
@Override public void readFrom(StreamInput in) throws IOException { super.readFrom(in); items = new BulkItemRequest[in.readVInt()]; for (int i = 0; i < items.length; i++) { if (in.readBoolean()) { items[i] = BulkItemRequest.readBulkItem(in); } } }
@Override public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); out.writeVInt(items.length); for (BulkItemRequest item : items) { if (item != null) { out.writeBoolean(true); item.writeTo(out); } else { out.writeBoolean(false); } } }
private void setResponse(BulkItemRequest request, BulkItemResponse response) { request.setPrimaryResponse(response); if (response.isFailed()) { request.setIgnoreOnReplica(); } }
/** * Abort this request, and store a {@link org.elasticsearch.action.bulk.BulkItemResponse.Failure} response. * * @param index The concrete index that was resolved for this request * @param cause The cause of the rejection (may not be null) * @throws IllegalStateException If a response already exists for this request */ public void abort(String index, Exception cause) { if (primaryResponse == null) { final BulkItemResponse.Failure failure = new BulkItemResponse.Failure(index, request.type(), request.id(), Objects.requireNonNull(cause), true); setPrimaryResponse(new BulkItemResponse(id, request.opType(), failure)); } else { assert primaryResponse.isFailed() && primaryResponse.getFailure().isAborted() : "response [" + Strings.toString(primaryResponse) + "]; cause [" + cause + "]"; if (primaryResponse.isFailed() && primaryResponse.getFailure().isAborted()) { primaryResponse.getFailure().getCause().addSuppressed(cause); } else { throw new IllegalStateException( "aborting item that with response [" + primaryResponse + "] that was previously processed", cause); } } }
BulkShardRequest bsr = (BulkShardRequest) request; for (BulkItemRequest bir : bsr.items()) { switch (bir.request().opType()) { case CREATE: additionalPermissionsRequired.add(IndexAction.NAME);