Skip to content

Commit 1649722

Browse files
committed
Merged presignedUrlGenerator into blobService
1 parent 21c894b commit 1649722

File tree

10 files changed

+43
-334
lines changed

10 files changed

+43
-334
lines changed

src/KeeperData.Core.Reports/Abstract/ICleanseReportPresignedUrlGenerator.cs

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/KeeperData.Core.Reports/CleanseReportService.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using KeeperData.Core.Reports.Domain;
99
using KeeperData.Core.Reports.Dtos;
1010
using KeeperData.Core.Reports.Strategies;
11+
using KeeperData.Core.Storage;
1112
using Microsoft.Extensions.Logging;
1213

1314
namespace KeeperData.Core.Reports;
@@ -24,7 +25,7 @@ public class CleanseReportService(
2425
ICleanseAnalysisRepository analysisRepository,
2526
IDistributedLock distributedLock,
2627
ICleanseReportExportService exportService,
27-
ICleanseReportPresignedUrlGenerator presignedUrlGenerator,
28+
IBlobStorageServiceFactory blobStorageServiceFactory,
2829
ICleanseReportNotificationService notificationService,
2930
ILogger<CleanseReportService> logger,
3031
IEnumerable<ICleanseAnalysisStrategy> strategies) : ICleanseReportService
@@ -364,7 +365,8 @@ public async Task<RegenerateReportUrlResult> RegenerateReportUrlAsync(string ope
364365
};
365366
}
366367

367-
var newUrl = presignedUrlGenerator.GeneratePresignedUrl(operation.ReportObjectKey);
368+
var blobService = blobStorageServiceFactory.GetCleanseReportsBlobService();
369+
var newUrl = blobService.GeneratePresignedUrl(operation.ReportObjectKey);
368370

369371
await analysisRepository.UpdateReportUrlAsync(operationId, newUrl, ct);
370372

src/KeeperData.Core.Reports/Impl/CleanseReportExportService.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,15 @@ public class CleanseReportExportService : ICleanseReportExportService
2020

2121
private readonly ICleanseReportRepository _reportRepository;
2222
private readonly IBlobStorageServiceFactory _blobStorageServiceFactory;
23-
private readonly ICleanseReportPresignedUrlGenerator _presignedUrlGenerator;
2423
private readonly ILogger<CleanseReportExportService> _logger;
2524

2625
public CleanseReportExportService(
2726
ICleanseReportRepository reportRepository,
2827
IBlobStorageServiceFactory blobStorageServiceFactory,
29-
ICleanseReportPresignedUrlGenerator presignedUrlGenerator,
3028
ILogger<CleanseReportExportService> logger)
3129
{
3230
_reportRepository = reportRepository;
3331
_blobStorageServiceFactory = blobStorageServiceFactory;
34-
_presignedUrlGenerator = presignedUrlGenerator;
3532
_logger = logger;
3633
}
3734

@@ -66,8 +63,8 @@ public async Task<CleanseReportExportResult> ExportAndUploadAsync(string operati
6663
await blobService.UploadAsync(zipFileName, zipContent, "application/zip", cancellationToken: ct);
6764
_logger.LogInformation("Uploaded report to S3 with key {ObjectKey}", zipFileName);
6865

69-
// Step 4: Generate presigned URL (using the zip file name as the key - factory adds the prefix)
70-
var presignedUrl = _presignedUrlGenerator.GeneratePresignedUrl(zipFileName);
66+
// Step 4: Generate presigned URL (using the zip file name as the key - blob service handles the prefix)
67+
var presignedUrl = blobService.GeneratePresignedUrl(zipFileName);
7168
_logger.LogInformation(
7269
"Generated presigned URL for cleanse report (operation {OperationId}): {ReportUrl}",
7370
operationId, presignedUrl);

src/KeeperData.Core/Storage/IBlobStorageServiceReadOnly.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,12 @@ Task<bool> ExistsAsync(
5050
string objectKey,
5151
CancellationToken cancellationToken = default);
5252

53+
/// <summary>
54+
/// Generates a presigned URL for downloading an object.
55+
/// </summary>
56+
/// <param name="objectKey">The object key.</param>
57+
/// <param name="expiresIn">Optional expiry duration. Defaults to 7 days if not specified.</param>
58+
/// <returns>A presigned URL for downloading the object.</returns>
59+
string GeneratePresignedUrl(string objectKey, TimeSpan? expiresIn = null);
60+
5361
}

src/KeeperData.Infrastructure/Reports/S3CleanseReportPresignedUrlGenerator.cs

Lines changed: 0 additions & 58 deletions
This file was deleted.

src/KeeperData.Infrastructure/Setup/CleanseReportServiceCollectionExtensions.cs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@
44
using KeeperData.Core.Reports.Setup;
55
using KeeperData.Infrastructure.Notifications;
66
using KeeperData.Infrastructure.Notifications.Configuration;
7-
using KeeperData.Infrastructure.Reports;
8-
using KeeperData.Infrastructure.Storage.Clients;
9-
using KeeperData.Infrastructure.Storage.Configuration;
10-
using KeeperData.Infrastructure.Storage.Factories;
117
using Microsoft.Extensions.Configuration;
128
using Microsoft.Extensions.DependencyInjection;
139
using System.Diagnostics.CodeAnalysis;
@@ -29,19 +25,6 @@ public static void AddCleanseReportServices(this IServiceCollection services, IC
2925
// Add core dependencies
3026
services.AddCleanseReportDependencies();
3127

32-
// Add infrastructure dependencies (presigned URL generator)
33-
services.AddScoped<ICleanseReportPresignedUrlGenerator>(sp =>
34-
{
35-
var s3ClientFactory = sp.GetRequiredService<IS3ClientFactory>();
36-
var storageConfig = sp.GetRequiredService<StorageConfiguration>();
37-
38-
var clientInfo = s3ClientFactory.GetClientInfo<InternalStorageClient>();
39-
return new S3CleanseReportPresignedUrlGenerator(
40-
clientInfo.Client,
41-
clientInfo.BucketName,
42-
storageConfig.TargetInternalPrefix);
43-
});
44-
4528
// Add notification service and configuration
4629
services.Configure<CleanseReportNotificationConfig>(
4730
configuration.GetSection(CleanseReportNotificationConfig.SectionName));

src/KeeperData.Infrastructure/Storage/S3BlobStorageServiceReadOnly.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,25 @@ public void Dispose()
376376
}
377377
}
378378

379+
private static readonly TimeSpan DefaultPresignedUrlExpiry = TimeSpan.FromDays(7);
380+
381+
/// <inheritdoc />
382+
public string GeneratePresignedUrl(string objectKey, TimeSpan? expiresIn = null)
383+
{
384+
var fullKey = GetFullObjectKey(objectKey);
385+
var expiry = expiresIn ?? DefaultPresignedUrlExpiry;
386+
387+
var request = new GetPreSignedUrlRequest
388+
{
389+
BucketName = _bucketName,
390+
Key = fullKey,
391+
Verb = HttpVerb.GET,
392+
Expires = DateTime.UtcNow.Add(expiry)
393+
};
394+
395+
return _s3Client.GetPreSignedURL(request);
396+
}
397+
379398
/// <summary>
380399
/// Normalizes the top-level folder to ensure consistent format:
381400
/// - Removes leading and trailing slashes

tests/KeeperData.Bridge.Tests.Integration/Cleanse/CleanseReportEndToEndTests.cs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
using KeeperData.Core.Storage;
1919
using KeeperData.Infrastructure.Database.Configuration;
2020
using KeeperData.Infrastructure.Locking;
21-
using KeeperData.Infrastructure.Reports;
2221
using KeeperData.Infrastructure.Storage;
2322
using MartinCostello.Logging.XUnit;
2423
using Microsoft.Extensions.Logging;
@@ -192,17 +191,10 @@ private Task SetupServices()
192191
// Create a factory that returns our real S3 service
193192
var blobStorageServiceFactory = new TestBlobStorageServiceFactory(blobStorageService);
194193

195-
// Create real presigned URL generator pointing to LocalStack
196-
var presignedUrlGenerator = new S3CleanseReportPresignedUrlGenerator(
197-
_s3Client,
198-
TestBucket,
199-
CleanseReportsFolder);
200-
201194
// Create real export service using real S3
202195
var exportService = new CleanseReportExportService(
203196
_reportRepository,
204197
blobStorageServiceFactory,
205-
presignedUrlGenerator,
206198
loggerFactory.CreateLogger<CleanseReportExportService>());
207199

208200
// Create fake notification service to capture calls
@@ -215,7 +207,7 @@ private Task SetupServices()
215207
_analysisRepository,
216208
distributedLock,
217209
exportService,
218-
presignedUrlGenerator,
210+
blobStorageServiceFactory,
219211
_fakeNotificationService,
220212
loggerFactory.CreateLogger<CleanseReportService>(),
221213
new ICleanseAnalysisStrategy[] { new CtsSamAnalysisStrategy() });

tests/KeeperData.Bridge.Tests.Integration/Cleanse/CleanseReportServiceTests.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using KeeperData.Core.Reports.Domain;
1212
using KeeperData.Core.Reports.Impl;
1313
using KeeperData.Core.Reports.Strategies;
14+
using KeeperData.Core.Storage;
1415
using KeeperData.Infrastructure.Database.Configuration;
1516
using KeeperData.Infrastructure.Locking;
1617
using Microsoft.Extensions.Logging;
@@ -101,11 +102,16 @@ private void InitializeServices()
101102
.Setup(x => x.ExportAndUploadAsync(It.IsAny<string>(), It.IsAny<CancellationToken>()))
102103
.ReturnsAsync(new CleanseReportExportResult { Success = true, ReportUrl = "https://example.com/report.zip", ObjectKey = "cleanse-reports/test.zip" });
103104

104-
var presignedUrlGeneratorMock = new Mock<ICleanseReportPresignedUrlGenerator>();
105-
presignedUrlGeneratorMock
105+
var blobStorageServiceMock = new Mock<IBlobStorageService>();
106+
blobStorageServiceMock
106107
.Setup(x => x.GeneratePresignedUrl(It.IsAny<string>(), It.IsAny<TimeSpan?>()))
107108
.Returns("https://example.com/regenerated-report.zip");
108109

110+
var blobStorageServiceFactoryMock = new Mock<IBlobStorageServiceFactory>();
111+
blobStorageServiceFactoryMock
112+
.Setup(x => x.GetCleanseReportsBlobService())
113+
.Returns(blobStorageServiceMock.Object);
114+
109115
var notificationServiceMock = new Mock<ICleanseReportNotificationService>();
110116
notificationServiceMock
111117
.Setup(x => x.SendReportNotificationAsync(It.IsAny<string>(), It.IsAny<CancellationToken>()))
@@ -120,7 +126,7 @@ private void InitializeServices()
120126
_analysisRepository,
121127
_distributedLock,
122128
exportServiceMock.Object,
123-
presignedUrlGeneratorMock.Object,
129+
blobStorageServiceFactoryMock.Object,
124130
notificationServiceMock.Object,
125131
loggerMock.Object,
126132
strategies);

0 commit comments

Comments
 (0)