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);
}
}
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);
}
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);
}
}
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);
}
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;
}
}
}
Aggregations