REST high-level client: add support for split and shrink index API (#28425)

Relates to #27205
This commit is contained in:
Luca Cavanna 2018-02-01 16:37:01 +01:00 committed by GitHub
parent d37c59d9dd
commit d860971572
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 996 additions and 251 deletions

View File

@ -21,11 +21,11 @@ package org.elasticsearch.client;
import org.apache.http.Header;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesResponse;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
import org.elasticsearch.action.admin.indices.close.CloseIndexResponse;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesResponse;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
@ -34,6 +34,8 @@ import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
import org.elasticsearch.action.admin.indices.open.OpenIndexResponse;
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
import org.elasticsearch.action.admin.indices.shrink.ResizeResponse;
import java.io.IOException;
@ -208,4 +210,48 @@ public final class IndicesClient {
restHighLevelClient.performRequestAsync(getAliasesRequest, Request::existsAlias, RestHighLevelClient::convertExistsResponse,
listener, emptySet(), headers);
}
/**
* Shrinks an index using the Shrink Index API
* <p>
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-shrink-index.html">
* Shrink Index API on elastic.co</a>
*/
public ResizeResponse shrink(ResizeRequest resizeRequest, Header... headers) throws IOException {
return restHighLevelClient.performRequestAndParseEntity(resizeRequest, Request::shrink, ResizeResponse::fromXContent,
emptySet(), headers);
}
/**
* Asynchronously shrinks an index using the Shrink index API
* <p>
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-shrink-index.html">
* Shrink Index API on elastic.co</a>
*/
public void shrinkAsync(ResizeRequest resizeRequest, ActionListener<ResizeResponse> listener, Header... headers) {
restHighLevelClient.performRequestAsyncAndParseEntity(resizeRequest, Request::shrink, ResizeResponse::fromXContent,
listener, emptySet(), headers);
}
/**
* Splits an index using the Split Index API
* <p>
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-split-index.html">
* Shrink Index API on elastic.co</a>
*/
public ResizeResponse split(ResizeRequest resizeRequest, Header... headers) throws IOException {
return restHighLevelClient.performRequestAndParseEntity(resizeRequest, Request::split, ResizeResponse::fromXContent,
emptySet(), headers);
}
/**
* Asynchronously splits an index using the Split Index API
* <p>
* See <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-split-index.html">
* Split Index API on elastic.co</a>
*/
public void splitAsync(ResizeRequest resizeRequest, ActionListener<ResizeResponse> listener, Header... headers) {
restHighLevelClient.performRequestAsyncAndParseEntity(resizeRequest, Request::split, ResizeResponse::fromXContent,
listener, emptySet(), headers);
}
}

View File

