Search in sources :

Example 11 with BridgeServiceException

use of org.sagebionetworks.bridge.exceptions.BridgeServiceException in project BridgeServer2 by Sage-Bionetworks.

the class UploadArchiveService method unzip.

/**
 * <p>
 * Unzips the given stream. For each individual zip entry, this method will call entryNameToOutputStream, passing
 * in the zip entry file name and expecting an OutputStream in which to write the unzipped bytes. It will then call
 * outputStreamFinalizer, allowing the caller to finalize the stream, for example, closing the stream.
 * </p>
 * <p>
 * The caller is responsible for closing any and all streams involved.
 * </p>
 *
 * @param source
 *         input stream of zipped data to unzip
 * @param entryNameToOutpuStream
 *         arg is the zip entry file name, return value is the OutputStream in which to write the unzipped bytes
 * @param outputStreamFinalizer
 *         args are the zip entry file name and the corresponding OutputStream returned by entryNameToOutputStream;
 *         this is where you finalize the stream, eg closing the stream
 */
public void unzip(InputStream source, Function<String, OutputStream> entryNameToOutpuStream, BiConsumer<String, OutputStream> outputStreamFinalizer) {
    // Validate input
    checkNotNull(source);
    checkNotNull(entryNameToOutpuStream);
    checkNotNull(outputStreamFinalizer);
    // Unzip
    Set<String> zipEntryNameSet = new HashSet<>();
    try (ZipInputStream zis = new ZipInputStream(source)) {
        ZipEntry zipEntry = zis.getNextEntry();
        while (zipEntry != null) {
            if (zipEntryNameSet.size() >= maxNumZipEntries) {
                throw new ZipOverflowException("The number of zip entries is over the max allowed");
            }
            final String entryName = zipEntry.getName();
            if (zipEntryNameSet.contains(entryName)) {
                throw new DuplicateZipEntryException("Duplicate filename " + entryName);
            }
            final long entrySize = zipEntry.getSize();
            if (entrySize > maxZipEntrySize) {
                throw new ZipOverflowException("Zip entry size is over the max allowed size. The entry " + entryName + " has size " + entrySize + ". The max allowed size is" + maxZipEntrySize + ".");
            }
            zipEntryNameSet.add(entryName);
            OutputStream outputStream = entryNameToOutpuStream.apply(entryName);
            toByteArray(entryName, zis, outputStream);
            outputStreamFinalizer.accept(entryName, outputStream);
            zipEntry = zis.getNextEntry();
        }
    } catch (DuplicateZipEntryException | ZipOverflowException ex) {
        throw new BadRequestException(ex);
    } catch (IOException ex) {
        throw new BridgeServiceException(ex);
    }
}
Also used : ZipOverflowException(org.sagebionetworks.bridge.util.ZipOverflowException) ZipEntry(java.util.zip.ZipEntry) ZipOutputStream(java.util.zip.ZipOutputStream) OutputStream(java.io.OutputStream) ByteArrayOutputStream(org.apache.commons.io.output.ByteArrayOutputStream) BridgeServiceException(org.sagebionetworks.bridge.exceptions.BridgeServiceException) IOException(java.io.IOException) ZipInputStream(java.util.zip.ZipInputStream) DuplicateZipEntryException(org.sagebionetworks.bridge.util.DuplicateZipEntryException) BadRequestException(org.sagebionetworks.bridge.exceptions.BadRequestException) HashSet(java.util.HashSet)

Example 12 with BridgeServiceException

use of org.sagebionetworks.bridge.exceptions.BridgeServiceException in project BridgeServer2 by Sage-Bionetworks.

the class UploadArchiveService method decrypt.

/**
 * Decrypts the specified data stream, using the encryption materials for the specified app, and returns the a
 * stream of decrypted data. The caller is responsible for closing both streams.
 */
