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
index 3f4845a12eb84..b4517574059e8 100644
--- 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
@@ -29,6 +29,7 @@
import org.elasticsearch.client.indexlifecycle.PutLifecyclePolicyRequest;
import org.elasticsearch.client.indexlifecycle.ExplainLifecycleRequest;
import org.elasticsearch.client.indexlifecycle.ExplainLifecycleResponse;
+import org.elasticsearch.client.indexlifecycle.RetryLifecyclePolicyRequest;
import org.elasticsearch.client.indexlifecycle.RemoveIndexLifecyclePolicyRequest;
import org.elasticsearch.client.indexlifecycle.RemoveIndexLifecyclePolicyResponse;
import org.elasticsearch.client.indexlifecycle.SetIndexLifecyclePolicyRequest;
@@ -302,4 +303,32 @@ public void explainLifecycleAsync(ExplainLifecycleRequest request, RequestOption
restHighLevelClient.performRequestAsyncAndParseEntity(request, RequestConverters::explainLifecycle, options,
ExplainLifecycleResponse::fromXContent, listener, emptySet());
}
+
+ /**
+ * Retry lifecycle step for given indices
+ * 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 AcknowledgedResponse retryLifecycleStep(RetryLifecyclePolicyRequest request, RequestOptions options) throws IOException {
+ return restHighLevelClient.performRequestAndParseEntity(request, RequestConverters::retryLifecycle, options,
+ AcknowledgedResponse::fromXContent, emptySet());
+ }
+
+ /**
+ * Asynchronously retry the lifecycle step for given indices
+ * 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 retryLifecycleStepAsync(RetryLifecyclePolicyRequest request, RequestOptions options,
+ ActionListener listener) {
+ restHighLevelClient.performRequestAsyncAndParseEntity(request, RequestConverters::retryLifecycle, options,
+ AcknowledgedResponse::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 acb3e6d02bcb1..eb6f722ba369c 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
@@ -19,6 +19,7 @@
package org.elasticsearch.client;
+import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
@@ -54,6 +55,7 @@
import org.elasticsearch.client.indexlifecycle.GetLifecyclePolicyRequest;
import org.elasticsearch.client.indexlifecycle.LifecycleManagementStatusRequest;
import org.elasticsearch.client.indexlifecycle.PutLifecyclePolicyRequest;
+import org.elasticsearch.client.indexlifecycle.RetryLifecyclePolicyRequest;
import org.elasticsearch.client.indexlifecycle.RemoveIndexLifecyclePolicyRequest;
import org.elasticsearch.client.indexlifecycle.SetIndexLifecyclePolicyRequest;
import org.elasticsearch.client.indexlifecycle.StartILMRequest;
@@ -717,6 +719,19 @@ static Request explainLifecycle(ExplainLifecycleRequest explainLifecycleRequest)
return request;
}
+ static Request retryLifecycle(RetryLifecyclePolicyRequest retryLifecyclePolicyRequest) {
+ Request request = new Request(HttpPost.METHOD_NAME,
+ new EndpointBuilder()
+ .addCommaSeparatedPathParts(retryLifecyclePolicyRequest.getIndices())
+ .addPathPartAsIs("_ilm")
+ .addPathPartAsIs("retry")
+ .build());
+ Params params = new Params(request);
+ params.withMasterTimeout(retryLifecyclePolicyRequest.masterNodeTimeout());
+ params.withTimeout(retryLifecyclePolicyRequest.timeout());
+ return request;
+ }
+
static HttpEntity createEntity(ToXContent toXContent, XContentType xContentType) throws IOException {
BytesRef source = XContentHelper.toXContent(toXContent, xContentType, false).toBytesRef();
return new ByteArrayEntity(source.bytes, source.offset, source.length, createContentType(xContentType));
@@ -1102,7 +1117,12 @@ EndpointBuilder addCommaSeparatedPathParts(String[] parts) {
return this;
}
- EndpointBuilder addPathPartAsIs(String... parts) {
+ EndpointBuilder addCommaSeparatedPathParts(List parts) {
+ addPathPart(String.join(",", parts));
+ return this;
+ }
+
+ EndpointBuilder addPathPartAsIs(String ... parts) {
for (String part : parts) {
if (Strings.hasLength(part)) {
joiner.add(part);
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/indexlifecycle/RetryLifecyclePolicyRequest.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/indexlifecycle/RetryLifecyclePolicyRequest.java
new file mode 100644
index 0000000000000..6f3acaf19aaea
--- /dev/null
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/indexlifecycle/RetryLifecyclePolicyRequest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.indexlifecycle;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import org.elasticsearch.client.TimedRequest;
+
+public class RetryLifecyclePolicyRequest extends TimedRequest {
+
+ private final List indices;
+
+ public RetryLifecyclePolicyRequest(String... indices) {
+ if (indices.length == 0) {
+ throw new IllegalArgumentException("Must at least specify one index to retry");
+ }
+ this.indices = Arrays.asList(indices);
+ }
+
+ public List getIndices() {
+ return indices;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ RetryLifecyclePolicyRequest that = (RetryLifecyclePolicyRequest) o;
+ return indices.size() == that.indices.size() && indices.containsAll(that.indices);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(indices);
+ }
+}
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
index 9d76c19adf74c..8f440539f52e2 100644
--- 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
@@ -41,6 +41,7 @@
import org.elasticsearch.client.indexlifecycle.Phase;
import org.elasticsearch.client.indexlifecycle.PhaseExecutionInfo;
import org.elasticsearch.client.indexlifecycle.PutLifecyclePolicyRequest;
+import org.elasticsearch.client.indexlifecycle.RetryLifecyclePolicyRequest;
import org.elasticsearch.client.indexlifecycle.RemoveIndexLifecyclePolicyRequest;
import org.elasticsearch.client.indexlifecycle.RemoveIndexLifecyclePolicyResponse;
import org.elasticsearch.client.indexlifecycle.RolloverAction;
@@ -288,4 +289,26 @@ public void testGetMultipleLifecyclePolicies() throws IOException {
.map(p -> ((LifecyclePolicyMetadata) p).getPolicy()).collect(Collectors.toList());
assertThat(retrievedPolicies, hasItems(policies));
}
+
+ public void testRetryLifecycleStep() throws IOException {
+ String policyName = randomAlphaOfLength(10);
+ LifecyclePolicy policy = createRandomPolicy(policyName);
+ PutLifecyclePolicyRequest putRequest = new PutLifecyclePolicyRequest(policy);
+ assertAcked(execute(putRequest, highLevelClient().indexLifecycle()::putLifecyclePolicy,
+ highLevelClient().indexLifecycle()::putLifecyclePolicyAsync));
+ createIndex("retry", Settings.builder().put("index.lifecycle.name", policy.getName()).build());
+ RetryLifecyclePolicyRequest retryRequest = new RetryLifecyclePolicyRequest("retry");
+ ElasticsearchStatusException ex = expectThrows(ElasticsearchStatusException.class,
+ () -> execute(
+ retryRequest, highLevelClient().indexLifecycle()::retryLifecycleStep,
+ highLevelClient().indexLifecycle()::retryLifecycleStepAsync
+ )
+ );
+ assertEquals(400, ex.status().getStatus());
+ assertEquals(
+ "Elasticsearch exception [type=illegal_argument_exception, reason=cannot retry an action for an index [retry]" +
+ " that has not encountered an error when running a Lifecycle Policy]",
+ ex.getRootCause().getMessage()
+ );
+ }
}
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 2f81ced664ba1..eb07c1b4cc160 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
@@ -60,6 +60,7 @@
import org.elasticsearch.client.indexlifecycle.LifecyclePolicy;
import org.elasticsearch.client.indexlifecycle.PutLifecyclePolicyRequest;
import org.elasticsearch.client.indexlifecycle.DeleteLifecyclePolicyRequest;
+import org.elasticsearch.client.indexlifecycle.RetryLifecyclePolicyRequest;
import org.elasticsearch.client.indexlifecycle.RemoveIndexLifecyclePolicyRequest;
import org.elasticsearch.common.CheckedBiConsumer;
import org.elasticsearch.common.Strings;
@@ -1593,6 +1594,19 @@ public void testExplainLifecycle() throws Exception {
assertThat(request.getParameters(), equalTo(expectedParams));
}
+ public void testRetryLifecycle() throws Exception {
+ String[] indices = randomIndicesNames(1, 10);
+ RetryLifecyclePolicyRequest req = new RetryLifecyclePolicyRequest(indices);
+ Map expectedParams = new HashMap<>();
+ setRandomMasterTimeout(req::setMasterTimeout, TimedRequest.DEFAULT_MASTER_NODE_TIMEOUT, expectedParams);
+ setRandomTimeoutTimeValue(req::setTimeout, TimedRequest.DEFAULT_ACK_TIMEOUT, expectedParams);
+ Request request = RequestConverters.retryLifecycle(req);
+ assertThat(request.getMethod(), equalTo(HttpPost.METHOD_NAME));
+ String idxString = Strings.arrayToCommaDelimitedString(indices);
+ assertThat(request.getEndpoint(), equalTo("/" + (idxString.isEmpty() ? "" : (idxString + "/")) + "_ilm/retry"));
+ assertThat(request.getParameters(), equalTo(expectedParams));
+ }
+
/**
* Randomize the {@link FetchSourceContext} request parameters.
*/