Skip to content

Commit 6157c35

Browse files
committed
Add rolling upgrade tests for component and composable templates
This adds rolling upgrade tests that component and composable templates can be read from older versions of the cluster. Relates to elastic#58643
1 parent 1c6f59b commit 6157c35

File tree

6 files changed

+165
-23
lines changed

6 files changed

+165
-23
lines changed

qa/rolling-upgrade/src/test/java/org/elasticsearch/upgrades/AbstractRollingTestCase.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ protected final boolean preserveReposUponCompletion() {
5454
return true;
5555
}
5656

57+
@Override
58+
protected boolean preserveTemplatesUponCompletion() {
59+
return true;
60+
}
61+
5762
@Override
5863
protected final Settings restClientSettings() {
5964
return Settings.builder().put(super.restClientSettings())

qa/rolling-upgrade/src/test/java/org/elasticsearch/upgrades/UpgradeClusterClientYamlTestSuiteIT.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ protected boolean preserveReposUponCompletion() {
4040
return true;
4141
}
4242

43+
@Override
44+
protected boolean preserveTemplatesUponCompletion() {
45+
return true;
46+
}
47+
4348
public UpgradeClusterClientYamlTestSuiteIT(ClientYamlTestCandidate testCandidate) {
4449
super(testCandidate);
4550
}

qa/rolling-upgrade/src/test/resources/rest-api-spec/test/mixed_cluster/10_basic.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,29 @@
7979
indices.get:
8080
index: queries
8181
- match: { queries.mappings.properties.id.type: "keyword" }
82+
83+
---
84+
"Component and composable templates can be retrieved":
85+
- do:
86+
cluster.get_component_template:
87+
name: my-ct
88+
89+
- match: {component_templates.0.name: my-ct}
90+
- match: {component_templates.0.component_template.version: 2}
91+
- match: {component_templates.0.component_template._meta: {foo: bar, baz: {eggplant: true}}}
92+
- match: {component_templates.0.component_template.template.settings: {index: {number_of_shards: '1', number_of_replicas: '0'}}}
93+
- is_true: component_templates.0.component_template.template.mappings
94+
- match: {component_templates.0.component_template.template.aliases: {aliasname: {}}}
95+
96+
- do:
97+
indices.get_index_template:
98+
name: my-it
99+
100+
- match: {index_templates.0.index_template.index_patterns: ["test-*"]}
101+
- match: {index_templates.0.index_template.template.settings.index: {number_of_shards: '1', number_of_replicas: '0'}}
102+
- is_true: index_templates.0.index_template.template.mappings
103+
- length: {index_templates.0.index_template.template.aliases: 3}
104+
- is_true: index_templates.0.index_template.template.aliases.test_alias
105+
- match: {index_templates.0.index_template.template.aliases.test_blias.index_routing: "b" }
106+
- match: {index_templates.0.index_template.template.aliases.test_blias.search_routing: "b" }
107+
- match: {index_templates.0.index_template.template.aliases.test_clias.filter.term.user: "kimchy" }

qa/rolling-upgrade/src/test/resources/rest-api-spec/test/old_cluster/10_basic.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,49 @@
205205
wait_for_completion: true
206206
task_id: $task
207207

208+
---
209+
"Component and composable template validation":
210+
- do:
211+
cluster.put_component_template:
212+
name: my-ct
213+
body:
214+
template:
215+
settings:
216+
number_of_shards: 1
217+
number_of_replicas: 0
218+
mappings:
219+
dynamic: false
220+
aliases:
221+
aliasname: {}
222+
version: 2
223+
_meta:
224+
foo: bar
225+
baz:
226+
eggplant: true
227+
228+
- do:
229+
indices.put_index_template:
230+
name: my-it
231+
body:
232+
index_patterns: [test-*]
233+
composed_of: ["my-ct"]
234+
template:
235+
settings:
236+
number_of_shards: 1
237+
number_of_replicas: 0
238+
mappings:
239+
properties:
240+
field:
241+
type: text
242+
aliases:
243+
test_alias: {}
244+
test_blias: { routing: b }
245+
test_clias: { filter: { term: { user: kimchy }}}
246+
247+
- do:
248+
cluster.get_component_template:
249+
name: my-ct
250+
251+
- do:
252+
indices.get_index_template:
253+
name: my-it

qa/rolling-upgrade/src/test/resources/rest-api-spec/test/upgraded_cluster/10_basic.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,4 +126,56 @@
126126
task_id: $task_id
127127
- match: { task.headers.X-Opaque-Id: "Reindexing Again" }
128128

129+
---
130+
"Component and composable templates can be retrieved and updated":
131+
- do:
132+
cluster.get_component_template:
133+
name: my-ct
134+
135+
- match: {component_templates.0.name: my-ct}
136+
- match: {component_templates.0.component_template.version: 2}
137+
- match: {component_templates.0.component_template._meta: {foo: bar, baz: {eggplant: true}}}
138+
- match: {component_templates.0.component_template.template.settings: {index: {number_of_shards: '1', number_of_replicas: '0'}}}
139+
- match: {component_templates.0.component_template.template.mappings: {dynamic: false}}
140+
- match: {component_templates.0.component_template.template.aliases: {aliasname: {}}}
141+
142+
- do:
143+
indices.get_index_template:
144+
name: my-it
145+
146+
- match: {index_templates.0.index_template.index_patterns: ["test-*"]}
147+
- match: {index_templates.0.index_template.template.settings.index: {number_of_shards: '1', number_of_replicas: '0'}}
148+
- is_true: index_templates.0.index_template.template.mappings
149+
- length: {index_templates.0.index_template.template.aliases: 3}
150+
- is_true: index_templates.0.index_template.template.aliases.test_alias
151+
- match: {index_templates.0.index_template.template.aliases.test_blias.index_routing: "b" }
152+
- match: {index_templates.0.index_template.template.aliases.test_blias.search_routing: "b" }
153+
- match: {index_templates.0.index_template.template.aliases.test_clias.filter.term.user: "kimchy" }
154+
- do:
155+
cluster.put_component_template:
156+
name: my-ct
157+
body:
158+
template:
159+
settings:
160+
number_of_shards: 1
161+
number_of_replicas: 0
162+
mappings:
163+
dynamic: true
164+
aliases:
165+
aliasname: {}
166+
version: 2
167+
_meta:
168+
foo: bar
169+
baz:
170+
eggplant: true
171+
172+
- do:
173+
cluster.get_component_template:
174+
name: my-ct
129175

176+
- match: {component_templates.0.name: my-ct}
177+
- match: {component_templates.0.component_template.version: 2}
178+
- match: {component_templates.0.component_template._meta: {foo: bar, baz: {eggplant: true}}}
179+
- match: {component_templates.0.component_template.template.settings: {index: {number_of_shards: '1', number_of_replicas: '0'}}}
180+
- is_true: component_templates.0.component_template.template.mappings
181+
- match: {component_templates.0.component_template.template.aliases: {aliasname: {}}}

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

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ ClusterState addComponentTemplate(final ClusterState currentState, final boolean
186186
}
187187

188188
CompressedXContent mappings = template.template().mappings();
189-
String stringMappings = mappings == null ? null : mappings.string();
189+
String stringMappings = wrapMappingsIfNecessary(mappings == null ? null : mappings.string(), xContentRegistry);
190190

191191
// We may need to normalize index settings, so do that also
192192
Settings finalSettings = template.template().settings();
@@ -225,17 +225,6 @@ ClusterState addComponentTemplate(final ClusterState currentState, final boolean
225225
}
226226
}
227227

