25
25
import org .elasticsearch .action .support .IndicesOptions ;
26
26
import org .elasticsearch .client .node .NodeClient ;
27
27
import org .elasticsearch .cluster .metadata .AliasMetaData ;
28
+ import org .elasticsearch .cluster .metadata .MetaData ;
28
29
import org .elasticsearch .common .Strings ;
29
30
import org .elasticsearch .common .collect .ImmutableOpenMap ;
30
31
import org .elasticsearch .common .regex .Regex ;
31
32
import org .elasticsearch .common .settings .Settings ;
32
- import org .elasticsearch .common .util .set .Sets ;
33
33
import org .elasticsearch .common .xcontent .ToXContent ;
34
34
import org .elasticsearch .common .xcontent .XContentBuilder ;
35
35
import org .elasticsearch .rest .BaseRestHandler ;
41
41
import org .elasticsearch .rest .action .RestBuilderListener ;
42
42
43
43
import java .io .IOException ;
44
- import java .util .ArrayList ;
45
- import java .util .Arrays ;
46
44
import java .util .HashSet ;
47
45
import java .util .List ;
48
46
import java .util .Locale ;
49
47
import java .util .Set ;
50
48
import java .util .SortedSet ;
51
- import java .util .stream . Collectors ;
49
+ import java .util .TreeSet ;
52
50
53
51
import static org .elasticsearch .rest .RestRequest .Method .GET ;
54
52
import static org .elasticsearch .rest .RestRequest .Method .HEAD ;
@@ -75,6 +73,94 @@ public String getName() {
75
73
return "get_aliases_action" ;
76
74
}
77
75
76
+ static RestResponse buildRestResponse (boolean aliasesExplicitlyRequested , String [] requestedAliases ,
77
+ ImmutableOpenMap <String , List <AliasMetaData >> responseAliasMap , XContentBuilder builder ) throws Exception {
78
+ final Set <String > indicesToDisplay = new HashSet <>();
79
+ final Set <String > returnedAliasNames = new HashSet <>();
80
+ for (final ObjectObjectCursor <String , List <AliasMetaData >> cursor : responseAliasMap ) {
81
+ for (final AliasMetaData aliasMetaData : cursor .value ) {
82
+ if (aliasesExplicitlyRequested ) {
83
+ // only display indices that have aliases
84
+ indicesToDisplay .add (cursor .key );
85
+ }
86
+ returnedAliasNames .add (aliasMetaData .alias ());
87
+ }
88
+ }
89
+ // compute explicitly requested aliases that have are not returned in the result
90
+ final SortedSet <String > missingAliases = new TreeSet <>();
91
+ // first wildcard index, leading "-" as an alias name after this index means
92
+ // that it is an exclusion
93
+ int firstWildcardIndex = requestedAliases .length ;
94
+ for (int i = 0 ; i < requestedAliases .length ; i ++) {
95
+ if (Regex .isSimpleMatchPattern (requestedAliases [i ])) {
96
+ firstWildcardIndex = i ;
97
+ break ;
98
+ }
99
+ }
100
+ for (int i = 0 ; i < requestedAliases .length ; i ++) {
101
+ if (MetaData .ALL .equals (requestedAliases [i ]) || Regex .isSimpleMatchPattern (requestedAliases [i ])
102
+ || (i > firstWildcardIndex && requestedAliases [i ].charAt (0 ) == '-' )) {
103
+ // only explicitly requested aliases will be called out as missing (404)
104
+ continue ;
105
+ }
106
+ // check if aliases[i] is subsequently excluded
107
+ int j = Math .max (i + 1 , firstWildcardIndex );
108
+ for (; j < requestedAliases .length ; j ++) {
109
+ if (requestedAliases [j ].charAt (0 ) == '-' ) {
110
+ // this is an exclude pattern
111
+ if (Regex .simpleMatch (requestedAliases [j ].substring (1 ), requestedAliases [i ])
112
+ || MetaData .ALL .equals (requestedAliases [j ].substring (1 ))) {
113
+ // aliases[i] is excluded by aliases[j]
114
+ break ;
115
+ }
116
+ }
117
+ }
118
+ if (j == requestedAliases .length ) {
119
+ // explicitly requested aliases[i] is not excluded by any subsequent "-" wildcard in expression
120
+ if (false == returnedAliasNames .contains (requestedAliases [i ])) {
121
+ // aliases[i] is not in the result set
122
+ missingAliases .add (requestedAliases [i ]);
123
+ }
124
+ }
125
+ }
126
+
127
+ final RestStatus status ;
128
+ builder .startObject ();
129
+ {
130
+ if (missingAliases .isEmpty ()) {
131
+ status = RestStatus .OK ;
132
+ } else {
133
+ status = RestStatus .NOT_FOUND ;
134
+ final String message ;
135
+ if (missingAliases .size () == 1 ) {
136
+ message = String .format (Locale .ROOT , "alias [%s] missing" , Strings .collectionToCommaDelimitedString (missingAliases ));
137
+ } else {
138
+ message = String .format (Locale .ROOT , "aliases [%s] missing" , Strings .collectionToCommaDelimitedString (missingAliases ));
139
+ }
140
+ builder .field ("error" , message );
141
+ builder .field ("status" , status .getStatus ());
142
+ }
143
+
144
+ for (final ObjectObjectCursor <String , List <AliasMetaData >> entry : responseAliasMap ) {
145
+ if (aliasesExplicitlyRequested == false || (aliasesExplicitlyRequested && indicesToDisplay .contains (entry .key ))) {
146
+ builder .startObject (entry .key );
147
+ {
148
+ builder .startObject ("aliases" );
149
+ {
150
+ for (final AliasMetaData alias : entry .value ) {
151
+ AliasMetaData .Builder .toXContent (alias , builder , ToXContent .EMPTY_PARAMS );
152
+ }
153
+ }
154
+ builder .endObject ();
155
+ }
156
+ builder .endObject ();
157
+ }
158
+ }
159
+ }
160
+ builder .endObject ();
161
+ return new BytesRestResponse (status , builder );
162
+ }
163
+
78
164
@ Override
79
165
public RestChannelConsumer prepareRequest (final RestRequest request , final NodeClient client ) throws IOException {
80
166
// The TransportGetAliasesAction was improved do the same post processing as is happening here.
@@ -94,76 +180,8 @@ public RestChannelConsumer prepareRequest(final RestRequest request, final NodeC
94
180
return channel -> client .admin ().indices ().getAliases (getAliasesRequest , new RestBuilderListener <GetAliasesResponse >(channel ) {
95
181
@ Override
96
182
public RestResponse buildResponse (GetAliasesResponse response , XContentBuilder builder ) throws Exception {
97
- final ImmutableOpenMap <String , List <AliasMetaData >> aliasMap = response .getAliases ();
98
-
99
- final Set <String > aliasNames = new HashSet <>();
100
- final Set <String > indicesToDisplay = new HashSet <>();
101
- for (final ObjectObjectCursor <String , List <AliasMetaData >> cursor : aliasMap ) {
102
- for (final AliasMetaData aliasMetaData : cursor .value ) {
103
- aliasNames .add (aliasMetaData .alias ());
104
- if (namesProvided ) {
105
- indicesToDisplay .add (cursor .key );
106
- }
107
- }
108
- }
109
-
110
- // first remove requested aliases that are exact matches
111
- final SortedSet <String > difference = Sets .sortedDifference (Arrays .stream (aliases ).collect (Collectors .toSet ()), aliasNames );
112
-
113
- // now remove requested aliases that contain wildcards that are simple matches
114
- final List <String > matches = new ArrayList <>();
115
- outer :
116
- for (final String pattern : difference ) {
117
- if (pattern .contains ("*" )) {
118
- for (final String aliasName : aliasNames ) {
119
- if (Regex .simpleMatch (pattern , aliasName )) {
120
- matches .add (pattern );
121
- continue outer ;
122
- }
123
- }
124
- }
125
- }
126
- difference .removeAll (matches );
127
-
128
- final RestStatus status ;
129
- builder .startObject ();
130
- {
131
- if (difference .isEmpty ()) {
132
- status = RestStatus .OK ;
133
- } else {
134
- status = RestStatus .NOT_FOUND ;
135
- final String message ;
136
- if (difference .size () == 1 ) {
137
- message = String .format (Locale .ROOT , "alias [%s] missing" ,
138
- Strings .collectionToCommaDelimitedString (difference ));
139
- } else {
140
- message = String .format (Locale .ROOT , "aliases [%s] missing" ,
141
- Strings .collectionToCommaDelimitedString (difference ));
142
- }
143
- builder .field ("error" , message );
144
- builder .field ("status" , status .getStatus ());
145
- }
146
-
147
- for (final ObjectObjectCursor <String , List <AliasMetaData >> entry : response .getAliases ()) {
148
- if (namesProvided == false || (namesProvided && indicesToDisplay .contains (entry .key ))) {
149
- builder .startObject (entry .key );
150
- {
151
- builder .startObject ("aliases" );
152
- {
153
- for (final AliasMetaData alias : entry .value ) {
154
- AliasMetaData .Builder .toXContent (alias , builder , ToXContent .EMPTY_PARAMS );
155
- }
156
- }
157
- builder .endObject ();
158
- }
159
- builder .endObject ();
160
- }
161
- }
162
- }
163
- builder .endObject ();
164
- return new BytesRestResponse (status , builder );
183
+ return buildRestResponse (namesProvided , aliases , response .getAliases (), builder );
165
184
}
166
-
167
185
});
168
186
}
169
187
0 commit comments