diff --git a/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/MediaType.java b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/MediaType.java
index 2221f1bc97614..0cf1a609e9128 100644
--- a/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/MediaType.java
+++ b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/MediaType.java
@@ -22,8 +22,8 @@
import org.elasticsearch.common.collect.Tuple;
import java.util.Collections;
+import java.util.List;
import java.util.Map;
-import java.util.Set;
/**
* Abstracts a Media Type and a query parameter format.
@@ -44,7 +44,7 @@ public interface MediaType {
* Returns a set of HeaderValues - allowed media type values on Accept or Content-Type headers
* Also defines media type parameters for validation.
*/
- Set headerValues();
+ List headerValues();
/**
* A class to represent supported mediaType values i.e. application/json and parameters to be validated.
diff --git a/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/MediaTypeRegistry.java b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/MediaTypeRegistry.java
index 674770944516d..c0ca282b12762 100644
--- a/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/MediaTypeRegistry.java
+++ b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/MediaTypeRegistry.java
@@ -22,7 +22,6 @@
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
-import java.util.Set;
import java.util.regex.Pattern;
/**
@@ -63,12 +62,16 @@ public Map parametersFor(String typeWithSubtype) {
public MediaTypeRegistry register(T[] mediaTypes ) {
for (T mediaType : mediaTypes) {
- Set tuples = mediaType.headerValues();
- for (MediaType.HeaderValue headerValue : tuples) {
- queryParamToMediaType.put(mediaType.queryParameter(), mediaType);
- typeWithSubtypeToMediaType.put(headerValue.v1(), mediaType);
- parametersMap.put(headerValue.v1(), convertPatterns(headerValue.v2()));
- }
+ register(mediaType);
+ }
+ return this;
+ }
+
+ public MediaTypeRegistry register(T mediaType) {
+ for (MediaType.HeaderValue headerValue : mediaType.headerValues()) {
+ queryParamToMediaType.put(mediaType.queryParameter(), mediaType);
+ typeWithSubtypeToMediaType.put(headerValue.v1(), mediaType);
+ parametersMap.put(headerValue.v1(), convertPatterns(headerValue.v2()));
}
return this;
}
diff --git a/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/ParsedMediaType.java b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/ParsedMediaType.java
index a7db4608bc867..21cf1b29543c2 100644
--- a/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/ParsedMediaType.java
+++ b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/ParsedMediaType.java
@@ -106,8 +106,8 @@ public static ParsedMediaType parseMediaType(String headerValue) {
return null;
}
- public static ParsedMediaType parseMediaType(XContentType requestContentType, Map parameters) {
- ParsedMediaType parsedMediaType = parseMediaType(requestContentType.mediaTypeWithoutParameters());
+ public static ParsedMediaType parseMediaType(MediaType requestContentType, Map parameters) {
+ ParsedMediaType parsedMediaType = parseMediaType(requestContentType.headerValues().get(0).v1());
parsedMediaType.parameters.putAll(parameters);
return parsedMediaType;
}
@@ -159,6 +159,10 @@ public String toString() {
return originalHeaderValue;
}
+ public String responseContentTypeHeader() {
+ return responseContentTypeHeader(this.parameters);
+ }
+
public String responseContentTypeHeader(Map parameters) {
return this.mediaTypeWithoutParameters() + formatParameters(parameters);
}
diff --git a/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java
index b19235d3e8060..59d6b320415b4 100644
--- a/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java
+++ b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java
@@ -208,9 +208,7 @@ public XContentBuilder(XContent xContent, OutputStream os, Set includes,
}
public String getResponseContentTypeString() {
- Map parameters = responseContentType != null ?
- responseContentType.getParameters() : Collections.emptyMap();
- return responseContentType.responseContentTypeHeader(parameters);
+ return responseContentType.responseContentTypeHeader();
}
public XContentType contentType() {
diff --git a/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/XContentType.java b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/XContentType.java
index f8e0dc23f0233..8660e20c6da12 100644
--- a/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/XContentType.java
+++ b/libs/x-content/src/main/java/org/elasticsearch/common/xcontent/XContentType.java
@@ -24,8 +24,8 @@
import org.elasticsearch.common.xcontent.smile.SmileXContent;
import org.elasticsearch.common.xcontent.yaml.YamlXContent;
+import java.util.List;
import java.util.Map;
-import java.util.Set;
/**
* The content type of {@link org.elasticsearch.common.xcontent.XContent}.
@@ -57,8 +57,8 @@ public XContent xContent() {
}
@Override
- public Set headerValues() {
- return Set.of(
+ public List headerValues() {
+ return List.of(
new HeaderValue("application/json"),
new HeaderValue("application/x-ndjson"),
new HeaderValue("application/*"));
@@ -84,8 +84,8 @@ public XContent xContent() {
}
@Override
- public Set headerValues() {
- return Set.of(
+ public List headerValues() {
+ return List.of(
new HeaderValue("application/smile"));
}
},
@@ -109,8 +109,8 @@ public XContent xContent() {
}
@Override
- public Set headerValues() {
- return Set.of(
+ public List headerValues() {
+ return List.of(
new HeaderValue("application/yaml"));
}
},
@@ -134,8 +134,8 @@ public XContent xContent() {
}
@Override
- public Set headerValues() {
- return Set.of(
+ public List headerValues() {
+ return List.of(
new HeaderValue("application/cbor"));
}
},
@@ -159,8 +159,8 @@ public XContent xContent() {
}
@Override
- public Set headerValues() {
- return Set.of(
+ public List headerValues() {
+ return List.of(
new HeaderValue(VENDOR_APPLICATION_PREFIX + "json",
Map.of(COMPATIBLE_WITH_PARAMETER_NAME, VERSION_PATTERN)),
new HeaderValue(VENDOR_APPLICATION_PREFIX + "x-ndjson",
@@ -192,8 +192,8 @@ public XContent xContent() {
}
@Override
- public Set headerValues() {
- return Set.of(
+ public List headerValues() {
+ return List.of(
new HeaderValue(VENDOR_APPLICATION_PREFIX + "smile",
Map.of(COMPATIBLE_WITH_PARAMETER_NAME, VERSION_PATTERN)));
}
@@ -223,8 +223,8 @@ public XContent xContent() {
}
@Override
- public Set headerValues() {
- return Set.of(
+ public List headerValues() {
+ return List.of(
new HeaderValue(VENDOR_APPLICATION_PREFIX + "yaml",
Map.of(COMPATIBLE_WITH_PARAMETER_NAME, VERSION_PATTERN)));
}
@@ -254,8 +254,8 @@ public XContent xContent() {
}
@Override
- public Set headerValues() {
- return Set.of(
+ public List headerValues() {
+ return List.of(
new HeaderValue(VENDOR_APPLICATION_PREFIX + "cbor",
Map.of(COMPATIBLE_WITH_PARAMETER_NAME, VERSION_PATTERN)));
}
diff --git a/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/CustomMustacheFactory.java b/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/CustomMustacheFactory.java
index f47ab68a940d9..0e29450908a83 100644
--- a/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/CustomMustacheFactory.java
+++ b/modules/lang-mustache/src/main/java/org/elasticsearch/script/mustache/CustomMustacheFactory.java
@@ -30,10 +30,12 @@
import com.github.mustachejava.codes.DefaultMustache;
import com.github.mustachejava.codes.IterableCode;
import com.github.mustachejava.codes.WriteCode;
-import org.apache.lucene.search.highlight.DefaultEncoder;
import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.xcontent.MediaType;
+import org.elasticsearch.common.xcontent.ParsedMediaType;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentType;
+import org.elasticsearch.script.MustacheMediaType;
import java.io.IOException;
import java.io.StringWriter;
@@ -51,28 +53,32 @@
import java.util.regex.Pattern;
public class CustomMustacheFactory extends DefaultMustacheFactory {
+ private static final MediaType DEFAULT_MIME_TYPE = XContentType.JSON;
- static final String JSON_MIME_TYPE_WITH_CHARSET = "application/json;charset=utf-8";
- static final String JSON_MIME_TYPE = "application/json";
- static final String PLAIN_TEXT_MIME_TYPE = "text/plain";
- static final String X_WWW_FORM_URLENCODED_MIME_TYPE = "application/x-www-form-urlencoded";
-
- private static final String DEFAULT_MIME_TYPE = JSON_MIME_TYPE;
-
- private static final Map> ENCODERS = Map.of(
- JSON_MIME_TYPE_WITH_CHARSET, JsonEscapeEncoder::new,
- JSON_MIME_TYPE, JsonEscapeEncoder::new,
- PLAIN_TEXT_MIME_TYPE, DefaultEncoder::new,
- X_WWW_FORM_URLENCODED_MIME_TYPE, UrlEncoder::new);
+ private static final Map> ENCODERS = Map.of(
+ XContentType.JSON, JsonEscapeEncoder::new,
+ MustacheMediaType.PLAIN_TEXT, DefaultEncoder::new,
+ MustacheMediaType.X_WWW_FORM_URLENCODED, UrlEncoder::new);
private final Encoder encoder;
- public CustomMustacheFactory(String mimeType) {
- super();
+ public CustomMustacheFactory(MediaType mimeType) {
setObjectHandler(new CustomReflectionObjectHandler());
this.encoder = createEncoder(mimeType);
}
+ public CustomMustacheFactory(String mimeType) {
+ this(parseMediaType(mimeType));
+ }
+
+ private static MediaType parseMediaType(String mimeType) {
+ MediaType mustacheMediaType = ParsedMediaType.parseMediaType(mimeType).toMediaType(MustacheMediaType.REGISTRY);
+ if (mustacheMediaType == null) {
+ throw new IllegalArgumentException("No encoder found for MIME type [" + mimeType + "]");
+ }
+ return mustacheMediaType;
+ }
+
public CustomMustacheFactory() {
this(DEFAULT_MIME_TYPE);
}
@@ -86,14 +92,19 @@ public void encode(String value, Writer writer) {
}
}
- static Encoder createEncoder(String mimeType) {
- final Supplier supplier = ENCODERS.get(mimeType);
+ private static Encoder createEncoder(MediaType mustacheMediaType) {
+ final Supplier supplier = ENCODERS.get(mustacheMediaType);
if (supplier == null) {
- throw new IllegalArgumentException("No encoder found for MIME type [" + mimeType + "]");
+ throw new IllegalArgumentException("No encoder found for MIME type [" + mustacheMediaType + "]");
}
return supplier.get();
}
+ // package scope for testing
+ Encoder getEncoder() {
+ return encoder;
+ }
+
@Override
public MustacheVisitor createMustacheVisitor() {
return new CustomMustacheVisitor(this);
diff --git a/modules/lang-mustache/src/test/java/org/elasticsearch/script/mustache/CustomMustacheFactoryTests.java b/modules/lang-mustache/src/test/java/org/elasticsearch/script/mustache/CustomMustacheFactoryTests.java
index f5465f256c225..c2cfc96138a73 100644
--- a/modules/lang-mustache/src/test/java/org/elasticsearch/script/mustache/CustomMustacheFactoryTests.java
+++ b/modules/lang-mustache/src/test/java/org/elasticsearch/script/mustache/CustomMustacheFactoryTests.java
@@ -19,54 +19,74 @@
package org.elasticsearch.script.mustache;
+import org.elasticsearch.common.xcontent.ParsedMediaType;
+import org.elasticsearch.common.xcontent.XContentType;
+import org.elasticsearch.script.MustacheMediaType;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptEngine;
import org.elasticsearch.script.TemplateScript;
import org.elasticsearch.test.ESTestCase;
+import java.util.Collections;
import java.util.Map;
-import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonMap;
-import static org.elasticsearch.script.mustache.CustomMustacheFactory.JSON_MIME_TYPE;
-import static org.elasticsearch.script.mustache.CustomMustacheFactory.PLAIN_TEXT_MIME_TYPE;
-import static org.elasticsearch.script.mustache.CustomMustacheFactory.X_WWW_FORM_URLENCODED_MIME_TYPE;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
public class CustomMustacheFactoryTests extends ESTestCase {
+ String JSON_MIME_TYPE_WITH_CHARSET = ParsedMediaType.parseMediaType(XContentType.JSON, Map.of("charset", "utf-8"))
+ .responseContentTypeHeader();
+ String JSON_MIME_TYPE = ParsedMediaType.parseMediaType(XContentType.JSON, Collections.emptyMap())
+ .responseContentTypeHeader();
+ String PLAIN_TEXT_MIME_TYPE = ParsedMediaType.parseMediaType(MustacheMediaType.PLAIN_TEXT, Collections.emptyMap())
+ .responseContentTypeHeader();
+ String X_WWW_FORM_URLENCODED_MIME_TYPE = ParsedMediaType.parseMediaType(MustacheMediaType.X_WWW_FORM_URLENCODED, Collections.emptyMap())
+ .responseContentTypeHeader();
public void testCreateEncoder() {
{
final IllegalArgumentException e =
- expectThrows(IllegalArgumentException.class, () -> CustomMustacheFactory.createEncoder("non-existent"));
- assertThat(e.getMessage(), equalTo("No encoder found for MIME type [non-existent]"));
+ expectThrows(IllegalArgumentException.class, () -> new CustomMustacheFactory("non-existent"));
+ assertThat(e.getMessage(), equalTo("invalid media-type [non-existent]"));
}
{
- final IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> CustomMustacheFactory.createEncoder(""));
- assertThat(e.getMessage(), equalTo("No encoder found for MIME type []"));
+ final IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> new CustomMustacheFactory(""));
+ assertThat(e.getMessage(), equalTo("invalid media-type []"));
}
{
final IllegalArgumentException e =
- expectThrows(IllegalArgumentException.class, () -> CustomMustacheFactory.createEncoder("test"));
- assertThat(e.getMessage(), equalTo("No encoder found for MIME type [test]"));
+ expectThrows(IllegalArgumentException.class, () -> new CustomMustacheFactory("test"));
+ assertThat(e.getMessage(), equalTo("invalid media-type [test]"));
}
- assertThat(CustomMustacheFactory.createEncoder(CustomMustacheFactory.JSON_MIME_TYPE_WITH_CHARSET),
+ String contentType = ParsedMediaType.parseMediaType("application/json ; charset=UTF-8")
+ .responseContentTypeHeader();
+ assertThat(new CustomMustacheFactory(contentType).getEncoder(),
+ instanceOf(CustomMustacheFactory.JsonEscapeEncoder.class));
+ assertThat(new CustomMustacheFactory(JSON_MIME_TYPE_WITH_CHARSET).getEncoder(),
+ instanceOf(CustomMustacheFactory.JsonEscapeEncoder.class));
+ assertThat(new CustomMustacheFactory(JSON_MIME_TYPE).getEncoder(),
+ instanceOf(CustomMustacheFactory.JsonEscapeEncoder.class));
+
+ assertThat(new CustomMustacheFactory(PLAIN_TEXT_MIME_TYPE).getEncoder(),
+ instanceOf(CustomMustacheFactory.DefaultEncoder.class));
+ assertThat(new CustomMustacheFactory(X_WWW_FORM_URLENCODED_MIME_TYPE).getEncoder(),
+ instanceOf(CustomMustacheFactory.UrlEncoder.class));
+
+ //TODO PG should this be rejected?
+ contentType = ParsedMediaType.parseMediaType("application/json ; unknown=UTF-8")
+ .responseContentTypeHeader();
+ assertThat(new CustomMustacheFactory(contentType).getEncoder(),
instanceOf(CustomMustacheFactory.JsonEscapeEncoder.class));
- assertThat(CustomMustacheFactory.createEncoder(CustomMustacheFactory.JSON_MIME_TYPE),
- instanceOf(CustomMustacheFactory.JsonEscapeEncoder.class));
- assertThat(CustomMustacheFactory.createEncoder(CustomMustacheFactory.PLAIN_TEXT_MIME_TYPE),
- instanceOf(CustomMustacheFactory.DefaultEncoder.class));
- assertThat(CustomMustacheFactory.createEncoder(CustomMustacheFactory.X_WWW_FORM_URLENCODED_MIME_TYPE),
- instanceOf(CustomMustacheFactory.UrlEncoder.class));
}
public void testJsonEscapeEncoder() {
final ScriptEngine engine = new MustacheScriptEngine();
- final Map params = randomBoolean() ? singletonMap(Script.CONTENT_TYPE_OPTION, JSON_MIME_TYPE) : emptyMap();
+ final Map params = randomBoolean() ? singletonMap(Script.CONTENT_TYPE_OPTION, JSON_MIME_TYPE) :
+ Collections.emptyMap();
TemplateScript.Factory compiled = engine.compile(null, "{\"field\": \"{{value}}\"}", TemplateScript.CONTEXT, params);
diff --git a/qa/rolling-upgrade/src/test/resources/rest-api-spec/test/mixed_cluster/10_basic.yml b/qa/rolling-upgrade/src/test/resources/rest-api-spec/test/mixed_cluster/10_basic.yml
index b79f73639da4c..bc4067776a045 100644
--- a/qa/rolling-upgrade/src/test/resources/rest-api-spec/test/mixed_cluster/10_basic.yml
+++ b/qa/rolling-upgrade/src/test/resources/rest-api-spec/test/mixed_cluster/10_basic.yml
@@ -1,9 +1,5 @@
---
"Verify that we can still find things with the template":
- - skip:
- version: "all"
- reason: "Awaits fix: https://github.com/elastic/elasticsearch/issues/66986"
-
- do:
search_template:
rest_total_hits_as_int: true
diff --git a/qa/rolling-upgrade/src/test/resources/rest-api-spec/test/upgraded_cluster/10_basic.yml b/qa/rolling-upgrade/src/test/resources/rest-api-spec/test/upgraded_cluster/10_basic.yml
index 16da4c9eb7f0b..33e3e2ede5157 100644
--- a/qa/rolling-upgrade/src/test/resources/rest-api-spec/test/upgraded_cluster/10_basic.yml
+++ b/qa/rolling-upgrade/src/test/resources/rest-api-spec/test/upgraded_cluster/10_basic.yml
@@ -1,8 +1,5 @@
---
"Verify that we can still find things with the template":
- - skip:
- version: "all"
- reason: "Awaits fix: https://github.com/elastic/elasticsearch/issues/66986"
- do:
search_template:
diff --git a/server/src/main/java/org/elasticsearch/script/MustacheMediaType.java b/server/src/main/java/org/elasticsearch/script/MustacheMediaType.java
new file mode 100644
index 0000000000000..0344f3e233c88
--- /dev/null
+++ b/server/src/main/java/org/elasticsearch/script/MustacheMediaType.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.script;
+
+import org.elasticsearch.common.xcontent.MediaType;
+import org.elasticsearch.common.xcontent.MediaTypeRegistry;
+import org.elasticsearch.common.xcontent.XContentType;
+
+import java.util.List;
+
+public enum MustacheMediaType implements MediaType {
+
+ // JSON {
+// @Override
+// public String queryParameter() {
+// return null;
+// }
+//
+// @Override
+// public List headerValues() {
+// return List.of(
+// new HeaderValue("application/json",
+// Map.of("charset", "utf-8")));
+// }
+// },
+ PLAIN_TEXT {
+ @Override
+ public String queryParameter() {
+ return null;
+ }
+
+ @Override
+ public List headerValues() {
+ return List.of(new HeaderValue("text/plain"));
+ }
+ },
+ X_WWW_FORM_URLENCODED {
+ @Override
+ public String queryParameter() {
+ return null;
+ }
+
+ @Override
+ public List headerValues() {
+ return List.of(new HeaderValue("application/x-www-form-urlencoded"));
+ }
+ };
+
+ public static final MediaTypeRegistry REGISTRY = new MediaTypeRegistry<>()
+ .register(MustacheMediaType.values())
+ .register(XContentType.JSON); // TODO PG make JSON and ND-JSON separate? then make the headerValues return single instance?
+}
diff --git a/server/src/main/java/org/elasticsearch/script/Script.java b/server/src/main/java/org/elasticsearch/script/Script.java
index 1b5566c5ca1c5..b3f3f3e96f944 100644
--- a/server/src/main/java/org/elasticsearch/script/Script.java
+++ b/server/src/main/java/org/elasticsearch/script/Script.java
@@ -30,9 +30,11 @@
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.AbstractObjectParser;
import org.elasticsearch.common.xcontent.LoggingDeprecationHandler;
+import org.elasticsearch.common.xcontent.MediaType;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.ObjectParser;
import org.elasticsearch.common.xcontent.ObjectParser.ValueType;
+import org.elasticsearch.common.xcontent.ParsedMediaType;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
@@ -631,9 +633,10 @@ public XContentBuilder toXContent(XContentBuilder builder, Params builderParams)
builder.startObject();
String contentType = options == null ? null : options.get(CONTENT_TYPE_OPTION);
-
- if (type == ScriptType.INLINE) {
- if (contentType != null && builder.contentType().mediaType().equals(contentType)) {
+ ParsedMediaType parsedMediaType = ParsedMediaType.parseMediaType(contentType);
+ MediaType type = parsedMediaType != null ? parsedMediaType.toMediaType(MustacheMediaType.REGISTRY) : null;
+ if (this.type == ScriptType.INLINE) {
+ if (contentType != null && builder.contentType().equals(type)) {
try (InputStream stream = new BytesArray(idOrCode).streamInput()) {
builder.rawField(SOURCE_PARSE_FIELD.getPreferredName(), stream);
}
diff --git a/server/src/test/java/org/elasticsearch/rest/RestControllerTests.java b/server/src/test/java/org/elasticsearch/rest/RestControllerTests.java
index 5683352c84d14..b5612724f44a7 100644
--- a/server/src/test/java/org/elasticsearch/rest/RestControllerTests.java
+++ b/server/src/test/java/org/elasticsearch/rest/RestControllerTests.java
@@ -732,8 +732,8 @@ public Version compatibleWithVersion() {
private String randomCompatibleMimeType(byte version) {
XContentType type = randomFrom(XContentType.VND_JSON, XContentType.VND_SMILE, XContentType.VND_CBOR, XContentType.VND_YAML);
- return ParsedMediaType.parseMediaType(type.mediaType())
- .responseContentTypeHeader(Map.of(MediaType.COMPATIBLE_WITH_PARAMETER_NAME, String.valueOf(version)));
+ return ParsedMediaType.parseMediaType(type, Map.of(MediaType.COMPATIBLE_WITH_PARAMETER_NAME, String.valueOf(version)))
+ .responseContentTypeHeader();
}
private static final class TestHttpServerTransport extends AbstractLifecycleComponent implements
diff --git a/server/src/test/java/org/elasticsearch/script/ScriptTests.java b/server/src/test/java/org/elasticsearch/script/ScriptTests.java
index 58560b1d1a85a..d459beaa1998d 100644
--- a/server/src/test/java/org/elasticsearch/script/ScriptTests.java
+++ b/server/src/test/java/org/elasticsearch/script/ScriptTests.java
@@ -44,7 +44,7 @@
public class ScriptTests extends ESTestCase {
public void testScriptParsing() throws IOException {
- Script expectedScript = createScript();
+ Script expectedScript = createScript(XContentType.JSON.mediaType());
try (XContentBuilder builder = XContentFactory.contentBuilder(randomFrom(XContentType.values()))) {
expectedScript.toXContent(builder, ToXContent.EMPTY_PARAMS);
try (XContentParser parser = createParser(builder)) {
@@ -55,7 +55,17 @@ public void testScriptParsing() throws IOException {
}
public void testScriptSerialization() throws IOException {
- Script expectedScript = createScript();
+ Script expectedScript = createScript(XContentType.JSON.mediaType());
+ testSerialisation(expectedScript);
+
+ expectedScript = createScript("application/json;charset=utf-8");
+ testSerialisation(expectedScript);
+
+ expectedScript = createScript("application/json; charset=UTF-8");
+ testSerialisation(expectedScript);
+ }
+
+ private void testSerialisation(Script expectedScript) throws IOException {
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
expectedScript.writeTo(new OutputStreamStreamOutput(out));
try (ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray())) {
@@ -65,7 +75,7 @@ public void testScriptSerialization() throws IOException {
}
}
- private Script createScript() throws IOException {
+ private Script createScript(String contentType) throws IOException {
final Map params = randomBoolean() ? Collections.emptyMap() : Collections.singletonMap("key", "value");
ScriptType scriptType = randomFrom(ScriptType.values());
String script;
@@ -84,12 +94,12 @@ private Script createScript() throws IOException {
scriptType == ScriptType.STORED ? null : randomFrom("_lang1", "_lang2", "_lang3"),
script,
scriptType == ScriptType.INLINE ?
- Collections.singletonMap(Script.CONTENT_TYPE_OPTION, XContentType.JSON.mediaType()) : null, params
+ Collections.singletonMap(Script.CONTENT_TYPE_OPTION, contentType) : null, params
);
}
public void testParse() throws IOException {
- Script expectedScript = createScript();
+ Script expectedScript = createScript(XContentType.JSON.mediaType());
try (XContentBuilder builder = XContentFactory.contentBuilder(randomFrom(XContentType.values()))) {
expectedScript.toXContent(builder, ToXContent.EMPTY_PARAMS);
try (XContentParser xParser = createParser(builder)) {
diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/TextFormat.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/TextFormat.java
index 6b771dcfd7ca3..7eb36de7325e9 100644
--- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/TextFormat.java
+++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/plugin/TextFormat.java
@@ -26,7 +26,6 @@
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
-import java.util.Set;
import java.util.function.Function;
import static org.elasticsearch.xpack.sql.action.BasicFormatter.FormatOption.TEXT;
@@ -105,8 +104,8 @@ protected String eol() {
}
@Override
- public Set headerValues() {
- return Set.of(
+ public List headerValues() {
+ return List.of(
new HeaderValue(CONTENT_TYPE_TXT,
Map.of("header", "present|absent")),
new HeaderValue(VENDOR_CONTENT_TYPE_TXT,
@@ -229,8 +228,8 @@ boolean hasHeader(RestRequest request) {
}
@Override
- public Set headerValues() {
- return Set.of(
+ public List headerValues() {
+ return List.of(
new HeaderValue(CONTENT_TYPE_CSV,
Map.of("header", "present|absent","delimiter", ".+")),// more detailed parsing is in TextFormat.CSV#delimiter
new HeaderValue(VENDOR_CONTENT_TYPE_CSV,
@@ -288,8 +287,8 @@ String maybeEscape(String value, Character __) {
}
@Override
- public Set headerValues() {
- return Set.of(
+ public List headerValues() {
+ return List.of(
new HeaderValue(CONTENT_TYPE_TSV, Map.of("header", "present|absent")),
new HeaderValue(VENDOR_CONTENT_TYPE_TSV,
Map.of("header", "present|absent", COMPATIBLE_WITH_PARAMETER_NAME, VERSION_PATTERN)));