summaryrefslogtreecommitdiffstats
path: root/vespaclient-container-plugin
diff options
context:
space:
mode:
authorJon Marius Venstad <venstad@gmail.com>2020-10-29 12:03:47 +0100
committerJon Marius Venstad <venstad@gmail.com>2020-10-29 12:03:47 +0100
commit4e479a0e71060390f8340acbd9b07fe85416510a (patch)
tree4c337fe6c98abfcd67671d942b81d5d1a532e5f1 /vespaclient-container-plugin
parent7ca55cf2810664ee1acc4a79f606ff8e77868dc3 (diff)
Add traces to document/v1
Diffstat (limited to 'vespaclient-container-plugin')
-rw-r--r--vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java76
-rw-r--r--vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/DocumentV1ApiTest.java30
2 files changed, 85 insertions, 21 deletions
diff --git a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java
index 43358aa8699..caf1403bdf8 100644
--- a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java
+++ b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/DocumentV1ApiHandler.java
@@ -52,6 +52,8 @@ import com.yahoo.jdisc.handler.UnsafeContentInputStream;
import com.yahoo.jdisc.http.HttpRequest;
import com.yahoo.jdisc.http.HttpRequest.Method;
import com.yahoo.messagebus.StaticThrottlePolicy;
+import com.yahoo.messagebus.Trace;
+import com.yahoo.messagebus.TraceNode;
import com.yahoo.metrics.simple.MetricReceiver;
import com.yahoo.restapi.Path;
import com.yahoo.text.Text;
@@ -309,13 +311,8 @@ public class DocumentV1ApiHandler extends AbstractRequestHandler {
private ContentChannel getDocument(HttpRequest request, DocumentPath path, ResponseHandler handler) {
enqueueAndDispatch(request, handler, () -> {
- DocumentOperationParameters rawParameters = parameters();
- rawParameters = getProperty(request, CLUSTER).map(cluster -> resolveCluster(Optional.of(cluster), clusters).route())
- .map(rawParameters::withRoute)
- .orElse(rawParameters);
- rawParameters = getProperty(request, FIELD_SET).map(rawParameters::withFieldSet)
- .orElse(rawParameters);
- DocumentOperationParameters parameters = rawParameters.withResponseHandler(response -> {
+ DocumentOperationParameters parameters = parametersFromRequest(request, CLUSTER, FIELD_SET)
+ .withResponseHandler(response -> {
handle(path, handler, response, (document, jsonResponse) -> {
if (document != null) {
jsonResponse.writeSingleDocument(document);
@@ -336,9 +333,8 @@ public class DocumentV1ApiHandler extends AbstractRequestHandler {
enqueueAndDispatch(request, handler, () -> {
DocumentPut put = parser.parsePut(in, path.id().toString());
getProperty(request, CONDITION).map(TestAndSetCondition::new).ifPresent(put::setCondition);
- DocumentOperationParameters rawParameters = getProperty(request, ROUTE).map(parameters()::withRoute)
- .orElse(parameters());
- DocumentOperationParameters parameters = rawParameters.withResponseHandler(response -> handle(path, handler, response));
+ DocumentOperationParameters parameters = parametersFromRequest(request, ROUTE)
+ .withResponseHandler(response -> handle(path, handler, response));
return () -> dispatchOperation(() -> asyncSession.put(put, parameters));
});
});
@@ -350,10 +346,9 @@ public class DocumentV1ApiHandler extends AbstractRequestHandler {
enqueueAndDispatch(request, handler, () -> {
DocumentUpdate update = parser.parseUpdate(in, path.id().toString());
getProperty(request, CONDITION).map(TestAndSetCondition::new).ifPresent(update::setCondition);
- getProperty(request, CREATE).map(booleanParser::parse).ifPresent(update::setCreateIfNonExistent);
- DocumentOperationParameters rawParameters = getProperty(request, ROUTE).map(parameters()::withRoute)
- .orElse(parameters());
- DocumentOperationParameters parameters = rawParameters.withResponseHandler(response -> handle(path, handler, response));
+ getProperty(request, CREATE, booleanParser).ifPresent(update::setCreateIfNonExistent);
+ DocumentOperationParameters parameters = parametersFromRequest(request, ROUTE)
+ .withResponseHandler(response -> handle(path, handler, response));
return () -> dispatchOperation(() -> asyncSession.update(update, parameters));
});
});
@@ -364,14 +359,40 @@ public class DocumentV1ApiHandler extends AbstractRequestHandler {
enqueueAndDispatch(request, handler, () -> {
DocumentRemove remove = new DocumentRemove(path.id());
getProperty(request, CONDITION).map(TestAndSetCondition::new).ifPresent(remove::setCondition);
- DocumentOperationParameters rawParameters = getProperty(request, ROUTE).map(parameters()::withRoute)
- .orElse(parameters());
- DocumentOperationParameters parameters = rawParameters.withResponseHandler(response -> handle(path, handler, response));
+ DocumentOperationParameters parameters = parametersFromRequest(request, ROUTE)
+ .withResponseHandler(response -> handle(path, handler, response));
return () -> dispatchOperation(() -> asyncSession.remove(remove, parameters));
});
return ignoredContent;
}
+ private DocumentOperationParameters parametersFromRequest(HttpRequest request, String... names) {
+ DocumentOperationParameters parameters = getProperty(request, TRACE_LEVEL, integerParser).map(parameters()::withTraceLevel)
+ .orElse(parameters());
+ for (String name : names) switch (name) {
+ case CLUSTER:
+ parameters = getProperty(request, CLUSTER).map(cluster -> resolveCluster(Optional.of(cluster), clusters).route())
+ .map(parameters::withRoute)
+ .orElse(parameters);
+ break;
+ case CONDITION:
+ parameters = getProperty(request, ROUTE).map(parameters::withRoute)
+ .orElse(parameters);
+ break;
+ case FIELD_SET:
+ parameters = getProperty(request, FIELD_SET).map(parameters::withFieldSet)
+ .orElse(parameters);
+ break;
+ case ROUTE:
+ parameters = getProperty(request, ROUTE).map(parameters::withRoute)
+ .orElse(parameters);
+ break;
+ default:
+ throw new IllegalArgumentException("Unrecognized document operation parameter name '" + name + "'");
+ }
+ return parameters;
+ }
+
/** Dispatches enqueued requests until one is blocked. */
void dispatchEnqueued() {
try {
@@ -501,6 +522,26 @@ public class DocumentV1ApiHandler extends AbstractRequestHandler {
json.writeStringField("id", id.toString());
}
+ synchronized void writeTrace(Trace trace) throws IOException {
+ if (trace != null && ! trace.getRoot().isEmpty()) {
+ writeTrace(trace.getRoot());
+ }
+ }
+
+ private void writeTrace(TraceNode node) throws IOException {
+ if (node.hasNote())
+ json.writeStringField("message", node.getNote());
+ if ( ! node.isLeaf()) {
+ json.writeArrayFieldStart(node.isStrict() ? "trace" : "fork");
+ for (int i = 0; i < node.getNumChildren(); i++) {
+ json.writeStartObject();
+ writeTrace(node.getChild(i));
+ json.writeEndObject();
+ }
+ json.writeEndArray();
+ }
+ }
+
synchronized void writeSingleDocument(Document document) throws IOException {
new JsonWriter(json).writeFields(document);
}
@@ -714,6 +755,7 @@ public class DocumentV1ApiHandler extends AbstractRequestHandler {
private static void handle(DocumentPath path, ResponseHandler handler, com.yahoo.documentapi.Response response, SuccessCallback callback) {
try (JsonResponse jsonResponse = JsonResponse.create(path, handler)) {
+ jsonResponse.writeTrace(response.getTrace());
if (response.isSuccess())
callback.onSuccess((response instanceof DocumentResponse) ? ((DocumentResponse) response).getDocument() : null, jsonResponse);
else {
diff --git a/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/DocumentV1ApiTest.java b/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/DocumentV1ApiTest.java
index 4aeb0c5f8cc..723c84935f1 100644
--- a/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/DocumentV1ApiTest.java
+++ b/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/DocumentV1ApiTest.java
@@ -43,6 +43,7 @@ import com.yahoo.documentapi.VisitorSession;
import com.yahoo.jdisc.Metric;
import com.yahoo.messagebus.StaticThrottlePolicy;
import com.yahoo.messagebus.Trace;
+import com.yahoo.messagebus.TraceNode;
import com.yahoo.metrics.simple.MetricReceiver;
import com.yahoo.searchdefinition.derived.Deriver;
import com.yahoo.slime.Inspector;
@@ -61,6 +62,7 @@ import java.io.UncheckedIOException;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.OptionalInt;
import java.util.TreeMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
@@ -320,11 +322,16 @@ public class DocumentV1ApiTest {
DocumentPut expectedPut = new DocumentPut(doc2);
expectedPut.setCondition(new TestAndSetCondition("test it"));
assertEquals(expectedPut, put);
- assertEquals(parameters(), parameters);
- parameters.responseHandler().get().handleResponse(new DocumentResponse(0, doc2));
+ assertEquals(parameters().withTraceLevel(9), parameters);
+ Trace trace = new Trace(9);
+ trace.trace(7, "Tracy Chapman", false);
+ trace.getRoot().addChild(new TraceNode().setStrict(false)
+ .addChild("Fast Car")
+ .addChild("Baby Can I Hold You"));
+ parameters.responseHandler().get().handleResponse(new DocumentResponse(0, doc2, trace));
return new Result(Result.ResultType.SUCCESS, null);
});
- response = driver.sendRequest("http://localhost/document/v1/space/music/number/1/two?condition=test%20it", POST,
+ response = driver.sendRequest("http://localhost/document/v1/space/music/number/1/two?condition=test%20it&traceLevel=9", POST,
"{" +
" \"fields\": {" +
" \"artist\": \"Asa-Chan & Jun-Ray\"" +
@@ -332,7 +339,22 @@ public class DocumentV1ApiTest {
"}");
assertSameJson("{" +
" \"pathId\": \"/document/v1/space/music/number/1/two\"," +
- " \"id\": \"id:space:music:n=1:two\"" +
+ " \"id\": \"id:space:music:n=1:two\"," +
+ " \"trace\": [" +
+ " {" +
+ " \"message\": \"Tracy Chapman\"" +
+ " }," +
+ " {" +
+ " \"fork\": [" +
+ " {" +
+ " \"message\": \"Fast Car\"" +
+ " }," +
+ " {" +
+ " \"message\": \"Baby Can I Hold You\"" +
+ " }" +
+ " ]" +
+ " }" +
+ " ]" +
"}", response.readAll());
assertEquals(200, response.getStatus());