簡體   English   中英

AWS Amazon S3 Java SDK-在上傳大文件時過期時刷新憑證/令牌

[英]AWS Amazon S3 Java SDK - Refresh credentials / token when expired while uploading large file

我正在嘗試將一個大文件上傳到使用令牌的服務器,並且令牌在10分鍾后過期,因此,如果我上傳一個小文件,它將可以正常工作,因此,如果文件比我大,將會遇到一些問題,並且會嘗試在訪問被拒絕時永遠上傳

所以,我需要刷新這比用於AWSStaticCredentialsProvider所以我不知道我怎么能做到這一點的BasicAWSCredentials令牌,請幫助=)

值得一提的是,我們使用提供令牌的本地服務器(而非亞馬遜雲),為方便起見,我們使用亞馬遜的代碼。

這是我的代碼:

public void uploadMultipart(File file) throws Exception {
    //this method will give you a initial token for a given user, 
    //than calculates when a new token is needed and will refresh it just when necessary

    String token = getUsetToken();
    String existingBucketName = myTenant.toLowerCase() + ".package.upload";
    String endPoint = urlAPI + "s3/buckets/";
    String strSize = FileUtils.byteCountToDisplaySize(FileUtils.sizeOf(file));
    System.out.println("File size: " + strSize);

    AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(endPoint, null);//note: Region has to be null
    //AWSCredentialsProvider        
    BasicAWSCredentials sessionCredentials = new BasicAWSCredentials(token, "NOT_USED");//secretKey should be set to NOT_USED

    AmazonS3 s3 = AmazonS3ClientBuilder
            .standard()
            .withCredentials(new AWSStaticCredentialsProvider(sessionCredentials))
            .withEndpointConfiguration(endpointConfiguration)
            .enablePathStyleAccess()
            .build();

    int maxUploadThreads = 5;
    TransferManager tm = TransferManagerBuilder
            .standard()
            .withS3Client(s3)
            .withMultipartUploadThreshold((long) (5 * 1024 * 1024))
            .withExecutorFactory(() -> Executors.newFixedThreadPool(maxUploadThreads))
            .build();

    PutObjectRequest request = new PutObjectRequest(existingBucketName, file.getName(), file);
    //request.putCustomRequestHeader("Access-Token", token);
    ProgressListener progressListener = progressEvent -> System.out.println("Transferred bytes: " + progressEvent.getBytesTransferred());
    request.setGeneralProgressListener(progressListener);
    Upload upload = tm.upload(request);

    LocalDateTime uploadStartedAt = LocalDateTime.now();
    log.info("Starting upload at: " + uploadStartedAt);

    try {
        upload.waitForCompletion();
        //upload.waitForUploadResult();
        log.info("Upload completed. " + strSize);

    } catch (Exception e) {//AmazonClientException
        log.error("Error occurred while uploading file - " + strSize);
        e.printStackTrace();
    }
}

找到解決方案!

我找到了一種解決辦法,說實話,我對結果感到非常滿意,我已經對大文件(50gd.zip)進行了許多測試,並且在每種情況下都可以正常工作

我的解決方案是, 刪除以下行: BasicAWSCredentials sessionCredentials = new BasicAWSCredentials(token, "NOT_USED");

AWSCredentials是一個接口,因此我們可以用動態的方式覆蓋它, 令牌過期的邏輯以及需要新的新令牌的邏輯都保存在getToken()方法中,這意味着您每次調用都不會造成任何傷害

AWSCredentials sessionCredentials = new AWSCredentials() {
    @Override
    public String getAWSAccessKeyId() {
        try {
            return getToken(); //getToken() method return a string 
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public String getAWSSecretKey() {
        return "NOT_USED";
    }
};

上載文件(或多部分文件的一部分)時,您使用的憑據必須持續足夠長的時間才能完成上載。 您無法刷新憑證,因為沒有方法可以更新AWS S3,即您將新憑證用於已簽名的請求。

您可以將上傳文件分成較小的文件,以便更快地上傳。 然后,僅上傳X個部分。 刷新您的憑據並上傳Y部分。 重復直到所有部分都上傳。 然后,您需要通過合並各個部分來完成操作(這是一個單獨的命令)。 這不是一個完美的解決方案,因為無法精確控制傳輸速度,這意味着您將必須編寫自己的上傳代碼(這並不困難)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM