forked from elastic/elasticsearch
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add rest endpoint for create_from_source_index (elastic#119250)
Add rest endpoint which creates a new index using the settings and mappings from an existing source index. Setting and mapping overrides can be added to the request which will override settings and mappings from the source index. Example: `PUT /_create_from/{source}/{dest}` Content is optional but can include a `settings_override` and `mappings_override` which will be combined with the settings and mappings from the source index to create the destination index.
- Loading branch information
1 parent
c3839e1
commit b34e278
Showing
9 changed files
with
367 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
pr: 119250 | ||
summary: Add rest endpoint for `create_from_source_index` | ||
area: Data streams | ||
type: enhancement | ||
issues: [] |
37 changes: 37 additions & 0 deletions
37
rest-api-spec/src/main/resources/rest-api-spec/api/migrate.create_from.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
{ | ||
"migrate.create_from":{ | ||
"documentation":{ | ||
"url":"https://www.elastic.co/guide/en/elasticsearch/reference/master/data-stream-reindex.html", | ||
"description":"This API creates a destination from a source index. It copies the mappings and settings from the source index while allowing request settings and mappings to override the source values." | ||
}, | ||
"stability":"experimental", | ||
"visibility":"private", | ||
"headers":{ | ||
"accept": [ "application/json"], | ||
"content_type": ["application/json"] | ||
}, | ||
"url":{ | ||
"paths":[ | ||
{ | ||
"path":"/_create_from/{source}/{dest}", | ||
"methods":[ "PUT", "POST"], | ||
"parts":{ | ||
"source":{ | ||
"type":"string", | ||
"description":"The source index name" | ||
}, | ||
"dest":{ | ||
"type":"string", | ||
"description":"The destination index name" | ||
} | ||
} | ||
} | ||
] | ||
}, | ||
"body":{ | ||
"description":"The body contains the fields `mappings_override` and `settings_override`.", | ||
"required":false | ||
} | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
...e/src/main/java/org/elasticsearch/xpack/migrate/rest/RestCreateIndexFromSourceAction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
package org.elasticsearch.xpack.migrate.rest; | ||
|
||
import org.elasticsearch.client.internal.node.NodeClient; | ||
import org.elasticsearch.rest.BaseRestHandler; | ||
import org.elasticsearch.rest.RestRequest; | ||
import org.elasticsearch.rest.action.RestToXContentListener; | ||
import org.elasticsearch.xpack.migrate.action.CreateIndexFromSourceAction; | ||
|
||
import java.io.IOException; | ||
import java.util.List; | ||
|
||
import static org.elasticsearch.rest.RestRequest.Method.POST; | ||
import static org.elasticsearch.rest.RestRequest.Method.PUT; | ||
|
||
public class RestCreateIndexFromSourceAction extends BaseRestHandler { | ||
|
||
@Override | ||
public String getName() { | ||
return "create_index_from_source_action"; | ||
} | ||
|
||
@Override | ||
public List<Route> routes() { | ||
return List.of(new Route(PUT, "/_create_from/{source}/{dest}"), new Route(POST, "/_create_from/{source}/{dest}")); | ||
} | ||
|
||
@Override | ||
protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { | ||
var createRequest = new CreateIndexFromSourceAction.Request(request.param("source"), request.param("dest")); | ||
request.applyContentParser(createRequest::fromXContent); | ||
return channel -> client.execute(CreateIndexFromSourceAction.INSTANCE, createRequest, new RestToXContentListener<>(channel)); | ||
} | ||
} |
95 changes: 95 additions & 0 deletions
95
...c/test/java/org/elasticsearch/xpack/migrate/action/CreateFromSourceIndexRequestTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
package org.elasticsearch.xpack.migrate.action; | ||
|
||
import org.elasticsearch.common.bytes.BytesReference; | ||
import org.elasticsearch.common.io.stream.Writeable; | ||
import org.elasticsearch.common.settings.Settings; | ||
import org.elasticsearch.test.AbstractWireSerializingTestCase; | ||
import org.elasticsearch.test.hamcrest.ElasticsearchAssertions; | ||
import org.elasticsearch.xcontent.XContentParser; | ||
import org.elasticsearch.xcontent.XContentType; | ||
import org.elasticsearch.xpack.migrate.action.CreateIndexFromSourceAction.Request; | ||
|
||
import java.io.IOException; | ||
import java.util.Map; | ||
|
||
import static org.elasticsearch.xcontent.ToXContent.EMPTY_PARAMS; | ||
|
||
public class CreateFromSourceIndexRequestTests extends AbstractWireSerializingTestCase<Request> { | ||
|
||
public void testToAndFromXContent() throws IOException { | ||
var request = createTestInstance(); | ||
|
||
boolean humanReadable = randomBoolean(); | ||
final XContentType xContentType = randomFrom(XContentType.values()); | ||
BytesReference originalBytes = toShuffledXContent(request, xContentType, EMPTY_PARAMS, humanReadable); | ||
|
||
var parsedRequest = new Request( | ||
randomValueOtherThan(request.sourceIndex(), () -> randomAlphanumericOfLength(30)), | ||
randomValueOtherThan(request.sourceIndex(), () -> randomAlphanumericOfLength(30)) | ||
); | ||
try (XContentParser xParser = createParser(xContentType.xContent(), originalBytes)) { | ||
parsedRequest.fromXContent(xParser); | ||
} | ||
|
||
// source and dest won't be equal | ||
assertNotEquals(request, parsedRequest); | ||
assertNotEquals(request.sourceIndex(), parsedRequest.sourceIndex()); | ||
assertNotEquals(request.destIndex(), parsedRequest.destIndex()); | ||
|
||
// but fields in xcontent will be equal | ||
assertEquals(request.settingsOverride(), parsedRequest.settingsOverride()); | ||
assertEquals(request.mappingsOverride(), parsedRequest.mappingsOverride()); | ||
|
||
BytesReference finalBytes = toShuffledXContent(parsedRequest, xContentType, EMPTY_PARAMS, humanReadable); | ||
ElasticsearchAssertions.assertToXContentEquivalent(originalBytes, finalBytes, xContentType); | ||
} | ||
|
||
@Override | ||
protected Writeable.Reader<Request> instanceReader() { | ||
return Request::new; | ||
} | ||
|
||
@Override | ||
protected Request createTestInstance() { | ||
String source = randomAlphaOfLength(30); | ||
String dest = randomAlphaOfLength(30); | ||
if (randomBoolean()) { | ||
return new Request(source, dest); | ||
} else { | ||
return new Request(source, dest, randomSettings(), randomMappings()); | ||
} | ||
} | ||
|
||
@Override | ||
protected Request mutateInstance(Request instance) throws IOException { | ||
|
||
String sourceIndex = instance.sourceIndex(); | ||
String destIndex = instance.destIndex(); | ||
Settings settingsOverride = instance.settingsOverride(); | ||
Map<String, Object> mappingsOverride = instance.mappingsOverride(); | ||
|
||
switch (between(0, 3)) { | ||
case 0 -> sourceIndex = randomValueOtherThan(sourceIndex, () -> randomAlphaOfLength(30)); | ||
case 1 -> destIndex = randomValueOtherThan(destIndex, () -> randomAlphaOfLength(30)); | ||
case 2 -> settingsOverride = randomValueOtherThan(settingsOverride, CreateFromSourceIndexRequestTests::randomSettings); | ||
case 3 -> mappingsOverride = randomValueOtherThan(mappingsOverride, CreateFromSourceIndexRequestTests::randomMappings); | ||
} | ||
return new Request(sourceIndex, destIndex, settingsOverride, mappingsOverride); | ||
} | ||
|
||
public static Map<String, Object> randomMappings() { | ||
var randMappings = Map.of("properties", Map.of(randomAlphaOfLength(5), Map.of("type", "keyword"))); | ||
return randomBoolean() ? Map.of() : Map.of("_doc", randMappings); | ||
} | ||
|
||
public static Settings randomSettings() { | ||
return randomBoolean() ? Settings.EMPTY : indexSettings(randomIntBetween(1, 10), randomIntBetween(0, 5)).build(); | ||
} | ||
} |
Oops, something went wrong.