|
@@ -683,11 +683,19 @@ public class Metadata implements Diffable<Metadata>, ChunkedToXContent {
|
|
|
|
|
|
@Override
|
|
|
public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params p) {
|
|
|
- XContentContext context = XContentContext.from(p);
|
|
|
+ final XContentContext context = XContentContext.from(p);
|
|
|
final Iterator<? extends ToXContent> start = context == XContentContext.API
|
|
|
? ChunkedToXContentHelper.startObject("metadata")
|
|
|
: Iterators.single((builder, params) -> builder.startObject("meta-data").field("version", version()));
|
|
|
|
|
|
+ final Iterator<? extends ToXContent> clusterCoordination = Iterators.single((builder, params) -> {
|
|
|
+ builder.field("cluster_uuid", clusterUUID);
|
|
|
+ builder.field("cluster_uuid_committed", clusterUUIDCommitted);
|
|
|
+ builder.startObject("cluster_coordination");
|
|
|
+ coordinationMetadata().toXContent(builder, params);
|
|
|
+ return builder.endObject();
|
|
|
+ });
|
|
|
+
|
|
|
final Iterator<? extends ToXContent> persistentSettings = context != XContentContext.API && persistentSettings().isEmpty() == false
|
|
|
? Iterators.single((builder, params) -> {
|
|
|
builder.startObject("settings");
|
|
@@ -696,89 +704,98 @@ public class Metadata implements Diffable<Metadata>, ChunkedToXContent {
|
|
|
})
|
|
|
: Collections.emptyIterator();
|
|
|
|
|
|
- // use a tree map so the order is deterministic
|
|
|
- Map<String, ReservedStateMetadata> clusterReservedState = new TreeMap<>(reservedStateMetadata);
|
|
|
-
|
|
|
@FixForMultiProject
|
|
|
// Need to revisit whether this should be a param or something else.
|
|
|
final boolean multiProject = p.paramAsBoolean("multi-project", false);
|
|
|
if (multiProject) {
|
|
|
- return Iterators.concat(start, Iterators.single((builder, params) -> {
|
|
|
- builder.field("cluster_uuid", clusterUUID);
|
|
|
- builder.field("cluster_uuid_committed", clusterUUIDCommitted);
|
|
|
- builder.startObject("cluster_coordination");
|
|
|
- coordinationMetadata().toXContent(builder, params);
|
|
|
- return builder.endObject();
|
|
|
- }),
|
|
|
- persistentSettings,
|
|
|
- ChunkedToXContentHelper.array(
|
|
|
- "projects",
|
|
|
- Iterators.flatMap(
|
|
|
- projectMetadata.entrySet().iterator(),
|
|
|
- e -> Iterators.concat(
|
|
|
- ChunkedToXContentHelper.startObject(),
|
|
|
- Iterators.single((builder, params) -> builder.field("id", e.getKey())),
|
|
|
- e.getValue().toXContentChunked(p),
|
|
|
- ChunkedToXContentHelper.endObject()
|
|
|
- )
|
|
|
- )
|
|
|
- ),
|
|
|
- Iterators.flatMap(
|
|
|
- customs.entrySet().iterator(),
|
|
|
- entry -> entry.getValue().context().contains(context)
|
|
|
- ? ChunkedToXContentHelper.object(entry.getKey(), entry.getValue().toXContentChunked(p))
|
|
|
- : Collections.emptyIterator()
|
|
|
- ),
|
|
|
- ChunkedToXContentHelper.object("reserved_state", reservedStateMetadata().values().iterator()),
|
|
|
- ChunkedToXContentHelper.endObject()
|
|
|
- );
|
|
|
+ return toXContentChunkedWithMultiProjectFormat(p, context, start, clusterCoordination, persistentSettings);
|
|
|
} else {
|
|
|
- if (projectMetadata.size() != 1) {
|
|
|
- throw new MultiProjectPendingException("There are multiple projects " + projectMetadata.keySet());
|
|
|
- }
|
|
|
- // Need to rethink what to do here. This might be right, but maybe not...
|
|
|
- @FixForMultiProject
|
|
|
- final ProjectMetadata project = projectMetadata.values().iterator().next();
|
|
|
-
|
|
|
- // need to combine reserved state together into a single block so we don't get duplicate keys
|
|
|
- // and not include it in the project xcontent output (through the lack of multi-project params)
|
|
|
- clusterReservedState.putAll(project.reservedStateMetadata());
|
|
|
-
|
|
|
- // Similarly, combine cluster and project persistent tasks and report them under a single key
|
|
|
- Iterator<ToXContent> customs = Iterators.flatMap(customs().entrySet().iterator(), entry -> {
|
|
|
- if (entry.getValue().context().contains(context)
|
|
|
- && ClusterPersistentTasksCustomMetadata.TYPE.equals(entry.getKey()) == false) {
|
|
|
- return ChunkedToXContentHelper.object(entry.getKey(), entry.getValue().toXContentChunked(p));
|
|
|
- } else {
|
|
|
- return Collections.emptyIterator();
|
|
|
- }
|
|
|
- });
|
|
|
- final var combinedTasks = PersistentTasksCustomMetadata.combine(
|
|
|
- ClusterPersistentTasksCustomMetadata.get(this),
|
|
|
- PersistentTasksCustomMetadata.get(project)
|
|
|
- );
|
|
|
- if (combinedTasks != null) {
|
|
|
- customs = Iterators.concat(
|
|
|
- customs,
|
|
|
- ChunkedToXContentHelper.object(PersistentTasksCustomMetadata.TYPE, combinedTasks.toXContentChunked(p))
|
|
|
- );
|
|
|
- }
|
|
|
+ return toXContentChunkedWithSingleProjectFormat(p, context, start, clusterCoordination, persistentSettings);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- final var iterators = Iterators.concat(start, Iterators.single((builder, params) -> {
|
|
|
- builder.field("cluster_uuid", clusterUUID);
|
|
|
- builder.field("cluster_uuid_committed", clusterUUIDCommitted);
|
|
|
- builder.startObject("cluster_coordination");
|
|
|
- coordinationMetadata().toXContent(builder, params);
|
|
|
- return builder.endObject();
|
|
|
- }),
|
|
|
- persistentSettings,
|
|
|
- project.toXContentChunked(p),
|
|
|
+ private Iterator<? extends ToXContent> toXContentChunkedWithMultiProjectFormat(
|
|
|
+ ToXContent.Params p,
|
|
|
+ XContentContext context,
|
|
|
+ Iterator<? extends ToXContent> start,
|
|
|
+ Iterator<? extends ToXContent> clusterCoordination,
|
|
|
+ Iterator<? extends ToXContent> persistentSettings
|
|
|
+ ) {
|
|
|
+ return Iterators.concat(
|
|
|
+ start,
|
|
|
+ clusterCoordination,
|
|
|
+ persistentSettings,
|
|
|
+ ChunkedToXContentHelper.array(
|
|
|
+ "projects",
|
|
|
+ Iterators.flatMap(
|
|
|
+ projectMetadata.entrySet().iterator(),
|
|
|
+ e -> Iterators.concat(
|
|
|
+ ChunkedToXContentHelper.startObject(),
|
|
|
+ Iterators.single((builder, params) -> builder.field("id", e.getKey())),
|
|
|
+ e.getValue().toXContentChunked(p),
|
|
|
+ ChunkedToXContentHelper.endObject()
|
|
|
+ )
|
|
|
+ )
|
|
|
+ ),
|
|
|
+ Iterators.flatMap(
|
|
|
+ customs.entrySet().iterator(),
|
|
|
+ entry -> entry.getValue().context().contains(context)
|
|
|
+ ? ChunkedToXContentHelper.object(entry.getKey(), entry.getValue().toXContentChunked(p))
|
|
|
+ : Collections.emptyIterator()
|
|
|
+ ),
|
|
|
+ ChunkedToXContentHelper.object("reserved_state", reservedStateMetadata().values().iterator()),
|
|
|
+ ChunkedToXContentHelper.endObject()
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ private Iterator<? extends ToXContent> toXContentChunkedWithSingleProjectFormat(
|
|
|
+ ToXContent.Params p,
|
|
|
+ XContentContext context,
|
|
|
+ Iterator<? extends ToXContent> start,
|
|
|
+ Iterator<? extends ToXContent> clusterCoordination,
|
|
|
+ Iterator<? extends ToXContent> persistentSettings
|
|
|
+ ) {
|
|
|
+ if (projectMetadata.size() != 1) {
|
|
|
+ throw new MultiProjectPendingException("There are multiple projects " + projectMetadata.keySet());
|
|
|
+ }
|
|
|
+ // Need to rethink what to do here. This might be right, but maybe not...
|
|
|
+ @FixForMultiProject
|
|
|
+ final ProjectMetadata project = projectMetadata.values().iterator().next();
|
|
|
+
|
|
|
+ // need to combine reserved state together into a single block so we don't get duplicate keys
|
|
|
+ // and not include it in the project xcontent output (through the lack of multi-project params)
|
|
|
+ // use a tree map so the order is deterministic
|
|
|
+ final Map<String, ReservedStateMetadata> clusterReservedState = new TreeMap<>(reservedStateMetadata);
|
|
|
+ clusterReservedState.putAll(project.reservedStateMetadata());
|
|
|
+
|
|
|
+ // Similarly, combine cluster and project persistent tasks and report them under a single key
|
|
|
+ Iterator<ToXContent> customs = Iterators.flatMap(customs().entrySet().iterator(), entry -> {
|
|
|
+ if (entry.getValue().context().contains(context) && ClusterPersistentTasksCustomMetadata.TYPE.equals(entry.getKey()) == false) {
|
|
|
+ return ChunkedToXContentHelper.object(entry.getKey(), entry.getValue().toXContentChunked(p));
|
|
|
+ } else {
|
|
|
+ return Collections.emptyIterator();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ final var combinedTasks = PersistentTasksCustomMetadata.combine(
|
|
|
+ ClusterPersistentTasksCustomMetadata.get(this),
|
|
|
+ PersistentTasksCustomMetadata.get(project)
|
|
|
+ );
|
|
|
+ if (combinedTasks != null) {
|
|
|
+ customs = Iterators.concat(
|
|
|
customs,
|
|
|
- ChunkedToXContentHelper.object("reserved_state", clusterReservedState.values().iterator()),
|
|
|
- ChunkedToXContentHelper.endObject()
|
|
|
+ ChunkedToXContentHelper.object(PersistentTasksCustomMetadata.TYPE, combinedTasks.toXContentChunked(p))
|
|
|
);
|
|
|
- return iterators;
|
|
|
}
|
|
|
+
|
|
|
+ return Iterators.concat(
|
|
|
+ start,
|
|
|
+ clusterCoordination,
|
|
|
+ persistentSettings,
|
|
|
+ project.toXContentChunked(p),
|
|
|
+ customs,
|
|
|
+ ChunkedToXContentHelper.object("reserved_state", clusterReservedState.values().iterator()),
|
|
|
+ ChunkedToXContentHelper.endObject()
|
|
|
+ );
|
|
|
}
|
|
|
|
|
|
private static final DiffableUtils.KeySerializer<ProjectId> PROJECT_ID_SERIALIZER = DiffableUtils.getWriteableKeySerializer(
|