Search in sources :

Example 1 with HttpStatusException

use of com.yahoo.elide.core.exceptions.HttpStatusException in project elide by yahoo.

the class AggregationDataStoreTransaction method loadObjects.

@Override
public <T> DataStoreIterable<T> loadObjects(EntityProjection entityProjection, RequestScope scope) {
    QueryResult result = null;
    QueryResponse response = null;
    String cacheKey = null;
    try {
        // Convert multivalued map to map.
        Map<String, String> headers = scope.getRequestHeaders().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, (entry) -> entry.getValue().stream().collect(Collectors.joining(" "))));
        queryLogger.acceptQuery(scope.getRequestId(), scope.getUser(), headers, scope.getApiVersion(), scope.getQueryParams(), scope.getPath());
        Query query = buildQuery(entityProjection, scope);
        Table table = (Table) query.getSource();
        if (cache != null && !query.isBypassingCache()) {
            String tableVersion = queryEngine.getTableVersion(table, queryEngineTransaction);
            tableVersion = tableVersion == null ? "" : tableVersion;
            cacheKey = tableVersion + ';' + QueryKeyExtractor.extractKey(query);
            result = cache.get(cacheKey);
        }
        boolean isCached = result != null;
        List<String> queryText = queryEngine.explain(query);
        queryLogger.processQuery(scope.getRequestId(), query, queryText, isCached);
        if (result == null) {
            result = queryEngine.executeQuery(query, queryEngineTransaction);
            if (cacheKey != null) {
                // The query result needs to be streamed into an in memory list before caching.
                // TODO - add a cap to how many records can be streamed back.  If this is exceeded, abort caching
                // and return the results.
                QueryResult cacheableResult = QueryResult.builder().data(Lists.newArrayList(result.getData().iterator())).pageTotals(result.getPageTotals()).build();
                cache.put(cacheKey, cacheableResult);
                result = cacheableResult;
            }
        }
        if (entityProjection.getPagination() != null && entityProjection.getPagination().returnPageTotals()) {
            entityProjection.getPagination().setPageTotals(result.getPageTotals());
        }
        response = new QueryResponse(HttpStatus.SC_OK, result.getData(), null);
        return new DataStoreIterableBuilder(result.getData()).build();
    } catch (HttpStatusException e) {
        response = new QueryResponse(e.getStatus(), null, e.getMessage());
        throw e;
    } catch (Exception e) {
        response = new QueryResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, null, e.getMessage());
        throw e;
    } finally {
        queryLogger.completeQuery(scope.getRequestId(), response);
    }
}
Also used : HttpStatus(com.yahoo.elide.core.exceptions.HttpStatus) DataStoreIterableBuilder(com.yahoo.elide.core.datastore.DataStoreIterableBuilder) QueryResponse(com.yahoo.elide.datastores.aggregation.core.QueryResponse) HashMap(java.util.HashMap) Argument(com.yahoo.elide.core.request.Argument) InvalidOperationException(com.yahoo.elide.core.exceptions.InvalidOperationException) Map(java.util.Map) MatchesTemplateVisitor(com.yahoo.elide.datastores.aggregation.filter.visitor.MatchesTemplateVisitor) Column(com.yahoo.elide.datastores.aggregation.metadata.models.Column) ToString(lombok.ToString) DataStoreIterable(com.yahoo.elide.core.datastore.DataStoreIterable) FilterExpression(com.yahoo.elide.core.filter.expression.FilterExpression) RequestScope(com.yahoo.elide.core.RequestScope) RequiresFilter(com.yahoo.elide.datastores.aggregation.metadata.models.RequiresFilter) DataStoreTransaction(com.yahoo.elide.core.datastore.DataStoreTransaction) HttpStatusException(com.yahoo.elide.core.exceptions.HttpStatusException) Cache(com.yahoo.elide.datastores.aggregation.cache.Cache) Lists(org.apache.commons.compress.utils.Lists) EntityProjection(com.yahoo.elide.core.request.EntityProjection) QueryResult(com.yahoo.elide.datastores.aggregation.query.QueryResult) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) EntityDictionary(com.yahoo.elide.core.dictionary.EntityDictionary) Query(com.yahoo.elide.datastores.aggregation.query.Query) List(java.util.List) BadRequestException(com.yahoo.elide.core.exceptions.BadRequestException) QueryKeyExtractor(com.yahoo.elide.datastores.aggregation.cache.QueryKeyExtractor) Type(com.yahoo.elide.core.type.Type) Table(com.yahoo.elide.datastores.aggregation.metadata.models.Table) VisibleForTesting(com.google.common.annotations.VisibleForTesting) MetaDataStore(com.yahoo.elide.datastores.aggregation.metadata.MetaDataStore) QueryLogger(com.yahoo.elide.datastores.aggregation.core.QueryLogger) Table(com.yahoo.elide.datastores.aggregation.metadata.models.Table) Query(com.yahoo.elide.datastores.aggregation.query.Query) DataStoreIterableBuilder(com.yahoo.elide.core.datastore.DataStoreIterableBuilder) HttpStatusException(com.yahoo.elide.core.exceptions.HttpStatusException) ToString(lombok.ToString) InvalidOperationException(com.yahoo.elide.core.exceptions.InvalidOperationException) HttpStatusException(com.yahoo.elide.core.exceptions.HttpStatusException) IOException(java.io.IOException) BadRequestException(com.yahoo.elide.core.exceptions.BadRequestException) QueryResult(com.yahoo.elide.datastores.aggregation.query.QueryResult) QueryResponse(com.yahoo.elide.datastores.aggregation.core.QueryResponse) HashMap(java.util.HashMap) Map(java.util.Map)

