Skip to content

Commit 15343e4

Browse files
prdoylethecoop
andauthored
Backport ChunkedXContentBuilder to 8.16.0 (#114659)
* Create a fluent builder to help implement ChunkedToXContent (#112389) Rather than manually adding startObject/endObject, and having to line everything up manually, this handles the start/end for you. A few implementations are converted already. In the long run, I would like this to replace ChunkedXContentHelper. * Convert a few more implementations to ChunkedXContentBuilder (#113125) Remove the complex methods from ChunkedXContentHelper * Further conversions to ChunkedXContentBuilder (#114237) --------- Co-authored-by: Simon Cooper <[email protected]>
1 parent 42aa343 commit 15343e4

File tree

46 files changed

+920
-710
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+920
-710
lines changed

modules/ingest-geoip/src/main/java/org/elasticsearch/ingest/geoip/IngestGeoIpMetadata.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@
1515
import org.elasticsearch.cluster.DiffableUtils;
1616
import org.elasticsearch.cluster.NamedDiff;
1717
import org.elasticsearch.cluster.metadata.Metadata;
18-
import org.elasticsearch.common.collect.Iterators;
1918
import org.elasticsearch.common.io.stream.StreamInput;
2019
import org.elasticsearch.common.io.stream.StreamOutput;
21-
import org.elasticsearch.common.xcontent.ChunkedToXContentHelper;
20+
import org.elasticsearch.common.xcontent.ChunkedToXContent;
2221
import org.elasticsearch.ingest.geoip.direct.DatabaseConfigurationMetadata;
2322
import org.elasticsearch.xcontent.ConstructingObjectParser;
2423
import org.elasticsearch.xcontent.ParseField;
@@ -91,8 +90,8 @@ public static IngestGeoIpMetadata fromXContent(XContentParser parser) throws IOE
9190
}
9291

9392
@Override
94-
public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params ignored) {
95-
return Iterators.concat(ChunkedToXContentHelper.xContentValuesMap(DATABASES_FIELD.getPreferredName(), databases));
93+
public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params params) {
94+
return ChunkedToXContent.builder(params).xContentObjectFields(DATABASES_FIELD.getPreferredName(), databases);
9695
}
9796

9897
@Override

modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/SearchTemplateResponse.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
107107

