private UpdateResult shardUpdateOperation( ClusterState clusterState, BulkShardRequest bulkShardRequest, UpdateRequest updateRequest, IndexShard indexShard) { UpdateHelper.Result translate = updateHelper.prepare(updateRequest, indexShard); switch (translate.operation()) { case UPSERT: case INDEX: IndexRequest indexRequest = translate.action(); try { WriteResult result = shardIndexOperation(bulkShardRequest, indexRequest, clusterState, indexShard, false); return new UpdateResult(translate, indexRequest, result); } catch (Throwable t) { t = ExceptionsHelper.unwrapCause(t); boolean retry = false; if (t instanceof VersionConflictEngineException || (t instanceof DocumentAlreadyExistsException && translate.operation() == UpdateHelper.Operation.UPSERT)) { retry = true; } return new UpdateResult(translate, indexRequest, retry, t, null); } case DELETE: DeleteRequest deleteRequest = translate.action(); try { WriteResult result = shardDeleteOperation(bulkShardRequest, deleteRequest, indexShard); return new UpdateResult(translate, deleteRequest, result); } catch (Throwable t) { t = ExceptionsHelper.unwrapCause(t); boolean retry = false; if (t instanceof VersionConflictEngineException) { retry = true; } return new UpdateResult(translate, deleteRequest, retry, t, null); } case NONE: UpdateResponse updateResponse = translate.action(); indexShard.indexingService().noopUpdate(updateRequest.type()); return new UpdateResult(translate, updateResponse); default: throw new IllegalStateException("Illegal update operation " + translate.operation()); } }
protected void shardOperation( final UpdateRequest request, final ActionListener<UpdateResponse> listener, final int retryCount) throws ElasticsearchException { final UpdateHelper.Result result = updateHelper.prepare(request); switch (result.operation()) { case UPSERT: IndexRequest upsertRequest = result.action(); // we fetch it from the index request so we don't generate the bytes twice, its already done // in the index request final BytesReference upsertSourceBytes = upsertRequest.source(); indexAction.execute( upsertRequest, new ActionListener<IndexResponse>() { @Override public void onResponse(IndexResponse response) { UpdateResponse update = new UpdateResponse( response.getIndex(), response.getType(), response.getId(), response.getVersion(), response.isCreated()); if (request.fields() != null && request.fields().length > 0) { Tuple<XContentType, Map<String, Object>> sourceAndContent = XContentHelper.convertToMap(upsertSourceBytes, true); update.setGetResult( updateHelper.extractGetResult( request, response.getVersion(), sourceAndContent.v2(), sourceAndContent.v1(), upsertSourceBytes)); } else { update.setGetResult(null); } listener.onResponse(update); } @Override public void onFailure(Throwable e) { e = ExceptionsHelper.unwrapCause(e); if (e instanceof VersionConflictEngineException || e instanceof DocumentAlreadyExistsException) { if (retryCount < request.retryOnConflict()) { threadPool .executor(executor()) .execute( new ActionRunnable<UpdateResponse>(listener) { @Override protected void doRun() { shardOperation(request, listener, retryCount + 1); } }); return; } } listener.onFailure(e); } }); break; case INDEX: IndexRequest indexRequest = result.action(); // we fetch it from the index request so we don't generate the bytes twice, its already done // in the index request final BytesReference indexSourceBytes = indexRequest.source(); indexAction.execute( indexRequest, new ActionListener<IndexResponse>() { @Override public void onResponse(IndexResponse response) { UpdateResponse update = new UpdateResponse( response.getIndex(), response.getType(), response.getId(), response.getVersion(), response.isCreated()); update.setGetResult( updateHelper.extractGetResult( request, response.getVersion(), result.updatedSourceAsMap(), result.updateSourceContentType(), indexSourceBytes)); listener.onResponse(update); } @Override public void onFailure(Throwable e) { e = ExceptionsHelper.unwrapCause(e); if (e instanceof VersionConflictEngineException) { if (retryCount < request.retryOnConflict()) { threadPool .executor(executor()) .execute( new ActionRunnable<UpdateResponse>(listener) { @Override protected void doRun() { shardOperation(request, listener, retryCount + 1); } }); return; } } listener.onFailure(e); } }); break; case DELETE: DeleteRequest deleteRequest = result.action(); deleteAction.execute( deleteRequest, new ActionListener<DeleteResponse>() { @Override public void onResponse(DeleteResponse response) { UpdateResponse update = new UpdateResponse( response.getIndex(), response.getType(), response.getId(), response.getVersion(), false); update.setGetResult( updateHelper.extractGetResult( request, response.getVersion(), result.updatedSourceAsMap(), result.updateSourceContentType(), null)); listener.onResponse(update); } @Override public void onFailure(Throwable e) { e = ExceptionsHelper.unwrapCause(e); if (e instanceof VersionConflictEngineException) { if (retryCount < request.retryOnConflict()) { threadPool .executor(executor()) .execute( new ActionRunnable<UpdateResponse>(listener) { @Override protected void doRun() { shardOperation(request, listener, retryCount + 1); } }); return; } } listener.onFailure(e); } }); break; case NONE: UpdateResponse update = result.action(); listener.onResponse(update); indicesService .indexService(request.index()) .shard(request.shardId()) .indexingService() .noopUpdate(request.type()); break; default: throw new ElasticsearchIllegalStateException("Illegal operation " + result.operation()); } }