11package com .microsoft .migration .assets .service ;
22
3+ import com .azure .identity .DefaultAzureCredentialBuilder ;
4+ import com .azure .storage .blob .BlobServiceClient ;
5+ import com .azure .storage .blob .BlobServiceClientBuilder ;
6+ import com .azure .storage .blob .models .BlobHttpHeaders ;
7+ import com .azure .storage .blob .models .BlobItem ;
8+ import com .azure .storage .blob .options .BlobParallelUploadOptions ;
39import com .microsoft .migration .assets .model .ImageMetadata ;
410import com .microsoft .migration .assets .model .ImageProcessingMessage ;
511import com .microsoft .migration .assets .model .S3StorageItem ;
1016import org .springframework .context .annotation .Profile ;
1117import org .springframework .stereotype .Service ;
1218import org .springframework .web .multipart .MultipartFile ;
13- import software .amazon .awssdk .core .sync .RequestBody ;
14- import software .amazon .awssdk .services .s3 .S3Client ;
15- import software .amazon .awssdk .services .s3 .model .*;
1619
1720import java .io .IOException ;
1821import java .io .InputStream ;
2831@ Profile ("!dev" ) // Active when not in dev profile
2932public class AwsS3Service implements StorageService {
3033
31- private final S3Client s3Client ;
34+ private final BlobServiceClient blobServiceClient ;
3235 private final RabbitTemplate rabbitTemplate ;
3336 private final ImageMetadataRepository imageMetadataRepository ;
3437
35- @ Value ("${aws.s3.bucket }" )
36- private String bucketName ;
38+ @ Value ("${azure.storage.blob.container-name }" )
39+ private String containerName ;
3740
3841 @ Override
3942 public List <S3StorageItem > listObjects () {
40- ListObjectsV2Request request = ListObjectsV2Request .builder ()
41- .bucket (bucketName )
42- .build ();
43-
44- ListObjectsV2Response response = s3Client .listObjectsV2 (request );
45-
46- return response .contents ().stream ()
47- .map (s3Object -> {
43+ return blobServiceClient .getBlobContainerClient (containerName ).listBlobs ().stream ()
44+ .map (blobItem -> {
4845 // Try to get metadata for upload time
4946 Instant uploadedAt = imageMetadataRepository .findAll ().stream ()
50- .filter (metadata -> metadata .getS3Key ().equals (s3Object . key ()))
47+ .filter (metadata -> metadata .getS3Key ().equals (blobItem . getName ()))
5148 .map (metadata -> metadata .getUploadedAt ().atZone (java .time .ZoneId .systemDefault ()).toInstant ())
5249 .findFirst ()
53- .orElse (s3Object . lastModified ()); // fallback to lastModified if metadata not found
50+ .orElse (blobItem . getProperties (). getLastModified (). toInstant ()); // fallback to lastModified if metadata not found
5451
5552 return new S3StorageItem (
56- s3Object . key (),
57- extractFilename (s3Object . key ()),
58- s3Object . size (),
59- s3Object . lastModified (),
53+ blobItem . getName (),
54+ extractFilename (blobItem . getName ()),
55+ blobItem . getProperties (). getContentLength (),
56+ blobItem . getProperties (). getLastModified (). toInstant (),
6057 uploadedAt ,
61- generateUrl (s3Object . key ())
58+ generateUrl (blobItem . getName ())
6259 );
6360 })
6461 .collect (Collectors .toList ());
@@ -67,14 +64,11 @@ public List<S3StorageItem> listObjects() {
6764 @ Override
6865 public void uploadObject (MultipartFile file ) throws IOException {
6966 String key = generateKey (file .getOriginalFilename ());
70-
71- PutObjectRequest request = PutObjectRequest .builder ()
72- .bucket (bucketName )
73- .key (key )
74- .contentType (file .getContentType ())
75- .build ();
76-
77- s3Client .putObject (request , RequestBody .fromInputStream (file .getInputStream (), file .getSize ()));
67+
68+ var blobClient = blobServiceClient .getBlobContainerClient (containerName ).getBlobClient (key );
69+ BlobHttpHeaders headers = new BlobHttpHeaders ().setContentType (file .getContentType ());
70+ BlobParallelUploadOptions options = new BlobParallelUploadOptions (file .getInputStream ()).setHeaders (headers );
71+ blobClient .uploadWithResponse (options , null , null );
7872
7973 // Send message to queue for thumbnail generation
8074 ImageProcessingMessage message = new ImageProcessingMessage (
@@ -99,31 +93,23 @@ public void uploadObject(MultipartFile file) throws IOException {
9993
10094 @ Override
10195 public InputStream getObject (String key ) throws IOException {
102- GetObjectRequest request = GetObjectRequest .builder ()
103- .bucket (bucketName )
104- .key (key )
105- .build ();
106-
107- return s3Client .getObject (request );
96+ return blobServiceClient .getBlobContainerClient (containerName )
97+ .getBlobClient (key )
98+ .openInputStream ();
10899 }
109100
110101 @ Override
111102 public void deleteObject (String key ) throws IOException {
112103 // Delete both original and thumbnail if it exists
113- DeleteObjectRequest request = DeleteObjectRequest .builder ()
114- .bucket (bucketName )
115- .key (key )
116- .build ();
117-
118- s3Client .deleteObject (request );
104+ blobServiceClient .getBlobContainerClient (containerName )
105+ .getBlobClient (key )
106+ .delete ();
119107
120108 try {
121109 // Try to delete thumbnail if it exists
122- DeleteObjectRequest thumbnailRequest = DeleteObjectRequest .builder ()
123- .bucket (bucketName )
124- .key (getThumbnailKey (key ))
125- .build ();
126- s3Client .deleteObject (thumbnailRequest );
110+ blobServiceClient .getBlobContainerClient (containerName )
111+ .getBlobClient (getThumbnailKey (key ))
112+ .delete ();
127113 } catch (Exception e ) {
128114 // Ignore if thumbnail doesn't exist
129115 }
@@ -137,21 +123,19 @@ public void deleteObject(String key) throws IOException {
137123
138124 @ Override
139125 public String getStorageType () {
140- return "s3 " ;
126+ return "azure " ;
141127 }
142128
143129 private String extractFilename (String key ) {
144130 // Extract filename from the object key
145131 int lastSlashIndex = key .lastIndexOf ('/' );
146132 return lastSlashIndex >= 0 ? key .substring (lastSlashIndex + 1 ) : key ;
147133 }
148-
134+
149135 private String generateUrl (String key ) {
150- GetUrlRequest request = GetUrlRequest .builder ()
151- .bucket (bucketName )
152- .key (key )
153- .build ();
154- return s3Client .utilities ().getUrl (request ).toString ();
136+ return blobServiceClient .getBlobContainerClient (containerName )
137+ .getBlobClient (key )
138+ .getBlobUrl ();
155139 }
156140
157141 private String generateKey (String filename ) {
0 commit comments