org.elasticsearch.cluster.block.ClusterBlocks Maven / Gradle / Ivy
The newest version!
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.cluster.block;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.elasticsearch.cluster.AbstractDiffable;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.MetaDataIndexStateService;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.rest.RestStatus;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
/**
* Represents current cluster level blocks to block dirty operations done against the cluster.
*/
public class ClusterBlocks extends AbstractDiffable {
public static final ClusterBlocks EMPTY_CLUSTER_BLOCK = new ClusterBlocks(ImmutableSet.of(), ImmutableMap.>of());
public static final ClusterBlocks PROTO = EMPTY_CLUSTER_BLOCK;
private final ImmutableSet global;
private final ImmutableMap> indicesBlocks;
private final ImmutableLevelHolder[] levelHolders;
ClusterBlocks(ImmutableSet global, ImmutableMap> indicesBlocks) {
this.global = global;
this.indicesBlocks = indicesBlocks;
levelHolders = new ImmutableLevelHolder[ClusterBlockLevel.values().length];
for (ClusterBlockLevel level : ClusterBlockLevel.values()) {
ImmutableSet.Builder globalBuilder = ImmutableSet.builder();
for (ClusterBlock block : global) {
if (block.contains(level)) {
globalBuilder.add(block);
}
}
ImmutableMap.Builder> indicesBuilder = ImmutableMap.builder();
for (Map.Entry> entry : indicesBlocks.entrySet()) {
ImmutableSet.Builder indexBuilder = ImmutableSet.builder();
for (ClusterBlock block : entry.getValue()) {
if (block.contains(level)) {
indexBuilder.add(block);
}
}
indicesBuilder.put(entry.getKey(), indexBuilder.build());
}
levelHolders[level.id()] = new ImmutableLevelHolder(globalBuilder.build(), indicesBuilder.build());
}
}
public ImmutableSet global() {
return global;
}
public ImmutableMap> indices() {
return indicesBlocks;
}
public ImmutableSet global(ClusterBlockLevel level) {
return levelHolders[level.id()].global();
}
public ImmutableMap> indices(ClusterBlockLevel level) {
return levelHolders[level.id()].indices();
}
/**
* Returns true if one of the global blocks as its disable state persistence flag set.
*/
public boolean disableStatePersistence() {
for (ClusterBlock clusterBlock : global) {
if (clusterBlock.disableStatePersistence()) {
return true;
}
}
return false;
}
public boolean hasGlobalBlock(ClusterBlock block) {
return global.contains(block);
}
public boolean hasGlobalBlock(int blockId) {
for (ClusterBlock clusterBlock : global) {
if (clusterBlock.id() == blockId) {
return true;
}
}
return false;
}
public boolean hasGlobalBlock(ClusterBlockLevel level) {
return global(level).size() > 0;
}
/**
* Is there a global block with the provided status?
*/
public boolean hasGlobalBlock(RestStatus status) {
for (ClusterBlock clusterBlock : global) {
if (clusterBlock.status().equals(status)) {
return true;
}
}
return false;
}
public boolean hasIndexBlock(String index, ClusterBlock 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;
}
}
private boolean globalBlocked(ClusterBlockLevel level) {
return global(level).isEmpty() == false;
}
public ClusterBlockException globalBlockedException(ClusterBlockLevel level) {
if (globalBlocked(level) == false) {
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) {
throw blockException;
}
}
public ClusterBlockException indexBlockedException(ClusterBlockLevel level, String index) {
if (!indexBlocked(level, index)) {
return null;
}
ImmutableSet.Builder builder = ImmutableSet.builder();
builder.addAll(global(level));
ImmutableSet indexBlocks = indices(level).get(index);
if (indexBlocks != null) {
builder.addAll(indexBlocks);
}
return new ClusterBlockException(builder.build());
}
public boolean indexBlocked(ClusterBlockLevel level, String index) {
if (globalBlocked(level)) {
return true;
}
ImmutableSet indexBlocks = indices(level).get(index);
if (indexBlocks != null && !indexBlocks.isEmpty()) {
return true;
}
return false;
}
public ClusterBlockException indicesBlockedException(ClusterBlockLevel level, String[] indices) {
boolean indexIsBlocked = false;
for (String index : indices) {
if (indexBlocked(level, index)) {
indexIsBlocked = true;
}
}
if (globalBlocked(level) == false && indexIsBlocked == false) {
return null;
}
ImmutableSet.Builder builder = ImmutableSet.builder();
builder.addAll(global(level));
for (String index : indices) {
ImmutableSet indexBlocks = indices(level).get(index);
if (indexBlocks != null) {
builder.addAll(indexBlocks);
}
}
return new ClusterBlockException(builder.build());
}
public String prettyPrint() {
if (global.isEmpty() && indices().isEmpty()) {
return "";
}
StringBuilder sb = new StringBuilder();
sb.append("blocks: \n");
if (global.isEmpty() == false) {
sb.append(" _global_:\n");
for (ClusterBlock block : global) {
sb.append(" ").append(block);
}
}
for (Map.Entry> entry : indicesBlocks.entrySet()) {
sb.append(" ").append(entry.getKey()).append(":\n");
for (ClusterBlock block : entry.getValue()) {
sb.append(" ").append(block);
}
}
sb.append("\n");
return sb.toString();
}
@Override
public void writeTo(StreamOutput out) throws IOException {
writeBlockSet(global, out);
out.writeVInt(indicesBlocks.size());
for (Map.Entry> entry : indicesBlocks.entrySet()) {
out.writeString(entry.getKey());
writeBlockSet(entry.getValue(), out);
}
}
private static void writeBlockSet(ImmutableSet blocks, StreamOutput out) throws IOException {
out.writeVInt(blocks.size());
for (ClusterBlock block : blocks) {
block.writeTo(out);
}
}
@Override
public ClusterBlocks readFrom(StreamInput in) throws IOException {
ImmutableSet global = readBlockSet(in);
ImmutableMap.Builder> indicesBuilder = ImmutableMap.builder();
int size = in.readVInt();
for (int j = 0; j < size; j++) {
indicesBuilder.put(in.readString().intern(), readBlockSet(in));
}
return new ClusterBlocks(global, indicesBuilder.build());
}
private static ImmutableSet readBlockSet(StreamInput in) throws IOException {
ImmutableSet.Builder builder = ImmutableSet.builder();
int size = in.readVInt();
for (int i = 0; i < size; i++) {
builder.add(ClusterBlock.readClusterBlock(in));
}
return builder.build();
}
static class ImmutableLevelHolder {
static final ImmutableLevelHolder EMPTY = new ImmutableLevelHolder(ImmutableSet.of(), ImmutableMap.>of());
private final ImmutableSet global;
private final ImmutableMap> indices;
ImmutableLevelHolder(ImmutableSet global, ImmutableMap> indices) {
this.global = global;
this.indices = indices;
}
public ImmutableSet global() {
return global;
}
public ImmutableMap> indices() {
return indices;
}
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private Set global = Sets.newHashSet();
private Map> indices = Maps.newHashMap();
public Builder() {
}
public Builder blocks(ClusterBlocks blocks) {
global.addAll(blocks.global());
for (Map.Entry> entry : blocks.indices().entrySet()) {
if (!indices.containsKey(entry.getKey())) {
indices.put(entry.getKey(), Sets.newHashSet());
}
indices.get(entry.getKey()).addAll(entry.getValue());
}
return this;
}
public Builder addBlocks(IndexMetaData indexMetaData) {
if (indexMetaData.getState() == IndexMetaData.State.CLOSE) {
addIndexBlock(indexMetaData.getIndex(), MetaDataIndexStateService.INDEX_CLOSED_BLOCK);
}
if (indexMetaData.getSettings().getAsBoolean(IndexMetaData.SETTING_READ_ONLY, false)) {
addIndexBlock(indexMetaData.getIndex(), IndexMetaData.INDEX_READ_ONLY_BLOCK);
}
if (indexMetaData.getSettings().getAsBoolean(IndexMetaData.SETTING_BLOCKS_READ, false)) {
addIndexBlock(indexMetaData.getIndex(), IndexMetaData.INDEX_READ_BLOCK);
}
if (indexMetaData.getSettings().getAsBoolean(IndexMetaData.SETTING_BLOCKS_WRITE, false)) {
addIndexBlock(indexMetaData.getIndex(), IndexMetaData.INDEX_WRITE_BLOCK);
}
if (indexMetaData.getSettings().getAsBoolean(IndexMetaData.SETTING_BLOCKS_METADATA, false)) {
addIndexBlock(indexMetaData.getIndex(), IndexMetaData.INDEX_METADATA_BLOCK);
}
return this;
}
public Builder updateBlocks(IndexMetaData indexMetaData) {
removeIndexBlock(indexMetaData.getIndex(), MetaDataIndexStateService.INDEX_CLOSED_BLOCK);
removeIndexBlock(indexMetaData.getIndex(), IndexMetaData.INDEX_READ_ONLY_BLOCK);
removeIndexBlock(indexMetaData.getIndex(), IndexMetaData.INDEX_READ_BLOCK);
removeIndexBlock(indexMetaData.getIndex(), IndexMetaData.INDEX_WRITE_BLOCK);
removeIndexBlock(indexMetaData.getIndex(), IndexMetaData.INDEX_METADATA_BLOCK);
return addBlocks(indexMetaData);
}
public Builder addGlobalBlock(ClusterBlock block) {
global.add(block);
return this;
}
public Builder removeGlobalBlock(ClusterBlock block) {
global.remove(block);
return this;
}
public Builder addIndexBlock(String index, ClusterBlock block) {
if (!indices.containsKey(index)) {
indices.put(index, Sets.newHashSet());
}
indices.get(index).add(block);
return this;
}
public Builder removeIndexBlocks(String index) {
if (!indices.containsKey(index)) {
return this;
}
indices.remove(index);
return this;
}
public Builder removeIndexBlock(String index, ClusterBlock block) {
if (!indices.containsKey(index)) {
return this;
}
indices.get(index).remove(block);
if (indices.get(index).isEmpty()) {
indices.remove(index);
}
return this;
}
public ClusterBlocks build() {
ImmutableMap.Builder> indicesBuilder = ImmutableMap.builder();
for (Map.Entry> entry : indices.entrySet()) {
indicesBuilder.put(entry.getKey(), ImmutableSet.copyOf(entry.getValue()));
}
return new ClusterBlocks(ImmutableSet.copyOf(global), indicesBuilder.build());
}
public static ClusterBlocks readClusterBlocks(StreamInput in) throws IOException {
return PROTO.readFrom(in);
}
}
}