2017-09-22 3 views
1

コードがあります。AWS4署名の計算後にストリームをリセットできません

List<PartETag> uploadPartsOfAsset(AssetUploadRequestVO requestVO) { 
    final SingleClient singleClient = clientProvider.getClient(requestVO.getAssetKind()); 
    final List<PartETag> parts = new ArrayList<>(); 
    final String key = String.join(DELIMITER, requestVO.getClientName(), requestVO.getAssetGroup(), requestVO.getAssetName()); 

    final long contentSize = requestVO.getContentSize(); 
    long position = 0; 
    long partSize = minPartSize; 

    final UploadPartRequest request = new UploadPartRequest(); 

    try (InputStream source = requestVO.getSource()) { 
     for (int partNumber = requestVO.getPartNumber(); position < requestVO.getContentSize(); partNumber++) { 
      partSize = Math.min(partSize, (requestVO.getContentSize() - position)); 

      final long nextFilePosition = position + partSize; 
      if((requestVO.getContentSize() - nextFilePosition) < minPartSize){ 
       partSize = contentSize - position; 
       position = contentSize; 
      } 

      request.withBucketName(singleClient.getBucketName()) 
        .withKey(key) 
        .withUploadId(requestVO.getUploadId()).withPartNumber(partNumber) 
        .withInputStream(source) 
        .withPartSize(partSize); 

      PartETag partETag = null; 
      try { 
       partETag = singleClient.getAmazonS3Client().uploadPart(request).getPartETag(); 
      } catch (AmazonS3Exception e){ 
       throw new AssetNotFoundException(e.getMessage()); 
      } 
      parts.add(partETag); 

      position += partSize; 
     } 
    } catch (IOException e) { 
     throw new AssetUploadException("The asset cannot be upload.", e); 
    } 

    return parts; 
} 

AssetUploadRequestVO.getSource()は、S3ObjectInputStreamのインスタンスです。問題は、このスロー例外です:

com.amazonaws.SdkClientException: Unable to reset stream after calculating AWS4 signature 
at com.amazonaws.auth.AWS4Signer.calculateContentHash(AWS4Signer.java:542) ~[aws-java-sdk-core-1.11.125.jar:na] 
at com.amazonaws.services.s3.internal.AWSS3V4Signer.calculateContentHash(AWSS3V4Signer.java:118) ~[aws-java-sdk-s3-1.11.125.jar:na] 
at com.amazonaws.auth.AWS4Signer.sign(AWS4Signer.java:213) ~[aws-java-sdk-core-1.11.125.jar:na] 
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1164) ~[aws-java-sdk-core-1.11.125.jar:na] 

...

Caused by: java.io.IOException: Resetting to invalid mark 
at java.io.BufferedInputStream.reset(BufferedInputStream.java:448) ~[na:1.8.0_144] 
at com.amazonaws.internal.SdkBufferedInputStream.reset(SdkBufferedInputStream.java:106) ~[aws-java-sdk-core-1.11.125.jar:na] 
at com.amazonaws.internal.SdkFilterInputStream.reset(SdkFilterInputStream.java:102) ~[aws-java-sdk-core-1.11.125.jar:na] 
at com.amazonaws.event.ProgressInputStream.reset(ProgressInputStream.java:168) ~[aws-java-sdk-core-1.11.125.jar:na] 

私はすでにこのバグを解決する方法を見つけたが、問題は、それがなぜ起こったか、私は本当に理解していないということです。

解決策は、S3ObjectInputStreamを他の入力ストリームに変更することです。だから、誰かが私を助けてくださいとどのような問題であり、そして私の解決策の良い説明できる

new ByteArrayInputStream(IOUtils.toByteArray(requestVO.getSource())) 

:?私の場合、私はそれを変更しましたか また、S3を使用してECSでのみ失敗する場合は、このコードが正常に動作することを追加したいと思います。

答えて

1

問題は、EC2から返されたストリームがマークをサポートしていないことです。 FileInputStreamまたはByteArrayInputStreamに保存する必要があります。または私の場合、アマゾン内のすべてをマージしてサーバにフェッチせずに

関連する問題