Add Indices Aliases API to the high level REST client (#27876)
Relates to #27205
This commit is contained in:
parent
0c83240b5f
commit
9db23e48cd
|
@ -23,6 +23,8 @@ import org.apache.http.Header;
|
|||
import org.elasticsearch.action.ActionListener;
|
||||
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;
|
||||
|
@ -111,7 +113,32 @@ public final class IndicesClient {
|
|||
public void putMappingAsync(PutMappingRequest putMappingRequest, ActionListener<PutMappingResponse> listener,
|
||||
Header... headers) {
|
||||
restHighLevelClient.performRequestAsyncAndParseEntity(putMappingRequest, Request::putMapping, PutMappingResponse::fromXContent,
|
||||
listener, Collections.emptySet(), headers);
|
||||
listener, Collections.emptySet(), headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates aliases using the Index Aliases API
|
||||
* <p>
|
||||
* See <a href=
|
||||
* "https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html">
|
||||
* Index Aliases API on elastic.co</a>
|
||||
*/
|
||||
public IndicesAliasesResponse updateAliases(IndicesAliasesRequest indicesAliasesRequest, Header... headers) throws IOException {
|
||||
return restHighLevelClient.performRequestAndParseEntity(indicesAliasesRequest, Request::updateAliases,
|
||||
IndicesAliasesResponse::fromXContent, Collections.emptySet(), headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously updates aliases using the Index Aliases API
|
||||
* <p>
|
||||
* See <a href=
|
||||
* "https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html">
|
||||
* Index Aliases API on elastic.co</a>
|
||||
*/
|
||||
public void updateAliasesAsync(IndicesAliasesRequest indicesAliasesRequestRequest, ActionListener<IndicesAliasesResponse> listener,
|
||||
Header... headers) {
|
||||
restHighLevelClient.performRequestAsyncAndParseEntity(indicesAliasesRequestRequest, Request::updateAliases,
|
||||
IndicesAliasesResponse::fromXContent, listener, Collections.emptySet(), headers);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.apache.http.entity.ContentType;
|
|||
import org.apache.lucene.util.BytesRef;
|
||||
import org.elasticsearch.action.DocWriteRequest;
|
||||
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
|
||||
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
|
||||
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;
|
||||
|
@ -178,6 +179,15 @@ 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);
|
||||
}
|
||||
|
||||
static Request putMapping(PutMappingRequest putMappingRequest) throws IOException {
|
||||
// The concreteIndex is an internal concept, not applicable to requests made over the REST API.
|
||||
|
|
|
@ -20,9 +20,13 @@
|
|||
package org.elasticsearch.client;
|
||||
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.ElasticsearchStatusException;
|
||||
import org.elasticsearch.action.admin.indices.alias.Alias;
|
||||
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.IndicesAliasesRequest.AliasActions;
|
||||
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;
|
||||
|
@ -32,6 +36,7 @@ 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.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;
|
||||
|
@ -43,7 +48,9 @@ import java.io.IOException;
|
|||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_REPLICAS;
|
||||
import static org.hamcrest.CoreMatchers.hasItem;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
|
||||
public class IndicesClientIT extends ESRestHighLevelClientTestCase {
|
||||
|
||||
|
@ -165,6 +172,97 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testUpdateAliases() throws IOException {
|
||||
String index = "index";
|
||||
String alias = "alias";
|
||||
|
||||
createIndex(index);
|
||||
assertThat(aliasExists(index, alias), equalTo(false));
|
||||
assertThat(aliasExists(alias), equalTo(false));
|
||||
|
||||
IndicesAliasesRequest aliasesAddRequest = new IndicesAliasesRequest();
|
||||
AliasActions addAction = new AliasActions(AliasActions.Type.ADD).index(index).aliases(alias);
|
||||
addAction.routing("routing").searchRouting("search_routing").filter("{\"term\":{\"year\":2016}}");
|
||||
aliasesAddRequest.addAliasAction(addAction);
|
||||
IndicesAliasesResponse aliasesAddResponse = execute(aliasesAddRequest, highLevelClient().indices()::updateAliases,
|
||||
highLevelClient().indices()::updateAliasesAsync);
|
||||
assertTrue(aliasesAddResponse.isAcknowledged());
|
||||
assertThat(aliasExists(alias), equalTo(true));
|
||||
assertThat(aliasExists(index, alias), equalTo(true));
|
||||
Map<String, Object> getAlias = getAlias(index, alias);
|
||||
assertThat(getAlias.get("index_routing"), equalTo("routing"));
|
||||
assertThat(getAlias.get("search_routing"), equalTo("search_routing"));
|
||||
Map<String, Object> filter = (Map<String, Object>) getAlias.get("filter");
|
||||
Map<String, Object> term = (Map<String, Object>) filter.get("term");
|
||||
assertEquals(2016, term.get("year"));
|
||||
|
||||
String alias2 = "alias2";
|
||||
IndicesAliasesRequest aliasesAddRemoveRequest = new IndicesAliasesRequest();
|
||||
addAction = new AliasActions(AliasActions.Type.ADD).indices(index).alias(alias2);
|
||||
aliasesAddRemoveRequest.addAliasAction(addAction);
|
||||
AliasActions removeAction = new AliasActions(AliasActions.Type.REMOVE).index(index).alias(alias);
|
||||
aliasesAddRemoveRequest.addAliasAction(removeAction);
|
||||
IndicesAliasesResponse aliasesAddRemoveResponse = execute(aliasesAddRemoveRequest, highLevelClient().indices()::updateAliases,
|
||||
highLevelClient().indices()::updateAliasesAsync);
|
||||
assertTrue(aliasesAddRemoveResponse.isAcknowledged());
|
||||
assertThat(aliasExists(alias), equalTo(false));
|
||||
assertThat(aliasExists(alias2), equalTo(true));
|
||||
assertThat(aliasExists(index, alias), equalTo(false));
|
||||
assertThat(aliasExists(index, alias2), equalTo(true));
|
||||
|
||||
IndicesAliasesRequest aliasesRemoveIndexRequest = new IndicesAliasesRequest();
|
||||
AliasActions removeIndexAction = new AliasActions(AliasActions.Type.REMOVE_INDEX).index(index);
|
||||
aliasesRemoveIndexRequest.addAliasAction(removeIndexAction);
|
||||
IndicesAliasesResponse aliasesRemoveIndexResponse = execute(aliasesRemoveIndexRequest, highLevelClient().indices()::updateAliases,
|
||||
highLevelClient().indices()::updateAliasesAsync);
|
||||
assertTrue(aliasesRemoveIndexResponse.isAcknowledged());
|
||||
assertThat(aliasExists(alias), equalTo(false));
|
||||
assertThat(aliasExists(alias2), equalTo(false));
|
||||
assertThat(aliasExists(index, alias), equalTo(false));
|
||||
assertThat(aliasExists(index, alias2), equalTo(false));
|
||||
assertThat(indexExists(index), equalTo(false));
|
||||
}
|
||||
|
||||
public void testAliasesNonExistentIndex() throws IOException {
|
||||
String index = "index";
|
||||
String alias = "alias";
|
||||
String nonExistentIndex = "non_existent_index";
|
||||
|
||||
IndicesAliasesRequest nonExistentIndexRequest = new IndicesAliasesRequest();
|
||||
nonExistentIndexRequest.addAliasAction(new AliasActions(AliasActions.Type.ADD).index(nonExistentIndex).alias(alias));
|
||||
ElasticsearchException exception = expectThrows(ElasticsearchException.class, () -> execute(nonExistentIndexRequest,
|
||||
highLevelClient().indices()::updateAliases, highLevelClient().indices()::updateAliasesAsync));
|
||||
assertThat(exception.status(), equalTo(RestStatus.NOT_FOUND));
|
||||
assertThat(exception.getMessage(), equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]"));
|
||||
assertThat(exception.getMetadata("es.index"), hasItem(nonExistentIndex));
|
||||
|
||||
createIndex(index);
|
||||
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));
|
||||
exception = expectThrows(ElasticsearchStatusException.class,
|
||||
() -> execute(mixedRequest, highLevelClient().indices()::updateAliases, highLevelClient().indices()::updateAliasesAsync));
|
||||
assertThat(exception.status(), equalTo(RestStatus.NOT_FOUND));
|
||||
assertThat(exception.getMessage(), equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]"));
|
||||
assertThat(exception.getMetadata("es.index"), hasItem(nonExistentIndex));
|
||||
assertThat(exception.getMetadata("es.index"), not(hasItem(index)));
|
||||
assertThat(aliasExists(index, alias), equalTo(false));
|
||||
assertThat(aliasExists(alias), equalTo(false));
|
||||
|
||||
IndicesAliasesRequest removeIndexRequest = new IndicesAliasesRequest();
|
||||
removeIndexRequest.addAliasAction(new AliasActions(AliasActions.Type.ADD).index(nonExistentIndex).alias(alias));
|
||||
removeIndexRequest.addAliasAction(new AliasActions(AliasActions.Type.REMOVE_INDEX).indices(nonExistentIndex));
|
||||
exception = expectThrows(ElasticsearchException.class, () -> execute(removeIndexRequest, highLevelClient().indices()::updateAliases,
|
||||
highLevelClient().indices()::updateAliasesAsync));
|
||||
assertThat(exception.status(), equalTo(RestStatus.NOT_FOUND));
|
||||
assertThat(exception.getMessage(), equalTo("Elasticsearch exception [type=index_not_found_exception, reason=no such index]"));
|
||||
assertThat(exception.getMetadata("es.index"), hasItem(nonExistentIndex));
|
||||
assertThat(exception.getMetadata("es.index"), not(hasItem(index)));
|
||||
assertThat(aliasExists(index, alias), equalTo(false));
|
||||
assertThat(aliasExists(alias), equalTo(false));
|
||||
}
|
||||
|
||||
public void testOpenExistingIndex() throws IOException {
|
||||
String index = "index";
|
||||
createIndex(index);
|
||||
|
@ -245,6 +343,16 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase {
|
|||
assertThat(response.getStatusLine().getStatusCode(), equalTo(RestStatus.OK.getStatus()));
|
||||
}
|
||||
|
||||
private static boolean aliasExists(String alias) throws IOException {
|
||||
Response response = client().performRequest("HEAD", "/_alias/" + alias);
|
||||
return RestStatus.OK.getStatus() == response.getStatusLine().getStatusCode();
|
||||
}
|
||||
|
||||
private static boolean aliasExists(String index, String alias) throws IOException {
|
||||
Response response = client().performRequest("HEAD", "/" + index + "/_alias/" + alias);
|
||||
return RestStatus.OK.getStatus() == response.getStatusLine().getStatusCode();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> getIndexMetadata(String index) throws IOException {
|
||||
Response response = client().performRequest("GET", index);
|
||||
|
@ -258,4 +366,26 @@ public class IndicesClientIT extends ESRestHighLevelClientTestCase {
|
|||
|
||||
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 = performGet(endpoint);
|
||||
return (Map) ((Map) ((Map) performGet.get(index)).get("aliases")).get(alias);
|
||||
}
|
||||
|
||||
private static Map<String, Object> performGet(final String endpoint) throws IOException {
|
||||
Response response = client().performRequest("GET", 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ import org.apache.http.entity.StringEntity;
|
|||
import org.apache.http.util.EntityUtils;
|
||||
import org.elasticsearch.action.DocWriteRequest;
|
||||
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
|
||||
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
|
||||
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions;
|
||||
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;
|
||||
|
@ -93,6 +95,7 @@ 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.alias.RandomAliasActionsGenerator.randomAliasAction;
|
||||
import static org.elasticsearch.search.RandomSearchRequestGenerator.randomSearchRequest;
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
|
@ -318,6 +321,21 @@ public class RequestTests extends ESTestCase {
|
|||
assertToXContentBody(createIndexRequest, request.getEntity());
|
||||
}
|
||||
|
||||
public void testUpdateAliases() throws IOException {
|
||||
IndicesAliasesRequest indicesAliasesRequest = new IndicesAliasesRequest();
|
||||
AliasActions aliasAction = randomAliasAction();
|
||||
indicesAliasesRequest.addAliasAction(aliasAction);
|
||||
|
||||
Map<String, String> expectedParams = new HashMap<>();
|
||||
setRandomTimeout(indicesAliasesRequest::timeout, AcknowledgedRequest.DEFAULT_ACK_TIMEOUT, expectedParams);
|
||||
setRandomMasterTimeout(indicesAliasesRequest, expectedParams);
|
||||
|
||||
Request request = Request.updateAliases(indicesAliasesRequest);
|
||||
assertEquals("/_aliases", request.getEndpoint());
|
||||
assertEquals(expectedParams, request.getParameters());
|
||||
assertToXContentBody(indicesAliasesRequest, request.getEntity());
|
||||
}
|
||||
|
||||
public void testPutMapping() throws IOException {
|
||||
PutMappingRequest putMappingRequest = new PutMappingRequest();
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@ import org.elasticsearch.action.ActionListener;
|
|||
import org.elasticsearch.action.admin.indices.alias.Alias;
|
||||
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.IndicesAliasesRequest.AliasActions;
|
||||
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;
|
||||
|
@ -444,4 +447,68 @@ public class IndicesClientDocumentationIT extends ESRestHighLevelClientTestCase
|
|||
// end::close-index-notfound
|
||||
}
|
||||
}
|
||||
|
||||
public void testIndicesAliases() throws IOException {
|
||||
RestHighLevelClient client = highLevelClient();
|
||||
|
||||
{
|
||||
CreateIndexResponse createIndexResponse = client.indices().create(new CreateIndexRequest("index1"));
|
||||
assertTrue(createIndexResponse.isAcknowledged());
|
||||
createIndexResponse = client.indices().create(new CreateIndexRequest("index2"));
|
||||
assertTrue(createIndexResponse.isAcknowledged());
|
||||
createIndexResponse = client.indices().create(new CreateIndexRequest("index3"));
|
||||
assertTrue(createIndexResponse.isAcknowledged());
|
||||
createIndexResponse = client.indices().create(new CreateIndexRequest("index4"));
|
||||
assertTrue(createIndexResponse.isAcknowledged());
|
||||
}
|
||||
|
||||
{
|
||||
// tag::update-aliases-request
|
||||
IndicesAliasesRequest request = new IndicesAliasesRequest(); // <1>
|
||||
AliasActions aliasAction = new AliasActions(AliasActions.Type.ADD).index("index1").alias("alias1"); // <2>
|
||||
request.addAliasAction(aliasAction); // <3>
|
||||
// end::update-aliases-request
|
||||
|
||||
// tag::update-aliases-request2
|
||||
AliasActions addIndexAction = new AliasActions(AliasActions.Type.ADD).index("index1").alias("alias1")
|
||||
.filter("{\"term\":{\"year\":2016}}"); // <1>
|
||||
AliasActions addIndicesAction = new AliasActions(AliasActions.Type.ADD).indices("index1", "index2").alias("alias2")
|
||||
.routing("1"); // <2>
|
||||
AliasActions removeAction = new AliasActions(AliasActions.Type.REMOVE).index("index3").alias("alias3"); // <3>
|
||||
AliasActions removeIndexAction = new AliasActions(AliasActions.Type.REMOVE_INDEX).index("index4"); // <4>
|
||||
// end::update-aliases-request2
|
||||
|
||||
// tag::update-aliases-request-timeout
|
||||
request.timeout(TimeValue.timeValueMinutes(2)); // <1>
|
||||
request.timeout("2m"); // <2>
|
||||
// end::update-aliases-request-timeout
|
||||
// tag::update-aliases-request-masterTimeout
|
||||
request.masterNodeTimeout(TimeValue.timeValueMinutes(1)); // <1>
|
||||
request.masterNodeTimeout("1m"); // <2>
|
||||
// end::update-aliases-request-masterTimeout
|
||||
|
||||
// tag::update-aliases-execute
|
||||
IndicesAliasesResponse indicesAliasesResponse = client.indices().updateAliases(request);
|
||||
// end::update-aliases-execute
|
||||
|
||||
// tag::update-aliases-response
|
||||
boolean acknowledged = indicesAliasesResponse.isAcknowledged(); // <1>
|
||||
// end::update-aliases-response
|
||||
assertTrue(acknowledged);
|
||||
|
||||
// tag::update-aliases-execute-async
|
||||
client.indices().updateAliasesAsync(request, new ActionListener<IndicesAliasesResponse>() {
|
||||
@Override
|
||||
public void onResponse(IndicesAliasesResponse indciesAliasesResponse) {
|
||||
// <1>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Exception e) {
|
||||
// <2>
|
||||
}
|
||||
});
|
||||
// end::update-aliases-execute-async
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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.alias;
|
||||
|
||||
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions;
|
||||
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.index.alias.RandomAliasActionsGenerator.randomAliasAction;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
|
||||
public class IndicesAliasesRequestTests extends ESTestCase {
|
||||
|
||||
public void testToAndFromXContent() throws IOException {
|
||||
IndicesAliasesRequest indicesAliasesRequest = createTestInstance();
|
||||
XContentType xContentType = randomFrom(XContentType.values());
|
||||
|
||||
BytesReference shuffled = toShuffledXContent(indicesAliasesRequest, xContentType, ToXContent.EMPTY_PARAMS, true, "filter");
|
||||
|
||||
IndicesAliasesRequest parsedIndicesAliasesRequest;
|
||||
try (XContentParser parser = createParser(xContentType.xContent(), shuffled)) {
|
||||
parsedIndicesAliasesRequest = IndicesAliasesRequest.fromXContent(parser);
|
||||
assertNull(parser.nextToken());
|
||||
}
|
||||
|
||||
for (int i = 0; i < parsedIndicesAliasesRequest.getAliasActions().size(); i++) {
|
||||
AliasActions expectedAction = indicesAliasesRequest.getAliasActions().get(i);
|
||||
AliasActions actualAction = parsedIndicesAliasesRequest.getAliasActions().get(i);
|
||||
assertThat(actualAction, equalTo(expectedAction));
|
||||
}
|
||||
}
|
||||
|
||||
private IndicesAliasesRequest createTestInstance() {
|
||||
int numItems = randomIntBetween(0, 32);
|
||||
IndicesAliasesRequest request = new IndicesAliasesRequest();
|
||||
if (randomBoolean()) {
|
||||
request.timeout(randomTimeValue());
|
||||
}
|
||||
|
||||
if (randomBoolean()) {
|
||||
request.masterNodeTimeout(randomTimeValue());
|
||||
}
|
||||
for (int i = 0; i < numItems; i++) {
|
||||
request.addAliasAction(randomAliasAction());
|
||||
}
|
||||
return request;
|
||||
}
|
||||
}
|
|
@ -8,6 +8,8 @@ include::close_index.asciidoc[]
|
|||
|
||||
include::putmapping.asciidoc[]
|
||||
|
||||
include::update_aliases.asciidoc[]
|
||||
|
||||
include::_index.asciidoc[]
|
||||
|
||||
include::get.asciidoc[]
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
[[java-rest-high-update-aliases]]
|
||||
=== Update Aliases API
|
||||
|
||||
[[java-rest-high-update-aliases-request]]
|
||||
==== Indices Aliases Request
|
||||
|
||||
The Update Aliases API allows aliasing an index with a name, with all APIs
|
||||
automatically converting the alias name to the actual index name.
|
||||
|
||||
An `IndicesAliasesRequest` must have at least one `AliasActions`:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[update-aliases-request]
|
||||
--------------------------------------------------
|
||||
<1> Creates an `IndicesAliasesRequest`
|
||||
<2> Creates an `AliasActions` that aliases index `test1` with `alias1`
|
||||
<3> Adds the alias action to the request
|
||||
|
||||
The following action types are supported: `add` - alias an index, `remove` -
|
||||
removes the alias associated with the index, and `remove_index` - deletes the
|
||||
index.
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[update-aliases-request2]
|
||||
--------------------------------------------------
|
||||
<1> Creates an alias `alias1` with an optional filter on field `year`
|
||||
<2> Creates an alias `alias2` associated with two indices and with an optional routing
|
||||
<3> Removes the associated alias `alias3`
|
||||
<4> `remove_index` is just like <<java-rest-high-delete-index>>
|
||||
|
||||
==== Optional arguments
|
||||
The following arguments can optionally be provided:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[update-aliases-request-timeout]
|
||||
--------------------------------------------------
|
||||
<1> Timeout to wait for the all the nodes to acknowledge the operation as a `TimeValue`
|
||||
<2> Timeout to wait for the all the nodes to acknowledge the operation as a `String`
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[update-aliases-request-masterTimeout]
|
||||
--------------------------------------------------
|
||||
<1> Timeout to connect to the master node as a `TimeValue`
|
||||
<2> Timeout to connect to the master node as a `String`
|
||||
|
||||
[[java-rest-high-update-aliases-sync]]
|
||||
==== Synchronous Execution
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[update-aliases-execute]
|
||||
--------------------------------------------------
|
||||
|
||||
[[java-rest-high-update-aliases-async]]
|
||||
==== Asynchronous Execution
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[update-aliases-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-update-aliases-response]]
|
||||
==== Indices Aliases Response
|
||||
|
||||
The returned `IndicesAliasesResponse` allows to retrieve information about the
|
||||
executed operation as follows:
|
||||
|
||||
["source","java",subs="attributes,callouts,macros"]
|
||||
--------------------------------------------------
|
||||
include-tagged::{doc-tests}/IndicesClientDocumentationIT.java[update-aliases-response]
|
||||
--------------------------------------------------
|
||||
<1> Indicates whether all of the nodes have acknowledged the request
|
|
@ -9,6 +9,7 @@ Indices APIs::
|
|||
* <<java-rest-high-open-index>>
|
||||
* <<java-rest-high-close-index>>
|
||||
* <<java-rest-high-put-mapping>>
|
||||
* <<java-rest-high-update-aliases>>
|
||||
|
||||
Single document APIs::
|
||||
* <<java-rest-high-document-index>>
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.elasticsearch.cluster.metadata.AliasAction;
|
|||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.ParsingException;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.io.stream.Writeable;
|
||||
|
@ -35,6 +36,7 @@ import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
|||
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser.ValueType;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
@ -56,7 +58,8 @@ import static org.elasticsearch.common.xcontent.ObjectParser.fromList;
|
|||
/**
|
||||
* A request to add/remove aliases for one or more indices.
|
||||
*/
|
||||
public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesRequest> {
|
||||
public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesRequest> implements ToXContentObject {
|
||||
|
||||
private List<AliasActions> allAliasActions = new ArrayList<>();
|
||||
|
||||
// indices options that require every specified index to exist, expand wildcards only to open
|
||||
|
@ -65,22 +68,37 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
|
|||
private static final IndicesOptions INDICES_OPTIONS = IndicesOptions.fromOptions(false, false, true, false, true, false, true);
|
||||
|
||||
public IndicesAliasesRequest() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Request to take one or more actions on one or more indexes and alias combinations.
|
||||
*/
|
||||
public static class AliasActions implements AliasesRequest, Writeable {
|
||||
public static class AliasActions implements AliasesRequest, Writeable, ToXContentObject {
|
||||
|
||||
private static final ParseField INDEX = new ParseField("index");
|
||||
private static final ParseField INDICES = new ParseField("indices");
|
||||
private static final ParseField ALIAS = new ParseField("alias");
|
||||
private static final ParseField ALIASES = new ParseField("aliases");
|
||||
private static final ParseField FILTER = new ParseField("filter");
|
||||
private static final ParseField ROUTING = new ParseField("routing");
|
||||
private static final ParseField INDEX_ROUTING = new ParseField("index_routing", "indexRouting", "index-routing");
|
||||
private static final ParseField SEARCH_ROUTING = new ParseField("search_routing", "searchRouting", "search-routing");
|
||||
|
||||
private static final ParseField ADD = new ParseField("add");
|
||||
private static final ParseField REMOVE = new ParseField("remove");
|
||||
private static final ParseField REMOVE_INDEX = new ParseField("remove_index");
|
||||
|
||||
public enum Type {
|
||||
ADD((byte) 0),
|
||||
REMOVE((byte) 1),
|
||||
REMOVE_INDEX((byte) 2);
|
||||
ADD((byte) 0, AliasActions.ADD),
|
||||
REMOVE((byte) 1, AliasActions.REMOVE),
|
||||
REMOVE_INDEX((byte) 2, AliasActions.REMOVE_INDEX);
|
||||
|
||||
private final byte value;
|
||||
private final String fieldName;
|
||||
|
||||
Type(byte value) {
|
||||
Type(byte value, ParseField field) {
|
||||
this.value = value;
|
||||
this.fieldName = field.getPreferredName();
|
||||
}
|
||||
|
||||
public byte value() {
|
||||
|
@ -125,29 +143,29 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
|
|||
throw new IllegalArgumentException("Only one of [index] and [indices] is supported");
|
||||
}
|
||||
action.index(index);
|
||||
}, new ParseField("index"));
|
||||
}, INDEX);
|
||||
parser.declareStringArray(fromList(String.class, (action, indices) -> {
|
||||
if (action.indices() != null) {
|
||||
throw new IllegalArgumentException("Only one of [index] and [indices] is supported");
|
||||
}
|
||||
action.indices(indices);
|
||||
}), new ParseField("indices"));
|
||||
}), INDICES);
|
||||
parser.declareString((action, alias) -> {
|
||||
if (action.aliases() != null && action.aliases().length != 0) {
|
||||
throw new IllegalArgumentException("Only one of [alias] and [aliases] is supported");
|
||||
}
|
||||
action.alias(alias);
|
||||
}, new ParseField("alias"));
|
||||
}, ALIAS);
|
||||
parser.declareStringArray(fromList(String.class, (action, aliases) -> {
|
||||
if (action.aliases() != null && action.aliases().length != 0) {
|
||||
throw new IllegalArgumentException("Only one of [alias] and [aliases] is supported");
|
||||
}
|
||||
action.aliases(aliases);
|
||||
}), new ParseField("aliases"));
|
||||
}), ALIASES);
|
||||
return parser;
|
||||
}
|
||||
|
||||
private static final ObjectParser<AliasActions, Void> ADD_PARSER = parser("add", AliasActions::add);
|
||||
private static final ObjectParser<AliasActions, Void> ADD_PARSER = parser(ADD.getPreferredName(), AliasActions::add);
|
||||
static {
|
||||
ADD_PARSER.declareObject(AliasActions::filter, (parser, m) -> {
|
||||
try {
|
||||
|
@ -155,14 +173,15 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
|
|||
} catch (IOException e) {
|
||||
throw new ParsingException(parser.getTokenLocation(), "Problems parsing [filter]", e);
|
||||
}
|
||||
}, new ParseField("filter"));
|
||||
}, FILTER);
|
||||
// Since we need to support numbers AND strings here we have to use ValueType.INT.
|
||||
ADD_PARSER.declareField(AliasActions::routing, XContentParser::text, new ParseField("routing"), ValueType.INT);
|
||||
ADD_PARSER.declareField(AliasActions::indexRouting, XContentParser::text, new ParseField("index_routing"), ValueType.INT);
|
||||
ADD_PARSER.declareField(AliasActions::searchRouting, XContentParser::text, new ParseField("search_routing"), ValueType.INT);
|
||||
ADD_PARSER.declareField(AliasActions::routing, XContentParser::text, ROUTING, ValueType.INT);
|
||||
ADD_PARSER.declareField(AliasActions::indexRouting, XContentParser::text, INDEX_ROUTING, ValueType.INT);
|
||||
ADD_PARSER.declareField(AliasActions::searchRouting, XContentParser::text, SEARCH_ROUTING, ValueType.INT);
|
||||
}
|
||||
private static final ObjectParser<AliasActions, Void> REMOVE_PARSER = parser("remove", AliasActions::remove);
|
||||
private static final ObjectParser<AliasActions, Void> REMOVE_INDEX_PARSER = parser("remove_index", AliasActions::removeIndex);
|
||||
private static final ObjectParser<AliasActions, Void> REMOVE_PARSER = parser(REMOVE.getPreferredName(), AliasActions::remove);
|
||||
private static final ObjectParser<AliasActions, Void> REMOVE_INDEX_PARSER = parser(REMOVE_INDEX.getPreferredName(),
|
||||
AliasActions::removeIndex);
|
||||
|
||||
/**
|
||||
* Parser for any one {@link AliasAction}.
|
||||
|
@ -183,9 +202,9 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
|
|||
return action;
|
||||
});
|
||||
static {
|
||||
PARSER.declareObject(optionalConstructorArg(), ADD_PARSER, new ParseField("add"));
|
||||
PARSER.declareObject(optionalConstructorArg(), REMOVE_PARSER, new ParseField("remove"));
|
||||
PARSER.declareObject(optionalConstructorArg(), REMOVE_INDEX_PARSER, new ParseField("remove_index"));
|
||||
PARSER.declareObject(optionalConstructorArg(), ADD_PARSER, ADD);
|
||||
PARSER.declareObject(optionalConstructorArg(), REMOVE_PARSER, REMOVE);
|
||||
PARSER.declareObject(optionalConstructorArg(), REMOVE_INDEX_PARSER, REMOVE_INDEX);
|
||||
}
|
||||
|
||||
private final AliasActions.Type type;
|
||||
|
@ -196,7 +215,7 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
|
|||
private String indexRouting;
|
||||
private String searchRouting;
|
||||
|
||||
AliasActions(AliasActions.Type type) {
|
||||
public AliasActions(AliasActions.Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
@ -402,6 +421,37 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
|
|||
return INDICES_OPTIONS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
builder.startObject(type.fieldName);
|
||||
if (null != indices && 0 != indices.length) {
|
||||
builder.array(INDICES.getPreferredName(), indices);
|
||||
}
|
||||
if (0 != aliases.length) {
|
||||
builder.array(ALIASES.getPreferredName(), aliases);
|
||||
}
|
||||
if (false == Strings.isEmpty(filter)) {
|
||||
builder.rawField(FILTER.getPreferredName(), new BytesArray(filter), XContentType.JSON);
|
||||
}
|
||||
if (false == Strings.isEmpty(routing)) {
|
||||
builder.field(ROUTING.getPreferredName(), routing);
|
||||
}
|
||||
if (false == Strings.isEmpty(indexRouting)) {
|
||||
builder.field(INDEX_ROUTING.getPreferredName(), indexRouting);
|
||||
}
|
||||
if (false == Strings.isEmpty(searchRouting)) {
|
||||
builder.field(SEARCH_ROUTING.getPreferredName(), searchRouting);
|
||||
}
|
||||
builder.endObject();
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static AliasActions fromXContent(XContentParser parser) throws IOException {
|
||||
return PARSER.apply(parser, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AliasActions["
|
||||
|
@ -478,4 +528,29 @@ public class IndicesAliasesRequest extends AcknowledgedRequest<IndicesAliasesReq
|
|||
public IndicesOptions indicesOptions() {
|
||||
return INDICES_OPTIONS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
builder.startArray("actions");
|
||||
for (AliasActions action : allAliasActions) {
|
||||
action.toXContent(builder, params);
|
||||
}
|
||||
builder.endArray();
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static final ObjectParser<IndicesAliasesRequest, Void> PARSER = new ObjectParser<>("aliases", IndicesAliasesRequest::new);
|
||||
static {
|
||||
PARSER.declareObjectArray((request, actions) -> {
|
||||
for (AliasActions action : actions) {
|
||||
request.addAliasAction(action);
|
||||
}
|
||||
}, AliasActions.PARSER, new ParseField("actions"));
|
||||
}
|
||||
|
||||
public static IndicesAliasesRequest fromXContent(XContentParser parser) throws IOException {
|
||||
return PARSER.apply(parser, null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,16 +22,25 @@ package org.elasticsearch.action.admin.indices.alias;
|
|||
import org.elasticsearch.action.support.master.AcknowledgedResponse;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A response for a add/remove alias action.
|
||||
*/
|
||||
public class IndicesAliasesResponse extends AcknowledgedResponse {
|
||||
public class IndicesAliasesResponse extends AcknowledgedResponse implements ToXContentObject {
|
||||
|
||||
private static final ConstructingObjectParser<IndicesAliasesResponse, Void> PARSER = new ConstructingObjectParser<>("indices_aliases",
|
||||
true, args -> new IndicesAliasesResponse((boolean) args[0]));
|
||||
static {
|
||||
declareAcknowledgedField(PARSER);
|
||||
}
|
||||
|
||||
IndicesAliasesResponse() {
|
||||
|
||||
}
|
||||
|
||||
IndicesAliasesResponse(boolean acknowledged) {
|
||||
|
@ -49,4 +58,16 @@ public class IndicesAliasesResponse extends AcknowledgedResponse {
|
|||
super.writeTo(out);
|
||||
writeAcknowledged(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
addAcknowledgedField(builder);
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static IndicesAliasesResponse fromXContent(XContentParser parser) throws IOException {
|
||||
return PARSER.apply(parser, null);
|
||||
}
|
||||
}
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
package org.elasticsearch.action.support.master;
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cluster.ack.AckedRequest;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
|
|
|
@ -24,7 +24,6 @@ import org.elasticsearch.common.io.stream.StreamInput;
|
|||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package org.elasticsearch.rest.action.admin.indices;
|
||||
|
||||
import com.carrotsearch.hppc.cursors.ObjectObjectCursor;
|
||||
|
||||
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
|
||||
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse;
|
||||
import org.elasticsearch.action.support.IndicesOptions;
|
||||
|
|
|
@ -36,14 +36,6 @@ import java.io.IOException;
|
|||
import static org.elasticsearch.rest.RestRequest.Method.POST;
|
||||
|
||||
public class RestIndicesAliasesAction extends BaseRestHandler {
|
||||
static final ObjectParser<IndicesAliasesRequest, Void> PARSER = new ObjectParser<>("aliases");
|
||||
static {
|
||||
PARSER.declareObjectArray((request, actions) -> {
|
||||
for (AliasActions action: actions) {
|
||||
request.addAliasAction(action);
|
||||
}
|
||||
}, AliasActions.PARSER, new ParseField("actions"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
|
@ -61,7 +53,7 @@ public class RestIndicesAliasesAction extends BaseRestHandler {
|
|||
indicesAliasesRequest.masterNodeTimeout(request.paramAsTime("master_timeout", indicesAliasesRequest.masterNodeTimeout()));
|
||||
indicesAliasesRequest.timeout(request.paramAsTime("timeout", indicesAliasesRequest.timeout()));
|
||||
try (XContentParser parser = request.contentParser()) {
|
||||
PARSER.parse(parser, indicesAliasesRequest, null);
|
||||
IndicesAliasesRequest.PARSER.parse(parser, indicesAliasesRequest, null);
|
||||
}
|
||||
if (indicesAliasesRequest.getAliasActions().isEmpty()) {
|
||||
throw new IllegalArgumentException("No action specified");
|
||||
|
|
|
@ -21,8 +21,10 @@ package org.elasticsearch.action.admin.indices.alias;
|
|||
|
||||
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions;
|
||||
import org.elasticsearch.common.ParsingException;
|
||||
import org.elasticsearch.common.bytes.BytesReference;
|
||||
import org.elasticsearch.common.io.stream.BytesStreamOutput;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
|
@ -30,13 +32,15 @@ import org.elasticsearch.common.xcontent.XContentType;
|
|||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.elasticsearch.index.alias.RandomAliasActionsGenerator.randomAliasAction;
|
||||
import static org.elasticsearch.index.alias.RandomAliasActionsGenerator.randomMap;
|
||||
import static org.elasticsearch.index.alias.RandomAliasActionsGenerator.randomRouting;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.Matchers.arrayContaining;
|
||||
import static org.hamcrest.Matchers.arrayWithSize;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
|
||||
public class AliasActionsTests extends ESTestCase {
|
||||
|
@ -58,8 +62,7 @@ public class AliasActionsTests extends ESTestCase {
|
|||
Exception e = expectThrows(IllegalArgumentException.class,
|
||||
() -> new AliasActions(randomFrom(AliasActions.Type.values())).index(null));
|
||||
assertEquals("[index] can't be empty string", e.getMessage());
|
||||
e = expectThrows(IllegalArgumentException.class,
|
||||
() -> new AliasActions(randomFrom(AliasActions.Type.values())).index(""));
|
||||
e = expectThrows(IllegalArgumentException.class, () -> new AliasActions(randomFrom(AliasActions.Type.values())).index(""));
|
||||
assertEquals("[index] can't be empty string", e.getMessage());
|
||||
e = expectThrows(IllegalArgumentException.class,
|
||||
() -> new AliasActions(randomFrom(AliasActions.Type.values())).indices((String[]) null));
|
||||
|
@ -110,8 +113,10 @@ public class AliasActionsTests extends ESTestCase {
|
|||
Object searchRouting = randomBoolean() ? randomRouting() : null;
|
||||
Object indexRouting = randomBoolean() ? randomBoolean() ? searchRouting : randomRouting() : null;
|
||||
XContentBuilder b = XContentBuilder.builder(randomFrom(XContentType.values()).xContent());
|
||||
b.startObject(); {
|
||||
b.startObject("add"); {
|
||||
b.startObject();
|
||||
{
|
||||
b.startObject("add");
|
||||
{
|
||||
if (indices.length > 1 || randomBoolean()) {
|
||||
b.array("indices", indices);
|
||||
} else {
|
||||
|
@ -161,8 +166,10 @@ public class AliasActionsTests extends ESTestCase {
|
|||
Object searchRouting = randomRouting();
|
||||
Object indexRouting = randomRouting();
|
||||
XContentBuilder b = XContentBuilder.builder(randomFrom(XContentType.values()).xContent());
|
||||
b.startObject(); {
|
||||
b.startObject("add"); {
|
||||
b.startObject();
|
||||
{
|
||||
b.startObject("add");
|
||||
{
|
||||
b.field("index", index);
|
||||
b.field("alias", alias);
|
||||
if (randomBoolean()) {
|
||||
|
@ -191,8 +198,10 @@ public class AliasActionsTests extends ESTestCase {
|
|||
String[] indices = generateRandomStringArray(10, 5, false, false);
|
||||
String[] aliases = generateRandomStringArray(10, 5, false, false);
|
||||
XContentBuilder b = XContentBuilder.builder(randomFrom(XContentType.values()).xContent());
|
||||
b.startObject(); {
|
||||
b.startObject("remove"); {
|
||||
b.startObject();
|
||||
{
|
||||
b.startObject("remove");
|
||||
{
|
||||
if (indices.length > 1 || randomBoolean()) {
|
||||
b.array("indices", indices);
|
||||
} else {
|
||||
|
@ -217,10 +226,12 @@ public class AliasActionsTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testParseRemoveIndex() throws IOException {
|
||||
String[] indices = randomBoolean() ? new String[] {randomAlphaOfLength(5)} : generateRandomStringArray(10, 5, false, false);
|
||||
String[] indices = randomBoolean() ? new String[] { randomAlphaOfLength(5) } : generateRandomStringArray(10, 5, false, false);
|
||||
XContentBuilder b = XContentBuilder.builder(randomFrom(XContentType.values()).xContent());
|
||||
b.startObject(); {
|
||||
b.startObject("remove_index"); {
|
||||
b.startObject();
|
||||
{
|
||||
b.startObject("remove_index");
|
||||
{
|
||||
if (indices.length > 1 || randomBoolean()) {
|
||||
b.array("indices", indices);
|
||||
} else {
|
||||
|
@ -241,8 +252,10 @@ public class AliasActionsTests extends ESTestCase {
|
|||
|
||||
public void testParseIndexAndIndicesThrowsError() throws IOException {
|
||||
XContentBuilder b = XContentBuilder.builder(randomFrom(XContentType.values()).xContent());
|
||||
b.startObject(); {
|
||||
b.startObject(randomFrom("add", "remove")); {
|
||||
b.startObject();
|
||||
{
|
||||
b.startObject(randomFrom("add", "remove"));
|
||||
{
|
||||
b.field("index", randomAlphaOfLength(5));
|
||||
b.array("indices", generateRandomStringArray(10, 5, false, false));
|
||||
b.field("alias", randomAlphaOfLength(5));
|
||||
|
@ -259,8 +272,10 @@ public class AliasActionsTests extends ESTestCase {
|
|||
|
||||
public void testParseAliasAndAliasesThrowsError() throws IOException {
|
||||
XContentBuilder b = XContentBuilder.builder(randomFrom(XContentType.values()).xContent());
|
||||
b.startObject(); {
|
||||
b.startObject(randomFrom("add", "remove")); {
|
||||
b.startObject();
|
||||
{
|
||||
b.startObject(randomFrom("add", "remove"));
|
||||
{
|
||||
b.field("index", randomAlphaOfLength(5));
|
||||
b.field("alias", randomAlphaOfLength(5));
|
||||
b.array("aliases", generateRandomStringArray(10, 5, false, false));
|
||||
|
@ -311,38 +326,17 @@ public class AliasActionsTests extends ESTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private Map<String, Object> randomMap(int maxDepth) {
|
||||
int members = between(0, 5);
|
||||
Map<String, Object> result = new HashMap<>(members);
|
||||
for (int i = 0; i < members; i++) {
|
||||
Object value;
|
||||
switch (between(0, 3)) {
|
||||
case 0:
|
||||
if (maxDepth > 0) {
|
||||
value = randomMap(maxDepth - 1);
|
||||
} else {
|
||||
value = randomAlphaOfLength(5);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
value = randomAlphaOfLength(5);
|
||||
break;
|
||||
case 2:
|
||||
value = randomBoolean();
|
||||
break;
|
||||
case 3:
|
||||
value = randomLong();
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException();
|
||||
public void testFromToXContent() throws IOException {
|
||||
for (int runs = 0; runs < 20; runs++) {
|
||||
AliasActions action = randomAliasAction();
|
||||
XContentType xContentType = randomFrom(XContentType.values());
|
||||
BytesReference shuffled = toShuffledXContent(action, xContentType, ToXContent.EMPTY_PARAMS, false, "filter");
|
||||
AliasActions parsedAction;
|
||||
try (XContentParser parser = createParser(xContentType.xContent(), shuffled)) {
|
||||
parsedAction = AliasActions.fromXContent(parser);
|
||||
assertNull(parser.nextToken());
|
||||
}
|
||||
result.put(randomAlphaOfLength(5), value);
|
||||
assertThat(parsedAction, equalTo(action));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Object randomRouting() {
|
||||
return randomBoolean() ? randomAlphaOfLength(5) : randomInt();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* 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.alias;
|
||||
|
||||
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.test.ESTestCase.between;
|
||||
import static org.elasticsearch.test.ESTestCase.randomAlphaOfLength;
|
||||
import static org.elasticsearch.test.ESTestCase.randomAlphaOfLengthBetween;
|
||||
import static org.elasticsearch.test.ESTestCase.randomBoolean;
|
||||
import static org.elasticsearch.test.ESTestCase.randomFrom;
|
||||
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 static AliasActions randomAliasAction() {
|
||||
return randomAliasAction(false);
|
||||
}
|
||||
|
||||
public static AliasActions randomAliasAction(boolean useStringAsFilter) {
|
||||
AliasActions action = new AliasActions(randomFrom(AliasActions.Type.values()));
|
||||
if (randomBoolean()) {
|
||||
action.index(randomAlphaOfLength(5));
|
||||
} else {
|
||||
int numIndices = randomIntBetween(1, 5);
|
||||
String[] indices = new String[numIndices];
|
||||
for (int i = 0; i < numIndices; i++) {
|
||||
indices[i] = "index-" + randomAlphaOfLengthBetween(2, 5).toLowerCase(Locale.ROOT);
|
||||
}
|
||||
action.indices(indices);
|
||||
}
|
||||
if (action.actionType() != AliasActions.Type.REMOVE_INDEX) {
|
||||
if (randomBoolean()) {
|
||||
action.alias(randomAlphaOfLength(5));
|
||||
} else {
|
||||
int numAliases = randomIntBetween(1, 5);
|
||||
String[] aliases = new String[numAliases];
|
||||
for (int i = 0; i < numAliases; i++) {
|
||||
aliases[i] = "alias-" + randomAlphaOfLengthBetween(2, 5).toLowerCase(Locale.ROOT);
|
||||
}
|
||||
action.aliases(aliases);
|
||||
}
|
||||
}
|
||||
if (action.actionType() == AliasActions.Type.ADD) {
|
||||
if (randomBoolean()) {
|
||||
if (useStringAsFilter) {
|
||||
action.filter(randomAlphaOfLength(5));
|
||||
} else {
|
||||
action.filter(randomMap(randomInt(5)));
|
||||
}
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
if (randomBoolean()) {
|
||||
action.routing(randomRouting().toString());
|
||||
} else {
|
||||
action.searchRouting(randomRouting().toString());
|
||||
action.indexRouting(randomRouting().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
public static Map<String, Object> randomMap(int maxDepth) {
|
||||
int members = between(0, 5);
|
||||
Map<String, Object> result = new HashMap<>(members);
|
||||
for (int i = 0; i < members; i++) {
|
||||
Object value;
|
||||
switch (between(0, 3)) {
|
||||
case 0:
|
||||
if (maxDepth > 0) {
|
||||
value = randomMap(maxDepth - 1);
|
||||
} else {
|
||||
value = randomAlphaOfLength(5);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
value = randomAlphaOfLength(5);
|
||||
break;
|
||||
case 2:
|
||||
value = randomBoolean();
|
||||
break;
|
||||
case 3:
|
||||
value = randomLong();
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
result.put(randomAlphaOfLength(5), value);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Object randomRouting() {
|
||||
return randomBoolean() ? randomAlphaOfLength(5) : randomInt();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue