use of uk.ac.bbsrc.tgac.miso.core.service.exception.BulkValidationException in project miso-lims by miso-lims.
the class BulkSaveService method startBulkOperation.
public default BulkSaveOperation<T> startBulkOperation(List<T> items, ThrowingFunction<T, Long, IOException> action, Consumer<BulkSaveOperation<T>> callback) throws IOException {
BulkSaveOperation<T> operation = new BulkSaveOperation<>(items, getAuthorizationManager().getCurrentUser());
// Authentication is tied to the thread, so use this same auth in the new thread
Authentication auth = SecurityContextHolder.getContextHolderStrategy().getContext().getAuthentication();
Thread thread = new Thread(() -> {
SecurityContextHolder.getContextHolderStrategy().getContext().setAuthentication(auth);
try {
getTransactionTemplate().execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
while (operation.hasMore()) {
try {
T item = operation.getNextItem();
operation.addSuccess(action.apply(item));
} catch (ValidationException e) {
operation.addFailure(e);
status.setRollbackOnly();
} catch (Exception e) {
operation.setFailed(e);
status.setRollbackOnly();
}
}
}
});
} catch (Exception e) {
// Exception during transaction commit
operation.setFailed(e);
}
if (operation.isFailed()) {
Exception exception = operation.getException();
if (!(exception instanceof BulkValidationException)) {
LoggerFactory.getLogger(BulkSaveService.class).error("Bulk save failed", exception);
}
}
if (callback != null) {
try {
callback.accept(operation);
} catch (Exception e) {
// Changes were committed, so not setting failed
LoggerFactory.getLogger(BulkSaveService.class).error("Exception thrown in bulk save callback", e);
}
}
operation.setComplete();
});
thread.start();
return operation;
}
use of uk.ac.bbsrc.tgac.miso.core.service.exception.BulkValidationException in project miso-lims by miso-lims.
the class DefaultQualityControlService method startBulkOperation.
private BulkQcSaveOperation startBulkOperation(List<QC> items, ThrowingFunction<QC, QC, IOException> action) throws IOException {
QcTarget qcTarget = qcTypeService.get(items.get(0).getType().getId()).getQcTarget();
BulkQcSaveOperation operation = new BulkQcSaveOperation(qcTarget, items, authorizationManager.getCurrentUser());
// Authentication is tied to the thread, so use this same auth in the new thread
Authentication auth = SecurityContextHolder.getContextHolderStrategy().getContext().getAuthentication();
Thread thread = new Thread(() -> {
SecurityContextHolder.getContextHolderStrategy().getContext().setAuthentication(auth);
try {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
while (operation.hasMore()) {
try {
QC item = operation.getNextItem();
QC saved = action.apply(item);
operation.addSuccess(saved.getId());
} catch (ValidationException e) {
operation.addFailure(e);
status.setRollbackOnly();
} catch (Exception e) {
operation.setFailed(e);
status.setRollbackOnly();
}
}
}
});
} catch (Exception e) {
// Exception during transaction commit
operation.setFailed(e);
}
if (operation.isFailed()) {
Exception exception = operation.getException();
if (!(exception instanceof BulkValidationException)) {
LoggerFactory.getLogger(DefaultQualityControlService.class).error("Bulk save failed", exception);
}
}
operation.setComplete();
});
thread.start();
return operation;
}
use of uk.ac.bbsrc.tgac.miso.core.service.exception.BulkValidationException in project miso-lims by miso-lims.
the class AsyncOperationManager method makeFailedProgress.
private static ObjectNode makeFailedProgress(String uuid, BulkSaveOperation<?> operation) {
ObjectNode json = makeBaseProgress(uuid, operation, "failed");
if (operation.getException() instanceof BulkValidationException) {
BulkValidationException bulkValidation = (BulkValidationException) operation.getException();
json.put("detail", bulkValidation.getLocalizedMessage());
RestUtils.addBulkValidationData(json, bulkValidation);
} else {
json.put("detail", "An unexpected error has occurred");
}
return json;
}
use of uk.ac.bbsrc.tgac.miso.core.service.exception.BulkValidationException in project miso-lims by miso-lims.
the class RestExceptionHandler method handleException.
/**
* Collects information from an exception, sets an appropriate HTTP Status for the response, and forms a representation of the
* error that may be returned to the client. e.g.
*
* <pre>
* {
* requestUrl: URL,
* detail: exception message,
* code: HTTP status code,
* message: HTTP status reason phrase,
* dataFormat: {custom|validation|bulk validation},
* data: format depends on dataFormat
* }
* </pre>
*
* @param request HTTP request that caused the exception
* @param response HTTP response that will be returned to the client
* @param exception The exception that was thrown while handling a REST request
* @return a representation of the error to return to the client
*/
public static ObjectNode handleException(HttpServletRequest request, HttpServletResponse response, Exception exception) {
ObjectMapper mapper = new ObjectMapper();
ObjectNode error = mapper.createObjectNode();
error.put("requestUrl", request.getRequestURL().toString());
String detailMessage = exception.getLocalizedMessage();
Status status = null;
ResponseStatus rs = AnnotationUtils.findAnnotation(exception.getClass(), ResponseStatus.class);
if (exception instanceof NestedServletException) {
NestedServletException nested = (NestedServletException) exception;
if (nested.getCause() instanceof Exception) {
return handleException(request, response, (Exception) nested.getCause());
}
}
if (rs != null) {
// Spring-annotated exception
status = Status.fromStatusCode(rs.value().value());
} else if (exception instanceof RestException) {
// Customized REST exception with additional data fields
RestException restException = (RestException) exception;
status = restException.getStatus();
addDataMap(error, restException.getData());
} else if (exception instanceof BulkValidationException) {
BulkValidationException bulkValidationException = (BulkValidationException) exception;
status = Status.BAD_REQUEST;
RestUtils.addBulkValidationData(error, bulkValidationException);
error.put("dataFormat", "bulk validation");
} else if (exception instanceof ValidationException) {
ValidationException valException = (ValidationException) exception;
status = Status.BAD_REQUEST;
addDataMap(error, valException.getErrorsByField());
error.put("dataFormat", "validation");
} else if (ExceptionUtils.getRootCause(exception) instanceof IOException && StringUtils.containsIgnoreCase(ExceptionUtils.getRootCauseMessage(exception), "Broken pipe")) {
response.setStatus(Status.SERVICE_UNAVAILABLE.getStatusCode());
return null;
} else {
// Unknown/unexpected exception
detailMessage = "An unexpected error has occurred";
status = Status.INTERNAL_SERVER_ERROR;
}
error.put("detail", detailMessage);
error.put("code", status.getStatusCode());
error.put("message", status.getReasonPhrase());
if (status.getFamily() == Status.Family.SERVER_ERROR) {
log.error(status.getStatusCode() + " error handling REST request", exception);
} else {
log.debug(status.getStatusCode() + " error handling REST request", exception);
}
if (!error.has("dataFormat")) {
error.put("dataFormat", "custom");
}
response.setStatus(status.getStatusCode());
return error;
}
Aggregations