228-
// Mappings in component templates don't include _doc, so update the mappings to include this single type
229-
if (stringMappings != null) {
230-
Map<String, Object> parsedMappings = MapperService.parseMapping(xContentRegistry, stringMappings);
231-
if (parsedMappings.size() > 0) {
232-
stringMappings = Strings.toString(XContentFactory.jsonBuilder()
233-
.startObject()
234-
.field(MapperService.SINGLE_MAPPING_NAME, parsedMappings)
235-
.endObject());
236-
}
237-
}
238-
239228
final Template finalTemplate = new Template(finalSettings,
240229
stringMappings == null ? null : new CompressedXContent(stringMappings), template.template().aliases());
241230
final ComponentTemplate finalComponentTemplate = new ComponentTemplate(finalTemplate, template.version(), template.metadata());
@@ -279,6 +268,35 @@ ClusterState addComponentTemplate(final ClusterState currentState, final boolean
279268
.build();
280269
}
281270

271+
@Nullable
272+
private static String wrapMappingsIfNecessary(@Nullable String mappings, NamedXContentRegistry xContentRegistry) throws Exception {
273+
// Mappings in templates don't have to include _doc, so update
274+
// the mappings to include this single type if necessary
275+
276+
String stringMappings = mappings;
277+
if (stringMappings != null) {
278+
Map<String, Object> parsedMappings = MapperService.parseMapping(xContentRegistry, stringMappings);
279+
if (parsedMappings.size() > 0) {
280+
if (parsedMappings.size() == 1) {
281+
final String keyName = parsedMappings.keySet().iterator().next();
282+
// Check if it's already wrapped in `_doc`, only rewrap if needed
283+
if (MapperService.SINGLE_MAPPING_NAME.equals(keyName) == false) {
284+
stringMappings = Strings.toString(XContentFactory.jsonBuilder()
285+
.startObject()
286+
.field(MapperService.SINGLE_MAPPING_NAME, parsedMappings)
287+
.endObject());
288+
}
289+
} else {
290+
stringMappings = Strings.toString(XContentFactory.jsonBuilder()
291+
.startObject()
292+
.field(MapperService.SINGLE_MAPPING_NAME, parsedMappings)
293+
.endObject());
294+
}
295+
}
296+
}
297+
return stringMappings;
298+
}
299+
282300
/**
283301
* Remove the given component template from the cluster state. The component template name
284302
* supports simple regex wildcards for removing multiple component templates at a time.
@@ -462,18 +480,8 @@ public ClusterState addIndexTemplateV2(final ClusterState currentState, final bo
462480
// If an inner template was specified, its mappings may need to be
463481
// adjusted (to add _doc) and it should be validated
464482
CompressedXContent mappings = innerTemplate.mappings();
465-
String stringMappings = mappings == null ? null : mappings.string();
483+
String stringMappings = wrapMappingsIfNecessary(mappings == null ? null : mappings.string(), xContentRegistry);
466484

467-
// Mappings in index templates don't include _doc, so update the mappings to include this single type
468-
if (stringMappings != null) {
469-
Map<String, Object> parsedMappings = MapperService.parseMapping(xContentRegistry, stringMappings);
470-
if (parsedMappings.size() > 0) {
471-
stringMappings = Strings.toString(XContentFactory.jsonBuilder()
472-
.startObject()
473-
.field(MapperService.SINGLE_MAPPING_NAME, parsedMappings)
474-
.endObject());
475-
}
476-
}
477485
final Template finalTemplate = new Template(finalSettings,
478486
stringMappings == null ? null : new CompressedXContent(stringMappings), innerTemplate.aliases());
479487
finalIndexTemplate = new ComposableIndexTemplate(template.indexPatterns(), finalTemplate, template.composedOf(),

0 commit comments

Comments
 (0)