associate a rest status with a cluster block, and derive the status based on the blocks a failure has

This commit is contained in:
Shay Banon 2012-01-05 23:24:47 +02:00
parent fcb96fdd1b
commit 13ad6015c4
9 changed files with 51 additions and 12 deletions

View File

@ -20,15 +20,19 @@
package org.elasticsearch.client.transport; package org.elasticsearch.client.transport;
import org.elasticsearch.ElasticSearchException; import org.elasticsearch.ElasticSearchException;
import org.elasticsearch.rest.RestStatus;
/** /**
* An exception indicating no node is available to perform the operation. * An exception indicating no node is available to perform the operation.
*
*
*/ */
public class NoNodeAvailableException extends ElasticSearchException { public class NoNodeAvailableException extends ElasticSearchException {
public NoNodeAvailableException() { public NoNodeAvailableException() {
super("No node available"); super("No node available");
} }
@Override
public RestStatus status() {
return RestStatus.SERVICE_UNAVAILABLE;
}
} }

View File

@ -24,6 +24,7 @@ import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Streamable; import org.elasticsearch.common.io.stream.Streamable;
import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.rest.RestStatus;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
@ -43,14 +44,17 @@ public class ClusterBlock implements Serializable, Streamable, ToXContent {
private boolean disableStatePersistence = false; private boolean disableStatePersistence = false;
private RestStatus status;
ClusterBlock() { 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.id = id;
this.description = description; this.description = description;
this.retryable = retryable; this.retryable = retryable;
this.disableStatePersistence = disableStatePersistence; this.disableStatePersistence = disableStatePersistence;
this.status = status;
this.levels = levels; this.levels = levels;
} }
@ -62,6 +66,10 @@ public class ClusterBlock implements Serializable, Streamable, ToXContent {
return this.description; return this.description;
} }
public RestStatus status() {
return this.status;
}
public ClusterBlockLevel[] levels() { public ClusterBlockLevel[] levels() {
return this.levels; return this.levels;
} }
@ -123,6 +131,7 @@ public class ClusterBlock implements Serializable, Streamable, ToXContent {
} }
retryable = in.readBoolean(); retryable = in.readBoolean();
disableStatePersistence = in.readBoolean(); disableStatePersistence = in.readBoolean();
status = RestStatus.readFrom(in);
} }
@Override @Override
@ -135,6 +144,7 @@ public class ClusterBlock implements Serializable, Streamable, ToXContent {
} }
out.writeBoolean(retryable); out.writeBoolean(retryable);
out.writeBoolean(disableStatePersistence); out.writeBoolean(disableStatePersistence);
RestStatus.writeTo(out, status);
} }
public String toString() { public String toString() {

View File

@ -51,13 +51,21 @@ public class ClusterBlockException extends ElasticSearchException {
private static String buildMessage(ImmutableSet<ClusterBlock> blocks) { private static String buildMessage(ImmutableSet<ClusterBlock> blocks) {
StringBuilder sb = new StringBuilder("blocked by: "); StringBuilder sb = new StringBuilder("blocked by: ");
for (ClusterBlock block : blocks) { 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(); return sb.toString();
} }
@Override @Override
public RestStatus status() { 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;
} }
} }

View File

@ -32,8 +32,6 @@ import java.util.Set;
/** /**
* Represents current cluster level blocks to block dirty operations done against the cluster. * Represents current cluster level blocks to block dirty operations done against the cluster.
*
*
*/ */
public class ClusterBlocks { public class ClusterBlocks {
@ -111,6 +109,20 @@ public class ClusterBlocks {
return indicesBlocks.containsKey(index) && indicesBlocks.get(index).contains(block); 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 { public void indexBlockedRaiseException(ClusterBlockLevel level, String index) throws ClusterBlockException {
ClusterBlockException blockException = indexBlockedException(level, index); ClusterBlockException blockException = indexBlockedException(level, index);
if (blockException != null) { if (blockException != null) {

View File

@ -37,6 +37,7 @@ import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.rest.RestStatus;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
@ -56,7 +57,7 @@ public class IndexMetaData {
.add(IndexMetaData.SETTING_READ_ONLY) .add(IndexMetaData.SETTING_READ_ONLY)
.build(); .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<String> dynamicSettings() { public static ImmutableSet<String> dynamicSettings() {
return dynamicSettings; return dynamicSettings;

View File

@ -35,6 +35,7 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.*; import org.elasticsearch.common.xcontent.*;
import org.elasticsearch.index.Index; import org.elasticsearch.index.Index;
import org.elasticsearch.indices.IndexMissingException; import org.elasticsearch.indices.IndexMissingException;
import org.elasticsearch.rest.RestStatus;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
@ -51,7 +52,7 @@ import static org.elasticsearch.common.settings.ImmutableSettings.*;
public class MetaData implements Iterable<IndexMetaData> { public class MetaData implements Iterable<IndexMetaData> {
public static final String SETTING_READ_ONLY = "cluster.blocks.read_only"; 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<String> dynamicSettings = ImmutableSet.<String>builder() private static ImmutableSet<String> dynamicSettings = ImmutableSet.<String>builder()
.add(SETTING_READ_ONLY) .add(SETTING_READ_ONLY)

View File

@ -35,6 +35,7 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.Index; import org.elasticsearch.index.Index;
import org.elasticsearch.indices.IndexMissingException; import org.elasticsearch.indices.IndexMissingException;
import org.elasticsearch.rest.RestStatus;
import static org.elasticsearch.cluster.ClusterState.newClusterStateBuilder; import static org.elasticsearch.cluster.ClusterState.newClusterStateBuilder;
@ -43,7 +44,7 @@ import static org.elasticsearch.cluster.ClusterState.newClusterStateBuilder;
*/ */
public class MetaDataStateIndexService extends AbstractComponent { 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; private final ClusterService clusterService;

View File

@ -26,6 +26,7 @@ import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.component.LifecycleComponent; import org.elasticsearch.common.component.LifecycleComponent;
import org.elasticsearch.common.inject.internal.Nullable; import org.elasticsearch.common.inject.internal.Nullable;
import org.elasticsearch.node.service.NodeService; 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 * 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<Discovery> { public interface Discovery extends LifecycleComponent<Discovery> {
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(); DiscoveryNode localNode();

View File

@ -39,6 +39,7 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.discovery.Discovery; import org.elasticsearch.discovery.Discovery;
import org.elasticsearch.discovery.DiscoveryService; import org.elasticsearch.discovery.DiscoveryService;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
import java.util.Map; import java.util.Map;
@ -53,7 +54,7 @@ import static org.elasticsearch.cluster.metadata.MetaData.newMetaDataBuilder;
*/ */
public class GatewayService extends AbstractLifecycleComponent<GatewayService> implements ClusterStateListener { public class GatewayService extends AbstractLifecycleComponent<GatewayService> 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; private final Gateway gateway;