Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.elasticsearch.xcontent.XContentBuilder;

import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
Expand Down Expand Up @@ -84,59 +85,28 @@ static RestResponse buildRestResponse(
) throws Exception {
final Set<String> indicesToDisplay = new HashSet<>();
final Set<String> returnedAliasNames = new HashSet<>();
for (final Map.Entry<String, List<AliasMetadata>> cursor : responseAliasMap.entrySet()) {
for (final AliasMetadata aliasMetadata : cursor.getValue()) {
if (aliasesExplicitlyRequested) {
if (aliasesExplicitlyRequested) {
for (final Map.Entry<String, List<AliasMetadata>> cursor : responseAliasMap.entrySet()) {
final var aliases = cursor.getValue();
if (aliases.isEmpty() == false) {
// only display indices that have aliases
indicesToDisplay.add(cursor.getKey());
}
returnedAliasNames.add(aliasMetadata.alias());
}
}
dataStreamAliases.entrySet()
.stream()
.flatMap(entry -> entry.getValue().stream())
.forEach(dataStreamAlias -> returnedAliasNames.add(dataStreamAlias.getName()));

// compute explicitly requested aliases that have are not returned in the result
final SortedSet<String> missingAliases = new TreeSet<>();
// first wildcard index, leading "-" as an alias name after this index means
// that it is an exclusion
int firstWildcardIndex = requestedAliases.length;
for (int i = 0; i < requestedAliases.length; i++) {
if (Regex.isSimpleMatchPattern(requestedAliases[i])) {
firstWildcardIndex = i;
break;
}
}
for (int i = 0; i < requestedAliases.length; i++) {
if (Metadata.ALL.equals(requestedAliases[i])
|| Regex.isSimpleMatchPattern(requestedAliases[i])
|| (i > firstWildcardIndex && requestedAliases[i].charAt(0) == '-')) {
// only explicitly requested aliases will be called out as missing (404)
continue;
}
// check if aliases[i] is subsequently excluded
int j = Math.max(i + 1, firstWildcardIndex);
for (; j < requestedAliases.length; j++) {
if (requestedAliases[j].charAt(0) == '-') {
// this is an exclude pattern
if (Regex.simpleMatch(requestedAliases[j].substring(1), requestedAliases[i])
|| Metadata.ALL.equals(requestedAliases[j].substring(1))) {
// aliases[i] is excluded by aliases[j]
break;
for (final AliasMetadata aliasMetadata : cursor.getValue()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit

Suggested change
for (final AliasMetadata aliasMetadata : cursor.getValue()) {
for (final AliasMetadata aliasMetadata : aliases) {

returnedAliasNames.add(aliasMetadata.alias());
}
}
}
if (j == requestedAliases.length) {
// explicitly requested aliases[i] is not excluded by any subsequent "-" wildcard in expression
if (false == returnedAliasNames.contains(requestedAliases[i])) {
// aliases[i] is not in the result set
missingAliases.add(requestedAliases[i]);

for (final Map.Entry<String, List<DataStreamAlias>> entry : dataStreamAliases.entrySet()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we don't need the keys here right?

Suggested change
for (final Map.Entry<String, List<DataStreamAlias>> entry : dataStreamAliases.entrySet()) {
for (final List<DataStreamAlias> dataStreamAliases : dataStreamAliases.values()) {

for (final DataStreamAlias dataStreamAlias : entry.getValue()) {
returnedAliasNames.add(dataStreamAlias.getName());
}
}
}

// compute explicitly requested aliases that would not be returned in the result
final var missingAliases = computeMissingAliases(requestedAliases, returnedAliasNames);

final RestStatus status;
builder.startObject();
{
Expand Down Expand Up @@ -239,4 +209,50 @@ public RestResponse buildResponse(GetAliasesResponse response, XContentBuilder b
});
}

private static SortedSet<String> computeMissingAliases(String[] requestedAliases, Set<String> returnedAliasNames) {
if (requestedAliases.length == 0) {
return Collections.emptySortedSet();
}

final var missingAliases = new TreeSet<String>();

// first wildcard index, leading "-" as an alias name after this index means
// that it is an exclusion
int firstWildcardIndex = requestedAliases.length;
for (int i = 0; i < requestedAliases.length; i++) {
if (Regex.isSimpleMatchPattern(requestedAliases[i])) {
firstWildcardIndex = i;
break;
}
}
for (int i = 0; i < requestedAliases.length; i++) {
if (Metadata.ALL.equals(requestedAliases[i])
|| Regex.isSimpleMatchPattern(requestedAliases[i])
|| (i > firstWildcardIndex && requestedAliases[i].charAt(0) == '-')) {
// only explicitly requested aliases will be called out as missing (404)
continue;
}
// check if aliases[i] is subsequently excluded
int j = Math.max(i + 1, firstWildcardIndex);
for (; j < requestedAliases.length; j++) {
if (requestedAliases[j].charAt(0) == '-') {
// this is an exclude pattern
if (Regex.simpleMatch(requestedAliases[j].substring(1), requestedAliases[i])
|| Metadata.ALL.equals(requestedAliases[j].substring(1))) {
// aliases[i] is excluded by aliases[j]
break;
}
}
}
if (j == requestedAliases.length) {
// explicitly requested aliases[i] is not excluded by any subsequent "-" wildcard in expression
if (false == returnedAliasNames.contains(requestedAliases[i])) {
// aliases[i] is not in the result set
missingAliases.add(requestedAliases[i]);
}
}
}

return missingAliases;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.elasticsearch.cluster.metadata.AliasMetadata;
import org.elasticsearch.rest.RestResponse;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.rest.FakeRestRequest;
import org.elasticsearch.xcontent.XContentBuilder;
import org.elasticsearch.xcontent.XContentFactory;
import org.elasticsearch.xcontent.XContentType;
Expand Down Expand Up @@ -51,6 +52,27 @@ public void testBareRequest() throws Exception {
assertThat(restResponse.content().utf8ToString(), equalTo("{\"index\":{\"aliases\":{\"foo\":{},\"foobar\":{}}}}"));
}

public void testNameParamWithAllValue() throws Exception {
final XContentBuilder xContentBuilder = XContentFactory.contentBuilder(XContentType.JSON);
final var req = new FakeRestRequest.Builder(xContentRegistry()).withParams(Map.of("name", "_all")).build();
final RestResponse restResponse = RestGetAliasesAction.buildRestResponse(
req.hasParam("name"),
req.paramAsStringArrayOrEmptyIfAll("name"),
Map.of(
"index",
Arrays.asList(AliasMetadata.builder("foo").build(), AliasMetadata.builder("foobar").build()),
"index2",
List.of()
),
Map.of(),
xContentBuilder
);
assertThat(restResponse.status(), equalTo(OK));
assertThat(restResponse.contentType(), equalTo("application/json"));
// Verify we don't get "index2" since it has no aliases.
assertThat(restResponse.content().utf8ToString(), equalTo("{\"index\":{\"aliases\":{\"foo\":{},\"foobar\":{}}}}"));
}

public void testSimpleAliasWildcardMatchingNothing() throws Exception {
final XContentBuilder xContentBuilder = XContentFactory.contentBuilder(XContentType.JSON);
final RestResponse restResponse = RestGetAliasesAction.buildRestResponse(
Expand Down