Example 2 with HttpStatusException

use of com.yahoo.elide.core.exceptions.HttpStatusException in project elide by yahoo.

the class Elide method handleRuntimeException.

private ElideResponse handleRuntimeException(RuntimeException error, boolean isVerbose) {
    CustomErrorException mappedException = mapError(error);
    if (mappedException != null) {
        return buildErrorResponse(mappedException, isVerbose);
    }
    if (error instanceof WebApplicationException) {
        throw error;
    }
    if (error instanceof ForbiddenAccessException) {
        ForbiddenAccessException e = (ForbiddenAccessException) error;
        if (log.isDebugEnabled()) {
            log.debug("{}", e.getLoggedMessage());
        }
        return buildErrorResponse(e, isVerbose);
    }
    if (error instanceof JsonPatchExtensionException) {
        JsonPatchExtensionException e = (JsonPatchExtensionException) error;
        log.debug("JSON patch extension exception caught", e);
        return buildErrorResponse(e, isVerbose);
    }
    if (error instanceof HttpStatusException) {
        HttpStatusException e = (HttpStatusException) error;
        log.debug("Caught HTTP status exception", e);
        return buildErrorResponse(e, isVerbose);
    }
    if (error instanceof ParseCancellationException) {
        ParseCancellationException e = (ParseCancellationException) error;
        log.debug("Parse cancellation exception uncaught by Elide (i.e. invalid URL)", e);
        return buildErrorResponse(new InvalidURLException(e), isVerbose);
    }
    if (error instanceof ConstraintViolationException) {
        ConstraintViolationException e = (ConstraintViolationException) error;
        log.debug("Constraint violation exception caught", e);
        String message = "Constraint violation";
        final ErrorObjects.ErrorObjectsBuilder errorObjectsBuilder = ErrorObjects.builder();
        for (ConstraintViolation<?> constraintViolation : e.getConstraintViolations()) {
            errorObjectsBuilder.addError().withDetail(constraintViolation.getMessage());
            final String propertyPathString = constraintViolation.getPropertyPath().toString();
            if (!propertyPathString.isEmpty()) {
                Map<String, Object> source = new HashMap<>(1);
                source.put("property", propertyPathString);
                errorObjectsBuilder.with("source", source);
            }
        }
        return buildErrorResponse(new CustomErrorException(HttpStatus.SC_BAD_REQUEST, message, errorObjectsBuilder.build()), isVerbose);
    }
    log.error("Error or exception uncaught by Elide", error);
    throw new RuntimeException(error);
}
Also used : ErrorObjects(com.yahoo.elide.core.exceptions.ErrorObjects) WebApplicationException(javax.ws.rs.WebApplicationException) HashMap(java.util.HashMap) HttpStatusException(com.yahoo.elide.core.exceptions.HttpStatusException) ForbiddenAccessException(com.yahoo.elide.core.exceptions.ForbiddenAccessException) InvalidURLException(com.yahoo.elide.core.exceptions.InvalidURLException) ParseCancellationException(org.antlr.v4.runtime.misc.ParseCancellationException) ConstraintViolationException(javax.validation.ConstraintViolationException) CustomErrorException(com.yahoo.elide.core.exceptions.CustomErrorException) JsonPatchExtensionException(com.yahoo.elide.core.exceptions.JsonPatchExtensionException)

