Skip to content

Commit e1425e2

Browse files
committed
Add fromxcontent methods to delete response
This commit adds the parsing fromXContent() methods to the DeleteResponse class. The method is based on a ObjectParser because it is easier to use when parsing parent abstract classes like DocWriteResponse. It also changes the ReplicationResponse.ShardInfo so that it now implements ToXContentObject. This way, the ShardInfo.fromXContent() method can be used by the DeleteResponse's ObjectParser. Backport of elastic#22680 in 5.x branch
1 parent 33e1dfc commit e1425e2

File tree

2 files changed

+138
-1
lines changed

2 files changed

+138
-1
lines changed

core/src/main/java/org/elasticsearch/action/delete/DeleteResponse.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,19 @@
2020
package org.elasticsearch.action.delete;
2121

2222
import org.elasticsearch.action.DocWriteResponse;
23+
import org.elasticsearch.cluster.metadata.IndexMetaData;
24+
import org.elasticsearch.common.ParseField;
25+
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
2326
import org.elasticsearch.common.xcontent.XContentBuilder;
27+
import org.elasticsearch.common.xcontent.XContentParser;
28+
import org.elasticsearch.index.Index;
2429
import org.elasticsearch.index.shard.ShardId;
2530
import org.elasticsearch.rest.RestStatus;
2631

2732
import java.io.IOException;
2833

