Skip to content

Commit 540397f

Browse files
committed
Store Template's mappings as bytes for disk serialization (elastic#78746)
This change the way we store mappings in `Template` during serialization to disk - instead storing it as map we use byte array that we already have. This avoids deserialization-serialization cycle during storing cluster state on disk. # Conflicts: # server/src/main/java/org/elasticsearch/cluster/coordination/ElasticsearchNodeCommand.java
1 parent c993176 commit 540397f

File tree

8 files changed

+42
-19
lines changed

8 files changed

+42
-19
lines changed

client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetComponentTemplatesResponseTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.elasticsearch.cluster.metadata.Template;
1414
import org.elasticsearch.common.compress.CompressedXContent;
1515
import org.elasticsearch.common.settings.Settings;
16+
import org.elasticsearch.xcontent.ToXContent;
1617
import org.elasticsearch.xcontent.XContentBuilder;
1718
import org.elasticsearch.test.ESTestCase;
1819

@@ -79,7 +80,7 @@ private static void toXContent(GetComponentTemplatesResponse response, XContentB
7980
builder.startObject();
8081
builder.field("name", e.getKey());
8182
builder.field("component_template");
82-
e.getValue().toXContent(builder, null);
83+
e.getValue().toXContent(builder, ToXContent.EMPTY_PARAMS);
8384
builder.endObject();
8485
}
8586
builder.endArray();

client/rest-high-level/src/test/java/org/elasticsearch/client/indices/GetComposableIndexTemplatesResponseTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import org.elasticsearch.cluster.metadata.ComposableIndexTemplate;
1212
import org.elasticsearch.xcontent.XContentBuilder;
13+
import org.elasticsearch.xcontent.ToXContent;
1314
import org.elasticsearch.test.ESTestCase;
1415

1516
import java.io.IOException;
@@ -53,7 +54,7 @@ private static void toXContent(GetComposableIndexTemplatesResponse response, XCo
5354
builder.startObject();
5455
builder.field("name", e.getKey());
5556
builder.field("index_template");
56-
e.getValue().toXContent(builder, null);
57+
e.getValue().toXContent(builder, ToXContent.EMPTY_PARAMS);
5758
builder.endObject();
5859
}
5960
builder.endArray();

server/src/main/java/org/elasticsearch/cluster/coordination/ElasticsearchNodeCommand.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,22 @@
2323
import org.elasticsearch.cluster.ClusterName;
2424
import org.elasticsearch.cluster.ClusterState;
2525
import org.elasticsearch.cluster.Diff;
26+
import org.elasticsearch.cluster.metadata.ComponentTemplateMetadata;
27+
import org.elasticsearch.cluster.metadata.ComposableIndexTemplateMetadata;
2628
import org.elasticsearch.cluster.metadata.DataStreamMetadata;
2729
import org.elasticsearch.cluster.metadata.Metadata;
28-
import org.elasticsearch.core.Tuple;
2930
import org.elasticsearch.common.io.stream.StreamOutput;
3031
import org.elasticsearch.common.settings.ClusterSettings;
3132
import org.elasticsearch.common.settings.Settings;
3233
import org.elasticsearch.common.util.BigArrays;
33-
import org.elasticsearch.xcontent.NamedXContentRegistry;
34-
import org.elasticsearch.xcontent.XContentBuilder;
35-
import org.elasticsearch.xcontent.XContentParser;
34+
import org.elasticsearch.core.Tuple;
3635
import org.elasticsearch.env.Environment;
3736
import org.elasticsearch.env.NodeEnvironment;
3837
import org.elasticsearch.env.NodeMetadata;
3938
import org.elasticsearch.gateway.PersistedClusterStateService;
39+
import org.elasticsearch.xcontent.NamedXContentRegistry;
40+
import org.elasticsearch.xcontent.XContentBuilder;
41+
import org.elasticsearch.xcontent.XContentParser;
4042

