UpdateRequest implements ToXContent (#23289)

This commit changes UpdateRequest so that it implements the ToXContentObject interface.
This commit is contained in:
Tanguy Leroux 2017-02-21 15:20:15 +01:00 committed by GitHub
parent cc865cbc96
commit 3a0fc526bb
3 changed files with 138 additions and 3 deletions

View File

@ -30,8 +30,11 @@ import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.lucene.uid.Versions;
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.VersionType;
@ -49,7 +52,7 @@ import java.util.Map;
import static org.elasticsearch.action.ValidateActions.addValidationError;
public class UpdateRequest extends InstanceShardOperationRequest<UpdateRequest>
implements DocWriteRequest<UpdateRequest>, WriteRequest<UpdateRequest> {
implements DocWriteRequest<UpdateRequest>, WriteRequest<UpdateRequest>, ToXContentObject {
private String type;
private String id;
@ -846,4 +849,42 @@ public class UpdateRequest extends InstanceShardOperationRequest<UpdateRequest>
out.writeBoolean(scriptedUpsert);
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
if (docAsUpsert) {
builder.field("doc_as_upsert", docAsUpsert);
}
if (doc != null) {
XContentType xContentType = doc.getContentType();
try (XContentParser parser = XContentHelper.createParser(NamedXContentRegistry.EMPTY, doc.source(), xContentType)) {
builder.field("doc");
builder.copyCurrentStructure(parser);
}
}
if (script != null) {
builder.field("script", script);
}
if (upsertRequest != null) {
XContentType xContentType = upsertRequest.getContentType();
try (XContentParser parser = XContentHelper.createParser(NamedXContentRegistry.EMPTY, upsertRequest.source(), xContentType)) {
builder.field("upsert");
builder.copyCurrentStructure(parser);
}
}
if (scriptedUpsert) {
builder.field("scripted_upsert", scriptedUpsert);
}
if (detectNoop == false) {
builder.field("detect_noop", detectNoop);
}
if (fields != null) {
builder.array("fields", fields);
}
if (fetchSourceContext != null) {
builder.field("_source", fetchSourceContext);
}
builder.endObject();
return builder;
}
}

View File

@ -22,10 +22,13 @@ package org.elasticsearch.action.update;
import org.elasticsearch.Version;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.stream.Streamable;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.env.Environment;
import org.elasticsearch.index.get.GetResult;
@ -38,6 +41,7 @@ import org.elasticsearch.script.ScriptService;
import org.elasticsearch.script.ScriptSettings;
import org.elasticsearch.script.ScriptType;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.RandomObjects;
import org.elasticsearch.watcher.ResourceWatcherService;
import java.io.IOException;
@ -48,13 +52,16 @@ import java.util.Map;
import java.util.function.Function;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.common.xcontent.XContentHelper.toXContent;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertToXContentEquivalent;
import static org.hamcrest.Matchers.arrayContaining;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.notNullValue;
public class UpdateRequestTests extends ESTestCase {
public void testUpdateRequest() throws Exception {
public void testFromXContent() throws Exception {
UpdateRequest request = new UpdateRequest("test", "type", "1");
// simple script
request.fromXContent(createParser(XContentFactory.jsonBuilder()
@ -314,4 +321,83 @@ public class UpdateRequestTests extends ESTestCase {
assertThat(action, instanceOf(IndexRequest.class));
}
}
public void testToAndFromXContent() throws IOException {
UpdateRequest updateRequest = new UpdateRequest();
updateRequest.detectNoop(randomBoolean());
if (randomBoolean()) {
XContentType xContentType = randomFrom(XContentType.values());
BytesReference source = RandomObjects.randomSource(random(), xContentType);
updateRequest.doc(new IndexRequest().source(source, xContentType));
updateRequest.docAsUpsert(randomBoolean());
} else {
ScriptType scriptType = randomFrom(ScriptType.values());
String scriptLang = (scriptType != ScriptType.STORED) ? randomAsciiOfLength(10) : null;
String scriptIdOrCode = randomAsciiOfLength(10);
int nbScriptParams = randomIntBetween(0, 5);
Map<String, Object> scriptParams = new HashMap<>(nbScriptParams);
for (int i = 0; i < nbScriptParams; i++) {
scriptParams.put(randomAsciiOfLength(5), randomAsciiOfLength(5));
}
updateRequest.script(new Script(scriptType, scriptLang, scriptIdOrCode, scriptParams));
updateRequest.scriptedUpsert(randomBoolean());
}
if (randomBoolean()) {
XContentType xContentType = randomFrom(XContentType.values());
BytesReference source = RandomObjects.randomSource(random(), xContentType);
updateRequest.upsert(new IndexRequest().source(source, xContentType));
}
if (randomBoolean()) {
String[] fields = new String[randomIntBetween(0, 5)];
for (int i = 0; i < fields.length; i++) {
fields[i] = randomAsciiOfLength(5);
}
updateRequest.fields(fields);
}
if (randomBoolean()) {
if (randomBoolean()) {
updateRequest.fetchSource(randomBoolean());
} else {
String[] includes = new String[randomIntBetween(0, 5)];
for (int i = 0; i < includes.length; i++) {
includes[i] = randomAsciiOfLength(5);
}
String[] excludes = new String[randomIntBetween(0, 5)];
for (int i = 0; i < excludes.length; i++) {
excludes[i] = randomAsciiOfLength(5);
}
if (randomBoolean()) {
updateRequest.fetchSource(includes, excludes);
}
}
}
XContentType xContentType = randomFrom(XContentType.values());
boolean humanReadable = randomBoolean();
BytesReference originalBytes = XContentHelper.toXContent(updateRequest, xContentType, humanReadable);
if (randomBoolean()) {
try (XContentParser parser = createParser(xContentType.xContent(), originalBytes)) {
originalBytes = shuffleXContent(parser, randomBoolean()).bytes();
}
}
UpdateRequest parsedUpdateRequest = new UpdateRequest();
try (XContentParser parser = createParser(xContentType.xContent(), originalBytes)) {
parsedUpdateRequest.fromXContent(parser);
assertNull(parser.nextToken());
}
assertEquals(updateRequest.detectNoop(), parsedUpdateRequest.detectNoop());
assertEquals(updateRequest.docAsUpsert(), parsedUpdateRequest.docAsUpsert());
assertEquals(updateRequest.docAsUpsert(), parsedUpdateRequest.docAsUpsert());
assertEquals(updateRequest.script(), parsedUpdateRequest.script());
assertEquals(updateRequest.scriptedUpsert(), parsedUpdateRequest.scriptedUpsert());
assertArrayEquals(updateRequest.fields(), parsedUpdateRequest.fields());
assertEquals(updateRequest.fetchSource(), parsedUpdateRequest.fetchSource());
BytesReference finalBytes = toXContent(parsedUpdateRequest, xContentType, humanReadable);
assertToXContentEquivalent(originalBytes, finalBytes, xContentType);
}
}

View File

@ -152,7 +152,15 @@ public final class RandomObjects {
*/
public static BytesReference randomSource(Random random) {
//the source can be stored in any format and eventually converted when retrieved depending on the format of the response
XContentType xContentType = RandomPicks.randomFrom(random, XContentType.values());
return randomSource(random, RandomPicks.randomFrom(random, XContentType.values()));
}
/**
* Returns a random source in a given XContentType containing a random number of fields, objects and array, with maximum depth 5.
*
* @param random Random generator
*/
public static BytesReference randomSource(Random random, XContentType xContentType) {
try (XContentBuilder builder = XContentFactory.contentBuilder(xContentType)) {
builder.startObject();
addFields(random, builder, 0);