summaryrefslogtreecommitdiff
path: root/core/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java
diff options
context:
space:
mode:
authorJay Modi <jaymode@users.noreply.github.com>2017-02-02 14:07:13 -0500
committerGitHub <noreply@github.com>2017-02-02 14:07:13 -0500
commit7520a107bee67099338813728147d2aee25ed240 (patch)
tree22828e74c5aa601c185c36c7463665fbfeaa4c51 /core/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java
parentb41d5747f0bd67dad05c8168312ba456bcdaebda (diff)
Optionally require a valid content type for all rest requests with content (#22691)
This change adds a strict mode for xcontent parsing on the rest layer. The strict mode will be off by default for 5.x and in a separate commit will be enabled by default for 6.0. The strict mode, which can be enabled by setting `http.content_type.required: true` in 5.x, will require that all incoming rest requests have a valid and supported content type header before the request is dispatched. In the non-strict mode, the Content-Type header will be inspected and if it is not present or not valid, we will continue with auto detection of content like we have done previously. The content type header is parsed to the matching XContentType value with the only exception being for plain text requests. This value is then passed on with the content bytes so that we can reduce the number of places where we need to auto-detect the content type. As part of this, many transport requests and builders were updated to provide methods that accepted the XContentType along with the bytes and the methods that would rely on auto-detection have been deprecated. In the non-strict mode, deprecation warnings are issued whenever a request with body doesn't provide the Content-Type header. See #19388
Diffstat (limited to 'core/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java')
-rw-r--r--core/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java119
1 files changed, 96 insertions, 23 deletions
diff --git a/core/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java b/core/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java
index 203483d89b..798c08bd18 100644
--- a/core/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java
+++ b/core/src/main/java/org/elasticsearch/action/admin/indices/create/CreateIndexRequest.java
@@ -21,6 +21,7 @@ package org.elasticsearch.action.admin.indices.create;
import org.elasticsearch.ElasticsearchGenerationException;
import org.elasticsearch.ElasticsearchParseException;
+import org.elasticsearch.Version;
import org.elasticsearch.action.ActionRequestValidationException;
import org.elasticsearch.action.IndicesRequest;
import org.elasticsearch.action.admin.indices.alias.Alias;
@@ -43,10 +44,11 @@ import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import java.io.IOException;
-import java.nio.charset.StandardCharsets;
+import java.io.UncheckedIOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import static org.elasticsearch.action.ValidateActions.addValidationError;
@@ -169,19 +171,29 @@ public class CreateIndexRequest extends AcknowledgedRequest<CreateIndexRequest>
}
/**
- * The settings to create the index with (either json/yaml/properties format)
+ * The settings to create the index with (either json or yaml format)
+ * @deprecated use {@link #source(String, XContentType)} instead to avoid content type detection
*/
+ @Deprecated
public CreateIndexRequest settings(String source) {
this.settings = Settings.builder().loadFromSource(source).build();
return this;
}
/**
+ * The settings to create the index with (either json or yaml format)
+ */
+ public CreateIndexRequest settings(String source, XContentType xContentType) {
+ this.settings = Settings.builder().loadFromSource(source, xContentType).build();
+ return this;
+ }
+
+ /**
* Allows to set the settings using a json builder.
*/
public CreateIndexRequest settings(XContentBuilder builder) {
try {
- settings(builder.string());
+ settings(builder.string(), builder.contentType());
} catch (IOException e) {
throw new ElasticsearchGenerationException("Failed to generate json settings from builder", e);
}
@@ -196,7 +208,7 @@ public class CreateIndexRequest extends AcknowledgedRequest<CreateIndexRequest>
try {
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON);
builder.map(source);
- settings(builder.string());
+ settings(builder.string(), XContentType.JSON);
} catch (IOException e) {
throw new ElasticsearchGenerationException("Failed to generate [" + source + "]", e);
}
@@ -208,13 +220,42 @@ public class CreateIndexRequest extends AcknowledgedRequest<CreateIndexRequest>
*
* @param type The mapping type
* @param source The mapping source
+ * @deprecated use {@link #mapping(String, String, XContentType)} to avoid content type detection
*/
+ @Deprecated
public CreateIndexRequest mapping(String type, String source) {
+ return mapping(type, new BytesArray(source), XContentFactory.xContentType(source));
+ }
+
+ /**
+ * Adds mapping that will be added when the index gets created.
+ *
+ * @param type The mapping type
+ * @param source The mapping source
+ * @param xContentType The content type of the source
+ */
+ public CreateIndexRequest mapping(String type, String source, XContentType xContentType) {
+ return mapping(type, new BytesArray(source), xContentType);
+ }
+
+ /**
+ * Adds mapping that will be added when the index gets created.
+ *
+ * @param type The mapping type
+ * @param source The mapping source
+ * @param xContentType the content type of the mapping source
+ */
+ private CreateIndexRequest mapping(String type, BytesReference source, XContentType xContentType) {
if (mappings.containsKey(type)) {
throw new IllegalStateException("mappings for type \"" + type + "\" were already defined");
}
- mappings.put(type, source);
- return this;
+ Objects.requireNonNull(xContentType);
+ try {
+ mappings.put(type, XContentHelper.convertToJson(source, false, false, xContentType));
+ return this;
+ } catch (IOException e) {
+ throw new UncheckedIOException("failed to convert to json", e);
+ }
}
/**
@@ -232,15 +273,7 @@ public class CreateIndexRequest extends AcknowledgedRequest<CreateIndexRequest>
* @param source The mapping source
*/
public CreateIndexRequest mapping(String type, XContentBuilder source) {
- if (mappings.containsKey(type)) {
- throw new IllegalStateException("mappings for type \"" + type + "\" were already defined");
- }
- try {
- mappings.put(type, source.string());
- } catch (IOException e) {
- throw new IllegalArgumentException("Failed to build json for mapping request", e);
- }
- return this;
+ return mapping(type, source.bytes(), source.contentType());
}
/**
@@ -261,7 +294,7 @@ public class CreateIndexRequest extends AcknowledgedRequest<CreateIndexRequest>
try {
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON);
builder.map(source);
- return mapping(type, builder.string());
+ return mapping(type, builder);
} catch (IOException e) {
throw new ElasticsearchGenerationException("Failed to generate [" + source + "]", e);
}
@@ -331,9 +364,18 @@ public class CreateIndexRequest extends AcknowledgedRequest<CreateIndexRequest>
/**
* Sets the settings and mappings as a single source.
+ * @deprecated use {@link #source(String, XContentType)}
*/
+ @Deprecated
public CreateIndexRequest source(String source) {
- return source(source.getBytes(StandardCharsets.UTF_8));
+ return source(new BytesArray(source));
+ }
+
+ /**
+ * Sets the settings and mappings as a single source.
+ */
+ public CreateIndexRequest source(String source, XContentType xContentType) {
+ return source(new BytesArray(source), xContentType);
}
/**
@@ -345,7 +387,9 @@ public class CreateIndexRequest extends AcknowledgedRequest<CreateIndexRequest>
/**
* Sets the settings and mappings as a single source.
+ * @deprecated use {@link #source(byte[], XContentType)}
*/
+ @Deprecated
public CreateIndexRequest source(byte[] source) {
return source(source, 0, source.length);
}
@@ -353,6 +397,15 @@ public class CreateIndexRequest extends AcknowledgedRequest<CreateIndexRequest>
/**
* Sets the settings and mappings as a single source.
*/
+ public CreateIndexRequest source(byte[] source, XContentType xContentType) {
+ return source(source, 0, source.length, xContentType);
+ }
+
+ /**
+ * Sets the settings and mappings as a single source.
+ * @deprecated use {@link #source(byte[], int, int, XContentType)}
+ */
+ @Deprecated
public CreateIndexRequest source(byte[] source, int offset, int length) {
return source(new BytesArray(source, offset, length));
}
@@ -360,13 +413,27 @@ public class CreateIndexRequest extends AcknowledgedRequest<CreateIndexRequest>
/**
* Sets the settings and mappings as a single source.
*/
+ public CreateIndexRequest source(byte[] source, int offset, int length, XContentType xContentType) {
+ return source(new BytesArray(source, offset, length), xContentType);
+ }
+
+ /**
+ * Sets the settings and mappings as a single source.
+ * @deprecated use {@link #source(BytesReference, XContentType)}
+ */
+ @Deprecated
public CreateIndexRequest source(BytesReference source) {
XContentType xContentType = XContentFactory.xContentType(source);
- if (xContentType != null) {
- source(XContentHelper.convertToMap(source, false).v2());
- } else {
- settings(source.utf8ToString());
- }
+ source(source, xContentType);
+ return this;
+ }
+
+ /**
+ * Sets the settings and mappings as a single source.
+ */
+ public CreateIndexRequest source(BytesReference source, XContentType xContentType) {
+ Objects.requireNonNull(xContentType);
+ source(XContentHelper.convertToMap(source, false, xContentType).v2());
return this;
}
@@ -483,7 +550,13 @@ public class CreateIndexRequest extends AcknowledgedRequest<CreateIndexRequest>
readTimeout(in);
int size = in.readVInt();
for (int i = 0; i < size; i++) {
- mappings.put(in.readString(), in.readString());
+ final String type = in.readString();
+ String source = in.readString();
+ if (in.getVersion().before(Version.V_6_0_0_alpha1_UNRELEASED)) { // TODO change to 5.3.0 after backport
+ // we do not know the content type that comes from earlier versions so we autodetect and convert
+ source = XContentHelper.convertToJson(new BytesArray(source), false, false, XContentFactory.xContentType(source));
+ }
+ mappings.put(type, source);
}
int customSize = in.readVInt();
for (int i = 0; i < customSize; i++) {