diff --git a/core/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequest.java b/core/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequest.java index 10d780a005b..9e98418f184 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequest.java +++ b/core/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequest.java @@ -70,14 +70,16 @@ public class RolloverRequest extends AcknowledgedRequest implem } private String alias; + private String newIndexName; private boolean dryRun; private Set conditions = new HashSet<>(2); private CreateIndexRequest createIndexRequest = new CreateIndexRequest("_na_"); RolloverRequest() {} - public RolloverRequest(String alias) { + public RolloverRequest(String alias, String newIndexName) { this.alias = alias; + this.newIndexName = newIndexName; } @Override @@ -96,6 +98,7 @@ public class RolloverRequest extends AcknowledgedRequest implem public void readFrom(StreamInput in) throws IOException { super.readFrom(in); alias = in.readString(); + newIndexName = in.readOptionalString(); dryRun = in.readBoolean(); int size = in.readVInt(); for (int i = 0; i < size; i++) { @@ -109,6 +112,7 @@ public class RolloverRequest extends AcknowledgedRequest implem public void writeTo(StreamOutput out) throws IOException { super.writeTo(out); out.writeString(alias); + out.writeOptionalString(newIndexName); out.writeBoolean(dryRun); out.writeVInt(conditions.size()); for (Condition condition : conditions) { @@ -134,6 +138,12 @@ public class RolloverRequest extends AcknowledgedRequest implem this.alias = alias; } + /** + * Sets the alias to rollover to another index + */ + public void setNewIndexName(String newIndexName) { + this.newIndexName = newIndexName; + } /** * Sets if the rollover should not be executed when conditions are met */ @@ -175,6 +185,10 @@ public class RolloverRequest extends AcknowledgedRequest implem return alias; } + String getNewIndexName() { + return newIndexName; + } + CreateIndexRequest getCreateIndexRequest() { return createIndexRequest; } diff --git a/core/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestBuilder.java b/core/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestBuilder.java index 8beebc2e516..e9b4351fc5d 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestBuilder.java +++ b/core/src/main/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestBuilder.java @@ -31,8 +31,13 @@ public class RolloverRequestBuilder extends MasterNodeOperationRequestBuilder conditionResults = evaluateConditions(rolloverRequest.getConditions(), statsResponse.getTotal().getDocs(), metaData.index(sourceIndexName)); - final String rolloverIndexName = generateRolloverIndexName(sourceIndexName); + final String rolloverIndexName = (rolloverRequest.getNewIndexName() != null) + ? rolloverRequest.getNewIndexName() + : generateRolloverIndexName(sourceIndexName); if (rolloverRequest.isDryRun()) { listener.onResponse( new RolloverResponse(sourceIndexName, rolloverIndexName, conditionResults, true, false)); diff --git a/core/src/main/java/org/elasticsearch/cluster/metadata/MetaDataMappingService.java b/core/src/main/java/org/elasticsearch/cluster/metadata/MetaDataMappingService.java index a41d02d28fa..a98f2148da8 100644 --- a/core/src/main/java/org/elasticsearch/cluster/metadata/MetaDataMappingService.java +++ b/core/src/main/java/org/elasticsearch/cluster/metadata/MetaDataMappingService.java @@ -299,7 +299,7 @@ public class MetaDataMappingService extends AbstractComponent { assert mappingType != null; if (!MapperService.DEFAULT_MAPPING.equals(mappingType) && mappingType.charAt(0) == '_') { - throw new InvalidTypeNameException("Document mapping type name can't start with '_'"); + throw new InvalidTypeNameException("Document mapping type name can't start with '_', found: [" + mappingType + "]"); } MetaData.Builder builder = MetaData.builder(metaData); for (Tuple toUpdate : updateList) { diff --git a/core/src/main/java/org/elasticsearch/rest/action/admin/indices/RestRolloverIndexAction.java b/core/src/main/java/org/elasticsearch/rest/action/admin/indices/RestRolloverIndexAction.java index 635e22ce83c..7eecaaa738c 100644 --- a/core/src/main/java/org/elasticsearch/rest/action/admin/indices/RestRolloverIndexAction.java +++ b/core/src/main/java/org/elasticsearch/rest/action/admin/indices/RestRolloverIndexAction.java @@ -38,12 +38,13 @@ public class RestRolloverIndexAction extends BaseRestHandler { public RestRolloverIndexAction(Settings settings, RestController controller, Client client) { super(settings, client); controller.registerHandler(RestRequest.Method.POST, "/{index}/_rollover", this); + controller.registerHandler(RestRequest.Method.POST, "/{index}/_rollover/{new_index}", this); } @SuppressWarnings({"unchecked"}) @Override public void handleRequest(final RestRequest request, final RestChannel channel, final Client client) { - RolloverRequest rolloverIndexRequest = new RolloverRequest(request.param("index")); + RolloverRequest rolloverIndexRequest = new RolloverRequest(request.param("index"), request.param("new_index")); if (request.hasContent()) { rolloverIndexRequest.source(request.content()); } diff --git a/core/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverIT.java b/core/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverIT.java index a47c91acc0f..b45383c47e4 100644 --- a/core/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverIT.java +++ b/core/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverIT.java @@ -130,6 +130,24 @@ public class RolloverIT extends ESIntegTestCase { assertNull(newIndex); } + public void testRolloverWithNewIndexName() throws Exception { + assertAcked(prepareCreate("test_index").addAlias(new Alias("test_alias")).get()); + index("test_index", "type1", "1", "field", "value"); + flush("test_index"); + final RolloverResponse response = client().admin().indices().prepareRolloverIndex("test_alias") + .setNewIndexName("test_new_index").get(); + assertThat(response.getOldIndex(), equalTo("test_index")); + assertThat(response.getNewIndex(), equalTo("test_new_index")); + assertThat(response.isDryRun(), equalTo(false)); + assertThat(response.isRolledOver(), equalTo(true)); + assertThat(response.getConditionStatus().size(), equalTo(0)); + final ClusterState state = client().admin().cluster().prepareState().get().getState(); + final IndexMetaData oldIndex = state.metaData().index("test_index"); + assertFalse(oldIndex.getAliases().containsKey("test_alias")); + final IndexMetaData newIndex = state.metaData().index("test_new_index"); + assertTrue(newIndex.getAliases().containsKey("test_alias")); + } + public void testRolloverOnExistingIndex() throws Exception { assertAcked(prepareCreate("test_index-0").addAlias(new Alias("test_alias")).get()); index("test_index-0", "type1", "1", "field", "value"); diff --git a/core/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestTests.java b/core/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestTests.java index 754e4c419bd..7f4db3b8409 100644 --- a/core/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestTests.java +++ b/core/src/test/java/org/elasticsearch/action/admin/indices/rollover/RolloverRequestTests.java @@ -31,7 +31,7 @@ import static org.hamcrest.Matchers.equalTo; public class RolloverRequestTests extends ESTestCase { public void testConditionsParsing() throws Exception { - final RolloverRequest request = new RolloverRequest(randomAsciiOfLength(10)); + final RolloverRequest request = new RolloverRequest(randomAsciiOfLength(10), randomAsciiOfLength(10)); final XContentBuilder builder = XContentFactory.jsonBuilder() .startObject() .startObject("conditions") @@ -56,7 +56,7 @@ public class RolloverRequestTests extends ESTestCase { } public void testParsingWithIndexSettings() throws Exception { - final RolloverRequest request = new RolloverRequest(randomAsciiOfLength(10)); + final RolloverRequest request = new RolloverRequest(randomAsciiOfLength(10), randomAsciiOfLength(10)); final XContentBuilder builder = XContentFactory.jsonBuilder() .startObject() .startObject("conditions") diff --git a/core/src/test/java/org/elasticsearch/action/admin/indices/rollover/TransportRolloverActionTests.java b/core/src/test/java/org/elasticsearch/action/admin/indices/rollover/TransportRolloverActionTests.java index 28c0a6e3787..7d163630afb 100644 --- a/core/src/test/java/org/elasticsearch/action/admin/indices/rollover/TransportRolloverActionTests.java +++ b/core/src/test/java/org/elasticsearch/action/admin/indices/rollover/TransportRolloverActionTests.java @@ -91,7 +91,7 @@ public class TransportRolloverActionTests extends ESTestCase { String sourceAlias = randomAsciiOfLength(10); String sourceIndex = randomAsciiOfLength(10); String targetIndex = randomAsciiOfLength(10); - final RolloverRequest rolloverRequest = new RolloverRequest(sourceAlias); + final RolloverRequest rolloverRequest = new RolloverRequest(sourceAlias, targetIndex); final IndicesAliasesClusterStateUpdateRequest updateRequest = TransportRolloverAction.prepareRolloverAliasesUpdateRequest(sourceIndex, targetIndex, rolloverRequest); @@ -137,13 +137,16 @@ public class TransportRolloverActionTests extends ESTestCase { ).build(); expectThrows(IllegalArgumentException.class, () -> - TransportRolloverAction.validate(metaData, new RolloverRequest(aliasWithMultipleIndices))); + TransportRolloverAction.validate(metaData, new RolloverRequest(aliasWithMultipleIndices, + randomAsciiOfLength(10)))); expectThrows(IllegalArgumentException.class, () -> - TransportRolloverAction.validate(metaData, new RolloverRequest(randomFrom(index1, index2)))); + TransportRolloverAction.validate(metaData, new RolloverRequest(randomFrom(index1, index2), + randomAsciiOfLength(10)))); expectThrows(IllegalArgumentException.class, () -> - TransportRolloverAction.validate(metaData, new RolloverRequest(randomAsciiOfLength(5))) + TransportRolloverAction.validate(metaData, new RolloverRequest(randomAsciiOfLength(5), + randomAsciiOfLength(10))) ); - TransportRolloverAction.validate(metaData, new RolloverRequest(alias)); + TransportRolloverAction.validate(metaData, new RolloverRequest(alias, randomAsciiOfLength(10))); } public void testGenerateRolloverIndexName() throws Exception { @@ -162,7 +165,7 @@ public class TransportRolloverActionTests extends ESTestCase { public void testCreateIndexRequest() throws Exception { String alias = randomAsciiOfLength(10); String rolloverIndex = randomAsciiOfLength(10); - final RolloverRequest rolloverRequest = new RolloverRequest(alias); + final RolloverRequest rolloverRequest = new RolloverRequest(alias, randomAsciiOfLength(10)); final Settings settings = Settings.builder() .put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT) .put(IndexMetaData.SETTING_INDEX_UUID, UUIDs.randomBase64UUID()) diff --git a/docs/reference/indices/rollover-index.asciidoc b/docs/reference/indices/rollover-index.asciidoc index 9deb8cc3c7f..b5c845f7360 100644 --- a/docs/reference/indices/rollover-index.asciidoc +++ b/docs/reference/indices/rollover-index.asciidoc @@ -4,9 +4,7 @@ The rollover index API allows to switch the index pointed to by an alias given some predicates. In order to rollover an index, the provided alias has to point to a single index. Upon satisfying any of the predicates, the alias is switched to point to the rollover index, if the rollover index -already exists, the rollover fails. The rollover API requires the old concrete index name to have -`{index_prefix}-{num}` format, as rollover index name is generated following `{index_prefix}-{num+1}` -format. +already exists, the rollover fails. This API is syntactic sugar for changing the index pointed to by an alias given some predicate. @@ -14,18 +12,18 @@ The rollover API must be used against an alias that points to a single index: [source,js] -------------------------------------------------- -$ curl -XPUT 'http://localhost:9200/index-1/' -d '{ +$ curl -XPUT 'http://localhost:9200/index1' -d '{ "aliases" : { "index_alias": {} } }' -------------------------------------------------- -To rollover `index_alias` to point to a new index: +To rollover `index_alias` to point to a new index `index2`: [source,js] -------------------------------------------------- -$ curl -XPOST 'http://localhost:9200/index_alias/_rollover' -d '{ +$ curl -XPOST 'http://localhost:9200/index_alias/_rollover/index2' -d '{ "conditions" : { "max_age": "7d", <1> "max_docs": 1000 <2> @@ -35,10 +33,14 @@ $ curl -XPOST 'http://localhost:9200/index_alias/_rollover' -d '{ <1> Sets a condition that the index has to be at least 7 days old <2> Sets a condition that the index has to have at least a 1000 documents -The API call above switches the index pointed to by `index_alias` from `index-1` to `index-2`, if any -of the conditions are met. `index-2` is created (using matching <> if available). +The API call above switches the index pointed to by `index_alias` from `index1` to `index2`, if any +of the conditions are met. `index2` is created (using matching <> if available). The API call returns immediately if none of the conditions are met. +The rollover API can be used without specifying the name for the new index. In this case, the API requires +the old concrete index name to have `{index_prefix}-{num}` format, as rollover index name is generated +following `{index_prefix}-{num+1}` format. + The `_rollover` API is similar to <> and accepts `settings`, `mappings` and `aliases` to override the index create request for the rollover index. diff --git a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.rollover.json b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.rollover.json index 7ba7d9cd29c..d3660c4a679 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/api/indices.rollover.json +++ b/rest-api-spec/src/main/resources/rest-api-spec/api/indices.rollover.json @@ -3,13 +3,18 @@ "documentation": "http://www.elastic.co/guide/en/elasticsearch/reference/master/indices-rollover-index.html", "methods": ["POST"], "url": { - "path": "/{alias}/_rollover", - "paths": ["/{alias}/_rollover"], + "path": "/{alias}/_rollover}", + "paths": ["/{alias}/_rollover", "/{alias}/_rollover/{new_index}"], "parts": { "alias": { "type" : "string", "required" : true, "description" : "The name of the alias to rollover" + }, + "new_index": { + "type" : "string", + "required" : false, + "description" : "The name of the rollover index" } }, "params": {