Use CLDR locale provider on JDK 23+ (#110222)

JDK 23 removes the COMPAT locale provider, leaving CLDR as the only option. This commit configures Elasticsearch
to use the CLDR provider when on JDK 23, but still use the existing COMPAT provider when on JDK 22 and below.

This causes some differences in locale behaviour; this also adapts various tests to still work whether run on COMPAT or CLDR.
This commit is contained in:
Simon Cooper 2024-09-04 13:42:40 +01:00 committed by GitHub
parent 0074c14bfa
commit a36d90cf34
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 73 additions and 92 deletions

View file

@ -167,7 +167,7 @@ if (providers.systemProperty('idea.active').getOrNull() == 'true') {
vmParameters = [ vmParameters = [
'-ea', '-ea',
'-Djava.security.manager=allow', '-Djava.security.manager=allow',
'-Djava.locale.providers=SPI,COMPAT', '-Djava.locale.providers=SPI,CLDR',
'-Des.nativelibs.path="' + testLibraryPath + '"', '-Des.nativelibs.path="' + testLibraryPath + '"',
// TODO: only open these for mockito when it is modularized // TODO: only open these for mockito when it is modularized
'--add-opens=java.base/java.security.cert=ALL-UNNAMED', '--add-opens=java.base/java.security.cert=ALL-UNNAMED',

View file

@ -92,7 +92,7 @@ public abstract class ElasticsearchTestBasePlugin implements Plugin<Project> {
mkdirs(test.getWorkingDir().toPath().resolve("temp").toFile()); mkdirs(test.getWorkingDir().toPath().resolve("temp").toFile());
// TODO remove once jvm.options are added to test system properties // TODO remove once jvm.options are added to test system properties
test.systemProperty("java.locale.providers", "SPI,COMPAT"); test.systemProperty("java.locale.providers", "SPI,CLDR");
} }
}); });
test.getJvmArgumentProviders().add(nonInputProperties); test.getJvmArgumentProviders().add(nonInputProperties);

View file

