Skip to content

Commit 88c7b39

Browse files
original-brownbeargwbrown
authored andcommitted
HLRC: Add ILM Retry (#33990)
* HLRC: Add ILM Retry * Relates #33100
1 parent f93b9f4 commit 88c7b39

File tree

5 files changed

+146
-1
lines changed

5 files changed

+146
-1
lines changed

client/rest-high-level/src/main/java/org/elasticsearch/client/IndexLifecycleClient.java

+29
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.elasticsearch.client.indexlifecycle.LifecycleManagementStatusRequest;
3030
import org.elasticsearch.client.indexlifecycle.LifecycleManagementStatusResponse;
3131
import org.elasticsearch.client.indexlifecycle.PutLifecyclePolicyRequest;
32+
import org.elasticsearch.client.indexlifecycle.RetryLifecyclePolicyRequest;
3233
import org.elasticsearch.client.indexlifecycle.RemoveIndexLifecyclePolicyRequest;
3334
import org.elasticsearch.client.indexlifecycle.RemoveIndexLifecyclePolicyResponse;
3435
import org.elasticsearch.client.indexlifecycle.StartILMRequest;
@@ -271,4 +272,32 @@ public void explainLifecycleAsync(ExplainLifecycleRequest request, RequestOption
271272
restHighLevelClient.performRequestAsyncAndParseEntity(request, RequestConverters::explainLifecycle, options,
272273
ExplainLifecycleResponse::fromXContent, listener, emptySet());
273274
}
275+
276+
/**
277+
* Retry lifecycle step for given indices
278+
* See <a href="https://fix-me-when-we-have-docs.com">
279+
* the docs</a> for more.
280+
* @param request the request
281+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
282+
* @return the response
283+
* @throws IOException in case there is a problem sending the request or parsing back the response
284+
*/
285+
public AcknowledgedResponse retryLifecycleStep(RetryLifecyclePolicyRequest request, RequestOptions options) throws IOException {
286+
return restHighLevelClient.performRequestAndParseEntity(request, RequestConverters::retryLifecycle, options,
287+
AcknowledgedResponse::fromXContent, emptySet());
288+
}
289+
290+
/**
291+
* Asynchronously retry the lifecycle step for given indices
292+
* See <a href="https://fix-me-when-we-have-docs.com">
293+
* the docs</a> for more.
294+
* @param request the request
295+
* @param options the request options (e.g. headers), use {@link RequestOptions#DEFAULT} if nothing needs to be customized
296+
* @param listener the listener to be notified upon request completion
297+
*/
298+
public void retryLifecycleStepAsync(RetryLifecyclePolicyRequest request, RequestOptions options,
299+
ActionListener<AcknowledgedResponse> listener) {
300+
restHighLevelClient.performRequestAsyncAndParseEntity(request, RequestConverters::retryLifecycle, options,
301+
AcknowledgedResponse::fromXContent, listener, emptySet());
302+
}
274303
}

client/rest-high-level/src/main/java/org/elasticsearch/client/RequestConverters.java

+21-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
package org.elasticsearch.client;
2121

22+
import java.util.List;
2223
import org.apache.http.HttpEntity;
2324
import org.apache.http.client.methods.HttpDelete;
2425
import org.apache.http.client.methods.HttpGet;
@@ -55,6 +56,7 @@
5556
import org.elasticsearch.client.indexlifecycle.GetLifecyclePolicyRequest;
5657
import org.elasticsearch.client.indexlifecycle.LifecycleManagementStatusRequest;
5758
import org.elasticsearch.client.indexlifecycle.PutLifecyclePolicyRequest;
59+
import org.elasticsearch.client.indexlifecycle.RetryLifecyclePolicyRequest;
5860
import org.elasticsearch.client.indexlifecycle.RemoveIndexLifecyclePolicyRequest;
5961
import org.elasticsearch.client.indexlifecycle.StartILMRequest;
6062
import org.elasticsearch.client.indexlifecycle.StopILMRequest;
@@ -746,6 +748,19 @@ static Request explainLifecycle(ExplainLifecycleRequest explainLifecycleRequest)
746748
return request;
747749
}
748750

