Skip to content

Commit c3d20fc

Browse files
authored
Refactor IndexAbstractionResolver (#135587)
Refactor `IndexAbstractionResolver` to make a single resource resolution step re-usable. Non-functional refactor in preparation for cross-project search index resolution (see [this](https://github.com/elastic/elasticsearch/pull/135346/files#diff-3e278f8a5f49993b4e491a25ddeaf382289d122a69492902cf61ede33589e9a6R53) PR).
1 parent fe74aa4 commit c3d20fc

File tree

1 file changed

+92
-70
lines changed

1 file changed

+92
-70
lines changed

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

Lines changed: 92 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -48,92 +48,114 @@ public ResolvedIndexExpressions resolveIndexAbstractions(
4848
boolean includeDataStreams
4949
) {
5050
final ResolvedIndexExpressions.Builder resolvedExpressionsBuilder = ResolvedIndexExpressions.builder();
51-
5251
boolean wildcardSeen = false;
5352
for (String index : indices) {
54-
String indexAbstraction;
55-
boolean minus = false;
56-
if (index.charAt(0) == '-' && wildcardSeen) {
57-
indexAbstraction = index.substring(1);
58-
minus = true;
59-
} else {
60-
indexAbstraction = index;
61-
}
53+
wildcardSeen = resolveIndexAbstraction(
54+
resolvedExpressionsBuilder,
55+
index,
56+
indicesOptions,
57+
projectMetadata,
58+
allAuthorizedAndAvailableBySelector,
59+
isAuthorized,
60+
includeDataStreams,
61+
wildcardSeen
62+
);
63+
}
64+
return resolvedExpressionsBuilder.build();
65+
}
6266

63-
// Always check to see if there's a selector on the index expression
64-
final Tuple<String, String> expressionAndSelector = IndexNameExpressionResolver.splitSelectorExpression(indexAbstraction);
65-
final String selectorString = expressionAndSelector.v2();
66-
if (indicesOptions.allowSelectors() == false && selectorString != null) {
67-
throw new UnsupportedSelectorException(indexAbstraction);
68-
}
69-
indexAbstraction = expressionAndSelector.v1();
70-
IndexComponentSelector selector = IndexComponentSelector.getByKeyOrThrow(selectorString);
67+
private boolean resolveIndexAbstraction(
68+
ResolvedIndexExpressions.Builder resolvedExpressionsBuilder,
69+
String index,
70+
IndicesOptions indicesOptions,
71+
ProjectMetadata projectMetadata,
72+
Function<IndexComponentSelector, Set<String>> allAuthorizedAndAvailableBySelector,
73+
BiPredicate<String, IndexComponentSelector> isAuthorized,
74+
boolean includeDataStreams,
75+
boolean wildcardSeen
76+
) {
77+
String indexAbstraction;
78+
boolean minus = false;
79+
if (index.charAt(0) == '-' && wildcardSeen) {
80+
indexAbstraction = index.substring(1);
81+
minus = true;
82+
} else {
83+
indexAbstraction = index;
84+
}
85+
86+
// Always check to see if there's a selector on the index expression
87+
final Tuple<String, String> expressionAndSelector = IndexNameExpressionResolver.splitSelectorExpression(indexAbstraction);
88+
final String selectorString = expressionAndSelector.v2();
89+
if (indicesOptions.allowSelectors() == false && selectorString != null) {
90+
throw new UnsupportedSelectorException(indexAbstraction);
91+
}
92+
indexAbstraction = expressionAndSelector.v1();
93+
IndexComponentSelector selector = IndexComponentSelector.getByKeyOrThrow(selectorString);
7194

72-
// we always need to check for date math expressions
73-
indexAbstraction = IndexNameExpressionResolver.resolveDateMathExpression(indexAbstraction);
95+
// we always need to check for date math expressions
96+
indexAbstraction = IndexNameExpressionResolver.resolveDateMathExpression(indexAbstraction);
7497

75-
if (indicesOptions.expandWildcardExpressions() && Regex.isSimpleMatchPattern(indexAbstraction)) {
76-
wildcardSeen = true;
77-
final HashSet<String> resolvedIndices = new HashSet<>();
78-
for (String authorizedIndex : allAuthorizedAndAvailableBySelector.apply(selector)) {
79-
if (Regex.simpleMatch(indexAbstraction, authorizedIndex)
98+
if (indicesOptions.expandWildcardExpressions() && Regex.isSimpleMatchPattern(indexAbstraction)) {
99+
wildcardSeen = true;
100+
final HashSet<String> resolvedIndices = new HashSet<>();
101+
for (String authorizedIndex : allAuthorizedAndAvailableBySelector.apply(selector)) {
102+
if (Regex.simpleMatch(indexAbstraction, authorizedIndex)
103+
&& isIndexVisible(
104+
indexAbstraction,
105+
selectorString,
106+
authorizedIndex,
107+
indicesOptions,
108+
projectMetadata,
109+
indexNameExpressionResolver,
110+
includeDataStreams
111+
)) {
112+
resolveSelectorsAndCollect(authorizedIndex, selectorString, indicesOptions, resolvedIndices, projectMetadata);
113+
}
114+
}
115+
if (resolvedIndices.isEmpty()) {
116+
// es core honours allow_no_indices for each wildcard expression, we do the same here by throwing index not found.
117+
if (indicesOptions.allowNoIndices() == false) {
118+
throw new IndexNotFoundException(indexAbstraction);
119+
}
120+
resolvedExpressionsBuilder.addLocalExpressions(index, new HashSet<>(), SUCCESS);
121+
} else {
122+
if (minus) {
123+
resolvedExpressionsBuilder.excludeFromLocalExpressions(resolvedIndices);
124+
} else {
125+
resolvedExpressionsBuilder.addLocalExpressions(index, resolvedIndices, SUCCESS);
126+
}
127+
}
128+
} else {
129+
final HashSet<String> resolvedIndices = new HashSet<>();
130+
resolveSelectorsAndCollect(indexAbstraction, selectorString, indicesOptions, resolvedIndices, projectMetadata);
131+
if (minus) {
132+
resolvedExpressionsBuilder.excludeFromLocalExpressions(resolvedIndices);
133+
} else {
134+
final boolean authorized = isAuthorized.test(indexAbstraction, selector);
135+
if (authorized) {
136+
final boolean visible = indexExists(projectMetadata, indexAbstraction)
80137
&& isIndexVisible(
81138
indexAbstraction,
82139
selectorString,
83-
authorizedIndex,
140+
indexAbstraction,
84141
indicesOptions,
85142
projectMetadata,
86143
indexNameExpressionResolver,
87144
includeDataStreams
88-
)) {
89-
resolveSelectorsAndCollect(authorizedIndex, selectorString, indicesOptions, resolvedIndices, projectMetadata);
90-
}
91-
}
92-
if (resolvedIndices.isEmpty()) {
93-
// es core honours allow_no_indices for each wildcard expression, we do the same here by throwing index not found.
94-
if (indicesOptions.allowNoIndices() == false) {
95-
throw new IndexNotFoundException(indexAbstraction);
96-
}
97-
resolvedExpressionsBuilder.addLocalExpressions(index, new HashSet<>(), SUCCESS);
98-
} else {
99-
if (minus) {
100-
resolvedExpressionsBuilder.excludeFromLocalExpressions(resolvedIndices);
101-
} else {
102-
resolvedExpressionsBuilder.addLocalExpressions(index, resolvedIndices, SUCCESS);
103-
}
104-
}
105-
} else {
106-
final HashSet<String> resolvedIndices = new HashSet<>();
107-
resolveSelectorsAndCollect(indexAbstraction, selectorString, indicesOptions, resolvedIndices, projectMetadata);
108-
if (minus) {
109-
resolvedExpressionsBuilder.excludeFromLocalExpressions(resolvedIndices);
145+
);
146+
final LocalIndexResolutionResult result = visible ? SUCCESS : CONCRETE_RESOURCE_NOT_VISIBLE;
147+
resolvedExpressionsBuilder.addLocalExpressions(index, resolvedIndices, result);
148+
} else if (indicesOptions.ignoreUnavailable()) {
149+
// ignoreUnavailable implies that the request should not fail if an index is not authorized
150+
// so we map this expression to an empty list,
151+
resolvedExpressionsBuilder.addLocalExpressions(index, new HashSet<>(), CONCRETE_RESOURCE_UNAUTHORIZED);
110152
} else {
111-
final boolean authorized = isAuthorized.test(indexAbstraction, selector);
112-
if (authorized) {
113-
final boolean visible = indexExists(projectMetadata, indexAbstraction)
114-
&& isIndexVisible(
115-
indexAbstraction,
116-
selectorString,
117-
indexAbstraction,
118-
indicesOptions,
119-
projectMetadata,
120-
indexNameExpressionResolver,
121-
includeDataStreams
122-
);
123-
final LocalIndexResolutionResult result = visible ? SUCCESS : CONCRETE_RESOURCE_NOT_VISIBLE;
124-
resolvedExpressionsBuilder.addLocalExpressions(index, resolvedIndices, result);
125-
} else if (indicesOptions.ignoreUnavailable()) {
126-
// ignoreUnavailable implies that the request should not fail if an index is not authorized
127-
// so we map this expression to an empty list,
128-
resolvedExpressionsBuilder.addLocalExpressions(index, new HashSet<>(), CONCRETE_RESOURCE_UNAUTHORIZED);
129-
} else {
130-
// store the calculated expansion as unauthorized, it will be rejected later
131-
resolvedExpressionsBuilder.addLocalExpressions(index, resolvedIndices, CONCRETE_RESOURCE_UNAUTHORIZED);
132-
}
153+
// store the calculated expansion as unauthorized, it will be rejected later
154+
resolvedExpressionsBuilder.addLocalExpressions(index, resolvedIndices, CONCRETE_RESOURCE_UNAUTHORIZED);
133155
}
134156
}
135157
}
136-
return resolvedExpressionsBuilder.build();
158+
return wildcardSeen;
137159
}
138160

139161
private static void resolveSelectorsAndCollect(

0 commit comments

Comments
 (0)