Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Create Index support to high-level REST client #27351

Merged
merged 9 commits into from
Dec 7, 2017
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

import org.apache.http.Header;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;

Expand All @@ -29,7 +31,7 @@

/**
* A wrapper for the {@link RestHighLevelClient} that provides methods for accessing the Indices API.
*
* <p>
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices.html">Indices API on elastic.co</a>
*/
public final class IndicesClient {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry I got confused with my own previous changes, let's leave this class final, then the final modifier is not necessary on each method. My bad.

Expand Down Expand Up @@ -60,4 +62,26 @@ public void deleteIndexAsync(DeleteIndexRequest deleteIndexRequest, ActionListen
restHighLevelClient.performRequestAsyncAndParseEntity(deleteIndexRequest, Request::deleteIndex, DeleteIndexResponse::fromXContent,
listener, Collections.emptySet(), headers);
}

/**
* Creates an index using the Create Index API
* <p>
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-create-index.html">
* Create Index API on elastic.co</a>
*/
public CreateIndexResponse createIndex(CreateIndexRequest createIndexRequest, Header... headers) throws IOException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you make it final please?

return restHighLevelClient.performRequestAndParseEntity(createIndexRequest, Request::createIndex, CreateIndexResponse::fromXContent,
Collections.emptySet(), headers);
}

/**
* Asynchronously creates an index using the Create Index API
* <p>
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-create-index.html">
* Create Index API on elastic.co</a>
*/
public void createIndexAsync(CreateIndexRequest createIndexRequest, ActionListener<CreateIndexResponse> listener, Header... headers) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you make it final please?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for the delete index methods, I suppose?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes please

restHighLevelClient.performRequestAsyncAndParseEntity(createIndexRequest, Request::createIndex, CreateIndexResponse::fromXContent,
listener, Collections.emptySet(), headers);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.apache.http.entity.ContentType;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
Expand Down Expand Up @@ -135,6 +136,18 @@ static Request deleteIndex(DeleteIndexRequest deleteIndexRequest) {
return new Request(HttpDelete.METHOD_NAME, endpoint, parameters.getParams(), null);
}

static Request createIndex(CreateIndexRequest createIndexRequest) throws IOException {
String endpoint = endpoint(createIndexRequest.indices(), Strings.EMPTY_ARRAY, "");

Params parameters = Params.builder();
parameters.withTimeout(createIndexRequest.timeout());
parameters.withMasterTimeout(createIndexRequest.masterNodeTimeout());
parameters.withWaitForActiveShards(createIndexRequest.waitForActiveShards());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we also support a parameter called updateAllTypes here.


HttpEntity entity = createEntity(createIndexRequest, REQUEST_BODY_CONTENT_TYPE);
return new Request(HttpPut.METHOD_NAME, endpoint, parameters.getParams(), entity);
}

static Request info() {
return new Request(HttpGet.METHOD_NAME, "/", Collections.emptyMap(), null);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,66 @@
package org.elasticsearch.client;

import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.rest.RestStatus;

import java.io.IOException;

import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_REPLICAS;

public class IndicesClientIT extends ESRestHighLevelClientTestCase {

public void testCreateIndex() throws IOException {
{
// Create index
String indexName = "plain_index";
assertFalse(indexExists(indexName));

CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);

CreateIndexResponse createIndexResponse =
execute(createIndexRequest, highLevelClient().indices()::createIndex, highLevelClient().indices()::createIndexAsync);
assertTrue(createIndexResponse.isAcknowledged());

assertTrue(indexExists(indexName));
}
{
// Create index with mappings, aliases and settings
String indexName = "rich_index";
assertFalse(indexExists(indexName));

CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);

Alias alias = new Alias("alias_name");
alias.filter("\"term\":{\"year\":2016}");
alias.routing("1");
createIndexRequest.alias(alias);

Settings.Builder settings = Settings.builder();
settings.put(SETTING_NUMBER_OF_REPLICAS, 2);
createIndexRequest.settings(settings);

XContentBuilder mappingBuilder = JsonXContent.contentBuilder();
mappingBuilder.startObject().startObject("properties").startObject("field");
mappingBuilder.field("type", "text");
mappingBuilder.endObject().endObject().endObject();
createIndexRequest.mapping("type_name", mappingBuilder);

CreateIndexResponse createIndexResponse =
execute(createIndexRequest, highLevelClient().indices()::createIndex, highLevelClient().indices()::createIndexAsync);
assertTrue(createIndexResponse.isAcknowledged());

assertTrue(indexExists(indexName));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The checks here could be expanded, to check for the alias, mapping and setting, once Get Index is implemented, I suppose; should I add a TODO?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would you mind using the low-level REST client to check this? You can parse the get index api response into a map and compare it to what you 'd expect?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good shout; alias filter creation was actually failing! Now fixed. ☺

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

}
}