public InputStream decrypt(String appId, InputStream source) {
    // validate
    checkNotNull(appId);
    checkArgument(StringUtils.isNotBlank(appId));
    checkNotNull(source);
    // get encryptor from cache
    CmsEncryptor encryptor = getEncryptorForApp(appId);
    // decrypt
    try {
        return encryptor.decrypt(source);
    } catch (CertificateEncodingException | CMSException | IOException ex) {
        throw new BridgeServiceException(ex);
    }
}
Also used : CmsEncryptor(org.sagebionetworks.bridge.crypto.CmsEncryptor) BridgeServiceException(org.sagebionetworks.bridge.exceptions.BridgeServiceException) CertificateEncodingException(java.security.cert.CertificateEncodingException) IOException(java.io.IOException) CMSException(org.bouncycastle.cms.CMSException)

Example 13 with BridgeServiceException

use of org.sagebionetworks.bridge.exceptions.BridgeServiceException in project BridgeServer2 by Sage-Bionetworks.

the class UploadCertificateService method createCmsKeyPair.

/**
 * Creates a CMS key pair for a particular app and save it in permanent storage.
 */
public void createCmsKeyPair(final String appId) {
    checkNotNull(appId);
    String pemFilename = getPemFilename(appId);
    if (!s3CmsClient.doesObjectExist(PRIVATE_KEY_BUCKET, pemFilename) || !s3CmsClient.doesObjectExist(CERT_BUCKET, pemFilename)) {
        final KeyPair keyPair = KeyPairFactory.newRsa2048();
        final CertificateInfo certInfo = new CertificateInfo.Builder().country(CONFIG.getProperty("upload.cms.certificate.country")).state(CONFIG.getProperty("upload.cms.certificate.state")).city(CONFIG.getProperty("upload.cms.certificate.city")).organization(CONFIG.getProperty("upload.cms.certificate.organization")).team(CONFIG.getProperty("upload.cms.certificate.team")).email(CONFIG.getProperty("upload.cms.certificate.email")).fqdn(CONFIG.getWebservicesURL()).build();
        final X509Certificate cert = certificateFactory.newCertificate(keyPair, certInfo);
        try {
            s3Put(PRIVATE_KEY_BUCKET, pemFilename, PemUtils.toPem(keyPair.getPrivate()));
            s3Put(CERT_BUCKET, pemFilename, PemUtils.toPem(cert));
        } catch (CertificateEncodingException e) {
            throw new BridgeServiceException(e);
        }
    }
}
Also used : KeyPair(java.security.KeyPair) BridgeServiceException(org.sagebionetworks.bridge.exceptions.BridgeServiceException) CertificateInfo(org.sagebionetworks.bridge.crypto.CertificateInfo) CertificateEncodingException(java.security.cert.CertificateEncodingException) X509Certificate(java.security.cert.X509Certificate)

Example 14 with BridgeServiceException

use of org.sagebionetworks.bridge.exceptions.BridgeServiceException in project BridgeServer2 by Sage-Bionetworks.

the class UploadService method uploadComplete.

public void uploadComplete(String appId, UploadCompletionClient completedBy, Upload upload, boolean redrive) {
    String uploadId = upload.getUploadId();
    // We don't want to kick off upload validation on an upload that already has upload validation.
    if (!upload.canBeValidated() && !redrive) {
        logger.info(String.format("uploadComplete called for upload %s, which is already complete", uploadId));
        return;
    }
    final String objectId = upload.getObjectId();
    ObjectMetadata obj;
    try {
        Stopwatch stopwatch = Stopwatch.createStarted();
        obj = s3Client.getObjectMetadata(uploadBucket, objectId);
        logger.info("Finished getting S3 metadata for bucket " + uploadBucket + " key " + objectId + " in " + stopwatch.elapsed(TimeUnit.MILLISECONDS) + " ms");
    } catch (AmazonS3Exception ex) {
        if (ex.getStatusCode() == 404) {
            throw new NotFoundException(ex);
        } else {
            // Only S3 404s are mapped to 404s. Everything else is an internal server error.
            throw new BridgeServiceException(ex);
        }
    }
    String sse = obj.getSSEAlgorithm();
    if (!AES_256_SERVER_SIDE_ENCRYPTION.equals(sse)) {
        logger.error("Missing S3 server-side encryption (SSE) for presigned upload " + uploadId + ".");
    }
    try {
        uploadDao.uploadComplete(completedBy, upload);
    } catch (ConcurrentModificationException ex) {
        // The old workflow is the app calls uploadComplete. The new workflow has an S3 trigger to call
        // uploadComplete. During the transition, it's very likely that this will be called twice, sometimes
        // concurrently. As such, we should log and squelch the ConcurrentModificationException.
        logger.info("Concurrent modification of upload " + uploadId + " while marking upload complete");
        // and duplicate records.
        return;
    }
    // kick off upload validation
    App app = appService.getApp(appId);
    if (BridgeUtils.isExporter3Configured(app)) {
        exporter3Service.completeUpload(app, upload);
    }
    // For backwards compatibility, always call Legacy Exporter 2.0. In the future, we may introduce a setting to
    // disable this for new apps.
    uploadValidationService.validateUpload(appId, upload);
}
Also used : App(org.sagebionetworks.bridge.models.apps.App) ConcurrentModificationException(org.sagebionetworks.bridge.exceptions.ConcurrentModificationException) Stopwatch(com.google.common.base.Stopwatch) BridgeServiceException(org.sagebionetworks.bridge.exceptions.BridgeServiceException) NotFoundException(org.sagebionetworks.bridge.exceptions.NotFoundException) AmazonS3Exception(com.amazonaws.services.s3.model.AmazonS3Exception) ObjectMetadata(com.amazonaws.services.s3.model.ObjectMetadata)

