Merge branch 'master' into hlclient/add-delete-method
# Conflicts: # client/rest-high-level/src/main/java/org/elasticsearch/client/Request.java # client/rest-high-level/src/test/java/org/elasticsearch/client/CrudIT.java
This commit is contained in:
commit
0bbcd94827
|
@ -20,10 +20,22 @@
|
||||||
package org.elasticsearch.client;
|
package org.elasticsearch.client;
|
||||||
|
|
||||||
import org.apache.http.HttpEntity;
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpHead;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.client.methods.HttpPut;
|
||||||
|
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.delete.DeleteRequest;
|
||||||
import org.elasticsearch.action.get.GetRequest;
|
import org.elasticsearch.action.get.GetRequest;
|
||||||
|
import org.elasticsearch.action.index.IndexRequest;
|
||||||
|
import org.elasticsearch.action.support.ActiveShardCount;
|
||||||
|
import org.elasticsearch.action.support.WriteRequest;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.lucene.uid.Versions;
|
import org.elasticsearch.common.lucene.uid.Versions;
|
||||||
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.index.VersionType;
|
import org.elasticsearch.index.VersionType;
|
||||||
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
||||||
|
|
||||||
|
@ -35,6 +47,8 @@ import java.util.StringJoiner;
|
||||||
|
|
||||||
final class Request {
|
final class Request {
|
||||||
|
|
||||||
|
private static final String DELIMITER = "/";
|
||||||
|
|
||||||
final String method;
|
final String method;
|
||||||
final String endpoint;
|
final String endpoint;
|
||||||
final Map<String, String> params;
|
final Map<String, String> params;
|
||||||
|
@ -61,53 +75,53 @@ final class Request {
|
||||||
}
|
}
|
||||||
|
|
||||||
static Request exists(GetRequest getRequest) {
|
static Request exists(GetRequest getRequest) {
|
||||||
return new Request("HEAD", getEndpoint(getRequest), getParams(getRequest), null);
|
Request request = get(getRequest);
|
||||||
|
return new Request(HttpHead.METHOD_NAME, request.endpoint, request.params, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Request get(GetRequest getRequest) {
|
static Request get(GetRequest getRequest) {
|
||||||
return new Request("GET", getEndpoint(getRequest), getParams(getRequest), null);
|
String endpoint = endpoint(getRequest.index(), getRequest.type(), getRequest.id());
|
||||||
|
|
||||||
|
Params parameters = Params.builder();
|
||||||
|
parameters.withPreference(getRequest.preference());
|
||||||
|
parameters.withRouting(getRequest.routing());
|
||||||
|
parameters.withParent(getRequest.parent());
|
||||||
|
parameters.withRefresh(getRequest.refresh());
|
||||||
|
parameters.withRealtime(getRequest.realtime());
|
||||||
|
parameters.withStoredFields(getRequest.storedFields());
|
||||||
|
parameters.withVersion(getRequest.version());
|
||||||
|
parameters.withVersionType(getRequest.versionType());
|
||||||
|
parameters.withFetchSourceContext(getRequest.fetchSourceContext());
|
||||||
|
|
||||||
|
return new Request(HttpGet.METHOD_NAME, endpoint, parameters.getParams(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Request index(IndexRequest indexRequest) {
|
||||||
|
String method = Strings.hasLength(indexRequest.id()) ? HttpPut.METHOD_NAME : HttpPost.METHOD_NAME;
|
||||||
|
|
||||||
|
boolean isCreate = (indexRequest.opType() == DocWriteRequest.OpType.CREATE);
|
||||||
|
String endpoint = endpoint(indexRequest.index(), indexRequest.type(), indexRequest.id(), isCreate ? "_create" : null);
|
||||||
|
|
||||||
|
Params parameters = Params.builder();
|
||||||
|
parameters.withRouting(indexRequest.routing());
|
||||||
|
parameters.withParent(indexRequest.parent());
|
||||||
|
parameters.withTimeout(indexRequest.timeout());
|
||||||
|
parameters.withVersion(indexRequest.version());
|
||||||
|
parameters.withVersionType(indexRequest.versionType());
|
||||||
|
parameters.withPipeline(indexRequest.getPipeline());
|
||||||
|
parameters.withRefreshPolicy(indexRequest.getRefreshPolicy());
|
||||||
|
parameters.withWaitForActiveShards(indexRequest.waitForActiveShards());
|
||||||
|
|
||||||
|
BytesRef source = indexRequest.source().toBytesRef();
|
||||||
|
ContentType contentType = ContentType.create(indexRequest.getContentType().mediaType());
|
||||||
|
HttpEntity entity = new ByteArrayEntity(source.bytes, source.offset, source.length, contentType);
|
||||||
|
|
||||||
|
return new Request(method, endpoint, parameters.getParams(), entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Request delete(DeleteRequest deleteRequest) {
|
static Request delete(DeleteRequest deleteRequest) {
|
||||||
return new Request("DELETE", deleteEndpoint(deleteRequest), deleteParams(deleteRequest), null);
|
return new Request("DELETE", deleteEndpoint(deleteRequest), deleteParams(deleteRequest), null);
|
||||||
}
|
|
||||||
|
|
||||||
private static Map<String, String> getParams(GetRequest getRequest) {
|
|
||||||
Map<String, String> params = new HashMap<>();
|
|
||||||
putParam("preference", getRequest.preference(), params);
|
|
||||||
putParam("routing", getRequest.routing(), params);
|
|
||||||
putParam("parent", getRequest.parent(), params);
|
|
||||||
if (getRequest.refresh()) {
|
|
||||||
params.put("refresh", Boolean.TRUE.toString());
|
|
||||||
}
|
|
||||||
if (getRequest.realtime() == false) {
|
|
||||||
params.put("realtime", Boolean.FALSE.toString());
|
|
||||||
}
|
|
||||||
if (getRequest.storedFields() != null && getRequest.storedFields().length > 0) {
|
|
||||||
params.put("stored_fields", String.join(",", getRequest.storedFields()));
|
|
||||||
}
|
|
||||||
if (getRequest.version() != Versions.MATCH_ANY) {
|
|
||||||
params.put("version", Long.toString(getRequest.version()));
|
|
||||||
}
|
|
||||||
if (getRequest.versionType() != VersionType.INTERNAL) {
|
|
||||||
params.put("version_type", getRequest.versionType().name().toLowerCase(Locale.ROOT));
|
|
||||||
}
|
|
||||||
if (getRequest.fetchSourceContext() != null) {
|
|
||||||
FetchSourceContext fetchSourceContext = getRequest.fetchSourceContext();
|
|
||||||
if (fetchSourceContext.fetchSource() == false) {
|
|
||||||
params.put("_source", Boolean.FALSE.toString());
|
|
||||||
}
|
|
||||||
if (fetchSourceContext.includes() != null && fetchSourceContext.includes().length > 0) {
|
|
||||||
params.put("_source_include", String.join(",", fetchSourceContext.includes()));
|
|
||||||
}
|
|
||||||
if (fetchSourceContext.excludes() != null && fetchSourceContext.excludes().length > 0) {
|
|
||||||
params.put("_source_exclude", String.join(",", fetchSourceContext.excludes()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Collections.unmodifiableMap(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Map<String, String> deleteParams(DeleteRequest deleteRequest) {
|
|
||||||
Map<String, String> params = new HashMap<>();
|
Map<String, String> params = new HashMap<>();
|
||||||
putParam("routing", deleteRequest.routing(), params);
|
putParam("routing", deleteRequest.routing(), params);
|
||||||
putParam("parent", deleteRequest.parent(), params);
|
putParam("parent", deleteRequest.parent(), params);
|
||||||
|
@ -118,21 +132,140 @@ final class Request {
|
||||||
params.put("version_type", deleteRequest.versionType().name().toLowerCase(Locale.ROOT));
|
params.put("version_type", deleteRequest.versionType().name().toLowerCase(Locale.ROOT));
|
||||||
}
|
}
|
||||||
return Collections.unmodifiableMap(params);
|
return Collections.unmodifiableMap(params);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getEndpoint(GetRequest getRequest) {
|
/**
|
||||||
StringJoiner pathJoiner = new StringJoiner("/", "/", "");
|
* Utility method to build request's endpoint.
|
||||||
return pathJoiner.add(getRequest.index()).add(getRequest.type()).add(getRequest.id()).toString();
|
*/
|
||||||
|
static String endpoint(String... parts) {
|
||||||
|
if (parts == null || parts.length == 0) {
|
||||||
|
return DELIMITER;
|
||||||
|
|
||||||
|
StringJoiner joiner = new StringJoiner(DELIMITER, DELIMITER, "");
|
||||||
|
for (String part : parts) {
|
||||||
|
if (part != null) {
|
||||||
|
joiner.add(part);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return joiner.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String deleteEndpoint(DeleteRequest deleteRequest) {
|
/**
|
||||||
StringJoiner pathJoiner = new StringJoiner("/", "/", "");
|
* Utility class to build request's parameters map and centralize all parameter names.
|
||||||
return pathJoiner.add(deleteRequest.index()).add(deleteRequest.type()).add(deleteRequest.id()).toString();
|
*/
|
||||||
|
static class Params {
|
||||||
|
private final Map<String, String> params = new HashMap<>();
|
||||||
|
|
||||||
|
private Params() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void putParam(String key, String value, Map<String, String> params) {
|
Params putParam(String key, String value) {
|
||||||
if (Strings.hasLength(value)) {
|
if (Strings.hasLength(value)) {
|
||||||
params.put(key, value);
|
if (params.putIfAbsent(key, value) != null) {
|
||||||
|
throw new IllegalArgumentException("Request parameter [" + key + "] is already registered");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Params putParam(String key, TimeValue value) {
|
||||||
|
if (value != null) {
|
||||||
|
return putParam(key, value.getStringRep());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Params withFetchSourceContext(FetchSourceContext fetchSourceContext) {
|
||||||
|
if (fetchSourceContext != null) {
|
||||||
|
if (fetchSourceContext.fetchSource() == false) {
|
||||||
|
putParam("_source", Boolean.FALSE.toString());
|
||||||
|
}
|
||||||
|
if (fetchSourceContext.includes() != null && fetchSourceContext.includes().length > 0) {
|
||||||
|
putParam("_source_include", String.join(",", fetchSourceContext.includes()));
|
||||||
|
}
|
||||||
|
if (fetchSourceContext.excludes() != null && fetchSourceContext.excludes().length > 0) {
|
||||||
|
putParam("_source_exclude", String.join(",", fetchSourceContext.excludes()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Params withParent(String parent) {
|
||||||
|
return putParam("parent", parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
Params withPipeline(String pipeline) {
|
||||||
|
return putParam("pipeline", pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
Params withPreference(String preference) {
|
||||||
|
return putParam("preference", preference);
|
||||||
|
}
|
||||||
|
|
||||||
|
Params withRealtime(boolean realtime) {
|
||||||
|
if (realtime == false) {
|
||||||
|
return putParam("realtime", Boolean.FALSE.toString());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Params withRefresh(boolean refresh) {
|
||||||
|
if (refresh) {
|
||||||
|
return withRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Params withRefreshPolicy(WriteRequest.RefreshPolicy refreshPolicy) {
|
||||||
|
if (refreshPolicy != WriteRequest.RefreshPolicy.NONE) {
|
||||||
|
putParam("refresh", refreshPolicy.getValue());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Params withRouting(String routing) {
|
||||||
|
return putParam("routing", routing);
|
||||||
|
}
|
||||||
|
|
||||||
|
Params withStoredFields(String[] storedFields) {
|
||||||
|
if (storedFields != null && storedFields.length > 0) {
|
||||||
|
return putParam("stored_fields", String.join(",", storedFields));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Params withTimeout(TimeValue timeout) {
|
||||||
|
return putParam("timeout", timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
Params withVersion(long version) {
|
||||||
|
if (version != Versions.MATCH_ANY) {
|
||||||
|
return putParam("version", Long.toString(version));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Params withVersionType(VersionType versionType) {
|
||||||
|
if (versionType != VersionType.INTERNAL) {
|
||||||
|
return putParam("version_type", versionType.name().toLowerCase(Locale.ROOT));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Params withWaitForActiveShards(ActiveShardCount activeShardCount) {
|
||||||
|
if (activeShardCount != null && activeShardCount != ActiveShardCount.DEFAULT) {
|
||||||
|
return putParam("wait_for_active_shards", activeShardCount.toString().toLowerCase(Locale.ROOT));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> getParams() {
|
||||||
|
return Collections.unmodifiableMap(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Params builder() {
|
||||||
|
return new Params();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,8 @@ import org.elasticsearch.action.delete.DeleteRequest;
|
||||||
import org.elasticsearch.action.delete.DeleteResponse;
|
import org.elasticsearch.action.delete.DeleteResponse;
|
||||||
import org.elasticsearch.action.get.GetRequest;
|
import org.elasticsearch.action.get.GetRequest;
|
||||||
import org.elasticsearch.action.get.GetResponse;
|
import org.elasticsearch.action.get.GetResponse;
|
||||||
|
import org.elasticsearch.action.index.IndexRequest;
|
||||||
|
import org.elasticsearch.action.index.IndexResponse;
|
||||||
import org.elasticsearch.action.main.MainRequest;
|
import org.elasticsearch.action.main.MainRequest;
|
||||||
import org.elasticsearch.common.CheckedFunction;
|
import org.elasticsearch.common.CheckedFunction;
|
||||||
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
||||||
|
@ -44,6 +46,9 @@ import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import static java.util.Collections.emptySet;
|
||||||
|
import static java.util.Collections.singleton;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* High level REST client that wraps an instance of the low level {@link RestClient} and allows to build requests and read responses.
|
* High level REST client that wraps an instance of the low level {@link RestClient} and allows to build requests and read responses.
|
||||||
* The provided {@link RestClient} is externally built and closed.
|
* The provided {@link RestClient} is externally built and closed.
|
||||||
|
@ -61,37 +66,61 @@ public class RestHighLevelClient {
|
||||||
*/
|
*/
|
||||||
public boolean ping(Header... headers) throws IOException {
|
public boolean ping(Header... headers) throws IOException {
|
||||||
return performRequest(new MainRequest(), (request) -> Request.ping(), RestHighLevelClient::convertExistsResponse,
|
return performRequest(new MainRequest(), (request) -> Request.ping(), RestHighLevelClient::convertExistsResponse,
|
||||||
Collections.emptySet(), headers);
|
emptySet(), headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a document by id using the get api
|
* Retrieves a document by id using the Get API
|
||||||
|
*
|
||||||
|
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-get.html">Get API on elastic.co</a>
|
||||||
*/
|
*/
|
||||||
public GetResponse get(GetRequest getRequest, Header... headers) throws IOException {
|
public GetResponse get(GetRequest getRequest, Header... headers) throws IOException {
|
||||||
return performRequestAndParseEntity(getRequest, Request::get, GetResponse::fromXContent, Collections.singleton(404), headers);
|
return performRequestAndParseEntity(getRequest, Request::get, GetResponse::fromXContent, singleton(404), headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asynchronously retrieves a document by id using the get api
|
* Asynchronously retrieves a document by id using the Get API
|
||||||
|
*
|
||||||
|
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-get.html">Get API on elastic.co</a>
|
||||||
*/
|
*/
|
||||||
public void getAsync(GetRequest getRequest, ActionListener<GetResponse> listener, Header... headers) {
|
public void getAsync(GetRequest getRequest, ActionListener<GetResponse> listener, Header... headers) {
|
||||||
performRequestAsyncAndParseEntity(getRequest, Request::get, GetResponse::fromXContent, listener,
|
performRequestAsyncAndParseEntity(getRequest, Request::get, GetResponse::fromXContent, listener, singleton(404), headers);
|
||||||
Collections.singleton(404), headers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks for the existence of a document. Returns true if it exists, false otherwise
|
* Checks for the existence of a document. Returns true if it exists, false otherwise
|
||||||
|
*
|
||||||
|
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-get.html">Get API on elastic.co</a>
|
||||||
*/
|
*/
|
||||||
public boolean exists(GetRequest getRequest, Header... headers) throws IOException {
|
public boolean exists(GetRequest getRequest, Header... headers) throws IOException {
|
||||||
return performRequest(getRequest, Request::exists, RestHighLevelClient::convertExistsResponse, Collections.emptySet(), headers);
|
return performRequest(getRequest, Request::exists, RestHighLevelClient::convertExistsResponse, emptySet(), headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asynchronously checks for the existence of a document. Returns true if it exists, false otherwise
|
* Asynchronously checks for the existence of a document. Returns true if it exists, false otherwise
|
||||||
|
*
|
||||||
|
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-get.html">Get API on elastic.co</a>
|
||||||
*/
|
*/
|
||||||
public void existsAsync(GetRequest getRequest, ActionListener<Boolean> listener, Header... headers) {
|
public void existsAsync(GetRequest getRequest, ActionListener<Boolean> listener, Header... headers) {
|
||||||
performRequestAsync(getRequest, Request::exists, RestHighLevelClient::convertExistsResponse, listener,
|
performRequestAsync(getRequest, Request::exists, RestHighLevelClient::convertExistsResponse, listener, emptySet(), headers);
|
||||||
Collections.emptySet(), headers);
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Index a document using the Index API
|
||||||
|
*
|
||||||
|
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-index_.html">Index API on elastic.co</a>
|
||||||
|
*/
|
||||||
|
public IndexResponse index(IndexRequest indexRequest, Header... headers) throws IOException {
|
||||||
|
return performRequestAndParseEntity(indexRequest, Request::index, IndexResponse::fromXContent, emptySet(), headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asynchronously index a document using the Index API
|
||||||
|
*
|
||||||
|
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-index_.html">Index API on elastic.co</a>
|
||||||
|
*/
|
||||||
|
public void indexAsync(IndexRequest indexRequest, ActionListener<IndexResponse> listener, Header... headers) {
|
||||||
|
performRequestAsyncAndParseEntity(indexRequest, Request::index, IndexResponse::fromXContent, listener, emptySet(), headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,12 +22,19 @@ package org.elasticsearch.client;
|
||||||
import org.apache.http.entity.ContentType;
|
import org.apache.http.entity.ContentType;
|
||||||
import org.apache.http.entity.StringEntity;
|
import org.apache.http.entity.StringEntity;
|
||||||
import org.elasticsearch.ElasticsearchException;
|
import org.elasticsearch.ElasticsearchException;
|
||||||
|
import org.elasticsearch.action.DocWriteRequest;
|
||||||
import org.elasticsearch.action.DocWriteResponse;
|
import org.elasticsearch.action.DocWriteResponse;
|
||||||
import org.elasticsearch.action.delete.DeleteRequest;
|
import org.elasticsearch.action.delete.DeleteRequest;
|
||||||
import org.elasticsearch.action.delete.DeleteResponse;
|
import org.elasticsearch.action.delete.DeleteResponse;
|
||||||
|
import org.elasticsearch.ElasticsearchStatusException;
|
||||||
import org.elasticsearch.action.get.GetRequest;
|
import org.elasticsearch.action.get.GetRequest;
|
||||||
import org.elasticsearch.action.get.GetResponse;
|
import org.elasticsearch.action.get.GetResponse;
|
||||||
|
import org.elasticsearch.action.index.IndexRequest;
|
||||||
|
import org.elasticsearch.action.index.IndexResponse;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentType;
|
||||||
|
import org.elasticsearch.index.VersionType;
|
||||||
import org.elasticsearch.rest.RestStatus;
|
import org.elasticsearch.rest.RestStatus;
|
||||||
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
||||||
|
|
||||||
|
@ -145,6 +152,122 @@ public class CrudIT extends ESRestHighLevelClientTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testIndex() throws IOException {
|
||||||
|
final XContentType xContentType = randomFrom(XContentType.values());
|
||||||
|
{
|
||||||
|
IndexRequest indexRequest = new IndexRequest("index", "type");
|
||||||
|
indexRequest.source(XContentBuilder.builder(xContentType.xContent()).startObject().field("test", "test").endObject());
|
||||||
|
|
||||||
|
IndexResponse indexResponse = execute(indexRequest, highLevelClient()::index, highLevelClient()::indexAsync);
|
||||||
|
assertEquals(RestStatus.CREATED, indexResponse.status());
|
||||||
|
assertEquals(DocWriteResponse.Result.CREATED, indexResponse.getResult());
|
||||||
|
assertEquals("index", indexResponse.getIndex());
|
||||||
|
assertEquals("type", indexResponse.getType());
|
||||||
|
assertTrue(Strings.hasLength(indexResponse.getId()));
|
||||||
|
assertEquals(1L, indexResponse.getVersion());
|
||||||
|
assertNotNull(indexResponse.getShardId());
|
||||||
|
assertEquals(-1, indexResponse.getShardId().getId());
|
||||||
|
assertEquals("index", indexResponse.getShardId().getIndexName());
|
||||||
|
assertEquals("index", indexResponse.getShardId().getIndex().getName());
|
||||||
|
assertEquals("_na_", indexResponse.getShardId().getIndex().getUUID());
|
||||||
|
assertNotNull(indexResponse.getShardInfo());
|
||||||
|
assertEquals(0, indexResponse.getShardInfo().getFailed());
|
||||||
|
assertTrue(indexResponse.getShardInfo().getSuccessful() > 0);
|
||||||
|
assertTrue(indexResponse.getShardInfo().getTotal() > 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
IndexRequest indexRequest = new IndexRequest("index", "type", "id");
|
||||||
|
indexRequest.source(XContentBuilder.builder(xContentType.xContent()).startObject().field("version", 1).endObject());
|
||||||
|
|
||||||
|
IndexResponse indexResponse = execute(indexRequest, highLevelClient()::index, highLevelClient()::indexAsync);
|
||||||
|
assertEquals(RestStatus.CREATED, indexResponse.status());
|
||||||
|
assertEquals("index", indexResponse.getIndex());
|
||||||
|
assertEquals("type", indexResponse.getType());
|
||||||
|
assertEquals("id", indexResponse.getId());
|
||||||
|
assertEquals(1L, indexResponse.getVersion());
|
||||||
|
|
||||||
|
indexRequest = new IndexRequest("index", "type", "id");
|
||||||
|
indexRequest.source(XContentBuilder.builder(xContentType.xContent()).startObject().field("version", 2).endObject());
|
||||||
|
|
||||||
|
indexResponse = execute(indexRequest, highLevelClient()::index, highLevelClient()::indexAsync);
|
||||||
|
assertEquals(RestStatus.OK, indexResponse.status());
|
||||||
|
assertEquals("index", indexResponse.getIndex());
|
||||||
|
assertEquals("type", indexResponse.getType());
|
||||||
|
assertEquals("id", indexResponse.getId());
|
||||||
|
assertEquals(2L, indexResponse.getVersion());
|
||||||
|
|
||||||
|
ElasticsearchStatusException exception = expectThrows(ElasticsearchStatusException.class, () -> {
|
||||||
|
IndexRequest wrongRequest = new IndexRequest("index", "type", "id");
|
||||||
|
wrongRequest.source(XContentBuilder.builder(xContentType.xContent()).startObject().field("field", "test").endObject());
|
||||||
|
wrongRequest.version(5L);
|
||||||
|
|
||||||
|
execute(wrongRequest, highLevelClient()::index, highLevelClient()::indexAsync);
|
||||||
|
});
|
||||||
|
assertEquals(RestStatus.CONFLICT, exception.status());
|
||||||
|
assertEquals("Elasticsearch exception [type=version_conflict_engine_exception, reason=[type][id]: " +
|
||||||
|
"version conflict, current version [2] is different than the one provided [5]]", exception.getMessage());
|
||||||
|
assertEquals("index", exception.getMetadata("es.index").get(0));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
ElasticsearchStatusException exception = expectThrows(ElasticsearchStatusException.class, () -> {
|
||||||
|
IndexRequest indexRequest = new IndexRequest("index", "type", "missing_parent");
|
||||||
|
indexRequest.source(XContentBuilder.builder(xContentType.xContent()).startObject().field("field", "test").endObject());
|
||||||
|
indexRequest.parent("missing");
|
||||||
|
|
||||||
|
execute(indexRequest, highLevelClient()::index, highLevelClient()::indexAsync);
|
||||||
|
});
|
||||||
|
|
||||||
|
assertEquals(RestStatus.BAD_REQUEST, exception.status());
|
||||||
|
assertEquals("Elasticsearch exception [type=illegal_argument_exception, " +
|
||||||
|
"reason=Can't specify parent if no parent field has been configured]", exception.getMessage());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
ElasticsearchStatusException exception = expectThrows(ElasticsearchStatusException.class, () -> {
|
||||||
|
IndexRequest indexRequest = new IndexRequest("index", "type", "missing_pipeline");
|
||||||
|
indexRequest.source(XContentBuilder.builder(xContentType.xContent()).startObject().field("field", "test").endObject());
|
||||||
|
indexRequest.setPipeline("missing");
|
||||||
|
|
||||||
|
execute(indexRequest, highLevelClient()::index, highLevelClient()::indexAsync);
|
||||||
|
});
|
||||||
|
|
||||||
|
assertEquals(RestStatus.BAD_REQUEST, exception.status());
|
||||||
|
assertEquals("Elasticsearch exception [type=illegal_argument_exception, " +
|
||||||
|
"reason=pipeline with id [missing] does not exist]", exception.getMessage());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
IndexRequest indexRequest = new IndexRequest("index", "type", "external_version_type");
|
||||||
|
indexRequest.source(XContentBuilder.builder(xContentType.xContent()).startObject().field("field", "test").endObject());
|
||||||
|
indexRequest.version(12L);
|
||||||
|
indexRequest.versionType(VersionType.EXTERNAL);
|
||||||
|
|
||||||
|
IndexResponse indexResponse = execute(indexRequest, highLevelClient()::index, highLevelClient()::indexAsync);
|
||||||
|
assertEquals(RestStatus.CREATED, indexResponse.status());
|
||||||
|
assertEquals("index", indexResponse.getIndex());
|
||||||
|
assertEquals("type", indexResponse.getType());
|
||||||
|
assertEquals("external_version_type", indexResponse.getId());
|
||||||
|
assertEquals(12L, indexResponse.getVersion());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
final IndexRequest indexRequest = new IndexRequest("index", "type", "with_create_op_type");
|
||||||
|
indexRequest.source(XContentBuilder.builder(xContentType.xContent()).startObject().field("field", "test").endObject());
|
||||||
|
indexRequest.opType(DocWriteRequest.OpType.CREATE);
|
||||||
|
|
||||||
|
IndexResponse indexResponse = execute(indexRequest, highLevelClient()::index, highLevelClient()::indexAsync);
|
||||||
|
assertEquals(RestStatus.CREATED, indexResponse.status());
|
||||||
|
assertEquals("index", indexResponse.getIndex());
|
||||||
|
assertEquals("type", indexResponse.getType());
|
||||||
|
assertEquals("with_create_op_type", indexResponse.getId());
|
||||||
|
|
||||||
|
ElasticsearchStatusException exception = expectThrows(ElasticsearchStatusException.class, () -> {
|
||||||
|
execute(indexRequest, highLevelClient()::index, highLevelClient()::indexAsync);
|
||||||
|
});
|
||||||
|
|
||||||
|
assertEquals(RestStatus.CONFLICT, exception.status());
|
||||||
|
assertEquals("Elasticsearch exception [type=version_conflict_engine_exception, reason=[type][with_create_op_type]: " +
|
||||||
|
"version conflict, document already exists (current version [1])]", exception.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void testDelete() throws IOException {
|
public void testDelete() throws IOException {
|
||||||
{
|
{
|
||||||
DeleteRequest deleteRequest = new DeleteRequest("index", "type", "does_not_exist");
|
DeleteRequest deleteRequest = new DeleteRequest("index", "type", "does_not_exist");
|
||||||
|
|
|
@ -19,12 +19,23 @@
|
||||||
|
|
||||||
package org.elasticsearch.client;
|
package org.elasticsearch.client;
|
||||||
|
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.entity.ByteArrayEntity;
|
||||||
|
import org.elasticsearch.action.DocWriteRequest;
|
||||||
import org.elasticsearch.action.get.GetRequest;
|
import org.elasticsearch.action.get.GetRequest;
|
||||||
|
import org.elasticsearch.action.index.IndexRequest;
|
||||||
|
import org.elasticsearch.action.support.WriteRequest;
|
||||||
|
import org.elasticsearch.action.support.replication.ReplicationRequest;
|
||||||
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.lucene.uid.Versions;
|
import org.elasticsearch.common.lucene.uid.Versions;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentType;
|
||||||
import org.elasticsearch.index.VersionType;
|
import org.elasticsearch.index.VersionType;
|
||||||
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -155,4 +166,145 @@ public class RequestTests extends ESTestCase {
|
||||||
assertNull(request.entity);
|
assertNull(request.entity);
|
||||||
assertEquals(method, request.method);
|
assertEquals(method, request.method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testIndex() throws IOException {
|
||||||
|
String index = randomAsciiOfLengthBetween(3, 10);
|
||||||
|
String type = randomAsciiOfLengthBetween(3, 10);
|
||||||
|
IndexRequest indexRequest = new IndexRequest(index, type);
|
||||||
|
|
||||||
|
String id = randomBoolean() ? randomAsciiOfLengthBetween(3, 10) : null;
|
||||||
|
indexRequest.id(id);
|
||||||
|
|
||||||
|
Map<String, String> expectedParams = new HashMap<>();
|
||||||
|
|
||||||
|
String method = "POST";
|
||||||
|
if (id != null) {
|
||||||
|
method = "PUT";
|
||||||
|
if (randomBoolean()) {
|
||||||
|
indexRequest.opType(DocWriteRequest.OpType.CREATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frequently()) {
|
||||||
|
if (randomBoolean()) {
|
||||||
|
String routing = randomAsciiOfLengthBetween(3, 10);
|
||||||
|
indexRequest.routing(routing);
|
||||||
|
expectedParams.put("routing", routing);
|
||||||
|
}
|
||||||
|
if (randomBoolean()) {
|
||||||
|
String parent = randomAsciiOfLengthBetween(3, 10);
|
||||||
|
indexRequest.parent(parent);
|
||||||
|
expectedParams.put("parent", parent);
|
||||||
|
}
|
||||||
|
if (randomBoolean()) {
|
||||||
|
String pipeline = randomAsciiOfLengthBetween(3, 10);
|
||||||
|
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());
|
||||||
|
int nbFields = randomIntBetween(0, 10);
|
||||||
|
try (XContentBuilder builder = XContentBuilder.builder(xContentType.xContent())) {
|
||||||
|
builder.startObject();
|
||||||
|
for (int i = 0; i < nbFields; i++) {
|
||||||
|
builder.field("field_" + i, i);
|
||||||
|
}
|
||||||
|
builder.endObject();
|
||||||
|
indexRequest.source(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
Request request = Request.index(indexRequest);
|
||||||
|
if (indexRequest.opType() == DocWriteRequest.OpType.CREATE) {
|
||||||
|
assertEquals("/" + index + "/" + type + "/" + id + "/_create", request.endpoint);
|
||||||
|
} else if (id != null) {
|
||||||
|
assertEquals("/" + index + "/" + type + "/" + id, request.endpoint);
|
||||||
|
} else {
|
||||||
|
assertEquals("/" + index + "/" + type, request.endpoint);
|
||||||
|
}
|
||||||
|
assertEquals(expectedParams, request.params);
|
||||||
|
assertEquals(method, request.method);
|
||||||
|
|
||||||
|
HttpEntity entity = request.entity;
|
||||||
|
assertNotNull(entity);
|
||||||
|
assertTrue(entity instanceof ByteArrayEntity);
|
||||||
|
|
||||||
|
try (XContentParser parser = createParser(xContentType.xContent(), entity.getContent())) {
|
||||||
|
assertEquals(nbFields, parser.map().size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testParams() {
|
||||||
|
final int nbParams = randomIntBetween(0, 10);
|
||||||
|
Request.Params params = Request.Params.builder();
|
||||||
|
Map<String, String> expectedParams = new HashMap<>();
|
||||||
|
for (int i = 0; i < nbParams; i++) {
|
||||||
|
String paramName = "p_" + i;
|
||||||
|
String paramValue = randomAsciiOfLength(5);
|
||||||
|
params.putParam(paramName, paramValue);
|
||||||
|
expectedParams.put(paramName, paramValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, String> requestParams = params.getParams();
|
||||||
|
assertEquals(nbParams, requestParams.size());
|
||||||
|
assertEquals(expectedParams, requestParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testParamsNoDuplicates() {
|
||||||
|
Request.Params params = Request.Params.builder();
|
||||||
|
params.putParam("test", "1");
|
||||||
|
|
||||||
|
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> params.putParam("test", "2"));
|
||||||
|
assertEquals("Request parameter [test] is already registered", e.getMessage());
|
||||||
|
|
||||||
|
Map<String, String> requestParams = params.getParams();
|
||||||
|
assertEquals(1L, requestParams.size());
|
||||||
|
assertEquals("1", requestParams.values().iterator().next());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testEndpoint() {
|
||||||
|
assertEquals("/", Request.endpoint());
|
||||||
|
assertEquals("/", Request.endpoint(Strings.EMPTY_ARRAY));
|
||||||
|
assertEquals("/", Request.endpoint(""));
|
||||||
|
assertEquals("/a/b", Request.endpoint("a", "b"));
|
||||||
|
assertEquals("/a/b/_create", Request.endpoint("a", "b", "_create"));
|
||||||
|
assertEquals("/a/b/c/_create", Request.endpoint("a", "b", "c", "_create"));
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -46,7 +46,7 @@ setup:
|
||||||
"field collapsing":
|
"field collapsing":
|
||||||
|
|
||||||
- skip:
|
- skip:
|
||||||
version: " - 5.99.99"
|
version: " - 5.2.99"
|
||||||
reason: this uses a new API that has been added in 5.3
|
reason: this uses a new API that has been added in 5.3
|
||||||
|
|
||||||
- do:
|
- do:
|
||||||
|
@ -82,7 +82,7 @@ setup:
|
||||||
"field collapsing and from":
|
"field collapsing and from":
|
||||||
|
|
||||||
- skip:
|
- skip:
|
||||||
version: " - 5.99.99"
|
version: " - 5.2.99"
|
||||||
reason: this uses a new API that has been added in 5.3
|
reason: this uses a new API that has been added in 5.3
|
||||||
|
|
||||||
- do:
|
- do:
|
||||||
|
@ -107,7 +107,7 @@ setup:
|
||||||
"field collapsing and inner_hits":
|
"field collapsing and inner_hits":
|
||||||
|
|
||||||
- skip:
|
- skip:
|
||||||
version: " - 5.99.99"
|
version: " - 5.2.99"
|
||||||
reason: this uses a new API that has been added in 5.3
|
reason: this uses a new API that has been added in 5.3
|
||||||
|
|
||||||
- do:
|
- do:
|
||||||
|
@ -152,7 +152,7 @@ setup:
|
||||||
"field collapsing, inner_hits and maxConcurrentGroupRequests":
|
"field collapsing, inner_hits and maxConcurrentGroupRequests":
|
||||||
|
|
||||||
- skip:
|
- skip:
|
||||||
version: " - 5.99.99"
|
version: " - 5.2.99"
|
||||||
reason: this uses a new API that has been added in 5.3
|
reason: this uses a new API that has been added in 5.3
|
||||||
|
|
||||||
- do:
|
- do:
|
||||||
|
@ -197,7 +197,7 @@ setup:
|
||||||
"field collapsing and scroll":
|
"field collapsing and scroll":
|
||||||
|
|
||||||
- skip:
|
- skip:
|
||||||
version: " - 5.99.99"
|
version: " - 5.2.99"
|
||||||
reason: this uses a new API that has been added in 5.3
|
reason: this uses a new API that has been added in 5.3
|
||||||
|
|
||||||
- do:
|
- do:
|
||||||
|
@ -213,7 +213,7 @@ setup:
|
||||||
"field collapsing and search_after":
|
"field collapsing and search_after":
|
||||||
|
|
||||||
- skip:
|
- skip:
|
||||||
version: " - 5.99.99"
|
version: " - 5.2.99"
|
||||||
reason: this uses a new API that has been added in 5.3
|
reason: this uses a new API that has been added in 5.3
|
||||||
|
|
||||||
- do:
|
- do:
|
||||||
|
@ -230,7 +230,7 @@ setup:
|
||||||
"field collapsing and rescore":
|
"field collapsing and rescore":
|
||||||
|
|
||||||
- skip:
|
- skip:
|
||||||
version: " - 5.99.99"
|
version: " - 5.2.99"
|
||||||
reason: this uses a new API that has been added in 5.3
|
reason: this uses a new API that has been added in 5.3
|
||||||
|
|
||||||
- do:
|
- do:
|
||||||
|
|
Loading…
Reference in New Issue