@ -36,6 +36,8 @@ import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
import org.elasticsearch.action.admin.indices.shrink.ResizeType;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
@ -182,12 +184,12 @@ public final class Request {
HttpEntity entity = createEntity(createIndexRequest, REQUEST_BODY_CONTENT_TYPE);
return new Request(HttpPut.METHOD_NAME, endpoint, parameters.getParams(), entity);
}
static Request updateAliases(IndicesAliasesRequest indicesAliasesRequest) throws IOException {
Params parameters = Params.builder();
parameters.withTimeout(indicesAliasesRequest.timeout());
parameters.withMasterTimeout(indicesAliasesRequest.masterNodeTimeout());
HttpEntity entity = createEntity(indicesAliasesRequest, REQUEST_BODY_CONTENT_TYPE);
return new Request(HttpPost.METHOD_NAME, "/_aliases", parameters.getParams(), entity);
}
@ -496,7 +498,31 @@ public final class Request {
HttpEntity entity = null;
entity = createEntity(rankEvalRequest.getRankEvalSpec(), REQUEST_BODY_CONTENT_TYPE);
return new Request(HttpGet.METHOD_NAME, endpoint, Collections.emptyMap(), entity);
}
static Request split(ResizeRequest resizeRequest) throws IOException {
if (resizeRequest.getResizeType() != ResizeType.SPLIT) {
throw new IllegalArgumentException("Wrong resize type [" + resizeRequest.getResizeType() + "] for indices split request");
}
return resize(resizeRequest);
}
static Request shrink(ResizeRequest resizeRequest) throws IOException {
if (resizeRequest.getResizeType() != ResizeType.SHRINK) {
throw new IllegalArgumentException("Wrong resize type [" + resizeRequest.getResizeType() + "] for indices shrink request");
}
return resize(resizeRequest);
}
private static Request resize(ResizeRequest resizeRequest) throws IOException {
Params params = Params.builder();
params.withTimeout(resizeRequest.timeout());
params.withMasterTimeout(resizeRequest.masterNodeTimeout());
params.withWaitForActiveShards(resizeRequest.getTargetIndexRequest().waitForActiveShards());
String endpoint = buildEndpoint(resizeRequest.getSourceIndex(), "_" + resizeRequest.getResizeType().name().toLowerCase(Locale.ROOT),
resizeRequest.getTargetIndexRequest().index());
HttpEntity entity = createEntity(resizeRequest, REQUEST_BODY_CONTENT_TYPE);
return new Request(HttpPut.METHOD_NAME, endpoint, params.getParams(), entity);
}
private static HttpEntity createEntity(ToXContent toXContent, XContentType xContentType) throws IOException {

View File

@ -20,8 +20,6 @@
package org.elasticsearch.client;
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.elasticsearch.ElasticsearchException;
import org.elasticsearch.ElasticsearchStatusException;
@ -40,13 +38,14 @@ import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
import org.elasticsearch.action.admin.indices.open.OpenIndexResponse;
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
import org.elasticsearch.action.admin.indices.shrink.ResizeResponse;
import org.elasticsearch.action.admin.indices.shrink.ResizeType;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.rest.RestStatus;
import java.io.IOException;
@ -59,7 +58,7 @@ import static org.hamcrest.Matchers.not;
public class IndicesClientIT extends ESRestHighLevelClientTestCase {
@SuppressWarnings({ "unchecked", "rawtypes" })
@SuppressWarnings({"unchecked", "rawtypes"})
public void testCreateIndex() throws IOException {
{
// Create index
@ -69,7 +68,7 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase {
CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);
CreateIndexResponse createIndexResponse =
execute(createIndexRequest, highLevelClient().indices()::create, highLevelClient().indices()::createAsync);
execute(createIndexRequest, highLevelClient().indices()::create, highLevelClient().indices()::createAsync);
assertTrue(createIndexResponse.isAcknowledged());
assertTrue(indexExists(indexName));
@ -97,37 +96,30 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase {
createIndexRequest.mapping("type_name", mappingBuilder);
CreateIndexResponse createIndexResponse =
execute(createIndexRequest, highLevelClient().indices()::create, highLevelClient().indices()::createAsync);
execute(createIndexRequest, highLevelClient().indices()::create, highLevelClient().indices()::createAsync);
assertTrue(createIndexResponse.isAcknowledged());
Map<String, Object> indexMetaData = getIndexMetadata(indexName);
Map<String, Object> getIndexResponse = getAsMap(indexName);
assertEquals("2", XContentMapValues.extractValue(indexName + ".settings.index.number_of_replicas", getIndexResponse));
Map<String, Object> settingsData = (Map) indexMetaData.get("settings");
Map<String, Object> indexSettings = (Map) settingsData.get("index");
assertEquals("2", indexSettings.get("number_of_replicas"));
Map<String, Object> aliasesData = (Map) indexMetaData.get("aliases");
Map<String, Object> aliasData = (Map) aliasesData.get("alias_name");
Map<String, Object> aliasData =
(Map<String, Object>)XContentMapValues.extractValue(indexName + ".aliases.alias_name", getIndexResponse);
assertNotNull(aliasData);
assertEquals("1", aliasData.get("index_routing"));
Map<String, Object> filter = (Map) aliasData.get("filter");
Map<String, Object> term = (Map) filter.get("term");
assertEquals(2016, term.get("year"));
Map<String, Object> mappingsData = (Map) indexMetaData.get("mappings");
Map<String, Object> typeData = (Map) mappingsData.get("type_name");
Map<String, Object> properties = (Map) typeData.get("properties");
Map<String, Object> field = (Map) properties.get("field");
assertEquals("text", field.get("type"));
assertEquals("text", XContentMapValues.extractValue(indexName + ".mappings.type_name.properties.field.type", getIndexResponse));
}
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@SuppressWarnings({"unchecked", "rawtypes"})
public void testPutMapping() throws IOException {
{
// Add mappings to index
String indexName = "mapping_index";
createIndex(indexName);
createIndex(indexName, Settings.EMPTY);
PutMappingRequest putMappingRequest = new PutMappingRequest(indexName);
putMappingRequest.type("type_name");
@ -138,16 +130,11 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase {
putMappingRequest.source(mappingBuilder);
PutMappingResponse putMappingResponse =
execute(putMappingRequest, highLevelClient().indices()::putMapping, highLevelClient().indices()::putMappingAsync);
execute(putMappingRequest, highLevelClient().indices()::putMapping, highLevelClient().indices()::putMappingAsync);
assertTrue(putMappingResponse.isAcknowledged());
Map<String, Object> indexMetaData = getIndexMetadata(indexName);
Map<String, Object> mappingsData = (Map) indexMetaData.get("mappings");
Map<String, Object> typeData = (Map) mappingsData.get("type_name");
Map<String, Object> properties = (Map) typeData.get("properties");
Map<String, Object> field = (Map) properties.get("field");
assertEquals("text", field.get("type"));
Map<String, Object> getIndexResponse = getAsMap(indexName);
assertEquals("text", XContentMapValues.extractValue(indexName + ".mappings.type_name.properties.field.type", getIndexResponse));
}
}
@ -155,11 +142,11 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase {
{
// Delete index if exists
String indexName = "test_index";
createIndex(indexName);
createIndex(indexName, Settings.EMPTY);
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(indexName);
DeleteIndexResponse deleteIndexResponse =
execute(deleteIndexRequest, highLevelClient().indices()::delete, highLevelClient().indices()::deleteAsync);
execute(deleteIndexRequest, highLevelClient().indices()::delete, highLevelClient().indices()::deleteAsync);
assertTrue(deleteIndexResponse.isAcknowledged());
assertFalse(indexExists(indexName));
@ -172,7 +159,7 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase {
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(nonExistentIndex);
ElasticsearchException exception = expectThrows(ElasticsearchException.class,
() -> execute(deleteIndexRequest, highLevelClient().indices()::delete, highLevelClient().indices()::deleteAsync));
() -> execute(deleteIndexRequest, highLevelClient().indices()::delete, highLevelClient().indices()::deleteAsync));
assertEquals(RestStatus.NOT_FOUND, exception.status());
}
}
@ -182,7 +169,7 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase {
String index = "index";
String alias = "alias";
createIndex(index);
createIndex(index, Settings.EMPTY);
assertThat(aliasExists(index, alias), equalTo(false));
assertThat(aliasExists(alias), equalTo(false));
@ -242,7 +229,7 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase {
assertThat(exception.getMessage(), equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]"));
assertThat(exception.getMetadata("es.index"), hasItem(nonExistentIndex));
createIndex(index);
createIndex(index, Settings.EMPTY);
IndicesAliasesRequest mixedRequest = new IndicesAliasesRequest();
mixedRequest.addAliasAction(new AliasActions(AliasActions.Type.ADD).indices(index).aliases(alias));
mixedRequest.addAliasAction(new AliasActions(AliasActions.Type.REMOVE).indices(nonExistentIndex).alias(alias));
@ -270,7 +257,7 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase {
public void testOpenExistingIndex() throws IOException {
String index = "index";
createIndex(index);
createIndex(index, Settings.EMPTY);
closeIndex(index);
ResponseException exception = expectThrows(ResponseException.class,
() -> client().performRequest(HttpGet.METHOD_NAME, index + "/_search"));
@ -310,7 +297,7 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase {
public void testCloseExistingIndex() throws IOException {
String index = "index";
createIndex(index);
createIndex(index, Settings.EMPTY);
Response response = client().performRequest(HttpGet.METHOD_NAME, index + "/_search");
assertThat(response.getStatusLine().getStatusCode(), equalTo(RestStatus.OK.getStatus()));
@ -339,7 +326,7 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase {
GetAliasesRequest getAliasesRequest = new GetAliasesRequest("alias");
assertFalse(execute(getAliasesRequest, highLevelClient().indices()::existsAlias, highLevelClient().indices()::existsAliasAsync));
createIndex("index");
createIndex("index", Settings.EMPTY);
client().performRequest(HttpPut.METHOD_NAME, "/index/_alias/alias");
assertTrue(execute(getAliasesRequest, highLevelClient().indices()::existsAlias, highLevelClient().indices()::existsAliasAsync));
@ -351,64 +338,49 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase {
assertFalse(execute(getAliasesRequest2, highLevelClient().indices()::existsAlias, highLevelClient().indices()::existsAliasAsync));
}
private static void createIndex(String index) throws IOException {
Response response = client().performRequest(HttpPut.METHOD_NAME, index);
assertThat(response.getStatusLine().getStatusCode(), equalTo(RestStatus.OK.getStatus()));
@SuppressWarnings("unchecked")
public void testShrink() throws IOException {
Map<String, Object> nodes = getAsMap("_nodes");
String firstNode = ((Map<String, Object>) nodes.get("nodes")).keySet().iterator().next();
createIndex("source", Settings.builder().put("index.number_of_shards", 4).put("index.number_of_replicas", 0).build());
updateIndexSettings("source", Settings.builder().put("index.routing.allocation.require._name", firstNode)
.put("index.blocks.write", true));
ResizeRequest resizeRequest = new ResizeRequest("target", "source");
resizeRequest.setResizeType(ResizeType.SHRINK);
Settings targetSettings = Settings.builder().put("index.number_of_shards", 2).put("index.number_of_replicas", 0).build();
resizeRequest.setTargetIndex(new CreateIndexRequest("target").settings(targetSettings).alias(new Alias("alias")));
ResizeResponse resizeResponse = highLevelClient().indices().shrink(resizeRequest);
assertTrue(resizeResponse.isAcknowledged());
assertTrue(resizeResponse.isShardsAcknowledged());
Map<String, Object> getIndexResponse = getAsMap("target");
Map<String, Object> indexSettings = (Map<String, Object>)XContentMapValues.extractValue("target.settings.index", getIndexResponse);
assertNotNull(indexSettings);
assertEquals("2", indexSettings.get("number_of_shards"));
assertEquals("0", indexSettings.get("number_of_replicas"));
Map<String, Object> aliasData = (Map<String, Object>)XContentMapValues.extractValue("target.aliases.alias", getIndexResponse);
assertNotNull(aliasData);
}
private static boolean indexExists(String index) throws IOException {
Response response = client().performRequest(HttpHead.METHOD_NAME, index);
return RestStatus.OK.getStatus() == response.getStatusLine().getStatusCode();
@SuppressWarnings("unchecked")
public void testSplit() throws IOException {
createIndex("source", Settings.builder().put("index.number_of_shards", 2).put("index.number_of_replicas", 0)
.put("index.number_of_routing_shards", 4).build());
updateIndexSettings("source", Settings.builder().put("index.blocks.write", true));
ResizeRequest resizeRequest = new ResizeRequest("target", "source");
resizeRequest.setResizeType(ResizeType.SPLIT);
Settings targetSettings = Settings.builder().put("index.number_of_shards", 4).put("index.number_of_replicas", 0).build();
resizeRequest.setTargetIndex(new CreateIndexRequest("target").settings(targetSettings).alias(new Alias("alias")));
ResizeResponse resizeResponse = highLevelClient().indices().split(resizeRequest);
assertTrue(resizeResponse.isAcknowledged());
assertTrue(resizeResponse.isShardsAcknowledged());
Map<String, Object> getIndexResponse = getAsMap("target");
Map<String, Object> indexSettings = (Map<String, Object>)XContentMapValues.extractValue("target.settings.index", getIndexResponse);
assertNotNull(indexSettings);
assertEquals("4", indexSettings.get("number_of_shards"));
assertEquals("0", indexSettings.get("number_of_replicas"));
Map<String, Object> aliasData = (Map<String, Object>)XContentMapValues.extractValue("target.aliases.alias", getIndexResponse);
assertNotNull(aliasData);
}
private static void closeIndex(String index) throws IOException {
Response response = client().performRequest(HttpPost.METHOD_NAME, index + "/_close");
assertThat(response.getStatusLine().getStatusCode(), equalTo(RestStatus.OK.getStatus()));
}
private static boolean aliasExists(String alias) throws IOException {
Response response = client().performRequest(HttpHead.METHOD_NAME, "/_alias/" + alias);
return RestStatus.OK.getStatus() == response.getStatusLine().getStatusCode();
}
private static boolean aliasExists(String index, String alias) throws IOException {
Response response = client().performRequest(HttpHead.METHOD_NAME, "/" + index + "/_alias/" + alias);
return RestStatus.OK.getStatus() == response.getStatusLine().getStatusCode();
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private static Map<String, Object> getIndexMetadata(String index) throws IOException {
Response response = client().performRequest(HttpGet.METHOD_NAME, index);
XContentType entityContentType = XContentType.fromMediaTypeOrFormat(response.getEntity().getContentType().getValue());
Map<String, Object> responseEntity = XContentHelper.convertToMap(entityContentType.xContent(), response.getEntity().getContent(),
false);
Map<String, Object> indexMetaData = (Map) responseEntity.get(index);
assertNotNull(indexMetaData);
return indexMetaData;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private static Map<String, Object> getAlias(final String index, final String alias) throws IOException {
String endpoint = "/_alias";
if (false == Strings.isEmpty(index)) {
endpoint = index + endpoint;
}
if (false == Strings.isEmpty(alias)) {
endpoint = endpoint + "/" + alias;
}
Map<String, Object> performGet = get(endpoint);
return (Map) ((Map) ((Map) performGet.get(index)).get("aliases")).get(alias);
}
private static Map<String, Object> get(final String endpoint) throws IOException {
Response response = client().performRequest(HttpGet.METHOD_NAME, endpoint);
XContentType entityContentType = XContentType.fromMediaTypeOrFormat(response.getEntity().getContentType().getValue());
Map<String, Object> responseEntity = XContentHelper.convertToMap(entityContentType.xContent(), response.getEntity().getContent(),
false);
assertNotNull(responseEntity);
return responseEntity;
}
}
}

View File

@ -38,6 +38,8 @@ import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
import org.elasticsearch.action.admin.indices.shrink.ResizeType;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkShardRequest;
import org.elasticsearch.action.delete.DeleteRequest;
@ -57,6 +59,7 @@ import org.elasticsearch.action.support.master.MasterNodeRequest;
import org.elasticsearch.action.support.replication.ReplicationRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.common.CheckedBiConsumer;
import org.elasticsearch.common.CheckedFunction;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference;
@ -108,6 +111,9 @@ import java.util.function.Supplier;
import static java.util.Collections.singletonMap;
import static org.elasticsearch.client.Request.REQUEST_BODY_CONTENT_TYPE;
import static org.elasticsearch.client.Request.enforceSameContentType;
import static org.elasticsearch.index.RandomCreateIndexGenerator.randomAliases;
import static org.elasticsearch.index.RandomCreateIndexGenerator.randomCreateIndexRequest;
import static org.elasticsearch.index.RandomCreateIndexGenerator.randomIndexSettings;
import static org.elasticsearch.index.alias.RandomAliasActionsGenerator.randomAliasAction;
import static org.elasticsearch.search.RandomSearchRequestGenerator.randomSearchRequest;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent;
@ -315,20 +321,15 @@ public class RequestTests extends ESTestCase {
}
public void testCreateIndex() throws IOException {
CreateIndexRequest createIndexRequest = new CreateIndexRequest();
String indexName = "index-" + randomAlphaOfLengthBetween(2, 5);
createIndexRequest.index(indexName);
CreateIndexRequest createIndexRequest = randomCreateIndexRequest();
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("/" + createIndexRequest.index(), request.getEndpoint());
assertEquals(expectedParams, request.getParameters());
assertEquals(HttpPut.METHOD_NAME, request.getMethod());
assertToXContentBody(createIndexRequest, request.getEntity());
@ -1026,6 +1027,7 @@ public class RequestTests extends ESTestCase {
if (Strings.hasLength(alias)) {
expectedEndpoint.add(alias);
}
assertEquals(HttpHead.METHOD_NAME, request.getMethod());
assertEquals(expectedEndpoint.toString(), request.getEndpoint());
assertEquals(expectedParams, request.getParameters());
assertNull(request.getEntity());
@ -1057,6 +1059,64 @@ public class RequestTests extends ESTestCase {
assertToXContentBody(spec, request.getEntity());
}
public void testSplit() throws IOException {
resizeTest(ResizeType.SPLIT, Request::split);
}
public void testSplitWrongResizeType() {
ResizeRequest resizeRequest = new ResizeRequest("target", "source");
resizeRequest.setResizeType(ResizeType.SHRINK);
IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> Request.split(resizeRequest));
assertEquals("Wrong resize type [SHRINK] for indices split request", iae.getMessage());
}
public void testShrinkWrongResizeType() {
ResizeRequest resizeRequest = new ResizeRequest("target", "source");
resizeRequest.setResizeType(ResizeType.SPLIT);
IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, () -> Request.shrink(resizeRequest));
assertEquals("Wrong resize type [SPLIT] for indices shrink request", iae.getMessage());
}
public void testShrink() throws IOException {
resizeTest(ResizeType.SHRINK, Request::shrink);
}
private static void resizeTest(ResizeType resizeType, CheckedFunction<ResizeRequest, Request, IOException> function)
throws IOException {
String[] indices = randomIndicesNames(2, 2);
ResizeRequest resizeRequest = new ResizeRequest(indices[0], indices[1]);
resizeRequest.setResizeType(resizeType);
Map<String, String> expectedParams = new HashMap<>();
setRandomMasterTimeout(resizeRequest, expectedParams);
setRandomTimeout(resizeRequest::timeout, resizeRequest.timeout(), expectedParams);
if (randomBoolean()) {
CreateIndexRequest createIndexRequest = new CreateIndexRequest(randomAlphaOfLengthBetween(3, 10));
if (randomBoolean()) {
createIndexRequest.settings(randomIndexSettings());
}
if (randomBoolean()) {
randomAliases(createIndexRequest);
}
if (randomBoolean()) {
setRandomWaitForActiveShards(createIndexRequest::waitForActiveShards, expectedParams);
}
resizeRequest.setTargetIndex(createIndexRequest);
} else {
if (randomBoolean()) {
setRandomWaitForActiveShards(resizeRequest::setWaitForActiveShards, expectedParams);
}
}
Request request = function.apply(resizeRequest);
assertEquals(HttpPut.METHOD_NAME, request.getMethod());
String expectedEndpoint = "/" + resizeRequest.getSourceIndex() + "/_" + resizeType.name().toLowerCase(Locale.ROOT) + "/"
+ resizeRequest.getTargetIndexRequest().index();
assertEquals(expectedEndpoint, request.getEndpoint());
assertEquals(expectedParams, request.getParameters());
assertToXContentBody(resizeRequest, request.getEntity());
}
private static void assertToXContentBody(ToXContent expectedBody, HttpEntity actualEntity) throws IOException {
BytesReference expectedBytes = XContentHelper.toXContent(expectedBody, REQUEST_BODY_CONTENT_TYPE, false);
assertEquals(XContentType.JSON.mediaTypeWithoutParameters(), actualEntity.getContentType().getValue());

View File

@ -36,6 +36,9 @@ import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
import org.elasticsearch.action.admin.indices.open.OpenIndexResponse;
import org.elasticsearch.action.admin.indices.shrink.ResizeRequest;
import org.elasticsearch.action.admin.indices.shrink.ResizeResponse;
import org.elasticsearch.action.admin.indices.shrink.ResizeType;
import org.elasticsearch.action.support.ActiveShardCount;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.ESRestHighLevelClientTestCase;
@ -47,6 +50,7 @@ import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.RestStatus;
import java.io.IOException;
import java.util.Map;
/**
* This class is used to generate the Java Indices API documentation.
@ -334,7 +338,6 @@ public class IndicesClientDocumentationIT extends ESRestHighLevelClientTestCase
request.waitForActiveShards(ActiveShardCount.DEFAULT); // <2>
// end::open-index-request-waitForActiveShards
// tag::open-index-request-indicesOptions
request.indicesOptions(IndicesOptions.strictExpandOpen()); // <1>
// end::open-index-request-indicesOptions
@ -559,4 +562,125 @@ public class IndicesClientDocumentationIT extends ESRestHighLevelClientTestCase
assertBusy(() -> assertTrue(client.indices().existsAlias(new GetAliasesRequest("async"))));
}
}
@SuppressWarnings("unchecked")
public void testShrinkIndex() throws IOException {
RestHighLevelClient client = highLevelClient();
{
Map<String, Object> nodes = getAsMap("_nodes");
String firstNode = ((Map<String, Object>) nodes.get("nodes")).keySet().iterator().next();
createIndex("source_index", Settings.builder().put("index.number_of_shards", 4).put("index.number_of_replicas", 0).build());
updateIndexSettings("source_index", Settings.builder().put("index.routing.allocation.require._name", firstNode)
.put("index.blocks.write", true));
}
// tag::shrink-index-request
ResizeRequest request = new ResizeRequest("target_index","source_index"); // <1>
// end::shrink-index-request
// tag::shrink-index-request-timeout
request.timeout(TimeValue.timeValueMinutes(2)); // <1>
request.timeout("2m"); // <2>
// end::shrink-index-request-timeout
// tag::shrink-index-request-masterTimeout
request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1>
request.masterNodeTimeout("1m"); // <2>
// end::shrink-index-request-masterTimeout
// tag::shrink-index-request-waitForActiveShards
request.getTargetIndexRequest().waitForActiveShards(2); // <1>
request.getTargetIndexRequest().waitForActiveShards(ActiveShardCount.DEFAULT); // <2>
// end::shrink-index-request-waitForActiveShards
// tag::shrink-index-request-settings
request.getTargetIndexRequest().settings(Settings.builder().put("index.number_of_shards", 2)); // <1>
// end::shrink-index-request-settings
// tag::shrink-index-request-aliases
request.getTargetIndexRequest().alias(new Alias("target_alias")); // <1>
// end::shrink-index-request-aliases
// tag::shrink-index-execute
ResizeResponse resizeResponse = client.indices().shrink(request);
// end::shrink-index-execute
// tag::shrink-index-response
boolean acknowledged = resizeResponse.isAcknowledged(); // <1>
boolean shardsAcked = resizeResponse.isShardsAcknowledged(); // <2>
// end::shrink-index-response
assertTrue(acknowledged);
assertTrue(shardsAcked);
// tag::shrink-index-execute-async
client.indices().shrinkAsync(request, new ActionListener<ResizeResponse>() {
@Override
public void onResponse(ResizeResponse resizeResponse) {
// <1>
}
@Override
public void onFailure(Exception e) {
// <2>
}
});
// end::shrink-index-execute-async
}
@SuppressWarnings("unchecked")
public void testSplitIndex() throws IOException {
RestHighLevelClient client = highLevelClient();
{
createIndex("source_index", Settings.builder().put("index.number_of_shards", 2).put("index.number_of_replicas", 0)
.put("index.number_of_routing_shards", 4).build());
updateIndexSettings("source_index", Settings.builder().put("index.blocks.write", true));
}
// tag::split-index-request
ResizeRequest request = new ResizeRequest("target_index","source_index"); // <1>
request.setResizeType(ResizeType.SPLIT); // <2>
// end::split-index-request
// tag::split-index-request-timeout
request.timeout(TimeValue.timeValueMinutes(2)); // <1>
request.timeout("2m"); // <2>
// end::split-index-request-timeout
// tag::split-index-request-masterTimeout
request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1>
request.masterNodeTimeout("1m"); // <2>
// end::split-index-request-masterTimeout
// tag::split-index-request-waitForActiveShards
request.getTargetIndexRequest().waitForActiveShards(2); // <1>
request.getTargetIndexRequest().waitForActiveShards(ActiveShardCount.DEFAULT); // <2>
// end::split-index-request-waitForActiveShards
// tag::split-index-request-settings
request.getTargetIndexRequest().settings(Settings.builder().put("index.number_of_shards", 4)); // <1>
// end::split-index-request-settings
// tag::split-index-request-aliases
request.getTargetIndexRequest().alias(new Alias("target_alias")); // <1>
// end::split-index-request-aliases
// tag::split-index-execute
ResizeResponse resizeResponse = client.indices().split(request);
// end::split-index-execute
// tag::split-index-response
boolean acknowledged = resizeResponse.isAcknowledged(); // <1>
boolean shardsAcked = resizeResponse.isShardsAcknowledged(); // <2>
// end::split-index-response
assertTrue(acknowledged);
assertTrue(shardsAcked);
// tag::split-index-execute-async
client.indices().splitAsync(request, new ActionListener<ResizeResponse>() {
@Override
public void onResponse(ResizeResponse resizeResponse) {
// <1>
}
@Override
public void onFailure(Exception e) {
// <2>
}
});
// end::split-index-execute-async
}
}

View File

@ -12,6 +12,10 @@ include::update_aliases.asciidoc[]
include::exists_alias.asciidoc[]
include::shrink_index.asciidoc[]
include::split_index.asciidoc[]
include::_index.asciidoc[]
include::get.asciidoc[]

View File

@ -0,0 +1,90 @@
[[java-rest-high-shrink-index]]
=== Shrink Index API
[[java-rest-high-shrink-index-request]]
==== Resize Request
The Shrink API requires a `ResizeRequest` instance.
A `ResizeRequest` requires two string arguments:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[shrink-index-request]
--------------------------------------------------
<1> The target index (first argument) to shrink the source index (second argument) into
==== Optional arguments
The following arguments can optionally be provided:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[shrink-index-request-timeout]
--------------------------------------------------
<1> Timeout to wait for the all the nodes to acknowledge the index is opened
as a `TimeValue`
<2> Timeout to wait for the all the nodes to acknowledge the index is opened
as a `String`
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[shrink-index-request-masterTimeout]
--------------------------------------------------
<1> Timeout to connect to the master node as a `TimeValue`
<2> Timeout to connect to the master node as a `String`
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[shrink-index-request-waitForActiveShards]
--------------------------------------------------
<1> The number of active shard copies to wait for before the shrink index API
returns a response, as an `int`
<2> The number of active shard copies to wait for before the shrink index API
returns a response, as an `ActiveShardCount`
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[shrink-index-request-settings]
--------------------------------------------------
<1> The settings to apply to the target index, which include the number of
shards to create for it
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[shrink-index-request-aliases]
--------------------------------------------------
<1> The aliases to associate the target index with
[[java-rest-high-shrink-index-sync]]
==== Synchronous Execution
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[shrink-index-execute]
--------------------------------------------------
[[java-rest-high-shrink-index-async]]
==== Asynchronous Execution
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[shrink-index-execute-async]
--------------------------------------------------
<1> Called when the execution is successfully completed. The response is
provided as an argument
<2> Called in case of failure. The raised exception is provided as an argument
[[java-rest-high-shrink-index-response]]
==== Shrink Index Response
The returned `ResizeResponse` allows to retrieve information about the
executed operation as follows:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[shrink-index-response]
--------------------------------------------------
<1> Indicates whether all of the nodes have acknowledged the request
<2> Indicates whether the requisite number of shard copies were started for
each shard in the index before timing out

View File

@ -0,0 +1,91 @@
[[java-rest-high-split-index]]
=== Split Index API
[[java-rest-high-split-index-request]]
==== Resize Request
The Split API requires a `ResizeRequest` instance.
A `ResizeRequest` requires two string arguments:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[split-index-request]
--------------------------------------------------
<1> The target index (first argument) to split the source index (second argument) into
<2> The resize type needs to be set to `SPLIT`
==== Optional arguments
The following arguments can optionally be provided:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[split-index-request-timeout]
--------------------------------------------------
<1> Timeout to wait for the all the nodes to acknowledge the index is opened
as a `TimeValue`
<2> Timeout to wait for the all the nodes to acknowledge the index is opened
as a `String`
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[split-index-request-masterTimeout]
--------------------------------------------------
<1> Timeout to connect to the master node as a `TimeValue`
<2> Timeout to connect to the master node as a `String`
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[split-index-request-waitForActiveShards]
--------------------------------------------------
<1> The number of active shard copies to wait for before the split index API
returns a response, as an `int`.
<2> The number of active shard copies to wait for before the split index API
returns a response, as an `ActiveShardCount`.
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[split-index-request-settings]
--------------------------------------------------
<1> The settings to apply to the target index, which include the number of
shards to create for it.
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[split-index-request-aliases]
--------------------------------------------------
<1> The aliases to associate the target index with.
[[java-rest-high-split-index-sync]]
==== Synchronous Execution
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[split-index-execute]
--------------------------------------------------
[[java-rest-high-split-index-async]]
==== Asynchronous Execution
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[split-index-execute-async]
--------------------------------------------------
<1> Called when the execution is successfully completed. The response is
provided as an argument
<2> Called in case of failure. The raised exception is provided as an argument
[[java-rest-high-split-index-response]]
==== Split Index Response
The returned `ResizeResponse` allows to retrieve information about the
executed operation as follows:
["source","java",subs="attributes,callouts,macros"]
--------------------------------------------------
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[split-index-response]
--------------------------------------------------
<1> Indicates whether all of the nodes have acknowledged the request
<2> Indicates whether the requisite number of shard copies were started for
each shard in the index before timing out

View File

@ -11,6 +11,8 @@ Indices APIs::
* <<java-rest-high-put-mapping>>
* <<java-rest-high-update-aliases>>
* <<java-rest-high-exists-alias>>
* <<java-rest-high-shrink-index>>
* <<java-rest-high-split-index>>
Single document APIs::
* <<java-rest-high-document-index>>

View File

@ -103,7 +103,7 @@ public class IndexingIT extends ESRestTestCase {
logger.info("indexing docs with [{}] concurrent updates initially", nUpdates);
final int finalVersionForDoc1 = indexDocWithConcurrentUpdates(index, 1, nUpdates);
logger.info("allowing shards on all nodes");
updateIndexSetting(index, Settings.builder().putNull("index.routing.allocation.include._name"));
updateIndexSettings(index, Settings.builder().putNull("index.routing.allocation.include._name"));
ensureGreen(index);
assertOK(client().performRequest("POST", index + "/_refresh"));
List<Shard> shards = buildShards(index, nodes, newNodeClient);
@ -128,7 +128,7 @@ public class IndexingIT extends ESRestTestCase {
primary = shards.stream().filter(Shard::isPrimary).findFirst().get();
logger.info("moving primary to new node by excluding {}", primary.getNode().getNodeName());
updateIndexSetting(index, Settings.builder().put("index.routing.allocation.exclude._name", primary.getNode().getNodeName()));
updateIndexSettings(index, Settings.builder().put("index.routing.allocation.exclude._name", primary.getNode().getNodeName()));
ensureGreen(index);
nUpdates = randomIntBetween(minUpdates, maxUpdates);
logger.info("indexing docs with [{}] concurrent updates after moving primary", nUpdates);
@ -141,7 +141,7 @@ public class IndexingIT extends ESRestTestCase {
}
logger.info("setting number of replicas to 0");
updateIndexSetting(index, Settings.builder().put("index.number_of_replicas", 0));
updateIndexSettings(index, Settings.builder().put("index.number_of_replicas", 0));
ensureGreen(index);
nUpdates = randomIntBetween(minUpdates, maxUpdates);
logger.info("indexing doc with [{}] concurrent updates after setting number of replicas to 0", nUpdates);
@ -154,7 +154,7 @@ public class IndexingIT extends ESRestTestCase {
}
logger.info("setting number of replicas to 1");
updateIndexSetting(index, Settings.builder().put("index.number_of_replicas", 1));
updateIndexSettings(index, Settings.builder().put("index.number_of_replicas", 1));
ensureGreen(index);
nUpdates = randomIntBetween(minUpdates, maxUpdates);
logger.info("indexing doc with [{}] concurrent updates after setting number of replicas to 1", nUpdates);
@ -189,7 +189,7 @@ public class IndexingIT extends ESRestTestCase {
numDocs += indexDocs(index, 0, numberOfInitialDocs);
assertSeqNoOnShards(index, nodes, nodes.getBWCVersion().major >= 6 ? numDocs : 0, newNodeClient);
logger.info("allowing shards on all nodes");
updateIndexSetting(index, Settings.builder().putNull("index.routing.allocation.include._name"));
updateIndexSettings(index, Settings.builder().putNull("index.routing.allocation.include._name"));
ensureGreen(index);
assertOK(client().performRequest("POST", index + "/_refresh"));
for (final String bwcName : bwcNamesList) {
@ -201,7 +201,7 @@ public class IndexingIT extends ESRestTestCase {
assertSeqNoOnShards(index, nodes, nodes.getBWCVersion().major >= 6 ? numDocs : 0, newNodeClient);
Shard primary = buildShards(index, nodes, newNodeClient).stream().filter(Shard::isPrimary).findFirst().get();
logger.info("moving primary to new node by excluding {}", primary.getNode().getNodeName());
updateIndexSetting(index, Settings.builder().put("index.routing.allocation.exclude._name", primary.getNode().getNodeName()));
updateIndexSettings(index, Settings.builder().put("index.routing.allocation.exclude._name", primary.getNode().getNodeName()));
ensureGreen(index);
int numDocsOnNewPrimary = 0;
final int numberOfDocsAfterMovingPrimary = 1 + randomInt(5);
@ -214,13 +214,13 @@ public class IndexingIT extends ESRestTestCase {
* the recovery code.
*/
logger.info("setting number of replicas to 0");
updateIndexSetting(index, Settings.builder().put("index.number_of_replicas", 0));
updateIndexSettings(index, Settings.builder().put("index.number_of_replicas", 0));
final int numberOfDocsAfterDroppingReplicas = 1 + randomInt(5);
logger.info("indexing [{}] docs after setting number of replicas to 0", numberOfDocsAfterDroppingReplicas);
numDocsOnNewPrimary += indexDocs(index, numDocs, numberOfDocsAfterDroppingReplicas);
numDocs += numberOfDocsAfterDroppingReplicas;
logger.info("setting number of replicas to 1");
updateIndexSetting(index, Settings.builder().put("index.number_of_replicas", 1));
updateIndexSettings(index, Settings.builder().put("index.number_of_replicas", 1));
ensureGreen(index);
assertOK(client().performRequest("POST", index + "/_refresh"));
@ -272,7 +272,7 @@ public class IndexingIT extends ESRestTestCase {
);
// Allocating shards on all nodes, taking snapshots should happen on all nodes.
updateIndexSetting(index, Settings.builder().putNull("index.routing.allocation.include._name"));
updateIndexSettings(index, Settings.builder().putNull("index.routing.allocation.include._name"));
ensureGreen(index);
assertOK(client().performRequest("POST", index + "/_refresh"));

View File

@ -172,20 +172,20 @@ public class RecoveryIT extends ESRestTestCase {
indexDocs(index, 0, 10);
ensureGreen(index);
// make sure that we can index while the replicas are recovering
updateIndexSetting(index, Settings.builder().put(INDEX_ROUTING_ALLOCATION_ENABLE_SETTING.getKey(), "primaries"));
updateIndexSettings(index, Settings.builder().put(INDEX_ROUTING_ALLOCATION_ENABLE_SETTING.getKey(), "primaries"));
break;
case MIXED:
updateIndexSetting(index, Settings.builder().put(INDEX_ROUTING_ALLOCATION_ENABLE_SETTING.getKey(), (String)null));
updateIndexSettings(index, Settings.builder().put(INDEX_ROUTING_ALLOCATION_ENABLE_SETTING.getKey(), (String)null));
asyncIndexDocs(index, 10, 50).get();
ensureGreen(index);
assertOK(client().performRequest("POST", index + "/_refresh"));
assertCount(index, "_only_nodes:" + nodes.get(0), 60);
assertCount(index, "_only_nodes:" + nodes.get(1), 60);
// make sure that we can index while the replicas are recovering
updateIndexSetting(index, Settings.builder().put(INDEX_ROUTING_ALLOCATION_ENABLE_SETTING.getKey(), "primaries"));
updateIndexSettings(index, Settings.builder().put(INDEX_ROUTING_ALLOCATION_ENABLE_SETTING.getKey(), "primaries"));
break;
case UPGRADED:
updateIndexSetting(index, Settings.builder().put(INDEX_ROUTING_ALLOCATION_ENABLE_SETTING.getKey(), (String)null));
updateIndexSettings(index, Settings.builder().put(INDEX_ROUTING_ALLOCATION_ENABLE_SETTING.getKey(), (String)null));
asyncIndexDocs(index, 60, 50).get();
ensureGreen(index);
assertOK(client().performRequest("POST", index + "/_refresh"));
@ -237,27 +237,27 @@ public class RecoveryIT extends ESRestTestCase {
ensureGreen(index);
// make sure that no shards are allocated, so we can make sure the primary stays on the old node (when one
// node stops, we lose the master too, so a replica will not be promoted)
updateIndexSetting(index, Settings.builder().put(INDEX_ROUTING_ALLOCATION_ENABLE_SETTING.getKey(), "none"));
updateIndexSettings(index, Settings.builder().put(INDEX_ROUTING_ALLOCATION_ENABLE_SETTING.getKey(), "none"));
break;
case MIXED:
final String newNode = getNodeId(v -> v.equals(Version.CURRENT));
final String oldNode = getNodeId(v -> v.before(Version.CURRENT));
// remove the replica and guaranteed the primary is placed on the old node
updateIndexSetting(index, Settings.builder()
updateIndexSettings(index, Settings.builder()
.put(IndexMetaData.INDEX_NUMBER_OF_REPLICAS_SETTING.getKey(), 0)
.put(INDEX_ROUTING_ALLOCATION_ENABLE_SETTING.getKey(), (String)null)
.put("index.routing.allocation.include._id", oldNode)
);
ensureGreen(index); // wait for the primary to be assigned
ensureNoInitializingShards(); // wait for all other shard activity to finish
updateIndexSetting(index, Settings.builder().put("index.routing.allocation.include._id", newNode));
updateIndexSettings(index, Settings.builder().put("index.routing.allocation.include._id", newNode));
asyncIndexDocs(index, 10, 50).get();
ensureGreen(index);
assertOK(client().performRequest("POST", index + "/_refresh"));
assertCount(index, "_only_nodes:" + newNode, 60);
break;
case UPGRADED:
updateIndexSetting(index, Settings.builder()
updateIndexSettings(index, Settings.builder()
.put(IndexMetaData.INDEX_NUMBER_OF_REPLICAS_SETTING.getKey(), 1)
.put("index.routing.allocation.include._id", (String)null)
);

View File

@ -70,8 +70,8 @@ import static org.elasticsearch.common.settings.Settings.Builder.EMPTY_SETTINGS;
public class CreateIndexRequest extends AcknowledgedRequest<CreateIndexRequest> implements IndicesRequest, ToXContentObject {
private static final ParseField MAPPINGS = new ParseField("mappings");
private static final ParseField SETTINGS = new ParseField("settings");
private static final ParseField ALIASES = new ParseField("aliases");
public static final ParseField SETTINGS = new ParseField("settings");
public static final ParseField ALIASES = new ParseField("aliases");
private String cause = "";

View File

@ -46,10 +46,14 @@ public class CreateIndexResponse extends AcknowledgedResponse implements ToXCont
true, args -> new CreateIndexResponse((boolean) args[0], (boolean) args[1], (String) args[2]));
static {
declareAcknowledgedField(PARSER);
PARSER.declareField(constructorArg(), (parser, context) -> parser.booleanValue(), SHARDS_ACKNOWLEDGED,
ObjectParser.ValueType.BOOLEAN);
PARSER.declareField(constructorArg(), (parser, context) -> parser.text(), INDEX, ObjectParser.ValueType.STRING);
declareFields(PARSER);
}
protected static <T extends CreateIndexResponse> void declareFields(ConstructingObjectParser<T, Void> objectParser) {
declareAcknowledgedField(objectParser);
objectParser.declareField(constructorArg(), (parser, context) -> parser.booleanValue(), SHARDS_ACKNOWLEDGED,
ObjectParser.ValueType.BOOLEAN);
objectParser.declareField(constructorArg(), (parser, context) -> parser.text(), INDEX, ObjectParser.ValueType.STRING);
}
private boolean shardsAcknowledged;
@ -112,7 +116,7 @@ public class CreateIndexResponse extends AcknowledgedResponse implements ToXCont
return builder;
}
public static CreateIndexResponse fromXContent(XContentParser parser) throws IOException {
public static CreateIndexResponse fromXContent(XContentParser parser) {
return PARSER.apply(parser, null);
}
}

View File

@ -18,9 +18,9 @@
*/
package org.elasticsearch.action.admin.indices.shrink;
import org.elasticsearch.Version;
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.IndicesRequest;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.support.ActiveShardCount;
import org.elasticsearch.action.support.IndicesOptions;
@ -30,6 +30,9 @@ import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
import java.util.Objects;
@ -39,7 +42,7 @@ import static org.elasticsearch.action.ValidateActions.addValidationError;
/**
* Request class to shrink an index into a single shard
*/
public class ResizeRequest extends AcknowledgedRequest<ResizeRequest> implements IndicesRequest {
public class ResizeRequest extends AcknowledgedRequest<ResizeRequest> implements IndicesRequest, ToXContentObject {
public static final ObjectParser<ResizeRequest, Void> PARSER = new ObjectParser<>("resize_request", null);
static {
@ -173,4 +176,29 @@ public class ResizeRequest extends AcknowledgedRequest<ResizeRequest> implements
public ResizeType getResizeType() {
return type;
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
{
builder.startObject(CreateIndexRequest.SETTINGS.getPreferredName());
{
targetIndexRequest.settings().toXContent(builder, params);
}
builder.endObject();
builder.startObject(CreateIndexRequest.ALIASES.getPreferredName());
{
for (Alias alias : targetIndexRequest.aliases()) {
alias.toXContent(builder, params);
}
}
builder.endObject();
}
builder.endObject();
return builder;
}
public void fromXContent(XContentParser parser) throws IOException {
PARSER.parse(parser, this, null);
}
}

View File

@ -20,12 +20,29 @@
package org.elasticsearch.action.admin.indices.shrink;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
import org.elasticsearch.common.xcontent.XContentParser;
/**
* A response for a resize index action, either shrink or split index.
*/
public final class ResizeResponse extends CreateIndexResponse {
private static final ConstructingObjectParser<ResizeResponse, Void> PARSER = new ConstructingObjectParser<>("resize_index",
true, args -> new ResizeResponse((boolean) args[0], (boolean) args[1], (String) args[2]));
static {
declareFields(PARSER);
}
ResizeResponse() {
}
ResizeResponse(boolean acknowledged, boolean shardsAcknowledged, String index) {
super(acknowledged, shardsAcknowledged, index);
}
public static ResizeResponse fromXContent(XContentParser parser) {
return PARSER.apply(parser, null);
}
}

View File

@ -38,8 +38,8 @@ public abstract class AcknowledgedResponse extends ActionResponse {
private static final ParseField ACKNOWLEDGED = new ParseField("acknowledged");
protected static <T extends AcknowledgedResponse> void declareAcknowledgedField(ConstructingObjectParser<T, Void> PARSER) {
PARSER.declareField(constructorArg(), (parser, context) -> parser.booleanValue(), ACKNOWLEDGED,
protected static <T extends AcknowledgedResponse> void declareAcknowledgedField(ConstructingObjectParser<T, Void> objectParser) {
objectParser.declareField(constructorArg(), (parser, context) -> parser.booleanValue(), ACKNOWLEDGED,
ObjectParser.ValueType.BOOLEAN);
}

View File

@ -55,7 +55,7 @@ public class RestShrinkIndexAction extends BaseRestHandler {
}
ResizeRequest shrinkIndexRequest = new ResizeRequest(request.param("target"), request.param("index"));
shrinkIndexRequest.setResizeType(ResizeType.SHRINK);
request.applyContentParser(parser -> ResizeRequest.PARSER.parse(parser, shrinkIndexRequest, null));
request.applyContentParser(shrinkIndexRequest::fromXContent);
shrinkIndexRequest.timeout(request.paramAsTime("timeout", shrinkIndexRequest.timeout()));
shrinkIndexRequest.masterNodeTimeout(request.paramAsTime("master_timeout", shrinkIndexRequest.masterNodeTimeout()));
shrinkIndexRequest.setWaitForActiveShards(ActiveShardCount.parseString(request.param("wait_for_active_shards")));

View File

@ -55,7 +55,7 @@ public class RestSplitIndexAction extends BaseRestHandler {
}
ResizeRequest shrinkIndexRequest = new ResizeRequest(request.param("target"), request.param("index"));
shrinkIndexRequest.setResizeType(ResizeType.SPLIT);
request.applyContentParser(parser -> ResizeRequest.PARSER.parse(parser, shrinkIndexRequest, null));
request.applyContentParser(shrinkIndexRequest::fromXContent);
shrinkIndexRequest.timeout(request.paramAsTime("timeout", shrinkIndexRequest.timeout()));
shrinkIndexRequest.masterNodeTimeout(request.paramAsTime("master_timeout", shrinkIndexRequest.masterNodeTimeout()));
shrinkIndexRequest.setWaitForActiveShards(ActiveShardCount.parseString(request.param("wait_for_active_shards")));

View File

@ -26,18 +26,16 @@ import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.index.RandomCreateIndexGenerator;
import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_REPLICAS;
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_SHARDS;
import static org.elasticsearch.common.xcontent.ToXContent.EMPTY_PARAMS;
@ -60,7 +58,7 @@ public class CreateIndexRequestTests extends ESTestCase {
}
}
public void testTopLevelKeys() throws IOException {
public void testTopLevelKeys() {
String createIndex =
"{\n"
+ " \"FOO_SHOULD_BE_ILLEGAL_HERE\": {\n"
@ -109,7 +107,7 @@ public class CreateIndexRequestTests extends ESTestCase {
public void testToAndFromXContent() throws IOException {
final CreateIndexRequest createIndexRequest = createTestItem();
final CreateIndexRequest createIndexRequest = RandomCreateIndexGenerator.randomCreateIndexRequest();
boolean humanReadable = randomBoolean();
final XContentType xContentType = randomFrom(XContentType.values());
@ -135,7 +133,7 @@ public class CreateIndexRequestTests extends ESTestCase {
}
}
private static void assertAliasesEqual(Set<Alias> expected, Set<Alias> actual) throws IOException {
public static void assertAliasesEqual(Set<Alias> expected, Set<Alias> actual) throws IOException {
assertEquals(expected, actual);
for (Alias expectedAlias : expected) {
@ -149,97 +147,4 @@ public class CreateIndexRequestTests extends ESTestCase {
}
}
}
/**
* Returns a random {@link CreateIndexRequest}.
*/
private static CreateIndexRequest createTestItem() throws IOException {
String index = randomAlphaOfLength(5);
CreateIndexRequest request = new CreateIndexRequest(index);
int aliasesNo = randomIntBetween(0, 2);
for (int i = 0; i < aliasesNo; i++) {
request.alias(randomAlias());
}
if (randomBoolean()) {
String type = randomAlphaOfLength(5);
request.mapping(type, randomMapping(type));
}
if (randomBoolean()) {
request.settings(randomIndexSettings());
}
return request;
}
private static Settings randomIndexSettings() {
Settings.Builder builder = Settings.builder();
if (randomBoolean()) {
int numberOfShards = randomIntBetween(1, 10);
builder.put(SETTING_NUMBER_OF_SHARDS, numberOfShards);
}
if (randomBoolean()) {
int numberOfReplicas = randomIntBetween(1, 10);
builder.put(SETTING_NUMBER_OF_REPLICAS, numberOfReplicas);
}
return builder.build();
}
private static XContentBuilder randomMapping(String type) throws IOException {
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject().startObject(type);
randomMappingFields(builder, true);
builder.endObject().endObject();
return builder;
}
public static void randomMappingFields(XContentBuilder builder, boolean allowObjectField) throws IOException {
builder.startObject("properties");
int fieldsNo = randomIntBetween(0, 5);
for (int i = 0; i < fieldsNo; i++) {
builder.startObject(randomAlphaOfLength(5));
if (allowObjectField && randomBoolean()) {
randomMappingFields(builder, false);
} else {
builder.field("type", "text");
}
builder.endObject();
}
builder.endObject();
}
private static Alias randomAlias() {
Alias alias = new Alias(randomAlphaOfLength(5));
if (randomBoolean()) {
if (randomBoolean()) {
alias.routing(randomAlphaOfLength(5));
} else {
if (randomBoolean()) {
alias.indexRouting(randomAlphaOfLength(5));
}
if (randomBoolean()) {
alias.searchRouting(randomAlphaOfLength(5));
}
}
}
if (randomBoolean()) {
alias.filter("{\"term\":{\"year\":2016}}");
}
return alias;
}
}

View File

@ -117,7 +117,7 @@ public class CreateIndexResponseTests extends ESTestCase {
/**
* Returns a random {@link CreateIndexResponse}.
*/
private static CreateIndexResponse createTestItem() throws IOException {
private static CreateIndexResponse createTestItem() {
boolean acknowledged = randomBoolean();
boolean shardsAcknowledged = acknowledged && randomBoolean();
String index = randomAlphaOfLength(5);

View File

@ -35,6 +35,7 @@ import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.common.xcontent.yaml.YamlXContent;
import org.elasticsearch.index.Index;
import org.elasticsearch.index.RandomCreateIndexGenerator;
import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
@ -172,7 +173,7 @@ public class PutMappingRequestTests extends ESTestCase {
builder.startObject();
if (randomBoolean()) {
CreateIndexRequestTests.randomMappingFields(builder, true);
RandomCreateIndexGenerator.randomMappingFields(builder, true);
}
builder.endObject();

View File

@ -0,0 +1,95 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.action.admin.indices.shrink;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequestTests;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.RandomCreateIndexGenerator;
import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_SHARDS;
import static org.elasticsearch.common.xcontent.ToXContent.EMPTY_PARAMS;
public class ResizeRequestTests extends ESTestCase {
public void testToXContent() throws IOException {
{
ResizeRequest request = new ResizeRequest("target", "source");
String actualRequestBody = Strings.toString(request);
assertEquals("{\"settings\":{},\"aliases\":{}}", actualRequestBody);
}
{
ResizeRequest request = new ResizeRequest();
CreateIndexRequest target = new CreateIndexRequest("target");
Alias alias = new Alias("test_alias");
alias.routing("1");
alias.filter("{\"term\":{\"year\":2016}}");
target.alias(alias);
Settings.Builder settings = Settings.builder();
settings.put(SETTING_NUMBER_OF_SHARDS, 10);
target.settings(settings);
request.setTargetIndex(target);
String actualRequestBody = Strings.toString(request);
String expectedRequestBody = "{\"settings\":{\"index\":{\"number_of_shards\":\"10\"}}," +
"\"aliases\":{\"test_alias\":{\"filter\":{\"term\":{\"year\":2016}},\"routing\":\"1\"}}}";
assertEquals(expectedRequestBody, actualRequestBody);
}
}
public void testToAndFromXContent() throws IOException {
final ResizeRequest resizeRequest = createTestItem();
boolean humanReadable = randomBoolean();
final XContentType xContentType = randomFrom(XContentType.values());
BytesReference originalBytes = toShuffledXContent(resizeRequest, xContentType, EMPTY_PARAMS, humanReadable);
ResizeRequest parsedResizeRequest = new ResizeRequest(resizeRequest.getTargetIndexRequest().index(),
resizeRequest.getSourceIndex());
parsedResizeRequest.fromXContent(createParser(xContentType.xContent(), originalBytes));
assertEquals(resizeRequest.getSourceIndex(), parsedResizeRequest.getSourceIndex());
assertEquals(resizeRequest.getTargetIndexRequest().index(), parsedResizeRequest.getTargetIndexRequest().index());
CreateIndexRequestTests.assertAliasesEqual(resizeRequest.getTargetIndexRequest().aliases(),
parsedResizeRequest.getTargetIndexRequest().aliases());
assertEquals(resizeRequest.getTargetIndexRequest().settings(), parsedResizeRequest.getTargetIndexRequest().settings());
}
private static ResizeRequest createTestItem() {
ResizeRequest resizeRequest = new ResizeRequest(randomAlphaOfLengthBetween(3, 10), randomAlphaOfLengthBetween(3, 10));
if (randomBoolean()) {
CreateIndexRequest createIndexRequest = new CreateIndexRequest(randomAlphaOfLengthBetween(3, 10));
if (randomBoolean()) {
RandomCreateIndexGenerator.randomAliases(createIndexRequest);
}
if (randomBoolean()) {
createIndexRequest.settings(RandomCreateIndexGenerator.randomIndexSettings());
}
resizeRequest.setTargetIndex(createIndexRequest);
}
return resizeRequest;
}
}

View File

@ -0,0 +1,86 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.action.admin.indices.shrink;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
import static org.elasticsearch.test.XContentTestUtils.insertRandomFields;
public class ResizeResponseTests extends ESTestCase {
public void testToXContent() {
ResizeResponse response = new ResizeResponse(true, false, "index_name");
String output = Strings.toString(response);
assertEquals("{\"acknowledged\":true,\"shards_acknowledged\":false,\"index\":\"index_name\"}", output);
}
public void testToAndFromXContent() throws IOException {
doFromXContentTestWithRandomFields(false);
}
/**
* This test adds random fields and objects to the xContent rendered out to
* ensure we can parse it back to be forward compatible with additions to
* the xContent
*/
public void testFromXContentWithRandomFields() throws IOException {
doFromXContentTestWithRandomFields(true);
}
private void doFromXContentTestWithRandomFields(boolean addRandomFields) throws IOException {
final ResizeResponse resizeResponse = createTestItem();
boolean humanReadable = randomBoolean();
final XContentType xContentType = randomFrom(XContentType.values());
BytesReference originalBytes = toShuffledXContent(resizeResponse, xContentType, ToXContent.EMPTY_PARAMS, humanReadable);
BytesReference mutated;
if (addRandomFields) {
mutated = insertRandomFields(xContentType, originalBytes, null, random());
} else {
mutated = originalBytes;
}
ResizeResponse parsedResizeResponse;
try (XContentParser parser = createParser(xContentType.xContent(), mutated)) {
parsedResizeResponse = ResizeResponse.fromXContent(parser);
assertNull(parser.nextToken());
}
assertEquals(resizeResponse.index(), parsedResizeResponse.index());
assertEquals(resizeResponse.isShardsAcknowledged(), parsedResizeResponse.isShardsAcknowledged());
assertEquals(resizeResponse.isAcknowledged(), parsedResizeResponse.isAcknowledged());
}
private static ResizeResponse createTestItem() {
boolean acknowledged = randomBoolean();
boolean shardsAcknowledged = acknowledged && randomBoolean();
String index = randomAlphaOfLength(5);
return new ResizeResponse(acknowledged, shardsAcknowledged, index);
}
}

View File

@ -0,0 +1,143 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.index;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import java.io.IOException;
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_REPLICAS;
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_SHARDS;
import static org.elasticsearch.test.ESTestCase.randomAlphaOfLength;
import static org.elasticsearch.test.ESTestCase.randomBoolean;
import static org.elasticsearch.test.ESTestCase.randomIntBetween;
public final class RandomCreateIndexGenerator {
private RandomCreateIndexGenerator() {}
/**
* Returns a random {@link CreateIndexRequest}. Randomizes the index name, the aliases,
* mappings and settings associated with the index.
*/
public static CreateIndexRequest randomCreateIndexRequest() throws IOException {
String index = randomAlphaOfLength(5);
CreateIndexRequest request = new CreateIndexRequest(index);
randomAliases(request);
if (randomBoolean()) {
String type = randomAlphaOfLength(5);
request.mapping(type, randomMapping(type));
}
if (randomBoolean()) {
request.settings(randomIndexSettings());
}
return request;
}
/**
* Returns a {@link Settings} instance which include random values for
* {@link org.elasticsearch.cluster.metadata.IndexMetaData#SETTING_NUMBER_OF_SHARDS} and
* {@link org.elasticsearch.cluster.metadata.IndexMetaData#SETTING_NUMBER_OF_REPLICAS}
*/
public static Settings randomIndexSettings() {
Settings.Builder builder = Settings.builder();
if (randomBoolean()) {
int numberOfShards = randomIntBetween(1, 10);
builder.put(SETTING_NUMBER_OF_SHARDS, numberOfShards);
}
if (randomBoolean()) {
int numberOfReplicas = randomIntBetween(1, 10);
builder.put(SETTING_NUMBER_OF_REPLICAS, numberOfReplicas);
}
return builder.build();
}
private static XContentBuilder randomMapping(String type) throws IOException {
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject().startObject(type);
randomMappingFields(builder, true);
builder.endObject().endObject();
return builder;
}
/**
* Adds random mapping fields to the provided {@link XContentBuilder}
*/
public static void randomMappingFields(XContentBuilder builder, boolean allowObjectField) throws IOException {
builder.startObject("properties");
int fieldsNo = randomIntBetween(0, 5);
for (int i = 0; i < fieldsNo; i++) {
builder.startObject(randomAlphaOfLength(5));
if (allowObjectField && randomBoolean()) {
randomMappingFields(builder, false);
} else {
builder.field("type", "text");
}
builder.endObject();
}
builder.endObject();
}
/**
* Sets random aliases to the provided {@link CreateIndexRequest}
*/
public static void randomAliases(CreateIndexRequest request) {
int aliasesNo = randomIntBetween(0, 2);
for (int i = 0; i < aliasesNo; i++) {
request.alias(randomAlias());
}
}
private static Alias randomAlias() {
Alias alias = new Alias(randomAlphaOfLength(5));
if (randomBoolean()) {
if (randomBoolean()) {
alias.routing(randomAlphaOfLength(5));
} else {
if (randomBoolean()) {
alias.indexRouting(randomAlphaOfLength(5));
}
if (randomBoolean()) {
alias.searchRouting(randomAlphaOfLength(5));
}
}
}
if (randomBoolean()) {
alias.filter("{\"term\":{\"year\":2016}}");
}
return alias;
}
}

View File

@ -34,7 +34,10 @@ import static org.elasticsearch.test.ESTestCase.randomInt;
import static org.elasticsearch.test.ESTestCase.randomIntBetween;
import static org.elasticsearch.test.ESTestCase.randomLong;
public class RandomAliasActionsGenerator {
public final class RandomAliasActionsGenerator {
private RandomAliasActionsGenerator() {}
public static AliasActions randomAliasAction() {
return randomAliasAction(false);
}

View File

@ -21,6 +21,10 @@ package org.elasticsearch.test.rest;
import org.apache.http.Header;
import org.apache.http.HttpHost;
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.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
@ -38,9 +42,12 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.test.ESTestCase;
import org.junit.After;
import org.junit.AfterClass;
@ -70,7 +77,6 @@ import static java.util.Collections.singletonMap;
import static java.util.Collections.sort;
import static java.util.Collections.unmodifiableList;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
/**
@ -423,7 +429,7 @@ public abstract class ESRestTestCase extends ESTestCase {
return runningTasks;
}
protected void assertOK(Response response) {
protected static void assertOK(Response response) {
assertThat(response.getStatusLine().getStatusCode(), anyOf(equalTo(200), equalTo(201)));
}
@ -432,7 +438,7 @@ public abstract class ESRestTestCase extends ESTestCase {
* in an non green state
* @param index index to test for
**/
protected void ensureGreen(String index) throws IOException {
protected static void ensureGreen(String index) throws IOException {
Map<String, String> params = new HashMap<>();
params.put("wait_for_status", "green");
params.put("wait_for_no_relocating_shards", "true");
@ -445,7 +451,7 @@ public abstract class ESRestTestCase extends ESTestCase {
* waits until all shard initialization is completed. This is a handy alternative to ensureGreen as it relates to all shards
* in the cluster and doesn't require to know how many nodes/replica there are.
*/
protected void ensureNoInitializingShards() throws IOException {
protected static void ensureNoInitializingShards() throws IOException {
Map<String, String> params = new HashMap<>();
params.put("wait_for_no_initializing_shards", "true");
params.put("timeout", "70s");
@ -453,22 +459,64 @@ public abstract class ESRestTestCase extends ESTestCase {
assertOK(client().performRequest("GET", "_cluster/health/", params));
}
protected void createIndex(String name, Settings settings) throws IOException {
protected static void createIndex(String name, Settings settings) throws IOException {
createIndex(name, settings, "");
}
protected void createIndex(String name, Settings settings, String mapping) throws IOException {
assertOK(client().performRequest("PUT", name, Collections.emptyMap(),
protected static void createIndex(String name, Settings settings, String mapping) throws IOException {
assertOK(client().performRequest(HttpPut.METHOD_NAME, name, Collections.emptyMap(),
new StringEntity("{ \"settings\": " + Strings.toString(settings)
+ ", \"mappings\" : {" + mapping + "} }", ContentType.APPLICATION_JSON)));
}
protected void updateIndexSetting(String index, Settings.Builder settings) throws IOException {
updateIndexSetting(index, settings.build());
protected static void updateIndexSettings(String index, Settings.Builder settings) throws IOException {
updateIndexSettings(index, settings.build());
}
private void updateIndexSetting(String index, Settings settings) throws IOException {
private static void updateIndexSettings(String index, Settings settings) throws IOException {
assertOK(client().performRequest("PUT", index + "/_settings", Collections.emptyMap(),
new StringEntity(Strings.toString(settings), ContentType.APPLICATION_JSON)));
}
protected static boolean indexExists(String index) throws IOException {
Response response = client().performRequest(HttpHead.METHOD_NAME, index);
return RestStatus.OK.getStatus() == response.getStatusLine().getStatusCode();
}
protected static void closeIndex(String index) throws IOException {
Response response = client().performRequest(HttpPost.METHOD_NAME, index + "/_close");
assertThat(response.getStatusLine().getStatusCode(), equalTo(RestStatus.OK.getStatus()));
}
protected static boolean aliasExists(String alias) throws IOException {
Response response = client().performRequest(HttpHead.METHOD_NAME, "/_alias/" + alias);
return RestStatus.OK.getStatus() == response.getStatusLine().getStatusCode();
}
protected static boolean aliasExists(String index, String alias) throws IOException {
Response response = client().performRequest(HttpHead.METHOD_NAME, "/" + index + "/_alias/" + alias);
return RestStatus.OK.getStatus() == response.getStatusLine().getStatusCode();
}
@SuppressWarnings("unchecked")
protected static Map<String, Object> getAlias(final String index, final String alias) throws IOException {
String endpoint = "/_alias";
if (false == Strings.isEmpty(index)) {
endpoint = index + endpoint;
}
if (false == Strings.isEmpty(alias)) {
endpoint = endpoint + "/" + alias;
}
Map<String, Object> getAliasResponse = getAsMap(endpoint);
return (Map<String, Object>)XContentMapValues.extractValue(index + ".aliases." + alias, getAliasResponse);
}
protected static Map<String, Object> getAsMap(final String endpoint) throws IOException {
Response response = client().performRequest(HttpGet.METHOD_NAME, endpoint);
XContentType entityContentType = XContentType.fromMediaTypeOrFormat(response.getEntity().getContentType().getValue());
Map<String, Object> responseEntity = XContentHelper.convertToMap(entityContentType.xContent(),
response.getEntity().getContent(), false);
assertNotNull(responseEntity);
return responseEntity;
}
}