Example 3 with HttpStatusException

use of com.yahoo.elide.core.exceptions.HttpStatusException in project elide by yahoo.

the class JsonApiPatch method handleAddOp.

/**
 * Add a document via patch extension.
 */
private Supplier<Pair<Integer, JsonNode>> handleAddOp(String path, JsonNode patchValue, PatchRequestScope requestScope, PatchAction action) {
    try {
        JsonApiDocument value = requestScope.getMapper().readJsonApiPatchExtValue(patchValue);
        Data<Resource> data = value.getData();
        if (data == null || data.get() == null) {
            throw new InvalidEntityBodyException("Expected an entity body but received none.");
        }
        Collection<Resource> resources = data.get();
        if (!path.contains("relationships")) {
            // Reserved key for relationships
            String id = getSingleResource(resources).getId();
            if (StringUtils.isEmpty(id)) {
                throw new InvalidEntityBodyException("Patch extension requires all objects to have an assigned " + "ID (temporary or permanent) when assigning relationships.");
            }
            String fullPath = path + "/" + id;
            // Defer relationship updating until the end
            getSingleResource(resources).setRelationships(null);
            // Reparse since we mangle it first
            action.doc = requestScope.getMapper().readJsonApiPatchExtValue(patchValue);
            action.path = fullPath;
            action.isPostProcessing = true;
        }
        PostVisitor visitor = new PostVisitor(new PatchRequestScope(path, value, requestScope));
        return visitor.visit(JsonApiParser.parse(path));
    } catch (HttpStatusException e) {
        action.cause = e;
        throw e;
    } catch (IOException e) {
        throw new InvalidEntityBodyException("Could not parse patch extension value: " + patchValue);
    }
}
Also used : InvalidEntityBodyException(com.yahoo.elide.core.exceptions.InvalidEntityBodyException) JsonApiDocument(com.yahoo.elide.jsonapi.models.JsonApiDocument) Resource(com.yahoo.elide.jsonapi.models.Resource) HttpStatusException(com.yahoo.elide.core.exceptions.HttpStatusException) IOException(java.io.IOException) PostVisitor(com.yahoo.elide.jsonapi.parser.PostVisitor)

Example 4 with HttpStatusException

use of com.yahoo.elide.core.exceptions.HttpStatusException in project elide by yahoo.

the class QueryRunner method handleRuntimeException.

public static ElideResponse handleRuntimeException(Elide elide, RuntimeException error, boolean isVerbose) {
    CustomErrorException mappedException = elide.mapError(error);
    ObjectMapper mapper = elide.getMapper().getObjectMapper();
    if (mappedException != null) {
        return buildErrorResponse(mapper, mappedException, isVerbose);
    }
    if (error instanceof WebApplicationException) {
        WebApplicationException e = (WebApplicationException) error;
        log.debug("WebApplicationException", e);
        String body = e.getResponse().getEntity() != null ? e.getResponse().getEntity().toString() : e.getMessage();
        return ElideResponse.builder().responseCode(e.getResponse().getStatus()).body(body).build();
    }
    if (error instanceof HttpStatusException) {
        HttpStatusException e = (HttpStatusException) error;
        if (e instanceof ForbiddenAccessException) {
            if (log.isDebugEnabled()) {
                log.debug("{}", ((ForbiddenAccessException) e).getLoggedMessage());
            }
        } else {
            log.debug("Caught HTTP status exception {}", e.getStatus(), e);
        }
        return buildErrorResponse(mapper, new HttpStatusException(200, e.getMessage()) {

            @Override
            public int getStatus() {
                return 200;
            }

            @Override
            public Pair<Integer, JsonNode> getErrorResponse() {
                return e.getErrorResponse();
            }

            @Override
            public Pair<Integer, JsonNode> getVerboseErrorResponse() {
                return e.getVerboseErrorResponse();
            }

            @Override
            public String getVerboseMessage() {
                return e.getVerboseMessage();
            }

            @Override
            public String toString() {
                return e.toString();
            }
        }, isVerbose);
    }
    if (error instanceof ConstraintViolationException) {
        ConstraintViolationException e = (ConstraintViolationException) error;
        log.debug("Constraint violation exception caught", e);
        String message = "Constraint violation";
        final ErrorObjects.ErrorObjectsBuilder errorObjectsBuilder = ErrorObjects.builder();
        for (ConstraintViolation<?> constraintViolation : e.getConstraintViolations()) {
            errorObjectsBuilder.addError().withDetail(constraintViolation.getMessage());
            final String propertyPathString = constraintViolation.getPropertyPath().toString();
            if (!propertyPathString.isEmpty()) {
                Map<String, Object> source = new HashMap<>(1);
                source.put("property", propertyPathString);
                errorObjectsBuilder.with("source", source);
            }
        }
        return buildErrorResponse(mapper, new CustomErrorException(HttpStatus.SC_OK, message, errorObjectsBuilder.build()), isVerbose);
    }
    log.error("Error or exception uncaught by Elide", error);
    throw new RuntimeException(error);
}
Also used : ErrorObjects(com.yahoo.elide.core.exceptions.ErrorObjects) WebApplicationException(javax.ws.rs.WebApplicationException) HashMap(java.util.HashMap) HttpStatusException(com.yahoo.elide.core.exceptions.HttpStatusException) ForbiddenAccessException(com.yahoo.elide.core.exceptions.ForbiddenAccessException) ConstraintViolationException(javax.validation.ConstraintViolationException) CustomErrorException(com.yahoo.elide.core.exceptions.CustomErrorException) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) Pair(org.apache.commons.lang3.tuple.Pair)