4143
import java.io.IOException;
4244
import java.nio.file.Files;
@@ -70,7 +72,8 @@ public abstract class ElasticsearchNodeCommand extends EnvironmentAwareCommand {
7072
public <T, C> T parseNamedObject(Class<T> categoryClass, String name, XContentParser parser, C context) throws IOException {
7173
// Currently, two unknown top-level objects are present
7274
if (Metadata.Custom.class.isAssignableFrom(categoryClass)) {
73-
if (DataStreamMetadata.TYPE.equals(name)) {
75+
if (DataStreamMetadata.TYPE.equals(name) || ComposableIndexTemplateMetadata.TYPE.equals(name)
76+
|| ComponentTemplateMetadata.TYPE.equals(name)) {
7477
// DataStreamMetadata is used inside Metadata class for validation purposes and building the indicesLookup,
7578
// therefor even es node commands need to be able to parse it.
7679
return super.parseNamedObject(categoryClass, name, parser, context);

server/src/main/java/org/elasticsearch/cluster/metadata/ComponentTemplate.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ public String toString() {
129129
@Override
130130
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
131131
builder.startObject();
132-
builder.field(TEMPLATE.getPreferredName(), this.template);
132+
builder.field(TEMPLATE.getPreferredName(), this.template, params);
133133
if (this.version != null) {
134134
builder.field(VERSION.getPreferredName(), this.version);
135135
}

server/src/main/java/org/elasticsearch/cluster/metadata/ComponentTemplateMetadata.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public static ComponentTemplateMetadata fromXContent(XContentParser parser) thro
9898
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
9999
builder.startObject(COMPONENT_TEMPLATE.getPreferredName());
100100
for (Map.Entry<String, ComponentTemplate> template : componentTemplates.entrySet()) {
101-
builder.field(template.getKey(), template.getValue());
101+
builder.field(template.getKey(), template.getValue(), params);
102102
}
103103
builder.endObject();
104104
return builder;

server/src/main/java/org/elasticsearch/cluster/metadata/ComposableIndexTemplate.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
218218
builder.startObject();
219219
builder.stringListField(INDEX_PATTERNS.getPreferredName(), this.indexPatterns);
220220
if (this.template != null) {
221-
builder.field(TEMPLATE.getPreferredName(), this.template);
221+
builder.field(TEMPLATE.getPreferredName(), this.template, params);
222222
}
223223
if (this.componentTemplates != null) {
224224
builder.stringListField(COMPOSED_OF.getPreferredName(), this.componentTemplates);
@@ -233,7 +233,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
233233
builder.field(METADATA.getPreferredName(), metadata);
234234
}
235235
if (this.dataStreamTemplate != null) {
236-
builder.field(DATA_STREAM.getPreferredName(), dataStreamTemplate);
236+
builder.field(DATA_STREAM.getPreferredName(), dataStreamTemplate, params);
237237
}
238238
if (this.allowAutoCreate != null) {
239239
builder.field(ALLOW_AUTO_CREATE.getPreferredName(), allowAutoCreate);

server/src/main/java/org/elasticsearch/cluster/metadata/ComposableIndexTemplateMetadata.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public void writeTo(StreamOutput out) throws IOException {
9999
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
100100
builder.startObject(INDEX_TEMPLATE.getPreferredName());
101101
for (Map.Entry<String, ComposableIndexTemplate> template : indexTemplates.entrySet()) {
102-
builder.field(template.getKey(), template.getValue());
102+
builder.field(template.getKey(), template.getValue(), params);
103103
}
104104
builder.endObject();
105105
return builder;

server/src/main/java/org/elasticsearch/cluster/metadata/Template.java

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.elasticsearch.cluster.AbstractDiffable;
1212
import org.elasticsearch.common.util.Maps;
1313
import org.elasticsearch.core.Nullable;
14+
import org.elasticsearch.xcontent.ObjectParser;
1415
import org.elasticsearch.xcontent.ParseField;
1516
import org.elasticsearch.common.Strings;
1617
import org.elasticsearch.common.compress.CompressedXContent;
@@ -27,6 +28,7 @@
2728
import org.elasticsearch.index.mapper.MapperService;
2829

2930
import java.io.IOException;
31+
import java.util.Base64;
3032
import java.util.HashMap;
3133
import java.util.Map;
3234
import java.util.Objects;
@@ -47,8 +49,18 @@ public class Template extends AbstractDiffable<Template> implements ToXContentOb
4749

4850
static {
4951
PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), (p, c) -> Settings.fromXContent(p), SETTINGS);
50-
PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), (p, c) ->
51-
new CompressedXContent(Strings.toString(XContentFactory.jsonBuilder().map(p.mapOrdered()))), MAPPINGS);
52+
PARSER.declareField(ConstructingObjectParser.optionalConstructorArg(), (p, c) -> {
53+
XContentParser.Token token = p.currentToken();
54+
if (token == XContentParser.Token.VALUE_STRING) {
55+
return new CompressedXContent(Base64.getDecoder().decode(p.text()));
56+
} else if(token == XContentParser.Token.VALUE_EMBEDDED_OBJECT){
57+
return new CompressedXContent(p.binaryValue());
58+
} else if (token == XContentParser.Token.START_OBJECT){
59+
return new CompressedXContent(Strings.toString(XContentFactory.jsonBuilder().map(p.mapOrdered())));
60+
} else {
61+
throw new IllegalArgumentException("Unexpected token: " + token);
62+
}
63+
}, MAPPINGS, ObjectParser.ValueType.VALUE_OBJECT_ARRAY);
5264
PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), (p, c) -> {
5365
Map<String, AliasMetadata> aliasMap = new HashMap<>();
5466
while ((p.nextToken()) != XContentParser.Token.END_OBJECT) {
@@ -160,11 +172,17 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
160172
builder.endObject();
161173
}
162174
if (this.mappings != null) {
163-
Map<String, Object> uncompressedMapping =
164-
XContentHelper.convertToMap(this.mappings.uncompressed(), true, XContentType.JSON).v2();
165-
if (uncompressedMapping.size() > 0) {
166-
builder.field(MAPPINGS.getPreferredName());
167-
builder.map(reduceMapping(uncompressedMapping));
175+
String context = params.param(Metadata.CONTEXT_MODE_PARAM, Metadata.CONTEXT_MODE_API);
176+
boolean binary = params.paramAsBoolean("binary", false);
177+
if (Metadata.CONTEXT_MODE_API.equals(context) || binary == false) {
178+
Map<String, Object> uncompressedMapping =
179+
XContentHelper.convertToMap(this.mappings.uncompressed(), true, XContentType.JSON).v2();
180+
if (uncompressedMapping.size() > 0) {
181+
builder.field(MAPPINGS.getPreferredName());
182+
builder.map(reduceMapping(uncompressedMapping));
183+
}
184+
} else {
185+
builder.field(MAPPINGS.getPreferredName(), mappings.compressed());
168186
}
169187
}
170188
if (this.aliases != null) {

0 commit comments

Comments
 (0)