@ -10,6 +10,7 @@ package org.elasticsearch.server.cli;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.EsExecutors; import org.elasticsearch.common.util.concurrent.EsExecutors;
import org.elasticsearch.core.UpdateForV9;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -59,11 +60,7 @@ final class SystemJvmOptions {
"-Dlog4j.shutdownHookEnabled=false", "-Dlog4j.shutdownHookEnabled=false",
"-Dlog4j2.disable.jmx=true", "-Dlog4j2.disable.jmx=true",
"-Dlog4j2.formatMsgNoLookups=true", "-Dlog4j2.formatMsgNoLookups=true",
/* "-Djava.locale.providers=" + getLocaleProviders(),
* Due to internationalization enhancements in JDK 9 Elasticsearch need to set the provider to COMPAT otherwise time/date
* parsing will break in an incompatible way for some date patterns and locales.
*/
"-Djava.locale.providers=SPI,COMPAT",
maybeEnableNativeAccess(), maybeEnableNativeAccess(),
maybeOverrideDockerCgroup(distroType), maybeOverrideDockerCgroup(distroType),
maybeSetActiveProcessorCount(nodeSettings), maybeSetActiveProcessorCount(nodeSettings),
@ -75,6 +72,16 @@ final class SystemJvmOptions {
).filter(e -> e.isEmpty() == false).collect(Collectors.toList()); ).filter(e -> e.isEmpty() == false).collect(Collectors.toList());
} }
@UpdateForV9 // only use CLDR in v9+
private static String getLocaleProviders() {
/*
* Specify SPI to load IsoCalendarDataProvider (see #48209), specifying the first day of week as Monday.
* When on pre-23, use COMPAT instead to maintain existing date formats as much as we can.
* When on JDK 23+, use the default CLDR locale database, as COMPAT was removed in JDK 23.
*/
return Runtime.version().feature() >= 23 ? "SPI,CLDR" : "SPI,COMPAT";
}
/* /*
* The virtual file /proc/self/cgroup should list the current cgroup * The virtual file /proc/self/cgroup should list the current cgroup
* membership. For each hierarchy, you can follow the cgroup path from * membership. For each hierarchy, you can follow the cgroup path from

View file

@ -64,14 +64,14 @@ actors that appear in each play:
---- ----
GET seats/_search GET seats/_search
{ {
"size": 2, "size": 2,
"query": { "query": {
"match_all": {} "match_all": {}
}, },
"script_fields": { "script_fields": {
"day-of-week": { "day-of-week": {
"script": { "script": {
"source": "doc['datetime'].value.getDayOfWeekEnum().getDisplayName(TextStyle.FULL, Locale.ROOT)" "source": "doc['datetime'].value.getDayOfWeekEnum().getDisplayName(TextStyle.FULL, Locale.ENGLISH)"
} }
}, },
"number-of-actors": { "number-of-actors": {
@ -132,4 +132,4 @@ GET seats/_search
} }
} }
---- ----
// TESTRESPONSE[s/"took" : 68/"took" : "$body.took"/] // TESTRESPONSE[s/"took" : 68/"took" : "$body.took"/]

View file

@ -749,7 +749,7 @@ POST /_scripts/painless/_execute
{ {
"script": { "script": {
"source": """ "source": """
emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)); emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
""" """
}, },
"context": "keyword_field", "context": "keyword_field",

View file

@ -156,7 +156,7 @@ GET /_search
"type": "keyword", "type": "keyword",
"script": """ "script": """
emit(doc['timestamp'].value.dayOfWeekEnum emit(doc['timestamp'].value.dayOfWeekEnum
.getDisplayName(TextStyle.FULL, Locale.ROOT)) .getDisplayName(TextStyle.FULL, Locale.ENGLISH))
""" """
} }
}, },

View file

@ -582,7 +582,7 @@ For example, the offset of `+19d` will result in buckets with names like `2022-0
Increasing the offset to `+20d`, each document will appear in a bucket for the previous month, Increasing the offset to `+20d`, each document will appear in a bucket for the previous month,
with all bucket keys ending with the same day of the month, as normal. with all bucket keys ending with the same day of the month, as normal.
However, further increasing to `+28d`, However, further increasing to `+28d`,
what used to be a February bucket has now become `"2022-03-01"`. what used to be a February bucket has now become `"2022-03-01"`.
[source,console,id=datehistogram-aggregation-offset-example-28d] [source,console,id=datehistogram-aggregation-offset-example-28d]
@ -819,7 +819,7 @@ POST /sales/_search?size=0
"runtime_mappings": { "runtime_mappings": {
"date.day_of_week": { "date.day_of_week": {
"type": "keyword", "type": "keyword",
"script": "emit(doc['date'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" "script": "emit(doc['date'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH))"
} }
}, },
"aggs": { "aggs": {

View file

@ -102,7 +102,7 @@ PUT _component_template/runtime_component_template
"day_of_week": { "day_of_week": {
"type": "keyword", "type": "keyword",
"script": { "script": {
"source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH))"
} }
} }
} }

View file

@ -135,7 +135,7 @@ PUT my-index-000001/
"day_of_week": { "day_of_week": {
"type": "keyword", "type": "keyword",
"script": { "script": {
"source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH))"
} }
} }
}, },
@ -291,7 +291,7 @@ GET my-index-000001/_search
"day_of_week": { "day_of_week": {
"type": "keyword", "type": "keyword",
"script": { "script": {
"source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH))"
} }
} }
}, },
@ -667,7 +667,7 @@ PUT my-index-000001/
"day_of_week": { "day_of_week": {
"type": "keyword", "type": "keyword",
"script": { "script": {
"source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH))"
} }
} }
}, },

View file

@ -951,7 +951,7 @@ For example:
"day_of_week": { "day_of_week": {
"type": "keyword", "type": "keyword",
"script": { "script": {
"source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH))"
} }
} }
} }

View file

@ -173,7 +173,7 @@ GET /my-index-000001/_search
"script": { "script": {
"source": "source":
"""emit(doc['@timestamp'].value.dayOfWeekEnum """emit(doc['@timestamp'].value.dayOfWeekEnum
.getDisplayName(TextStyle.FULL, Locale.ROOT))""" .getDisplayName(TextStyle.FULL, Locale.ENGLISH))"""
} }
} }
}, },

View file

@ -12,7 +12,7 @@ setup:
script: script:
source: | source: |
for (date in field('date')) { for (date in field('date')) {
emit(date.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)); emit(date.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
} }
total_value_double: total_value_double:
type: double type: double
@ -55,7 +55,7 @@ setup:
source: | source: |
if (doc.containsKey('date')) { if (doc.containsKey('date')) {
for (date in doc['date']) { for (date in doc['date']) {
emit(date.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)); emit(date.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
} }
} }
doc_total_value_double: doc_total_value_double:
@ -737,7 +737,7 @@ setup:
script: script:
source: | source: |
for (date in field('date')) { for (date in field('date')) {
emit(date.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)); emit(date.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
} }
sort: [ { rank: asc } ] sort: [ { rank: asc } ]
script_fields: script_fields:
@ -758,7 +758,7 @@ setup:
script: script:
source: | source: |
for (date in field('date')) { for (date in field('date')) {
emit(date.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)); emit(date.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
} }
sort: [ { rank: asc } ] sort: [ { rank: asc } ]
script_fields: script_fields:
@ -924,7 +924,7 @@ setup:
source: | source: |
if (doc.containsKey('date')) { if (doc.containsKey('date')) {
for (date in doc['date']) { for (date in doc['date']) {
emit(date.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)); emit(date.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
} }
} }
sort: [ { rank: asc } ] sort: [ { rank: asc } ]
@ -947,7 +947,7 @@ setup:
source: | source: |
if (doc.containsKey('date')) { if (doc.containsKey('date')) {
for (date in doc['date']) { for (date in doc['date']) {
emit(date.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)); emit(date.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
} }
} }
sort: [ { rank: asc } ] sort: [ { rank: asc } ]
@ -1133,7 +1133,7 @@ setup:
script: script:
source: | source: |
for (date in field('date')) { for (date in field('date')) {
emit(date.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)); emit(date.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
} }
sort: [ { rank: asc } ] sort: [ { rank: asc } ]
script_fields: script_fields:
@ -1156,7 +1156,7 @@ setup:
script: script:
source: | source: |
for (date in field('date')) { for (date in field('date')) {
emit(date.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)); emit(date.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
} }
sort: [ { rank: asc } ] sort: [ { rank: asc } ]
script_fields: script_fields:
@ -1337,7 +1337,7 @@ setup:
source: | source: |
if (doc.containsKey('date')) { if (doc.containsKey('date')) {
for (date in doc['date']) { for (date in doc['date']) {
emit(date.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)); emit(date.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
} }
} }
sort: [ { rank: asc } ] sort: [ { rank: asc } ]
@ -1362,7 +1362,7 @@ setup:
source: | source: |
if (doc.containsKey('date')) { if (doc.containsKey('date')) {
for (date in doc['date']) { for (date in doc['date']) {
emit(date.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)); emit(date.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
} }
} }
sort: [ { rank: asc } ] sort: [ { rank: asc } ]

View file

@ -12,7 +12,7 @@ setup:
day_of_week: day_of_week:
type: keyword type: keyword
script: | script: |
emit(doc['timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)); emit(doc['timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
# Test fetching from _source # Test fetching from _source
day_of_week_from_source: day_of_week_from_source:
type: keyword type: keyword
@ -75,7 +75,7 @@ setup:
- match: {sensor.mappings.runtime.day_of_week.type: keyword } - match: {sensor.mappings.runtime.day_of_week.type: keyword }
- match: - match:
sensor.mappings.runtime.day_of_week.script.source: | sensor.mappings.runtime.day_of_week.script.source: |
emit(doc['timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)); emit(doc['timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
- match: {sensor.mappings.runtime.day_of_week.script.lang: painless } - match: {sensor.mappings.runtime.day_of_week.script.lang: painless }
# --- TODO get field mappings needs to be adapted # --- TODO get field mappings needs to be adapted
@ -90,7 +90,7 @@ setup:
# type: keyword # type: keyword
# script: # script:
# source: | # source: |
# emit(doc['timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)); # emit(doc['timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
# lang: painless # lang: painless
# meta: {} # meta: {}
# #

View file

@ -21,7 +21,7 @@ setup:
day_of_week: day_of_week:
type: keyword type: keyword
script: | script: |
emit(doc['timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)); emit(doc['timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
# Test fetching from _source # Test fetching from _source
day_of_week_from_source: day_of_week_from_source:
type: keyword type: keyword
@ -74,7 +74,7 @@ setup:
- match: {sensor.mappings.properties.day_of_week.type: keyword } - match: {sensor.mappings.properties.day_of_week.type: keyword }
- match: - match:
sensor.mappings.properties.day_of_week.script.source: | sensor.mappings.properties.day_of_week.script.source: |
emit(doc['timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)); emit(doc['timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
- match: {sensor.mappings.properties.day_of_week.script.lang: painless } - match: {sensor.mappings.properties.day_of_week.script.lang: painless }
--- ---

View file

@ -34,7 +34,7 @@ setup:
day_of_week: day_of_week:
type: keyword type: keyword
script: script:
source: "emit(doc['timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" source: "emit(doc['timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH))"
- match: {indices: ["test-1"]} - match: {indices: ["test-1"]}
- length: {fields.timestamp: 1} - length: {fields.timestamp: 1}
@ -78,7 +78,7 @@ setup:
day_of_week: day_of_week:
type: keyword type: keyword
script: script:
source: "emit(doc['timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" source: "emit(doc['timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH))"
- match: {indices: ["test-1", "test-2"]} - match: {indices: ["test-1", "test-2"]}
- length: {fields.day_of_week: 1} - length: {fields.day_of_week: 1}

View file

@ -12,7 +12,7 @@ setup:
day_of_week: day_of_week:
type: keyword type: keyword
script: | script: |
emit(doc['timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT)); emit(doc['timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH));
tomorrow: tomorrow:
type: date type: date
script: script:

View file

@ -1,25 +1,10 @@
tests: tests:
- class: "org.elasticsearch.xpack.textstructure.structurefinder.TimestampFormatFinderTests"
issue: "https://github.com/elastic/elasticsearch/issues/108855"
method: "testGuessIsDayFirstFromLocale"
- class: "org.elasticsearch.test.rest.ClientYamlTestSuiteIT"
issue: "https://github.com/elastic/elasticsearch/issues/108857"
method: "test {yaml=search/180_locale_dependent_mapping/Test Index and Search locale dependent mappings / dates}"
- class: "org.elasticsearch.upgrades.SearchStatesIT" - class: "org.elasticsearch.upgrades.SearchStatesIT"
issue: "https://github.com/elastic/elasticsearch/issues/108991" issue: "https://github.com/elastic/elasticsearch/issues/108991"
method: "testCanMatch" method: "testCanMatch"
- class: "org.elasticsearch.upgrades.MlTrainedModelsUpgradeIT" - class: "org.elasticsearch.upgrades.MlTrainedModelsUpgradeIT"
issue: "https://github.com/elastic/elasticsearch/issues/108993" issue: "https://github.com/elastic/elasticsearch/issues/108993"
method: "testTrainedModelInference" method: "testTrainedModelInference"
- class: "org.elasticsearch.xpack.security.CoreWithSecurityClientYamlTestSuiteIT"
issue: "https://github.com/elastic/elasticsearch/issues/109188"
method: "test {yaml=search/180_locale_dependent_mapping/Test Index and Search locale dependent mappings / dates}"
- class: "org.elasticsearch.xpack.esql.qa.mixed.EsqlClientYamlIT"
issue: "https://github.com/elastic/elasticsearch/issues/109189"
method: "test {p0=esql/70_locale/Date format with Italian locale}"
- class: "org.elasticsearch.xpack.test.rest.XPackRestIT"
issue: "https://github.com/elastic/elasticsearch/issues/109200"
method: "test {p0=esql/70_locale/Date format with Italian locale}"
- class: org.elasticsearch.smoketest.DocsClientYamlTestSuiteIT - class: org.elasticsearch.smoketest.DocsClientYamlTestSuiteIT
method: test {yaml=reference/esql/esql-async-query-api/line_17} method: test {yaml=reference/esql/esql-async-query-api/line_17}
issue: https://github.com/elastic/elasticsearch/issues/109260 issue: https://github.com/elastic/elasticsearch/issues/109260

View file

@ -13,7 +13,7 @@ setup:
day_of_week: day_of_week:
type: keyword type: keyword
script: script:
source: "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" source: "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH))"
- do: - do:
bulk: bulk:
refresh: true refresh: true

View file

@ -9,7 +9,7 @@ setup:
day_of_week: day_of_week:
type: keyword type: keyword
script: script:
source: "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" source: "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH))"
- do: - do:
bulk: bulk:
refresh: true refresh: true

View file

@ -11,26 +11,26 @@
date_field: date_field:
type: date type: date
format: "E, d MMM yyyy HH:mm:ss Z" format: "E, d MMM yyyy HH:mm:ss Z"
locale: "de" locale: "fr"
- do: - do:
bulk: bulk:
refresh: true refresh: true
body: body:
- '{"index": {"_index": "test_index", "_id": "1"}}' - '{"index": {"_index": "test_index", "_id": "1"}}'
- '{"date_field": "Mi, 06 Dez 2000 02:55:00 -0800"}' - '{"date_field": "mer., 6 déc. 2000 02:55:00 -0800"}'
- '{"index": {"_index": "test_index", "_id": "2"}}' - '{"index": {"_index": "test_index", "_id": "2"}}'
- '{"date_field": "Do, 07 Dez 2000 02:55:00 -0800"}' - '{"date_field": "jeu., 7 déc. 2000 02:55:00 -0800"}'
- do: - do:
search: search:
rest_total_hits_as_int: true rest_total_hits_as_int: true
index: test_index index: test_index
body: {"query" : {"range" : {"date_field" : {"gte": "Di, 05 Dez 2000 02:55:00 -0800", "lte": "Do, 07 Dez 2000 00:00:00 -0800"}}}} body: {"query" : {"range" : {"date_field" : {"gte": "mar., 5 déc. 2000 02:55:00 -0800", "lte": "jeu., 7 déc. 2000 00:00:00 -0800"}}}}
- match: { hits.total: 1 } - match: { hits.total: 1 }
- do: - do:
search: search:
rest_total_hits_as_int: true rest_total_hits_as_int: true
index: test_index index: test_index
body: {"query" : {"range" : {"date_field" : {"gte": "Di, 05 Dez 2000 02:55:00 -0800", "lte": "Fr, 08 Dez 2000 00:00:00 -0800"}}}} body: {"query" : {"range" : {"date_field" : {"gte": "mar., 5 déc. 2000 02:55:00 -0800", "lte": "ven., 8 déc. 2000 00:00:00 -0800"}}}}
- match: { hits.total: 2 } - match: { hits.total: 2 }

View file

@ -1629,14 +1629,8 @@ public class SearchQueryIT extends ESIntegTestCase {
* Test range with a custom locale, e.g. "de" in this case. Documents here mention the day of week * Test range with a custom locale, e.g. "de" in this case. Documents here mention the day of week
* as "Mi" for "Mittwoch (Wednesday" and "Do" for "Donnerstag (Thursday)" and the month in the query * as "Mi" for "Mittwoch (Wednesday" and "Do" for "Donnerstag (Thursday)" and the month in the query
* as "Dez" for "Dezember (December)". * as "Dez" for "Dezember (December)".
* Note: this test currently needs the JVM arg `-Djava.locale.providers=SPI,COMPAT` to be set.
* When running with gradle this is done implicitly through the BuildPlugin, but when running from
* an IDE this might need to be set manually in the run configuration. See also CONTRIBUTING.md section
* on "Configuring IDEs And Running Tests".
*/ */
public void testRangeQueryWithLocaleMapping() throws Exception { public void testRangeQueryWithLocaleMapping() throws Exception {
assert ("SPI,COMPAT".equals(System.getProperty("java.locale.providers"))) : "`-Djava.locale.providers=SPI,COMPAT` needs to be set";
assertAcked( assertAcked(
prepareCreate("test").setMapping( prepareCreate("test").setMapping(
jsonBuilder().startObject() jsonBuilder().startObject()
@ -1644,7 +1638,7 @@ public class SearchQueryIT extends ESIntegTestCase {
.startObject("date_field") .startObject("date_field")
.field("type", "date") .field("type", "date")
.field("format", "E, d MMM yyyy HH:mm:ss Z") .field("format", "E, d MMM yyyy HH:mm:ss Z")
.field("locale", "de") .field("locale", "fr")
.endObject() .endObject()
.endObject() .endObject()
.endObject() .endObject()
@ -1653,19 +1647,19 @@ public class SearchQueryIT extends ESIntegTestCase {
indexRandom( indexRandom(
true, true,
prepareIndex("test").setId("1").setSource("date_field", "Mi, 06 Dez 2000 02:55:00 -0800"), prepareIndex("test").setId("1").setSource("date_field", "mer., 6 déc. 2000 02:55:00 -0800"),
prepareIndex("test").setId("2").setSource("date_field", "Do, 07 Dez 2000 02:55:00 -0800") prepareIndex("test").setId("2").setSource("date_field", "jeu., 7 déc. 2000 02:55:00 -0800")
); );
assertHitCount( assertHitCount(
prepareSearch("test").setQuery( prepareSearch("test").setQuery(
QueryBuilders.rangeQuery("date_field").gte("Di, 05 Dez 2000 02:55:00 -0800").lte("Do, 07 Dez 2000 00:00:00 -0800") QueryBuilders.rangeQuery("date_field").gte("mar., 5 déc. 2000 02:55:00 -0800").lte("jeu., 7 déc. 2000 00:00:00 -0800")
), ),
1L 1L
); );
assertHitCount( assertHitCount(
prepareSearch("test").setQuery( prepareSearch("test").setQuery(
QueryBuilders.rangeQuery("date_field").gte("Di, 05 Dez 2000 02:55:00 -0800").lte("Fr, 08 Dez 2000 00:00:00 -0800") QueryBuilders.rangeQuery("date_field").gte("mar., 5 déc. 2000 02:55:00 -0800").lte("ven., 8 déc. 2000 00:00:00 -0800")
), ),
2L 2L
); );

View file

@ -270,7 +270,7 @@ public class ReservedComposableIndexTemplateActionTests extends ESTestCase {
"day_of_week": { "day_of_week": {
"type": "keyword", "type": "keyword",
"script": { "script": {
"source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH))"
} }
} }
} }
@ -294,7 +294,7 @@ public class ReservedComposableIndexTemplateActionTests extends ESTestCase {
"day_of_week": { "day_of_week": {
"type": "keyword", "type": "keyword",
"script": { "script": {
"source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH))"
} }
} }
} }

View file

@ -880,11 +880,11 @@ public class DateFormattersTests extends ESTestCase {
public void testCustomLocales() { public void testCustomLocales() {
// also ensure that locale based dates are the same // also ensure that locale based dates are the same
DateFormatter formatter = DateFormatter.forPattern("E, d MMM yyyy HH:mm:ss Z").withLocale(LocaleUtils.parse("de")); DateFormatter formatter = DateFormatter.forPattern("E, d MMM yyyy HH:mm:ss Z").withLocale(LocaleUtils.parse("fr"));
assertParses("Di, 05 Dez 2000 02:55:00 -0800", formatter); assertParses("mar., 5 déc. 2000 02:55:00 -0800", formatter);
assertParses("Mi, 06 Dez 2000 02:55:00 -0800", formatter); assertParses("mer., 6 déc. 2000 02:55:00 -0800", formatter);
assertParses("Do, 07 Dez 2000 00:00:00 -0800", formatter); assertParses("jeu., 7 déc. 2000 00:00:00 -0800", formatter);
assertParses("Fr, 08 Dez 2000 00:00:00 -0800", formatter); assertParses("ven., 8 déc. 2000 00:00:00 -0800", formatter);
} }
public void testFormatsValidParsing() { public void testFormatsValidParsing() {

View file

@ -183,10 +183,10 @@ public class DateFieldMapperTests extends MapperTestCase {
public void testChangeLocale() throws IOException { public void testChangeLocale() throws IOException {
DocumentMapper mapper = createDocumentMapper( DocumentMapper mapper = createDocumentMapper(
fieldMapping(b -> b.field("type", "date").field("format", "E, d MMM yyyy HH:mm:ss Z").field("locale", "de")) fieldMapping(b -> b.field("type", "date").field("format", "E, d MMM yyyy HH:mm:ss Z").field("locale", "fr"))
); );
mapper.parse(source(b -> b.field("field", "Mi, 06 Dez 2000 02:55:00 -0800"))); mapper.parse(source(b -> b.field("field", "mer., 6 déc. 2000 02:55:00 -0800")));
} }
public void testNullValue() throws IOException { public void testNullValue() throws IOException {

View file

@ -25,7 +25,7 @@ import java.util.concurrent.TimeUnit;
public class LicenseUtils { public class LicenseUtils {
public static final String EXPIRED_FEATURE_METADATA = "es.license.expired.feature"; public static final String EXPIRED_FEATURE_METADATA = "es.license.expired.feature";
public static final DateFormatter DATE_FORMATTER = DateFormatter.forPattern("EEEE, MMMM dd, yyyy"); public static final DateFormatter DATE_FORMATTER = DateFormatter.forPattern("EEEE, MMMM dd, yyyy").withLocale(Locale.ENGLISH);
/** /**
* Exception to be thrown when a feature action requires a valid license, but license * Exception to be thrown when a feature action requires a valid license, but license

View file

@ -65,11 +65,6 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
/**
* Due to changes in JDK9 where locale data is used from CLDR, the licence message will differ in jdk 8 and jdk9+
* https://openjdk.java.net/jeps/252
* We run ES with -Djava.locale.providers=SPI,COMPAT and same option has to be applied when running this test from IDE
*/
public class ClusterStateLicenseServiceTests extends ESTestCase { public class ClusterStateLicenseServiceTests extends ESTestCase {
// must use member mock for generic // must use member mock for generic

View file

@ -13,7 +13,7 @@ setup:
day_of_week: day_of_week:
type: keyword type: keyword
script: script:
source: "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" source: "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH))"
- do: - do:
bulk: bulk:
refresh: true refresh: true

View file

@ -9,7 +9,7 @@ setup:
day_of_week: day_of_week:
type: keyword type: keyword
script: script:
source: "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" source: "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH))"
- do: - do:
bulk: bulk:
refresh: true refresh: true

View file

@ -157,12 +157,12 @@ public class DateTimeFormatProcessorTests extends AbstractSqlWireSerializingTest
new DateTimeFormat(Source.EMPTY, dateTime, l("YYYY-MM-dd HH:mm:ss.SSSSSSSS"), zoneId).makePipe().asProcessor().process(null) new DateTimeFormat(Source.EMPTY, dateTime, l("YYYY-MM-dd HH:mm:ss.SSSSSSSS"), zoneId).makePipe().asProcessor().process(null)
); );
assertEquals("+1000", new DateTimeFormat(Source.EMPTY, dateTime, l("Z"), zoneId).makePipe().asProcessor().process(null)); assertEquals("+1000", new DateTimeFormat(Source.EMPTY, dateTime, l("Z"), zoneId).makePipe().asProcessor().process(null));
assertEquals("Etc/GMT-10", new DateTimeFormat(Source.EMPTY, dateTime, l("z"), zoneId).makePipe().asProcessor().process(null)); assertEquals("GMT+10:00", new DateTimeFormat(Source.EMPTY, dateTime, l("z"), zoneId).makePipe().asProcessor().process(null));
assertEquals("Etc/GMT-10", new DateTimeFormat(Source.EMPTY, dateTime, l("VV"), zoneId).makePipe().asProcessor().process(null)); assertEquals("Etc/GMT-10", new DateTimeFormat(Source.EMPTY, dateTime, l("VV"), zoneId).makePipe().asProcessor().process(null));
zoneId = ZoneId.of("America/Sao_Paulo"); zoneId = ZoneId.of("America/Sao_Paulo");
assertEquals("-0300", new DateTimeFormat(Source.EMPTY, dateTime, l("Z"), zoneId).makePipe().asProcessor().process(null)); assertEquals("-0300", new DateTimeFormat(Source.EMPTY, dateTime, l("Z"), zoneId).makePipe().asProcessor().process(null));
assertEquals("BRT", new DateTimeFormat(Source.EMPTY, dateTime, l("z"), zoneId).makePipe().asProcessor().process(null)); assertEquals("GMT-03:00", new DateTimeFormat(Source.EMPTY, dateTime, l("z"), zoneId).makePipe().asProcessor().process(null));
assertEquals( assertEquals(
"America/Sao_Paulo", "America/Sao_Paulo",
new DateTimeFormat(Source.EMPTY, dateTime, l("VV"), zoneId).makePipe().asProcessor().process(null) new DateTimeFormat(Source.EMPTY, dateTime, l("VV"), zoneId).makePipe().asProcessor().process(null)
@ -208,7 +208,7 @@ public class DateTimeFormatProcessorTests extends AbstractSqlWireSerializingTest
); );
assertEquals("Z", new Format(Source.EMPTY, dateTime, l("Z"), zoneId).makePipe().asProcessor().process(null)); assertEquals("Z", new Format(Source.EMPTY, dateTime, l("Z"), zoneId).makePipe().asProcessor().process(null));
assertEquals("+10", new Format(Source.EMPTY, dateTime, l("z"), zoneId).makePipe().asProcessor().process(null)); assertEquals("+10", new Format(Source.EMPTY, dateTime, l("z"), zoneId).makePipe().asProcessor().process(null));
assertEquals("Etc/GMT-10", new Format(Source.EMPTY, dateTime, l("K"), zoneId).makePipe().asProcessor().process(null)); assertEquals("GMT+10:00", new Format(Source.EMPTY, dateTime, l("K"), zoneId).makePipe().asProcessor().process(null));
assertEquals("1", new Format(Source.EMPTY, dateTime, l("F"), zoneId).makePipe().asProcessor().process(null)); assertEquals("1", new Format(Source.EMPTY, dateTime, l("F"), zoneId).makePipe().asProcessor().process(null));
assertEquals("12", new Format(Source.EMPTY, dateTime, l("FF"), zoneId).makePipe().asProcessor().process(null)); assertEquals("12", new Format(Source.EMPTY, dateTime, l("FF"), zoneId).makePipe().asProcessor().process(null));

View file

@ -290,7 +290,7 @@ public class PermissionsIT extends ESRestTestCase {
painlessExecute.setJsonEntity(""" painlessExecute.setJsonEntity("""
{ {
"script": { "script": {
"source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT));" "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ENGLISH));"
}, },
"context": "keyword_field", "context": "keyword_field",
"context_setup": { "context_setup": {