summaryrefslogtreecommitdiffstats
path: root/vespaclient-container-plugin
diff options
context:
space:
mode:
authorvalerijf <valerijf@yahoo-inc.com>2017-05-11 12:56:58 +0200
committervalerijf <valerijf@yahoo-inc.com>2017-05-11 12:56:58 +0200
commita661b7f44aecae50f15b61111cd6d567b6b62f58 (patch)
tree8962e6a257ba4b1f8d43f1747989f0b665dd8a60 /vespaclient-container-plugin
parent605ae73f3699b35a9071b0736235b5c5cfbc5ad4 (diff)
Report feed metrics against /document/v1
Diffstat (limited to 'vespaclient-container-plugin')
-rw-r--r--vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/OperationHandlerImpl.java67
-rw-r--r--vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/resource/RestApi.java7
2 files changed, 52 insertions, 22 deletions
diff --git a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/OperationHandlerImpl.java b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/OperationHandlerImpl.java
index 9adb0a09016..f7638a45168 100644
--- a/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/OperationHandlerImpl.java
+++ b/vespaclient-container-plugin/src/main/java/com/yahoo/document/restapi/OperationHandlerImpl.java
@@ -16,7 +16,11 @@ import com.yahoo.documentapi.VisitorParameters;
import com.yahoo.documentapi.VisitorSession;
import com.yahoo.documentapi.messagebus.MessageBusSyncSession;
import com.yahoo.documentapi.messagebus.protocol.DocumentProtocol;
+import com.yahoo.documentapi.metrics.DocumentApiMetricsHelper;
+import com.yahoo.documentapi.metrics.DocumentOperationStatus;
+import com.yahoo.documentapi.metrics.DocumentOperationType;
import com.yahoo.messagebus.StaticThrottlePolicy;
+import com.yahoo.metrics.simple.MetricReceiver;
import com.yahoo.storage.searcher.ContinuationHit;
import com.yahoo.vdslib.VisitorOrdering;
import com.yahoo.vespaclient.ClusterDef;
@@ -30,6 +34,7 @@ import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Optional;
+import java.util.Set;
/**
* Sends operations to messagebus via document api.
@@ -44,6 +49,7 @@ public class OperationHandlerImpl implements OperationHandler {
public static final int VISIT_TIMEOUT_MS = 120000;
private final DocumentAccess documentAccess;
+ private final DocumentApiMetricsHelper metricsHelper;
private final ClusterEnumerator clusterEnumerator;
private static final class SyncSessionFactory extends ResourceFactory<SyncSession> {
@@ -59,14 +65,15 @@ public class OperationHandlerImpl implements OperationHandler {
private final ConcurrentResourcePool<SyncSession> syncSessions;
- public OperationHandlerImpl(DocumentAccess documentAccess) {
- this(documentAccess, () -> new ClusterList("client").getStorageClusters());
+ public OperationHandlerImpl(DocumentAccess documentAccess, MetricReceiver metricReceiver) {
+ this(documentAccess, () -> new ClusterList("client").getStorageClusters(), metricReceiver);
}
- public OperationHandlerImpl(DocumentAccess documentAccess, ClusterEnumerator clusterEnumerator) {
+ public OperationHandlerImpl(DocumentAccess documentAccess, ClusterEnumerator clusterEnumerator, MetricReceiver metricReceiver) {
this.documentAccess = documentAccess;
this.clusterEnumerator = clusterEnumerator;
syncSessions = new ConcurrentResourcePool<>(new SyncSessionFactory(documentAccess));
+ metricsHelper = new DocumentApiMetricsHelper(metricReceiver, "/document/v1");
}
@Override
@@ -81,11 +88,11 @@ public class OperationHandlerImpl implements OperationHandler {
private static final int HTTP_STATUS_INSUFFICIENT_STORAGE = 507;
private static final int HTTP_PRE_CONDIDTION_FAILED = 412;
- private static int getHTTPStatusCode(DocumentAccessException documentException) {
- if (documentException.getErrorCodes().size() == 1 && documentException.getErrorCodes().contains(DocumentProtocol.ERROR_NO_SPACE)) {
+ public static int getHTTPStatusCode(Set<Integer> errorCodes) {
+ if (errorCodes.size() == 1 && errorCodes.contains(DocumentProtocol.ERROR_NO_SPACE)) {
return HTTP_STATUS_INSUFFICIENT_STORAGE;
}
- if (documentException.hasConditionNotMetError()) {
+ if (errorCodes.contains(DocumentProtocol.ERROR_TEST_AND_SET_CONDITION_FAILED)) {
return HTTP_PRE_CONDIDTION_FAILED;
}
return HTTP_STATUS_BAD_REQUEST;
@@ -93,10 +100,10 @@ public class OperationHandlerImpl implements OperationHandler {
private static Response createErrorResponse(DocumentAccessException documentException, RestUri restUri) {
if (documentException.hasConditionNotMetError()) {
- return Response.createErrorResponse(getHTTPStatusCode(documentException), "Condition did not match document.",
+ return Response.createErrorResponse(getHTTPStatusCode(documentException.getErrorCodes()), "Condition did not match document.",
restUri, RestUri.apiErrorCodes.DOCUMENT_CONDITION_NOT_MET);
}
- return Response.createErrorResponse(getHTTPStatusCode(documentException), documentException.getMessage(), restUri,
+ return Response.createErrorResponse(getHTTPStatusCode(documentException.getErrorCodes()), documentException.getMessage(), restUri,
RestUri.apiErrorCodes.DOCUMENT_EXCPETION);
}
@@ -179,57 +186,79 @@ public class OperationHandlerImpl implements OperationHandler {
@Override
public void put(RestUri restUri, VespaXMLFeedReader.Operation data, Optional<String> route) throws RestApiException {
SyncSession syncSession = syncSessions.alloc();
+ Response response;
try {
+ long startTime = System.currentTimeMillis();
DocumentPut put = new DocumentPut(data.getDocument());
put.setCondition(data.getCondition());
setRoute(syncSession, route);
syncSession.put(put);
+ metricsHelper.reportSuccessful(DocumentOperationType.PUT, startTime);
+ return;
} catch (DocumentAccessException documentException) {
- throw new RestApiException(createErrorResponse(documentException, restUri));
+ response = createErrorResponse(documentException, restUri);
} catch (Exception e) {
- throw new RestApiException(Response.createErrorResponse(500, ExceptionUtils.getStackTrace(e), restUri, RestUri.apiErrorCodes.INTERNAL_EXCEPTION));
+ response = Response.createErrorResponse(500, ExceptionUtils.getStackTrace(e), restUri, RestUri.apiErrorCodes.INTERNAL_EXCEPTION);
} finally {
syncSessions.free(syncSession);
}
+
+ metricsHelper.reportFailure(DocumentOperationType.PUT, DocumentOperationStatus.fromHttpStatusCode(response.getStatus()));
+ throw new RestApiException(response);
}
@Override
public void update(RestUri restUri, VespaXMLFeedReader.Operation data, Optional<String> route) throws RestApiException {
SyncSession syncSession = syncSessions.alloc();
- setRoute(syncSession, route);
+ Response response;
try {
+ long startTime = System.currentTimeMillis();
+ setRoute(syncSession, route);
syncSession.update(data.getDocumentUpdate());
+ metricsHelper.reportSuccessful(DocumentOperationType.UPDATE, startTime);
+ return;
} catch (DocumentAccessException documentException) {
- throw new RestApiException(createErrorResponse(documentException, restUri));
+ response = createErrorResponse(documentException, restUri);
} catch (Exception e) {
- throw new RestApiException(Response.createErrorResponse(500, ExceptionUtils.getStackTrace(e), restUri, RestUri.apiErrorCodes.INTERNAL_EXCEPTION));
+ response = Response.createErrorResponse(500, ExceptionUtils.getStackTrace(e), restUri, RestUri.apiErrorCodes.INTERNAL_EXCEPTION);
} finally {
syncSessions.free(syncSession);
}
+
+ metricsHelper.reportFailure(DocumentOperationType.UPDATE, DocumentOperationStatus.fromHttpStatusCode(response.getStatus()));
+ throw new RestApiException(response);
}
@Override
public void delete(RestUri restUri, String condition, Optional<String> route) throws RestApiException {
SyncSession syncSession = syncSessions.alloc();
- setRoute(syncSession, route);
+ Response response;
try {
+ long startTime = System.currentTimeMillis();
DocumentId id = new DocumentId(restUri.generateFullId());
DocumentRemove documentRemove = new DocumentRemove(id);
+ setRoute(syncSession, route);
if (condition != null && ! condition.isEmpty()) {
documentRemove.setCondition(new TestAndSetCondition(condition));
}
syncSession.remove(documentRemove);
+ metricsHelper.reportSuccessful(DocumentOperationType.REMOVE, startTime);
+ return;
} catch (DocumentAccessException documentException) {
if (documentException.hasConditionNotMetError()) {
- throw new RestApiException(Response.createErrorResponse(412, "Condition not met: " + documentException.getMessage(),
- restUri, RestUri.apiErrorCodes.DOCUMENT_CONDITION_NOT_MET));
+ response = Response.createErrorResponse(412, "Condition not met: " + documentException.getMessage(),
+ restUri, RestUri.apiErrorCodes.DOCUMENT_CONDITION_NOT_MET);
+ } else {
+ response = Response.createErrorResponse(400, documentException.getMessage(), restUri, RestUri.apiErrorCodes.DOCUMENT_EXCPETION);
}
- throw new RestApiException(Response.createErrorResponse(400, documentException.getMessage(), restUri, RestUri.apiErrorCodes.DOCUMENT_EXCPETION));
} catch (Exception e) {
- throw new RestApiException(Response.createErrorResponse(500, ExceptionUtils.getStackTrace(e), restUri, RestUri.apiErrorCodes.UNSPECIFIED));
+ response = Response.createErrorResponse(500, ExceptionUtils.getStackTrace(e), restUri, RestUri.apiErrorCodes.UNSPECIFIED);
} finally {
syncSessions.free(syncSession);
}
+
+ metricsHelper.reportFailure(DocumentOperationType.REMOVE, DocumentOperationStatus.fromHttpStatusCode(response.getStatus()));
+ throw new RestApiException(response);
}
@Override
@@ -267,7 +296,7 @@ public class OperationHandlerImpl implements OperationHandler {
}
if (! wantedCluster.isPresent()) {
if (clusters.size() != 1) {
- new RestApiException(Response.createErrorResponse(400, "Several clusters exist: " +
+ throw new RestApiException(Response.createErrorResponse(400, "Several clusters exist: " +
clusterListToString(clusters) + " you must specify one. ", RestUri.apiErrorCodes.SEVERAL_CLUSTERS));
}
return clusterDefToRoute(clusters.get(0));
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 66e8c6475aa..bce8af4593b 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
@@ -24,6 +24,7 @@ import com.yahoo.document.restapi.RestUri;
import com.yahoo.documentapi.messagebus.MessageBusDocumentAccess;
import com.yahoo.documentapi.messagebus.MessageBusParams;
import com.yahoo.documentapi.messagebus.loadtypes.LoadTypeSet;
+import com.yahoo.metrics.simple.MetricReceiver;
import com.yahoo.vespa.config.content.LoadTypeConfig;
import com.yahoo.vespaxmlparser.VespaXMLFeedReader;
@@ -58,12 +59,12 @@ public class RestApi extends LoggingRequestHandler {
private final AtomicInteger threadsAvailableForApi;
@Inject
- public RestApi(Executor executor, AccessLog accessLog, DocumentmanagerConfig documentManagerConfig,
- LoadTypeConfig loadTypeConfig, ThreadpoolConfig threadpoolConfig) {
+ public RestApi(Executor executor, AccessLog accessLog, DocumentmanagerConfig documentManagerConfig,
+ LoadTypeConfig loadTypeConfig, ThreadpoolConfig threadpoolConfig, MetricReceiver metricReceiver) {
super(executor, accessLog);
MessageBusParams params = new MessageBusParams(new LoadTypeSet(loadTypeConfig));
params.setDocumentmanagerConfig(documentManagerConfig);
- this.operationHandler = new OperationHandlerImpl(new MessageBusDocumentAccess(params));
+ this.operationHandler = new OperationHandlerImpl(new MessageBusDocumentAccess(params), metricReceiver);
this.singleDocumentParser = new SingleDocumentParser(new DocumentTypeManager(documentManagerConfig));
// 40% of the threads can be blocked before we deny requests.
if (threadpoolConfig != null) {