Skip to content

Commit 928ea95

Browse files
gmjehovichjoegallo
authored andcommitted
Add age_in_millis to ILM Explain Response (elastic#128866)
* Add age_in_millis to ILM Explain Response * Fix: Declare age_in_millis in ILM Explain Response Parser * Add unit tests for age_in_millis field in IndexLifecycleExplainResponse * Update docs/changelog/128866.yaml * Update docs/changelog/128866.yaml * Update IndexLifecycleExplainResponse.java Fix comments; follow DRY for getAge(nowSupplier) call in IndexLifecycleExplainResponse --------- Co-authored-by: Joe Gallo <[email protected]>
1 parent f3289ce commit 928ea95

File tree

4 files changed

+62
-2
lines changed

4 files changed

+62
-2
lines changed

docs/changelog/128866.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 128866
2+
summary: Add `age_in_millis` to ILM Explain Response
3+
area: ILM+SLM
4+
type: enhancement
5+
issues:
6+
- 103659

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/IndexLifecycleExplainResponse.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public class IndexLifecycleExplainResponse implements ToXContentObject, Writeabl
5151
private static final ParseField PREVIOUS_STEP_INFO_FIELD = new ParseField("previous_step_info");
5252
private static final ParseField PHASE_EXECUTION_INFO = new ParseField("phase_execution");
5353
private static final ParseField AGE_FIELD = new ParseField("age");
54+
private static final ParseField AGE_IN_MILLIS_FIELD = new ParseField("age_in_millis");
5455
private static final ParseField TIME_SINCE_INDEX_CREATION_FIELD = new ParseField("time_since_index_creation");
5556
private static final ParseField REPOSITORY_NAME = new ParseField("repository_name");
5657
private static final ParseField SHRINK_INDEX_NAME = new ParseField("shrink_index_name");
@@ -83,6 +84,7 @@ public class IndexLifecycleExplainResponse implements ToXContentObject, Writeabl
8384
Objects.requireNonNullElse((Boolean) a[22], false)
8485
// a[13] == "age"
8586
// a[20] == "time_since_index_creation"
87+
// a[23] = "age_in_millis"
8688
)
8789
);
8890
static {
@@ -121,6 +123,7 @@ public class IndexLifecycleExplainResponse implements ToXContentObject, Writeabl
121123
return BytesReference.bytes(builder);
122124
}, PREVIOUS_STEP_INFO_FIELD);
123125
PARSER.declareBoolean(ConstructingObjectParser.optionalConstructorArg(), SKIP_NAME);
126+
PARSER.declareLong(ConstructingObjectParser.optionalConstructorArg(), AGE_IN_MILLIS_FIELD);
124127
}
125128