34+
import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constructorArg;
35+
2936
/**
3037
* The response of the delete action.
3138
*
@@ -34,6 +41,8 @@
3441
*/
3542
public class DeleteResponse extends DocWriteResponse {
3643

44+
private static final String FOUND = "found";
45+
3746
public DeleteResponse() {
3847

3948
}
@@ -49,11 +58,34 @@ public RestStatus status() {
4958

5059
@Override
5160
public XContentBuilder innerToXContent(XContentBuilder builder, Params params) throws IOException {
52-
builder.field("found", result == Result.DELETED);
61+
builder.field(FOUND, result == Result.DELETED);
5362
super.innerToXContent(builder, params);
5463
return builder;
5564
}
5665

66+
private static final ConstructingObjectParser<DeleteResponse, Void> PARSER;
67+
static {
68+
PARSER = new ConstructingObjectParser<>(DeleteResponse.class.getName(),
69+
args -> {
70+
// index uuid and shard id are unknown and can't be parsed back for now.
71+
ShardId shardId = new ShardId(new Index((String) args[0], IndexMetaData.INDEX_UUID_NA_VALUE), -1);
72+
String type = (String) args[1];
73+
String id = (String) args[2];
74+
long version = (long) args[3];
75+
ShardInfo shardInfo = (ShardInfo) args[5];
76+
boolean found = (boolean) args[6];
77+
DeleteResponse deleteResponse = new DeleteResponse(shardId, type, id, version, found);
78+
deleteResponse.setShardInfo(shardInfo);
79+
return deleteResponse;
80+
});
81+
DocWriteResponse.declareParserFields(PARSER);
82+
PARSER.declareBoolean(constructorArg(), new ParseField(FOUND));
83+
}
84+
85+
public static DeleteResponse fromXContent(XContentParser parser) throws IOException {
86+
return PARSER.apply(parser, null);
87+
}
88+
5789
@Override
5890
public String toString() {
5991
StringBuilder builder = new StringBuilder();
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.action.delete;
21+
22+
import org.elasticsearch.action.DocWriteResponse;
23+
import org.elasticsearch.action.support.replication.ReplicationResponse;
24+
import org.elasticsearch.common.Strings;
25+
import org.elasticsearch.common.bytes.BytesReference;
26+
import org.elasticsearch.common.xcontent.XContentParser;
27+
import org.elasticsearch.common.xcontent.XContentType;
28+
import org.elasticsearch.index.shard.ShardId;
29+
import org.elasticsearch.test.ESTestCase;
30+
import org.elasticsearch.test.RandomObjects;
31+
32+
import java.io.IOException;
33+
import java.util.Map;
34+
35+
import static org.elasticsearch.action.index.IndexResponseTests.assertDocWriteResponse;
36+
import static org.elasticsearch.common.xcontent.XContentHelper.toXContent;
37+
38+
public class DeleteResponseTests extends ESTestCase {
39+
40+
public void testToXContent() throws IOException {
41+
{
42+
DeleteResponse response = new DeleteResponse(new ShardId("index", "index_uuid", 0), "type", "id", 5, true);
43+
String output = Strings.toString(response);
44+
assertEquals("{\"found\":true,\"_index\":\"index\",\"_type\":\"type\",\"_id\":\"id\",\"_version\":5,\"result\":\"deleted\"," +
45+
"\"_shards\":null}", output);
46+
}
47+
{
48+
DeleteResponse response = new DeleteResponse(new ShardId("index", "index_uuid", 0), "type", "id", 7, true);
49+
response.setForcedRefresh(true);
50+
response.setShardInfo(new ReplicationResponse.ShardInfo(10, 5));
51+
String output = Strings.toString(response);
52+
assertEquals("{\"found\":true,\"_index\":\"index\",\"_type\":\"type\",\"_id\":\"id\",\"_version\":7,\"result\":\"deleted\"," +
53+
"\"forced_refresh\":true,\"_shards\":{\"total\":10,\"successful\":5,\"failed\":0}}", output);
54+
}
55+
}
56+
57+
public void testToAndFromXContent() throws IOException {
58+
final XContentType xContentType = randomFrom(XContentType.values());
59+
60+
// Create a random DeleteResponse and converts it to XContent in bytes
61+
DeleteResponse deleteResponse = randomDeleteResponse();
62+
BytesReference deleteResponseBytes = toXContent(deleteResponse, xContentType);
63+
64+
// Parse the XContent bytes to obtain a parsed
65+
DeleteResponse parsedDeleteResponse;
66+
try (XContentParser parser = createParser(xContentType.xContent(), deleteResponseBytes)) {
67+
parsedDeleteResponse = DeleteResponse.fromXContent(parser);
68+
assertNull(parser.nextToken());
69+
}
70+
71+
// We can't use equals() to compare the original and the parsed index response
72+
// because the random index response can contain shard failures with exceptions,
73+
// and those exceptions are not parsed back with the same types.
74+
75+
// Print the parsed object out and test that the output is the same as the original output
76+
BytesReference parsedDeleteResponseBytes = toXContent(parsedDeleteResponse, xContentType);
77+
try (XContentParser parser = createParser(xContentType.xContent(), parsedDeleteResponseBytes)) {
78+
assertDeleteResponse(deleteResponse, parser.map());
79+
}
80+
}
81+
82+
private static void assertDeleteResponse(DeleteResponse expected, Map<String, Object> actual) {
83+
assertDocWriteResponse(expected, actual);
84+
if (expected.getResult() == DocWriteResponse.Result.DELETED) {
85+
assertTrue((boolean) actual.get("found"));
86+
} else {
87+
assertFalse((boolean) actual.get("found"));
88+
}
89+
}
90+
91+
private static DeleteResponse randomDeleteResponse() {
92+
ShardId shardId = new ShardId(randomAsciiOfLength(5), randomAsciiOfLength(5), randomIntBetween(0, 5));
93+
String type = randomAsciiOfLength(5);
94+
String id = randomAsciiOfLength(5);
95+
long seqNo = randomIntBetween(-2, 5);
96+
long version = (long) randomIntBetween(0, 5);
97+
boolean found = randomBoolean();
98+
99+
DeleteResponse response = new DeleteResponse(shardId, type, id, version, found);
100+
response.setForcedRefresh(randomBoolean());
101+
response.setShardInfo(RandomObjects.randomShardInfo(random(), randomBoolean()));
102+
return response;
103+
}
104+
105+
}

0 commit comments

Comments
 (0)