Skip to content

Commit

Permalink
Add descriptions to various tasks (#76700)
Browse files Browse the repository at this point in the history
Adds a more detailed description to get-snapshots, get-shard-snapshot,
snapshots-status and field-capabilities tasks since these may somtimes
be long-running things and it may occasionally be necessary to track
down why they are running and what they're doing.
  • Loading branch information
DaveCTurner committed Aug 20, 2021
1 parent e38df5f commit 03e5c55
Show file tree
Hide file tree
Showing 9 changed files with 258 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Base64;
import java.util.Map;

Expand Down Expand Up @@ -458,4 +459,14 @@ public void writeTo(StreamOutput out) throws IOException {
out.writeString(snapshotName);
}
}

@Override
public String getDescription() {
final StringBuilder stringBuilder = new StringBuilder("repositories[");
Strings.collectionToDelimitedStringWithLimit(Arrays.asList(repositories), ",", "", "", 512, stringBuilder);
stringBuilder.append("], snapshots[");
Strings.collectionToDelimitedStringWithLimit(Arrays.asList(snapshots), ",", "", "", 1024, stringBuilder);
stringBuilder.append("]");
return stringBuilder.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.support.master.MasterNodeRequest;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.index.shard.ShardId;
Expand Down Expand Up @@ -102,4 +103,12 @@ public boolean equals(Object o) {
public int hashCode() {
return Objects.hash(repositories, shardId);
}

@Override
public String getDescription() {
final StringBuilder stringBuilder = new StringBuilder("shard").append(shardId).append(", repositories[");
Strings.collectionToDelimitedStringWithLimit(repositories, ",", "", "", 1024, stringBuilder);
stringBuilder.append("]");
return stringBuilder.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.elasticsearch.tasks.TaskId;

import java.io.IOException;
import java.util.Arrays;
import java.util.Map;

import static org.elasticsearch.action.ValidateActions.addValidationError;
Expand Down Expand Up @@ -146,4 +147,12 @@ public SnapshotsStatusRequest ignoreUnavailable(boolean ignoreUnavailable) {
public boolean ignoreUnavailable() {
return ignoreUnavailable;
}

@Override
public String getDescription() {
final StringBuilder stringBuilder = new StringBuilder("repository[").append(repository).append("], snapshots[");
Strings.collectionToDelimitedStringWithLimit(Arrays.asList(snapshots), ",", "", "", 1024, stringBuilder);
stringBuilder.append("]");
return stringBuilder.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -235,4 +235,15 @@ public int hashCode() {
result = 31 * result + Arrays.hashCode(fields);
return result;
}

@Override
public String getDescription() {
final StringBuilder stringBuilder = new StringBuilder("indices[");
Strings.collectionToDelimitedStringWithLimit(Arrays.asList(indices), ",", "", "", 1024, stringBuilder);
stringBuilder.append("], fields[");
Strings.collectionToDelimitedStringWithLimit(Arrays.asList(fields), ",", "", "", 1024, stringBuilder);
stringBuilder.append("]");
return stringBuilder.toString();
}

}
39 changes: 39 additions & 0 deletions server/src/main/java/org/elasticsearch/common/Strings.java
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,45 @@ public static void collectionToDelimitedString(Iterable<?> coll, String delim, S
}
}

/**
* Converts a collection of items to a string like {@link #collectionToDelimitedString(Iterable, String, String, String, StringBuilder)}
* except that it stops if the string gets too long and just indicates how many items were omitted.
*
* @param coll the collection of items to display
* @param delim the delimiter to write between the items (usually {@code ","})
* @param prefix a string to write before each item (usually {@code ""} or {@code "["})
* @param suffix a string to write after each item (usually {@code ""} or {@code "]"})
* @param appendLimit if this many characters have been appended to the string and there are still items to display then the remaining
* items are omitted
*/
public static void collectionToDelimitedStringWithLimit(
Iterable<?> coll,
String delim,
String prefix,
String suffix,
int appendLimit,
StringBuilder sb
) {
final Iterator<?> it = coll.iterator();
final long lengthLimit = sb.length() + appendLimit; // long to avoid overflow
int count = 0;
while (it.hasNext()) {
sb.append(prefix).append(it.next()).append(suffix);
count += 1;
if (it.hasNext()) {
sb.append(delim);
if (sb.length() > lengthLimit) {
int omitted = 0;
while (it.hasNext()) {
it.next();
omitted += 1;
}
sb.append("... (").append(count + omitted).append(" in total, ").append(omitted).append(" omitted)");
}
}
}
}

/**
* Convenience method to return a Collection as a delimited (e.g. CSV)
* String. E.g. useful for <code>toString()</code> implementations.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.elasticsearch.test.ESTestCase;

import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;

public class GetSnapshotsRequestTests extends ESTestCase {

Expand Down Expand Up @@ -62,4 +63,12 @@ public void testValidateParameters() {
assertThat(e.getMessage(), containsString("can't use after and offset simultaneously"));
}
}

public void testGetDescription() {
final GetSnapshotsRequest request = new GetSnapshotsRequest(
new String[] { "repo1", "repo2" },
new String[] { "snapshotA", "snapshotB" }
);
assertThat(request.getDescription(), equalTo("repositories[repo1,repo2], snapshots[snapshotA,snapshotB]"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,13 @@
import org.elasticsearch.test.AbstractWireSerializingTestCase;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.lessThanOrEqualTo;

public class GetShardSnapshotRequestSerializationTests extends AbstractWireSerializingTestCase<GetShardSnapshotRequest> {
@Override
protected Writeable.Reader<GetShardSnapshotRequest> instanceReader() {
Expand Down Expand Up @@ -46,4 +51,21 @@ protected GetShardSnapshotRequest mutateInstance(GetShardSnapshotRequest instanc
private ShardId randomShardId() {
return new ShardId(randomAlphaOfLength(10), UUIDs.randomBase64UUID(), randomIntBetween(0, 100));
}

public void testGetDescription() {
final GetShardSnapshotRequest request = new GetShardSnapshotRequest(Arrays.asList("repo1", "repo2"), new ShardId("idx", "uuid", 0));
assertThat(request.getDescription(), equalTo("shard[idx][0], repositories[repo1,repo2]"));

final GetShardSnapshotRequest randomRequest = createTestInstance();
final String description = randomRequest.getDescription();
assertThat(description, containsString(randomRequest.getShardId().toString()));
assertThat(
description,
description.length(),
lessThanOrEqualTo(
("shard" + randomRequest.getShardId() + ", repositories[").length() + 1024 + 100 + ",... (999 in total, 999 omitted)"
.length()
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,13 @@
import java.util.function.Consumer;

import static java.util.Collections.singletonMap;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.startsWith;

public class FieldCapabilitiesRequestTests extends AbstractWireSerializingTestCase<FieldCapabilitiesRequest> {

Expand Down Expand Up @@ -153,4 +159,54 @@ public void testSerializingWithRuntimeFieldsBeforeSupportedThrows() {
assertThat(e.getMessage(), equalTo("Versions before 7.12.0 don't support [runtime_mappings], but trying to send _field_caps "
+ "request to a node with version [" + v + "]"));
}

public void testGetDescription() {
final FieldCapabilitiesRequest request = new FieldCapabilitiesRequest();
assertThat(request.getDescription(), equalTo("indices[], fields[]"));

request.fields("a", "b");
assertThat(request.getDescription(), anyOf(
equalTo("indices[], fields[a,b]"),
equalTo("indices[], fields[b,a]")));

request.indices("x", "y", "z");
request.fields("a");
assertThat(request.getDescription(), equalTo("indices[x,y,z], fields[a]"));

final String[] lots = new String[between(1024, 2048)];
for (int i = 0; i < lots.length; i++) {
lots[i] = "s" + i;
}

request.indices("x","y","z");
request.fields(lots);
assertThat(request.getDescription(), allOf(
startsWith("indices[x,y,z], fields["),
containsString("..."),
containsString(lots.length + " in total"),
containsString("omitted")));
assertThat(request.getDescription().length(), lessThanOrEqualTo(
1024 + ("indices[x,y,z], fields[" + "s9999,... (9999 in total, 9999 omitted)]").length()));

request.fields("a");
request.indices(lots);
assertThat(request.getDescription(), allOf(
startsWith("indices[s0,s1,s2,s3"),
containsString("..."),
containsString(lots.length + " in total"),
containsString("omitted"),
endsWith("], fields[a]")));
assertThat(request.getDescription().length(), lessThanOrEqualTo(
1024 + ("indices[" + "s9999,... (9999 in total, 9999 omitted)], fields[a]").length()));

final FieldCapabilitiesRequest randomRequest = createTestInstance();
final String description = randomRequest.getDescription();
for (String index : randomRequest.indices()) {
assertThat(description, containsString(index));
}
for (String field : randomRequest.fields()) {
assertThat(description, containsString(field));
}
}

}
92 changes: 92 additions & 0 deletions server/src/test/java/org/elasticsearch/common/StringsTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,16 @@
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.test.ESTestCase;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.lessThanOrEqualTo;

public class StringsTests extends ESTestCase {

Expand Down Expand Up @@ -111,4 +117,90 @@ public void testSplitStringToSet() {
assertEquals(Strings.tokenizeByCommaToSet(" aa "), Sets.newHashSet("aa"));
assertEquals(Strings.tokenizeByCommaToSet(" "), Sets.newHashSet());
}

public void testCollectionToDelimitedStringWithLimitZero() {
final String delimiter = randomFrom("", ",", ", ", "/");
final String prefix = randomFrom("", "[");
final String suffix = randomFrom("", "]");

final int count = between(0, 100);
final List<String> strings = new ArrayList<>(count);
while (strings.size() < count) {
// avoid starting with a sequence of empty appends, it makes the assertions much messier
final int minLength = strings.isEmpty() && delimiter.isEmpty() && prefix.isEmpty() && suffix.isEmpty() ? 1 : 0;
strings.add(randomAlphaOfLength(between(minLength, 10)));
}

final StringBuilder stringBuilder = new StringBuilder();
Strings.collectionToDelimitedStringWithLimit(strings, delimiter, prefix, suffix, 0, stringBuilder);
final String completelyTruncatedDescription = stringBuilder.toString();

if (count == 0) {
assertThat(completelyTruncatedDescription, equalTo(""));
} else if (count == 1) {
assertThat(completelyTruncatedDescription, equalTo(prefix + strings.get(0) + suffix));
} else {
assertThat(completelyTruncatedDescription, equalTo(prefix + strings.get(0) + suffix + delimiter +
"... (" + count + " in total, " + (count - 1) + " omitted)"));
}
}

public void testCollectionToDelimitedStringWithLimitTruncation() {
final String delimiter = randomFrom("", ",", ", ", "/");
final String prefix = randomFrom("", "[");
final String suffix = randomFrom("", "]");

final int count = between(2, 100);
final List<String> strings = new ArrayList<>(count);
while (strings.size() < count) {
// avoid empty appends, it makes the assertions much messier
final int minLength = delimiter.isEmpty() && prefix.isEmpty() && suffix.isEmpty() ? 1 : 0;
strings.add(randomAlphaOfLength(between(minLength, 10)));
}

final int fullDescriptionLength = Strings.collectionToDelimitedString(strings, delimiter, prefix, suffix).length();
final int lastItemSize = prefix.length() + strings.get(count-1).length() + suffix.length();
final int truncatedLength = between(0, fullDescriptionLength - lastItemSize - 1);
final StringBuilder stringBuilder = new StringBuilder();
Strings.collectionToDelimitedStringWithLimit(strings, delimiter, prefix, suffix, truncatedLength, stringBuilder);
final String truncatedDescription = stringBuilder.toString();

assertThat(truncatedDescription, allOf(
containsString("... (" + count + " in total,"),
endsWith(" omitted)")
));

assertThat(truncatedDescription, truncatedDescription.length(), lessThanOrEqualTo(
truncatedLength + (prefix + "0123456789" + suffix + delimiter + "... (999 in total, 999 omitted)").length()
));
}

public void testCollectionToDelimitedStringWithLimitNoTruncation() {
final String delimiter = randomFrom("", ",", ", ", "/");
final String prefix = randomFrom("", "[");
final String suffix = randomFrom("", "]");

final int count = between(1, 100);
final List<String> strings = new ArrayList<>(count);
while (strings.size() < count) {
strings.add(randomAlphaOfLength(between(0, 10)));
}

final String fullDescription = Strings.collectionToDelimitedString(strings, delimiter, prefix, suffix);
for (String string : strings) {
assertThat(fullDescription, containsString(prefix + string + suffix));
}

final int lastItemSize = prefix.length() + strings.get(count-1).length() + suffix.length();
final int minLimit = fullDescription.length() - lastItemSize;
final int limit = randomFrom(
between(minLimit, fullDescription.length()),
between(minLimit, Integer.MAX_VALUE),
Integer.MAX_VALUE
);

final StringBuilder stringBuilder = new StringBuilder();
Strings.collectionToDelimitedStringWithLimit(strings, delimiter, prefix, suffix, limit, stringBuilder);
assertThat(stringBuilder.toString(), equalTo(fullDescription));
}
}

0 comments on commit 03e5c55

Please sign in to comment.