Example 15 with BridgeServiceException

use of org.sagebionetworks.bridge.exceptions.BridgeServiceException in project BridgeServer2 by Sage-Bionetworks.

the class UploadService method pollUploadValidationStatusUntilComplete.

/**
 * Polls for validation status for a given upload ID. Polls until validation is complete or otherwise is in a state
 * where further polling won't get any results (like validation failed, or upload is requested but not yet
 * uploaded), or until it times out. See getUploadValidationStatus() for more details.
 */
public UploadValidationStatus pollUploadValidationStatusUntilComplete(String uploadId) {
    // Loop logic is a little wonky. (Loop-and-a-half problem.) Use an infinite loop here and rely on tests to make
    // sure we don't go infinite.
    int numIters = 0;
    while (true) {
        UploadValidationStatus validationStatus = getUploadValidationStatus(uploadId);
        if (validationStatus.getStatus() != UploadStatus.VALIDATION_IN_PROGRESS) {
            // Return the answer we have now.
            return validationStatus;
        }
        // Short-circuit: If we've elapsed our timeout, just exit now. Don't wait for a sleep.
        numIters++;
        if (numIters >= pollValidationStatusMaxIterations) {
            throw new BridgeServiceException("Timeout polling validation status for upload " + uploadId);
        }
        // Sleep and try again.
        try {
            Thread.sleep(pollValidationStatusSleepMillis);
        } catch (InterruptedException ex) {
            logger.error("Interrupted while polling for validation status: " + ex.getMessage());
        }
    }
}
Also used : UploadValidationStatus(org.sagebionetworks.bridge.models.upload.UploadValidationStatus) BridgeServiceException(org.sagebionetworks.bridge.exceptions.BridgeServiceException)

Aggregations

BridgeServiceException (org.sagebionetworks.bridge.exceptions.BridgeServiceException)78 IOException (java.io.IOException)25 Test (org.testng.annotations.Test)21 PersistenceException (javax.persistence.PersistenceException)7 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)6 JsonNode (com.fasterxml.jackson.databind.JsonNode)6 CacheKey (org.sagebionetworks.bridge.cache.CacheKey)5 App (org.sagebionetworks.bridge.models.apps.App)5 AmazonServiceException (com.amazonaws.AmazonServiceException)4 ObjectMetadata (com.amazonaws.services.s3.model.ObjectMetadata)4 EntityNotFoundException (org.sagebionetworks.bridge.exceptions.EntityNotFoundException)4 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)3 Stopwatch (com.google.common.base.Stopwatch)3 ByteArrayInputStream (java.io.ByteArrayInputStream)3 List (java.util.List)3 BadRequestException (org.sagebionetworks.bridge.exceptions.BadRequestException)3 FailedBatch (com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.FailedBatch)2 AmazonS3Exception (com.amazonaws.services.s3.model.AmazonS3Exception)2 SendMessageResult (com.amazonaws.services.sqs.model.SendMessageResult)2 ObjectNode (com.fasterxml.jackson.databind.node.ObjectNode)2