diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/Request.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/Request.java
index ecba2953c94..b92150386a1 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/Request.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/Request.java
@@ -20,6 +20,7 @@
package org.elasticsearch.client;
import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpPost;
@@ -28,6 +29,7 @@ import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.action.DocWriteRequest;
+import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.index.IndexRequest;
@@ -80,8 +82,19 @@ final class Request {
'}';
}
- static Request ping() {
- return new Request("HEAD", "/", Collections.emptyMap(), null);
+ static Request delete(DeleteRequest deleteRequest) {
+ String endpoint = endpoint(deleteRequest.index(), deleteRequest.type(), deleteRequest.id());
+
+ Params parameters = Params.builder();
+ parameters.withRouting(deleteRequest.routing());
+ parameters.withParent(deleteRequest.parent());
+ parameters.withTimeout(deleteRequest.timeout());
+ parameters.withVersion(deleteRequest.version());
+ parameters.withVersionType(deleteRequest.versionType());
+ parameters.withRefreshPolicy(deleteRequest.getRefreshPolicy());
+ parameters.withWaitForActiveShards(deleteRequest.waitForActiveShards());
+
+ return new Request(HttpDelete.METHOD_NAME, endpoint, parameters.getParams(), null);
}
static Request bulk(BulkRequest bulkRequest) throws IOException {
@@ -250,6 +263,10 @@ final class Request {
return new Request(method, endpoint, parameters.getParams(), entity);
}
+ static Request ping() {
+ return new Request("HEAD", "/", Collections.emptyMap(), null);
+ }
+
static Request update(UpdateRequest updateRequest) throws IOException {
String endpoint = endpoint(updateRequest.index(), updateRequest.type(), updateRequest.id(), "_update");
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/RestHighLevelClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/RestHighLevelClient.java
index e174e2fffe6..913a1ae52d7 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/RestHighLevelClient.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/RestHighLevelClient.java
@@ -28,6 +28,8 @@ import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
+import org.elasticsearch.action.delete.DeleteRequest;
+import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
@@ -43,6 +45,7 @@ import org.elasticsearch.rest.BytesRestResponse;
import org.elasticsearch.rest.RestStatus;
import java.io.IOException;
+import java.util.Collections;
import java.util.Objects;
import java.util.Set;
@@ -159,6 +162,26 @@ public class RestHighLevelClient {
performRequestAsyncAndParseEntity(updateRequest, Request::update, UpdateResponse::fromXContent, listener, emptySet(), headers);
}
+ /**
+ * Deletes a document by id using the Delete api
+ *
+ * See Delete API on elastic.co
+ */
+ public DeleteResponse delete(DeleteRequest deleteRequest, Header... headers) throws IOException {
+ return performRequestAndParseEntity(deleteRequest, Request::delete, DeleteResponse::fromXContent, Collections.singleton(404),
+ headers);
+ }
+
+ /**
+ * Asynchronously deletes a document by id using the Delete api
+ *
+ * See Delete API on elastic.co
+ */
+ public void deleteAsync(DeleteRequest deleteRequest, ActionListener listener, Header... headers) {
+ performRequestAsyncAndParseEntity(deleteRequest, Request::delete, DeleteResponse::fromXContent, listener,
+ Collections.singleton(404), headers);
+ }
+
private Resp performRequestAndParseEntity(Req request,
CheckedFunction requestConverter,
CheckedFunction entityParser,
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/CrudIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/CrudIT.java
index 4686a23b868..346d7d7c756 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/CrudIT.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/CrudIT.java
@@ -29,6 +29,7 @@ import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
+import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
@@ -54,6 +55,82 @@ import static java.util.Collections.singletonMap;
public class CrudIT extends ESRestHighLevelClientTestCase {
+ public void testDelete() throws IOException {
+ {
+ // Testing non existing document
+ String docId = "does_not_exist";
+ DeleteRequest deleteRequest = new DeleteRequest("index", "type", docId);
+ DeleteResponse deleteResponse = execute(deleteRequest, highLevelClient()::delete, highLevelClient()::deleteAsync);
+ assertEquals("index", deleteResponse.getIndex());
+ assertEquals("type", deleteResponse.getType());
+ assertEquals(docId, deleteResponse.getId());
+ assertEquals(DocWriteResponse.Result.NOT_FOUND, deleteResponse.getResult());
+ }
+ {
+ // Testing deletion
+ String docId = "id";
+ highLevelClient().index(new IndexRequest("index", "type", docId).source(Collections.singletonMap("foo", "bar")));
+ DeleteRequest deleteRequest = new DeleteRequest("index", "type", docId);
+ if (randomBoolean()) {
+ deleteRequest.version(1L);
+ }
+ DeleteResponse deleteResponse = execute(deleteRequest, highLevelClient()::delete, highLevelClient()::deleteAsync);
+ assertEquals("index", deleteResponse.getIndex());
+ assertEquals("type", deleteResponse.getType());
+ assertEquals(docId, deleteResponse.getId());
+ assertEquals(DocWriteResponse.Result.DELETED, deleteResponse.getResult());
+ }
+ {
+ // Testing version conflict
+ String docId = "version_conflict";
+ highLevelClient().index(new IndexRequest("index", "type", docId).source(Collections.singletonMap("foo", "bar")));
+ DeleteRequest deleteRequest = new DeleteRequest("index", "type", docId).version(2);
+ ElasticsearchException exception = expectThrows(ElasticsearchException.class,
+ () -> execute(deleteRequest, highLevelClient()::delete, highLevelClient()::deleteAsync));
+ assertEquals(RestStatus.CONFLICT, exception.status());
+ assertEquals("Elasticsearch exception [type=version_conflict_engine_exception, reason=[type][" + docId + "]: " +
+ "version conflict, current version [1] is different than the one provided [2]]", exception.getMessage());
+ assertEquals("index", exception.getMetadata("es.index").get(0));
+ }
+ {
+ // Testing version type
+ String docId = "version_type";
+ highLevelClient().index(new IndexRequest("index", "type", docId).source(Collections.singletonMap("foo", "bar"))
+ .versionType(VersionType.EXTERNAL).version(12));
+ DeleteRequest deleteRequest = new DeleteRequest("index", "type", docId).versionType(VersionType.EXTERNAL).version(13);
+ DeleteResponse deleteResponse = execute(deleteRequest, highLevelClient()::delete, highLevelClient()::deleteAsync);
+ assertEquals("index", deleteResponse.getIndex());
+ assertEquals("type", deleteResponse.getType());
+ assertEquals(docId, deleteResponse.getId());
+ assertEquals(DocWriteResponse.Result.DELETED, deleteResponse.getResult());
+ }
+ {
+ // Testing version type with a wrong version
+ String docId = "wrong_version";
+ highLevelClient().index(new IndexRequest("index", "type", docId).source(Collections.singletonMap("foo", "bar"))
+ .versionType(VersionType.EXTERNAL).version(12));
+ ElasticsearchStatusException exception = expectThrows(ElasticsearchStatusException.class, () -> {
+ DeleteRequest deleteRequest = new DeleteRequest("index", "type", docId).versionType(VersionType.EXTERNAL).version(10);
+ execute(deleteRequest, highLevelClient()::delete, highLevelClient()::deleteAsync);
+ });
+ assertEquals(RestStatus.CONFLICT, exception.status());
+ assertEquals("Elasticsearch exception [type=version_conflict_engine_exception, reason=[type][" +
+ docId + "]: version conflict, current version [12] is higher or equal to the one provided [10]]", exception.getMessage());
+ assertEquals("index", exception.getMetadata("es.index").get(0));
+ }
+ {
+ // Testing routing
+ String docId = "routing";
+ highLevelClient().index(new IndexRequest("index", "type", docId).source(Collections.singletonMap("foo", "bar")).routing("foo"));
+ DeleteRequest deleteRequest = new DeleteRequest("index", "type", docId).routing("foo");
+ DeleteResponse deleteResponse = execute(deleteRequest, highLevelClient()::delete, highLevelClient()::deleteAsync);
+ assertEquals("index", deleteResponse.getIndex());
+ assertEquals("type", deleteResponse.getType());
+ assertEquals(docId, deleteResponse.getId());
+ assertEquals(DocWriteResponse.Result.DELETED, deleteResponse.getResult());
+ }
+ }
+
public void testExists() throws IOException {
{
GetRequest getRequest = new GetRequest("index", "type", "id");
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestTests.java
index 1d61ef87c48..62bb6b551af 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestTests.java
@@ -28,6 +28,7 @@ import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.support.WriteRequest;
+import org.elasticsearch.action.support.replication.ReplicatedWriteRequest;
import org.elasticsearch.action.support.replication.ReplicationRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.common.Strings;
@@ -69,6 +70,39 @@ public class RequestTests extends ESTestCase {
getAndExistsTest(Request::get, "GET");
}
+ public void testDelete() throws IOException {
+ String index = randomAsciiOfLengthBetween(3, 10);
+ String type = randomAsciiOfLengthBetween(3, 10);
+ String id = randomAsciiOfLengthBetween(3, 10);
+ DeleteRequest deleteRequest = new DeleteRequest(index, type, id);
+
+ Map expectedParams = new HashMap<>();
+
+ setRandomTimeout(deleteRequest, expectedParams);
+ setRandomRefreshPolicy(deleteRequest, expectedParams);
+ setRandomVersion(deleteRequest, expectedParams);
+ setRandomVersionType(deleteRequest, expectedParams);
+
+ if (frequently()) {
+ if (randomBoolean()) {
+ String routing = randomAsciiOfLengthBetween(3, 10);
+ deleteRequest.routing(routing);
+ expectedParams.put("routing", routing);
+ }
+ if (randomBoolean()) {
+ String parent = randomAsciiOfLengthBetween(3, 10);
+ deleteRequest.parent(parent);
+ expectedParams.put("parent", parent);
+ }
+ }
+
+ Request request = Request.delete(deleteRequest);
+ assertEquals("/" + index + "/" + type + "/" + id, request.endpoint);
+ assertEquals(expectedParams, request.params);
+ assertEquals("DELETE", request.method);
+ assertNull(request.entity);
+ }
+
public void testExists() {
getAndExistsTest(Request::exists, "HEAD");
}
@@ -163,33 +197,16 @@ public class RequestTests extends ESTestCase {
}
}
+ setRandomTimeout(indexRequest, expectedParams);
+ setRandomRefreshPolicy(indexRequest, expectedParams);
+
// There is some logic around _create endpoint and version/version type
if (indexRequest.opType() == DocWriteRequest.OpType.CREATE) {
indexRequest.version(randomFrom(Versions.MATCH_ANY, Versions.MATCH_DELETED));
expectedParams.put("version", Long.toString(Versions.MATCH_DELETED));
} else {
- if (randomBoolean()) {
- long version = randomFrom(Versions.MATCH_ANY, Versions.MATCH_DELETED, Versions.NOT_FOUND, randomNonNegativeLong());
- indexRequest.version(version);
- if (version != Versions.MATCH_ANY) {
- expectedParams.put("version", Long.toString(version));
- }
- }
- if (randomBoolean()) {
- VersionType versionType = randomFrom(VersionType.values());
- indexRequest.versionType(versionType);
- if (versionType != VersionType.INTERNAL) {
- expectedParams.put("version_type", versionType.name().toLowerCase(Locale.ROOT));
- }
- }
- }
-
- if (randomBoolean()) {
- String timeout = randomTimeValue();
- indexRequest.timeout(timeout);
- expectedParams.put("timeout", timeout);
- } else {
- expectedParams.put("timeout", ReplicationRequest.DEFAULT_TIMEOUT.getStringRep());
+ setRandomVersion(indexRequest, expectedParams);
+ setRandomVersionType(indexRequest, expectedParams);
}
if (frequently()) {
@@ -208,14 +225,6 @@ public class RequestTests extends ESTestCase {
indexRequest.setPipeline(pipeline);
expectedParams.put("pipeline", pipeline);
}
-
- if (randomBoolean()) {
- WriteRequest.RefreshPolicy refreshPolicy = randomFrom(WriteRequest.RefreshPolicy.values());
- indexRequest.setRefreshPolicy(refreshPolicy);
- if (refreshPolicy != WriteRequest.RefreshPolicy.NONE) {
- expectedParams.put("refresh", refreshPolicy.getValue());
- }
- }
}
XContentType xContentType = randomFrom(XContentType.values());
@@ -676,4 +685,44 @@ public class RequestTests extends ESTestCase {
}
}
}
-}
\ No newline at end of file
+
+ private static void setRandomTimeout(ReplicationRequest> request, Map expectedParams) {
+ if (randomBoolean()) {
+ String timeout = randomTimeValue();
+ request.timeout(timeout);
+ expectedParams.put("timeout", timeout);
+ } else {
+ expectedParams.put("timeout", ReplicationRequest.DEFAULT_TIMEOUT.getStringRep());
+ }
+ }
+
+ private static void setRandomRefreshPolicy(ReplicatedWriteRequest> request, Map expectedParams) {
+ if (randomBoolean()) {
+ WriteRequest.RefreshPolicy refreshPolicy = randomFrom(WriteRequest.RefreshPolicy.values());
+ request.setRefreshPolicy(refreshPolicy);
+ if (refreshPolicy != WriteRequest.RefreshPolicy.NONE) {
+ expectedParams.put("refresh", refreshPolicy.getValue());
+ }
+ }
+ }
+
+ private static void setRandomVersion(DocWriteRequest> request, Map expectedParams) {
+ if (randomBoolean()) {
+ long version = randomFrom(Versions.MATCH_ANY, Versions.MATCH_DELETED, Versions.NOT_FOUND, randomNonNegativeLong());
+ request.version(version);
+ if (version != Versions.MATCH_ANY) {
+ expectedParams.put("version", Long.toString(version));
+ }
+ }
+ }
+
+ private static void setRandomVersionType(DocWriteRequest> request, Map expectedParams) {
+ if (randomBoolean()) {
+ VersionType versionType = randomFrom(VersionType.values());
+ request.versionType(versionType);
+ if (versionType != VersionType.INTERNAL) {
+ expectedParams.put("version_type", versionType.name().toLowerCase(Locale.ROOT));
+ }
+ }
+ }
+}