751+
static Request retryLifecycle(RetryLifecyclePolicyRequest retryLifecyclePolicyRequest) {
752+
Request request = new Request(HttpPost.METHOD_NAME,
753+
new EndpointBuilder()
754+
.addCommaSeparatedPathParts(retryLifecyclePolicyRequest.getIndices())
755+
.addPathPartAsIs("_ilm")
756+
.addPathPartAsIs("retry")
757+
.build());
758+
Params params = new Params(request);
759+
params.withMasterTimeout(retryLifecyclePolicyRequest.masterNodeTimeout());
760+
params.withTimeout(retryLifecyclePolicyRequest.timeout());
761+
return request;
762+
}
763+
749764
static HttpEntity createEntity(ToXContent toXContent, XContentType xContentType) throws IOException {
750765
BytesRef source = XContentHelper.toXContent(toXContent, xContentType, false).toBytesRef();
751766
return new ByteArrayEntity(source.bytes, source.offset, source.length, createContentType(xContentType));
@@ -1138,7 +1153,12 @@ EndpointBuilder addCommaSeparatedPathParts(String[] parts) {
11381153
return this;
11391154
}
11401155

1141-
EndpointBuilder addPathPartAsIs(String... parts) {
1156+
EndpointBuilder addCommaSeparatedPathParts(List<String> parts) {
1157+
addPathPart(String.join(",", parts));
1158+
return this;
1159+
}
1160+
1161+
EndpointBuilder addPathPartAsIs(String ... parts) {
11421162
for (String part : parts) {
11431163
if (Strings.hasLength(part)) {
11441164
joiner.add(part);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.client.indexlifecycle;
21+
22+
import java.util.Arrays;
23+
import java.util.List;
24+
import java.util.Objects;
25+
import org.elasticsearch.client.TimedRequest;
26+
27+
public class RetryLifecyclePolicyRequest extends TimedRequest {
28+
29+
private final List<String> indices;
30+
31+
public RetryLifecyclePolicyRequest(String... indices) {
32+
if (indices.length == 0) {
33+
throw new IllegalArgumentException("Must at least specify one index to retry");
34+
}
35+
this.indices = Arrays.asList(indices);
36+
}
37+
38+
public List<String> getIndices() {
39+
return indices;
40+
}
41+
42+
@Override
43+
public boolean equals(Object o) {
44+
if (this == o) {
45+
return true;
46+
}
47+
if (o == null || getClass() != o.getClass()) {
48+
return false;
49+
}
50+
RetryLifecyclePolicyRequest that = (RetryLifecyclePolicyRequest) o;
51+
return indices.size() == that.indices.size() && indices.containsAll(that.indices);
52+
}
53+
54+
@Override
55+
public int hashCode() {
56+
return Objects.hash(indices);
57+
}
58+
}

client/rest-high-level/src/test/java/org/elasticsearch/client/IndexLifecycleIT.java

+23
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.elasticsearch.client.indexlifecycle.Phase;
4242
import org.elasticsearch.client.indexlifecycle.PhaseExecutionInfo;
4343
import org.elasticsearch.client.indexlifecycle.PutLifecyclePolicyRequest;
44+
import org.elasticsearch.client.indexlifecycle.RetryLifecyclePolicyRequest;
4445
import org.elasticsearch.client.indexlifecycle.RemoveIndexLifecyclePolicyRequest;
4546
import org.elasticsearch.client.indexlifecycle.RemoveIndexLifecyclePolicyResponse;
4647
import org.elasticsearch.client.indexlifecycle.RolloverAction;
@@ -260,4 +261,26 @@ public void testGetMultipleLifecyclePolicies() throws IOException {
260261
.map(p -> ((LifecyclePolicyMetadata) p).getPolicy()).collect(Collectors.toList());
261262
assertThat(retrievedPolicies, hasItems(policies));
262263
}
264+
265+
public void testRetryLifecycleStep() throws IOException {
266+
String policyName = randomAlphaOfLength(10);
267+
LifecyclePolicy policy = createRandomPolicy(policyName);
268+
PutLifecyclePolicyRequest putRequest = new PutLifecyclePolicyRequest(policy);
269+
assertAcked(execute(putRequest, highLevelClient().indexLifecycle()::putLifecyclePolicy,
270+
highLevelClient().indexLifecycle()::putLifecyclePolicyAsync));
271+
createIndex("retry", Settings.builder().put("index.lifecycle.name", policy.getName()).build());
272+
RetryLifecyclePolicyRequest retryRequest = new RetryLifecyclePolicyRequest("retry");
273+
ElasticsearchStatusException ex = expectThrows(ElasticsearchStatusException.class,
274+
() -> execute(
275+
retryRequest, highLevelClient().indexLifecycle()::retryLifecycleStep,
276+
highLevelClient().indexLifecycle()::retryLifecycleStepAsync
277+
)
278+
);
279+
assertEquals(400, ex.status().getStatus());
280+
assertEquals(
281+
"Elasticsearch exception [type=illegal_argument_exception, reason=cannot retry an action for an index [retry]" +
282+
" that has not encountered an error when running a Lifecycle Policy]",
283+
ex.getRootCause().getMessage()
284+
);
285+
}
263286
}

client/rest-high-level/src/test/java/org/elasticsearch/client/RequestConvertersTests.java

+15
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@
6161
import org.elasticsearch.client.indexlifecycle.LifecycleManagementStatusRequest;
6262
import org.elasticsearch.client.indexlifecycle.LifecyclePolicy;
6363
import org.elasticsearch.client.indexlifecycle.PutLifecyclePolicyRequest;
64+
import org.elasticsearch.client.indexlifecycle.DeleteLifecyclePolicyRequest;
65+
import org.elasticsearch.client.indexlifecycle.RetryLifecyclePolicyRequest;
6466
import org.elasticsearch.client.indexlifecycle.RemoveIndexLifecyclePolicyRequest;
6567
import org.elasticsearch.client.indexlifecycle.StartILMRequest;
6668
import org.elasticsearch.client.indexlifecycle.StopILMRequest;
@@ -1648,6 +1650,19 @@ public void testExplainLifecycle() throws Exception {
16481650
assertThat(request.getParameters(), equalTo(expectedParams));
16491651
}
16501652

1653+
public void testRetryLifecycle() throws Exception {
1654+
String[] indices = randomIndicesNames(1, 10);
1655+
RetryLifecyclePolicyRequest req = new RetryLifecyclePolicyRequest(indices);
1656+
Map<String, String> expectedParams = new HashMap<>();
1657+
setRandomMasterTimeout(req::setMasterTimeout, TimedRequest.DEFAULT_MASTER_NODE_TIMEOUT, expectedParams);
1658+
setRandomTimeoutTimeValue(req::setTimeout, TimedRequest.DEFAULT_ACK_TIMEOUT, expectedParams);
1659+
Request request = RequestConverters.retryLifecycle(req);
1660+
assertThat(request.getMethod(), equalTo(HttpPost.METHOD_NAME));
1661+
String idxString = Strings.arrayToCommaDelimitedString(indices);
1662+
assertThat(request.getEndpoint(), equalTo("/" + (idxString.isEmpty() ? "" : (idxString + "/")) + "_ilm/retry"));
1663+
assertThat(request.getParameters(), equalTo(expectedParams));
1664+
}
1665+
16511666
/**
16521667
* Randomize the {@link FetchSourceContext} request parameters.
16531668
*/

0 commit comments

Comments
 (0)