126129
private final String index;
@@ -529,7 +532,10 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
529532
LIFECYCLE_DATE_FIELD.getPreferredName(),
530533
lifecycleDate
531534
);
532-
builder.field(AGE_FIELD.getPreferredName(), getAge(nowSupplier).toHumanReadableString(2));
535+
536+
final TimeValue ageNow = getAge(nowSupplier);
537+
builder.field(AGE_FIELD.getPreferredName(), ageNow.toHumanReadableString(2));
538+
builder.field(AGE_IN_MILLIS_FIELD.getPreferredName(), ageNow.getMillis());
533539
}
534540
if (phase != null) {
535541
builder.field(PHASE_FIELD.getPreferredName(), phase);

x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ilm/IndexLifecycleExplainResponseTests.java

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,20 @@
2020
import org.elasticsearch.xcontent.ParseField;
2121
import org.elasticsearch.xcontent.ToXContentObject;
2222
import org.elasticsearch.xcontent.XContentBuilder;
23+
import org.elasticsearch.xcontent.XContentFactory;
2324
import org.elasticsearch.xcontent.XContentParser;
2425

2526
import java.io.IOException;
2627
import java.util.List;
28+
import java.util.Map;
2729
import java.util.Objects;
2830
import java.util.function.Supplier;
2931

3032
import static org.hamcrest.Matchers.containsString;
3133
import static org.hamcrest.Matchers.equalTo;
34+
import static org.hamcrest.Matchers.hasKey;
3235
import static org.hamcrest.Matchers.is;
36+
import static org.hamcrest.Matchers.not;
3337
import static org.hamcrest.Matchers.notNullValue;
3438
import static org.hamcrest.Matchers.nullValue;
3539
import static org.hamcrest.Matchers.startsWith;
@@ -110,14 +114,16 @@ public void testInvalidStepDetails() {
110114
assertThat(exception.getMessage(), containsString("=null"));
111115
}
112116

113-
public void testIndexAges() {
117+
public void testIndexAges() throws IOException {
114118
IndexLifecycleExplainResponse unmanagedExplainResponse = randomUnmanagedIndexExplainResponse();
115119
assertThat(unmanagedExplainResponse.getLifecycleDate(), is(nullValue()));
116120
assertThat(unmanagedExplainResponse.getAge(System::currentTimeMillis), is(TimeValue.MINUS_ONE));
117121

118122
assertThat(unmanagedExplainResponse.getIndexCreationDate(), is(nullValue()));
119123
assertThat(unmanagedExplainResponse.getTimeSinceIndexCreation(System::currentTimeMillis), is(nullValue()));
120124

125+
assertAgeInMillisXContentAbsentForUnmanagedResponse(unmanagedExplainResponse);
126+
121127
IndexLifecycleExplainResponse managedExplainResponse = IndexLifecycleExplainResponse.newManagedIndexResponse(
122128
"indexName",
123129
12345L,
@@ -155,6 +161,46 @@ public void testIndexAges() {
155161
is(equalTo(TimeValue.timeValueMillis(now - managedExplainResponse.getIndexCreationDate())))
156162
);
157163
assertThat(managedExplainResponse.getTimeSinceIndexCreation(() -> 0L), is(equalTo(TimeValue.ZERO)));
164+
165+
long expectedAgeInMillisForThisCase = Math.max(0L, now - managedExplainResponse.getLifecycleDate());
166+
assertAgeInMillisXContent(managedExplainResponse, expectedAgeInMillisForThisCase, now);
167+
}
168+
169+
protected void assertAgeInMillisXContent(
170+
final IndexLifecycleExplainResponse managedExplainResponse,
171+
final long expectedAgeInMillis,
172+
final long now
173+
) throws IOException {
174+
XContentBuilder builder = XContentFactory.jsonBuilder();
175+
managedExplainResponse.nowSupplier = () -> now;
176+
try (builder) {
177+
managedExplainResponse.toXContent(builder, ToXContentObject.EMPTY_PARAMS);
178+
}
179+
final String json = Strings.toString(builder);
180+
181+
try (XContentParser parser = createParser(builder.contentType().xContent(), json)) {
182+
Map<String, Object> parsedMap = parser.map();
183+
184+
assertThat(parsedMap, hasKey("age_in_millis"));
185+
final long actualParsedAgeInMillis = ((Number) parsedMap.get("age_in_millis")).longValue();
186+
assertThat(actualParsedAgeInMillis, equalTo((Number) expectedAgeInMillis));
187+
}
188+
}
189+
190+
protected void assertAgeInMillisXContentAbsentForUnmanagedResponse(final IndexLifecycleExplainResponse unmanagedExplainResponse)
191+
throws IOException {
192+
XContentBuilder builder = XContentFactory.jsonBuilder();
193+
try (builder) {
194+
unmanagedExplainResponse.toXContent(builder, ToXContentObject.EMPTY_PARAMS);
195+
}
196+
final String json = Strings.toString(builder);
197+
198+
try (XContentParser parser = createParser(builder.contentType().xContent(), json)) {
199+
Map<String, Object> parsedMap = parser.map();
200+
201+
assertThat(parsedMap, not(hasKey("age_in_millis")));
202+
}
203+
158204
}
159205

160206
@Override

x-pack/plugin/ilm/qa/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/ilm/ExplainLifecycleIT.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ public void testExplainIndicesWildcard() throws Exception {
207207
assertThat(explainIndexWithMissingPolicy.get("action"), is(nullValue()));
208208
assertThat(explainIndexWithMissingPolicy.get("step"), is(ErrorStep.NAME));
209209
assertThat(explainIndexWithMissingPolicy.get("age"), is(nullValue()));
210+
assertThat(explainIndexWithMissingPolicy.get("age_in_millis"), is(nullValue()));
210211
assertThat(explainIndexWithMissingPolicy.get("failed_step"), is(nullValue()));
211212
Map<String, Object> stepInfo = (Map<String, Object>) explainIndexWithMissingPolicy.get("step_info");
212213
assertThat(stepInfo, is(notNullValue()));
@@ -343,6 +344,7 @@ private void assertManagedIndex(Map<String, Object> explainIndexMap) {
343344
assertThat(explainIndexMap.get("step"), is("complete"));
344345
assertThat(explainIndexMap.get("phase_time_millis"), is(notNullValue()));
345346
assertThat(explainIndexMap.get("age"), is(notNullValue()));
347+
assertThat(explainIndexMap.get("age_in_millis"), is(notNullValue()));
346348
assertThat(explainIndexMap.get("phase_execution"), is(notNullValue()));
347349
assertThat(explainIndexMap.get("failed_step"), is(nullValue()));
348350
assertThat(explainIndexMap.get("step_info"), is(nullValue()));

0 commit comments

Comments
 (0)