Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ static TransportVersion def(int id) {
public static final TransportVersion SEARCH_LOAD_PER_INDEX_STATS = def(9_095_0_00);
public static final TransportVersion HEAP_USAGE_IN_CLUSTER_INFO = def(9_096_0_00);
public static final TransportVersion NONE_CHUNKING_STRATEGY = def(9_097_0_00);
public static final TransportVersion PROJECT_DELETION_GLOBAL_BLOCK = def(9_098_0_00);

/*
* STOP! READ THIS FIRST! No, really,
Expand Down
45 changes: 33 additions & 12 deletions server/src/main/java/org/elasticsearch/cluster/ClusterState.java
Original file line number Diff line number Diff line change
Expand Up @@ -873,21 +873,24 @@ private Iterator<ToXContent> blocksXContentMultiProjects() {
}
builder.endObject();
}
if (blocks().noIndexBlockAllProjects() == false) {
if (blocks().noProjectHasAProjectBlock() == false) {
builder.startArray("projects");
}
return builder;
};
final ToXContent after = (builder, params) -> {
if (blocks().noIndexBlockAllProjects() == false) {
if (blocks().noProjectHasAProjectBlock() == false) {
builder.endArray();
}
return builder.endObject();
};
return chunkedSection(
true,
before,
Iterators.map(metadata().projects().keySet().iterator(), projectId -> new Tuple<>(projectId, blocks().indices(projectId))),
Iterators.map(
metadata().projects().keySet().iterator(),
projectId -> new Tuple<>(projectId, blocks().projectBlocks(projectId))
),
ClusterState::projectBlocksXContent,
after
);
Expand Down Expand Up @@ -929,19 +932,37 @@ private Iterator<ToXContent> blocksXContentSingleProject(ProjectId singleProject
);
}

private static Iterator<ToXContent> projectBlocksXContent(Tuple<ProjectId, Map<String, Set<ClusterBlock>>> entry) {
return chunkedSection(
entry.v2().isEmpty() == false,
(builder, params) -> builder.startObject().field("id", entry.v1()).startObject("indices"),
entry.v2().entrySet().iterator(),
e -> Iterators.single((builder, params) -> {
builder.startObject(e.getKey());
for (ClusterBlock block : e.getValue()) {
private static Iterator<ToXContent> projectBlocksXContent(Tuple<ProjectId, ClusterBlocks.ProjectBlocks> entry) {
final var projectId = entry.v1();
final var projectBlocks = entry.v2();
if (projectBlocks.isEmpty()) {
return Collections.emptyIterator();
}
return Iterators.concat(
Iterators.single((builder, params) -> builder.startObject().field("id", projectId)),
// write project global blocks in one chunk
projectBlocks.projectGlobals().isEmpty() ? Collections.emptyIterator() : Iterators.single((builder, params) -> {
builder.startObject("project_globals");
for (ClusterBlock block : projectBlocks.projectGlobals()) {
block.toXContent(builder, params);
}
return builder.endObject();
}),
(builder, params) -> builder.endObject().endObject()
// write index blocks for the project
projectBlocks.indices().isEmpty()
? Collections.emptyIterator()
: Iterators.concat(
Iterators.single((builder, params) -> builder.startObject("indices")),
Iterators.flatMap(projectBlocks.indices().entrySet().iterator(), indexBlocks -> Iterators.single((builder, params) -> {
builder.startObject(indexBlocks.getKey());
for (ClusterBlock block : indexBlocks.getValue()) {
block.toXContent(builder, params);
}
return builder.endObject();
})),
Iterators.single((builder, params) -> builder.endObject())
),
Iterators.single((builder, params) -> builder.endObject())
);
}

Expand Down
Loading