8
8
9
9
package org .elasticsearch .cluster .metadata ;
10
10
11
+ import org .elasticsearch .action .ActionListener ;
12
+ import org .elasticsearch .action .ActionRunnable ;
13
+ import org .elasticsearch .action .StepListener ;
11
14
import org .elasticsearch .action .support .IndicesOptions ;
15
+ import org .elasticsearch .action .support .PlainActionFuture ;
12
16
import org .elasticsearch .common .regex .Regex ;
17
+ import org .elasticsearch .common .util .AsyncSupplier ;
18
+ import org .elasticsearch .common .util .concurrent .FutureUtils ;
13
19
import org .elasticsearch .index .IndexNotFoundException ;
14
20
15
21
import java .util .ArrayList ;
16
22
import java .util .Arrays ;
17
23
import java .util .Collection ;
18
24
import java .util .HashSet ;
25
+ import java .util .Iterator ;
19
26
import java .util .List ;
20
27
import java .util .Set ;
28
+ import java .util .concurrent .TimeUnit ;
29
+ import java .util .concurrent .atomic .AtomicBoolean ;
30
+ import java .util .concurrent .atomic .AtomicReference ;
21
31
22
32
public class IndexAbstractionResolver {
23
33
@@ -43,69 +53,116 @@ public List<String> resolveIndexAbstractions(Iterable<String> indices, IndicesOp
43
53
public List <String > resolveIndexAbstractions (Iterable <String > indices , IndicesOptions indicesOptions , Metadata metadata ,
44
54
Collection <String > availableIndexAbstractions , boolean replaceWildcards ,
45
55
boolean includeDataStreams ) {
46
- List <String > finalIndices = new ArrayList <>();
47
- boolean wildcardSeen = false ;
48
- for (String index : indices ) {
49
- String indexAbstraction ;
50
- boolean minus = false ;
51
- if (index .charAt (0 ) == '-' && wildcardSeen ) {
52
- indexAbstraction = index .substring (1 );
53
- minus = true ;
54
- } else {
55
- indexAbstraction = index ;
56
- }
56
+ PlainActionFuture <List <String >> future = PlainActionFuture .newFuture ();
57
+ // if the supplier is not async, the method is not async, hence get is non-blocking
58
+ resolveIndexAbstractions (indices , indicesOptions , metadata , listener -> listener .onResponse (availableIndexAbstractions ),
59
+ replaceWildcards ,
60
+ includeDataStreams ,
61
+ future );
62
+ return FutureUtils .get (future , 0 , TimeUnit .MILLISECONDS );
63
+ }
57
64
58
- // we always need to check for date math expressions
59
- final String dateMathName = indexNameExpressionResolver .resolveDateMathExpression (indexAbstraction );
60
- if (dateMathName != indexAbstraction ) {
61
- assert dateMathName .equals (indexAbstraction ) == false ;
62
- if (replaceWildcards && Regex .isSimpleMatchPattern (dateMathName )) {
63
- // continue
64
- indexAbstraction = dateMathName ;
65
- } else if (availableIndexAbstractions .contains (dateMathName ) &&
66
- isIndexVisible (indexAbstraction , dateMathName , indicesOptions , metadata , includeDataStreams , true )) {
67
- if (minus ) {
68
- finalIndices .remove (dateMathName );
69
- } else {
70
- finalIndices .add (dateMathName );
71
- }
65
+ public void resolveIndexAbstractions (Iterable <String > indices , IndicesOptions indicesOptions , Metadata metadata ,
66
+ AsyncSupplier <Collection <String >> availableIndexAbstractionsSupplier , boolean replaceWildcards ,
67
+ boolean includeDataStreams , ActionListener <List <String >> listener ) {
68
+ final Iterator <String > indicesIterator = indices .iterator ();
69
+ final Runnable evalItems = new ActionRunnable (listener ) {
70
+
71
+ final List <String > finalIndices = new ArrayList <>();
72
+ final AtomicBoolean wildcardSeen = new AtomicBoolean (false );
73
+
74
+ @ Override
75
+ public void doRun () {
76
+ if (false == indicesIterator .hasNext ()) {
77
+ listener .onResponse (finalIndices );
72
78
} else {
73
- if (indicesOptions .ignoreUnavailable () == false ) {
74
- throw new IndexNotFoundException (dateMathName );
79
+ final String index = indicesIterator .next ();
80
+ final AtomicReference <String > indexAbstraction ;
81
+ final boolean minus ;
82
+ if (index .charAt (0 ) == '-' && wildcardSeen .get ()) {
83
+ indexAbstraction = new AtomicReference <>(index .substring (1 ));
84
+ minus = true ;
85
+ } else {
86
+ indexAbstraction = new AtomicReference <>(index );
87
+ minus = false ;
75
88
}
76
- }
77
- }
78
89
79
- if (replaceWildcards && Regex .isSimpleMatchPattern (indexAbstraction )) {
80
- wildcardSeen = true ;
81
- Set <String > resolvedIndices = new HashSet <>();
82
- for (String authorizedIndex : availableIndexAbstractions ) {
83
- if (Regex .simpleMatch (indexAbstraction , authorizedIndex ) &&
84
- isIndexVisible (indexAbstraction , authorizedIndex , indicesOptions , metadata , includeDataStreams )) {
85
- resolvedIndices .add (authorizedIndex );
86
- }
87
- }
88
- if (resolvedIndices .isEmpty ()) {
89
- //es core honours allow_no_indices for each wildcard expression, we do the same here by throwing index not found.
90
- if (indicesOptions .allowNoIndices () == false ) {
91
- throw new IndexNotFoundException (indexAbstraction );
92
- }
93
- } else {
94
- if (minus ) {
95
- finalIndices .removeAll (resolvedIndices );
90
+ // we always need to check for date math expressions
91
+ final String dateMathName = indexNameExpressionResolver .resolveDateMathExpression (indexAbstraction .get ());
92
+ final StepListener <Void > evaluateDateMathStep = new StepListener <>();
93
+ if (dateMathName != indexAbstraction .get ()) {
94
+ assert dateMathName .equals (indexAbstraction .get ()) == false ;
95
+ if (replaceWildcards && Regex .isSimpleMatchPattern (dateMathName )) {
96
+ // this is a date math and a wildcard
97
+ indexAbstraction .set (dateMathName );
98
+ // continue
99
+ evaluateDateMathStep .onResponse (null );
100
+ } else {
101
+ availableIndexAbstractionsSupplier .getAsync (ActionListener .wrap (availableIndexAbstractions -> {
102
+ if (availableIndexAbstractions .contains (dateMathName ) &&
103
+ isIndexVisible (indexAbstraction .get (), dateMathName , indicesOptions , metadata , includeDataStreams , true )) {
104
+ if (minus ) {
105
+ finalIndices .remove (dateMathName );
106
+ } else {
107
+ finalIndices .add (dateMathName );
108
+ }
109
+ } else {
110
+ if (indicesOptions .ignoreUnavailable () == false ) {
111
+ listener .onFailure (new IndexNotFoundException (dateMathName ));
112
+ return ;
113
+ }
114
+ }
115
+ evaluateDateMathStep .onResponse (null );
116
+ }, listener ::onFailure ));
117
+ }
96
118
} else {
97
- finalIndices . addAll ( resolvedIndices );
119
+ evaluateDateMathStep . onResponse ( null );
98
120
}
99
- }
100
- } else if (dateMathName .equals (indexAbstraction )) {
101
- if (minus ) {
102
- finalIndices .remove (indexAbstraction );
103
- } else {
104
- finalIndices .add (indexAbstraction );
121
+
122
+ evaluateDateMathStep .whenComplete (anotherVoid -> {
123
+ if (replaceWildcards && Regex .isSimpleMatchPattern (indexAbstraction .get ())) {
124
+ wildcardSeen .set (true );
125
+ availableIndexAbstractionsSupplier .getAsync (ActionListener .wrap (availableIndexAbstractions -> {
126
+ Set <String > resolvedIndices = new HashSet <>();
127
+ for (String authorizedIndex : availableIndexAbstractions ) {
128
+ if (Regex .simpleMatch (indexAbstraction .get (), authorizedIndex ) &&
129
+ isIndexVisible (indexAbstraction .get (), authorizedIndex , indicesOptions , metadata , includeDataStreams )) {
130
+ resolvedIndices .add (authorizedIndex );
131
+ }
132
+ }
133
+ if (resolvedIndices .isEmpty ()) {
134
+ //es core honours allow_no_indices for each wildcard expression, we do the same here by throwing index not found.
135
+ if (indicesOptions .allowNoIndices () == false ) {
136
+ listener .onFailure (new IndexNotFoundException (indexAbstraction .get ()));
137
+ return ;
138
+ }
139
+ } else {
140
+ if (minus ) {
141
+ finalIndices .removeAll (resolvedIndices );
142
+ } else {
143
+ finalIndices .addAll (resolvedIndices );
144
+ }
145
+ }
146
+ // next expression item
147
+ this .doRun ();
148
+ }, listener ::onFailure ));
149
+ } else if (dateMathName .equals (indexAbstraction .get ())) {
150
+ if (minus ) {
151
+ finalIndices .remove (indexAbstraction .get ());
152
+ } else {
153
+ finalIndices .add (indexAbstraction .get ());
154
+ }
155
+ // next expression item
156
+ this .doRun ();
157
+ } else {
158
+ // next expression item
159
+ this .doRun ();
160
+ }
161
+ }, listener ::onFailure );
105
162
}
106
163
}
107
- }
108
- return finalIndices ;
164
+ };
165
+ evalItems . run () ;
109
166
}
110
167
111
168
public static boolean isIndexVisible (String expression , String index , IndicesOptions indicesOptions , Metadata metadata ,
0 commit comments