public void testDeleteIndex() throws IOException {
{
// Delete index if exists
Expand Down Expand Up @@ -55,9 +107,9 @@ public void testDeleteIndex() throws IOException {
}

private static void createIndex(String index) throws IOException {
Response response = client().performRequest("PUT", index);
CreateIndexResponse response = highLevelClient().indices().createIndex(new CreateIndexRequest(index));

assertEquals(200, response.getStatusLine().getStatusCode());
assertTrue(response.isAcknowledged());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I wonder if we should leave this method that uses the low-level REST client, given that we call it e.g. when testing delete index, otherwise we end up testing create index also as part of delete index.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would obviously be trivial to revert to using the low-level client here, but I'd be wary of applying that principle later on - e.g., it we're testing Get Alias, it would be a lot more costly to create the test data using the low-level client, rather than the high-level client Create Alias; and so forth.

}

private static boolean indexExists(String index) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkShardRequest;
Expand All @@ -35,6 +36,7 @@
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchScrollRequest;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.support.ActiveShardCount;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.action.support.master.AcknowledgedRequest;
Expand Down Expand Up @@ -245,6 +247,26 @@ private static void getAndExistsTest(Function<GetRequest, Request> requestConver
assertEquals(method, request.getMethod());
}

public void testCreateIndex() throws IOException {
CreateIndexRequest createIndexRequest = new CreateIndexRequest();

String indexName = "index-" + randomAlphaOfLengthBetween(2, 5);

createIndexRequest.index(indexName);

Map<String, String> expectedParams = new HashMap<>();

setRandomTimeout(createIndexRequest::timeout, AcknowledgedRequest.DEFAULT_ACK_TIMEOUT, expectedParams);
setRandomMasterTimeout(createIndexRequest, expectedParams);
setRandomWaitForActiveShards(createIndexRequest::waitForActiveShards, expectedParams);

Request request = Request.createIndex(createIndexRequest);
assertEquals("/" + indexName, request.getEndpoint());
assertEquals(expectedParams, request.getParameters());
assertEquals("PUT", request.getMethod());
assertToXContentBody(createIndexRequest, request.getEntity());
}

public void testDeleteIndex() throws IOException {
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest();

Expand Down Expand Up @@ -399,11 +421,7 @@ public void testUpdate() throws IOException {
expectedParams.put("refresh", refreshPolicy.getValue());
}
}
if (randomBoolean()) {
int waitForActiveShards = randomIntBetween(0, 10);
updateRequest.waitForActiveShards(waitForActiveShards);
expectedParams.put("wait_for_active_shards", String.valueOf(waitForActiveShards));
}
setRandomWaitForActiveShards(updateRequest::waitForActiveShards, expectedParams);
if (randomBoolean()) {
long version = randomLong();
updateRequest.version(version);
Expand Down Expand Up @@ -959,6 +977,14 @@ private static void setRandomMasterTimeout(MasterNodeRequest<?> request, Map<Str
}
}

private static void setRandomWaitForActiveShards(Consumer<Integer> setter, Map<String, String> expectedParams) {
if (randomBoolean()) {
int waitForActiveShards = randomIntBetween(0, 10);
setter.accept(waitForActiveShards);
expectedParams.put("wait_for_active_shards", String.valueOf(waitForActiveShards));
}
}

private static void setRandomRefreshPolicy(ReplicatedWriteRequest<?> request, Map<String, String> expectedParams) {
if (randomBoolean()) {
WriteRequest.RefreshPolicy refreshPolicy = randomFrom(WriteRequest.RefreshPolicy.values());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,18 @@

import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.support.ActiveShardCount;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.ESRestHighLevelClientTestCase;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.RestStatus;

import java.io.IOException;
Expand All @@ -52,23 +57,35 @@ public void testDeleteIndex() throws IOException {
RestHighLevelClient client = highLevelClient();

{
Response createIndexResponse = client().performRequest("PUT", "/posts");
assertEquals(200, createIndexResponse.getStatusLine().getStatusCode());
CreateIndexResponse createIndexResponse = client.indices().createIndex(new CreateIndexRequest("posts"));
assertTrue(createIndexResponse.isAcknowledged());
}

{
// tag::delete-index-request
DeleteIndexRequest request = new DeleteIndexRequest("posts"); // <1>
// end::delete-index-request

// tag::delete-index-request-timeout
request.timeout(TimeValue.timeValueMinutes(2)); // <1>
request.timeout("2m"); // <2>
// end::delete-index-request-timeout
// tag::delete-index-request-masterTimeout
request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1>
request.timeout("1m"); // <2>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this one be masterNodeTimeout too?

// end::delete-index-request-masterTimeout
// tag::delete-index-request-indicesOptions
request.indicesOptions(IndicesOptions.lenientExpandOpen()); // <1>
// end::delete-index-request-indicesOptions

// tag::delete-index-execute
DeleteIndexResponse deleteIndexResponse = client.indices().deleteIndex(request);
// end::delete-index-execute
assertTrue(deleteIndexResponse.isAcknowledged());

// tag::delete-index-response
boolean acknowledged = deleteIndexResponse.isAcknowledged(); // <1>
// end::delete-index-response
assertTrue(acknowledged);

// tag::delete-index-execute-async
client.indices().deleteIndexAsync(request, new ActionListener<DeleteIndexResponse>() {
Expand All @@ -85,26 +102,11 @@ public void onFailure(Exception e) {
// end::delete-index-execute-async
}

{
DeleteIndexRequest request = new DeleteIndexRequest("posts");
// tag::delete-index-request-timeout
request.timeout(TimeValue.timeValueMinutes(2)); // <1>
request.timeout("2m"); // <2>
// end::delete-index-request-timeout
// tag::delete-index-request-masterTimeout
request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1>
request.timeout("1m"); // <2>
// end::delete-index-request-masterTimeout
// tag::delete-index-request-indicesOptions
request.indicesOptions(IndicesOptions.lenientExpandOpen()); // <1>
// end::delete-index-request-indicesOptions
}

{
// tag::delete-index-notfound
try {
DeleteIndexRequest request = new DeleteIndexRequest("does_not_exist");
DeleteIndexResponse deleteIndexResponse = client.indices().deleteIndex(request);
client.indices().deleteIndex(request);
} catch (ElasticsearchException exception) {
if (exception.status() == RestStatus.NOT_FOUND) {
// <1>
Expand All @@ -113,4 +115,79 @@ public void onFailure(Exception e) {
// end::delete-index-notfound
}
}

public void testCreateIndex() throws IOException {
RestHighLevelClient client = highLevelClient();

{
// tag::create-index-request
CreateIndexRequest request = new CreateIndexRequest("twitter"); // <1>
// end::create-index-request

// tag::create-index-request-settings
request.settings(Settings.builder() // <1>
.put("index.number_of_shards", 3)
.put("index.number_of_replicas", 2)
);
// end::create-index-request-settings

// tag::create-index-request-mappings
request.mapping("tweet", // <1>
" {\n" +
" \"tweet\": {\n" +
" \"properties\": {\n" +
" \"message\": {\n" +
" \"type\": \"text\"\n" +
" }\n" +
" }\n" +
" }\n" +
" }", // <2>
XContentType.JSON);
// end::create-index-request-mappings

// tag::create-index-request-aliases
request.alias(
new Alias("twitter_alias") // <1>
);
// end::create-index-request-aliases

// tag::create-index-request-timeout
request.timeout(TimeValue.timeValueMinutes(2)); // <1>
request.timeout("2m"); // <2>
// end::create-index-request-timeout
// tag::create-index-request-masterTimeout
request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1>
request.timeout("1m"); // <2>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this also be masterNodeTimeout?

// end::create-index-request-masterTimeout
// tag::create-index-request-waitForActiveShards
request.waitForActiveShards(2); // <1>
request.waitForActiveShards(ActiveShardCount.DEFAULT); // <2>
// end::create-index-request-waitForActiveShards

// tag::create-index-execute
CreateIndexResponse createIndexResponse = client.indices().createIndex(request);
// end::create-index-execute

// tag::create-index-response
boolean acknowledged = createIndexResponse.isAcknowledged(); // <1>
boolean shardsAcked = createIndexResponse.isShardsAcked(); // <2>
// end::create-index-response
assertTrue(acknowledged);
assertTrue(shardsAcked);

// tag::create-index-execute-async
client.indices().createIndexAsync(request, new ActionListener<CreateIndexResponse>() {
@Override
public void onResponse(CreateIndexResponse createIndexResponse) {
// <1>
}

@Override
public void onFailure(Exception e) {
// <2>
}
});
// end::create-index-execute-async
}
}
}
Loading