aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@oath.com>2019-04-29 11:41:50 +0200
committerGitHub <noreply@github.com>2019-04-29 11:41:50 +0200
commitd26962c2102e9b38004035bb9876326d1c92722f (patch)
tree420b0c331590f6de40d0a2bdca8749f871236dd7
parentc9f9f467df69a65fe1a403f58411259e3c0fa823 (diff)
parent8cbc4e04c8caf10222e00e203cc8e0b1ea569087 (diff)
Merge pull request #9220 from vespa-engine/bratseth/document-api-dont-blame-users
Bratseth/document api dont blame users
-rw-r--r--document/src/main/java/com/yahoo/document/TestAndSetCondition.java6
-rw-r--r--document/src/main/java/com/yahoo/document/json/JsonFeedReader.java2
-rw-r--r--document/src/main/java/com/yahoo/document/json/JsonReader.java15
-rw-r--r--document/src/main/java/com/yahoo/document/json/JsonReaderException.java6
-rw-r--r--document/src/main/java/com/yahoo/document/json/SingleDocumentParser.java8
-rw-r--r--document/src/main/java/com/yahoo/document/json/readers/AddRemoveCreator.java2
-rw-r--r--document/src/main/java/com/yahoo/document/json/readers/JsonParserHelpers.java44
-rw-r--r--document/src/main/java/com/yahoo/document/json/readers/StructReader.java12
-rw-r--r--document/src/main/java/com/yahoo/document/json/readers/VespaJsonDocumentReader.java5
-rw-r--r--document/src/test/java/com/yahoo/document/json/JsonReaderTestCase.java21
-rw-r--r--vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/RestApi.java105
-rw-r--r--vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/RestApiTest.java2
12 files changed, 137 insertions, 91 deletions
diff --git a/document/src/main/java/com/yahoo/document/TestAndSetCondition.java b/document/src/main/java/com/yahoo/document/TestAndSetCondition.java
index 78e75ba8e95..767fd6672d4 100644
--- a/document/src/main/java/com/yahoo/document/TestAndSetCondition.java
+++ b/document/src/main/java/com/yahoo/document/TestAndSetCondition.java
@@ -16,6 +16,7 @@ import java.util.Optional;
*/
@Beta
public class TestAndSetCondition {
+
public static final TestAndSetCondition NOT_PRESENT_CONDITION = new TestAndSetCondition();
private final String conditionStr;
@@ -33,9 +34,9 @@ public class TestAndSetCondition {
public boolean isPresent() { return !conditionStr.isEmpty(); }
/**
- * Maps and optional test and set conditiong string to a TestAndSetCondition.
+ * Maps and optional test and set condition string to a TestAndSetCondition.
* If the condition string is not present, a "not present" condition is returned
- * @param conditionString test and set conditiong string (document selection)
+ * @param conditionString test and set condition string (document selection)
* @return a TestAndSetCondition representing the condition string or a "not present" condition
*/
public static TestAndSetCondition fromConditionString(Optional<String> conditionString) {
@@ -43,4 +44,5 @@ public class TestAndSetCondition {
.map(TestAndSetCondition::new)
.orElse(TestAndSetCondition.NOT_PRESENT_CONDITION);
}
+
}
diff --git a/document/src/main/java/com/yahoo/document/json/JsonFeedReader.java b/document/src/main/java/com/yahoo/document/json/JsonFeedReader.java
index be4aa6cfb41..5da6b58ac98 100644
--- a/document/src/main/java/com/yahoo/document/json/JsonFeedReader.java
+++ b/document/src/main/java/com/yahoo/document/json/JsonFeedReader.java
@@ -52,7 +52,7 @@ public class JsonFeedReader implements FeedReader {
} else if (documentOperation instanceof DocumentPut) {
return new DocumentFeedOperation(((DocumentPut) documentOperation).getDocument(), documentOperation.getCondition());
} else {
- throw new IllegalStateException("Got unknown class from JSON reader: " + documentOperation.getClass().getName());
+ throw new IllegalArgumentException("Got unknown class from JSON reader: " + documentOperation.getClass().getName());
}
}
diff --git a/document/src/main/java/com/yahoo/document/json/JsonReader.java b/document/src/main/java/com/yahoo/document/json/JsonReader.java
index d512fd3a6d1..79e435b6d9d 100644
--- a/document/src/main/java/com/yahoo/document/json/JsonReader.java
+++ b/document/src/main/java/com/yahoo/document/json/JsonReader.java
@@ -49,7 +49,7 @@ public class JsonReader {
parser = parserFactory.createParser(input);
} catch (IOException e) {
state = END_OF_FEED;
- throw new RuntimeException(e);
+ throw new IllegalArgumentException(e);
}
}
@@ -61,13 +61,13 @@ public class JsonReader {
*/
public DocumentOperation readSingleDocument(DocumentParser.SupportedOperation operationType, String docIdString) {
DocumentId docId = new DocumentId(docIdString);
- final DocumentParseInfo documentParseInfo;
+ DocumentParseInfo documentParseInfo;
try {
DocumentParser documentParser = new DocumentParser(parser);
documentParseInfo = documentParser.parse(Optional.of(docId)).get();
} catch (IOException e) {
state = END_OF_FEED;
- throw new RuntimeException(e);
+ throw new IllegalArgumentException(e);
}
documentParseInfo.operationType = operationType;
VespaJsonDocumentReader vespaJsonDocumentReader = new VespaJsonDocumentReader();
@@ -96,9 +96,9 @@ public class JsonReader {
} catch (IOException r) {
// Jackson is not able to recover from structural parse errors
state = END_OF_FEED;
- throw new RuntimeException(r);
+ throw new IllegalArgumentException(r);
}
- if (! documentParseInfo.isPresent()) {
+ if ( ! documentParseInfo.isPresent()) {
state = END_OF_FEED;
return null;
}
@@ -117,9 +117,8 @@ public class JsonReader {
private static DocumentType getDocumentTypeFromString(String docTypeString, DocumentTypeManager typeManager) {
final DocumentType docType = typeManager.getDocumentType(docTypeString);
- if (docType == null) {
+ if (docType == null)
throw new IllegalArgumentException(String.format("Document type %s does not exist", docTypeString));
- }
return docType;
}
@@ -129,7 +128,7 @@ public class JsonReader {
} catch (IOException e) {
// Jackson is not able to recover from structural parse errors
state = END_OF_FEED;
- throw new RuntimeException(e);
+ throw new IllegalArgumentException(e);
}
}
}
diff --git a/document/src/main/java/com/yahoo/document/json/JsonReaderException.java b/document/src/main/java/com/yahoo/document/json/JsonReaderException.java
index f919d00d20c..2363df30374 100644
--- a/document/src/main/java/com/yahoo/document/json/JsonReaderException.java
+++ b/document/src/main/java/com/yahoo/document/json/JsonReaderException.java
@@ -7,7 +7,8 @@ import com.yahoo.document.Field;
/**
* @author bjorncs
*/
-public class JsonReaderException extends RuntimeException {
+public class JsonReaderException extends IllegalArgumentException {
+
public final DocumentId docId;
public final Field field;
public final Throwable cause;
@@ -32,7 +33,7 @@ public class JsonReaderException extends RuntimeException {
private static String createErrorMessage(DocumentId docId, Field field, Throwable cause) {
return String.format("Error in document '%s' - could not parse field '%s' of type '%s': %s",
- docId, field.getName(), field.getDataType().getName(), cause.getMessage());
+ docId, field.getName(), field.getDataType().getName(), cause.getMessage());
}
public DocumentId getDocId() {
@@ -42,4 +43,5 @@ public class JsonReaderException extends RuntimeException {
public Field getField() {
return field;
}
+
}
diff --git a/document/src/main/java/com/yahoo/document/json/SingleDocumentParser.java b/document/src/main/java/com/yahoo/document/json/SingleDocumentParser.java
index 28aa9ed1d8d..b57b55c9d73 100644
--- a/document/src/main/java/com/yahoo/document/json/SingleDocumentParser.java
+++ b/document/src/main/java/com/yahoo/document/json/SingleDocumentParser.java
@@ -20,6 +20,7 @@ import java.io.InputStream;
* @author dybis
*/
public class SingleDocumentParser {
+
private static final JsonFactory jsonFactory = new JsonFactory().disable(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES);
private DocumentTypeManager docMan;
@@ -36,12 +37,12 @@ public class SingleDocumentParser {
}
private FeedOperation parse(InputStream inputStream, String docId, DocumentParser.SupportedOperation supportedOperation) {
- final JsonReader reader = new JsonReader(docMan, inputStream, jsonFactory);
- final DocumentOperation documentOperation = reader.readSingleDocument(supportedOperation, docId);
+ JsonReader reader = new JsonReader(docMan, inputStream, jsonFactory);
+ DocumentOperation documentOperation = reader.readSingleDocument(supportedOperation, docId);
try {
inputStream.close();
} catch (IOException e) {
- throw new RuntimeException(e);
+ throw new IllegalStateException(e);
}
if (supportedOperation == DocumentParser.SupportedOperation.PUT) {
return new DocumentFeedOperation(((DocumentPut) documentOperation).getDocument(), documentOperation.getCondition());
@@ -49,4 +50,5 @@ public class SingleDocumentParser {
return new DocumentUpdateFeedOperation((DocumentUpdate) documentOperation, documentOperation.getCondition());
}
}
+
}
diff --git a/document/src/main/java/com/yahoo/document/json/readers/AddRemoveCreator.java b/document/src/main/java/com/yahoo/document/json/readers/AddRemoveCreator.java
index a5af14a1cde..73be43ca9d9 100644
--- a/document/src/main/java/com/yahoo/document/json/readers/AddRemoveCreator.java
+++ b/document/src/main/java/com/yahoo/document/json/readers/AddRemoveCreator.java
@@ -60,7 +60,7 @@ public class AddRemoveCreator {
List<FieldValue> arrayContents = new ArrayList<>();
ArrayReader.fillArrayUpdate(buffer, initNesting, valueType, arrayContents);
if (buffer.currentToken() != JsonToken.END_ARRAY) {
- throw new IllegalStateException("Expected END_ARRAY. Got '" + buffer.currentToken() + "'.");
+ throw new IllegalArgumentException("Expected END_ARRAY. Got '" + buffer.currentToken() + "'.");
}
if (isRemove) {
singleUpdate = FieldUpdate.createRemoveAll(field, arrayContents);
diff --git a/document/src/main/java/com/yahoo/document/json/readers/JsonParserHelpers.java b/document/src/main/java/com/yahoo/document/json/readers/JsonParserHelpers.java
index e3bfdb7bb2c..6339add222e 100644
--- a/document/src/main/java/com/yahoo/document/json/readers/JsonParserHelpers.java
+++ b/document/src/main/java/com/yahoo/document/json/readers/JsonParserHelpers.java
@@ -6,27 +6,59 @@ import com.fasterxml.jackson.core.JsonToken;
import com.google.common.base.Preconditions;
public class JsonParserHelpers {
+
public static void expectArrayStart(JsonToken token) {
- Preconditions.checkState(token == JsonToken.START_ARRAY, "Expected start of array, got %s", token);
+ try {
+ Preconditions.checkState(token == JsonToken.START_ARRAY, "Expected start of array, got %s", token);
+ }
+ catch (IllegalStateException e) {
+ throw new IllegalArgumentException(e);
+ }
}
public static void expectArrayEnd(JsonToken token) {
- Preconditions.checkState(token == JsonToken.END_ARRAY, "Expected start of array, got %s", token);
+ try {
+ Preconditions.checkState(token == JsonToken.END_ARRAY, "Expected start of array, got %s", token);
+ }
+ catch (IllegalStateException e) {
+ throw new IllegalArgumentException(e);
+ }
}
public static void expectObjectStart(JsonToken token) {
- Preconditions.checkState(token == JsonToken.START_OBJECT, "Expected start of JSON object, got %s", token);
+ try {
+ Preconditions.checkState(token == JsonToken.START_OBJECT, "Expected start of JSON object, got %s", token);
+ }
+ catch (IllegalStateException e) {
+ throw new IllegalArgumentException(e);
+ }
}
public static void expectObjectEnd(JsonToken token) {
- Preconditions.checkState(token == JsonToken.END_OBJECT, "Expected end of JSON object, got %s", token);
+ try {
+ Preconditions.checkState(token == JsonToken.END_OBJECT, "Expected end of JSON object, got %s", token);
+ }
+ catch (IllegalStateException e) {
+ throw new IllegalArgumentException(e);
+ }
}
public static void expectCompositeEnd(JsonToken token) {
- Preconditions.checkState(token.isStructEnd(), "Expected end of composite, got %s", token);
+ try {
+ Preconditions.checkState(token.isStructEnd(), "Expected end of composite, got %s", token);
+ }
+ catch (IllegalStateException e) {
+ throw new IllegalArgumentException(e);
+ }
}
public static void expectScalarValue(JsonToken token) {
- Preconditions.checkState(token.isScalarValue(), "Expected to be scalar value, got %s", token);
+ try {
+ Preconditions.checkState(token.isScalarValue(), "Expected to be scalar value, got %s", token);
+ }
+ catch (IllegalStateException e) {
+ throw new IllegalArgumentException(e);
+ }
}
+
}
diff --git a/document/src/main/java/com/yahoo/document/json/readers/StructReader.java b/document/src/main/java/com/yahoo/document/json/readers/StructReader.java
index cab55903b76..dc2c001672d 100644
--- a/document/src/main/java/com/yahoo/document/json/readers/StructReader.java
+++ b/document/src/main/java/com/yahoo/document/json/readers/StructReader.java
@@ -11,6 +11,7 @@ import com.yahoo.document.json.TokenBuffer;
import static com.yahoo.document.json.readers.SingleValueReader.readSingleValue;
public class StructReader {
+
public static void fillStruct(TokenBuffer buffer, StructuredFieldValue parent) {
// do note the order of initializing initNesting and token is relevant for empty docs
int initNesting = buffer.nesting();
@@ -32,12 +33,11 @@ public class StructReader {
}
public static Field getField(TokenBuffer buffer, StructuredFieldValue parent) {
- Field f = parent.getField(buffer.currentName());
- if (f == null) {
- throw new NullPointerException("Could not get field \"" + buffer.currentName() +
- "\" in the structure of type \"" + parent.getDataType().getDataTypeName() + "\".");
- }
- return f;
+ Field field = parent.getField(buffer.currentName());
+ if (field == null)
+ throw new IllegalArgumentException("No field '" + buffer.currentName() + "' in the structure of type '" +
+ parent.getDataType().getDataTypeName() + "'");
+ return field;
}
}
diff --git a/document/src/main/java/com/yahoo/document/json/readers/VespaJsonDocumentReader.java b/document/src/main/java/com/yahoo/document/json/readers/VespaJsonDocumentReader.java
index 2aeab67f290..e252e71407a 100644
--- a/document/src/main/java/com/yahoo/document/json/readers/VespaJsonDocumentReader.java
+++ b/document/src/main/java/com/yahoo/document/json/readers/VespaJsonDocumentReader.java
@@ -40,6 +40,7 @@ import static com.yahoo.document.json.readers.TensorRemoveUpdateReader.createTen
* @author freva
*/
public class VespaJsonDocumentReader {
+
private static final String UPDATE_REMOVE = "remove";
private static final String UPDATE_ADD = "add";
@@ -67,8 +68,8 @@ public class VespaJsonDocumentReader {
throw JsonReaderException.addDocId(e, documentParseInfo.documentId);
}
if (documentParseInfo.create.isPresent()) {
- if (!(documentOperation instanceof DocumentUpdate)) {
- throw new RuntimeException("Could not set create flag on non update operation.");
+ if (! ( documentOperation instanceof DocumentUpdate)) {
+ throw new IllegalArgumentException("Could not set create flag on non update operation.");
}
DocumentUpdate update = (DocumentUpdate) documentOperation;
update.setCreateIfNonExistent(documentParseInfo.create.get());
diff --git a/document/src/test/java/com/yahoo/document/json/JsonReaderTestCase.java b/document/src/test/java/com/yahoo/document/json/JsonReaderTestCase.java
index 15d1e859f73..9df7d1f91c1 100644
--- a/document/src/test/java/com/yahoo/document/json/JsonReaderTestCase.java
+++ b/document/src/test/java/com/yahoo/document/json/JsonReaderTestCase.java
@@ -914,16 +914,17 @@ public class JsonReaderTestCase {
}
@Test
- public final void misspelledFieldTest() throws IOException{
- JsonReader r = createReader(inputJson("{ 'put': 'id:unittest:smoke::whee',",
+ public void misspelledFieldTest() throws IOException{
+ JsonReader r = createReader(inputJson(
+ "{ 'put': 'id:unittest:smoke::whee',",
" 'fields': {",
" 'smething': 'smoketest',",
" 'nalle': 'bamse' }}"));
DocumentParseInfo parseInfo = r.parseDocument().get();
DocumentType docType = r.readDocumentType(parseInfo.documentId);
DocumentPut put = new DocumentPut(new Document(docType, parseInfo.documentId));
- exception.expect(NullPointerException.class);
- exception.expectMessage("Could not get field \"smething\" in the structure of type \"smoke\".");
+ exception.expect(IllegalArgumentException.class);
+ exception.expectMessage("No field 'smething' in the structure of type 'smoke'");
new VespaJsonDocumentReader().readPut(parseInfo.fieldsBuffer, put);
}
@@ -954,9 +955,9 @@ public class JsonReaderTestCase {
}
private void testFeedWithTestAndSetCondition(String jsonDoc) {
- final ByteArrayInputStream parseInfoDoc = new ByteArrayInputStream(Utf8.toBytes(jsonDoc));
- final JsonReader reader = new JsonReader(types, parseInfoDoc, parserFactory);
- final int NUM_OPERATIONS_IN_FEED = 3;
+ ByteArrayInputStream parseInfoDoc = new ByteArrayInputStream(Utf8.toBytes(jsonDoc));
+ JsonReader reader = new JsonReader(types, parseInfoDoc, parserFactory);
+ int NUM_OPERATIONS_IN_FEED = 3;
for (int i = 0; i < NUM_OPERATIONS_IN_FEED; i++) {
DocumentOperation operation = reader.next();
@@ -1005,7 +1006,7 @@ public class JsonReaderTestCase {
}
@Test
- public final void testFeedWithTestAndSetConditionOrderingTwo() {
+ public void testFeedWithTestAndSetConditionOrderingTwo() {
testFeedWithTestAndSetCondition(
inputJson("[",
" {",
@@ -1037,7 +1038,7 @@ public class JsonReaderTestCase {
}
@Test
- public final void testFeedWithTestAndSetConditionOrderingThree() {
+ public void testFeedWithTestAndSetConditionOrderingThree() {
testFeedWithTestAndSetCondition(
inputJson("[",
" {",
@@ -1108,7 +1109,7 @@ public class JsonReaderTestCase {
@Test(expected = IllegalArgumentException.class)
public void testInvalidFieldWithoutFieldsFieldShouldFailParse() {
- final String jsonData = inputJson(
+ String jsonData = inputJson(
"[",
" {",
" 'remove': 'id:unittest:smoke::whee',",
diff --git a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/RestApi.java b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/RestApi.java
index 873b0569553..b4992fb519b 100644
--- a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/RestApi.java
+++ b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/RestApi.java
@@ -36,6 +36,7 @@ import com.yahoo.vespaclient.ClusterList;
import com.yahoo.vespaxmlparser.DocumentFeedOperation;
import com.yahoo.vespaxmlparser.FeedOperation;
import com.yahoo.vespaxmlparser.VespaXMLFeedReader;
+import com.yahoo.yolean.Exceptions;
import java.io.IOException;
import java.io.OutputStream;
@@ -79,16 +80,14 @@ public class RestApi extends LoggingRequestHandler {
public RestApi(LoggingRequestHandler.Context parentCtx, DocumentmanagerConfig documentManagerConfig,
LoadTypeConfig loadTypeConfig, ThreadpoolConfig threadpoolConfig,
AllClustersBucketSpacesConfig bucketSpacesConfig,
- ClusterListConfig clusterListConfig, MetricReceiver metricReceiver)
- {
+ ClusterListConfig clusterListConfig, MetricReceiver metricReceiver) {
super(parentCtx);
MessageBusParams params = new MessageBusParams(new LoadTypeSet(loadTypeConfig));
params.setDocumentmanagerConfig(documentManagerConfig);
- this.operationHandler = new OperationHandlerImpl(
- new MessageBusDocumentAccess(params),
- fixedClusterEnumeratorFromConfig(clusterListConfig),
- fixedBucketSpaceResolverFromConfig(bucketSpacesConfig),
- metricReceiver);
+ this.operationHandler = new OperationHandlerImpl(new MessageBusDocumentAccess(params),
+ fixedClusterEnumeratorFromConfig(clusterListConfig),
+ fixedBucketSpaceResolverFromConfig(bucketSpacesConfig),
+ metricReceiver);
this.singleDocumentParser = new SingleDocumentParser(new DocumentTypeManager(documentManagerConfig));
// 40% of the threads can be blocked before we deny requests.
if (threadpoolConfig != null) {
@@ -100,11 +99,10 @@ public class RestApi extends LoggingRequestHandler {
}
// For testing and development
- public RestApi(
- Executor executor,
- AccessLog accessLog,
- OperationHandler operationHandler,
- int threadsAvailable) {
+ public RestApi(Executor executor,
+ AccessLog accessLog,
+ OperationHandler operationHandler,
+ int threadsAvailable) {
super(executor, accessLog, null);
this.operationHandler = operationHandler;
this.threadsAvailableForApi = new AtomicInteger(threadsAvailable);
@@ -121,12 +119,11 @@ public class RestApi extends LoggingRequestHandler {
}
private static OperationHandlerImpl.ClusterEnumerator fixedClusterEnumeratorFromConfig(ClusterListConfig config) {
- final List<ClusterDef> clusters = Collections.unmodifiableList(new ClusterList(config).getStorageClusters());
+ List<ClusterDef> clusters = Collections.unmodifiableList(new ClusterList(config).getStorageClusters());
return () -> clusters;
}
- private static OperationHandlerImpl.BucketSpaceResolver fixedBucketSpaceResolverFromConfig(
- AllClustersBucketSpacesConfig bucketSpacesConfig) {
+ private static OperationHandlerImpl.BucketSpaceResolver fixedBucketSpaceResolverFromConfig(AllClustersBucketSpacesConfig bucketSpacesConfig) {
return (clusterId, docType) ->
Optional.ofNullable(bucketSpacesConfig.cluster(clusterId))
.map(cluster -> cluster.documentType(docType))
@@ -134,7 +131,7 @@ public class RestApi extends LoggingRequestHandler {
}
private static Optional<String> requestProperty(String parameter, HttpRequest request) {
- final String property = request.getProperty(parameter);
+ String property = request.getProperty(parameter);
if (property != null && ! property.isEmpty()) {
return Optional.of(property);
}
@@ -151,8 +148,15 @@ public class RestApi extends LoggingRequestHandler {
}
private static Optional<Boolean> parseBoolean(String parameter, HttpRequest request) {
- Optional<String> property = requestProperty(parameter, request);
- return property.map(RestApi::parseBooleanStrict);
+ try {
+ Optional<String> property = requestProperty(parameter, request);
+ return property.map(RestApi::parseBooleanStrict);
+ }
+ catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("Invalid value for '" + parameter + "' parameter: " +
+ "Must be empty, true, or false but was '" +
+ request.getProperty(parameter) + "'");
+ }
}
private static int parsePositiveInt(String str) throws NumberFormatException {
@@ -167,9 +171,9 @@ public class RestApi extends LoggingRequestHandler {
public HttpResponse handle(HttpRequest request) {
try {
if (threadsAvailableForApi.decrementAndGet() < 1) {
- return Response.createErrorResponse(
- 429 /* Too Many Requests */,
- "Too many parallel requests, consider using http-vespa-java-client. Please try again later.", RestUri.apiErrorCodes.TOO_MANY_PARALLEL_REQUESTS);
+ return Response.createErrorResponse(429 /* Too Many Requests */,
+ "Too many parallel requests, consider using http-vespa-java-client. Please try again later.",
+ RestUri.apiErrorCodes.TOO_MANY_PARALLEL_REQUESTS);
}
return handleInternal(request);
} finally {
@@ -177,11 +181,12 @@ public class RestApi extends LoggingRequestHandler {
}
}
- private static void validateUriStructureForRequestMethod(RestUri uri, com.yahoo.jdisc.http.HttpRequest.Method method) throws RestApiException {
+ private static void validateUriStructureForRequestMethod(RestUri uri, com.yahoo.jdisc.http.HttpRequest.Method method)
+ throws RestApiException {
if ((method != com.yahoo.jdisc.http.HttpRequest.Method.GET) && uri.isRootOnly()) {
throw new RestApiException(Response.createErrorResponse(BAD_REQUEST,
- "Root /document/v1/ requests only supported for HTTP GET",
- RestUri.apiErrorCodes.ERROR_ID_BASIC_USAGE));
+ "Root /document/v1/ requests only supported for HTTP GET",
+ RestUri.apiErrorCodes.ERROR_ID_BASIC_USAGE));
}
}
@@ -191,28 +196,23 @@ public class RestApi extends LoggingRequestHandler {
// protected for testing
protected HttpResponse handleInternal(HttpRequest request) {
- final RestUri restUri;
+ RestUri restUri = null;
try {
restUri = new RestUri(request.getUri());
validateUriStructureForRequestMethod(restUri, request.getMethod());
- } catch (RestApiException e) {
- return e.getResponse();
- } catch (Exception e2) {
- return Response.createErrorResponse(500, "Exception while parsing URI: " + e2.getMessage(), RestUri.apiErrorCodes.URL_PARSING);
- }
- final Optional<Boolean> create;
- try {
- create = parseBoolean(CREATE_PARAMETER_NAME, request);
- } catch (IllegalArgumentException e) {
- return Response.createErrorResponse(400, "Non valid value for 'create' parameter, must be empty, true, or " +
- "false: " + request.getProperty(CREATE_PARAMETER_NAME), RestUri.apiErrorCodes.INVALID_CREATE_VALUE);
- }
- String condition = request.getProperty(CONDITION_PARAMETER_NAME);
- Optional<String> route = Optional.ofNullable(request.getProperty(ROUTE_PARAMETER_NAME));
+ Optional<Boolean> create;
+ try {
+ create = parseBoolean(CREATE_PARAMETER_NAME, request);
+ }
+ catch (IllegalArgumentException e) {
+ return Response.createErrorResponse(400, e.getMessage(), RestUri.apiErrorCodes.INVALID_CREATE_VALUE);
+ }
- Optional<ObjectNode> resultJson = Optional.empty();
- try {
+ String condition = request.getProperty(CONDITION_PARAMETER_NAME);
+ Optional<String> route = Optional.ofNullable(request.getProperty(ROUTE_PARAMETER_NAME));
+
+ Optional<ObjectNode> resultJson = Optional.empty();
switch (request.getMethod()) {
case GET: // Vespa Visit/Get
return isVisitRequestUri(restUri) ? handleVisit(restUri, request) : handleGet(restUri, request);
@@ -228,14 +228,21 @@ public class RestApi extends LoggingRequestHandler {
default:
return new Response(405, Optional.empty(), Optional.of(restUri));
}
- } catch (RestApiException e) {
+ return new Response(200, resultJson, Optional.of(restUri));
+ }
+ catch (RestApiException e) {
return e.getResponse();
- } catch (Exception e2) {
- // We always blame the user. This might be a bit nasty, but the parser throws various kind of exception
- // types, but with nice descriptions.
- return Response.createErrorResponse(400, e2.getMessage(), restUri, RestUri.apiErrorCodes.PARSER_ERROR);
}
- return new Response(200, resultJson, Optional.of(restUri));
+ catch (IllegalArgumentException userException) {
+ return Response.createErrorResponse(400, Exceptions.toMessageString(userException),
+ restUri,
+ RestUri.apiErrorCodes.PARSER_ERROR);
+ }
+ catch (RuntimeException systemException) {
+ return Response.createErrorResponse(500, Exceptions.toMessageString(systemException),
+ restUri,
+ RestUri.apiErrorCodes.UNSPECIFIED);
+ }
}
private FeedOperation createPutOperation(HttpRequest request, String id, String condition) {
@@ -401,8 +408,8 @@ public class RestApi extends LoggingRequestHandler {
} catch (BadRequestParameterException e) {
return createInvalidParameterResponse(e.getParameter(), e.getMessage());
}
- final OperationHandler.VisitResult visit = operationHandler.visit(restUri, documentSelection, options);
- final ObjectNode resultNode = mapper.createObjectNode();
+ OperationHandler.VisitResult visit = operationHandler.visit(restUri, documentSelection, options);
+ ObjectNode resultNode = mapper.createObjectNode();
visit.token.ifPresent(t -> resultNode.put(CONTINUATION, t));
resultNode.putArray(DOCUMENTS).addPOJO(visit.documentsAsJsonList);
resultNode.put(PATH_NAME, restUri.getRawPath());
diff --git a/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/RestApiTest.java b/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/RestApiTest.java
index 94bc8deb47a..773d45b6b18 100644
--- a/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/RestApiTest.java
+++ b/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/RestApiTest.java
@@ -197,7 +197,7 @@ public class RestApiTest {
HttpPut httpPut = new HttpPut(request.getUri());
StringEntity entity = new StringEntity(update_test_doc, ContentType.create("application/json"));
httpPut.setEntity(entity);
- assertHttp400ResponseContains(doRest(httpPut), "Non valid value for 'create' parameter, must be empty, true, or false: batman");
+ assertHttp400ResponseContains(doRest(httpPut), "Invalid value for 'create' parameter: Must be empty, true, or false but was 'batman'");
}
// Get logs through some hackish fetch method. Logs is something the mocked backend write.