use of com.yahoo.elide.core.exceptions.BadRequestException in project elide by yahoo.
the class TableExportOperation method call.
@Override
public AsyncAPIResult call() {
log.debug("TableExport Object from request: {}", exportObj);
Elide elide = service.getElide();
TableExportResult exportResult = new TableExportResult();
UUID requestId = UUID.fromString(exportObj.getRequestId());
try (DataStoreTransaction tx = elide.getDataStore().beginTransaction()) {
// Do Not Cache Export Results
Map<String, List<String>> requestHeaders = new HashMap<String, List<String>>();
requestHeaders.put("bypasscache", new ArrayList<String>(Arrays.asList("true")));
RequestScope requestScope = getRequestScope(exportObj, scope, tx, requestHeaders);
Collection<EntityProjection> projections = getProjections(exportObj, requestScope);
validateProjections(projections);
EntityProjection projection = projections.iterator().next();
Observable<PersistentResource> observableResults = Observable.empty();
elide.getTransactionRegistry().addRunningTransaction(requestId, tx);
// TODO - we need to add the baseUrlEndpoint to the queryObject.
// TODO - Can we have projectionInfo as null?
requestScope.setEntityProjection(projection);
if (projection != null) {
projection.setPagination(null);
observableResults = PersistentResource.loadRecords(projection, Collections.emptyList(), requestScope);
}
Observable<String> results = Observable.empty();
String preResult = formatter.preFormat(projection, exportObj);
results = observableResults.map(resource -> {
this.recordNumber++;
return formatter.format(resource, recordNumber);
});
String postResult = formatter.postFormat(projection, exportObj);
// Stitch together Pre-Formatted, Formatted, Post-Formatted results of Formatter in single observable.
Observable<String> interimResults = concatStringWithObservable(preResult, results, true);
Observable<String> finalResults = concatStringWithObservable(postResult, interimResults, false);
TableExportResult result = storeResults(exportObj, engine, finalResults);
if (result != null && result.getMessage() != null) {
throw new IllegalStateException(result.getMessage());
}
exportResult.setUrl(new URL(generateDownloadURL(exportObj, scope)));
exportResult.setRecordCount(recordNumber);
tx.flush(requestScope);
elide.getAuditLogger().commit();
tx.commit(requestScope);
} catch (BadRequestException e) {
exportResult.setMessage(e.getMessage());
} catch (MalformedURLException e) {
exportResult.setMessage("Download url generation failure.");
} catch (IOException e) {
log.error("IOException during TableExport", e);
exportResult.setMessage(e.getMessage());
} catch (Exception e) {
exportResult.setMessage(e.getMessage());
} finally {
// Follows same flow as GraphQL. The query may result in failure but request was successfully processed.
exportResult.setHttpStatus(200);
exportResult.setCompletedOn(new Date());
elide.getTransactionRegistry().removeRunningTransaction(requestId);
elide.getAuditLogger().clear();
}
return exportResult;
}
use of com.yahoo.elide.core.exceptions.BadRequestException in project elide by yahoo.
the class FilterTranslator method apply.
/**
* Transforms a filter predicate into a JPQL query fragment.
* @param filterPredicate The predicate to transform.
* @param aliasGenerator Function which supplies a HQL fragment which represents the column in the predicate.
* @return The hql query fragment.
*/
protected String apply(FilterPredicate filterPredicate, Function<Path, String> aliasGenerator) {
Function<Path, String> removeThisFromAlias = (path) -> {
String fieldPath = aliasGenerator.apply(path);
// JPQL doesn't support 'this', but it does support aliases.
return fieldPath.replaceAll("\\.this", "");
};
Path.PathElement last = filterPredicate.getPath().lastElement().get();
Operator op = filterPredicate.getOperator();
JPQLPredicateGenerator generator = predicateOverrides.get(Triple.of(op, last.getType(), last.getFieldName()));
if (generator == null) {
generator = operatorGenerators.get(op);
}
if (generator == null) {
throw new BadRequestException("Operator not implemented: " + filterPredicate.getOperator());
}
return generator.generate(filterPredicate, removeThisFromAlias);
}
use of com.yahoo.elide.core.exceptions.BadRequestException in project elide by yahoo.
the class SubscriptionDataFetcherTest method testErrorInSubscriptionStream.
@Test
void testErrorInSubscriptionStream() {
Book book1 = new Book();
book1.setTitle("Book 1");
book1.setId(1);
Book book2 = new Book();
book2.setTitle("Book 2");
book2.setId(2);
reset(dataStoreTransaction);
when(dataStoreTransaction.getAttribute(any(), any(), any())).thenThrow(new BadRequestException("Bad Request"));
when(dataStoreTransaction.loadObjects(any(), any())).thenReturn(new DataStoreIterableBuilder(List.of(book1, book2)).build());
List<String> responses = List.of("{\"book\":{\"id\":\"1\",\"title\":null}}", "{\"book\":{\"id\":\"2\",\"title\":null}}");
List<String> errors = List.of("Bad Request", "Bad Request");
String graphQLRequest = "subscription {book(topic: ADDED) {id title}}";
assertSubscriptionEquals(graphQLRequest, responses, errors);
}
use of com.yahoo.elide.core.exceptions.BadRequestException in project elide by yahoo.
the class SubscriptionWebSocketTest method testErrorPriorToStream.
@Test
void testErrorPriorToStream() throws IOException {
SubscriptionWebSocket endpoint = SubscriptionWebSocket.builder().executorService(executorService).elide(elide).build();
reset(dataStoreTransaction);
when(dataStoreTransaction.loadObjects(any(), any())).thenThrow(new BadRequestException("Bad Request"));
ConnectionInit init = new ConnectionInit();
endpoint.onOpen(session);
endpoint.onMessage(session, mapper.writeValueAsString(init));
Subscribe subscribe = Subscribe.builder().id("1").payload(Subscribe.Payload.builder().query("subscription {book(topic: ADDED) {id title}}").build()).build();
endpoint.onMessage(session, mapper.writeValueAsString(subscribe));
List<String> expected = List.of("{\"type\":\"connection_ack\"}", "{\"type\":\"next\",\"id\":\"1\",\"payload\":{\"data\":null,\"errors\":[{\"message\":\"Exception while fetching data (/book) : Bad Request\",\"locations\":[{\"line\":1,\"column\":15}],\"path\":[\"book\"],\"extensions\":{\"classification\":\"DataFetchingException\"}}]}}", "{\"type\":\"complete\",\"id\":\"1\"}");
ArgumentCaptor<String> message = ArgumentCaptor.forClass(String.class);
verify(remote, times(3)).sendText(message.capture());
assertEquals(expected, message.getAllValues());
}
use of com.yahoo.elide.core.exceptions.BadRequestException in project elide by yahoo.
the class Elide method handleRequest.
/**
* Handle JSON API requests.
*
* @param isReadOnly if the transaction is read only
* @param user the user object from the container
* @param transaction a transaction supplier
* @param requestId the Request ID
* @param handler a function that creates the request scope and request handler
* @return the response
*/
protected ElideResponse handleRequest(boolean isReadOnly, User user, Supplier<DataStoreTransaction> transaction, UUID requestId, Handler<DataStoreTransaction, User, HandlerResult> handler) {
boolean isVerbose = false;
try (DataStoreTransaction tx = transaction.get()) {
transactionRegistry.addRunningTransaction(requestId, tx);
HandlerResult result = handler.handle(tx, user);
RequestScope requestScope = result.getRequestScope();
isVerbose = requestScope.getPermissionExecutor().isVerbose();
Supplier<Pair<Integer, JsonNode>> responder = result.getResponder();
tx.preCommit(requestScope);
requestScope.runQueuedPreSecurityTriggers();
requestScope.getPermissionExecutor().executeCommitChecks();
requestScope.runQueuedPreFlushTriggers();
if (!isReadOnly) {
requestScope.saveOrCreateObjects();
}
tx.flush(requestScope);
requestScope.runQueuedPreCommitTriggers();
ElideResponse response = buildResponse(responder.get());
auditLogger.commit();
tx.commit(requestScope);
requestScope.runQueuedPostCommitTriggers();
if (log.isTraceEnabled()) {
requestScope.getPermissionExecutor().logCheckStats();
}
return response;
} catch (JacksonException e) {
String message = (e.getLocation() != null && e.getLocation().getSourceRef() != null) ? // This will leak Java class info if the location isn't known.
e.getMessage() : e.getOriginalMessage();
return buildErrorResponse(new BadRequestException(message), isVerbose);
} catch (IOException e) {
log.error("IO Exception uncaught by Elide", e);
return buildErrorResponse(new TransactionException(e), isVerbose);
} catch (RuntimeException e) {
return handleRuntimeException(e, isVerbose);
} finally {
transactionRegistry.removeRunningTransaction(requestId);
auditLogger.clear();
}
}
Aggregations