Java tutorial
/* * The MIT License * * Copyright 2016 Peter Hayes. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package jenkins.plugins.itemstorage.s3; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.model.ObjectListing; import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.S3ObjectSummary; import com.amazonaws.services.s3.transfer.TransferManager; import hudson.remoting.VirtualChannel; import hudson.util.DirScanner; import hudson.util.FileVisitor; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; /** * Created by hayep on 12/2/2016. */ public class S3UploadAllCallable extends S3BaseUploadCallable<Integer> { private static final long serialVersionUID = 1L; private String bucketName; private String pathPrefix; private final DirScanner.Glob scanner; public S3UploadAllCallable(ClientHelper clientHelper, String fileMask, String excludes, String bucketName, String pathPrefix, Map<String, String> userMetadata, String storageClass, boolean useServerSideEncryption) { super(clientHelper, userMetadata, storageClass, useServerSideEncryption); this.bucketName = bucketName; this.pathPrefix = pathPrefix; scanner = new DirScanner.Glob(fileMask, excludes); } /** * Upload from slave */ @Override public Integer invoke(final TransferManager transferManager, File base, VirtualChannel channel) throws IOException, InterruptedException { if (!base.exists()) return 0; final AtomicInteger count = new AtomicInteger(0); final Uploads uploads = new Uploads(); final Map<String, S3ObjectSummary> summaries = lookupExistingCacheEntries( transferManager.getAmazonS3Client()); // Find files to upload that match scan scanner.scan(base, new FileVisitor() { @Override public void visit(File f, String relativePath) throws IOException { if (f.isFile()) { String key = pathPrefix + "/" + relativePath; S3ObjectSummary summary = summaries.get(key); if (summary == null || f.lastModified() > summary.getLastModified().getTime()) { final ObjectMetadata metadata = buildMetadata(f); uploads.startUploading(transferManager, f, IOUtils.toBufferedInputStream(FileUtils.openInputStream(f)), new Destination(bucketName, key), metadata); if (uploads.count() > 20) { waitForUploads(count, uploads); } } } } }); // Wait for each file to complete before returning waitForUploads(count, uploads); return uploads.count(); } private Map<String, S3ObjectSummary> lookupExistingCacheEntries(AmazonS3 s3) { Map<String, S3ObjectSummary> summaries = new HashMap<>(); ObjectListing listing = s3.listObjects(bucketName, pathPrefix); do { for (S3ObjectSummary summary : listing.getObjectSummaries()) { summaries.put(summary.getKey(), summary); } listing = listing.isTruncated() ? s3.listNextBatchOfObjects(listing) : null; } while (listing != null); return summaries; } private void waitForUploads(AtomicInteger count, Uploads uploads) { count.addAndGet(uploads.count()); try { uploads.finishUploading(); } catch (InterruptedException ie) { // clean up and bomb out uploads.cleanup(); Thread.interrupted(); } } }