Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@
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;
Expand All @@ -49,7 +52,7 @@
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;
Expand Down Expand Up @@ -846,4 +849,42 @@ public void writeTo(StreamOutput out) throws IOException {
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,13 @@
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;
Expand All @@ -38,6 +41,7 @@
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;
Expand All @@ -48,13 +52,16 @@
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()
Expand Down Expand Up @@ -314,4 +321,83 @@ public void testNowInScript() throws IOException {
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,15 @@ public static Tuple<List<Object>, List<Object>> randomStoredFieldValues(Random r
*/
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);
Expand Down