@@ -109,31 +109,36 @@ public void getUser(String username, ActionListener<User> listener) {
109
109
*/
110
110
public void getUsers (String [] userNames , final ActionListener <Collection <User >> listener ) {
111
111
final Consumer <Exception > handleException = (t ) -> {
112
- if (t instanceof IndexNotFoundException ) {
113
- logger .trace ("could not retrieve users because security index does not exist" );
114
- // We don't invoke the onFailure listener here, instead just pass an empty list
115
- listener .onResponse (Collections .emptyList ());
116
- } else {
117
- listener .onFailure (t );
112
+ if (TransportActions .isShardNotAvailableException (t )) {
113
+ logger .trace ("could not retrieve users because of a shard not available exception" , t );
114
+ if (t instanceof IndexNotFoundException ) {
115
+ // We don't invoke the onFailure listener here, instead just pass an empty list
116
+ // as the index doesn't exist. Could have been deleted between checks and execution
117
+ listener .onResponse (Collections .emptyList ());
118
+ } else {
119
+ listener .onFailure (t );
120
+ }
118
121
}
122
+ listener .onFailure (t );
119
123
};
120
124
121
- if ( securityIndex .indexExists () == false ) {
122
- // TODO remove this short circuiting and fix tests that fail without this!
125
+ final SecurityIndexManager frozenSecurityIndex = this . securityIndex .freeze ();
126
+ if ( frozenSecurityIndex . indexExists () == false ) {
123
127
listener .onResponse (Collections .emptyList ());
128
+ } else if (frozenSecurityIndex .isAvailable () == false ) {
129
+ listener .onFailure (frozenSecurityIndex .getUnavailableReason ());
124
130
} else if (userNames .length == 1 ) { // optimization for single user lookup
125
131
final String username = userNames [0 ];
126
132
getUserAndPassword (username , ActionListener .wrap (
127
133
(uap ) -> listener .onResponse (uap == null ? Collections .emptyList () : Collections .singletonList (uap .user ())),
128
134
handleException ));
129
135
} else {
130
- securityIndex .prepareIndexIfNeededThenExecute (listener ::onFailure , () -> {
136
+ securityIndex .checkIndexVersionThenExecute (listener ::onFailure , () -> {
131
137
final QueryBuilder query ;
132
138
if (userNames == null || userNames .length == 0 ) {
133
139
query = QueryBuilders .termQuery (Fields .TYPE .getPreferredName (), USER_DOC_TYPE );
134
140
} else {
135
- final String [] users = Arrays .asList (userNames ).stream ()
136
- .map (s -> getIdForUser (USER_DOC_TYPE , s )).toArray (String []::new );
141
+ final String [] users = Arrays .stream (userNames ).map (s -> getIdForUser (USER_DOC_TYPE , s )).toArray (String []::new );
137
142
query = QueryBuilders .boolQuery ().filter (QueryBuilders .idsQuery (INDEX_TYPE ).addIds (users ));
138
143
}
139
144
final Supplier <ThreadContext .StoredContext > supplier = client .threadPool ().getThreadContext ().newRestorableContext (false );
@@ -155,10 +160,13 @@ public void getUsers(String[] userNames, final ActionListener<Collection<User>>
155
160
}
156
161
157
162
void getUserCount (final ActionListener <Long > listener ) {
158
- if (securityIndex .indexExists () == false ) {
163
+ final SecurityIndexManager frozenSecurityIndex = this .securityIndex .freeze ();
164
+ if (frozenSecurityIndex .indexExists () == false ) {
159
165
listener .onResponse (0L );
166
+ } else if (frozenSecurityIndex .isAvailable () == false ) {
167
+ listener .onFailure (frozenSecurityIndex .getUnavailableReason ());
160
168
} else {
161
- securityIndex .prepareIndexIfNeededThenExecute (listener ::onFailure , () ->
169
+ securityIndex .checkIndexVersionThenExecute (listener ::onFailure , () ->
162
170
executeAsyncWithOrigin (client .threadPool ().getThreadContext (), SECURITY_ORIGIN ,
163
171
client .prepareSearch (SECURITY_INDEX_NAME )
164
172
.setQuery (QueryBuilders .termQuery (Fields .TYPE .getPreferredName (), USER_DOC_TYPE ))
@@ -182,11 +190,16 @@ public void onFailure(Exception e) {
182
190
* Async method to retrieve a user and their password
183
191
*/
184
192
private void getUserAndPassword (final String user , final ActionListener <UserAndPassword > listener ) {
185
- if (securityIndex .indexExists () == false ) {
186
- // TODO remove this short circuiting and fix tests that fail without this!
193
+ final SecurityIndexManager frozenSecurityIndex = securityIndex .freeze ();
194
+ if (frozenSecurityIndex .isAvailable () == false ) {
195
+ if (frozenSecurityIndex .indexExists ()) {
196
+ logger .trace ("could not retrieve user [{}] because security index does not exist" , user );
197
+ } else {
198
+ logger .error ("security index is unavailable. short circuiting retrieval of user [{}]" , user );
199
+ }
187
200
listener .onResponse (null );
188
201
} else {
189
- securityIndex .prepareIndexIfNeededThenExecute (listener ::onFailure , () ->
202
+ securityIndex .checkIndexVersionThenExecute (listener ::onFailure , () ->
190
203
executeAsyncWithOrigin (client .threadPool ().getThreadContext (), SECURITY_ORIGIN ,
191
204
client .prepareGet (SECURITY_INDEX_NAME ,
192
205
INDEX_TYPE , getIdForUser (USER_DOC_TYPE , user )).request (),
@@ -459,24 +472,31 @@ public void onFailure(Exception e) {
459
472
}
460
473
461
474
public void deleteUser (final DeleteUserRequest deleteUserRequest , final ActionListener <Boolean > listener ) {
462
- securityIndex .prepareIndexIfNeededThenExecute (listener ::onFailure , () -> {
463
- DeleteRequest request = client .prepareDelete (SECURITY_INDEX_NAME ,
475
+ final SecurityIndexManager frozenSecurityIndex = securityIndex .freeze ();
476
+ if (frozenSecurityIndex .indexExists () == false ) {
477
+ listener .onResponse (false );
478
+ } else if (frozenSecurityIndex .isAvailable () == false ) {
479
+ listener .onFailure (frozenSecurityIndex .getUnavailableReason ());
480
+ } else {
481
+ securityIndex .checkIndexVersionThenExecute (listener ::onFailure , () -> {
482
+ DeleteRequest request = client .prepareDelete (SECURITY_INDEX_NAME ,
464
483
INDEX_TYPE , getIdForUser (USER_DOC_TYPE , deleteUserRequest .username ())).request ();
465
- request .setRefreshPolicy (deleteUserRequest .getRefreshPolicy ());
466
- executeAsyncWithOrigin (client .threadPool ().getThreadContext (), SECURITY_ORIGIN , request ,
484
+ request .setRefreshPolicy (deleteUserRequest .getRefreshPolicy ());
485
+ executeAsyncWithOrigin (client .threadPool ().getThreadContext (), SECURITY_ORIGIN , request ,
467
486
new ActionListener <DeleteResponse >() {
468
487
@ Override
469
488
public void onResponse (DeleteResponse deleteResponse ) {
470
489
clearRealmCache (deleteUserRequest .username (), listener ,
471
- deleteResponse .getResult () == DocWriteResponse .Result .DELETED );
490
+ deleteResponse .getResult () == DocWriteResponse .Result .DELETED );
472
491
}
473
492
474
493
@ Override
475
494
public void onFailure (Exception e ) {
476
495
listener .onFailure (e );
477
496
}
478
497
}, client ::delete );
479
- });
498
+ });
499
+ }
480
500
}
481
501
482
502
/**
@@ -498,11 +518,13 @@ void verifyPassword(String username, final SecureString password, ActionListener
498
518
}
499
519
500
520
void getReservedUserInfo (String username , ActionListener <ReservedUserInfo > listener ) {
501
- if ( securityIndex .indexExists () == false ) {
502
- // TODO remove this short circuiting and fix tests that fail without this!
521
+ final SecurityIndexManager frozenSecurityIndex = securityIndex .freeze ();
522
+ if ( frozenSecurityIndex . indexExists () == false ) {
503
523
listener .onResponse (null );
524
+ } else if (frozenSecurityIndex .isAvailable () == false ) {
525
+ listener .onFailure (frozenSecurityIndex .getUnavailableReason ());
504
526
} else {
505
- securityIndex .prepareIndexIfNeededThenExecute (listener ::onFailure , () ->
527
+ securityIndex .checkIndexVersionThenExecute (listener ::onFailure , () ->
506
528
executeAsyncWithOrigin (client .threadPool ().getThreadContext (), SECURITY_ORIGIN ,
507
529
client .prepareGet (SECURITY_INDEX_NAME , INDEX_TYPE ,
508
530
getIdForUser (RESERVED_USER_TYPE , username )).request (),
@@ -541,49 +563,56 @@ public void onFailure(Exception e) {
541
563
}
542
564
543
565
void getAllReservedUserInfo (ActionListener <Map <String , ReservedUserInfo >> listener ) {
544
- securityIndex .prepareIndexIfNeededThenExecute (listener ::onFailure , () ->
545
- executeAsyncWithOrigin (client .threadPool ().getThreadContext (), SECURITY_ORIGIN ,
546
- client .prepareSearch (SECURITY_INDEX_NAME )
566
+ final SecurityIndexManager frozenSecurityIndex = securityIndex .freeze ();
567
+ if (frozenSecurityIndex .indexExists () == false ) {
568
+ listener .onResponse (Collections .emptyMap ());
569
+ } else if (frozenSecurityIndex .isAvailable () == false ) {
570
+ listener .onFailure (frozenSecurityIndex .getUnavailableReason ());
571
+ } else {
572
+ securityIndex .checkIndexVersionThenExecute (listener ::onFailure , () ->
573
+ executeAsyncWithOrigin (client .threadPool ().getThreadContext (), SECURITY_ORIGIN ,
574
+ client .prepareSearch (SECURITY_INDEX_NAME )
547
575
.setQuery (QueryBuilders .termQuery (Fields .TYPE .getPreferredName (), RESERVED_USER_TYPE ))
548
576
.setFetchSource (true ).request (),
549
- new ActionListener <SearchResponse >() {
550
- @ Override
551
- public void onResponse (SearchResponse searchResponse ) {
552
- Map <String , ReservedUserInfo > userInfos = new HashMap <>();
553
- assert searchResponse .getHits ().getTotalHits () <= 10 :
577
+ new ActionListener <SearchResponse >() {
578
+ @ Override
579
+ public void onResponse (SearchResponse searchResponse ) {
580
+ Map <String , ReservedUserInfo > userInfos = new HashMap <>();
581
+ assert searchResponse .getHits ().getTotalHits () <= 10 :
554
582
"there are more than 10 reserved users we need to change this to retrieve them all!" ;
555
- for (SearchHit searchHit : searchResponse .getHits ().getHits ()) {
556
- Map <String , Object > sourceMap = searchHit .getSourceAsMap ();
557
- String password = (String ) sourceMap .get (Fields .PASSWORD .getPreferredName ());
558
- Boolean enabled = (Boolean ) sourceMap .get (Fields .ENABLED .getPreferredName ());
559
- final String id = searchHit .getId ();
560
- assert id != null && id .startsWith (RESERVED_USER_TYPE ) :
583
+ for (SearchHit searchHit : searchResponse .getHits ().getHits ()) {
584
+ Map <String , Object > sourceMap = searchHit .getSourceAsMap ();
585
+ String password = (String ) sourceMap .get (Fields .PASSWORD .getPreferredName ());
586
+ Boolean enabled = (Boolean ) sourceMap .get (Fields .ENABLED .getPreferredName ());
587
+ final String id = searchHit .getId ();
588
+ assert id != null && id .startsWith (RESERVED_USER_TYPE ) :
561
589
"id [" + id + "] does not start with reserved-user prefix" ;
562
- final String username = id .substring (RESERVED_USER_TYPE .length () + 1 );
563
- if (password == null ) {
564
- listener .onFailure (new IllegalStateException ("password hash must not be null!" ));
565
- return ;
566
- } else if (enabled == null ) {
567
- listener .onFailure (new IllegalStateException ("enabled must not be null!" ));
568
- return ;
569
- } else {
570
- userInfos .put (username , new ReservedUserInfo (password .toCharArray (), enabled , false ));
590
+ final String username = id .substring (RESERVED_USER_TYPE .length () + 1 );
591
+ if (password == null ) {
592
+ listener .onFailure (new IllegalStateException ("password hash must not be null!" ));
593
+ return ;
594
+ } else if (enabled == null ) {
595
+ listener .onFailure (new IllegalStateException ("enabled must not be null!" ));
596
+ return ;
597
+ } else {
598
+ userInfos .put (username , new ReservedUserInfo (password .toCharArray (), enabled , false ));
599
+ }
571
600
}
601
+ listener .onResponse (userInfos );
572
602
}
573
- listener .onResponse (userInfos );
574
- }
575
603
576
- @ Override
577
- public void onFailure (Exception e ) {
578
- if (e instanceof IndexNotFoundException ) {
579
- logger .trace ("could not retrieve built in users since security index does not exist" , e );
580
- listener .onResponse (Collections .emptyMap ());
581
- } else {
582
- logger .error ("failed to retrieve built in users" , e );
583
- listener .onFailure (e );
604
+ @ Override
605
+ public void onFailure (Exception e ) {
606
+ if (e instanceof IndexNotFoundException ) {
607
+ logger .trace ("could not retrieve built in users since security index does not exist" , e );
608
+ listener .onResponse (Collections .emptyMap ());
609
+ } else {
610
+ logger .error ("failed to retrieve built in users" , e );
611
+ listener .onFailure (e );
612
+ }
584
613
}
585
- }
586
- }, client :: search ));
614
+ }, client :: search ));
615
+ }
587
616
}
588
617
589
618
private <Response > void clearRealmCache (String username , ActionListener <Response > listener , Response response ) {
0 commit comments