* Add REST APIs for IndexTemplateV2Metadata CRUD (#54039) * Add REST APIs for IndexTemplateV2Metadata CRUD This commit adds the get/put/delete APIs for interacting with the now v2 versions of index templates. These APIs are behind the existing `es.itv2_feature_flag_registered` system property feature flag. Relates to #53101 * Add exceptions for HLRC tests * Add skips for 7.x versions * Use index_template instead of template_v2 in action names * Add test for MetaDataIndexTemplateService.addIndexTemplateV2 * Move removal to static method and add test * Add unit tests for request classes (implement hashCode & equals) Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> * Fix compilation Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
1690e78646
commit
f2cc2b1127
|
@ -801,7 +801,9 @@ public class RestHighLevelClientTests extends ESTestCase {
|
|||
"cluster.delete_component_template",
|
||||
"indices.create_data_stream",
|
||||
"indices.get_data_streams",
|
||||
"indices.delete_data_stream"
|
||||
"indices.delete_data_stream",
|
||||
"indices.put_index_template",
|
||||
"indices.delete_index_template"
|
||||
};
|
||||
//These API are not required for high-level client feature completeness
|
||||
String[] notRequiredApi = new String[] {
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"indices.delete_index_template":{
|
||||
"documentation":{
|
||||
"url":"https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-templates.html",
|
||||
"description":"Deletes an index template."
|
||||
},
|
||||
"stability":"stable",
|
||||
"url":{
|
||||
"paths":[
|
||||
{
|
||||
"path":"/_index_template/{name}",
|
||||
"methods":[
|
||||
"DELETE"
|
||||
],
|
||||
"parts":{
|
||||
"name":{
|
||||
"type":"string",
|
||||
"description":"The name of the template"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"params":{
|
||||
"timeout":{
|
||||
"type":"time",
|
||||
"description":"Explicit operation timeout"
|
||||
},
|
||||
"master_timeout":{
|
||||
"type":"time",
|
||||
"description":"Specify timeout for connection to master"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"indices.get_index_template":{
|
||||
"documentation":{
|
||||
"url":"https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-templates.html",
|
||||
"description":"Returns an index template."
|
||||
},
|
||||
"stability":"stable",
|
||||
"url":{
|
||||
"paths":[
|
||||
{
|
||||
"path":"/_index_template",
|
||||
"methods":[
|
||||
"GET"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path":"/_index_template/{name}",
|
||||
"methods":[
|
||||
"GET"
|
||||
],
|
||||
"parts":{
|
||||
"name":{
|
||||
"type":"list",
|
||||
"description":"The comma separated names of the index templates"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"params":{
|
||||
"flat_settings":{
|
||||
"type":"boolean",
|
||||
"description":"Return settings in flat format (default: false)"
|
||||
},
|
||||
"master_timeout":{
|
||||
"type":"time",
|
||||
"description":"Explicit operation timeout for connection to master node"
|
||||
},
|
||||
"local":{
|
||||
"type":"boolean",
|
||||
"description":"Return local information, do not retrieve the state from master node (default: false)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"indices.put_index_template":{
|
||||
"documentation":{
|
||||
"url":"https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-templates.html",
|
||||
"description":"Creates or updates an index template."
|
||||
},
|
||||
"stability":"stable",
|
||||
"url":{
|
||||
"paths":[
|
||||
{
|
||||
"path":"/_index_template/{name}",
|
||||
"methods":[
|
||||
"PUT",
|
||||
"POST"
|
||||
],
|
||||
"parts":{
|
||||
"name":{
|
||||
"type":"string",
|
||||
"description":"The name of the template"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"params":{
|
||||
"order":{
|
||||
"type":"number",
|
||||
"description":"The order for this template when merging multiple matching ones (higher numbers are merged later, overriding the lower numbers)"
|
||||
},
|
||||
"create":{
|
||||
"type":"boolean",
|
||||
"description":"Whether the index template should only be added if new or can also replace an existing one",
|
||||
"default":false
|
||||
},
|
||||
"master_timeout":{
|
||||
"type":"time",
|
||||
"description":"Specify timeout for connection to master"
|
||||
}
|
||||
},
|
||||
"body":{
|
||||
"description":"The template definition",
|
||||
"required":true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
setup:
|
||||
- skip:
|
||||
version: " - 7.7.99"
|
||||
reason: "index template v2 API unavailable before 7.8"
|
||||
|
||||
- do:
|
||||
indices.put_index_template:
|
||||
name: test
|
||||
body:
|
||||
index_patterns: test-*
|
||||
template:
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
mappings:
|
||||
properties:
|
||||
field:
|
||||
type: keyword
|
||||
|
||||
---
|
||||
"Get index template":
|
||||
- skip:
|
||||
version: " - 7.7.99"
|
||||
reason: "index template v2 API unavailable before 7.8"
|
||||
|
||||
- do:
|
||||
indices.get_index_template:
|
||||
name: test
|
||||
|
||||
- match: {index_templates.0.name: test}
|
||||
- match: {index_templates.0.index_template.index_patterns: ["test-*"]}
|
||||
- match: {index_templates.0.index_template.template.settings: {index: {number_of_shards: '1', number_of_replicas: '0'}}}
|
||||
- match: {index_templates.0.index_template.template.mappings: {properties: {field: {type: keyword}}}}
|
||||
|
||||
---
|
||||
"Get all tindex emplates":
|
||||
- skip:
|
||||
version: " - 7.7.99"
|
||||
reason: "index template v2 API unavailable before 7.8"
|
||||
|
||||
- do:
|
||||
indices.put_index_template:
|
||||
name: test2
|
||||
body:
|
||||
index_patterns: test2-*
|
||||
template:
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
|
||||
- do:
|
||||
indices.get_index_template: {}
|
||||
|
||||
- length: {index_templates: 2}
|
||||
|
||||
---
|
||||
"Get index template with local flag":
|
||||
- skip:
|
||||
version: " - 7.7.99"
|
||||
reason: "index template v2 API unavailable before 7.8"
|
||||
|
||||
- do:
|
||||
indices.get_index_template:
|
||||
name: test
|
||||
local: true
|
||||
|
||||
- match: {index_templates.0.name: test}
|
|
@ -0,0 +1,20 @@
|
|||
setup:
|
||||
- skip:
|
||||
version: " - 7.7.99"
|
||||
reason: "index template v2 API unavailable before 7.8"
|
||||
|
||||
- do:
|
||||
indices.delete_index_template:
|
||||
name: '*'
|
||||
ignore: 404
|
||||
---
|
||||
"Get missing template":
|
||||
- skip:
|
||||
version: " - 7.7.99"
|
||||
reason: "index template v2 API unavailable before 7.8"
|
||||
|
||||
- do:
|
||||
catch: missing
|
||||
indices.get_index_template:
|
||||
name: test
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
---
|
||||
"Put index template":
|
||||
- skip:
|
||||
version: " - 7.7.99"
|
||||
reason: "index template v2 API unavailable before 7.8"
|
||||
|
||||
- do:
|
||||
indices.put_index_template:
|
||||
name: test
|
||||
body:
|
||||
index_patterns: test-*
|
||||
template:
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
mappings:
|
||||
properties:
|
||||
field:
|
||||
type: keyword
|
||||
|
||||
- do:
|
||||
indices.get_index_template:
|
||||
name: test
|
||||
|
||||
- match: {index_templates.0.name: "test"}
|
||||
- match: {index_templates.0.index_template.index_patterns: ["test-*"]}
|
||||
- match: {index_templates.0.index_template.template.settings.index: {number_of_shards: '1', number_of_replicas: '0'}}
|
||||
- match: {index_templates.0.index_template.template.mappings: {properties: {field: {type: keyword}}}}
|
||||
|
||||
---
|
||||
"Put multiple index templates":
|
||||
- skip:
|
||||
version: " - 7.7.99"
|
||||
reason: "index template v2 API unavailable before 7.8"
|
||||
|
||||
- do:
|
||||
indices.put_index_template:
|
||||
name: test
|
||||
body:
|
||||
index_patterns: [test-*, test2-*]
|
||||
template:
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
mappings:
|
||||
properties:
|
||||
field:
|
||||
type: text
|
||||
aliases:
|
||||
test_alias: {}
|
||||
test_blias: { routing: b }
|
||||
test_clias: { filter: { term: { user: kimchy }}}
|
||||
|
||||
- do:
|
||||
indices.get_index_template:
|
||||
name: test
|
||||
|
||||
- match: {index_templates.0.index_template.index_patterns: ["test-*", "test2-*"]}
|
||||
- match: {index_templates.0.index_template.template.settings.index: {number_of_shards: '1', number_of_replicas: '0'}}
|
||||
- match: {index_templates.0.index_template.template.mappings: {properties: {field: {type: text}}}}
|
||||
- length: {index_templates.0.index_template.template.aliases: 3}
|
||||
- is_true: index_templates.0.index_template.template.aliases.test_alias
|
||||
- match: {index_templates.0.index_template.template.aliases.test_blias.index_routing: "b" }
|
||||
- match: {index_templates.0.index_template.template.aliases.test_blias.search_routing: "b" }
|
||||
- match: {index_templates.0.index_template.template.aliases.test_clias.filter.term.user: "kimchy" }
|
||||
|
||||
---
|
||||
"Put index template with 'create' flag":
|
||||
- skip:
|
||||
version: " - 7.7.99"
|
||||
reason: "index template v2 API unavailable before 7.8"
|
||||
|
||||
- do:
|
||||
indices.put_index_template:
|
||||
name: test2
|
||||
body:
|
||||
index_patterns: test-*
|
||||
template:
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
|
||||
- do:
|
||||
indices.get_index_template:
|
||||
name: test2
|
||||
|
||||
- match: {index_templates.0.index_template.index_patterns: ["test-*"]}
|
||||
- match: {index_templates.0.index_template.template.settings.index: {number_of_shards: '1', number_of_replicas: '0'}}
|
||||
|
||||
- do:
|
||||
catch: bad_request
|
||||
indices.put_index_template:
|
||||
name: test2
|
||||
create: true
|
||||
body:
|
||||
index_patterns: test-*
|
||||
template:
|
||||
settings:
|
||||
number_of_shards: 1
|
||||
number_of_replicas: 0
|
||||
|
||||
---
|
||||
"Put index template without index_patterns":
|
||||
- skip:
|
||||
version: " - 7.7.99"
|
||||
reason: "index template v2 API unavailable before 7.8"
|
||||
|
||||
- do:
|
||||
catch: bad_request
|
||||
indices.put_index_template:
|
||||
name: test
|
||||
body: {}
|
|
@ -153,16 +153,22 @@ import org.elasticsearch.action.admin.indices.stats.IndicesStatsAction;
|
|||
import org.elasticsearch.action.admin.indices.stats.TransportIndicesStatsAction;
|
||||
import org.elasticsearch.action.admin.indices.template.delete.DeleteComponentTemplateAction;
|
||||
import org.elasticsearch.action.admin.indices.template.delete.DeleteIndexTemplateAction;
|
||||
import org.elasticsearch.action.admin.indices.template.delete.DeleteIndexTemplateV2Action;
|
||||
import org.elasticsearch.action.admin.indices.template.delete.TransportDeleteComponentTemplateAction;
|
||||
import org.elasticsearch.action.admin.indices.template.delete.TransportDeleteIndexTemplateAction;
|
||||
import org.elasticsearch.action.admin.indices.template.delete.TransportDeleteIndexTemplateV2Action;
|
||||
import org.elasticsearch.action.admin.indices.template.get.GetComponentTemplateAction;
|
||||
import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplateV2Action;
|
||||
import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesAction;
|
||||
import org.elasticsearch.action.admin.indices.template.get.TransportGetComponentTemplateAction;
|
||||
import org.elasticsearch.action.admin.indices.template.get.TransportGetIndexTemplateV2Action;
|
||||
import org.elasticsearch.action.admin.indices.template.get.TransportGetIndexTemplatesAction;
|
||||
import org.elasticsearch.action.admin.indices.template.put.PutComponentTemplateAction;
|
||||
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateAction;
|
||||
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateV2Action;
|
||||
import org.elasticsearch.action.admin.indices.template.put.TransportPutComponentTemplateAction;
|
||||
import org.elasticsearch.action.admin.indices.template.put.TransportPutIndexTemplateAction;
|
||||
import org.elasticsearch.action.admin.indices.template.put.TransportPutIndexTemplateV2Action;
|
||||
import org.elasticsearch.action.admin.indices.upgrade.get.TransportUpgradeStatusAction;
|
||||
import org.elasticsearch.action.admin.indices.upgrade.get.UpgradeStatusAction;
|
||||
import org.elasticsearch.action.admin.indices.upgrade.post.TransportUpgradeAction;
|
||||
|
@ -287,12 +293,14 @@ import org.elasticsearch.rest.action.admin.indices.RestCreateIndexAction;
|
|||
import org.elasticsearch.rest.action.admin.indices.RestDeleteComponentTemplateAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestDeleteIndexAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestDeleteIndexTemplateAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestDeleteIndexTemplateV2Action;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestFlushAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestForceMergeAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestGetAliasesAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestGetComponentTemplateAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestGetFieldMappingAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestGetIndexTemplateAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestGetIndexTemplateV2Action;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestGetIndicesAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestGetMappingAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestGetSettingsAction;
|
||||
|
@ -305,6 +313,7 @@ import org.elasticsearch.rest.action.admin.indices.RestIndicesStatsAction;
|
|||
import org.elasticsearch.rest.action.admin.indices.RestOpenIndexAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestPutComponentTemplateAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestPutIndexTemplateAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestPutIndexTemplateV2Action;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestPutMappingAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestRecoveryAction;
|
||||
import org.elasticsearch.rest.action.admin.indices.RestRefreshAction;
|
||||
|
@ -549,6 +558,9 @@ public class ActionModule extends AbstractModule {
|
|||
actions.register(PutComponentTemplateAction.INSTANCE, TransportPutComponentTemplateAction.class);
|
||||
actions.register(GetComponentTemplateAction.INSTANCE, TransportGetComponentTemplateAction.class);
|
||||
actions.register(DeleteComponentTemplateAction.INSTANCE, TransportDeleteComponentTemplateAction.class);
|
||||
actions.register(PutIndexTemplateV2Action.INSTANCE, TransportPutIndexTemplateV2Action.class);
|
||||
actions.register(GetIndexTemplateV2Action.INSTANCE, TransportGetIndexTemplateV2Action.class);
|
||||
actions.register(DeleteIndexTemplateV2Action.INSTANCE, TransportDeleteIndexTemplateV2Action.class);
|
||||
}
|
||||
actions.register(ValidateQueryAction.INSTANCE, TransportValidateQueryAction.class);
|
||||
actions.register(RefreshAction.INSTANCE, TransportRefreshAction.class);
|
||||
|
@ -688,6 +700,9 @@ public class ActionModule extends AbstractModule {
|
|||
registerHandler.accept(new RestPutComponentTemplateAction());
|
||||
registerHandler.accept(new RestGetComponentTemplateAction());
|
||||
registerHandler.accept(new RestDeleteComponentTemplateAction());
|
||||
registerHandler.accept(new RestPutIndexTemplateV2Action());
|
||||
registerHandler.accept(new RestGetIndexTemplateV2Action());
|
||||
registerHandler.accept(new RestDeleteIndexTemplateV2Action());
|
||||
}
|
||||
|
||||
registerHandler.accept(new RestPutMappingAction());
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* 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.template.delete;
|
||||
|
||||
import org.elasticsearch.action.ActionRequestValidationException;
|
||||
import org.elasticsearch.action.ActionType;
|
||||
import org.elasticsearch.action.support.master.AcknowledgedResponse;
|
||||
import org.elasticsearch.action.support.master.MasterNodeRequest;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.elasticsearch.action.ValidateActions.addValidationError;
|
||||
|
||||
public class DeleteIndexTemplateV2Action extends ActionType<AcknowledgedResponse> {
|
||||
|
||||
public static final DeleteIndexTemplateV2Action INSTANCE = new DeleteIndexTemplateV2Action();
|
||||
public static final String NAME = "indices:admin/index_template/delete";
|
||||
|
||||
private DeleteIndexTemplateV2Action() {
|
||||
super(NAME, AcknowledgedResponse::new);
|
||||
}
|
||||
|
||||
public static class Request extends MasterNodeRequest<Request> {
|
||||
|
||||
private String name;
|
||||
|
||||
public Request(StreamInput in) throws IOException {
|
||||
super(in);
|
||||
name = in.readString();
|
||||
}
|
||||
|
||||
public Request() { }
|
||||
|
||||
/**
|
||||
* Constructs a new delete template request for the specified name.
|
||||
*/
|
||||
public Request(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the index template name to delete.
|
||||
*/
|
||||
public Request name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionRequestValidationException validate() {
|
||||
ActionRequestValidationException validationException = null;
|
||||
if (name == null) {
|
||||
validationException = addValidationError("name is missing", validationException);
|
||||
}
|
||||
return validationException;
|
||||
}
|
||||
|
||||
/**
|
||||
* The index template name to delete.
|
||||
*/
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
super.writeTo(out);
|
||||
out.writeString(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return name.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Request other = (Request) obj;
|
||||
return Objects.equals(other.name, this.name);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* 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.template.delete;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.support.ActionFilters;
|
||||
import org.elasticsearch.action.support.master.AcknowledgedResponse;
|
||||
import org.elasticsearch.action.support.master.TransportMasterNodeAction;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.block.ClusterBlockException;
|
||||
import org.elasticsearch.cluster.block.ClusterBlockLevel;
|
||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||
import org.elasticsearch.cluster.metadata.MetaDataIndexTemplateService;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.transport.TransportService;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class TransportDeleteIndexTemplateV2Action
|
||||
extends TransportMasterNodeAction<DeleteIndexTemplateV2Action.Request, AcknowledgedResponse> {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(TransportDeleteIndexTemplateV2Action.class);
|
||||
|
||||
private final MetaDataIndexTemplateService indexTemplateService;
|
||||
|
||||
@Inject
|
||||
public TransportDeleteIndexTemplateV2Action(TransportService transportService, ClusterService clusterService,
|
||||
ThreadPool threadPool, MetaDataIndexTemplateService indexTemplateService,
|
||||
ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) {
|
||||
super(DeleteIndexTemplateV2Action.NAME, transportService, clusterService, threadPool, actionFilters,
|
||||
DeleteIndexTemplateV2Action.Request::new, indexNameExpressionResolver);
|
||||
this.indexTemplateService = indexTemplateService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String executor() {
|
||||
// we go async right away
|
||||
return ThreadPool.Names.SAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AcknowledgedResponse read(StreamInput in) throws IOException {
|
||||
return new AcknowledgedResponse(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClusterBlockException checkBlock(DeleteIndexTemplateV2Action.Request request, ClusterState state) {
|
||||
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void masterOperation(final DeleteIndexTemplateV2Action.Request request, final ClusterState state,
|
||||
final ActionListener<AcknowledgedResponse> listener) {
|
||||
indexTemplateService.removeIndexTemplateV2(request.name(), request.masterNodeTimeout(), listener);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* 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.template.get;
|
||||
|
||||
import org.elasticsearch.action.ActionRequestValidationException;
|
||||
import org.elasticsearch.action.ActionResponse;
|
||||
import org.elasticsearch.action.ActionType;
|
||||
import org.elasticsearch.action.support.master.MasterNodeReadRequest;
|
||||
import org.elasticsearch.cluster.metadata.IndexTemplateV2;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.elasticsearch.action.ValidateActions.addValidationError;
|
||||
|
||||
public class GetIndexTemplateV2Action extends ActionType<GetIndexTemplateV2Action.Response> {
|
||||
|
||||
public static final GetIndexTemplateV2Action INSTANCE = new GetIndexTemplateV2Action();
|
||||
public static final String NAME = "indices:admin/index_template/get";
|
||||
|
||||
private GetIndexTemplateV2Action() {
|
||||
super(NAME, GetIndexTemplateV2Action.Response::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request that to retrieve one or more index templates
|
||||
*/
|
||||
public static class Request extends MasterNodeReadRequest<Request> {
|
||||
|
||||
private String[] names;
|
||||
|
||||
public Request() { }
|
||||
|
||||
public Request(String... names) {
|
||||
this.names = names;
|
||||
}
|
||||
|
||||
public Request(StreamInput in) throws IOException {
|
||||
super(in);
|
||||
names = in.readStringArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
super.writeTo(out);
|
||||
out.writeStringArray(names);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionRequestValidationException validate() {
|
||||
ActionRequestValidationException validationException = null;
|
||||
if (names == null) {
|
||||
validationException = addValidationError("names is null or empty", validationException);
|
||||
} else {
|
||||
for (String name : names) {
|
||||
if (name == null || Strings.hasText(name) == false) {
|
||||
validationException = addValidationError("name is missing", validationException);
|
||||
}
|
||||
}
|
||||
}
|
||||
return validationException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the names of the index templates.
|
||||
*/
|
||||
public Request names(String... names) {
|
||||
this.names = names;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The names of the index templates.
|
||||
*/
|
||||
public String[] names() {
|
||||
return this.names;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(names);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Request other = (Request) obj;
|
||||
return Arrays.equals(other.names, this.names);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Response extends ActionResponse implements ToXContentObject {
|
||||
public static final ParseField NAME = new ParseField("name");
|
||||
public static final ParseField INDEX_TEMPLATES = new ParseField("index_templates");
|
||||
public static final ParseField INDEX_TEMPLATE = new ParseField("index_template");
|
||||
|
||||
private final Map<String, IndexTemplateV2> indexTemplates;
|
||||
|
||||
public Response(StreamInput in) throws IOException {
|
||||
super(in);
|
||||
int size = in.readVInt();
|
||||
indexTemplates = new HashMap<>();
|
||||
for (int i = 0 ; i < size ; i++) {
|
||||
indexTemplates.put(in.readString(), new IndexTemplateV2(in));
|
||||
}
|
||||
}
|
||||
|
||||
public Response(Map<String, IndexTemplateV2> indexTemplates) {
|
||||
this.indexTemplates = indexTemplates;
|
||||
}
|
||||
|
||||
public Map<String, IndexTemplateV2> indexTemplates() {
|
||||
return indexTemplates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
out.writeVInt(indexTemplates.size());
|
||||
for (Map.Entry<String, IndexTemplateV2> indexTemplate : indexTemplates.entrySet()) {
|
||||
out.writeString(indexTemplate.getKey());
|
||||
indexTemplate.getValue().writeTo(out);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
GetIndexTemplateV2Action.Response that = (GetIndexTemplateV2Action.Response) o;
|
||||
return Objects.equals(indexTemplates, that.indexTemplates);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(indexTemplates);
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
builder.startArray(INDEX_TEMPLATES.getPreferredName());
|
||||
for (Map.Entry<String, IndexTemplateV2> indexTemplate : this.indexTemplates.entrySet()) {
|
||||
builder.startObject();
|
||||
builder.field(NAME.getPreferredName(), indexTemplate.getKey());
|
||||
builder.field(INDEX_TEMPLATE.getPreferredName(), indexTemplate.getValue());
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endArray();
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* 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.template.get;
|
||||
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.support.ActionFilters;
|
||||
import org.elasticsearch.action.support.master.TransportMasterNodeReadAction;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.block.ClusterBlockException;
|
||||
import org.elasticsearch.cluster.block.ClusterBlockLevel;
|
||||
import org.elasticsearch.cluster.metadata.IndexTemplateV2;
|
||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.regex.Regex;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.transport.TransportService;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class TransportGetIndexTemplateV2Action
|
||||
extends TransportMasterNodeReadAction<GetIndexTemplateV2Action.Request, GetIndexTemplateV2Action.Response> {
|
||||
|
||||
@Inject
|
||||
public TransportGetIndexTemplateV2Action(TransportService transportService, ClusterService clusterService,
|
||||
ThreadPool threadPool, ActionFilters actionFilters,
|
||||
IndexNameExpressionResolver indexNameExpressionResolver) {
|
||||
super(GetIndexTemplateV2Action.NAME, transportService, clusterService, threadPool, actionFilters,
|
||||
GetIndexTemplateV2Action.Request::new, indexNameExpressionResolver);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String executor() {
|
||||
return ThreadPool.Names.SAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GetIndexTemplateV2Action.Response read(StreamInput in) throws IOException {
|
||||
return new GetIndexTemplateV2Action.Response(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClusterBlockException checkBlock(GetIndexTemplateV2Action.Request request, ClusterState state) {
|
||||
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_READ);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void masterOperation(GetIndexTemplateV2Action.Request request, ClusterState state,
|
||||
ActionListener<GetIndexTemplateV2Action.Response> listener) {
|
||||
Map<String, IndexTemplateV2> allTemplates = state.metaData().templatesV2();
|
||||
|
||||
// If we did not ask for a specific name, then we return all templates
|
||||
if (request.names().length == 0) {
|
||||
listener.onResponse(new GetIndexTemplateV2Action.Response(allTemplates));
|
||||
return;
|
||||
}
|
||||
|
||||
final Map<String, IndexTemplateV2> results = new HashMap<>();
|
||||
for (String name : request.names()) {
|
||||
if (Regex.isSimpleMatchPattern(name)) {
|
||||
for (Map.Entry<String, IndexTemplateV2> entry : allTemplates.entrySet()) {
|
||||
if (Regex.simpleMatch(name, entry.getKey())) {
|
||||
results.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
} else if (allTemplates.containsKey(name)) {
|
||||
results.put(name, allTemplates.get(name));
|
||||
}
|
||||
}
|
||||
|
||||
listener.onResponse(new GetIndexTemplateV2Action.Response(results));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* 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.template.put;
|
||||
|
||||
import org.elasticsearch.action.ActionRequestValidationException;
|
||||
import org.elasticsearch.action.ActionType;
|
||||
import org.elasticsearch.action.IndicesRequest;
|
||||
import org.elasticsearch.action.support.IndicesOptions;
|
||||
import org.elasticsearch.action.support.master.AcknowledgedResponse;
|
||||
import org.elasticsearch.action.support.master.MasterNodeRequest;
|
||||
import org.elasticsearch.cluster.metadata.IndexTemplateV2;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.elasticsearch.action.ValidateActions.addValidationError;
|
||||
|
||||
public class PutIndexTemplateV2Action extends ActionType<AcknowledgedResponse> {
|
||||
|
||||
public static final PutIndexTemplateV2Action INSTANCE = new PutIndexTemplateV2Action();
|
||||
public static final String NAME = "indices:admin/index_template/put";
|
||||
|
||||
private PutIndexTemplateV2Action() {
|
||||
super(NAME, AcknowledgedResponse::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* A request for putting a single index template into the cluster state
|
||||
*/
|
||||
public static class Request extends MasterNodeRequest<Request> implements IndicesRequest {
|
||||
private final String name;
|
||||
@Nullable
|
||||
private String cause;
|
||||
private boolean create;
|
||||
private IndexTemplateV2 indexTemplate;
|
||||
|
||||
public Request(StreamInput in) throws IOException {
|
||||
super(in);
|
||||
this.name = in.readString();
|
||||
this.cause = in.readOptionalString();
|
||||
this.create = in.readBoolean();
|
||||
this.indexTemplate = new IndexTemplateV2(in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new put index template request with the provided name.
|
||||
*/
|
||||
public Request(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
super.writeTo(out);
|
||||
out.writeString(name);
|
||||
out.writeOptionalString(cause);
|
||||
out.writeBoolean(create);
|
||||
this.indexTemplate.writeTo(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionRequestValidationException validate() {
|
||||
ActionRequestValidationException validationException = null;
|
||||
if (name == null || Strings.hasText(name) == false) {
|
||||
validationException = addValidationError("name is missing", validationException);
|
||||
}
|
||||
if (indexTemplate == null) {
|
||||
validationException = addValidationError("an index template is required", validationException);
|
||||
}
|
||||
return validationException;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the index template.
|
||||
*/
|
||||
public String name() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set to {@code true} to force only creation, not an update of an index template. If it already
|
||||
* exists, it will fail with an {@link IllegalArgumentException}.
|
||||
*/
|
||||
public Request create(boolean create) {
|
||||
this.create = create;
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean create() {
|
||||
return create;
|
||||
}
|
||||
|
||||
/**
|
||||
* The cause for this index template creation.
|
||||
*/
|
||||
public Request cause(@Nullable String cause) {
|
||||
this.cause = cause;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String cause() {
|
||||
return this.cause;
|
||||
}
|
||||
|
||||
/**
|
||||
* The index template that will be inserted into the cluster state
|
||||
*/
|
||||
public Request indexTemplate(IndexTemplateV2 template) {
|
||||
this.indexTemplate = template;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IndexTemplateV2 indexTemplate() {
|
||||
return this.indexTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder("PutTemplateV2Request[");
|
||||
sb.append("name=").append(name);
|
||||
sb.append(", cause=").append(cause);
|
||||
sb.append(", create=").append(create);
|
||||
sb.append(", index_template=").append(indexTemplate);
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] indices() {
|
||||
return indexTemplate.indexPatterns().toArray(Strings.EMPTY_ARRAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IndicesOptions indicesOptions() {
|
||||
return IndicesOptions.strictExpand();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name, cause, create, indexTemplate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Request other = (Request) obj;
|
||||
return Objects.equals(this.name, other.name) &&
|
||||
Objects.equals(this.cause, other.cause) &&
|
||||
Objects.equals(this.indexTemplate, other.indexTemplate) &&
|
||||
this.create == other.create;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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.template.put;
|
||||
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.support.ActionFilters;
|
||||
import org.elasticsearch.action.support.master.AcknowledgedResponse;
|
||||
import org.elasticsearch.action.support.master.TransportMasterNodeAction;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.block.ClusterBlockException;
|
||||
import org.elasticsearch.cluster.block.ClusterBlockLevel;
|
||||
import org.elasticsearch.cluster.metadata.IndexTemplateV2;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||
import org.elasticsearch.cluster.metadata.MetaDataIndexTemplateService;
|
||||
import org.elasticsearch.cluster.metadata.Template;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.transport.TransportService;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class TransportPutIndexTemplateV2Action
|
||||
extends TransportMasterNodeAction<PutIndexTemplateV2Action.Request, AcknowledgedResponse> {
|
||||
|
||||
private final MetaDataIndexTemplateService indexTemplateService;
|
||||
|
||||
@Inject
|
||||
public TransportPutIndexTemplateV2Action(TransportService transportService, ClusterService clusterService,
|
||||
ThreadPool threadPool, MetaDataIndexTemplateService indexTemplateService,
|
||||
ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) {
|
||||
super(PutIndexTemplateV2Action.NAME, transportService, clusterService, threadPool, actionFilters,
|
||||
PutIndexTemplateV2Action.Request::new, indexNameExpressionResolver);
|
||||
this.indexTemplateService = indexTemplateService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String executor() {
|
||||
// we go async right away
|
||||
return ThreadPool.Names.SAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AcknowledgedResponse read(StreamInput in) throws IOException {
|
||||
return new AcknowledgedResponse(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClusterBlockException checkBlock(PutIndexTemplateV2Action.Request request, ClusterState state) {
|
||||
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void masterOperation(final PutIndexTemplateV2Action.Request request, final ClusterState state,
|
||||
final ActionListener<AcknowledgedResponse> listener) {
|
||||
IndexTemplateV2 indexTemplate = request.indexTemplate();
|
||||
Template template = indexTemplate.template();
|
||||
// Normalize the index settings if necessary
|
||||
if (template.settings() != null) {
|
||||
Settings.Builder settings = Settings.builder().put(template.settings()).normalizePrefix(IndexMetaData.INDEX_SETTING_PREFIX);
|
||||
template = new Template(settings.build(), template.mappings(), template.aliases());
|
||||
indexTemplate = new IndexTemplateV2(indexTemplate.indexPatterns(), template, indexTemplate.composedOf(),
|
||||
indexTemplate.priority(), indexTemplate.version(), indexTemplate.metadata());
|
||||
}
|
||||
indexTemplateService.putIndexTemplateV2(request.cause(), request.create(), request.name(), request.masterNodeTimeout(),
|
||||
indexTemplate, listener);
|
||||
}
|
||||
}
|
|
@ -241,6 +241,108 @@ public class MetaDataIndexTemplateService {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given component template to the cluster state. If {@code create} is true, an
|
||||
* exception will be thrown if the component template already exists
|
||||
*/
|
||||
public void putIndexTemplateV2(final String cause, final boolean create, final String name, final TimeValue masterTimeout,
|
||||
final IndexTemplateV2 template, final ActionListener<AcknowledgedResponse> listener) {
|
||||
clusterService.submitStateUpdateTask("create-index-template-v2 [" + name + "], cause [" + cause + "]",
|
||||
new ClusterStateUpdateTask(Priority.URGENT) {
|
||||
|
||||
@Override
|
||||
public TimeValue timeout() {
|
||||
return masterTimeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(String source, Exception e) {
|
||||
listener.onFailure(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClusterState execute(ClusterState currentState) {
|
||||
return addIndexTemplateV2(currentState, create, name, template);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) {
|
||||
listener.onResponse(new AcknowledgedResponse(true));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Package visible for testing
|
||||
static ClusterState addIndexTemplateV2(final ClusterState currentState, final boolean create,
|
||||
final String name, final IndexTemplateV2 template) {
|
||||
if (create && currentState.metaData().templatesV2().containsKey(name)) {
|
||||
throw new IllegalArgumentException("index template [" + name + "] already exists");
|
||||
}
|
||||
|
||||
// TODO: validation of index template
|
||||
// validateAndAddTemplate(request, templateBuilder, indicesService, xContentRegistry);
|
||||
|
||||
logger.info("adding index template [{}]", name);
|
||||
return ClusterState.builder(currentState)
|
||||
.metaData(MetaData.builder(currentState.metaData()).put(name, template))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given index template from the cluster state. The index template name
|
||||
* supports simple regex wildcards for removing multiple index templates at a time.
|
||||
*/
|
||||
public void removeIndexTemplateV2(final String name, final TimeValue masterTimeout,
|
||||
final ActionListener<AcknowledgedResponse> listener) {
|
||||
clusterService.submitStateUpdateTask("remove-index-template-v2 [" + name + "]",
|
||||
new ClusterStateUpdateTask(Priority.URGENT) {
|
||||
|
||||
@Override
|
||||
public TimeValue timeout() {
|
||||
return masterTimeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(String source, Exception e) {
|
||||
listener.onFailure(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClusterState execute(ClusterState currentState) {
|
||||
return innerRemoveIndexTemplateV2(currentState, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) {
|
||||
listener.onResponse(new AcknowledgedResponse(true));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Package visible for testing
|
||||
static ClusterState innerRemoveIndexTemplateV2(ClusterState currentState, String name) {
|
||||
Set<String> templateNames = new HashSet<>();
|
||||
for (String templateName : currentState.metaData().templatesV2().keySet()) {
|
||||
if (Regex.simpleMatch(name, templateName)) {
|
||||
templateNames.add(templateName);
|
||||
}
|
||||
}
|
||||
if (templateNames.isEmpty()) {
|
||||
// if its a match all pattern, and no templates are found (we have none), don't
|
||||
// fail with index missing...
|
||||
if (Regex.isMatchAllPattern(name)) {
|
||||
return currentState;
|
||||
}
|
||||
throw new IndexTemplateMissingException(name);
|
||||
}
|
||||
MetaData.Builder metaData = MetaData.builder(currentState.metaData());
|
||||
for (String templateName : templateNames) {
|
||||
logger.info("removing index template [{}]", templateName);
|
||||
metaData.removeIndexTemplate(templateName);
|
||||
}
|
||||
return ClusterState.builder(currentState).metaData(metaData).build();
|
||||
}
|
||||
|
||||
public void putTemplate(final PutRequest request, final PutListener listener) {
|
||||
Settings.Builder updatedSettingsBuilder = Settings.builder();
|
||||
updatedSettingsBuilder.put(request.settings).normalizePrefix(IndexMetaData.INDEX_SETTING_PREFIX);
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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.rest.action.admin.indices;
|
||||
|
||||
import org.elasticsearch.action.admin.indices.template.delete.DeleteIndexTemplateV2Action;
|
||||
import org.elasticsearch.client.node.NodeClient;
|
||||
import org.elasticsearch.rest.BaseRestHandler;
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
import org.elasticsearch.rest.action.RestToXContentListener;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.elasticsearch.rest.RestRequest.Method.DELETE;
|
||||
|
||||
public class RestDeleteIndexTemplateV2Action extends BaseRestHandler {
|
||||
|
||||
@Override
|
||||
public List<Route> routes() {
|
||||
return Collections.singletonList(new Route(DELETE, "/_index_template/{name}"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "delete_index_template_v2_action";
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
|
||||
|
||||
DeleteIndexTemplateV2Action.Request deleteReq = new DeleteIndexTemplateV2Action.Request(request.param("name"));
|
||||
deleteReq.masterNodeTimeout(request.paramAsTime("master_timeout", deleteReq.masterNodeTimeout()));
|
||||
|
||||
return channel -> client.execute(DeleteIndexTemplateV2Action.INSTANCE, deleteReq, new RestToXContentListener<>(channel));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* 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.rest.action.admin.indices;
|
||||
|
||||
import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplateV2Action;
|
||||
import org.elasticsearch.client.node.NodeClient;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.rest.BaseRestHandler;
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
import org.elasticsearch.rest.action.RestToXContentListener;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.elasticsearch.rest.RestRequest.Method.GET;
|
||||
import static org.elasticsearch.rest.RestRequest.Method.HEAD;
|
||||
import static org.elasticsearch.rest.RestStatus.NOT_FOUND;
|
||||
import static org.elasticsearch.rest.RestStatus.OK;
|
||||
|
||||
public class RestGetIndexTemplateV2Action extends BaseRestHandler {
|
||||
|
||||
@Override
|
||||
public List<Route> routes() {
|
||||
return Arrays.asList(
|
||||
new Route(GET, "/_index_template"),
|
||||
new Route(GET, "/_index_template/{name}"),
|
||||
new Route(HEAD, "/_index_template/{name}"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "get_index_template_v2_action";
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
|
||||
final String[] names = Strings.splitStringByCommaToArray(request.param("name"));
|
||||
|
||||
final GetIndexTemplateV2Action.Request getRequest = new GetIndexTemplateV2Action.Request(names);
|
||||
|
||||
getRequest.local(request.paramAsBoolean("local", getRequest.local()));
|
||||
getRequest.masterNodeTimeout(request.paramAsTime("master_timeout", getRequest.masterNodeTimeout()));
|
||||
|
||||
final boolean implicitAll = getRequest.names().length == 0;
|
||||
|
||||
return channel ->
|
||||
client.execute(GetIndexTemplateV2Action.INSTANCE, getRequest,
|
||||
new RestToXContentListener<GetIndexTemplateV2Action.Response>(channel) {
|
||||
@Override
|
||||
protected RestStatus getStatus(final GetIndexTemplateV2Action.Response response) {
|
||||
final boolean templateExists = response.indexTemplates().isEmpty() == false;
|
||||
return (templateExists || implicitAll) ? OK : NOT_FOUND;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> responseParams() {
|
||||
return Settings.FORMAT_PARAMS;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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.rest.action.admin.indices;
|
||||
|
||||
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateV2Action;
|
||||
import org.elasticsearch.client.node.NodeClient;
|
||||
import org.elasticsearch.cluster.metadata.IndexTemplateV2;
|
||||
import org.elasticsearch.rest.BaseRestHandler;
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
import org.elasticsearch.rest.action.RestToXContentListener;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.elasticsearch.rest.RestRequest.Method.POST;
|
||||
import static org.elasticsearch.rest.RestRequest.Method.PUT;
|
||||
|
||||
public class RestPutIndexTemplateV2Action extends BaseRestHandler {
|
||||
|
||||
@Override
|
||||
public List<Route> routes() {
|
||||
return Arrays.asList(
|
||||
new Route(POST, "/_index_template/{name}"),
|
||||
new Route(PUT, "/_index_template/{name}"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "put_index_template_v2_action";
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
|
||||
|
||||
PutIndexTemplateV2Action.Request putRequest = new PutIndexTemplateV2Action.Request(request.param("name"));
|
||||
putRequest.masterNodeTimeout(request.paramAsTime("master_timeout", putRequest.masterNodeTimeout()));
|
||||
putRequest.create(request.paramAsBoolean("create", false));
|
||||
putRequest.cause(request.param("cause", "api"));
|
||||
putRequest.indexTemplate(IndexTemplateV2.parse(request.contentParser()));
|
||||
|
||||
return channel -> client.execute(PutIndexTemplateV2Action.INSTANCE, putRequest, new RestToXContentListener<>(channel));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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.template.delete;
|
||||
|
||||
import org.elasticsearch.common.io.stream.Writeable;
|
||||
import org.elasticsearch.test.AbstractWireSerializingTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DeleteIndexTemplateV2RequestTests extends AbstractWireSerializingTestCase<DeleteIndexTemplateV2Action.Request> {
|
||||
@Override
|
||||
protected Writeable.Reader<DeleteIndexTemplateV2Action.Request> instanceReader() {
|
||||
return DeleteIndexTemplateV2Action.Request::new;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DeleteIndexTemplateV2Action.Request createTestInstance() {
|
||||
return new DeleteIndexTemplateV2Action.Request(randomAlphaOfLength(5));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DeleteIndexTemplateV2Action.Request mutateInstance(DeleteIndexTemplateV2Action.Request instance) throws IOException {
|
||||
return randomValueOtherThan(instance, this::createTestInstance);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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.template.get;
|
||||
|
||||
import org.elasticsearch.common.io.stream.Writeable;
|
||||
import org.elasticsearch.test.AbstractWireSerializingTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class GetIndexTemplateV2RequestTests extends AbstractWireSerializingTestCase<GetIndexTemplateV2Action.Request> {
|
||||
@Override
|
||||
protected Writeable.Reader<GetIndexTemplateV2Action.Request> instanceReader() {
|
||||
return GetIndexTemplateV2Action.Request::new;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GetIndexTemplateV2Action.Request createTestInstance() {
|
||||
return new GetIndexTemplateV2Action.Request(generateRandomStringArray(5, 5, false, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GetIndexTemplateV2Action.Request mutateInstance(GetIndexTemplateV2Action.Request instance) throws IOException {
|
||||
return randomValueOtherThan(instance, this::createTestInstance);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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.template.get;
|
||||
|
||||
import org.elasticsearch.cluster.metadata.IndexTemplateV2;
|
||||
import org.elasticsearch.cluster.metadata.IndexTemplateV2Tests;
|
||||
import org.elasticsearch.common.io.stream.Writeable;
|
||||
import org.elasticsearch.test.AbstractWireSerializingTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class GetIndexTemplateV2ResponseTests extends AbstractWireSerializingTestCase<GetIndexTemplateV2Action.Response> {
|
||||
@Override
|
||||
protected Writeable.Reader<GetIndexTemplateV2Action.Response> instanceReader() {
|
||||
return GetIndexTemplateV2Action.Response::new;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GetIndexTemplateV2Action.Response createTestInstance() {
|
||||
if (randomBoolean()) {
|
||||
return new GetIndexTemplateV2Action.Response(Collections.emptyMap());
|
||||
}
|
||||
Map<String, IndexTemplateV2> templates = new HashMap<>();
|
||||
for (int i = 0; i < randomIntBetween(1, 4); i++) {
|
||||
templates.put(randomAlphaOfLength(4), IndexTemplateV2Tests.randomInstance());
|
||||
}
|
||||
return new GetIndexTemplateV2Action.Response(templates);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GetIndexTemplateV2Action.Response mutateInstance(GetIndexTemplateV2Action.Response instance) throws IOException {
|
||||
return randomValueOtherThan(instance, this::createTestInstance);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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.template.put;
|
||||
|
||||
import org.elasticsearch.cluster.metadata.IndexTemplateV2Tests;
|
||||
import org.elasticsearch.common.io.stream.Writeable;
|
||||
import org.elasticsearch.test.AbstractWireSerializingTestCase;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class PutIndexTemplateV2RequestTests extends AbstractWireSerializingTestCase<PutIndexTemplateV2Action.Request> {
|
||||
@Override
|
||||
protected Writeable.Reader<PutIndexTemplateV2Action.Request> instanceReader() {
|
||||
return PutIndexTemplateV2Action.Request::new;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PutIndexTemplateV2Action.Request createTestInstance() {
|
||||
PutIndexTemplateV2Action.Request req = new PutIndexTemplateV2Action.Request(randomAlphaOfLength(4));
|
||||
req.cause(randomAlphaOfLength(4));
|
||||
req.create(randomBoolean());
|
||||
req.indexTemplate(IndexTemplateV2Tests.randomInstance());
|
||||
return req;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PutIndexTemplateV2Action.Request mutateInstance(PutIndexTemplateV2Action.Request instance) throws IOException {
|
||||
return randomValueOtherThan(instance, this::createTestInstance);
|
||||
}
|
||||
}
|
|
@ -32,6 +32,7 @@ import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
|||
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.index.mapper.MapperParsingException;
|
||||
import org.elasticsearch.indices.IndexTemplateMissingException;
|
||||
import org.elasticsearch.indices.IndicesService;
|
||||
import org.elasticsearch.indices.InvalidIndexTemplateException;
|
||||
import org.elasticsearch.test.ESSingleNodeTestCase;
|
||||
|
@ -237,6 +238,37 @@ public class MetaDataIndexTemplateServiceTests extends ESSingleNodeTestCase {
|
|||
() -> metaDataIndexTemplateService.addComponentTemplate(throwState, true, "foo2", componentTemplate4));
|
||||
}
|
||||
|
||||
public void testAddIndexTemplateV2() {
|
||||
ClusterState state = ClusterState.EMPTY_STATE;
|
||||
IndexTemplateV2 template = IndexTemplateV2Tests.randomInstance();
|
||||
state = MetaDataIndexTemplateService.addIndexTemplateV2(state, false, "foo", template);
|
||||
|
||||
assertNotNull(state.metaData().templatesV2().get("foo"));
|
||||
assertThat(state.metaData().templatesV2().get("foo"), equalTo(template));
|
||||
|
||||
final ClusterState throwState = ClusterState.builder(state).build();
|
||||
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
|
||||
() -> MetaDataIndexTemplateService.addIndexTemplateV2(throwState, true, "foo", template));
|
||||
assertThat(e.getMessage(), containsString("index template [foo] already exists"));
|
||||
|
||||
state = MetaDataIndexTemplateService.addIndexTemplateV2(state, randomBoolean(), "bar", template);
|
||||
assertNotNull(state.metaData().templatesV2().get("bar"));
|
||||
}
|
||||
|
||||
public void testRemoveIndexTemplateV2() {
|
||||
IndexTemplateV2 template = IndexTemplateV2Tests.randomInstance();
|
||||
IndexTemplateMissingException e = expectThrows(IndexTemplateMissingException.class,
|
||||
() -> MetaDataIndexTemplateService.innerRemoveIndexTemplateV2(ClusterState.EMPTY_STATE, "foo"));
|
||||
assertThat(e.getMessage(), equalTo("index_template [foo] missing"));
|
||||
|
||||
final ClusterState state = MetaDataIndexTemplateService.addIndexTemplateV2(ClusterState.EMPTY_STATE, false, "foo", template);
|
||||
assertNotNull(state.metaData().templatesV2().get("foo"));
|
||||
assertThat(state.metaData().templatesV2().get("foo"), equalTo(template));
|
||||
|
||||
ClusterState updatedState = MetaDataIndexTemplateService.innerRemoveIndexTemplateV2(state, "foo");
|
||||
assertNull(updatedState.metaData().templatesV2().get("foo"));
|
||||
}
|
||||
|
||||
private static List<Throwable> putTemplate(NamedXContentRegistry xContentRegistry, PutRequest request) {
|
||||
MetaDataCreateIndexService createIndexService = new MetaDataCreateIndexService(
|
||||
Settings.EMPTY,
|
||||
|
|
|
@ -58,7 +58,7 @@ public class ClusterPrivilegeResolver {
|
|||
private static final Set<String> MONITOR_WATCHER_PATTERN = Collections.singleton("cluster:monitor/xpack/watcher/*");
|
||||
private static final Set<String> MONITOR_ROLLUP_PATTERN = Collections.singleton("cluster:monitor/xpack/rollup/*");
|
||||
private static final Set<String> ALL_CLUSTER_PATTERN = Collections.unmodifiableSet(
|
||||
Sets.newHashSet("cluster:*", "indices:admin/template/*", "indices:admin/data_stream/*"));
|
||||
Sets.newHashSet("cluster:*", "indices:admin/template/*", "indices:admin/index_template/*", "indices:admin/data_stream/*"));
|
||||
private static final Set<String> MANAGE_ML_PATTERN = Collections.unmodifiableSet(
|
||||
Sets.newHashSet("cluster:admin/xpack/ml/*", "cluster:monitor/xpack/ml/*"));
|
||||
private static final Set<String> MANAGE_TRANSFORM_PATTERN = Collections.unmodifiableSet(
|
||||
|
@ -68,7 +68,8 @@ public class ClusterPrivilegeResolver {
|
|||
Sets.newHashSet("cluster:admin/xpack/watcher/*", "cluster:monitor/xpack/watcher/*"));
|
||||
private static final Set<String> TRANSPORT_CLIENT_PATTERN = Collections.unmodifiableSet(
|
||||
Sets.newHashSet("cluster:monitor/nodes/liveness", "cluster:monitor/state"));
|
||||
private static final Set<String> MANAGE_IDX_TEMPLATE_PATTERN = Collections.singleton("indices:admin/template/*");
|
||||
private static final Set<String> MANAGE_IDX_TEMPLATE_PATTERN = Collections.unmodifiableSet(Sets.newHashSet("indices:admin/template/*",
|
||||
"indices:admin/index_template/*"));
|
||||
private static final Set<String> MANAGE_INGEST_PIPELINE_PATTERN = Collections.singleton("cluster:admin/ingest/pipeline/*");
|
||||
private static final Set<String> MANAGE_ROLLUP_PATTERN = Collections.unmodifiableSet(
|
||||
Sets.newHashSet("cluster:admin/xpack/rollup/*", "cluster:monitor/xpack/rollup/*"));
|
||||
|
@ -212,7 +213,8 @@ public class ClusterPrivilegeResolver {
|
|||
return actionName.startsWith("cluster:") ||
|
||||
actionName.startsWith("indices:admin/template/") ||
|
||||
// todo: hack until we implement security of data_streams
|
||||
actionName.startsWith("indices:admin/data_stream/");
|
||||
actionName.startsWith("indices:admin/data_stream/") ||
|
||||
actionName.startsWith("indices:admin/index_template/");
|
||||
}
|
||||
|
||||
private static String actionToPattern(String text) {
|
||||
|
|
Loading…
Reference in New Issue