Skip to content

Commit 7f4fcec

Browse files
committed
simpler solution and improvements
1 parent 1826916 commit 7f4fcec

File tree

3 files changed

+24
-24
lines changed

3 files changed

+24
-24
lines changed

server/src/main/java/org/elasticsearch/cluster/metadata/LifecycleExecutionState.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -291,12 +291,19 @@ public static String potentiallyTruncateLongJsonWithExplanation(String json) {
291291
if (json == null) {
292292
return null;
293293
}
294-
// Avoid no-op truncations: we must append `"}` (2 chars) to the end to keep JSON valid
295-
if (json.length() <= MAXIMUM_STEP_INFO_STRING_LENGTH + 2) {
294+
if (json.length() <= MAXIMUM_STEP_INFO_STRING_LENGTH) {
296295
return json;
297296
}
298-
final int actuallyRemovedCharacters = json.length() - MAXIMUM_STEP_INFO_STRING_LENGTH - 2;
299-
return Strings.cleanTruncate(json, MAXIMUM_STEP_INFO_STRING_LENGTH) + "... (" + actuallyRemovedCharacters + " chars truncated)\"}";
297+
assert json.startsWith("{\"") && json.endsWith("\"}") : "expected more specific JSON format";
298+
// we'll now do our best to truncate the JSON and have the result be valid JSON.
299+
// a long input JSON should generally only be possible with an exception turned into JSON that's well-formatted.
300+
// if we fail to produce valid JSON, we might return invalid JSON in REST API in niche cases, so this isn't catastrophic.
301+
final int removedChars = json.length() - MAXIMUM_STEP_INFO_STRING_LENGTH;
302+
// -2 to truncate characters within the JSON (before `"}`, which we add back in, so wouldn't actually be truncating anything),
303+
// and to avoid invalid JSON if we truncate one character (result would be `"... (1 chars truncated)"}`,
304+
// this adds a dangling double-quote).
305+
// we don't aim to arrive at a string of exactly MAXIMUM_STEP_INFO_STRING_LENGTH, that's just the condition to apply truncation.
306+
return Strings.cleanTruncate(json, MAXIMUM_STEP_INFO_STRING_LENGTH - 2) + "... (" + removedChars + " chars truncated)\"}";
300307
}
301308

302309
public static class Builder {

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

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,15 @@ public void testTruncatingStepInfo() {
2929
Map<String, String> custom = createCustomMetadata();
3030
LifecycleExecutionState state = LifecycleExecutionState.fromCustomMetadata(custom);
3131
assertThat(custom.get("step_info"), equalTo(state.stepInfo()));
32-
String longStepInfo = randomAlphanumericOfLength(LifecycleExecutionState.MAXIMUM_STEP_INFO_STRING_LENGTH + 100);
32+
String longStepInfo = "{\"key\": \""
33+
+ randomAlphanumericOfLength(LifecycleExecutionState.MAXIMUM_STEP_INFO_STRING_LENGTH + 100)
34+
+ "\"}";
3335
LifecycleExecutionState newState = LifecycleExecutionState.builder(state).setStepInfo(longStepInfo).build();
3436
// Length includes the post suffix (`... (X chars truncated)`)
35-
assertThat(newState.stepInfo().length(), equalTo(LifecycleExecutionState.MAXIMUM_STEP_INFO_STRING_LENGTH + 26));
37+
assertThat(newState.stepInfo().length(), equalTo(LifecycleExecutionState.MAXIMUM_STEP_INFO_STRING_LENGTH + 25));
3638
assertThat(
37-
newState.stepInfo().substring(LifecycleExecutionState.MAXIMUM_STEP_INFO_STRING_LENGTH, 1050),
38-
equalTo("... (98 chars truncated)\"}")
39+
newState.stepInfo().substring(LifecycleExecutionState.MAXIMUM_STEP_INFO_STRING_LENGTH - 2, 1049),
40+
equalTo("... (111 chars truncated)\"}")
3941
);
4042
}
4143

@@ -147,19 +149,14 @@ public void testGetCurrentStepKey() {
147149
}
148150

149151
public void testPotentiallyTruncateLongJsonWithExplanationNotTruncated() {
150-
// +2 because with the JSON ending in `"}`, we'll add it back anyway so it's a NOP
151-
final String input = randomAlphaOfLengthBetween(0, LifecycleExecutionState.MAXIMUM_STEP_INFO_STRING_LENGTH + 2);
152+
final String input = randomAlphaOfLengthBetween(0, LifecycleExecutionState.MAXIMUM_STEP_INFO_STRING_LENGTH);
152153
assertSame(input, LifecycleExecutionState.potentiallyTruncateLongJsonWithExplanation(input));
153154
}
154155

155156
public void testPotentiallyTruncateLongJsonWithExplanationOneCharTruncated() {
156157
final String jsonBaseFormat = "{\"key\": \"%s\"}";
157158
final int baseLength = Strings.format(jsonBaseFormat, "").length();
158-
final String value = randomAlphanumericOfLength(
159-
// +3 because +1 and +2 are no-ops, they will truncate the end of JSON `"}` and then add it back,
160-
// so we need another char to truncate.
161-
LifecycleExecutionState.MAXIMUM_STEP_INFO_STRING_LENGTH - baseLength + 3
162-
);
159+
final String value = randomAlphanumericOfLength(LifecycleExecutionState.MAXIMUM_STEP_INFO_STRING_LENGTH - baseLength + 1);
163160
final String input = Strings.format(jsonBaseFormat, value);
164161
final String expectedOutput = Strings.format(jsonBaseFormat, value.substring(0, value.length() - 1) + "... (1 chars truncated)");
165162
assertEquals(expectedOutput, LifecycleExecutionState.potentiallyTruncateLongJsonWithExplanation(input));
@@ -168,11 +165,7 @@ public void testPotentiallyTruncateLongJsonWithExplanationOneCharTruncated() {
168165
public void testPotentiallyTruncateLongJsonWithExplanationTwoCharsTruncated() {
169166
final String jsonBaseFormat = "{\"key\": \"%s\"}";
170167
final int baseLength = Strings.format(jsonBaseFormat, "").length();
171-
final String value = randomAlphanumericOfLength(
172-
// +4 because +1 and +2 are no-ops, they will truncate the end of JSON `"}` and then add it back,
173-
// so we need another two chars to truncate.
174-
LifecycleExecutionState.MAXIMUM_STEP_INFO_STRING_LENGTH - baseLength + 4
175-
);
168+
final String value = randomAlphanumericOfLength(LifecycleExecutionState.MAXIMUM_STEP_INFO_STRING_LENGTH - baseLength + 2);
176169
final String input = Strings.format(jsonBaseFormat, value);
177170
final String expectedOutput = Strings.format(jsonBaseFormat, value.substring(0, value.length() - 2) + "... (2 chars truncated)");
178171
assertEquals(expectedOutput, LifecycleExecutionState.potentiallyTruncateLongJsonWithExplanation(input));

x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/action/TransportExplainLifecycleActionTests.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -292,14 +292,14 @@ public void testPreviousStepInfoTruncationDoesNotBreakExplainJson() throws Excep
292292

293293
final String expectedPreviousStepInfoFormat = """
294294
{"type":"illegal_argument_exception","reason":"%s"}""";
295-
final int jsonCharsBeforeReasonValue = Strings.format(expectedPreviousStepInfoFormat, "").length() - 2; // -2 for `"}`
295+
final int jsonBaseLength = Strings.format(expectedPreviousStepInfoFormat, "").length();
296296
final String expectedReason = Strings.format(
297297
"%s... (%d chars truncated)",
298-
"a".repeat(LifecycleExecutionState.MAXIMUM_STEP_INFO_STRING_LENGTH - jsonCharsBeforeReasonValue),
299-
jsonCharsBeforeReasonValue
298+
"a".repeat(LifecycleExecutionState.MAXIMUM_STEP_INFO_STRING_LENGTH - jsonBaseLength),
299+
jsonBaseLength
300300
);
301301
final String expectedPreviousStepInfo = Strings.format(expectedPreviousStepInfoFormat, expectedReason);
302-
assertThat(actualPreviousStepInfo, equalTo(expectedPreviousStepInfo));
302+
assertEquals(actualPreviousStepInfo, expectedPreviousStepInfo);
303303
}
304304
}
305305

0 commit comments

Comments
 (0)