From 13ad6015c48a0033123269f991812e75b16c0635 Mon Sep 17 00:00:00 2001 From: Shay Banon Date: Thu, 5 Jan 2012 23:24:47 +0200 Subject: [PATCH] associate a rest status with a cluster block, and derive the status based on the blocks a failure has --- .../transport/NoNodeAvailableException.java | 8 ++++++-- .../cluster/block/ClusterBlock.java | 12 +++++++++++- .../cluster/block/ClusterBlockException.java | 12 ++++++++++-- .../cluster/block/ClusterBlocks.java | 16 ++++++++++++++-- .../cluster/metadata/IndexMetaData.java | 3 ++- .../elasticsearch/cluster/metadata/MetaData.java | 3 ++- .../metadata/MetaDataStateIndexService.java | 3 ++- .../org/elasticsearch/discovery/Discovery.java | 3 ++- .../elasticsearch/gateway/GatewayService.java | 3 ++- 9 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/elasticsearch/client/transport/NoNodeAvailableException.java b/src/main/java/org/elasticsearch/client/transport/NoNodeAvailableException.java index 34c49d097a6..e0af1f7bb7e 100644 --- a/src/main/java/org/elasticsearch/client/transport/NoNodeAvailableException.java +++ b/src/main/java/org/elasticsearch/client/transport/NoNodeAvailableException.java @@ -20,15 +20,19 @@ package org.elasticsearch.client.transport; import org.elasticsearch.ElasticSearchException; +import org.elasticsearch.rest.RestStatus; /** * An exception indicating no node is available to perform the operation. - * - * */ public class NoNodeAvailableException extends ElasticSearchException { public NoNodeAvailableException() { super("No node available"); } + + @Override + public RestStatus status() { + return RestStatus.SERVICE_UNAVAILABLE; + } } diff --git a/src/main/java/org/elasticsearch/cluster/block/ClusterBlock.java b/src/main/java/org/elasticsearch/cluster/block/ClusterBlock.java index ef4eb4ecfb0..4de7a9588b5 100644 --- a/src/main/java/org/elasticsearch/cluster/block/ClusterBlock.java +++ b/src/main/java/org/elasticsearch/cluster/block/ClusterBlock.java @@ -24,6 +24,7 @@ import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.Streamable; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.rest.RestStatus; import java.io.IOException; import java.io.Serializable; @@ -43,14 +44,17 @@ public class ClusterBlock implements Serializable, Streamable, ToXContent { private boolean disableStatePersistence = false; + private RestStatus status; + ClusterBlock() { } - public ClusterBlock(int id, String description, boolean retryable, boolean disableStatePersistence, ClusterBlockLevel... levels) { + public ClusterBlock(int id, String description, boolean retryable, boolean disableStatePersistence, RestStatus status, ClusterBlockLevel... levels) { this.id = id; this.description = description; this.retryable = retryable; this.disableStatePersistence = disableStatePersistence; + this.status = status; this.levels = levels; } @@ -62,6 +66,10 @@ public class ClusterBlock implements Serializable, Streamable, ToXContent { return this.description; } + public RestStatus status() { + return this.status; + } + public ClusterBlockLevel[] levels() { return this.levels; } @@ -123,6 +131,7 @@ public class ClusterBlock implements Serializable, Streamable, ToXContent { } retryable = in.readBoolean(); disableStatePersistence = in.readBoolean(); + status = RestStatus.readFrom(in); } @Override @@ -135,6 +144,7 @@ public class ClusterBlock implements Serializable, Streamable, ToXContent { } out.writeBoolean(retryable); out.writeBoolean(disableStatePersistence); + RestStatus.writeTo(out, status); } public String toString() { diff --git a/src/main/java/org/elasticsearch/cluster/block/ClusterBlockException.java b/src/main/java/org/elasticsearch/cluster/block/ClusterBlockException.java index 0151360c5f8..0ed5493c3c2 100644 --- a/src/main/java/org/elasticsearch/cluster/block/ClusterBlockException.java +++ b/src/main/java/org/elasticsearch/cluster/block/ClusterBlockException.java @@ -51,13 +51,21 @@ public class ClusterBlockException extends ElasticSearchException { private static String buildMessage(ImmutableSet blocks) { StringBuilder sb = new StringBuilder("blocked by: "); for (ClusterBlock block : blocks) { - sb.append("[").append(block.id()).append("/").append(block.description()).append("];"); + sb.append("[").append(block.status()).append("/").append(block.id()).append("/").append(block.description()).append("];"); } return sb.toString(); } @Override public RestStatus status() { - return RestStatus.SERVICE_UNAVAILABLE; + RestStatus status = null; + for (ClusterBlock block : blocks) { + if (status == null) { + status = block.status(); + } else if (status.getStatus() < block.status().getStatus()) { + status = block.status(); + } + } + return status; } } diff --git a/src/main/java/org/elasticsearch/cluster/block/ClusterBlocks.java b/src/main/java/org/elasticsearch/cluster/block/ClusterBlocks.java index 2189ff28d64..c71e9398675 100644 --- a/src/main/java/org/elasticsearch/cluster/block/ClusterBlocks.java +++ b/src/main/java/org/elasticsearch/cluster/block/ClusterBlocks.java @@ -32,8 +32,6 @@ import java.util.Set; /** * Represents current cluster level blocks to block dirty operations done against the cluster. - * - * */ public class ClusterBlocks { @@ -111,6 +109,20 @@ public class ClusterBlocks { return indicesBlocks.containsKey(index) && indicesBlocks.get(index).contains(block); } + public void globalBlockedRaiseException(ClusterBlockLevel level) throws ClusterBlockException { + ClusterBlockException blockException = globalBlockedException(level); + if (blockException != null) { + throw blockException; + } + } + + public ClusterBlockException globalBlockedException(ClusterBlockLevel level) { + if (global(level).isEmpty()) { + return null; + } + return new ClusterBlockException(ImmutableSet.copyOf(global(level))); + } + public void indexBlockedRaiseException(ClusterBlockLevel level, String index) throws ClusterBlockException { ClusterBlockException blockException = indexBlockedException(level, index); if (blockException != null) { diff --git a/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java b/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java index cf01f742fd6..46a77fe43ec 100644 --- a/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java +++ b/src/main/java/org/elasticsearch/cluster/metadata/IndexMetaData.java @@ -37,6 +37,7 @@ import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentParser; +import org.elasticsearch.rest.RestStatus; import java.io.IOException; import java.util.Arrays; @@ -56,7 +57,7 @@ public class IndexMetaData { .add(IndexMetaData.SETTING_READ_ONLY) .build(); - public static final ClusterBlock INDEX_READ_ONLY_BLOCK = new ClusterBlock(5, "index read-only (api)", false, false, ClusterBlockLevel.WRITE, ClusterBlockLevel.METADATA); + public static final ClusterBlock INDEX_READ_ONLY_BLOCK = new ClusterBlock(5, "index read-only (api)", false, false, RestStatus.FORBIDDEN, ClusterBlockLevel.WRITE, ClusterBlockLevel.METADATA); public static ImmutableSet dynamicSettings() { return dynamicSettings; diff --git a/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java b/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java index cdc6728ec93..16ff991aacd 100644 --- a/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java +++ b/src/main/java/org/elasticsearch/cluster/metadata/MetaData.java @@ -35,6 +35,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.*; import org.elasticsearch.index.Index; import org.elasticsearch.indices.IndexMissingException; +import org.elasticsearch.rest.RestStatus; import java.io.IOException; import java.util.*; @@ -51,7 +52,7 @@ import static org.elasticsearch.common.settings.ImmutableSettings.*; public class MetaData implements Iterable { public static final String SETTING_READ_ONLY = "cluster.blocks.read_only"; - public static final ClusterBlock CLUSTER_READ_ONLY_BLOCK = new ClusterBlock(6, "cluster read-only (api)", false, false, ClusterBlockLevel.WRITE, ClusterBlockLevel.METADATA); + public static final ClusterBlock CLUSTER_READ_ONLY_BLOCK = new ClusterBlock(6, "cluster read-only (api)", false, false, RestStatus.FORBIDDEN, ClusterBlockLevel.WRITE, ClusterBlockLevel.METADATA); private static ImmutableSet dynamicSettings = ImmutableSet.builder() .add(SETTING_READ_ONLY) diff --git a/src/main/java/org/elasticsearch/cluster/metadata/MetaDataStateIndexService.java b/src/main/java/org/elasticsearch/cluster/metadata/MetaDataStateIndexService.java index 5a30e233768..6a6d89996f0 100644 --- a/src/main/java/org/elasticsearch/cluster/metadata/MetaDataStateIndexService.java +++ b/src/main/java/org/elasticsearch/cluster/metadata/MetaDataStateIndexService.java @@ -35,6 +35,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.Index; import org.elasticsearch.indices.IndexMissingException; +import org.elasticsearch.rest.RestStatus; import static org.elasticsearch.cluster.ClusterState.newClusterStateBuilder; @@ -43,7 +44,7 @@ import static org.elasticsearch.cluster.ClusterState.newClusterStateBuilder; */ public class MetaDataStateIndexService extends AbstractComponent { - public static final ClusterBlock INDEX_CLOSED_BLOCK = new ClusterBlock(4, "index closed", false, false, ClusterBlockLevel.READ_WRITE); + public static final ClusterBlock INDEX_CLOSED_BLOCK = new ClusterBlock(4, "index closed", false, false, RestStatus.FORBIDDEN, ClusterBlockLevel.READ_WRITE); private final ClusterService clusterService; diff --git a/src/main/java/org/elasticsearch/discovery/Discovery.java b/src/main/java/org/elasticsearch/discovery/Discovery.java index c702d98c4b1..373b7e79bea 100644 --- a/src/main/java/org/elasticsearch/discovery/Discovery.java +++ b/src/main/java/org/elasticsearch/discovery/Discovery.java @@ -26,6 +26,7 @@ import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.component.LifecycleComponent; import org.elasticsearch.common.inject.internal.Nullable; import org.elasticsearch.node.service.NodeService; +import org.elasticsearch.rest.RestStatus; /** * A pluggable module allowing to implement discovery of other nodes, publishing of the cluster @@ -34,7 +35,7 @@ import org.elasticsearch.node.service.NodeService; */ public interface Discovery extends LifecycleComponent { - final ClusterBlock NO_MASTER_BLOCK = new ClusterBlock(2, "no master", true, true, ClusterBlockLevel.ALL); + final ClusterBlock NO_MASTER_BLOCK = new ClusterBlock(2, "no master", true, true, RestStatus.SERVICE_UNAVAILABLE, ClusterBlockLevel.ALL); DiscoveryNode localNode(); diff --git a/src/main/java/org/elasticsearch/gateway/GatewayService.java b/src/main/java/org/elasticsearch/gateway/GatewayService.java index 47683331930..b415cc8d33e 100644 --- a/src/main/java/org/elasticsearch/gateway/GatewayService.java +++ b/src/main/java/org/elasticsearch/gateway/GatewayService.java @@ -39,6 +39,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.discovery.Discovery; import org.elasticsearch.discovery.DiscoveryService; +import org.elasticsearch.rest.RestStatus; import org.elasticsearch.threadpool.ThreadPool; import java.util.Map; @@ -53,7 +54,7 @@ import static org.elasticsearch.cluster.metadata.MetaData.newMetaDataBuilder; */ public class GatewayService extends AbstractLifecycleComponent implements ClusterStateListener { - public static final ClusterBlock STATE_NOT_RECOVERED_BLOCK = new ClusterBlock(1, "state not recovered / initialized", true, true, ClusterBlockLevel.ALL); + public static final ClusterBlock STATE_NOT_RECOVERED_BLOCK = new ClusterBlock(1, "state not recovered / initialized", true, true, RestStatus.SERVICE_UNAVAILABLE, ClusterBlockLevel.ALL); private final Gateway gateway;