Example 5 with HttpStatusException

use of com.yahoo.elide.core.exceptions.HttpStatusException in project elide by yahoo.

the class MultiplexWriteTransaction method commit.

@Override
public void commit(RequestScope scope) {
    // flush all before commits
    flush(scope);
    ArrayList<DataStore> commitList = new ArrayList<>();
    for (Entry<DataStore, DataStoreTransaction> entry : transactions.entrySet()) {
        try {
            entry.getValue().commit(scope);
            commitList.add(entry.getKey());
        } catch (HttpStatusException | WebApplicationException e) {
            reverseTransactions(commitList, e, scope);
            throw e;
        } catch (Error | RuntimeException e) {
            TransactionException transactionException = new TransactionException(e);
            reverseTransactions(commitList, transactionException, scope);
            throw transactionException;
        }
    }
}
Also used : TransactionException(com.yahoo.elide.core.exceptions.TransactionException) WebApplicationException(javax.ws.rs.WebApplicationException) DataStore(com.yahoo.elide.core.datastore.DataStore) ArrayList(java.util.ArrayList) DataStoreTransaction(com.yahoo.elide.core.datastore.DataStoreTransaction) HttpStatusException(com.yahoo.elide.core.exceptions.HttpStatusException)

Aggregations

HttpStatusException (com.yahoo.elide.core.exceptions.HttpStatusException)5 HashMap (java.util.HashMap)3 WebApplicationException (javax.ws.rs.WebApplicationException)3 DataStoreTransaction (com.yahoo.elide.core.datastore.DataStoreTransaction)2 CustomErrorException (com.yahoo.elide.core.exceptions.CustomErrorException)2 ErrorObjects (com.yahoo.elide.core.exceptions.ErrorObjects)2 ForbiddenAccessException (com.yahoo.elide.core.exceptions.ForbiddenAccessException)2 IOException (java.io.IOException)2 ConstraintViolationException (javax.validation.ConstraintViolationException)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 VisibleForTesting (com.google.common.annotations.VisibleForTesting)1 RequestScope (com.yahoo.elide.core.RequestScope)1 DataStore (com.yahoo.elide.core.datastore.DataStore)1 DataStoreIterable (com.yahoo.elide.core.datastore.DataStoreIterable)1 DataStoreIterableBuilder (com.yahoo.elide.core.datastore.DataStoreIterableBuilder)1 EntityDictionary (com.yahoo.elide.core.dictionary.EntityDictionary)1 BadRequestException (com.yahoo.elide.core.exceptions.BadRequestException)1 HttpStatus (com.yahoo.elide.core.exceptions.HttpStatus)1 InvalidEntityBodyException (com.yahoo.elide.core.exceptions.InvalidEntityBodyException)1 InvalidOperationException (com.yahoo.elide.core.exceptions.InvalidOperationException)1