11package dev .zarr .zarrjava .store ;
22
3- import com .amazonaws .services .s3 .AmazonS3 ;
4- import com .amazonaws .services .s3 .model .GetObjectRequest ;
5- import com .amazonaws .services .s3 .model .ObjectMetadata ;
6- import com .amazonaws .services .s3 .model .S3ObjectInputStream ;
73import dev .zarr .zarrjava .utils .Utils ;
4+ import software .amazon .awssdk .core .ResponseInputStream ;
5+ import software .amazon .awssdk .core .sync .RequestBody ;
6+ import software .amazon .awssdk .services .s3 .S3Client ;
7+ import software .amazon .awssdk .services .s3 .model .DeleteObjectRequest ;
8+ import software .amazon .awssdk .services .s3 .model .GetObjectRequest ;
9+ import software .amazon .awssdk .services .s3 .model .GetObjectResponse ;
10+ import software .amazon .awssdk .services .s3 .model .HeadObjectRequest ;
11+ import software .amazon .awssdk .services .s3 .model .ListObjectsRequest ;
12+ import software .amazon .awssdk .services .s3 .model .ListObjectsResponse ;
13+ import software .amazon .awssdk .services .s3 .model .PutObjectRequest ;
14+
815import java .io .ByteArrayInputStream ;
916import java .io .IOException ;
1017import java .io .InputStream ;
1623public class S3Store implements Store , Store .ListableStore {
1724
1825 @ Nonnull
19- private final AmazonS3 s3client ;
26+ private final S3Client s3client ;
2027 @ Nonnull
2128 private final String bucketName ;
2229 @ Nullable
2330 private final String prefix ;
2431
25- public S3Store (@ Nonnull AmazonS3 s3client , @ Nonnull String bucketName , @ Nullable String prefix ) {
32+ public S3Store (@ Nonnull S3Client s3client , @ Nonnull String bucketName , @ Nullable String prefix ) {
2633 this .s3client = s3client ;
2734 this .bucketName = bucketName ;
2835 this .prefix = prefix ;
@@ -40,8 +47,7 @@ String resolveKeys(String[] keys) {
4047
4148 @ Nullable
4249 ByteBuffer get (GetObjectRequest getObjectRequest ) {
43- try (S3ObjectInputStream inputStream = s3client .getObject (getObjectRequest )
44- .getObjectContent ()) {
50+ try (ResponseInputStream <GetObjectResponse > inputStream = s3client .getObject (getObjectRequest )) {
4551 return Utils .asByteBuffer (inputStream );
4652 } catch (IOException e ) {
4753 return null ;
@@ -50,48 +56,65 @@ ByteBuffer get(GetObjectRequest getObjectRequest) {
5056
5157 @ Override
5258 public boolean exists (String [] keys ) {
53- return s3client .doesObjectExist (bucketName , resolveKeys (keys ));
59+ HeadObjectRequest req = HeadObjectRequest .builder ().bucket (bucketName ).key (resolveKeys (keys )).build ();
60+ return s3client .headObject (req ).sdkHttpResponse ().statusCode () == 200 ;
5461 }
5562
5663 @ Nullable
5764 @ Override
5865 public ByteBuffer get (String [] keys ) {
59- return get (new GetObjectRequest (bucketName , resolveKeys (keys )));
66+ return get (GetObjectRequest .builder ().bucket (bucketName ).key (resolveKeys (keys ))
67+ .build ());
6068 }
6169
6270 @ Nullable
6371 @ Override
6472 public ByteBuffer get (String [] keys , long start ) {
65- return get (new GetObjectRequest (bucketName , resolveKeys (keys )).withRange (start ));
73+ GetObjectRequest req = GetObjectRequest .builder ()
74+ .bucket (bucketName )
75+ .key (resolveKeys (keys ))
76+ .range (String .valueOf (start ))
77+ .build ();
78+ return get (req );
6679 }
6780
6881 @ Nullable
6982 @ Override
7083 public ByteBuffer get (String [] keys , long start , long end ) {
71- return get (new GetObjectRequest (bucketName , resolveKeys (keys )).withRange (start , end ));
84+ GetObjectRequest req = GetObjectRequest .builder ()
85+ .bucket (bucketName )
86+ .key (resolveKeys (keys ))
87+ .range (String .valueOf (start )+"-" +String .valueOf (end ))
88+ .build ();
89+ return get (req );
7290 }
7391
7492 @ Override
7593 public void set (String [] keys , ByteBuffer bytes ) {
7694 try (InputStream byteStream = new ByteArrayInputStream (Utils .toArray (bytes ))) {
77- s3client .putObject (bucketName , resolveKeys (keys ), byteStream , new ObjectMetadata ());
95+ /*AWS SDK for Java v2 migration: When using InputStream to upload with S3Client, Content-Length should be specified and used with RequestBody.fromInputStream(). Otherwise, the entire stream will be buffered in memory. If content length must be unknown, we recommend using the CRT-based S3 client - https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/crt-based-s3-client.html*/
96+ s3client .putObject (PutObjectRequest .builder ().bucket (bucketName ).key (resolveKeys (keys )).build (), RequestBody .fromContentProvider (() -> byteStream , "application/octet-stream" ));
7897 } catch (IOException e ) {
7998 throw new RuntimeException (e );
8099 }
81100 }
82101
83102 @ Override
84103 public void delete (String [] keys ) {
85- s3client .deleteObject (bucketName , resolveKeys (keys ));
104+ s3client .deleteObject (DeleteObjectRequest .builder ().bucket (bucketName ).key (resolveKeys (keys ))
105+ .build ());
86106 }
87107
88108 @ Override
89109 public Stream <String > list (String [] keys ) {
90110 final String fullKey = resolveKeys (keys );
91- return s3client .listObjects (bucketName , fullKey )
92- .getObjectSummaries ()
111+ ListObjectsRequest req = ListObjectsRequest .builder ()
112+ .bucket (bucketName ).prefix (fullKey )
113+ .build ();
114+ ListObjectsResponse res = s3client .listObjects (req );
115+ return res .contents ()
93116 .stream ()
94- .map (p -> p .getKey ().substring (fullKey .length () + 1 ));
117+ .map (p -> p .key ().substring (fullKey .length () + 1 ));
95118 }
96119
97120 @ Nonnull
0 commit comments