From a314efc92004d78279af15afd3b1e3f54e5e6408 Mon Sep 17 00:00:00 2001 From: Lee Hinman Date: Mon, 30 Jul 2018 16:57:25 -0600 Subject: [PATCH] Add high level rest client support for SetIndexLifecyclePolicy (#32443) This adds HLRC support for the ILM operation of setting an index's lifecycle policy. It also includes extracting and renaming a number of classes (like the request and response objects) as well as the addition of a new `IndexLifecycleClient` for the HLRC. This is a prerequisite to making the `index.lifecycle.name` setting internal only, because we require a dedicated REST endpoint to change the policy, and our tests currently set this setting with the REST client multiple places. A subsequent PR will change the setting to be internal and move those uses over to this new API. This misses some links to the documentation because I don't think ILM has any documentation available yet. Relates to #29827 and #29823 --- .../client/IndexLifecycleClient.java | 65 ++++++ .../client/RequestConverters.java | 23 +- .../org/elasticsearch/client/XPackClient.java | 13 ++ .../client/IndexLifecycleIT.java | 103 +++++++++ .../client/RequestConvertersTests.java | 20 ++ .../xpack/core/XPackClientPlugin.java | 4 +- .../action/SetIndexLifecyclePolicyAction.java | 25 +++ .../action/SetPolicyForIndexAction.java | 197 ------------------ .../SetPolicyForIndexResponseTests.java | 69 ------ .../xpack/indexlifecycle/IndexLifecycle.java | 10 +- ...=> RestSetIndexLifecyclePolicyAction.java} | 18 +- ...ansportSetIndexLifecyclePolicyAction.java} | 33 +-- .../SetIndexLifecyclePolicyRequest.java | 122 +++++++++++ .../SetIndexLifecyclePolicyResponse.java | 111 ++++++++++ .../SetIndexLifecyclePolicyRequestTests.java} | 43 ++-- .../SetIndexLifecyclePolicyResponseTests.java | 81 +++++++ 16 files changed, 623 insertions(+), 314 deletions(-) create mode 100644 client/rest-high-level/src/main/java/org/elasticsearch/client/IndexLifecycleClient.java create mode 100644 client/rest-high-level/src/test/java/org/elasticsearch/client/IndexLifecycleIT.java create mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/action/SetIndexLifecyclePolicyAction.java delete mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/action/SetPolicyForIndexAction.java delete mode 100644 x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/action/SetPolicyForIndexResponseTests.java rename x-pack/plugin/index-lifecycle/src/main/java/org/elasticsearch/xpack/indexlifecycle/action/{RestSetPolicyForIndexAction.java => RestSetIndexLifecyclePolicyAction.java} (61%) rename x-pack/plugin/index-lifecycle/src/main/java/org/elasticsearch/xpack/indexlifecycle/action/{TransportSetPolicyForIndexAction.java => TransportSetIndexLifecyclePolicyAction.java} (65%) create mode 100644 x-pack/protocol/src/main/java/org/elasticsearch/protocol/xpack/indexlifecycle/SetIndexLifecyclePolicyRequest.java create mode 100644 x-pack/protocol/src/main/java/org/elasticsearch/protocol/xpack/indexlifecycle/SetIndexLifecyclePolicyResponse.java rename x-pack/{plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/action/SetPolicyForIndexRequestTests.java => protocol/src/test/java/org/elasticsearch/protocol/xpack/indexlifecycle/SetIndexLifecyclePolicyRequestTests.java} (52%) create mode 100644 x-pack/protocol/src/test/java/org/elasticsearch/protocol/xpack/indexlifecycle/SetIndexLifecyclePolicyResponseTests.java diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/IndexLifecycleClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndexLifecycleClient.java new file mode 100644 index 00000000000..d2714da560f --- /dev/null +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/IndexLifecycleClient.java @@ -0,0 +1,65 @@ +/* + * 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.client; + +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyRequest; +import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyResponse; + +import java.io.IOException; + +import static java.util.Collections.emptySet; + +public class IndexLifecycleClient { + private final RestHighLevelClient restHighLevelClient; + + IndexLifecycleClient(RestHighLevelClient restHighLevelClient) { + this.restHighLevelClient = restHighLevelClient; + } + + /** + * Set the index lifecycle policy for an index + * See + * the docs for more. + * @param request the request + * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized + * @return the response + * @throws IOException in case there is a problem sending the request or parsing back the response + */ + public SetIndexLifecyclePolicyResponse setIndexLifecyclePolicy(SetIndexLifecyclePolicyRequest request, + RequestOptions options) throws IOException { + return restHighLevelClient.performRequestAndParseEntity(request, RequestConverters::setIndexLifecyclePolicy, options, + SetIndexLifecyclePolicyResponse::fromXContent, emptySet()); + } + + /** + * Asynchronously set the index lifecycle policy for an index + * See + * the docs for more. + * @param request the request + * @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized + * @param listener the listener to be notified upon request completion + */ + public void setIndexLifecyclePolicyAsync(SetIndexLifecyclePolicyRequest request, RequestOptions options, + ActionListener listener) { + restHighLevelClient.performRequestAsyncAndParseEntity(request, RequestConverters::setIndexLifecyclePolicy, options, + SetIndexLifecyclePolicyResponse::fromXContent, listener, emptySet()); + } +} diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java index b9360877dfc..d85f316efa8 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java @@ -39,12 +39,12 @@ import org.elasticsearch.action.admin.cluster.repositories.verify.VerifyReposito import org.elasticsearch.action.admin.cluster.settings.ClusterGetSettingsRequest; import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest; import org.elasticsearch.action.admin.cluster.snapshots.create.CreateSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; import org.elasticsearch.action.admin.cluster.snapshots.restore.RestoreSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest; import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest; import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; -import org.elasticsearch.action.admin.cluster.snapshots.status.SnapshotsStatusRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; import org.elasticsearch.action.admin.indices.analyze.AnalyzeRequest; @@ -78,8 +78,8 @@ import org.elasticsearch.action.get.MultiGetRequest; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.ingest.DeletePipelineRequest; import org.elasticsearch.action.ingest.GetPipelineRequest; -import org.elasticsearch.action.ingest.SimulatePipelineRequest; import org.elasticsearch.action.ingest.PutPipelineRequest; +import org.elasticsearch.action.ingest.SimulatePipelineRequest; import org.elasticsearch.action.search.ClearScrollRequest; import org.elasticsearch.action.search.MultiSearchRequest; import org.elasticsearch.action.search.SearchRequest; @@ -107,9 +107,10 @@ import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.VersionType; import org.elasticsearch.index.rankeval.RankEvalRequest; import org.elasticsearch.protocol.xpack.XPackInfoRequest; -import org.elasticsearch.protocol.xpack.watcher.PutWatchRequest; import org.elasticsearch.protocol.xpack.XPackUsageRequest; +import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyRequest; import org.elasticsearch.protocol.xpack.license.PutLicenseRequest; +import org.elasticsearch.protocol.xpack.watcher.PutWatchRequest; import org.elasticsearch.rest.action.search.RestSearchAction; import org.elasticsearch.script.mustache.MultiSearchTemplateRequest; import org.elasticsearch.script.mustache.SearchTemplateRequest; @@ -1140,6 +1141,20 @@ final class RequestConverters { return request; } + static Request setIndexLifecyclePolicy(SetIndexLifecyclePolicyRequest setPolicyRequest) { + String[] indices = setPolicyRequest.indices() == null ? Strings.EMPTY_ARRAY : setPolicyRequest.indices(); + Request request = new Request(HttpPut.METHOD_NAME, + new EndpointBuilder() + .addCommaSeparatedPathParts(indices) + .addPathPartAsIs("_lifecycle") + .addPathPart(setPolicyRequest.policy()) + .build()); + Params params = new Params(request); + params.withIndicesOptions(setPolicyRequest.indicesOptions()); + params.withMasterTimeout(setPolicyRequest.masterNodeTimeout()); + return request; + } + static Request putLicense(PutLicenseRequest putLicenseRequest) { Request request = new Request(HttpPut.METHOD_NAME, "/_xpack/license"); Params parameters = new Params(request); diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/XPackClient.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/XPackClient.java index 1401376527d..dcb0a3f64f5 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/XPackClient.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/XPackClient.java @@ -43,11 +43,13 @@ public final class XPackClient { private final RestHighLevelClient restHighLevelClient; private final WatcherClient watcherClient; private final LicenseClient licenseClient; + private final IndexLifecycleClient indexLifecycleClient; XPackClient(RestHighLevelClient restHighLevelClient) { this.restHighLevelClient = restHighLevelClient; this.watcherClient = new WatcherClient(restHighLevelClient); this.licenseClient = new LicenseClient(restHighLevelClient); + this.indexLifecycleClient = new IndexLifecycleClient(restHighLevelClient); } public WatcherClient watcher() { @@ -113,4 +115,15 @@ public final class XPackClient { public LicenseClient license() { return licenseClient; } + + /** + * A wrapper for the {@link RestHighLevelClient} that provides methods for + * accessing the Elastic Index Lifecycle APIs. + *

+ * See the + * X-Pack APIs on elastic.co for more information. + */ + public IndexLifecycleClient indexLifecycle() { + return this.indexLifecycleClient; + } } diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/IndexLifecycleIT.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/IndexLifecycleIT.java new file mode 100644 index 00000000000..3f89d9c061d --- /dev/null +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/IndexLifecycleIT.java @@ -0,0 +1,103 @@ +/* + * 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.client; + +import org.apache.http.HttpEntity; +import org.apache.http.entity.ContentType; +import org.apache.http.nio.entity.NStringEntity; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyRequest; +import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyResponse; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; + +public class IndexLifecycleIT extends ESRestHighLevelClientTestCase { + + public void testSetIndexLifecyclePolicy() throws Exception { + String policy = randomAlphaOfLength(10); + + // TODO: NORELEASE convert this to using the high level client once there are APIs for it + String jsonString = "{\n" + + " \"policy\": {\n" + + " \"type\": \"timeseries\",\n" + + " \"phases\": {\n" + + " \"hot\": {\n" + + " \"after\": \"60s\",\n" + + " \"actions\": {\n" + + " \"rollover\": {\n" + + " \"max_age\": \"500s\"\n" + + " } \n" + + " }\n" + + " },\n" + + " \"warm\": {\n" + + " \"after\": \"1000s\",\n" + + " \"actions\": {\n" + + " \"allocate\": {\n" + + " \"require\": { \"_name\": \"node-1\" },\n" + + " \"include\": {},\n" + + " \"exclude\": {}\n" + + " },\n" + + " \"shrink\": {\n" + + " \"number_of_shards\": 1\n" + + " },\n" + + " \"forcemerge\": {\n" + + " \"max_num_segments\": 1000\n" + + " }\n" + + " }\n" + + " },\n" + + " \"cold\": {\n" + + " \"after\": \"2000s\",\n" + + " \"actions\": {\n" + + " \"replicas\": {\n" + + " \"number_of_replicas\": 0\n" + + " }\n" + + " }\n" + + " },\n" + + " \"delete\": {\n" + + " \"after\": \"3000s\",\n" + + " \"actions\": {\n" + + " \"delete\": {}\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + "}"; + HttpEntity entity = new NStringEntity(jsonString, ContentType.APPLICATION_JSON); + Request request = new Request("PUT", "/_xpack/index_lifecycle/" + policy); + request.setEntity(entity); + client().performRequest(request); + + createIndex("foo", Settings.builder().put("index.lifecycle.name", "bar").build()); + createIndex("baz", Settings.builder().put("index.lifecycle.name", "eggplant").build()); + SetIndexLifecyclePolicyRequest req = new SetIndexLifecyclePolicyRequest(policy, "foo", "baz"); + SetIndexLifecyclePolicyResponse response = execute(req, highLevelClient().xpack().indexLifecycle()::setIndexLifecyclePolicy, + highLevelClient().xpack().indexLifecycle()::setIndexLifecyclePolicyAsync); + assertThat(response.hasFailures(), is(false)); + assertThat(response.getFailedIndexes().isEmpty(), is(true)); + + GetSettingsRequest getSettingsRequest = new GetSettingsRequest().indices("foo", "baz"); + GetSettingsResponse settingsResponse = highLevelClient().indices().getSettings(getSettingsRequest, RequestOptions.DEFAULT); + assertThat(settingsResponse.getSetting("foo", "index.lifecycle.name"), equalTo(policy)); + assertThat(settingsResponse.getSetting("baz", "index.lifecycle.name"), equalTo(policy)); + } +} diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java index 0415d363c54..1b38ae195e9 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java @@ -126,6 +126,7 @@ import org.elasticsearch.index.rankeval.RankEvalSpec; import org.elasticsearch.index.rankeval.RatedRequest; import org.elasticsearch.index.rankeval.RestRankEvalAction; import org.elasticsearch.protocol.xpack.XPackInfoRequest; +import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyRequest; import org.elasticsearch.protocol.xpack.watcher.PutWatchRequest; import org.elasticsearch.repositories.fs.FsRepository; import org.elasticsearch.rest.action.search.RestSearchAction; @@ -2580,6 +2581,25 @@ public class RequestConvertersTests extends ESTestCase { assertThat(bos.toString("UTF-8"), is(body)); } + public void testSetIndexLifecyclePolicy() throws Exception { + SetIndexLifecyclePolicyRequest req = new SetIndexLifecyclePolicyRequest(); + String policyName = randomAlphaOfLength(10); + String[] indices = rarely() ? null : randomIndicesNames(0, 10); + req.policy(policyName); + req.indices(indices); + Map expectedParams = new HashMap<>(); + setRandomMasterTimeout(req, expectedParams); + setRandomIndicesOptions(req::indicesOptions, req::indicesOptions, expectedParams); + + Request request = RequestConverters.setIndexLifecyclePolicy(req); + assertThat(request.getMethod(), equalTo(HttpPut.METHOD_NAME)); + String idxString = Strings.arrayToCommaDelimitedString(indices); + assertThat(request.getEndpoint(), + equalTo("/" + (idxString.isEmpty() ? "" : (idxString + "/")) + + "_lifecycle/" + policyName)); + assertThat(request.getParameters(), equalTo(expectedParams)); + } + /** * Randomize the {@link FetchSourceContext} request parameters. */ diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClientPlugin.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClientPlugin.java index 49449e44d98..76df45d8a5e 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClientPlugin.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackClientPlugin.java @@ -60,7 +60,7 @@ import org.elasticsearch.xpack.core.indexlifecycle.action.MoveToStepAction; import org.elasticsearch.xpack.core.indexlifecycle.action.PutLifecycleAction; import org.elasticsearch.xpack.core.indexlifecycle.action.RemovePolicyForIndexAction; import org.elasticsearch.xpack.core.indexlifecycle.action.RetryAction; -import org.elasticsearch.xpack.core.indexlifecycle.action.SetPolicyForIndexAction; +import org.elasticsearch.xpack.core.indexlifecycle.action.SetIndexLifecyclePolicyAction; import org.elasticsearch.xpack.core.logstash.LogstashFeatureSetUsage; import org.elasticsearch.xpack.core.beats.BeatsFeatureSetUsage; import org.elasticsearch.xpack.core.ml.MachineLearningFeatureSetUsage; @@ -338,7 +338,7 @@ public class XPackClientPlugin extends Plugin implements ActionPlugin, NetworkPl GetLifecycleAction.INSTANCE, PutLifecycleAction.INSTANCE, ExplainLifecycleAction.INSTANCE, - SetPolicyForIndexAction.INSTANCE, + SetIndexLifecyclePolicyAction.INSTANCE, RemovePolicyForIndexAction.INSTANCE, MoveToStepAction.INSTANCE, RetryAction.INSTANCE diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/action/SetIndexLifecyclePolicyAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/action/SetIndexLifecyclePolicyAction.java new file mode 100644 index 00000000000..e0d979c69a9 --- /dev/null +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/action/SetIndexLifecyclePolicyAction.java @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +package org.elasticsearch.xpack.core.indexlifecycle.action; + +import org.elasticsearch.action.Action; +import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyResponse; + +public class SetIndexLifecyclePolicyAction extends Action { + + public static final SetIndexLifecyclePolicyAction INSTANCE = new SetIndexLifecyclePolicyAction(); + public static final String NAME = "indices:admin/xpack/index_lifecycle/set_index_policy"; + + protected SetIndexLifecyclePolicyAction() { + super(NAME); + } + + @Override + public SetIndexLifecyclePolicyResponse newResponse() { + return new SetIndexLifecyclePolicyResponse(); + } +} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/action/SetPolicyForIndexAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/action/SetPolicyForIndexAction.java deleted file mode 100644 index 0ad551501de..00000000000 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/action/SetPolicyForIndexAction.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -package org.elasticsearch.xpack.core.indexlifecycle.action; - -import org.elasticsearch.action.Action; -import org.elasticsearch.action.ActionRequestValidationException; -import org.elasticsearch.action.ActionResponse; -import org.elasticsearch.action.IndicesRequest; -import org.elasticsearch.action.support.IndicesOptions; -import org.elasticsearch.action.support.master.AcknowledgedRequest; -import org.elasticsearch.common.ParseField; -import org.elasticsearch.common.io.stream.StreamInput; -import org.elasticsearch.common.io.stream.StreamOutput; -import org.elasticsearch.common.xcontent.ConstructingObjectParser; -import org.elasticsearch.common.xcontent.ToXContentObject; -import org.elasticsearch.common.xcontent.XContentBuilder; - -import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.Objects; - -public class SetPolicyForIndexAction extends Action { - public static final SetPolicyForIndexAction INSTANCE = new SetPolicyForIndexAction(); - public static final String NAME = "indices:admin/xpack/index_lifecycle/set_policy"; - - protected SetPolicyForIndexAction() { - super(NAME); - } - - @Override - public SetPolicyForIndexAction.Response newResponse() { - return new Response(); - } - - public static class Response extends ActionResponse implements ToXContentObject { - - public static final ParseField HAS_FAILURES_FIELD = new ParseField("has_failures"); - public static final ParseField FAILED_INDEXES_FIELD = new ParseField("failed_indexes"); - @SuppressWarnings("unchecked") - public static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( - "change_policy_for_index_response", a -> new Response((List) a[0])); - static { - PARSER.declareStringArray(ConstructingObjectParser.constructorArg(), FAILED_INDEXES_FIELD); - // Needs to be declared but not used in constructing the response object - PARSER.declareBoolean(ConstructingObjectParser.constructorArg(), HAS_FAILURES_FIELD); - } - - private List failedIndexes; - - public Response() { - } - - public Response(List failedIndexes) { - if (failedIndexes == null) { - throw new IllegalArgumentException(FAILED_INDEXES_FIELD.getPreferredName() + " cannot be null"); - } - this.failedIndexes = failedIndexes; - } - - public List getFailedIndexes() { - return failedIndexes; - } - - public boolean hasFailures() { - return failedIndexes.isEmpty() == false; - } - - @Override - public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { - builder.startObject(); - builder.field(HAS_FAILURES_FIELD.getPreferredName(), hasFailures()); - builder.field(FAILED_INDEXES_FIELD.getPreferredName(), failedIndexes); - builder.endObject(); - return builder; - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - failedIndexes = in.readList(StreamInput::readString); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeStringList(failedIndexes); - } - - @Override - public int hashCode() { - return Objects.hash(failedIndexes); - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - Response other = (Response) obj; - return Objects.equals(failedIndexes, other.failedIndexes); - } - - } - - public static class Request extends AcknowledgedRequest implements IndicesRequest.Replaceable { - - private String[] indices; - private IndicesOptions indicesOptions = IndicesOptions.strictExpandOpen(); - private String policy; - - public Request() { - } - - public Request(String policy, String... indices) { - if (indices == null) { - throw new IllegalArgumentException("indices cannot be null"); - } - if (policy == null) { - throw new IllegalArgumentException("policy cannot be null"); - } - this.indices = indices; - this.policy = policy; - } - - @Override - public Request indices(String... indices) { - this.indices = indices; - return this; - } - - @Override - public String[] indices() { - return indices; - } - - public String policy() { - return policy; - } - - public void indicesOptions(IndicesOptions indicesOptions) { - this.indicesOptions = indicesOptions; - } - - public IndicesOptions indicesOptions() { - return indicesOptions; - } - - @Override - public ActionRequestValidationException validate() { - return null; - } - - @Override - public void readFrom(StreamInput in) throws IOException { - super.readFrom(in); - indices = in.readStringArray(); - indicesOptions = IndicesOptions.readIndicesOptions(in); - policy = in.readString(); - } - - @Override - public void writeTo(StreamOutput out) throws IOException { - super.writeTo(out); - out.writeStringArray(indices); - indicesOptions.writeIndicesOptions(out); - out.writeString(policy); - } - - @Override - public int hashCode() { - return Objects.hash(Arrays.hashCode(indices), indicesOptions, policy); - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - Request other = (Request) obj; - return Objects.deepEquals(indices, other.indices) && - Objects.equals(indicesOptions, other.indicesOptions) && - Objects.equals(policy, other.policy); - } - - } -} diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/action/SetPolicyForIndexResponseTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/action/SetPolicyForIndexResponseTests.java deleted file mode 100644 index 0489b0cf14f..00000000000 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/action/SetPolicyForIndexResponseTests.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -package org.elasticsearch.xpack.core.indexlifecycle.action; - -import org.elasticsearch.common.xcontent.XContentParser; -import org.elasticsearch.test.AbstractStreamableXContentTestCase; -import org.elasticsearch.xpack.core.indexlifecycle.action.SetPolicyForIndexAction.Response; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -public class SetPolicyForIndexResponseTests extends AbstractStreamableXContentTestCase { - - @Override - protected Response createBlankInstance() { - return new Response(); - } - - @Override - protected Response createTestInstance() { - List failedIndexes = Arrays.asList(generateRandomStringArray(20, 20, false)); - return new Response(failedIndexes); - } - - @Override - protected Response mutateInstance(Response instance) throws IOException { - List failedIndices = randomValueOtherThan(instance.getFailedIndexes(), - () -> Arrays.asList(generateRandomStringArray(20, 20, false))); - return new Response(failedIndices); - } - - @Override - protected Response doParseInstance(XContentParser parser) throws IOException { - return Response.PARSER.apply(parser, null); - } - - @Override - protected boolean supportsUnknownFields() { - return false; - } - - public void testNullFailedIndices() { - IllegalArgumentException exception = expectThrows(IllegalArgumentException.class, () -> new Response((List) null)); - assertEquals("failed_indexes cannot be null", exception.getMessage()); - } - - public void testHasFailures() { - Response response = new Response(new ArrayList<>()); - assertFalse(response.hasFailures()); - assertEquals(Collections.emptyList(), response.getFailedIndexes()); - - int size = randomIntBetween(1, 10); - List failedIndexes = new ArrayList<>(size); - for (int i = 0; i < size; i++) { - failedIndexes.add(randomAlphaOfLength(20)); - } - response = new Response(failedIndexes); - assertTrue(response.hasFailures()); - assertEquals(failedIndexes, response.getFailedIndexes()); - } - -} diff --git a/x-pack/plugin/index-lifecycle/src/main/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycle.java b/x-pack/plugin/index-lifecycle/src/main/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycle.java index ffb1d837fe7..3583d79641a 100644 --- a/x-pack/plugin/index-lifecycle/src/main/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycle.java +++ b/x-pack/plugin/index-lifecycle/src/main/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycle.java @@ -43,7 +43,7 @@ import org.elasticsearch.xpack.core.indexlifecycle.action.PutLifecycleAction; import org.elasticsearch.xpack.core.indexlifecycle.action.PutOperationModeAction; import org.elasticsearch.xpack.core.indexlifecycle.action.RemovePolicyForIndexAction; import org.elasticsearch.xpack.core.indexlifecycle.action.RetryAction; -import org.elasticsearch.xpack.core.indexlifecycle.action.SetPolicyForIndexAction; +import org.elasticsearch.xpack.core.indexlifecycle.action.SetIndexLifecyclePolicyAction; import org.elasticsearch.xpack.indexlifecycle.action.RestDeleteLifecycleAction; import org.elasticsearch.xpack.indexlifecycle.action.RestExplainLifecycleAction; import org.elasticsearch.xpack.indexlifecycle.action.RestGetLifecycleAction; @@ -52,7 +52,7 @@ import org.elasticsearch.xpack.indexlifecycle.action.RestMoveToStepAction; import org.elasticsearch.xpack.indexlifecycle.action.RestPutLifecycleAction; import org.elasticsearch.xpack.indexlifecycle.action.RestRemovePolicyForIndexAction; import org.elasticsearch.xpack.indexlifecycle.action.RestRetryAction; -import org.elasticsearch.xpack.indexlifecycle.action.RestSetPolicyForIndexAction; +import org.elasticsearch.xpack.indexlifecycle.action.RestSetIndexLifecyclePolicyAction; import org.elasticsearch.xpack.indexlifecycle.action.RestStartAction; import org.elasticsearch.xpack.indexlifecycle.action.RestStopAction; import org.elasticsearch.xpack.indexlifecycle.action.TransportDeleteLifecycleAction; @@ -64,7 +64,7 @@ import org.elasticsearch.xpack.indexlifecycle.action.TransportPutLifecycleAction import org.elasticsearch.xpack.indexlifecycle.action.TransportPutOperationModeAction; import org.elasticsearch.xpack.indexlifecycle.action.TransportRemovePolicyForIndexAction; import org.elasticsearch.xpack.indexlifecycle.action.TransportRetryAction; -import org.elasticsearch.xpack.indexlifecycle.action.TransportSetPolicyForIndexAction; +import org.elasticsearch.xpack.indexlifecycle.action.TransportSetIndexLifecyclePolicyAction; import java.time.Clock; import java.util.ArrayList; @@ -160,7 +160,7 @@ public class IndexLifecycle extends Plugin implements ActionPlugin { new RestGetLifecycleAction(settings, restController), new RestDeleteLifecycleAction(settings, restController), new RestExplainLifecycleAction(settings, restController), - new RestSetPolicyForIndexAction(settings, restController), + new RestSetIndexLifecyclePolicyAction(settings, restController), new RestRemovePolicyForIndexAction(settings, restController), new RestMoveToStepAction(settings, restController), new RestRetryAction(settings, restController), @@ -180,7 +180,7 @@ public class IndexLifecycle extends Plugin implements ActionPlugin { new ActionHandler<>(GetLifecycleAction.INSTANCE, TransportGetLifecycleAction.class), new ActionHandler<>(DeleteLifecycleAction.INSTANCE, TransportDeleteLifecycleAction.class), new ActionHandler<>(ExplainLifecycleAction.INSTANCE, TransportExplainLifecycleAction.class), - new ActionHandler<>(SetPolicyForIndexAction.INSTANCE, TransportSetPolicyForIndexAction.class), + new ActionHandler<>(SetIndexLifecyclePolicyAction.INSTANCE, TransportSetIndexLifecyclePolicyAction.class), new ActionHandler<>(RemovePolicyForIndexAction.INSTANCE, TransportRemovePolicyForIndexAction.class), new ActionHandler<>(MoveToStepAction.INSTANCE, TransportMoveToStepAction.class), new ActionHandler<>(RetryAction.INSTANCE, TransportRetryAction.class), diff --git a/x-pack/plugin/index-lifecycle/src/main/java/org/elasticsearch/xpack/indexlifecycle/action/RestSetPolicyForIndexAction.java b/x-pack/plugin/index-lifecycle/src/main/java/org/elasticsearch/xpack/indexlifecycle/action/RestSetIndexLifecyclePolicyAction.java similarity index 61% rename from x-pack/plugin/index-lifecycle/src/main/java/org/elasticsearch/xpack/indexlifecycle/action/RestSetPolicyForIndexAction.java rename to x-pack/plugin/index-lifecycle/src/main/java/org/elasticsearch/xpack/indexlifecycle/action/RestSetIndexLifecyclePolicyAction.java index dc903296a5f..0f12357bdec 100644 --- a/x-pack/plugin/index-lifecycle/src/main/java/org/elasticsearch/xpack/indexlifecycle/action/RestSetPolicyForIndexAction.java +++ b/x-pack/plugin/index-lifecycle/src/main/java/org/elasticsearch/xpack/indexlifecycle/action/RestSetIndexLifecyclePolicyAction.java @@ -5,6 +5,7 @@ */ package org.elasticsearch.xpack.indexlifecycle.action; +import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.client.node.NodeClient; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; @@ -12,13 +13,14 @@ import org.elasticsearch.rest.BaseRestHandler; import org.elasticsearch.rest.RestController; import org.elasticsearch.rest.RestRequest; import org.elasticsearch.rest.action.RestToXContentListener; -import org.elasticsearch.xpack.core.indexlifecycle.action.SetPolicyForIndexAction; +import org.elasticsearch.xpack.core.indexlifecycle.action.SetIndexLifecyclePolicyAction; +import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyRequest; import java.io.IOException; -public class RestSetPolicyForIndexAction extends BaseRestHandler { +public class RestSetIndexLifecyclePolicyAction extends BaseRestHandler { - public RestSetPolicyForIndexAction(Settings settings, RestController controller) { + public RestSetIndexLifecyclePolicyAction(Settings settings, RestController controller) { super(settings); controller.registerHandler(RestRequest.Method.PUT, "_lifecycle/{new_policy}", this); controller.registerHandler(RestRequest.Method.PUT, "{index}/_lifecycle/{new_policy}", this); @@ -26,16 +28,18 @@ public class RestSetPolicyForIndexAction extends BaseRestHandler { @Override public String getName() { - return "xpack_set_policy_for_index_action"; + return "xpack_set_index_policy_action"; } @Override protected RestChannelConsumer prepareRequest(RestRequest restRequest, NodeClient client) throws IOException { String[] indexes = Strings.splitStringByCommaToArray(restRequest.param("index")); String newPolicyName = restRequest.param("new_policy"); - SetPolicyForIndexAction.Request changePolicyRequest = new SetPolicyForIndexAction.Request(newPolicyName, indexes); + SetIndexLifecyclePolicyRequest changePolicyRequest = new SetIndexLifecyclePolicyRequest(newPolicyName, indexes); changePolicyRequest.masterNodeTimeout(restRequest.paramAsTime("master_timeout", changePolicyRequest.masterNodeTimeout())); + changePolicyRequest.indicesOptions(IndicesOptions.fromRequest(restRequest, changePolicyRequest.indicesOptions())); - return channel -> client.execute(SetPolicyForIndexAction.INSTANCE, changePolicyRequest, new RestToXContentListener<>(channel)); + return channel -> client.execute(SetIndexLifecyclePolicyAction.INSTANCE, + changePolicyRequest, new RestToXContentListener<>(channel)); } -} \ No newline at end of file +} diff --git a/x-pack/plugin/index-lifecycle/src/main/java/org/elasticsearch/xpack/indexlifecycle/action/TransportSetPolicyForIndexAction.java b/x-pack/plugin/index-lifecycle/src/main/java/org/elasticsearch/xpack/indexlifecycle/action/TransportSetIndexLifecyclePolicyAction.java similarity index 65% rename from x-pack/plugin/index-lifecycle/src/main/java/org/elasticsearch/xpack/indexlifecycle/action/TransportSetPolicyForIndexAction.java rename to x-pack/plugin/index-lifecycle/src/main/java/org/elasticsearch/xpack/indexlifecycle/action/TransportSetIndexLifecyclePolicyAction.java index 4e66e77d5a9..fd1d1d22593 100644 --- a/x-pack/plugin/index-lifecycle/src/main/java/org/elasticsearch/xpack/indexlifecycle/action/TransportSetPolicyForIndexAction.java +++ b/x-pack/plugin/index-lifecycle/src/main/java/org/elasticsearch/xpack/indexlifecycle/action/TransportSetIndexLifecyclePolicyAction.java @@ -23,21 +23,23 @@ import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.transport.TransportService; import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleMetadata; import org.elasticsearch.xpack.core.indexlifecycle.LifecyclePolicy; -import org.elasticsearch.xpack.core.indexlifecycle.action.SetPolicyForIndexAction; -import org.elasticsearch.xpack.core.indexlifecycle.action.SetPolicyForIndexAction.Request; -import org.elasticsearch.xpack.core.indexlifecycle.action.SetPolicyForIndexAction.Response; +import org.elasticsearch.xpack.core.indexlifecycle.action.SetIndexLifecyclePolicyAction; +import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyRequest; +import org.elasticsearch.protocol.xpack.indexlifecycle.SetIndexLifecyclePolicyResponse; import org.elasticsearch.xpack.indexlifecycle.IndexLifecycleRunner; import java.util.ArrayList; import java.util.List; -public class TransportSetPolicyForIndexAction extends TransportMasterNodeAction { +public class TransportSetIndexLifecyclePolicyAction + extends TransportMasterNodeAction { @Inject - public TransportSetPolicyForIndexAction(Settings settings, TransportService transportService, ClusterService clusterService, - ThreadPool threadPool, ActionFilters actionFilters, IndexNameExpressionResolver indexNameExpressionResolver) { - super(settings, SetPolicyForIndexAction.NAME, transportService, clusterService, threadPool, actionFilters, - indexNameExpressionResolver, Request::new); + public TransportSetIndexLifecyclePolicyAction(Settings settings, TransportService transportService, ClusterService clusterService, + ThreadPool threadPool, ActionFilters actionFilters, + IndexNameExpressionResolver indexNameExpressionResolver) { + super(settings, SetIndexLifecyclePolicyAction.NAME, transportService, clusterService, threadPool, actionFilters, + indexNameExpressionResolver, SetIndexLifecyclePolicyRequest::new); } @Override @@ -46,21 +48,22 @@ public class TransportSetPolicyForIndexAction extends TransportMasterNodeAction< } @Override - protected Response newResponse() { - return new Response(); + protected SetIndexLifecyclePolicyResponse newResponse() { + return new SetIndexLifecyclePolicyResponse(); } @Override - protected ClusterBlockException checkBlock(Request request, ClusterState state) { + protected ClusterBlockException checkBlock(SetIndexLifecyclePolicyRequest request, ClusterState state) { return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_WRITE); } @Override - protected void masterOperation(Request request, ClusterState state, ActionListener listener) throws Exception { + protected void masterOperation(SetIndexLifecyclePolicyRequest request, ClusterState state, + ActionListener listener) throws Exception { final String newPolicyName = request.policy(); final Index[] indices = indexNameExpressionResolver.concreteIndices(state, request.indicesOptions(), request.indices()); clusterService.submitStateUpdateTask("change-lifecycle-for-index-" + newPolicyName, - new AckedClusterStateUpdateTask(request, listener) { + new AckedClusterStateUpdateTask(request, listener) { private final List failedIndexes = new ArrayList<>(); @@ -89,8 +92,8 @@ public class TransportSetPolicyForIndexAction extends TransportMasterNodeAction< } @Override - protected Response newResponse(boolean acknowledged) { - return new Response(failedIndexes); + protected SetIndexLifecyclePolicyResponse newResponse(boolean acknowledged) { + return new SetIndexLifecyclePolicyResponse(failedIndexes); } }); } diff --git a/x-pack/protocol/src/main/java/org/elasticsearch/protocol/xpack/indexlifecycle/SetIndexLifecyclePolicyRequest.java b/x-pack/protocol/src/main/java/org/elasticsearch/protocol/xpack/indexlifecycle/SetIndexLifecyclePolicyRequest.java new file mode 100644 index 00000000000..af19d51fd80 --- /dev/null +++ b/x-pack/protocol/src/main/java/org/elasticsearch/protocol/xpack/indexlifecycle/SetIndexLifecyclePolicyRequest.java @@ -0,0 +1,122 @@ +/* + * 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.protocol.xpack.indexlifecycle; + +import org.elasticsearch.action.ActionRequestValidationException; +import org.elasticsearch.action.IndicesRequest; +import org.elasticsearch.action.support.IndicesOptions; +import org.elasticsearch.action.support.master.AcknowledgedRequest; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Objects; + +public class SetIndexLifecyclePolicyRequest extends AcknowledgedRequest + implements IndicesRequest.Replaceable { + + private String[] indices; + private IndicesOptions indicesOptions = IndicesOptions.strictExpandOpen(); + private String policy; + + public SetIndexLifecyclePolicyRequest() { + } + + public SetIndexLifecyclePolicyRequest(String policy, String... indices) { + if (indices == null) { + throw new IllegalArgumentException("indices cannot be null"); + } + if (policy == null) { + throw new IllegalArgumentException("policy cannot be null"); + } + this.indices = indices; + this.policy = policy; + } + + @Override + public SetIndexLifecyclePolicyRequest indices(String... indices) { + this.indices = indices; + return this; + } + + @Override + public String[] indices() { + return indices; + } + + public SetIndexLifecyclePolicyRequest policy(String policy) { + this.policy = policy; + return this; + } + + public String policy() { + return policy; + } + + public void indicesOptions(IndicesOptions indicesOptions) { + this.indicesOptions = indicesOptions; + } + + public IndicesOptions indicesOptions() { + return indicesOptions; + } + + @Override + public ActionRequestValidationException validate() { + return null; + } + + @Override + public void readFrom(StreamInput in) throws IOException { + super.readFrom(in); + indices = in.readStringArray(); + indicesOptions = IndicesOptions.readIndicesOptions(in); + policy = in.readString(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + out.writeStringArray(indices); + indicesOptions.writeIndicesOptions(out); + out.writeString(policy); + } + + @Override + public int hashCode() { + return Objects.hash(Arrays.hashCode(indices), indicesOptions, policy); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + SetIndexLifecyclePolicyRequest other = (SetIndexLifecyclePolicyRequest) obj; + return Objects.deepEquals(indices, other.indices) && + Objects.equals(indicesOptions, other.indicesOptions) && + Objects.equals(policy, other.policy); + } + +} diff --git a/x-pack/protocol/src/main/java/org/elasticsearch/protocol/xpack/indexlifecycle/SetIndexLifecyclePolicyResponse.java b/x-pack/protocol/src/main/java/org/elasticsearch/protocol/xpack/indexlifecycle/SetIndexLifecyclePolicyResponse.java new file mode 100644 index 00000000000..c1c2b5c7da7 --- /dev/null +++ b/x-pack/protocol/src/main/java/org/elasticsearch/protocol/xpack/indexlifecycle/SetIndexLifecyclePolicyResponse.java @@ -0,0 +1,111 @@ +/* + * 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.protocol.xpack.indexlifecycle; + +import org.elasticsearch.action.ActionResponse; +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.xcontent.ConstructingObjectParser; +import org.elasticsearch.common.xcontent.ToXContentObject; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentParser; + +import java.io.IOException; +import java.util.List; +import java.util.Objects; + +public class SetIndexLifecyclePolicyResponse extends ActionResponse implements ToXContentObject { + + public static final ParseField HAS_FAILURES_FIELD = new ParseField("has_failures"); + public static final ParseField FAILED_INDEXES_FIELD = new ParseField("failed_indexes"); + @SuppressWarnings("unchecked") + public static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>( + "change_policy_for_index_response", a -> new SetIndexLifecyclePolicyResponse((List) a[0])); + static { + PARSER.declareStringArray(ConstructingObjectParser.constructorArg(), FAILED_INDEXES_FIELD); + // Needs to be declared but not used in constructing the response object + PARSER.declareBoolean(ConstructingObjectParser.constructorArg(), HAS_FAILURES_FIELD); + } + + private List failedIndexes; + + public SetIndexLifecyclePolicyResponse() { + } + + public SetIndexLifecyclePolicyResponse(List failedIndexes) { + if (failedIndexes == null) { + throw new IllegalArgumentException(FAILED_INDEXES_FIELD.getPreferredName() + " cannot be null"); + } + this.failedIndexes = failedIndexes; + } + + public List getFailedIndexes() { + return failedIndexes; + } + + public boolean hasFailures() { + return failedIndexes.isEmpty() == false; + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field(HAS_FAILURES_FIELD.getPreferredName(), hasFailures()); + builder.field(FAILED_INDEXES_FIELD.getPreferredName(), failedIndexes); + builder.endObject(); + return builder; + } + + public static SetIndexLifecyclePolicyResponse fromXContent(XContentParser parser) { + return PARSER.apply(parser, null); + } + + @Override + public void readFrom(StreamInput in) throws IOException { + super.readFrom(in); + failedIndexes = in.readList(StreamInput::readString); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + out.writeStringList(failedIndexes); + } + + @Override + public int hashCode() { + return Objects.hash(failedIndexes); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + SetIndexLifecyclePolicyResponse other = (SetIndexLifecyclePolicyResponse) obj; + return Objects.equals(failedIndexes, other.failedIndexes); + } + +} + diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/action/SetPolicyForIndexRequestTests.java b/x-pack/protocol/src/test/java/org/elasticsearch/protocol/xpack/indexlifecycle/SetIndexLifecyclePolicyRequestTests.java similarity index 52% rename from x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/action/SetPolicyForIndexRequestTests.java rename to x-pack/protocol/src/test/java/org/elasticsearch/protocol/xpack/indexlifecycle/SetIndexLifecyclePolicyRequestTests.java index e7c93f60717..fd1b7068a06 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/action/SetPolicyForIndexRequestTests.java +++ b/x-pack/protocol/src/test/java/org/elasticsearch/protocol/xpack/indexlifecycle/SetIndexLifecyclePolicyRequestTests.java @@ -1,23 +1,36 @@ /* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. + * 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.xpack.core.indexlifecycle.action; +package org.elasticsearch.protocol.xpack.indexlifecycle; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.test.AbstractStreamableTestCase; -import org.elasticsearch.xpack.core.indexlifecycle.action.SetPolicyForIndexAction.Request; import java.io.IOException; import java.util.Arrays; -public class SetPolicyForIndexRequestTests extends AbstractStreamableTestCase { +public class SetIndexLifecyclePolicyRequestTests extends AbstractStreamableTestCase { @Override - protected Request createTestInstance() { - Request request = new Request(randomAlphaOfLength(20), generateRandomStringArray(20, 20, false)); + protected SetIndexLifecyclePolicyRequest createTestInstance() { + SetIndexLifecyclePolicyRequest request = new SetIndexLifecyclePolicyRequest(randomAlphaOfLength(20), + generateRandomStringArray(20, 20, false)); if (randomBoolean()) { IndicesOptions indicesOptions = IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean()); @@ -27,12 +40,12 @@ public class SetPolicyForIndexRequestTests extends AbstractStreamableTestCase new Request(randomAlphaOfLength(20), (String[]) null)); + () -> new SetIndexLifecyclePolicyRequest(randomAlphaOfLength(20), (String[]) null)); assertEquals("indices cannot be null", exception.getMessage()); } public void testNullPolicy() { IllegalArgumentException exception = expectThrows(IllegalArgumentException.class, - () -> new Request(null, generateRandomStringArray(20, 20, false))); + () -> new SetIndexLifecyclePolicyRequest(null, generateRandomStringArray(20, 20, false))); assertEquals("policy cannot be null", exception.getMessage()); } public void testValidate() { - Request request = createTestInstance(); + SetIndexLifecyclePolicyRequest request = createTestInstance(); assertNull(request.validate()); } } diff --git a/x-pack/protocol/src/test/java/org/elasticsearch/protocol/xpack/indexlifecycle/SetIndexLifecyclePolicyResponseTests.java b/x-pack/protocol/src/test/java/org/elasticsearch/protocol/xpack/indexlifecycle/SetIndexLifecyclePolicyResponseTests.java new file mode 100644 index 00000000000..9216d50b1ae --- /dev/null +++ b/x-pack/protocol/src/test/java/org/elasticsearch/protocol/xpack/indexlifecycle/SetIndexLifecyclePolicyResponseTests.java @@ -0,0 +1,81 @@ +/* + * 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.protocol.xpack.indexlifecycle; + +import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.test.AbstractStreamableXContentTestCase; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class SetIndexLifecyclePolicyResponseTests extends AbstractStreamableXContentTestCase { + + @Override + protected SetIndexLifecyclePolicyResponse createBlankInstance() { + return new SetIndexLifecyclePolicyResponse(); + } + + @Override + protected SetIndexLifecyclePolicyResponse createTestInstance() { + List failedIndexes = Arrays.asList(generateRandomStringArray(20, 20, false)); + return new SetIndexLifecyclePolicyResponse(failedIndexes); + } + + @Override + protected SetIndexLifecyclePolicyResponse mutateInstance(SetIndexLifecyclePolicyResponse instance) throws IOException { + List failedIndices = randomValueOtherThan(instance.getFailedIndexes(), + () -> Arrays.asList(generateRandomStringArray(20, 20, false))); + return new SetIndexLifecyclePolicyResponse(failedIndices); + } + + @Override + protected SetIndexLifecyclePolicyResponse doParseInstance(XContentParser parser) throws IOException { + return SetIndexLifecyclePolicyResponse.PARSER.apply(parser, null); + } + + @Override + protected boolean supportsUnknownFields() { + return false; + } + + public void testNullFailedIndices() { + IllegalArgumentException exception = expectThrows(IllegalArgumentException.class, () -> new SetIndexLifecyclePolicyResponse(null)); + assertEquals("failed_indexes cannot be null", exception.getMessage()); + } + + public void testHasFailures() { + SetIndexLifecyclePolicyResponse response = new SetIndexLifecyclePolicyResponse(new ArrayList<>()); + assertFalse(response.hasFailures()); + assertEquals(Collections.emptyList(), response.getFailedIndexes()); + + int size = randomIntBetween(1, 10); + List failedIndexes = new ArrayList<>(size); + for (int i = 0; i < size; i++) { + failedIndexes.add(randomAlphaOfLength(20)); + } + response = new SetIndexLifecyclePolicyResponse(failedIndexes); + assertTrue(response.hasFailures()); + assertEquals(failedIndexes, response.getFailedIndexes()); + } + +}