Java API: XContentFactory creation of XContentBuilder to always be "safe", closes #1291.
This commit is contained in:
parent
d1d3340aa2
commit
bc1dd108d1
|
@ -60,10 +60,11 @@ public class BulkRequest implements ActionRequest {
|
|||
* (for example, if no id is provided, one will be generated, or usage of the create flag).
|
||||
*/
|
||||
public BulkRequest add(IndexRequest request) {
|
||||
// if the source is from a builder, we need to copy it over before adding the next one, which can come from a builder as well...
|
||||
if (request.sourceFromBuilder()) {
|
||||
request.beforeLocalFork();
|
||||
}
|
||||
request.beforeLocalFork();
|
||||
return internalAdd(request);
|
||||
}
|
||||
|
||||
private BulkRequest internalAdd(IndexRequest request) {
|
||||
requests.add(request);
|
||||
return this;
|
||||
}
|
||||
|
@ -155,19 +156,21 @@ public class BulkRequest implements ActionRequest {
|
|||
break;
|
||||
}
|
||||
// order is important, we set parent after routing, so routing will be set to parent if not set explicitly
|
||||
// we use internalAdd so we don't fork here, this allows us not to copy over the big byte array to small chunks
|
||||
// of index request. All index requests are still unsafe if applicable.
|
||||
if ("index".equals(action)) {
|
||||
if (opType == null) {
|
||||
add(new IndexRequest(index, type, id).routing(routing).parent(parent).timestamp(timestamp).version(version).versionType(versionType)
|
||||
internalAdd(new IndexRequest(index, type, id).routing(routing).parent(parent).timestamp(timestamp).version(version).versionType(versionType)
|
||||
.source(data, from, nextMarker - from, contentUnsafe)
|
||||
.percolate(percolate));
|
||||
} else {
|
||||
add(new IndexRequest(index, type, id).routing(routing).parent(parent).timestamp(timestamp).version(version).versionType(versionType)
|
||||
internalAdd(new IndexRequest(index, type, id).routing(routing).parent(parent).timestamp(timestamp).version(version).versionType(versionType)
|
||||
.create("create".equals(opType))
|
||||
.source(data, from, nextMarker - from, contentUnsafe)
|
||||
.percolate(percolate));
|
||||
}
|
||||
} else if ("create".equals(action)) {
|
||||
add(new IndexRequest(index, type, id).routing(routing).parent(parent).timestamp(timestamp).version(version).versionType(versionType)
|
||||
internalAdd(new IndexRequest(index, type, id).routing(routing).parent(parent).timestamp(timestamp).version(version).versionType(versionType)
|
||||
.create(true)
|
||||
.source(data, from, nextMarker - from, contentUnsafe)
|
||||
.percolate(percolate));
|
||||
|
|
|
@ -171,7 +171,7 @@ public class CountRequest extends BroadcastOperationRequest {
|
|||
*/
|
||||
@Required public CountRequest query(QueryBuilder queryBuilder) {
|
||||
BytesStream bos = queryBuilder.buildAsUnsafeBytes();
|
||||
this.querySource = bos.unsafeByteArray();
|
||||
this.querySource = bos.underlyingBytes();
|
||||
this.querySourceOffset = 0;
|
||||
this.querySourceLength = bos.size();
|
||||
this.querySourceUnsafe = true;
|
||||
|
@ -193,10 +193,10 @@ public class CountRequest extends BroadcastOperationRequest {
|
|||
|
||||
@Required public CountRequest query(XContentBuilder builder) {
|
||||
try {
|
||||
this.querySource = builder.unsafeBytes();
|
||||
this.querySource = builder.underlyingBytes();
|
||||
this.querySourceOffset = 0;
|
||||
this.querySourceLength = builder.unsafeBytesLength();
|
||||
this.querySourceUnsafe = true;
|
||||
this.querySourceLength = builder.underlyingBytesLength();
|
||||
this.querySourceUnsafe = false;
|
||||
return this;
|
||||
} catch (IOException e) {
|
||||
throw new ElasticSearchGenerationException("Failed to generate [" + builder + "]", e);
|
||||
|
|
|
@ -123,7 +123,7 @@ public class DeleteByQueryRequest extends IndicesReplicationOperationRequest {
|
|||
*/
|
||||
@Required public DeleteByQueryRequest query(QueryBuilder queryBuilder) {
|
||||
BytesStream bos = queryBuilder.buildAsUnsafeBytes();
|
||||
this.querySource = bos.unsafeByteArray();
|
||||
this.querySource = bos.underlyingBytes();
|
||||
this.querySourceOffset = 0;
|
||||
this.querySourceLength = bos.size();
|
||||
this.querySourceUnsafe = true;
|
||||
|
@ -158,10 +158,10 @@ public class DeleteByQueryRequest extends IndicesReplicationOperationRequest {
|
|||
|
||||
@Required public DeleteByQueryRequest query(XContentBuilder builder) {
|
||||
try {
|
||||
this.querySource = builder.unsafeBytes();
|
||||
this.querySource = builder.underlyingBytes();
|
||||
this.querySourceOffset = 0;
|
||||
this.querySourceLength = builder.unsafeBytesLength();
|
||||
this.querySourceUnsafe = true;
|
||||
this.querySourceLength = builder.underlyingBytesLength();
|
||||
this.querySourceUnsafe = false;
|
||||
return this;
|
||||
} catch (IOException e) {
|
||||
throw new ElasticSearchGenerationException("Failed to generate [" + builder + "]", e);
|
||||
|
|
|
@ -124,7 +124,6 @@ public class IndexRequest extends ShardReplicationOperationRequest {
|
|||
private int sourceOffset;
|
||||
private int sourceLength;
|
||||
private boolean sourceUnsafe;
|
||||
private boolean sourceFromBuilder;
|
||||
|
||||
private OpType opType = OpType.INDEX;
|
||||
|
||||
|
@ -174,14 +173,10 @@ public class IndexRequest extends ShardReplicationOperationRequest {
|
|||
* Before we fork on a local thread, make sure we copy over the bytes if they are unsafe
|
||||
*/
|
||||
@Override public void beforeLocalFork() {
|
||||
source();
|
||||
}
|
||||
|
||||
/**
|
||||
* Need this in case builders are used, we need to copy after adding...
|
||||
*/
|
||||
public boolean sourceFromBuilder() {
|
||||
return sourceFromBuilder;
|
||||
// only fork if copy over if source is unsafe
|
||||
if (sourceUnsafe) {
|
||||
source();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -296,7 +291,7 @@ public class IndexRequest extends ShardReplicationOperationRequest {
|
|||
* The source of the document to index, recopied to a new array if it has an offset or unsafe.
|
||||
*/
|
||||
public byte[] source() {
|
||||
if (sourceUnsafe || sourceOffset > 0) {
|
||||
if (sourceUnsafe || sourceOffset > 0 || source.length != sourceLength) {
|
||||
source = Arrays.copyOfRange(source, sourceOffset, sourceOffset + sourceLength);
|
||||
sourceOffset = 0;
|
||||
sourceUnsafe = false;
|
||||
|
@ -304,18 +299,6 @@ public class IndexRequest extends ShardReplicationOperationRequest {
|
|||
return source;
|
||||
}
|
||||
|
||||
public byte[] unsafeSource() {
|
||||
return this.source;
|
||||
}
|
||||
|
||||
public int unsafeSourceOffset() {
|
||||
return this.sourceOffset;
|
||||
}
|
||||
|
||||
public int unsafeSourceLength() {
|
||||
return this.sourceLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Index the Map as a {@link org.elasticsearch.client.Requests#INDEX_CONTENT_TYPE}.
|
||||
*
|
||||
|
@ -360,11 +343,10 @@ public class IndexRequest extends ShardReplicationOperationRequest {
|
|||
*/
|
||||
@Required public IndexRequest source(XContentBuilder sourceBuilder) {
|
||||
try {
|
||||
source = sourceBuilder.unsafeBytes();
|
||||
source = sourceBuilder.underlyingBytes();
|
||||
sourceOffset = 0;
|
||||
sourceLength = sourceBuilder.unsafeBytesLength();
|
||||
sourceUnsafe = true;
|
||||
this.sourceFromBuilder = true;
|
||||
sourceLength = sourceBuilder.underlyingBytesLength();
|
||||
sourceUnsafe = false;
|
||||
} catch (IOException e) {
|
||||
throw new ElasticSearchGenerationException("Failed to generate [" + sourceBuilder + "]", e);
|
||||
}
|
||||
|
|
|
@ -326,7 +326,7 @@ public class MoreLikeThisRequest implements ActionRequest {
|
|||
*/
|
||||
public MoreLikeThisRequest searchSource(SearchSourceBuilder sourceBuilder) {
|
||||
BytesStream bos = sourceBuilder.buildAsUnsafeBytes(Requests.CONTENT_TYPE);
|
||||
this.searchSource = bos.unsafeByteArray();
|
||||
this.searchSource = bos.underlyingBytes();
|
||||
this.searchSourceOffset = 0;
|
||||
this.searchSourceLength = bos.size();
|
||||
this.searchSourceUnsafe = true;
|
||||
|
@ -358,10 +358,10 @@ public class MoreLikeThisRequest implements ActionRequest {
|
|||
|
||||
public MoreLikeThisRequest searchSource(XContentBuilder builder) {
|
||||
try {
|
||||
this.searchSource = builder.unsafeBytes();
|
||||
this.searchSource = builder.underlyingBytes();
|
||||
this.searchSourceOffset = 0;
|
||||
this.searchSourceLength = builder.unsafeBytesLength();
|
||||
this.searchSourceUnsafe = true;
|
||||
this.searchSourceLength = builder.underlyingBytesLength();
|
||||
this.searchSourceUnsafe = false;
|
||||
return this;
|
||||
} catch (IOException e) {
|
||||
throw new ElasticSearchGenerationException("Failed to generate [" + builder + "]", e);
|
||||
|
|
|
@ -87,11 +87,13 @@ public class PercolateRequest extends SingleCustomOperationRequest {
|
|||
* Before we fork on a local thread, make sure we copy over the bytes if they are unsafe
|
||||
*/
|
||||
@Override public void beforeLocalFork() {
|
||||
source();
|
||||
if (sourceUnsafe) {
|
||||
source();
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] source() {
|
||||
if (sourceUnsafe || sourceOffset > 0) {
|
||||
if (sourceUnsafe || sourceOffset > 0 || source.length != sourceLength) {
|
||||
source = Arrays.copyOfRange(source, sourceOffset, sourceOffset + sourceLength);
|
||||
sourceOffset = 0;
|
||||
sourceUnsafe = false;
|
||||
|
@ -99,15 +101,15 @@ public class PercolateRequest extends SingleCustomOperationRequest {
|
|||
return source;
|
||||
}
|
||||
|
||||
public byte[] unsafeSource() {
|
||||
public byte[] underlyingSource() {
|
||||
return this.source;
|
||||
}
|
||||
|
||||
public int unsafeSourceOffset() {
|
||||
public int underlyingSourceOffset() {
|
||||
return this.sourceOffset;
|
||||
}
|
||||
|
||||
public int unsafeSourceLength() {
|
||||
public int underlyingSourceLength() {
|
||||
return this.sourceLength;
|
||||
}
|
||||
|
||||
|
@ -136,10 +138,10 @@ public class PercolateRequest extends SingleCustomOperationRequest {
|
|||
|
||||
@Required public PercolateRequest source(XContentBuilder sourceBuilder) {
|
||||
try {
|
||||
source = sourceBuilder.unsafeBytes();
|
||||
source = sourceBuilder.underlyingBytes();
|
||||
sourceOffset = 0;
|
||||
sourceLength = sourceBuilder.unsafeBytesLength();
|
||||
sourceUnsafe = true;
|
||||
sourceLength = sourceBuilder.underlyingBytesLength();
|
||||
sourceUnsafe = false;
|
||||
} catch (IOException e) {
|
||||
throw new ElasticSearchGenerationException("Failed to generate [" + sourceBuilder + "]", e);
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ public class TransportPercolateAction extends TransportSingleCustomOperationActi
|
|||
IndexService indexService = indicesService.indexServiceSafe(request.index());
|
||||
PercolatorService percolatorService = indexService.percolateService();
|
||||
|
||||
PercolatorExecutor.Response percolate = percolatorService.percolate(new PercolatorExecutor.SourceRequest(request.type(), request.source()));
|
||||
PercolatorExecutor.Response percolate = percolatorService.percolate(new PercolatorExecutor.SourceRequest(request.type(), request.underlyingSource(), request.underlyingSourceOffset(), request.underlyingSourceLength()));
|
||||
return new PercolateResponse(percolate.matches());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -257,7 +257,7 @@ public class SearchRequest implements ActionRequest {
|
|||
*/
|
||||
public SearchRequest source(SearchSourceBuilder sourceBuilder) {
|
||||
BytesStream bos = sourceBuilder.buildAsUnsafeBytes(Requests.CONTENT_TYPE);
|
||||
this.source = bos.unsafeByteArray();
|
||||
this.source = bos.underlyingBytes();
|
||||
this.sourceOffset = 0;
|
||||
this.sourceLength = bos.size();
|
||||
this.sourceUnsafe = true;
|
||||
|
@ -292,10 +292,10 @@ public class SearchRequest implements ActionRequest {
|
|||
|
||||
public SearchRequest source(XContentBuilder builder) {
|
||||
try {
|
||||
this.source = builder.unsafeBytes();
|
||||
this.source = builder.underlyingBytes();
|
||||
this.sourceOffset = 0;
|
||||
this.sourceLength = builder.unsafeBytesLength();
|
||||
this.sourceUnsafe = true;
|
||||
this.sourceLength = builder.underlyingBytesLength();
|
||||
this.sourceUnsafe = false;
|
||||
return this;
|
||||
} catch (IOException e) {
|
||||
throw new ElasticSearchGenerationException("Failed to generate [" + builder + "]", e);
|
||||
|
@ -348,7 +348,7 @@ public class SearchRequest implements ActionRequest {
|
|||
*/
|
||||
public SearchRequest extraSource(SearchSourceBuilder sourceBuilder) {
|
||||
BytesStream bos = sourceBuilder.buildAsUnsafeBytes(Requests.CONTENT_TYPE);
|
||||
this.extraSource = bos.unsafeByteArray();
|
||||
this.extraSource = bos.underlyingBytes();
|
||||
this.extraSourceOffset = 0;
|
||||
this.extraSourceLength = bos.size();
|
||||
this.extraSourceUnsafe = true;
|
||||
|
@ -367,10 +367,10 @@ public class SearchRequest implements ActionRequest {
|
|||
|
||||
public SearchRequest extraSource(XContentBuilder builder) {
|
||||
try {
|
||||
this.extraSource = builder.unsafeBytes();
|
||||
this.extraSource = builder.underlyingBytes();
|
||||
this.extraSourceOffset = 0;
|
||||
this.extraSourceLength = builder.unsafeBytesLength();
|
||||
this.extraSourceUnsafe = true;
|
||||
this.extraSourceLength = builder.underlyingBytesLength();
|
||||
this.extraSourceUnsafe = false;
|
||||
return this;
|
||||
} catch (IOException e) {
|
||||
throw new ElasticSearchGenerationException("Failed to generate [" + builder + "]", e);
|
||||
|
|
|
@ -21,7 +21,7 @@ package org.elasticsearch.common.io;
|
|||
|
||||
public interface BytesStream {
|
||||
|
||||
byte[] unsafeByteArray();
|
||||
byte[] underlyingBytes();
|
||||
|
||||
int size();
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ import org.elasticsearch.common.io.stream.CachedStreamOutput;
|
|||
public class CachedStreams {
|
||||
|
||||
public static void clear() {
|
||||
FastByteArrayOutputStream.Cached.clear();
|
||||
CachedStreamInput.clear();
|
||||
CachedStreamOutput.clear();
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@ package org.elasticsearch.common.io;
|
|||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
|
@ -32,32 +31,6 @@ import java.util.Arrays;
|
|||
*/
|
||||
public class FastByteArrayOutputStream extends OutputStream implements BytesStream {
|
||||
|
||||
/**
|
||||
* A thread local based cache of {@link FastByteArrayOutputStream}.
|
||||
*/
|
||||
public static class Cached {
|
||||
|
||||
private static final ThreadLocal<SoftReference<FastByteArrayOutputStream>> cache = new ThreadLocal<SoftReference<FastByteArrayOutputStream>>();
|
||||
|
||||
/**
|
||||
* Returns the cached thread local byte stream, with its internal stream cleared.
|
||||
*/
|
||||
public static FastByteArrayOutputStream cached() {
|
||||
SoftReference<FastByteArrayOutputStream> ref = cache.get();
|
||||
FastByteArrayOutputStream fos = ref == null ? null : ref.get();
|
||||
if (fos == null) {
|
||||
fos = new FastByteArrayOutputStream();
|
||||
cache.set(new SoftReference(fos));
|
||||
}
|
||||
fos.reset();
|
||||
return fos;
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
cache.remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The buffer where data is stored.
|
||||
*/
|
||||
|
@ -70,10 +43,13 @@ public class FastByteArrayOutputStream extends OutputStream implements BytesStre
|
|||
|
||||
/**
|
||||
* Creates a new byte array output stream. The buffer capacity is
|
||||
* initially 32 bytes, though its size increases if necessary.
|
||||
* initially 1024 bytes, though its size increases if necessary.
|
||||
*
|
||||
* ES: We use 1024 bytes since we mainly use this to build json/smile
|
||||
* content in memory, and rarely does the 32 byte default in ByteArrayOutputStream fits...
|
||||
*/
|
||||
public FastByteArrayOutputStream() {
|
||||
this(32);
|
||||
this(1024);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -167,7 +143,7 @@ public class FastByteArrayOutputStream extends OutputStream implements BytesStre
|
|||
* Returns the underlying byte array. Note, use {@link #size()} in order to know
|
||||
* the length of it.
|
||||
*/
|
||||
public byte[] unsafeByteArray() {
|
||||
public byte[] underlyingBytes() {
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ public final class Serializers {
|
|||
ThrowableObjectOutputStream oos = new ThrowableObjectOutputStream(os);
|
||||
oos.writeObject(t);
|
||||
oos.close();
|
||||
return os.unsafeByteArray();
|
||||
return os.underlyingBytes();
|
||||
}
|
||||
|
||||
public static Throwable throwableFromBytes(byte[] bytes) throws IOException, ClassNotFoundException {
|
||||
|
@ -62,7 +62,7 @@ public final class Serializers {
|
|||
CompactObjectOutputStream oos = new CompactObjectOutputStream(os);
|
||||
oos.writeObject(obj);
|
||||
oos.close();
|
||||
return os.unsafeByteArray();
|
||||
return os.underlyingBytes();
|
||||
}
|
||||
|
||||
public static Object objectFromBytes(byte[] bytes) throws IOException, ClassNotFoundException {
|
||||
|
|
|
@ -100,7 +100,7 @@ public class BytesStreamOutput extends StreamOutput implements BytesStream {
|
|||
* Returns the underlying byte array. Note, use {@link #size()} in order to know
|
||||
* the length of it.
|
||||
*/
|
||||
public byte[] unsafeByteArray() {
|
||||
public byte[] underlyingBytes() {
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ public class CachedStreamOutput {
|
|||
}
|
||||
|
||||
public static void pushEntry(Entry entry) {
|
||||
if (entry.bytes().unsafeByteArray().length > BYTES_LIMIT) {
|
||||
if (entry.bytes().underlyingBytes().length > BYTES_LIMIT) {
|
||||
return;
|
||||
}
|
||||
Queue<Entry> ref = cache.get();
|
||||
|
|
|
@ -65,13 +65,6 @@ public final class XContentBuilder {
|
|||
XContentBuilder.globalFieldCaseConversion = globalFieldCaseConversion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new cached builder over a cached (thread local) {@link FastByteArrayOutputStream}.
|
||||
*/
|
||||
public static XContentBuilder cachedBuilder(XContent xContent) throws IOException {
|
||||
return new XContentBuilder(xContent, FastByteArrayOutputStream.Cached.cached());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new builder using a fresh {@link FastByteArrayOutputStream}.
|
||||
*/
|
||||
|
@ -945,22 +938,22 @@ public final class XContentBuilder {
|
|||
|
||||
/**
|
||||
* Returns the unsafe bytes (thread local bound). Make sure to use it with
|
||||
* {@link #unsafeBytesLength()}.
|
||||
* {@link #underlyingBytesLength()}.
|
||||
*
|
||||
* <p>Only applicable when the builder is constructed with {@link FastByteArrayOutputStream}.
|
||||
*/
|
||||
public byte[] unsafeBytes() throws IOException {
|
||||
public byte[] underlyingBytes() throws IOException {
|
||||
close();
|
||||
return ((BytesStream) bos).unsafeByteArray();
|
||||
return ((BytesStream) bos).underlyingBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unsafe bytes length (thread local bound). Make sure to use it with
|
||||
* {@link #unsafeBytes()}.
|
||||
* {@link #underlyingBytes()}.
|
||||
*
|
||||
* <p>Only applicable when the builder is constructed with {@link FastByteArrayOutputStream}.
|
||||
*/
|
||||
public int unsafeBytesLength() throws IOException {
|
||||
public int underlyingBytesLength() throws IOException {
|
||||
close();
|
||||
return ((BytesStream) bos).size();
|
||||
}
|
||||
|
@ -968,7 +961,7 @@ public final class XContentBuilder {
|
|||
/**
|
||||
* Returns the actual stream used.
|
||||
*/
|
||||
public BytesStream unsafeStream() throws IOException {
|
||||
public BytesStream underlyingStream() throws IOException {
|
||||
close();
|
||||
return (BytesStream) bos;
|
||||
}
|
||||
|
@ -990,6 +983,6 @@ public final class XContentBuilder {
|
|||
*/
|
||||
public String string() throws IOException {
|
||||
close();
|
||||
return Unicode.fromBytes(unsafeBytes(), 0, unsafeBytesLength());
|
||||
return Unicode.fromBytes(underlyingBytes(), 0, underlyingBytesLength());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,9 +49,6 @@ public class XContentFactory {
|
|||
|
||||
/**
|
||||
* Returns a content builder using JSON format ({@link org.elasticsearch.common.xcontent.XContentType#JSON}.
|
||||
*
|
||||
* <p>Note, this should be passed directly to an API, if its going to be used around, make sure you use
|
||||
* {@link #safeJsonBuilder()}.
|
||||
*/
|
||||
public static XContentBuilder jsonBuilder() throws IOException {
|
||||
return contentBuilder(XContentType.JSON);
|
||||
|
@ -64,19 +61,8 @@ public class XContentFactory {
|
|||
return new XContentBuilder(JsonXContent.jsonXContent, os);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a content builder using JSON format ({@link org.elasticsearch.common.xcontent.XContentType#JSON}
|
||||
* that can be used outside of the scope of passing it directly to an API call.
|
||||
*/
|
||||
public static XContentBuilder safeJsonBuilder() throws IOException {
|
||||
return unCachedContentBuilder(XContentType.JSON);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a content builder using SMILE format ({@link org.elasticsearch.common.xcontent.XContentType#SMILE}.
|
||||
*
|
||||
* <p>Note, this should be passed directly to an API, if its going to be used around, make sure you use
|
||||
* {@link #safeSmileBuilder()}.
|
||||
*/
|
||||
public static XContentBuilder smileBuilder() throws IOException {
|
||||
return contentBuilder(XContentType.SMILE);
|
||||
|
@ -89,14 +75,6 @@ public class XContentFactory {
|
|||
return new XContentBuilder(SmileXContent.smileXContent, os);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a content builder using SMILE format ({@link org.elasticsearch.common.xcontent.XContentType#SMILE}
|
||||
* that can be used outside of the scope of passing it directly to an API call.
|
||||
*/
|
||||
public static XContentBuilder safeSmileBuilder() throws IOException {
|
||||
return unCachedContentBuilder(XContentType.SMILE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a xcontent builder that will output the result into the provided output stream.
|
||||
*/
|
||||
|
@ -121,18 +99,6 @@ public class XContentFactory {
|
|||
throw new ElasticSearchIllegalArgumentException("No matching content type for " + type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a binary content builder for the provided content type.
|
||||
*/
|
||||
public static XContentBuilder unCachedContentBuilder(XContentType type) throws IOException {
|
||||
if (type == XContentType.JSON) {
|
||||
return JsonXContent.unCachedContentBuilder();
|
||||
} else if (type == XContentType.SMILE) {
|
||||
return SmileXContent.unCachedContentBuilder();
|
||||
}
|
||||
throw new ElasticSearchIllegalArgumentException("No matching content type for " + type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link org.elasticsearch.common.xcontent.XContent} for the provided content type.
|
||||
*/
|
||||
|
|
|
@ -24,9 +24,17 @@ import org.elasticsearch.common.jackson.JsonEncoding;
|
|||
import org.elasticsearch.common.jackson.JsonFactory;
|
||||
import org.elasticsearch.common.jackson.JsonGenerator;
|
||||
import org.elasticsearch.common.jackson.JsonParser;
|
||||
import org.elasticsearch.common.xcontent.*;
|
||||
import org.elasticsearch.common.xcontent.XContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentGenerator;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* A JSON based content implementation using Jackson.
|
||||
|
@ -36,10 +44,6 @@ import java.io.*;
|
|||
public class JsonXContent implements XContent {
|
||||
|
||||
public static XContentBuilder contentBuilder() throws IOException {
|
||||
return XContentBuilder.cachedBuilder(jsonXContent);
|
||||
}
|
||||
|
||||
public static XContentBuilder unCachedContentBuilder() throws IOException {
|
||||
return XContentBuilder.builder(jsonXContent);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,10 +23,18 @@ import org.elasticsearch.common.io.FastStringReader;
|
|||
import org.elasticsearch.common.jackson.JsonEncoding;
|
||||
import org.elasticsearch.common.jackson.smile.SmileFactory;
|
||||
import org.elasticsearch.common.jackson.smile.SmileGenerator;
|
||||
import org.elasticsearch.common.xcontent.*;
|
||||
import org.elasticsearch.common.xcontent.XContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentGenerator;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.common.xcontent.json.JsonXContentParser;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* A JSON based content implementation using Jackson.
|
||||
|
@ -36,10 +44,6 @@ import java.io.*;
|
|||
public class SmileXContent implements XContent {
|
||||
|
||||
public static XContentBuilder contentBuilder() throws IOException {
|
||||
return XContentBuilder.cachedBuilder(smileXContent);
|
||||
}
|
||||
|
||||
public static XContentBuilder unCachedContentBuilder() throws IOException {
|
||||
return XContentBuilder.builder(smileXContent);
|
||||
}
|
||||
|
||||
|
|
|
@ -163,7 +163,7 @@ public abstract class BlobStoreGateway extends SharedStorageGateway {
|
|||
MetaData.Builder.toXContent(metaData, builder, ToXContent.EMPTY_PARAMS);
|
||||
builder.endObject();
|
||||
builder.close();
|
||||
metaDataBlobContainer.writeBlob(newMetaData, new ByteArrayInputStream(out.unsafeByteArray(), 0, out.size()), out.size());
|
||||
metaDataBlobContainer.writeBlob(newMetaData, new ByteArrayInputStream(out.underlyingBytes(), 0, out.size()), out.size());
|
||||
} catch (IOException e) {
|
||||
throw new GatewayException("Failed to write metadata [" + newMetaData + "]", e);
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ public class NettyHttpChannel implements HttpChannel {
|
|||
XContentBuilder builder = ((XContentRestResponse) response).builder();
|
||||
if (builder.payload() instanceof CachedStreamOutput.Entry) {
|
||||
releaseContentListener = new NettyTransport.CacheFutureListener((CachedStreamOutput.Entry) builder.payload());
|
||||
buf = ChannelBuffers.wrappedBuffer(builder.unsafeBytes(), 0, builder.unsafeBytesLength());
|
||||
buf = ChannelBuffers.wrappedBuffer(builder.underlyingBytes(), 0, builder.underlyingBytesLength());
|
||||
} else if (response.contentThreadSafe()) {
|
||||
buf = ChannelBuffers.wrappedBuffer(response.content(), 0, response.contentLength());
|
||||
} else {
|
||||
|
|
|
@ -462,7 +462,7 @@ public abstract class BlobStoreIndexShardGateway extends AbstractIndexShardCompo
|
|||
if (bos.size() < 4) {
|
||||
return;
|
||||
}
|
||||
BytesStreamInput si = new BytesStreamInput(bos.unsafeByteArray(), 0, bos.size());
|
||||
BytesStreamInput si = new BytesStreamInput(bos.underlyingBytes(), 0, bos.size());
|
||||
int position;
|
||||
while (true) {
|
||||
try {
|
||||
|
@ -497,7 +497,7 @@ public abstract class BlobStoreIndexShardGateway extends AbstractIndexShardCompo
|
|||
|
||||
int leftOver = bos.size() - position;
|
||||
if (leftOver > 0) {
|
||||
newBos.write(bos.unsafeByteArray(), position, leftOver);
|
||||
newBos.write(bos.underlyingBytes(), position, leftOver);
|
||||
}
|
||||
|
||||
bos = newBos;
|
||||
|
|
|
@ -198,8 +198,8 @@ public class PercolatorExecutor extends AbstractIndexComponent {
|
|||
try {
|
||||
XContentBuilder builder = XContentFactory.smileBuilder()
|
||||
.startObject().field("query", queryBuilder).endObject();
|
||||
BytesStream unsafeBytes = builder.unsafeStream();
|
||||
addQuery(name, unsafeBytes.unsafeByteArray(), 0, unsafeBytes.size());
|
||||
BytesStream unsafeBytes = builder.underlyingStream();
|
||||
addQuery(name, unsafeBytes.underlyingBytes(), 0, unsafeBytes.size());
|
||||
} catch (IOException e) {
|
||||
throw new ElasticSearchException("Failed to add query [" + name + "]", e);
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public abstract class BaseQueryBuilder implements QueryBuilder {
|
|||
|
||||
@Override public String toString() {
|
||||
try {
|
||||
XContentBuilder builder = XContentFactory.safeJsonBuilder();
|
||||
XContentBuilder builder = XContentFactory.jsonBuilder();
|
||||
builder.prettyPrint();
|
||||
toXContent(builder, EMPTY_PARAMS);
|
||||
return builder.string();
|
||||
|
@ -50,7 +50,7 @@ public abstract class BaseQueryBuilder implements QueryBuilder {
|
|||
try {
|
||||
XContentBuilder builder = XContentFactory.contentBuilder(contentType);
|
||||
toXContent(builder, EMPTY_PARAMS);
|
||||
return builder.unsafeStream();
|
||||
return builder.underlyingStream();
|
||||
} catch (Exception e) {
|
||||
throw new QueryBuilderException("Failed to build query", e);
|
||||
}
|
||||
|
|
|
@ -158,7 +158,7 @@ public class IndexQueryParserService extends AbstractIndexComponent {
|
|||
XContentParser parser = null;
|
||||
try {
|
||||
BytesStream unsafeBytes = queryBuilder.buildAsUnsafeBytes();
|
||||
parser = XContentFactory.xContent(unsafeBytes.unsafeByteArray(), 0, unsafeBytes.size()).createParser(unsafeBytes.unsafeByteArray(), 0, unsafeBytes.size());
|
||||
parser = XContentFactory.xContent(unsafeBytes.underlyingBytes(), 0, unsafeBytes.size()).createParser(unsafeBytes.underlyingBytes(), 0, unsafeBytes.size());
|
||||
return parse(cache.get(), parser);
|
||||
} catch (QueryParsingException e) {
|
||||
throw e;
|
||||
|
|
|
@ -731,13 +731,13 @@ public class InternalIndexShard extends AbstractIndexShardComponent implements I
|
|||
// ignore if closed....
|
||||
return;
|
||||
}
|
||||
logger.warn("check index [failure]\n{}", new String(os.unsafeByteArray(), 0, os.size()));
|
||||
logger.warn("check index [failure]\n{}", new String(os.underlyingBytes(), 0, os.size()));
|
||||
if (throwException) {
|
||||
throw new IndexShardException(shardId, "index check failure");
|
||||
}
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("check index [success]\n{}", new String(os.unsafeByteArray(), 0, os.size()));
|
||||
logger.debug("check index [success]\n{}", new String(os.underlyingBytes(), 0, os.size()));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -218,14 +218,14 @@ public class FsTranslog extends AbstractIndexShardComponent implements Translog
|
|||
out.seek(0);
|
||||
out.writeInt(size - 4);
|
||||
|
||||
Location location = current.add(out.unsafeByteArray(), 0, size);
|
||||
Location location = current.add(out.underlyingBytes(), 0, size);
|
||||
if (syncOnEachOperation) {
|
||||
current.sync();
|
||||
}
|
||||
FsTranslogFile trans = this.trans;
|
||||
if (trans != null) {
|
||||
try {
|
||||
location = trans.add(out.unsafeByteArray(), 0, size);
|
||||
location = trans.add(out.underlyingBytes(), 0, size);
|
||||
} catch (ClosedChannelException e) {
|
||||
// ignore
|
||||
}
|
||||
|
|
|
@ -70,11 +70,11 @@ public class XContentRestResponse extends AbstractRestResponse {
|
|||
}
|
||||
|
||||
@Override public byte[] content() throws IOException {
|
||||
return builder.unsafeBytes();
|
||||
return builder.underlyingBytes();
|
||||
}
|
||||
|
||||
@Override public int contentLength() throws IOException {
|
||||
return builder.unsafeBytesLength();
|
||||
return builder.underlyingBytesLength();
|
||||
}
|
||||
|
||||
@Override public RestStatus status() {
|
||||
|
|
|
@ -384,7 +384,7 @@ public class SearchSourceBuilder implements ToXContent {
|
|||
try {
|
||||
XContentBuilder builder = XContentFactory.contentBuilder(contentType);
|
||||
toXContent(builder, ToXContent.EMPTY_PARAMS);
|
||||
return builder.unsafeStream();
|
||||
return builder.underlyingStream();
|
||||
} catch (Exception e) {
|
||||
throw new SearchSourceBuilderException("Failed to build search source", e);
|
||||
}
|
||||
|
|
|
@ -455,7 +455,7 @@ public class NettyTransport extends AbstractLifecycleComponent<Transport> implem
|
|||
|
||||
CachedStreamOutput.Entry cachedEntry = CachedStreamOutput.popEntry();
|
||||
TransportStreams.buildRequest(cachedEntry, requestId, action, message, options);
|
||||
ChannelBuffer buffer = ChannelBuffers.wrappedBuffer(cachedEntry.bytes().unsafeByteArray(), 0, cachedEntry.bytes().size());
|
||||
ChannelBuffer buffer = ChannelBuffers.wrappedBuffer(cachedEntry.bytes().underlyingBytes(), 0, cachedEntry.bytes().size());
|
||||
ChannelFuture future = targetChannel.write(buffer);
|
||||
future.addListener(new CacheFutureListener(cachedEntry));
|
||||
// We handle close connection exception in the #exceptionCaught method, which is the main reason we want to add this future
|
||||
|
|
|
@ -72,7 +72,7 @@ public class NettyTransportChannel implements TransportChannel {
|
|||
}
|
||||
CachedStreamOutput.Entry cachedEntry = CachedStreamOutput.popEntry();
|
||||
TransportStreams.buildResponse(cachedEntry, requestId, message, options);
|
||||
ChannelBuffer buffer = ChannelBuffers.wrappedBuffer(cachedEntry.bytes().unsafeByteArray(), 0, cachedEntry.bytes().size());
|
||||
ChannelBuffer buffer = ChannelBuffers.wrappedBuffer(cachedEntry.bytes().underlyingBytes(), 0, cachedEntry.bytes().size());
|
||||
ChannelFuture future = channel.write(buffer);
|
||||
future.addListener(new NettyTransport.CacheFutureListener(cachedEntry));
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ public class NettyTransportChannel implements TransportChannel {
|
|||
too.writeObject(tx);
|
||||
too.close();
|
||||
}
|
||||
ChannelBuffer buffer = ChannelBuffers.wrappedBuffer(stream.unsafeByteArray(), 0, stream.size());
|
||||
ChannelBuffer buffer = ChannelBuffers.wrappedBuffer(stream.underlyingBytes(), 0, stream.size());
|
||||
buffer.setInt(0, buffer.writerIndex() - 4); // update real size.
|
||||
ChannelFuture future = channel.write(buffer);
|
||||
future.addListener(new NettyTransport.CacheFutureListener(cachedEntry));
|
||||
|
|
|
@ -117,7 +117,7 @@ public class TransportStreams {
|
|||
message.writeTo(stream);
|
||||
stream.flush();
|
||||
}
|
||||
TransportStreams.writeHeader(cachedEntry.bytes().unsafeByteArray(), cachedEntry.bytes().size(), requestId, status);
|
||||
TransportStreams.writeHeader(cachedEntry.bytes().underlyingBytes(), cachedEntry.bytes().size(), requestId, status);
|
||||
}
|
||||
|
||||
public static void buildResponse(CachedStreamOutput.Entry cachedEntry, final long requestId, Streamable message, TransportResponseOptions options) throws IOException {
|
||||
|
@ -136,6 +136,6 @@ public class TransportStreams {
|
|||
message.writeTo(stream);
|
||||
stream.flush();
|
||||
}
|
||||
TransportStreams.writeHeader(cachedEntry.bytes().unsafeByteArray(), cachedEntry.bytes().size(), requestId, status);
|
||||
TransportStreams.writeHeader(cachedEntry.bytes().underlyingBytes(), cachedEntry.bytes().size(), requestId, status);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ public class BuilderRawFieldTests {
|
|||
XContentBuilder builder = XContentFactory.contentBuilder(type);
|
||||
builder.startObject();
|
||||
builder.field("field1", "value1");
|
||||
builder.rawField("_source", XContentFactory.unCachedContentBuilder(type).startObject().field("s_field", "s_value").endObject().copiedBytes());
|
||||
builder.rawField("_source", XContentFactory.contentBuilder(type).startObject().field("s_field", "s_value").endObject().copiedBytes());
|
||||
builder.field("field2", "value2");
|
||||
builder.endObject();
|
||||
|
||||
|
|
|
@ -199,7 +199,9 @@ public class DocumentActionsTests extends AbstractNodesTests {
|
|||
assertThat(getResult.index(), equalTo(getConcreteIndexName()));
|
||||
assertThat("cycle #" + i, getResult.sourceAsString(), equalTo(source("1", "test").string()));
|
||||
getResult = client1.get(getRequest("test").type("type1").id("2")).actionGet();
|
||||
assertThat("cycle #" + i, getResult.sourceAsString(), equalTo(source("2", "test2").string()));
|
||||
String ste1 = getResult.sourceAsString();
|
||||
String ste2 = source("2", "test2").string();
|
||||
assertThat("cycle #" + i, ste1, equalTo(ste2));
|
||||
assertThat(getResult.index(), equalTo(getConcreteIndexName()));
|
||||
}
|
||||
|
||||
|
|
|
@ -117,10 +117,10 @@ public class MemcachedRestChannel implements RestChannel {
|
|||
XContentBuilder builder = ((XContentRestResponse) response).builder();
|
||||
if (builder.payload() instanceof CachedStreamOutput.Entry) {
|
||||
releaseContentListener = new NettyTransport.CacheFutureListener((CachedStreamOutput.Entry) builder.payload());
|
||||
ChannelBuffer buf = ChannelBuffers.wrappedBuffer(builder.unsafeBytes(), 0, builder.unsafeBytesLength());
|
||||
ChannelBuffer buf = ChannelBuffers.wrappedBuffer(builder.underlyingBytes(), 0, builder.underlyingBytesLength());
|
||||
writeBuffer = ChannelBuffers.wrappedBuffer(writeBuffer, buf);
|
||||
} else if (response.contentThreadSafe()) {
|
||||
ChannelBuffer buf = ChannelBuffers.wrappedBuffer(builder.unsafeBytes(), 0, builder.unsafeBytesLength());
|
||||
ChannelBuffer buf = ChannelBuffers.wrappedBuffer(builder.underlyingBytes(), 0, builder.underlyingBytesLength());
|
||||
writeBuffer = ChannelBuffers.wrappedBuffer(writeBuffer, buf);
|
||||
} else {
|
||||
writeBuffer.writeBytes(response.content(), 0, response.contentLength());
|
||||
|
|
Loading…
Reference in New Issue