Search in sources :

Example 1 with BulkValidationException

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;
}
Also used : ValidationException(uk.ac.bbsrc.tgac.miso.core.service.exception.ValidationException) BulkValidationException(uk.ac.bbsrc.tgac.miso.core.service.exception.BulkValidationException) Authentication(org.springframework.security.core.Authentication) TransactionStatus(org.springframework.transaction.TransactionStatus) BulkValidationException(uk.ac.bbsrc.tgac.miso.core.service.exception.BulkValidationException) TransactionCallbackWithoutResult(org.springframework.transaction.support.TransactionCallbackWithoutResult) ValidationException(uk.ac.bbsrc.tgac.miso.core.service.exception.ValidationException) IOException(java.io.IOException) BulkValidationException(uk.ac.bbsrc.tgac.miso.core.service.exception.BulkValidationException)

Example 2 with BulkValidationException

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;
}
Also used : ContainerQC(uk.ac.bbsrc.tgac.miso.core.data.qc.ContainerQC) LibraryQC(uk.ac.bbsrc.tgac.miso.core.data.qc.LibraryQC) QC(uk.ac.bbsrc.tgac.miso.core.data.qc.QC) SampleQC(uk.ac.bbsrc.tgac.miso.core.data.qc.SampleQC) PoolQC(uk.ac.bbsrc.tgac.miso.core.data.qc.PoolQC) ValidationException(uk.ac.bbsrc.tgac.miso.core.service.exception.ValidationException) BulkValidationException(uk.ac.bbsrc.tgac.miso.core.service.exception.BulkValidationException) Authentication(org.springframework.security.core.Authentication) QcTarget(uk.ac.bbsrc.tgac.miso.core.data.qc.QcTarget) TransactionStatus(org.springframework.transaction.TransactionStatus) BulkValidationException(uk.ac.bbsrc.tgac.miso.core.service.exception.BulkValidationException) BulkQcSaveOperation(uk.ac.bbsrc.tgac.miso.core.service.BulkQcSaveOperation) TransactionCallbackWithoutResult(org.springframework.transaction.support.TransactionCallbackWithoutResult) ValidationException(uk.ac.bbsrc.tgac.miso.core.service.exception.ValidationException) BulkValidationException(uk.ac.bbsrc.tgac.miso.core.service.exception.BulkValidationException) IOException(java.io.IOException)

Example 3 with BulkValidationException

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;
}
Also used : ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) BulkValidationException(uk.ac.bbsrc.tgac.miso.core.service.exception.BulkValidationException)

Example 4 with BulkValidationException

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;
}
Also used : ResponseStatus(org.springframework.web.bind.annotation.ResponseStatus) Status(javax.ws.rs.core.Response.Status) NestedServletException(org.springframework.web.util.NestedServletException) ValidationException(uk.ac.bbsrc.tgac.miso.core.service.exception.ValidationException) BulkValidationException(uk.ac.bbsrc.tgac.miso.core.service.exception.BulkValidationException) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) ResponseStatus(org.springframework.web.bind.annotation.ResponseStatus) IOException(java.io.IOException) BulkValidationException(uk.ac.bbsrc.tgac.miso.core.service.exception.BulkValidationException) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) ValidationException(uk.ac.bbsrc.tgac.miso.core.service.exception.ValidationException) IOException(java.io.IOException) NestedServletException(org.springframework.web.util.NestedServletException) BulkValidationException(uk.ac.bbsrc.tgac.miso.core.service.exception.BulkValidationException)

Aggregations

BulkValidationException (uk.ac.bbsrc.tgac.miso.core.service.exception.BulkValidationException)4 IOException (java.io.IOException)3 ValidationException (uk.ac.bbsrc.tgac.miso.core.service.exception.ValidationException)3 ObjectNode (com.fasterxml.jackson.databind.node.ObjectNode)2 Authentication (org.springframework.security.core.Authentication)2 TransactionStatus (org.springframework.transaction.TransactionStatus)2 TransactionCallbackWithoutResult (org.springframework.transaction.support.TransactionCallbackWithoutResult)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 Status (javax.ws.rs.core.Response.Status)1 ResponseStatus (org.springframework.web.bind.annotation.ResponseStatus)1 NestedServletException (org.springframework.web.util.NestedServletException)1 ContainerQC (uk.ac.bbsrc.tgac.miso.core.data.qc.ContainerQC)1 LibraryQC (uk.ac.bbsrc.tgac.miso.core.data.qc.LibraryQC)1 PoolQC (uk.ac.bbsrc.tgac.miso.core.data.qc.PoolQC)1 QC (uk.ac.bbsrc.tgac.miso.core.data.qc.QC)1 QcTarget (uk.ac.bbsrc.tgac.miso.core.data.qc.QcTarget)1 SampleQC (uk.ac.bbsrc.tgac.miso.core.data.qc.SampleQC)1 BulkQcSaveOperation (uk.ac.bbsrc.tgac.miso.core.service.BulkQcSaveOperation)1