use of com.amazonaws.services.s3.transfer.TransferProgress in project herd by FINRAOS.
the class MockS3OperationsImpl method copyFile.
/**
* {@inheritDoc} <p/> <p> This implementation simulates a copyFile operation. </p> <p> This method copies files in-memory. </p> <p> The result {@link Copy}
* has the following properties: <dl> <p/> <dt>description</dt> <dd>"MockTransfer"</dd> <p/> <dt>state</dt> <dd>{@link TransferState#Completed}</dd> <p/>
* <dt>transferProgress.totalBytesToTransfer</dt> <dd>1024</dd> <p/> <dt>transferProgress.updateProgress</dt> <dd>1024</dd> <p/> </dl> <p/> All other
* properties are set as default. </p> <p> This operation takes the following hints when suffixed in copyObjectRequest.sourceKey: <dl> <p/>
* <dt>MOCK_S3_FILE_NAME_SERVICE_EXCEPTION</dt> <dd>Throws a AmazonServiceException</dd> <p/> </dl> </p>
*/
@Override
public Copy copyFile(final CopyObjectRequest copyObjectRequest, TransferManager transferManager) {
LOGGER.debug("copyFile(): copyObjectRequest.getSourceBucketName() = " + copyObjectRequest.getSourceBucketName() + ", copyObjectRequest.getSourceKey() = " + copyObjectRequest.getSourceKey() + ", copyObjectRequest.getDestinationBucketName() = " + copyObjectRequest.getDestinationBucketName() + ", copyObjectRequest.getDestinationKey() = " + copyObjectRequest.getDestinationKey());
if (copyObjectRequest.getSourceKey().endsWith(MOCK_S3_FILE_NAME_SERVICE_EXCEPTION)) {
throw new AmazonServiceException(null);
}
String sourceBucketName = copyObjectRequest.getSourceBucketName();
String sourceKey = copyObjectRequest.getSourceKey();
MockS3Bucket mockSourceS3Bucket = getOrCreateBucket(sourceBucketName);
MockS3Object mockSourceS3Object = mockSourceS3Bucket.getObjects().get(sourceKey);
if (mockSourceS3Object == null) {
AmazonServiceException amazonServiceException = new AmazonServiceException(S3Operations.ERROR_CODE_NO_SUCH_KEY);
amazonServiceException.setErrorCode(S3Operations.ERROR_CODE_NO_SUCH_KEY);
throw amazonServiceException;
}
// Set the result CopyImpl and TransferProgress.
TransferProgress transferProgress = new TransferProgress();
transferProgress.setTotalBytesToTransfer(mockSourceS3Object.getObjectMetadata().getContentLength());
transferProgress.updateProgress(mockSourceS3Object.getObjectMetadata().getContentLength());
CopyImpl copy = new CopyImpl(MOCK_TRANSFER_DESCRIPTION, transferProgress, null, null);
copy.setState(TransferState.Completed);
// If an invalid KMS Id was passed in, mark the transfer as failed and return an exception via the transfer monitor.
if (copyObjectRequest.getSSEAwsKeyManagementParams() != null) {
final String kmsId = copyObjectRequest.getSSEAwsKeyManagementParams().getAwsKmsKeyId();
if (kmsId.startsWith(MOCK_KMS_ID_FAILED_TRANSFER)) {
copy.setState(TransferState.Failed);
copy.setMonitor(new TransferMonitor() {
@Override
public Future<?> getFuture() {
if (!kmsId.equals(MOCK_KMS_ID_FAILED_TRANSFER_NO_EXCEPTION)) {
throw new AmazonServiceException("Key '" + copyObjectRequest.getSSEAwsKeyManagementParams().getAwsKmsKeyId() + "' does not exist (Service: Amazon S3; Status Code: 400; Error Code: KMS.NotFoundException; Request ID: 1234567890123456)");
}
// We don't want an exception to be thrown so return a basic future that won't throw an exception.
BasicFuture<?> future = new BasicFuture<Void>(null);
future.completed(null);
return future;
}
@Override
public boolean isDone() {
return true;
}
});
} else if (kmsId.startsWith(MOCK_KMS_ID_CANCELED_TRANSFER)) {
// If the KMS indicates a cancelled transfer, just update the state to canceled.
copy.setState(TransferState.Canceled);
}
}
// If copy operation is marked as completed, perform the actual file copy in memory.
if (copy.getState().equals(TransferState.Completed)) {
String destinationBucketName = copyObjectRequest.getDestinationBucketName();
String destinationObjectKey = copyObjectRequest.getDestinationKey();
String destinationObjectVersion = MOCK_S3_BUCKET_NAME_VERSIONING_ENABLED.equals(destinationBucketName) ? UUID.randomUUID().toString() : null;
String destinationObjectKeyVersion = destinationObjectKey + (destinationObjectVersion != null ? destinationObjectVersion : "");
ObjectMetadata objectMetadata = copyObjectRequest.getNewObjectMetadata();
MockS3Object mockDestinationS3Object = new MockS3Object();
mockDestinationS3Object.setKey(destinationObjectKey);
mockDestinationS3Object.setVersion(destinationObjectVersion);
mockDestinationS3Object.setData(Arrays.copyOf(mockSourceS3Object.getData(), mockSourceS3Object.getData().length));
mockDestinationS3Object.setObjectMetadata(objectMetadata);
MockS3Bucket mockDestinationS3Bucket = getOrCreateBucket(destinationBucketName);
mockDestinationS3Bucket.getObjects().put(destinationObjectKey, mockDestinationS3Object);
mockDestinationS3Bucket.getVersions().put(destinationObjectKeyVersion, mockDestinationS3Object);
}
return copy;
}
use of com.amazonaws.services.s3.transfer.TransferProgress in project herd by FINRAOS.
the class MockS3OperationsImpl method downloadDirectory.
/**
* {@inheritDoc}
* <p/>
* This implementation creates any directory that does not exist in the path to the destination directory.
*/
@Override
public MultipleFileDownload downloadDirectory(String bucketName, String keyPrefix, File destinationDirectory, TransferManager transferManager) {
LOGGER.debug("downloadDirectory(): bucketName = " + bucketName + ", keyPrefix = " + keyPrefix + ", destinationDirectory = " + destinationDirectory);
MockS3Bucket mockS3Bucket = mockS3Buckets.get(bucketName);
List<Download> downloads = new ArrayList<>();
long totalBytes = 0;
if (mockS3Bucket != null) {
for (MockS3Object mockS3Object : mockS3Bucket.getObjects().values()) {
if (mockS3Object.getKey().startsWith(keyPrefix)) {
String filePath = destinationDirectory.getAbsolutePath() + "/" + mockS3Object.getKey();
File file = new File(filePath);
// Create any directory in the path that does not exist.
file.getParentFile().mkdirs();
try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
LOGGER.debug("downloadDirectory(): Writing file " + file);
fileOutputStream.write(mockS3Object.getData());
totalBytes += mockS3Object.getData().length;
downloads.add(new DownloadImpl(null, null, null, null, null, new GetObjectRequest(bucketName, mockS3Object.getKey()), file, mockS3Object.getObjectMetadata(), false));
} catch (IOException e) {
throw new RuntimeException("Error writing to file " + file, e);
}
}
}
}
TransferProgress progress = new TransferProgress();
progress.setTotalBytesToTransfer(totalBytes);
progress.updateProgress(totalBytes);
MultipleFileDownloadImpl multipleFileDownload = new MultipleFileDownloadImpl(null, progress, null, keyPrefix, bucketName, downloads);
multipleFileDownload.setState(TransferState.Completed);
return multipleFileDownload;
}
use of com.amazonaws.services.s3.transfer.TransferProgress in project herd by FINRAOS.
the class MockS3OperationsImpl method uploadFileList.
@Override
public MultipleFileUpload uploadFileList(String bucketName, String virtualDirectoryKeyPrefix, File directory, List<File> files, ObjectMetadataProvider metadataProvider, TransferManager transferManager) {
LOGGER.debug("uploadFileList(): bucketName = " + bucketName + ", virtualDirectoryKeyPrefix = " + virtualDirectoryKeyPrefix + ", directory = " + directory + ", files = " + files);
String directoryPath = directory.getAbsolutePath();
long totalFileLength = 0;
List<Upload> subTransfers = new ArrayList<>();
for (File file : files) {
// Get path to file relative to the specified directory
String relativeFilePath = file.getAbsolutePath().substring(directoryPath.length());
// Replace any backslashes (i.e. Windows separator) with a forward slash.
relativeFilePath = relativeFilePath.replace("\\", "/");
// Remove any leading slashes
relativeFilePath = relativeFilePath.replaceAll("^/+", "");
long fileLength = file.length();
// Remove any trailing slashes
virtualDirectoryKeyPrefix = virtualDirectoryKeyPrefix.replaceAll("/+$", "");
String s3ObjectKey = virtualDirectoryKeyPrefix + "/" + relativeFilePath;
totalFileLength += fileLength;
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, s3ObjectKey, file);
ObjectMetadata objectMetadata = new ObjectMetadata();
metadataProvider.provideObjectMetadata(null, objectMetadata);
putObjectRequest.setMetadata(objectMetadata);
putObject(putObjectRequest, transferManager.getAmazonS3Client());
subTransfers.add(new UploadImpl(null, null, null, null));
}
TransferProgress progress = new TransferProgress();
progress.setTotalBytesToTransfer(totalFileLength);
progress.updateProgress(totalFileLength);
MultipleFileUploadImpl multipleFileUpload = new MultipleFileUploadImpl(null, progress, null, virtualDirectoryKeyPrefix, bucketName, subTransfers);
multipleFileUpload.setState(TransferState.Completed);
return multipleFileUpload;
}
use of com.amazonaws.services.s3.transfer.TransferProgress in project herd by FINRAOS.
the class S3DaoImpl method performTransfer.
/**
* Performs a file/directory transfer.
*
* @param params the parameters.
* @param transferer a transferer that knows how to perform the transfer.
*
* @return the results.
* @throws InterruptedException if a problem is encountered.
*/
private S3FileTransferResultsDto performTransfer(final S3FileTransferRequestParamsDto params, Transferer transferer) throws InterruptedException {
// Create a transfer manager.
TransferManager transferManager = getTransferManager(params);
try {
// Start a stop watch to keep track of how long the transfer takes.
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// Perform the transfer.
Transfer transfer = transferer.performTransfer(transferManager);
TransferProgress transferProgress = transfer.getProgress();
logTransferProgress(transferProgress);
long stepCount = 0;
// Loop until the transfer is complete.
do {
Thread.sleep(sleepIntervalsMillis);
stepCount++;
// Log progress status every 30 seconds and when transfer is complete.
if (transfer.isDone() || stepCount % 300 == 0) {
logTransferProgress(transferProgress);
}
} while (!transfer.isDone());
// Stop the stop watch and create a results object.
stopWatch.stop();
// If the transfer failed, throw the underlying AWS exception if we can determine one. Otherwise, throw our own exception.
TransferState transferState = transfer.getState();
if (transferState == TransferState.Failed) {
// The waitForException method should return the underlying AWS exception since the state is "Failed". It should not block since the
// transfer is already "done" per previous code checking "isDone".
AmazonClientException amazonClientException = transfer.waitForException();
// This is unlikely since the transfer failed, but it's better to handle the possibility just in case.
if (amazonClientException == null) {
throw new IllegalStateException("The transfer operation \"" + transfer.getDescription() + "\" failed for an unknown reason.");
}
// Throw the Amazon underlying exception.
throw amazonClientException;
} else // Ensure the transfer completed. If not, throw an exception.
if (transferState != TransferState.Completed) {
throw new IllegalStateException("The transfer operation \"" + transfer.getDescription() + "\" did not complete successfully. Current state: \"" + transferState + "\".");
}
// TransferProgress.getBytesTransferred() are not populated for S3 Copy objects.
if (!(transfer instanceof Copy)) {
// Sanity check for the number of bytes transferred.
Assert.isTrue(transferProgress.getBytesTransferred() >= transferProgress.getTotalBytesToTransfer(), String.format("Actual number of bytes transferred is less than expected (actual: %d bytes; expected: %d bytes).", transferProgress.getBytesTransferred(), transferProgress.getTotalBytesToTransfer()));
}
// Create the results object and populate it with the standard data.
S3FileTransferResultsDto results = new S3FileTransferResultsDto();
results.setDurationMillis(stopWatch.getTime());
results.setTotalBytesTransferred(transfer.getProgress().getBytesTransferred());
results.setTotalFilesTransferred(1L);
if (transfer instanceof MultipleFileUpload) {
// For upload directory, we need to calculate the total number of files transferred differently.
results.setTotalFilesTransferred((long) ((MultipleFileUpload) transfer).getSubTransfers().size());
} else if (transfer instanceof MultipleFileDownload) {
// For download directory, we need to calculate the total number of files differently.
results.setTotalFilesTransferred((long) listDirectory(params).size());
}
// Return the results.
return results;
} finally {
// Shutdown the transfer manager to release resources. If this isn't done, the JVM may delay upon exiting.
transferManager.shutdownNow();
}
}
use of com.amazonaws.services.s3.transfer.TransferProgress in project herd by FINRAOS.
the class S3DaoTest method testPerformTransferAssertErrorWhenTransferBytesMismatch.
@Test
public void testPerformTransferAssertErrorWhenTransferBytesMismatch() throws Exception {
S3Operations originalS3Operations = (S3Operations) ReflectionTestUtils.getField(s3Dao, "s3Operations");
S3Operations mockS3Operations = mock(S3Operations.class);
ReflectionTestUtils.setField(s3Dao, "s3Operations", mockS3Operations);
// Shorten the sleep interval for faster tests
long originalSleepIntervalsMillis = (long) ReflectionTestUtils.getField(s3Dao, "sleepIntervalsMillis");
ReflectionTestUtils.setField(s3Dao, "sleepIntervalsMillis", 1l);
try {
S3FileTransferRequestParamsDto s3FileTransferRequestParamsDto = new S3FileTransferRequestParamsDto();
s3FileTransferRequestParamsDto.setLocalPath("localPath");
when(mockS3Operations.upload(any(), any())).then(new Answer<Upload>() {
@Override
public Upload answer(InvocationOnMock invocation) throws Throwable {
Upload mockedUpload = mock(Upload.class);
TransferProgress transferProgress = new TransferProgress();
// bytesTransferred < totalBytesToTransfer should cause error
ReflectionTestUtils.setField(transferProgress, "bytesTransferred", 0l);
ReflectionTestUtils.setField(transferProgress, "totalBytesToTransfer", 1l);
when(mockedUpload.getProgress()).thenReturn(transferProgress);
when(mockedUpload.isDone()).thenReturn(true);
when(mockedUpload.getState()).thenReturn(TransferState.Completed);
return mockedUpload;
}
});
try {
s3Dao.uploadFile(s3FileTransferRequestParamsDto);
fail();
} catch (Exception e) {
assertEquals(IllegalArgumentException.class, e.getClass());
assertEquals("Actual number of bytes transferred is less than expected (actual: 0 bytes; expected: 1 bytes).", e.getMessage());
}
} finally {
ReflectionTestUtils.setField(s3Dao, "s3Operations", originalS3Operations);
ReflectionTestUtils.setField(s3Dao, "sleepIntervalsMillis", originalSleepIntervalsMillis);
}
}
Aggregations