summaryrefslogtreecommitdiff
path: root/core/src/main/java/org/elasticsearch/common
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/main/java/org/elasticsearch/common')
-rw-r--r--core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java1
-rw-r--r--core/src/main/java/org/elasticsearch/common/settings/Settings.java22
-rw-r--r--core/src/main/java/org/elasticsearch/common/settings/loader/SettingsLoaderFactory.java26
-rw-r--r--core/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java39
-rw-r--r--core/src/main/java/org/elasticsearch/common/xcontent/XContentGenerator.java30
-rw-r--r--core/src/main/java/org/elasticsearch/common/xcontent/XContentHelper.java79
-rw-r--r--core/src/main/java/org/elasticsearch/common/xcontent/XContentType.java36
-rw-r--r--core/src/main/java/org/elasticsearch/common/xcontent/json/JsonXContentGenerator.java15
8 files changed, 229 insertions, 19 deletions
diff --git a/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java b/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java
index 279be58e01..69adc5878f 100644
--- a/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java
+++ b/core/src/main/java/org/elasticsearch/common/settings/ClusterSettings.java
@@ -237,6 +237,7 @@ public final class ClusterSettings extends AbstractScopedSettings {
HttpTransportSettings.SETTING_CORS_ALLOW_METHODS,
HttpTransportSettings.SETTING_CORS_ALLOW_HEADERS,
HttpTransportSettings.SETTING_HTTP_DETAILED_ERRORS_ENABLED,
+ HttpTransportSettings.SETTING_HTTP_CONTENT_TYPE_REQUIRED,
HttpTransportSettings.SETTING_HTTP_MAX_CONTENT_LENGTH,
HttpTransportSettings.SETTING_HTTP_MAX_CHUNK_SIZE,
HttpTransportSettings.SETTING_HTTP_MAX_HEADER_SIZE,
diff --git a/core/src/main/java/org/elasticsearch/common/settings/Settings.java b/core/src/main/java/org/elasticsearch/common/settings/Settings.java
index 883f1e7c82..579be7ce31 100644
--- a/core/src/main/java/org/elasticsearch/common/settings/Settings.java
+++ b/core/src/main/java/org/elasticsearch/common/settings/Settings.java
@@ -37,6 +37,7 @@ import org.elasticsearch.common.unit.SizeValue;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
+import org.elasticsearch.common.xcontent.XContentType;
import java.io.IOException;
import java.io.InputStream;
@@ -960,7 +961,9 @@ public final class Settings implements ToXContent {
/**
* Loads settings from the actual string content that represents them using the
* {@link SettingsLoaderFactory#loaderFromSource(String)}.
+ * @deprecated use {@link #loadFromSource(String, XContentType)} to avoid content type detection
*/
+ @Deprecated
public Builder loadFromSource(String source) {
SettingsLoader settingsLoader = SettingsLoaderFactory.loaderFromSource(source);
try {
@@ -973,8 +976,23 @@ public final class Settings implements ToXContent {
}
/**
+ * Loads settings from the actual string content that represents them using the
+ * {@link SettingsLoaderFactory#loaderFromXContentType(XContentType)} method to obtain a loader
+ */
+ public Builder loadFromSource(String source, XContentType xContentType) {
+ SettingsLoader settingsLoader = SettingsLoaderFactory.loaderFromXContentType(xContentType);
+ try {
+ Map<String, String> loadedSettings = settingsLoader.load(source);
+ put(loadedSettings);
+ } catch (Exception e) {
+ throw new SettingsException("Failed to load settings from [" + source + "]", e);
+ }
+ return this;
+ }
+
+ /**
* Loads settings from a url that represents them using the
- * {@link SettingsLoaderFactory#loaderFromSource(String)}.
+ * {@link SettingsLoaderFactory#loaderFromResource(String)}.
*/
public Builder loadFromPath(Path path) throws IOException {
// NOTE: loadFromStream will close the input stream
@@ -983,7 +1001,7 @@ public final class Settings implements ToXContent {
/**
* Loads settings from a stream that represents them using the
- * {@link SettingsLoaderFactory#loaderFromSource(String)}.
+ * {@link SettingsLoaderFactory#loaderFromResource(String)}.
*/
public Builder loadFromStream(String resourceName, InputStream is) throws IOException {
SettingsLoader settingsLoader = SettingsLoaderFactory.loaderFromResource(resourceName);
diff --git a/core/src/main/java/org/elasticsearch/common/settings/loader/SettingsLoaderFactory.java b/core/src/main/java/org/elasticsearch/common/settings/loader/SettingsLoaderFactory.java
index 5f2da22c5f..5d8cb4918b 100644
--- a/core/src/main/java/org/elasticsearch/common/settings/loader/SettingsLoaderFactory.java
+++ b/core/src/main/java/org/elasticsearch/common/settings/loader/SettingsLoaderFactory.java
@@ -19,6 +19,8 @@
package org.elasticsearch.common.settings.loader;
+import org.elasticsearch.common.xcontent.XContentType;
+
/**
* A class holding factory methods for settings loaders that attempts
* to infer the type of the underlying settings content.
@@ -33,9 +35,7 @@ public final class SettingsLoaderFactory {
* name. This factory method assumes that if the resource name ends
* with ".json" then the content should be parsed as JSON, else if
* the resource name ends with ".yml" or ".yaml" then the content
- * should be parsed as YAML, else if the resource name ends with
- * ".properties" then the content should be parsed as properties,
- * otherwise default to attempting to parse as JSON. Note that the
+ * should be parsed as YAML, otherwise throws an exception. Note that the
* parsers returned by this method will not accept null-valued
* keys.
*
@@ -59,13 +59,15 @@ public final class SettingsLoaderFactory {
* contains an opening and closing brace ('{' and '}') then the
* content should be parsed as JSON, else if the underlying content
* fails this condition but contains a ':' then the content should
- * be parsed as YAML, and otherwise should be parsed as properties.
+ * be parsed as YAML, and otherwise throws an exception.
* Note that the JSON and YAML parsers returned by this method will
* accept null-valued keys.
*
* @param source The underlying settings content.
* @return A settings loader.
+ * @deprecated use {@link #loaderFromXContentType(XContentType)} instead
*/
+ @Deprecated
public static SettingsLoader loaderFromSource(String source) {
if (source.indexOf('{') != -1 && source.indexOf('}') != -1) {
return new JsonSettingsLoader(true);
@@ -76,4 +78,20 @@ public final class SettingsLoaderFactory {
}
}
+ /**
+ * Returns a {@link SettingsLoader} based on the {@link XContentType}. Note only {@link XContentType#JSON} and
+ * {@link XContentType#YAML} are supported
+ *
+ * @param xContentType The content type
+ * @return A settings loader.
+ */
+ public static SettingsLoader loaderFromXContentType(XContentType xContentType) {
+ if (xContentType == XContentType.JSON) {
+ return new JsonSettingsLoader(true);
+ } else if (xContentType == XContentType.YAML) {
+ return new YamlSettingsLoader(true);
+ } else {
+ throw new IllegalArgumentException("unsupported content type [" + xContentType + "]");
+ }
+ }
}
diff --git a/core/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java b/core/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java
index df34ec726f..189e9d3c8d 100644
--- a/core/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java
+++ b/core/src/main/java/org/elasticsearch/common/xcontent/XContentBuilder.java
@@ -964,21 +964,60 @@ public final class XContentBuilder implements BytesStream, Releasable, Flushable
// Raw fields
//////////////////////////////////
+ /**
+ * Writes a raw field with the value taken from the bytes in the stream
+ * @deprecated use {@link #rawField(String, InputStream, XContentType)} to avoid content type auto-detection
+ */
+ @Deprecated
public XContentBuilder rawField(String name, InputStream value) throws IOException {
generator.writeRawField(name, value);
return this;
}
+ /**
+ * Writes a raw field with the value taken from the bytes in the stream
+ */
+ public XContentBuilder rawField(String name, InputStream value, XContentType contentType) throws IOException {
+ generator.writeRawField(name, value, contentType);
+ return this;
+ }
+
+ /**
+ * Writes a raw field with the given bytes as the value
+ * @deprecated use {@link #rawField(String name, BytesReference, XContentType)} to avoid content type auto-detection
+ */
+ @Deprecated
public XContentBuilder rawField(String name, BytesReference value) throws IOException {
generator.writeRawField(name, value);
return this;
}
+ /**
+ * Writes a raw field with the given bytes as the value
+ */
+ public XContentBuilder rawField(String name, BytesReference value, XContentType contentType) throws IOException {
+ generator.writeRawField(name, value, contentType);
+ return this;
+ }
+
+ /**
+ * Writes a value with the source coming directly from the bytes
+ * @deprecated use {@link #rawValue(BytesReference, XContentType)} to avoid content type auto-detection
+ */
+ @Deprecated
public XContentBuilder rawValue(BytesReference value) throws IOException {
generator.writeRawValue(value);
return this;
}
+ /**
+ * Writes a value with the source coming directly from the bytes
+ */
+ public XContentBuilder rawValue(BytesReference value, XContentType contentType) throws IOException {
+ generator.writeRawValue(value, contentType);
+ return this;
+ }
+
public XContentBuilder copyCurrentStructure(XContentParser parser) throws IOException {
generator.copyCurrentStructure(parser);
return this;
diff --git a/core/src/main/java/org/elasticsearch/common/xcontent/XContentGenerator.java b/core/src/main/java/org/elasticsearch/common/xcontent/XContentGenerator.java
index 478f3a8a08..60a188ca6c 100644
--- a/core/src/main/java/org/elasticsearch/common/xcontent/XContentGenerator.java
+++ b/core/src/main/java/org/elasticsearch/common/xcontent/XContentGenerator.java
@@ -86,12 +86,42 @@ public interface XContentGenerator extends Closeable, Flushable {
void writeBinary(byte[] value, int offset, int length) throws IOException;
+ /**
+ * Writes a raw field with the value taken from the bytes in the stream
+ * @deprecated use {@link #writeRawField(String, InputStream, XContentType)} to avoid content type auto-detection
+ */
+ @Deprecated
void writeRawField(String name, InputStream value) throws IOException;
+ /**
+ * Writes a raw field with the value taken from the bytes in the stream
+ */
+ void writeRawField(String name, InputStream value, XContentType xContentType) throws IOException;
+
+ /**
+ * Writes a raw field with the given bytes as the value
+ * @deprecated use {@link #writeRawField(String, BytesReference, XContentType)} to avoid content type auto-detection
+ */
+ @Deprecated
void writeRawField(String name, BytesReference value) throws IOException;
+ /**
+ * Writes a raw field with the given bytes as the value
+ */
+ void writeRawField(String name, BytesReference value, XContentType xContentType) throws IOException;
+
+ /**
+ * Writes a value with the source coming directly from the bytes
+ * @deprecated use {@link #writeRawValue(BytesReference, XContentType)} to avoid content type auto-detection
+ */
+ @Deprecated
void writeRawValue(BytesReference value) throws IOException;
+ /**
+ * Writes a value with the source coming directly from the bytes
+ */
+ void writeRawValue(BytesReference value, XContentType xContentType) throws IOException;
+
void copyCurrentStructure(XContentParser parser) throws IOException;
/**
diff --git a/core/src/main/java/org/elasticsearch/common/xcontent/XContentHelper.java b/core/src/main/java/org/elasticsearch/common/xcontent/XContentHelper.java
index 6cf8d12c21..dd7508280d 100644
--- a/core/src/main/java/org/elasticsearch/common/xcontent/XContentHelper.java
+++ b/core/src/main/java/org/elasticsearch/common/xcontent/XContentHelper.java
@@ -41,6 +41,11 @@ import static org.elasticsearch.common.xcontent.ToXContent.EMPTY_PARAMS;
@SuppressWarnings("unchecked")
public class XContentHelper {
+ /**
+ * Creates a parser based on the bytes provided
+ * @deprecated use {@link #createParser(NamedXContentRegistry, BytesReference, XContentType)} to avoid content type auto-detection
+ */
+ @Deprecated
public static XContentParser createParser(NamedXContentRegistry xContentRegistry, BytesReference bytes) throws IOException {
Compressor compressor = CompressorFactory.compressor(bytes);
if (compressor != null) {
@@ -48,17 +53,49 @@ public class XContentHelper {
if (compressedInput.markSupported() == false) {
compressedInput = new BufferedInputStream(compressedInput);
}
- XContentType contentType = XContentFactory.xContentType(compressedInput);
+ final XContentType contentType = XContentFactory.xContentType(compressedInput);
return XContentFactory.xContent(contentType).createParser(xContentRegistry, compressedInput);
} else {
return XContentFactory.xContent(bytes).createParser(xContentRegistry, bytes.streamInput());
}
}
+ /**
+ * Creates a parser for the bytes using the supplied content-type
+ */
+ public static XContentParser createParser(NamedXContentRegistry xContentRegistry, BytesReference bytes,
+ XContentType xContentType) throws IOException {
+ Objects.requireNonNull(xContentType);
+ Compressor compressor = CompressorFactory.compressor(bytes);
+ if (compressor != null) {
+ InputStream compressedInput = compressor.streamInput(bytes.streamInput());
+ if (compressedInput.markSupported() == false) {
+ compressedInput = new BufferedInputStream(compressedInput);
+ }
+ return XContentFactory.xContent(xContentType).createParser(xContentRegistry, compressedInput);
+ } else {
+ return xContentType.xContent().createParser(xContentRegistry, bytes.streamInput());
+ }
+ }
+
+ /**
+ * Converts the given bytes into a map that is optionally ordered.
+ * @deprecated this method relies on auto-detection of content type. Use {@link #convertToMap(BytesReference, boolean, XContentType)}
+ * instead with the proper {@link XContentType}
+ */
+ @Deprecated
public static Tuple<XContentType, Map<String, Object>> convertToMap(BytesReference bytes, boolean ordered)
throws ElasticsearchParseException {
+ return convertToMap(bytes, ordered, null);
+ }
+
+ /**
+ * Converts the given bytes into a map that is optionally ordered. The provided {@link XContentType} must be non-null.
+ */
+ public static Tuple<XContentType, Map<String, Object>> convertToMap(BytesReference bytes, boolean ordered, XContentType xContentType)
+ throws ElasticsearchParseException {
try {
- XContentType contentType;
+ final XContentType contentType;
InputStream input;
Compressor compressor = CompressorFactory.compressor(bytes);
if (compressor != null) {
@@ -66,13 +103,12 @@ public class XContentHelper {
if (compressedStreamInput.markSupported() == false) {
compressedStreamInput = new BufferedInputStream(compressedStreamInput);
}
- contentType = XContentFactory.xContentType(compressedStreamInput);
input = compressedStreamInput;
} else {
- contentType = XContentFactory.xContentType(bytes);
input = bytes.streamInput();
}
- return new Tuple<>(contentType, convertToMap(XContentFactory.xContent(contentType), input, ordered));
+ contentType = xContentType != null ? xContentType : XContentFactory.xContentType(input);
+ return new Tuple<>(Objects.requireNonNull(contentType), convertToMap(XContentFactory.xContent(contentType), input, ordered));
} catch (IOException e) {
throw new ElasticsearchParseException("Failed to parse content to map", e);
}
@@ -105,15 +141,27 @@ public class XContentHelper {
}
}
+ @Deprecated
public static String convertToJson(BytesReference bytes, boolean reformatJson) throws IOException {
return convertToJson(bytes, reformatJson, false);
}
+ @Deprecated
public static String convertToJson(BytesReference bytes, boolean reformatJson, boolean prettyPrint) throws IOException {
- XContentType xContentType = XContentFactory.xContentType(bytes);
+ return convertToJson(bytes, reformatJson, prettyPrint, XContentFactory.xContentType(bytes));
+ }
+
+ public static String convertToJson(BytesReference bytes, boolean reformatJson, XContentType xContentType) throws IOException {
+ return convertToJson(bytes, reformatJson, false, xContentType);
+ }
+
+ public static String convertToJson(BytesReference bytes, boolean reformatJson, boolean prettyPrint, XContentType xContentType)
+ throws IOException {
+ Objects.requireNonNull(xContentType);
if (xContentType == XContentType.JSON && !reformatJson) {
return bytes.utf8ToString();
}
+
// It is safe to use EMPTY here because this never uses namedObject
try (XContentParser parser = XContentFactory.xContent(xContentType).createParser(NamedXContentRegistry.EMPTY,
bytes.streamInput())) {
@@ -365,7 +413,10 @@ public class XContentHelper {
/**
* Writes a "raw" (bytes) field, handling cases where the bytes are compressed, and tries to optimize writing using
* {@link XContentBuilder#rawField(String, org.elasticsearch.common.bytes.BytesReference)}.
+ * @deprecated use {@link #writeRawField(String, BytesReference, XContentType, XContentBuilder, Params)} to avoid content type
+ * auto-detection
*/
+ @Deprecated
public static void writeRawField(String field, BytesReference source, XContentBuilder builder, ToXContent.Params params) throws IOException {
Compressor compressor = CompressorFactory.compressor(source);
if (compressor != null) {
@@ -377,6 +428,22 @@ public class XContentHelper {
}
/**
+ * Writes a "raw" (bytes) field, handling cases where the bytes are compressed, and tries to optimize writing using
+ * {@link XContentBuilder#rawField(String, org.elasticsearch.common.bytes.BytesReference, XContentType)}.
+ */
+ public static void writeRawField(String field, BytesReference source, XContentType xContentType, XContentBuilder builder,
+ ToXContent.Params params) throws IOException {
+ Objects.requireNonNull(xContentType);
+ Compressor compressor = CompressorFactory.compressor(source);
+ if (compressor != null) {
+ InputStream compressedStreamInput = compressor.streamInput(source.streamInput());
+ builder.rawField(field, compressedStreamInput, xContentType);
+ } else {
+ builder.rawField(field, source, xContentType);
+ }
+ }
+
+ /**
* Returns the bytes that represent the XContent output of the provided {@link ToXContent} object, using the provided
* {@link XContentType}. Wraps the output into a new anonymous object.
*/
diff --git a/core/src/main/java/org/elasticsearch/common/xcontent/XContentType.java b/core/src/main/java/org/elasticsearch/common/xcontent/XContentType.java
index ddd736e0d0..8e3c298270 100644
--- a/core/src/main/java/org/elasticsearch/common/xcontent/XContentType.java
+++ b/core/src/main/java/org/elasticsearch/common/xcontent/XContentType.java
@@ -29,6 +29,7 @@ import org.elasticsearch.common.xcontent.yaml.YamlXContent;
import java.io.IOException;
import java.util.Locale;
+import java.util.Objects;
/**
* The content type of {@link org.elasticsearch.common.xcontent.XContent}.
@@ -40,7 +41,7 @@ public enum XContentType implements Writeable {
*/
JSON(0) {
@Override
- protected String mediaTypeWithoutParameters() {
+ public String mediaTypeWithoutParameters() {
return "application/json";
}
@@ -64,7 +65,7 @@ public enum XContentType implements Writeable {
*/
SMILE(1) {
@Override
- protected String mediaTypeWithoutParameters() {
+ public String mediaTypeWithoutParameters() {
return "application/smile";
}
@@ -83,7 +84,7 @@ public enum XContentType implements Writeable {
*/
YAML(2) {
@Override
- protected String mediaTypeWithoutParameters() {
+ public String mediaTypeWithoutParameters() {
return "application/yaml";
}
@@ -102,7 +103,7 @@ public enum XContentType implements Writeable {
*/
CBOR(3) {
@Override
- protected String mediaTypeWithoutParameters() {
+ public String mediaTypeWithoutParameters() {
return "application/cbor";
}
@@ -117,12 +118,18 @@ public enum XContentType implements Writeable {
}
};
+ /**
+ * Accepts either a format string, which is equivalent to {@link XContentType#shortName()} or a media type that optionally has
+ * parameters and attempts to match the value to an {@link XContentType}. The comparisons are done in lower case format and this method
+ * also supports a wildcard accept for {@code application/*}. This method can be used to parse the {@code Accept} HTTP header or a
+ * format query string parameter. This method will return {@code null} if no match is found
+ */
public static XContentType fromMediaTypeOrFormat(String mediaType) {
if (mediaType == null) {
return null;
}
for (XContentType type : values()) {
- if (isSameMediaTypeAs(mediaType, type)) {
+ if (isSameMediaTypeOrFormatAs(mediaType, type)) {
return type;
}
}
@@ -133,7 +140,22 @@ public enum XContentType implements Writeable {
return null;
}
- private static boolean isSameMediaTypeAs(String stringType, XContentType type) {
+ /**
+ * Attempts to match the given media type with the known {@link XContentType} values. This match is done in a case-insensitive manner.
+ * The provided media type should not include any parameters. This method is suitable for parsing part of the {@code Content-Type}
+ * HTTP header. This method will return {@code null} if no match is found
+ */
+ public static XContentType fromMediaType(String mediaType) {
+ final String lowercaseMediaType = Objects.requireNonNull(mediaType, "mediaType cannot be null").toLowerCase(Locale.ROOT);
+ for (XContentType type : values()) {
+ if (type.mediaTypeWithoutParameters().equals(lowercaseMediaType)) {
+ return type;
+ }
+ }
+ return null;
+ }
+
+ private static boolean isSameMediaTypeOrFormatAs(String stringType, XContentType type) {
return type.mediaTypeWithoutParameters().equalsIgnoreCase(stringType) ||
stringType.toLowerCase(Locale.ROOT).startsWith(type.mediaTypeWithoutParameters().toLowerCase(Locale.ROOT) + ";") ||
type.shortName().equalsIgnoreCase(stringType);
@@ -157,7 +179,7 @@ public enum XContentType implements Writeable {
public abstract XContent xContent();
- protected abstract String mediaTypeWithoutParameters();
+ public abstract String mediaTypeWithoutParameters();
public static XContentType readFrom(StreamInput in) throws IOException {
int index = in.readVInt();
diff --git a/core/src/main/java/org/elasticsearch/common/xcontent/json/JsonXContentGenerator.java b/core/src/main/java/org/elasticsearch/common/xcontent/json/JsonXContentGenerator.java
index 07ae16b96c..1e09f8334f 100644
--- a/core/src/main/java/org/elasticsearch/common/xcontent/json/JsonXContentGenerator.java
+++ b/core/src/main/java/org/elasticsearch/common/xcontent/json/JsonXContentGenerator.java
@@ -307,6 +307,11 @@ public class JsonXContentGenerator implements XContentGenerator {
if (contentType == null) {
throw new IllegalArgumentException("Can't write raw bytes whose xcontent-type can't be guessed");
}
+ writeRawField(name, content, contentType);
+ }
+
+ @Override
+ public void writeRawField(String name, InputStream content, XContentType contentType) throws IOException {
if (mayWriteRawData(contentType) == false) {
// EMPTY is safe here because we never call namedObject when writing raw data
try (XContentParser parser = XContentFactory.xContent(contentType).createParser(NamedXContentRegistry.EMPTY, content)) {
@@ -328,6 +333,11 @@ public class JsonXContentGenerator implements XContentGenerator {
if (contentType == null) {
throw new IllegalArgumentException("Can't write raw bytes whose xcontent-type can't be guessed");
}
+ writeRawField(name, content, contentType);
+ }
+
+ @Override
+ public final void writeRawField(String name, BytesReference content, XContentType contentType) throws IOException {
if (mayWriteRawData(contentType) == false) {
writeFieldName(name);
copyRawValue(content, contentType.xContent());
@@ -345,6 +355,11 @@ public class JsonXContentGenerator implements XContentGenerator {
if (contentType == null) {
throw new IllegalArgumentException("Can't write raw bytes whose xcontent-type can't be guessed");
}
+ writeRawValue(content, contentType);
+ }
+
+ @Override
+ public final void writeRawValue(BytesReference content, XContentType contentType) throws IOException {
if (mayWriteRawData(contentType) == false) {
copyRawValue(content, contentType.xContent());
} else {