108108
void innerToXContent(XContentBuilder builder, Params params) throws IOException {
109109
if (hasResponse()) {
110-
ChunkedToXContent.wrapAsToXContent(p -> response.innerToXContentChunked(p)).toXContent(builder, params);
110+
ChunkedToXContent.wrapAsToXContent(response::innerToXContentChunked).toXContent(builder, params);
111111
} else {
112112
// we can assume the template is always json as we convert it before compiling it
113113
try (InputStream stream = source.streamInput()) {

server/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/NodeStats.java

Lines changed: 36 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import org.elasticsearch.cluster.node.DiscoveryNodeRole;
1616
import org.elasticsearch.cluster.routing.allocation.DiskThresholdSettings;
1717
import org.elasticsearch.cluster.routing.allocation.NodeAllocationStats;
18-
import org.elasticsearch.common.collect.Iterators;
1918
import org.elasticsearch.common.io.stream.StreamInput;
2019
import org.elasticsearch.common.io.stream.StreamOutput;
2120
import org.elasticsearch.common.xcontent.ChunkedToXContent;
@@ -43,8 +42,6 @@
4342
import java.util.Map;
4443
import java.util.Objects;
4544

46-
import static org.elasticsearch.common.xcontent.ChunkedToXContentHelper.singleChunk;
47-
4845
/**
4946
* Node statistics (dynamic, changes depending on when created).
5047
*/
@@ -345,58 +342,46 @@ public void writeTo(StreamOutput out) throws IOException {
345342

346343
@Override
347344
public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params outerParams) {
348-
349-
return Iterators.concat(
350-
351-
singleChunk((builder, params) -> {
352-
builder.field("name", getNode().getName());
353-
builder.field("transport_address", getNode().getAddress().toString());
354-
builder.field("host", getNode().getHostName());
355-
builder.field("ip", getNode().getAddress());
356-
357-
builder.startArray("roles");
358-
for (DiscoveryNodeRole role : getNode().getRoles()) {
359-
builder.value(role.roleName());
360-
}
361-
builder.endArray();
362-
363-
if (getNode().getAttributes().isEmpty() == false) {
364-
builder.startObject("attributes");
365-
for (Map.Entry<String, String> attrEntry : getNode().getAttributes().entrySet()) {
366-
builder.field(attrEntry.getKey(), attrEntry.getValue());
367-
}
368-
builder.endObject();
345+
return ChunkedToXContent.builder(outerParams).append((builder, params) -> {
346+
builder.field("name", getNode().getName());
347+
builder.field("transport_address", getNode().getAddress().toString());
348+
builder.field("host", getNode().getHostName());
349+
builder.field("ip", getNode().getAddress());
350+
351+
builder.startArray("roles");
352+
for (DiscoveryNodeRole role : getNode().getRoles()) {
353+
builder.value(role.roleName());
354+
}
355+
builder.endArray();
356+
357+
if (getNode().getAttributes().isEmpty() == false) {
358+
builder.startObject("attributes");
359+
for (Map.Entry<String, String> attrEntry : getNode().getAttributes().entrySet()) {
360+
builder.field(attrEntry.getKey(), attrEntry.getValue());
369361
}
370-
371-
return builder;
372-
}),
373-
374-
ifPresent(getIndices()).toXContentChunked(outerParams),
375-
376-
singleChunk(
377-
(builder, p) -> builder.value(ifPresent(getOs()), p).value(ifPresent(getProcess()), p).value(ifPresent(getJvm()), p)
378-
),
379-
380-
ifPresent(getThreadPool()).toXContentChunked(outerParams),
381-
singleChunk(ifPresent(getFs())),
382-
ifPresent(getTransport()).toXContentChunked(outerParams),
383-
ifPresent(getHttp()).toXContentChunked(outerParams),
384-
singleChunk(ifPresent(getBreaker())),
385-
ifPresent(getScriptStats()).toXContentChunked(outerParams),
386-
singleChunk(ifPresent(getDiscoveryStats())),
387-
ifPresent(getIngestStats()).toXContentChunked(outerParams),
388-
singleChunk(ifPresent(getAdaptiveSelectionStats())),
389-
ifPresent(getScriptCacheStats()).toXContentChunked(outerParams),
390-
singleChunk(
362+
builder.endObject();
363+
}
364+
return builder;
365+
})
366+
367+
.appendIfPresent(getIndices())
368+
.append((builder, p) -> builder.value(ifPresent(getOs()), p).value(ifPresent(getProcess()), p).value(ifPresent(getJvm()), p))
369+
370+
.appendIfPresent(getThreadPool())
371+
.appendIfPresent(getFs())
372+
.appendIfPresent(getTransport())
373+
.appendIfPresent(getHttp())
374+
.appendIfPresent(getBreaker())
375+
.appendIfPresent(getScriptStats())
376+
.appendIfPresent(getDiscoveryStats())
377+
.appendIfPresent(getIngestStats())
378+
.appendIfPresent(getAdaptiveSelectionStats())
379+
.appendIfPresent(getScriptCacheStats())
380+
.append(
391381
(builder, p) -> builder.value(ifPresent(getIndexingPressureStats()), p)
392382
.value(ifPresent(getRepositoriesStats()), p)
393383
.value(ifPresent(getNodeAllocationStats()), p)
394-
)
395-
);
396-
}
397-
398-
private static ChunkedToXContent ifPresent(@Nullable ChunkedToXContent chunkedToXContent) {
399-
return Objects.requireNonNullElse(chunkedToXContent, ChunkedToXContent.EMPTY);
384+
);
400385
}
401386

402387
private static ToXContent ifPresent(@Nullable ToXContent toXContent) {

server/src/main/java/org/elasticsearch/action/admin/cluster/node/stats/NodesStatsResponse.java

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@
1414
import org.elasticsearch.action.support.nodes.BaseNodesXContentResponse;
1515
import org.elasticsearch.cluster.ClusterName;
1616
import org.elasticsearch.common.Strings;
17-
import org.elasticsearch.common.collect.Iterators;
1817
import org.elasticsearch.common.io.stream.StreamInput;
1918
import org.elasticsearch.common.io.stream.StreamOutput;
20-
import org.elasticsearch.common.xcontent.ChunkedToXContentHelper;
19+
import org.elasticsearch.common.xcontent.ChunkedToXContent;
2120
import org.elasticsearch.xcontent.ToXContent;
2221

2322
import java.io.IOException;
@@ -42,15 +41,12 @@ protected void writeNodesTo(StreamOutput out, List<NodeStats> nodes) throws IOEx
4241

4342
@Override
4443
protected Iterator<? extends ToXContent> xContentChunks(ToXContent.Params outerParams) {
45-
return Iterators.concat(
46-
ChunkedToXContentHelper.startObject("nodes"),
47-
Iterators.flatMap(getNodes().iterator(), nodeStats -> Iterators.concat(Iterators.single((builder, params) -> {
48-
builder.startObject(nodeStats.getNode().getId());
49-
builder.field("timestamp", nodeStats.getTimestamp());
50-
return builder;
51-
}), nodeStats.toXContentChunked(outerParams), ChunkedToXContentHelper.endObject())),
52-
ChunkedToXContentHelper.endObject()
53-
);
44+
return ChunkedToXContent.builder(outerParams)
45+
.object(
46+
"nodes",
47+
getNodes().iterator(),
48+
(b, ns) -> b.object(ns.getNode().getId(), ob -> ob.field("timestamp", ns.getTimestamp()).append(ns))
49+
);
5450
}
5551

5652
@Override

server/src/main/java/org/elasticsearch/action/admin/cluster/reroute/ClusterRerouteResponse.java

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,17 @@
1313
import org.elasticsearch.action.support.master.IsAcknowledgedSupplier;
1414
import org.elasticsearch.cluster.ClusterState;
1515
import org.elasticsearch.cluster.routing.allocation.RoutingExplanations;
16-
import org.elasticsearch.common.collect.Iterators;
1716
import org.elasticsearch.common.io.stream.StreamInput;
1817
import org.elasticsearch.common.io.stream.StreamOutput;
1918
import org.elasticsearch.common.logging.DeprecationCategory;
2019
import org.elasticsearch.common.logging.DeprecationLogger;
21-
import org.elasticsearch.common.xcontent.ChunkedToXContentHelper;
20+
import org.elasticsearch.common.xcontent.ChunkedToXContent;
2221
import org.elasticsearch.common.xcontent.ChunkedToXContentObject;
2322
import org.elasticsearch.core.RestApiVersion;
2423
import org.elasticsearch.rest.action.search.RestSearchAction;
2524
import org.elasticsearch.xcontent.ToXContent;
2625

2726
import java.io.IOException;
28-
import java.util.Collections;
2927
import java.util.Iterator;
3028
import java.util.Objects;
3129

@@ -96,20 +94,15 @@ public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params outerP
9694
}
9795

9896
@Override
99-
public Iterator<? extends ToXContent> toXContentChunkedV7(ToXContent.Params outerParams) {
100-
return Iterators.concat(
101-
Iterators.single((builder, params) -> builder.startObject().field(ACKNOWLEDGED_KEY, isAcknowledged())),
102-
emitState(outerParams)
103-
? ChunkedToXContentHelper.wrapWithObject("state", state.toXContentChunked(outerParams))
104-
: Collections.emptyIterator(),
105-
Iterators.single((builder, params) -> {
106-
if (params.paramAsBoolean("explain", false)) {
107-
explanations.toXContent(builder, params);
108-
}
109-
110-
builder.endObject();
111-
return builder;
112-
})
113-
);
97+
public Iterator<? extends ToXContent> toXContentChunkedV7(ToXContent.Params params) {
98+
return ChunkedToXContent.builder(params).object(b -> {
99+
b.field(ACKNOWLEDGED_KEY, isAcknowledged());
100+
if (emitState(params)) {
101+
b.xContentObject("state", state);
102+
}
103+
if (params.paramAsBoolean("explain", false)) {
104+
b.append(explanations);
105+
}
106+
});
114107
}
115108
}

server/src/main/java/org/elasticsearch/action/bulk/BulkResponse.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.elasticsearch.common.collect.Iterators;
1515
import org.elasticsearch.common.io.stream.StreamInput;
1616
import org.elasticsearch.common.io.stream.StreamOutput;
17+
import org.elasticsearch.common.xcontent.ChunkedToXContent;
1718
import org.elasticsearch.common.xcontent.ChunkedToXContentObject;
1819
import org.elasticsearch.core.TimeValue;
1920
import org.elasticsearch.xcontent.ToXContent;
@@ -157,14 +158,13 @@ public void writeTo(StreamOutput out) throws IOException {
157158

158159
@Override
159160
public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params params) {
160-
return Iterators.concat(Iterators.single((builder, p) -> {
161-
builder.startObject();
162-
builder.field(ERRORS, hasFailures());
163-
builder.field(TOOK, tookInMillis);
161+
return ChunkedToXContent.builder(params).object(ob -> {
162+
ob.field(ERRORS, hasFailures());
163+
ob.field(TOOK, tookInMillis);
164164
if (ingestTookInMillis != BulkResponse.NO_INGEST_TOOK) {
165-
builder.field(INGEST_TOOK, ingestTookInMillis);
165+
ob.field(INGEST_TOOK, ingestTookInMillis);
166166
}
167-
return builder.startArray(ITEMS);
168-
}), Iterators.forArray(responses), Iterators.<ToXContent>single((builder, p) -> builder.endArray().endObject()));
167+
ob.array(ITEMS, Iterators.forArray(responses));
168+
});
169169
}
170170
}

server/src/main/java/org/elasticsearch/action/search/SearchResponse.java

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,12 @@
1414
import org.elasticsearch.action.OriginalIndices;
1515
import org.elasticsearch.common.Strings;
1616
import org.elasticsearch.common.bytes.BytesReference;
17-
import org.elasticsearch.common.collect.Iterators;
1817
import org.elasticsearch.common.io.stream.StreamInput;
1918
import org.elasticsearch.common.io.stream.StreamOutput;
2019
import org.elasticsearch.common.io.stream.Writeable;
2120
import org.elasticsearch.common.lucene.Lucene;
2221
import org.elasticsearch.common.util.concurrent.ConcurrentCollections;
23-
import org.elasticsearch.common.xcontent.ChunkedToXContentHelper;
22+
import org.elasticsearch.common.xcontent.ChunkedToXContent;
2423
import org.elasticsearch.common.xcontent.ChunkedToXContentObject;
2524
import org.elasticsearch.core.Nullable;
2625
import org.elasticsearch.core.RefCounted;
@@ -383,39 +382,17 @@ public Clusters getClusters() {
383382
@Override
384383
public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params params) {
385384
assert hasReferences();
386-
return Iterators.concat(
387-
ChunkedToXContentHelper.startObject(),
388-
this.innerToXContentChunked(params),
389-
ChunkedToXContentHelper.endObject()
390-
);
385+
return ChunkedToXContent.builder(params).xContentObject(innerToXContentChunked(params));
391386
}
392387

393388
public Iterator<? extends ToXContent> innerToXContentChunked(ToXContent.Params params) {
394-
return Iterators.concat(
395-
ChunkedToXContentHelper.singleChunk(SearchResponse.this::headerToXContent),
396-
Iterators.single(clusters),
397-
Iterators.concat(
398-
Iterators.flatMap(Iterators.single(hits), r -> r.toXContentChunked(params)),
399-
Iterators.single((ToXContent) (b, p) -> {
400-
if (aggregations != null) {
401-
aggregations.toXContent(b, p);
402-
}
403-
return b;
404-
}),
405-
Iterators.single((b, p) -> {
406-
if (suggest != null) {
407-
suggest.toXContent(b, p);
408-
}
409-
return b;
410-
}),
411-
Iterators.single((b, p) -> {
412-
if (profileResults != null) {
413-
profileResults.toXContent(b, p);
414-
}
415-
return b;
416-
})
417-
)
418-
);
389+
return ChunkedToXContent.builder(params)
390+
.append(SearchResponse.this::headerToXContent)
391+
.append(clusters)
392+
.append(hits)
393+
.appendIfPresent(aggregations)
394+
.appendIfPresent(suggest)
395+
.appendIfPresent(profileResults);
419396
}
420397

421398
public XContentBuilder headerToXContent(XContentBuilder builder, ToXContent.Params params) throws IOException {

server/src/main/java/org/elasticsearch/action/support/broadcast/ChunkedBroadcastResponse.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
package org.elasticsearch.action.support.broadcast;
1010

1111
import org.elasticsearch.action.support.DefaultShardOperationFailedException;
12-
import org.elasticsearch.common.collect.Iterators;
1312
import org.elasticsearch.common.io.stream.StreamInput;
13+
import org.elasticsearch.common.xcontent.ChunkedToXContent;
1414
import org.elasticsearch.common.xcontent.ChunkedToXContentObject;
1515
import org.elasticsearch.rest.action.RestActions;
1616
import org.elasticsearch.xcontent.ToXContent;
@@ -35,11 +35,8 @@ public ChunkedBroadcastResponse(
3535

3636
@Override
3737
public final Iterator<ToXContent> toXContentChunked(ToXContent.Params params) {
38-
return Iterators.concat(Iterators.single((b, p) -> {
39-
b.startObject();
40-
RestActions.buildBroadcastShardsHeader(b, p, this);
41-
return b;
42-
}), customXContentChunks(params), Iterators.single((builder, p) -> builder.endObject()));
38+
return ChunkedToXContent.builder(params)
39+
.object(ob -> ob.append((b, p) -> RestActions.buildBroadcastShardsHeader(b, p, this)).append(this::customXContentChunks));
4340
}
4441

4542
protected abstract Iterator<ToXContent> customXContentChunks(ToXContent.Params params);

server/src/main/java/org/elasticsearch/action/support/nodes/BaseNodesXContentResponse.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111

1212
import org.elasticsearch.action.FailedNodeException;
1313
import org.elasticsearch.cluster.ClusterName;
14-
import org.elasticsearch.common.collect.Iterators;
15-
import org.elasticsearch.common.xcontent.ChunkedToXContentHelper;
14+
import org.elasticsearch.common.xcontent.ChunkedToXContent;
1615
import org.elasticsearch.common.xcontent.ChunkedToXContentObject;
1716
import org.elasticsearch.rest.action.RestActions;
1817
import org.elasticsearch.xcontent.ToXContent;
@@ -30,11 +29,12 @@ protected BaseNodesXContentResponse(ClusterName clusterName, List<TNodeResponse>
3029

3130
@Override
3231
public final Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params params) {
33-
return Iterators.concat(Iterators.single((b, p) -> {
34-
b.startObject();
35-
RestActions.buildNodesHeader(b, p, this);
36-
return b.field("cluster_name", getClusterName().value());
37-
}), xContentChunks(params), ChunkedToXContentHelper.endObject());
32+
return ChunkedToXContent.builder(params)
33+
.object(
34+
ob -> ob.append((b, p) -> RestActions.buildNodesHeader(b, p, this))
35+
.field("cluster_name", getClusterName().value())
36+
.append(xContentChunks(params))
37+
);
3838
}
3939

4040
protected abstract Iterator<? extends ToXContent> xContentChunks(ToXContent.Params outerParams);

0 commit comments

Comments
 (0)