4545import org .elasticsearch .common .xcontent .XContentType ;
4646import org .elasticsearch .common .xcontent .json .JsonXContent ;
4747import org .elasticsearch .gateway .GatewayService ;
48+ import org .elasticsearch .index .Index ;
4849import org .elasticsearch .index .IndexNotFoundException ;
4950import org .elasticsearch .index .mapper .MapperService ;
51+ import org .elasticsearch .indices .IndexClosedException ;
5052import org .elasticsearch .rest .RestStatus ;
5153import org .elasticsearch .xpack .core .security .index .RestrictedIndicesNames ;
5254import org .elasticsearch .xpack .core .template .TemplateUtils ;
@@ -173,9 +175,11 @@ public ElasticsearchException getUnavailableReason() {
173175 throw new IllegalStateException ("caller must make sure to use a frozen state and check indexAvailable" );
174176 }
175177
176- if (localState .indexExists ()) {
178+ if (localState .indexState == IndexMetaData .State .CLOSE ) {
179+ return new IndexClosedException (new Index (localState .concreteIndexName , ClusterState .UNKNOWN_UUID ));
180+ } else if (localState .indexExists ()) {
177181 return new UnavailableShardsException (null ,
178- "at least one primary shard for the index [" + localState .concreteIndexName + "] is unavailable" );
182+ "at least one primary shard for the index [" + localState .concreteIndexName + "] is unavailable" );
179183 } else {
180184 return new IndexNotFoundException (localState .concreteIndexName );
181185 }
@@ -206,11 +210,24 @@ public void clusterChanged(ClusterChangedEvent event) {
206210 final boolean indexAvailable = checkIndexAvailable (event .state ());
207211 final boolean mappingIsUpToDate = indexMetaData == null || checkIndexMappingUpToDate (event .state ());
208212 final Version mappingVersion = oldestIndexMappingVersion (event .state ());
209- final ClusterHealthStatus indexStatus = indexMetaData == null ? null :
210- new ClusterIndexHealth (indexMetaData , event .state ().getRoutingTable ().index (indexMetaData .getIndex ())).getStatus ();
211213 final String concreteIndexName = indexMetaData == null ? internalIndexName : indexMetaData .getIndex ().getName ();
214+ final ClusterHealthStatus indexHealth ;
215+ final IndexMetaData .State indexState ;
216+ if (indexMetaData == null ) {
217+ // Index does not exist
218+ indexState = null ;
219+ indexHealth = null ;
220+ } else if (indexMetaData .getState () == IndexMetaData .State .CLOSE ) {
221+ indexState = IndexMetaData .State .CLOSE ;
222+ indexHealth = null ;
223+ logger .warn ("Index [{}] is closed. This is likely to prevent security from functioning correctly" , concreteIndexName );
224+ } else {
225+ indexState = IndexMetaData .State .OPEN ;
226+ final IndexRoutingTable routingTable = event .state ().getRoutingTable ().index (indexMetaData .getIndex ());
227+ indexHealth = new ClusterIndexHealth (indexMetaData , routingTable ).getStatus ();
228+ }
212229 final State newState = new State (creationTime , isIndexUpToDate , indexAvailable , mappingIsUpToDate , mappingVersion ,
213- concreteIndexName , indexStatus );
230+ concreteIndexName , indexHealth , indexState );
214231 this .indexState = newState ;
215232
216233 if (newState .equals (previousState ) == false ) {
@@ -221,23 +238,21 @@ public void clusterChanged(ClusterChangedEvent event) {
221238 }
222239
223240 private boolean checkIndexAvailable (ClusterState state ) {
224- final IndexRoutingTable routingTable = getIndexRoutingTable (state );
225- if (routingTable != null && routingTable .allPrimaryShardsActive ()) {
226- return true ;
227- }
228- logger .debug ("Index [{}] is not yet active" , aliasName );
229- return false ;
230- }
231-
232- /**
233- * Returns the routing-table for this index, or <code>null</code> if the index does not exist.
234- */
235- private IndexRoutingTable getIndexRoutingTable (ClusterState clusterState ) {
236- IndexMetaData metaData = resolveConcreteIndex (aliasName , clusterState .metaData ());
241+ IndexMetaData metaData = resolveConcreteIndex (aliasName , state .metaData ());
237242 if (metaData == null ) {
238- return null ;
243+ logger .debug ("Index [{}] is not available - no metadata" , aliasName );
244+ return false ;
245+ }
246+ if (metaData .getState () == IndexMetaData .State .CLOSE ) {
247+ logger .warn ("Index [{}] is closed" , aliasName );
248+ return false ;
249+ }
250+ final IndexRoutingTable routingTable = state .routingTable ().index (metaData .getIndex ());
251+ if (routingTable == null || routingTable .allPrimaryShardsActive () == false ) {
252+ logger .debug ("Index [{}] is not yet active" , aliasName );
253+ return false ;
239254 } else {
240- return clusterState . routingTable (). index ( metaData . getIndex ()) ;
255+ return true ;
241256 }
242257 }
243258
@@ -402,15 +417,15 @@ public void onFailure(Exception e) {
402417 * Return true if the state moves from an unhealthy ("RED") index state to a healthy ("non-RED") state.
403418 */
404419 public static boolean isMoveFromRedToNonRed (State previousState , State currentState ) {
405- return (previousState .indexStatus == null || previousState .indexStatus == ClusterHealthStatus .RED )
406- && currentState .indexStatus != null && currentState .indexStatus != ClusterHealthStatus .RED ;
420+ return (previousState .indexHealth == null || previousState .indexHealth == ClusterHealthStatus .RED )
421+ && currentState .indexHealth != null && currentState .indexHealth != ClusterHealthStatus .RED ;
407422 }
408423
409424 /**
410425 * Return true if the state moves from the index existing to the index not existing.
411426 */
412427 public static boolean isIndexDeleted (State previousState , State currentState ) {
413- return previousState .indexStatus != null && currentState .indexStatus == null ;
428+ return previousState .indexHealth != null && currentState .indexHealth == null ;
414429 }
415430
416431 private static byte [] readTemplateAsBytes (String templateName ) {
@@ -440,24 +455,27 @@ private static Tuple<String, Settings> parseMappingAndSettingsFromTemplateBytes(
440455 * State of the security index.
441456 */
442457 public static class State {
443- public static final State UNRECOVERED_STATE = new State (null , false , false , false , null , null , null );
458+ public static final State UNRECOVERED_STATE = new State (null , false , false , false , null , null , null , null );
444459 public final Instant creationTime ;
445460 public final boolean isIndexUpToDate ;
446461 public final boolean indexAvailable ;
447462 public final boolean mappingUpToDate ;
448463 public final Version mappingVersion ;
449464 public final String concreteIndexName ;
450- public final ClusterHealthStatus indexStatus ;
465+ public final ClusterHealthStatus indexHealth ;
466+ public final IndexMetaData .State indexState ;
451467
452468 public State (Instant creationTime , boolean isIndexUpToDate , boolean indexAvailable ,
453- boolean mappingUpToDate , Version mappingVersion , String concreteIndexName , ClusterHealthStatus indexStatus ) {
469+ boolean mappingUpToDate , Version mappingVersion , String concreteIndexName , ClusterHealthStatus indexHealth ,
470+ IndexMetaData .State indexState ) {
454471 this .creationTime = creationTime ;
455472 this .isIndexUpToDate = isIndexUpToDate ;
456473 this .indexAvailable = indexAvailable ;
457474 this .mappingUpToDate = mappingUpToDate ;
458475 this .mappingVersion = mappingVersion ;
459476 this .concreteIndexName = concreteIndexName ;
460- this .indexStatus = indexStatus ;
477+ this .indexHealth = indexHealth ;
478+ this .indexState = indexState ;
461479 }
462480
463481 @ Override
@@ -471,7 +489,8 @@ public boolean equals(Object o) {
471489 mappingUpToDate == state .mappingUpToDate &&
472490 Objects .equals (mappingVersion , state .mappingVersion ) &&
473491 Objects .equals (concreteIndexName , state .concreteIndexName ) &&
474- indexStatus == state .indexStatus ;
492+ indexHealth == state .indexHealth &&
493+ indexState == state .indexState ;
475494 }
476495
477496 public boolean indexExists () {
@@ -481,7 +500,7 @@ public boolean indexExists() {
481500 @ Override
482501 public int hashCode () {
483502 return Objects .hash (creationTime , isIndexUpToDate , indexAvailable , mappingUpToDate , mappingVersion , concreteIndexName ,
484- indexStatus );
503+ indexHealth );
485504 }
486505 }
487506}
0 commit comments