feat(files): stamp entities with storage policy

This commit is contained in:
yoyuzh
2026-04-08 21:44:38 +08:00
parent 00b268c30f
commit 3e67760712
6 changed files with 54 additions and 4 deletions

View File

@@ -18,6 +18,7 @@ public class FileEntityBackfillService implements CommandLineRunner {
private final StoredFileRepository storedFileRepository;
private final FileEntityRepository fileEntityRepository;
private final StoredFileEntityRepository storedFileEntityRepository;
private final StoragePolicyService storagePolicyService;
@Override
@Transactional
@@ -51,6 +52,7 @@ public class FileEntityBackfillService implements CommandLineRunner {
fileEntity.setEntityType(FileEntityType.VERSION);
fileEntity.setReferenceCount(1);
fileEntity.setCreatedBy(storedFile.getUser());
fileEntity.setStoragePolicyId(storagePolicyService.ensureDefaultPolicy().getId());
return fileEntityRepository.save(fileEntity);
}

View File

@@ -56,6 +56,7 @@ public class FileService {
private final FileContentStorage fileContentStorage;
private final FileShareLinkRepository fileShareLinkRepository;
private final AdminMetricsService adminMetricsService;
private final StoragePolicyService storagePolicyService;
private final long maxFileSize;
private final String packageDownloadBaseUrl;
private final String packageDownloadSecret;
@@ -70,8 +71,9 @@ public class FileService {
FileContentStorage fileContentStorage,
FileShareLinkRepository fileShareLinkRepository,
AdminMetricsService adminMetricsService,
StoragePolicyService storagePolicyService,
FileStorageProperties properties) {
this(storedFileRepository, fileBlobRepository, fileEntityRepository, storedFileEntityRepository, fileContentStorage, fileShareLinkRepository, adminMetricsService, properties, Clock.systemUTC());
this(storedFileRepository, fileBlobRepository, fileEntityRepository, storedFileEntityRepository, fileContentStorage, fileShareLinkRepository, adminMetricsService, storagePolicyService, properties, Clock.systemUTC());
}
FileService(StoredFileRepository storedFileRepository,
@@ -81,6 +83,7 @@ public class FileService {
FileContentStorage fileContentStorage,
FileShareLinkRepository fileShareLinkRepository,
AdminMetricsService adminMetricsService,
StoragePolicyService storagePolicyService,
FileStorageProperties properties,
Clock clock) {
this.storedFileRepository = storedFileRepository;
@@ -90,6 +93,7 @@ public class FileService {
this.fileContentStorage = fileContentStorage;
this.fileShareLinkRepository = fileShareLinkRepository;
this.adminMetricsService = adminMetricsService;
this.storagePolicyService = storagePolicyService;
this.maxFileSize = properties.getMaxFileSize();
this.packageDownloadBaseUrl = StringUtils.hasText(properties.getS3().getPackageDownloadBaseUrl())
? properties.getS3().getPackageDownloadBaseUrl().trim()
@@ -107,7 +111,7 @@ public class FileService {
FileShareLinkRepository fileShareLinkRepository,
AdminMetricsService adminMetricsService,
FileStorageProperties properties) {
this(storedFileRepository, fileBlobRepository, null, null, fileContentStorage, fileShareLinkRepository, adminMetricsService, properties, Clock.systemUTC());
this(storedFileRepository, fileBlobRepository, null, null, fileContentStorage, fileShareLinkRepository, adminMetricsService, null, properties, Clock.systemUTC());
}
FileService(StoredFileRepository storedFileRepository,
@@ -117,7 +121,7 @@ public class FileService {
AdminMetricsService adminMetricsService,
FileStorageProperties properties,
Clock clock) {
this(storedFileRepository, fileBlobRepository, null, null, fileContentStorage, fileShareLinkRepository, adminMetricsService, properties, clock);
this(storedFileRepository, fileBlobRepository, null, null, fileContentStorage, fileShareLinkRepository, adminMetricsService, null, properties, clock);
}
@Transactional
@@ -745,9 +749,17 @@ public class FileService {
entity.setEntityType(FileEntityType.VERSION);
entity.setReferenceCount(1);
entity.setCreatedBy(user);
entity.setStoragePolicyId(resolveDefaultStoragePolicyId());
return entity;
}
private Long resolveDefaultStoragePolicyId() {
if (storagePolicyService == null) {
return null;
}
return storagePolicyService.ensureDefaultPolicy().getId();
}
private void savePrimaryEntityRelation(StoredFile storedFile, FileEntity primaryEntity) {
if (storedFileEntityRepository == null) {
return;

View File

@@ -26,6 +26,8 @@ class FileEntityBackfillServiceTest {
private FileEntityRepository fileEntityRepository;
@Mock
private StoredFileEntityRepository storedFileEntityRepository;
@Mock
private StoragePolicyService storagePolicyService;
private FileEntityBackfillService backfillService;
@@ -34,7 +36,8 @@ class FileEntityBackfillServiceTest {
backfillService = new FileEntityBackfillService(
storedFileRepository,
fileEntityRepository,
storedFileEntityRepository
storedFileEntityRepository,
storagePolicyService
);
}
@@ -50,6 +53,7 @@ class FileEntityBackfillServiceTest {
entity.setId(100L);
return entity;
});
when(storagePolicyService.ensureDefaultPolicy()).thenReturn(createDefaultStoragePolicy());
backfillService.backfillPrimaryEntities();
@@ -57,6 +61,7 @@ class FileEntityBackfillServiceTest {
assertThat(storedFile.getPrimaryEntity().getObjectKey()).isEqualTo("blobs/blob-20");
assertThat(storedFile.getPrimaryEntity().getEntityType()).isEqualTo(FileEntityType.VERSION);
assertThat(storedFile.getPrimaryEntity().getReferenceCount()).isEqualTo(1);
assertThat(storedFile.getPrimaryEntity().getStoragePolicyId()).isEqualTo(42L);
verify(fileEntityRepository).save(any(FileEntity.class));
verify(storedFileRepository).save(storedFile);
verify(storedFileEntityRepository).save(any(StoredFileEntity.class));
@@ -111,4 +116,16 @@ class FileEntityBackfillServiceTest {
blob.setCreatedAt(LocalDateTime.now());
return blob;
}
private StoragePolicy createDefaultStoragePolicy() {
StoragePolicy policy = new StoragePolicy();
policy.setId(42L);
policy.setName("Default Local Storage");
policy.setType(StoragePolicyType.LOCAL);
policy.setCredentialMode(StoragePolicyCredentialMode.NONE);
policy.setMaxSizeBytes(500L * 1024 * 1024);
policy.setEnabled(true);
policy.setDefaultPolicy(true);
return policy;
}
}

View File

@@ -63,6 +63,8 @@ class FileServiceTest {
private FileShareLinkRepository fileShareLinkRepository;
@Mock
private AdminMetricsService adminMetricsService;
@Mock
private StoragePolicyService storagePolicyService;
private FileService fileService;
@@ -150,6 +152,7 @@ class FileServiceTest {
fileContentStorage,
fileShareLinkRepository,
adminMetricsService,
storagePolicyService,
new FileStorageProperties()
);
User user = createUser(7L);
@@ -168,6 +171,7 @@ class FileServiceTest {
entity.setId(200L);
return entity;
});
when(storagePolicyService.ensureDefaultPolicy()).thenReturn(createDefaultStoragePolicy());
when(storedFileRepository.save(any(StoredFile.class))).thenAnswer(invocation -> {
StoredFile file = invocation.getArgument(0);
file.setId(10L);
@@ -181,6 +185,7 @@ class FileServiceTest {
assertThat(entityCaptor.getValue().getObjectKey()).startsWith("blobs/");
assertThat(entityCaptor.getValue().getEntityType()).isEqualTo(FileEntityType.VERSION);
assertThat(entityCaptor.getValue().getCreatedBy()).isSameAs(user);
assertThat(entityCaptor.getValue().getStoragePolicyId()).isEqualTo(42L);
var relationCaptor = forClass(StoredFileEntity.class);
verify(storedFileEntityRepository).save(relationCaptor.capture());
@@ -828,4 +833,16 @@ class FileServiceTest {
directory.setBlob(null);
return directory;
}
private StoragePolicy createDefaultStoragePolicy() {
StoragePolicy policy = new StoragePolicy();
policy.setId(42L);
policy.setName("Default Local Storage");
policy.setType(StoragePolicyType.LOCAL);
policy.setCredentialMode(StoragePolicyCredentialMode.NONE);
policy.setMaxSizeBytes(500L * 1024 * 1024);
policy.setEnabled(true);
policy.setDefaultPolicy(true);
return policy;
}
}