/** * DeployMan # Thomas Uhrig (Stuttgart, 2014) # www.tuhrig.de */ package de.tuhrig.deployman.repo; import java.io.ByteArrayInputStream; import java.io.File; import java.io.InputStream; import java.util.List; import java.util.stream.Collectors; import com.amazonaws.AmazonClientException; import com.amazonaws.AmazonServiceException; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.model.ListObjectsRequest; import com.amazonaws.services.s3.model.ObjectListing; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.PutObjectRequest; import com.amazonaws.services.s3.model.S3ObjectSummary; import com.amazonaws.services.s3.transfer.MultipleFileUpload; import com.amazonaws.services.s3.transfer.Transfer; import com.amazonaws.services.s3.transfer.TransferManager; import com.amazonaws.services.s3.transfer.Upload; import de.tuhrig.deployman.aws.Aws; import de.tuhrig.deployman.aws.S3; import de.tuhrig.deployman.aws.SharpProgressListener; import de.tuhrig.deployman.model.Size; import static de.tuhrig.deployman.DeployMan.*; /** * @author tuhrig */ public class RemoteRepository implements IRepository { private AmazonS3 s3 = new S3().getClient(); public boolean objectExistsRemote(String objectName) { try { String bucketName = getUserProperty(REPO_BUCKET); this.s3.getObject(bucketName, objectName); } catch (AmazonServiceException e) { String errorCode = e.getErrorCode(); if (!errorCode.equals("NoSuchKey")) //$NON-NLS-1$ { throw e; } return false; } return true; } public boolean folderExistsRemote(String objectName) { try { String bucketName = getUserProperty(REPO_BUCKET); return this.s3.listObjects(bucketName, objectName).getObjectSummaries().size() > 0; } catch (AmazonServiceException e) { String errorCode = e.getErrorCode(); if (!errorCode.equals("NoSuchKey")) //$NON-NLS-1$ { throw e; } return false; } } public boolean folderExistsInRootOfBucket(String key) { if (!key.endsWith(SLASH)) key += SLASH; ObjectListing objects = listObjectsInRootFolder(); for (String commonPrefix : objects.getCommonPrefixes()) { if (commonPrefix.equals(key)) return true; } return false; } public long getSizeOfRemoteFolder(String folderPath) { ObjectListing objectListing = listObjectsWithPrefix(folderPath); return objectListing.getObjectSummaries().stream().mapToLong(os -> os.getSize()).sum(); } public long getNumberOfFilesOfRemoteFolder(String folderPath) { ObjectListing objectListing = listObjectsWithPrefix(folderPath); return objectListing.getObjectSummaries().stream().count(); } public List<String> getRemoteFolders(String prefix) { String bucket = getUserProperty(REPO_BUCKET); ObjectListing listing = this.s3.listObjects(new ListObjectsRequest().withBucketName(bucket).withPrefix(prefix) .withDelimiter("/")); //$NON-NLS-1$ return listing.getCommonPrefixes().stream().map(o -> o.substring(0, o.length() - 1)) .collect(Collectors.toList()); } public void createRemoteFolder(String bucket, String folder) { ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentLength(0); InputStream emptyContent = new ByteArrayInputStream(new byte[0]); PutObjectRequest createImagesFolder = new PutObjectRequest(bucket, folder, emptyContent, metadata); this.s3.putObject(createImagesFolder); } private void waitForUpload(Transfer upload, TransferManager tm) throws AmazonServiceException, AmazonClientException, InterruptedException { long bytes = upload.getProgress().getTotalBytesToTransfer(); console.write(new Size(bytes) + " to upload"); //$NON-NLS-1$ long fraction = bytes / 50; upload.addProgressListener(new SharpProgressListener(fraction)); upload.waitForCompletion(); tm.shutdownNow(); console.write("\nDone"); //$NON-NLS-1$ } public List<S3ObjectSummary> getRemoteObjects(String prefix) { ObjectListing objectListing = listObjectsWithPrefix(prefix); return objectListing.getObjectSummaries().stream().filter(obj -> !obj.getKey().endsWith(SLASH)) .collect(Collectors.toList()); } private ObjectListing listObjectsWithPrefix(String prefix) { String bucket = getUserProperty(REPO_BUCKET); return this.s3.listObjects(new ListObjectsRequest().withBucketName(bucket).withPrefix(prefix)); } private ObjectListing listObjectsInRootFolder() { String bucket = getUserProperty(REPO_BUCKET); return this.s3 .listObjects(new ListObjectsRequest().withBucketName(bucket).withDelimiter(SLASH)); } public void uploadFile(File file, String key) throws AmazonServiceException, AmazonClientException, InterruptedException { TransferManager tm = new TransferManager(new Aws().getAwsCredentials()); Upload upload = tm.upload(getUserProperty(REPO_BUCKET), key, file); waitForUpload(upload, tm); } public void uploadFileSilently(File file, String key) throws AmazonServiceException, AmazonClientException { TransferManager tm = new TransferManager(new Aws().getAwsCredentials()); tm.upload(getUserProperty(REPO_BUCKET), key, file); } public void uploadFolder(File folder, String key) throws AmazonServiceException, AmazonClientException, InterruptedException { TransferManager tm = new TransferManager(new Aws().getAwsCredentials()); MultipleFileUpload upload = tm.uploadDirectory(getUserProperty(REPO_BUCKET), key, folder, true); waitForUpload(upload, tm); } @Override public void init() { new ImageRepository().initRemote(); new ConfigRepository().initRemote(); } @Override public boolean exists() { return new ImageRepository().existsRemote() && new ConfigRepository().existsRemote(); } @Override public void printInfo() { String bucket = getUserProperty(REPO_BUCKET); if (exists()) { console.write("Remote repository: " + bucket + " (exists)"); //$NON-NLS-1$ //$NON-NLS-2$ console.newLine(); new ImageRepository().printRemoteObjects(); new ConfigRepository().printLocaleObjects(); } else { if (!new ImageRepository().existsRemote()) console.write("Remote image repository in '" + bucket + "' is missing"); //$NON-NLS-1$ //$NON-NLS-2$ if (!new ConfigRepository().existsRemote()) console.write("Remote config repository in '" + bucket + "' is missing"); //$NON-NLS-1$ //$NON-NLS-2$ console.newLine(); } } }