Skip to content

Commit

Permalink
Add REST API for ComponentTemplate CRUD
Browse files Browse the repository at this point in the history
This adds the Put/Get/DeleteComponentTemplate APIs that allow inserting, retrieving, and removing
ComponentTemplateMetadata into the cluster state metadata.

These APIs are currently only available behind a feature flag system property -
`es.itv2_feature_flag_registered`.

Relates to elastic#53101
  • Loading branch information
dakrone committed Mar 13, 2020
1 parent 0f8de60 commit 0d1fcfd
Show file tree
Hide file tree
Showing 25 changed files with 1,495 additions and 157 deletions.
7 changes: 7 additions & 0 deletions distribution/archives/integ-test-zip/build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import org.elasticsearch.gradle.info.BuildParams
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
Expand Down Expand Up @@ -32,3 +33,9 @@ integTest.runner {
systemProperty 'tests.logfile', '--external--'
}
}

testClusters.integTest {
if (BuildParams.isSnapshotBuild() == false) {
systemProperty 'es.itv2_feature_flag_registered', 'true'
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"cluster.delete_template":{
"documentation":{
"url":"https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-component-templates.html",
"description":"Deletes a component template"
},
"stability":"stable",
"url":{
"paths":[
{
"path":"/_component_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"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"cluster.get_component_template":{
"documentation":{
"url":"https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-component-templates.html",
"description":"Returns one or more component templates"
},
"stability":"stable",
"url":{
"paths":[
{
"path":"/_component_template",
"methods":[
"GET"
]
},
{
"path":"/_component_template/{name}",
"methods":[
"GET"
],
"parts":{
"name":{
"type":"list",
"description":"The comma separated names of the component templates"
}
}
}
]
},
"params":{
"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)"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"cluster.put_template":{
"documentation":{
"url":"https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-component-templates.html",
"description":"Creates or updates a component template"
},
"stability":"stable",
"url":{
"paths":[
{
"path":"/_component_template/{name}",
"methods":[
"PUT",
"POST"
],
"parts":{
"name":{
"type":"string",
"description":"The name of the template"
}
}
}
]
},
"params":{
"create":{
"type":"boolean",
"description":"Whether the index template should only be added if new or can also replace an existing one",
"default":false
},
"timeout":{
"type":"time",
"description":"Explicit operation timeout"
},
"master_timeout":{
"type":"time",
"description":"Specify timeout for connection to master"
}
},
"body":{
"description":"The template definition",
"required":true
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
"Basic CRUD"
- do:
cluster.put_component_template:
name: test
body:
template:
settings:
number_of_shards: 1
number_of_replicas: 0
mappings:
properties:
field:
type: keyword
aliases:
aliasname: {}
version: 2
_meta:
foo: bar
baz:
eggplant: true

- do:
cluster.get_component_template:
name: test

- match: {test.version: 2}
- match: {test._meta: {foo: bar, baz: {eggplant: true}}}
- match: {test.template.settings: {index.number_of_shards: '1', index.number_of_replicas: '0'}}
- match: {test.template.mappings: {properties: {field: {type: keyword}}}}
- match: {test.template.aliases: {}}

- do:
cluster.delete_component_template:
name: test

- do:
catch: /missing/
cluster.get_component_template:
name: test
37 changes: 37 additions & 0 deletions server/src/main/java/org/elasticsearch/action/ActionModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.Build;
import org.elasticsearch.action.admin.cluster.allocation.ClusterAllocationExplainAction;
import org.elasticsearch.action.admin.cluster.allocation.TransportClusterAllocationExplainAction;
import org.elasticsearch.action.admin.cluster.configuration.AddVotingConfigExclusionsAction;
Expand Down Expand Up @@ -142,11 +143,17 @@
import org.elasticsearch.action.admin.indices.shrink.TransportResizeAction;
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.TransportDeleteComponentTemplateAction;
import org.elasticsearch.action.admin.indices.template.delete.TransportDeleteIndexTemplateAction;
import org.elasticsearch.action.admin.indices.template.get.GetComponentTemplateAction;
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.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.TransportPutComponentTemplateAction;
import org.elasticsearch.action.admin.indices.template.put.TransportPutIndexTemplateAction;
import org.elasticsearch.action.admin.indices.upgrade.get.TransportUpgradeStatusAction;
import org.elasticsearch.action.admin.indices.upgrade.get.UpgradeStatusAction;
Expand Down Expand Up @@ -269,11 +276,13 @@
import org.elasticsearch.rest.action.admin.indices.RestClearIndicesCacheAction;
import org.elasticsearch.rest.action.admin.indices.RestCloseIndexAction;
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.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.RestGetIndicesAction;
Expand All @@ -286,6 +295,7 @@
import org.elasticsearch.rest.action.admin.indices.RestIndicesShardStoresAction;
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.RestPutMappingAction;
import org.elasticsearch.rest.action.admin.indices.RestRecoveryAction;
Expand Down Expand Up @@ -361,6 +371,23 @@ public class ActionModule extends AbstractModule {

private static final Logger logger = LogManager.getLogger(ActionModule.class);

private static final boolean ITV2_FEATURE_FLAG_REGISTERED;

static {
final String property = System.getProperty("es.itv2_feature_flag_registered");
if (Build.CURRENT.isSnapshot() && property != null) {
throw new IllegalArgumentException("es.itv2_feature_flag_registered is only supported in non-snapshot builds");
}
if (Build.CURRENT.isSnapshot() || "true".equals(property)) {
ITV2_FEATURE_FLAG_REGISTERED = true;
} else if ("false".equals(property) || property == null) {
ITV2_FEATURE_FLAG_REGISTERED = false;
} else {
throw new IllegalArgumentException("expected es.itv2_feature_flag_registered to be unset, true, or false but was [" +
property + "]");
}
}

private final Settings settings;
private final IndexNameExpressionResolver indexNameExpressionResolver;
private final IndexScopedSettings indexScopedSettings;
Expand Down Expand Up @@ -486,6 +513,11 @@ public <Request extends ActionRequest, Response extends ActionResponse> void reg
actions.register(PutIndexTemplateAction.INSTANCE, TransportPutIndexTemplateAction.class);
actions.register(GetIndexTemplatesAction.INSTANCE, TransportGetIndexTemplatesAction.class);
actions.register(DeleteIndexTemplateAction.INSTANCE, TransportDeleteIndexTemplateAction.class);
if (ITV2_FEATURE_FLAG_REGISTERED) {
actions.register(PutComponentTemplateAction.INSTANCE, TransportPutComponentTemplateAction.class);
actions.register(GetComponentTemplateAction.INSTANCE, TransportGetComponentTemplateAction.class);
actions.register(DeleteComponentTemplateAction.INSTANCE, TransportDeleteComponentTemplateAction.class);
}
actions.register(ValidateQueryAction.INSTANCE, TransportValidateQueryAction.class);
actions.register(RefreshAction.INSTANCE, TransportRefreshAction.class);
actions.register(FlushAction.INSTANCE, TransportFlushAction.class);
Expand Down Expand Up @@ -621,6 +653,11 @@ public void initRestHandlers(Supplier<DiscoveryNodes> nodesInCluster) {
registerHandler.accept(new RestGetIndexTemplateAction());
registerHandler.accept(new RestPutIndexTemplateAction());
registerHandler.accept(new RestDeleteIndexTemplateAction());
if (ITV2_FEATURE_FLAG_REGISTERED) {
registerHandler.accept(new RestPutComponentTemplateAction());
registerHandler.accept(new RestGetComponentTemplateAction());
registerHandler.accept(new RestDeleteComponentTemplateAction());
}

registerHandler.accept(new RestPutMappingAction());
registerHandler.accept(new RestGetMappingAction());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* 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.ActionType;
import org.elasticsearch.action.support.master.AcknowledgedResponse;

public class DeleteComponentTemplateAction extends ActionType<AcknowledgedResponse> {

public static final DeleteComponentTemplateAction INSTANCE = new DeleteComponentTemplateAction();
public static final String NAME = "cluster:admin/component_template/delete";

private DeleteComponentTemplateAction() {
super(NAME, AcknowledgedResponse::new);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* 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.support.master.MasterNodeRequest;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;

import java.io.IOException;

import static org.elasticsearch.action.ValidateActions.addValidationError;

public class DeleteComponentTemplateRequest extends MasterNodeRequest<DeleteComponentTemplateRequest> {

private String name;

public DeleteComponentTemplateRequest(StreamInput in) throws IOException {
super(in);
name = in.readString();
}

public DeleteComponentTemplateRequest() {
}

/**
* Constructs a new delete index request for the specified name.
*/
public DeleteComponentTemplateRequest(String name) {
this.name = name;
}

/**
* Set the index template name to delete.
*/
public DeleteComponentTemplateRequest 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);
}
}
Loading

0 comments on commit 0d1fcfd

Please sign in to comment.