[TEST] eagerly parse response body at ObjectPath initialization and read content type from response headers

We are going to parse the body anyways whenever it's in json format as it is going to be stashed. It is not useful to lazily parse it anymore. Also this allows us to not rely on automatic detection of the xcontent type based on the content of the response, but rather read the content type from the response headers.
This commit is contained in:
javanna 2016-06-25 15:40:41 +02:00 committed by Luca Cavanna
parent d5df738538
commit 34f5c50a7f
3 changed files with 42 additions and 45 deletions

View File

@ -18,7 +18,7 @@
*/
package org.elasticsearch.test.rest;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContent;
import org.elasticsearch.common.xcontent.XContentParser;
import java.io.IOException;
@ -33,8 +33,8 @@ public class ObjectPath {
private final Object object;
public static ObjectPath createFromXContent(String input) throws IOException {
try (XContentParser parser = XContentFactory.xContent(input).createParser(input)) {
public static ObjectPath createFromXContent(XContent xContent, String input) throws IOException {
try (XContentParser parser = xContent.createParser(input)) {
if (parser.nextToken() == XContentParser.Token.START_ARRAY) {
return new ObjectPath(parser.listOrderedMap());
}

View File

@ -23,6 +23,7 @@ import org.apache.http.util.EntityUtils;
import org.apache.lucene.util.IOUtils;
import org.elasticsearch.client.Response;
import org.elasticsearch.client.ResponseException;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.test.rest.ObjectPath;
import org.elasticsearch.test.rest.Stash;
@ -39,7 +40,7 @@ public class RestTestResponse {
private final String body;
private ObjectPath parsedResponse;
public RestTestResponse(Response response) {
public RestTestResponse(Response response) throws IOException {
this.response = response;
if (response.getEntity() != null) {
try {
@ -53,11 +54,24 @@ public class RestTestResponse {
} else {
this.body = null;
}
parseResponseBody();
}
public RestTestResponse(ResponseException responseException) {
public RestTestResponse(ResponseException responseException) throws IOException {
this.response = responseException.getResponse();
this.body = responseException.getResponseBody();
parseResponseBody();
}
private void parseResponseBody() throws IOException {
if (body != null) {
String contentType = response.getHeader("Content-Type");
XContentType xContentType = XContentType.fromMediaTypeOrFormat(contentType);
//skip parsing if we got text back (e.g. if we called _cat apis)
if (xContentType == XContentType.JSON) {
this.parsedResponse = ObjectPath.createFromXContent(xContentType.xContent(), body);
}
}
}
public int getStatusCode() {
@ -73,11 +87,7 @@ public class RestTestResponse {
* Might be a string or a json object parsed as a map.
*/
public Object getBody() throws IOException {
if (isJson()) {
ObjectPath parsedResponse = parsedResponse();
if (parsedResponse == null) {
return null;
}
if (parsedResponse != null) {
return parsedResponse.evaluate("");
}
return body;
@ -109,9 +119,7 @@ public class RestTestResponse {
return null;
}
ObjectPath objectPath = parsedResponse();
if (objectPath == null) {
if (parsedResponse == null) {
//special case: api that don't support body (e.g. exists) return true if 200, false if 404, even if no body
//is_true: '' means the response had no body but the client returned true (caused by 200)
//is_false: '' means the response had no body but the client returned false (caused by 404)
@ -121,21 +129,6 @@ public class RestTestResponse {
return null;
}
return objectPath.evaluate(path, stash);
}
private boolean isJson() {
String contentType = response.getHeader("Content-Type");
return contentType != null && contentType.contains("application/json");
}
private ObjectPath parsedResponse() throws IOException {
if (parsedResponse != null) {
return parsedResponse;
}
if (response == null || body == null) {
return null;
}
return parsedResponse = ObjectPath.createFromXContent(body);
return parsedResponse.evaluate(path, stash);
}
}

View File

@ -52,7 +52,7 @@ public class ObjectPathTests extends ESTestCase {
xContentBuilder.field("field2.field3", "value2");
xContentBuilder.endObject();
xContentBuilder.endObject();
ObjectPath objectPath = ObjectPath.createFromXContent(xContentBuilder.string());
ObjectPath objectPath = ObjectPath.createFromXContent(xContentBuilder.contentType().xContent(), xContentBuilder.string());
Object object = objectPath.evaluate("field1.field2\\.field3");
assertThat(object, instanceOf(String.class));
assertThat(object, equalTo("value2"));
@ -65,7 +65,7 @@ public class ObjectPathTests extends ESTestCase {
xContentBuilder.field("field2", "value2");
xContentBuilder.endObject();
xContentBuilder.endObject();
ObjectPath objectPath = ObjectPath.createFromXContent(xContentBuilder.string());
ObjectPath objectPath = ObjectPath.createFromXContent(xContentBuilder.contentType().xContent(), xContentBuilder.string());
Object object = objectPath.evaluate("field1..field2");
assertThat(object, instanceOf(String.class));
assertThat(object, equalTo("value2"));
@ -84,7 +84,7 @@ public class ObjectPathTests extends ESTestCase {
xContentBuilder.field("field2", 333);
xContentBuilder.endObject();
xContentBuilder.endObject();
ObjectPath objectPath = ObjectPath.createFromXContent(xContentBuilder.string());
ObjectPath objectPath = ObjectPath.createFromXContent(xContentBuilder.contentType().xContent(), xContentBuilder.string());
Object object = objectPath.evaluate("field1.field2");
assertThat(object, instanceOf(Integer.class));
assertThat(object, equalTo(333));
@ -97,7 +97,7 @@ public class ObjectPathTests extends ESTestCase {
xContentBuilder.field("field2", 3.55);
xContentBuilder.endObject();
xContentBuilder.endObject();
ObjectPath objectPath = ObjectPath.createFromXContent(xContentBuilder.string());
ObjectPath objectPath = ObjectPath.createFromXContent(xContentBuilder.contentType().xContent(), xContentBuilder.string());
Object object = objectPath.evaluate("field1.field2");
assertThat(object, instanceOf(Double.class));
assertThat(object, equalTo(3.55));
@ -110,7 +110,7 @@ public class ObjectPathTests extends ESTestCase {
xContentBuilder.array("array1", "value1", "value2");
xContentBuilder.endObject();
xContentBuilder.endObject();
ObjectPath objectPath = ObjectPath.createFromXContent(xContentBuilder.string());
ObjectPath objectPath = ObjectPath.createFromXContent(xContentBuilder.contentType().xContent(), xContentBuilder.string());
Object object = objectPath.evaluate("field1.array1");
assertThat(object, instanceOf(List.class));
List list = (List) object;
@ -139,7 +139,7 @@ public class ObjectPathTests extends ESTestCase {
xContentBuilder.endArray();
xContentBuilder.endObject();
xContentBuilder.endObject();
ObjectPath objectPath = ObjectPath.createFromXContent(xContentBuilder.string());
ObjectPath objectPath = ObjectPath.createFromXContent(xContentBuilder.contentType().xContent(), xContentBuilder.string());
Object object = objectPath.evaluate("field1.array1.1.element");
assertThat(object, instanceOf(String.class));
assertThat(object, equalTo("value2"));
@ -166,7 +166,7 @@ public class ObjectPathTests extends ESTestCase {
xContentBuilder.endObject();
xContentBuilder.endObject();
xContentBuilder.endObject();
ObjectPath objectPath = ObjectPath.createFromXContent(xContentBuilder.string());
ObjectPath objectPath = ObjectPath.createFromXContent(xContentBuilder.contentType().xContent(), xContentBuilder.string());
Object object = objectPath.evaluate("metadata.templates");
assertThat(object, instanceOf(Map.class));
Map<String, Object> map = (Map<String, Object>)object;
@ -184,7 +184,7 @@ public class ObjectPathTests extends ESTestCase {
xContentBuilder.endObject();
xContentBuilder.endObject();
xContentBuilder.endObject();
ObjectPath objectPath = ObjectPath.createFromXContent(xContentBuilder.string());
ObjectPath objectPath = ObjectPath.createFromXContent(xContentBuilder.contentType().xContent(), xContentBuilder.string());
try {
objectPath.evaluate("field1.$placeholder.element1");
fail("evaluate should have failed due to unresolved placeholder");
@ -201,13 +201,18 @@ public class ObjectPathTests extends ESTestCase {
@SuppressWarnings("unchecked")
public void testEvaluateArrayAsRoot() throws Exception {
String input = "---\n" +
"- alias: \"test_alias1\"\n" +
" index: \"test1\"\n" +
"- alias: \"test_alias2\"\n" +
" index: \"test2\"";
ObjectPath objectPath = ObjectPath.createFromXContent(input);
XContentBuilder xContentBuilder = randomXContentBuilder();
xContentBuilder.startArray();
xContentBuilder.startObject();
xContentBuilder.field("alias", "test_alias1");
xContentBuilder.field("index", "test1");
xContentBuilder.endObject();
xContentBuilder.startObject();
xContentBuilder.field("alias", "test_alias2");
xContentBuilder.field("index", "test2");
xContentBuilder.endObject();
xContentBuilder.endArray();
ObjectPath objectPath = ObjectPath.createFromXContent(XContentFactory.xContent(XContentType.YAML), xContentBuilder.string());
Object object = objectPath.evaluate("");
assertThat(object, notNullValue());
assertThat(object, instanceOf(List.class));
@ -221,5 +226,4 @@ public class ObjectPathTests extends ESTestCase {
assertThat(object, instanceOf(String.class));
assertThat(object, equalTo("test2"));
}
}