Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.elasticsearch.cluster.metadata.Metadata;
import org.elasticsearch.cluster.metadata.MetadataIndexStateService;
import org.elasticsearch.cluster.metadata.ProjectId;
import org.elasticsearch.cluster.metadata.ProjectMetadata;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable;
Expand All @@ -43,7 +44,7 @@
public class ClusterBlocks implements Diffable<ClusterBlocks> {
private static final ClusterBlock[] EMPTY_BLOCKS_ARRAY = new ClusterBlock[0];

public static final ClusterBlocks EMPTY_CLUSTER_BLOCK = new ClusterBlocks(Set.of(), Map.of());
public static final ClusterBlocks EMPTY_CLUSTER_BLOCK = new ClusterBlocks(Set.of(), Map.of(), 0);

private final Set<ClusterBlock> global;

Expand All @@ -57,15 +58,17 @@ public class ClusterBlocks implements Diffable<ClusterBlocks> {
*/
// Package private for testing
final Map<ProjectId, ProjectBlocks> projectBlocksMap;
private final long projectsWithUnderDeletionBlockGeneration;

private final EnumMap<ClusterBlockLevel, ImmutableLevelHolder> levelHolders;

ClusterBlocks(Set<ClusterBlock> global, Map<ProjectId, ProjectBlocks> projectBlocksMap) {
ClusterBlocks(Set<ClusterBlock> global, Map<ProjectId, ProjectBlocks> projectBlocksMap, long projectsWithUnderDeletionBlockGeneration) {
this.global = global;
assert projectBlocksMap.values().stream().allMatch(projectBlocks -> projectBlocks.isEmpty() == false)
: "Map must not contain projects with empty blocks " + projectBlocksMap;
this.projectBlocksMap = projectBlocksMap;
this.levelHolders = generateLevelHolders(global, projectBlocksMap);
this.projectsWithUnderDeletionBlockGeneration = projectsWithUnderDeletionBlockGeneration;
}

public Set<ClusterBlock> global() {
Expand Down Expand Up @@ -165,6 +168,14 @@ public boolean hasGlobalBlock(ClusterBlock block) {
return global.contains(block);
}

public boolean hasProjectGlobalBlock(ProjectId projectId, ClusterBlock block) {
var projectBlocks = projectBlocksMap.get(projectId);
if (projectBlocks == null) {
return false;
}
return projectBlocks.projectGlobals().contains(block);
}

public boolean hasGlobalBlockWithId(final int blockId) {
for (ClusterBlock clusterBlock : global) {
if (clusterBlock.id() == blockId) {
Expand Down Expand Up @@ -493,7 +504,7 @@ && noProjectOrDefaultProjectOnly(projectBlocksMap)
&& projectBlocksMap.getOrDefault(Metadata.DEFAULT_PROJECT_ID, ProjectBlocks.EMPTY).indices().isEmpty()) {
return EMPTY_CLUSTER_BLOCK;
}
return new ClusterBlocks(global, projectBlocksMap);
return new ClusterBlocks(global, projectBlocksMap, 0 /*todo*/);
} else {
return readFromSingleProjectNode(in);
}
Expand All @@ -506,9 +517,9 @@ private static ClusterBlocks readFromSingleProjectNode(StreamInput in) throws IO
return EMPTY_CLUSTER_BLOCK;
}
if (indicesBlocks.isEmpty()) {
return new ClusterBlocks(global, Map.of());
return new ClusterBlocks(global, Map.of(), 0);
}
return new ClusterBlocks(global, Map.of(Metadata.DEFAULT_PROJECT_ID, new ProjectBlocks(indicesBlocks, Set.of())));
return new ClusterBlocks(global, Map.of(Metadata.DEFAULT_PROJECT_ID, new ProjectBlocks(indicesBlocks, Set.of())), 0);
}

private static Set<ClusterBlock> readBlockSet(StreamInput in) throws IOException {
Expand Down Expand Up @@ -602,6 +613,10 @@ public ClusterBlocks initializeProjects(Set<ProjectId> projectIds) {
}
}

public long projectsWithUnderDeletionBlockGeneration() {
return projectsWithUnderDeletionBlockGeneration;
}

public static Builder builder() {
return new Builder();
}
Expand All @@ -617,6 +632,8 @@ public static class Builder {

private final Set<ClusterBlock> global = new HashSet<>();
private final Map<ProjectId, ProjectBlocks> projects = new HashMap<>();
private long projectsWithUnderDeletionBlockGeneration = 0;
private boolean newProjectsWithUnderDeletionBlock = false;

public Builder() {}

Expand All @@ -636,6 +653,7 @@ public Builder blocks(ClusterBlocks blocks) {
projectBlocks.indices.get(entry.getKey()).addAll(entry.getValue());
}
}
this.projectsWithUnderDeletionBlockGeneration = blocks.projectsWithUnderDeletionBlockGeneration();
return this;
}

Expand Down Expand Up @@ -700,7 +718,10 @@ public Builder removeProject(ProjectId projectId) {

public Builder addProjectGlobalBlock(ProjectId projectId, ClusterBlock block) {
assert projectId.equals(ProjectId.DEFAULT) == false;
projects.computeIfAbsent(projectId, k -> emptyMutableProjectBlocks()).projectGlobal.add(block);
boolean added = projects.computeIfAbsent(projectId, k -> emptyMutableProjectBlocks()).projectGlobal.add(block);
if (newProjectsWithUnderDeletionBlock == false && block.id() == ProjectMetadata.PROJECT_UNDER_DELETION_BLOCK.id() && added) {
newProjectsWithUnderDeletionBlock = true;
}
return this;
}

Expand Down Expand Up @@ -812,7 +833,10 @@ && noProjectOrDefaultProjectOnly(projects)
);
}
}
return new ClusterBlocks(Set.copyOf(global), Map.copyOf(projectsBuilder));
long newProjectsWithUnderDeletionBlockGeneration = newProjectsWithUnderDeletionBlock
? projectsWithUnderDeletionBlockGeneration + 1
: projectsWithUnderDeletionBlockGeneration;
return new ClusterBlocks(Set.copyOf(global), Map.copyOf(projectsBuilder), newProjectsWithUnderDeletionBlockGeneration);
}
}
}