Skip to content
This repository was archived by the owner on Apr 5, 2024. It is now read-only.

Commit 53fb6a4

Browse files
authored
FF-402 - IdGenerationService (#105)
* Added IdGenerationService instead of FileSystemHelperService * Fixed IdGenerationService and added UnitTests * Remove exception throw and warn instead.
1 parent cdccd96 commit 53fb6a4

File tree

6 files changed

+145
-19
lines changed

6 files changed

+145
-19
lines changed

src/main/java/de/filefighter/rest/configuration/PrepareDataBase.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package de.filefighter.rest.configuration;
22

33
import de.filefighter.rest.domain.common.exceptions.FileFighterDataException;
4+
import de.filefighter.rest.domain.filesystem.business.IdGenerationService;
45
import de.filefighter.rest.domain.filesystem.data.persistence.FileSystemEntity;
56
import de.filefighter.rest.domain.filesystem.data.persistence.FileSystemRepository;
67
import de.filefighter.rest.domain.token.business.AccessTokenBusinessService;
@@ -95,7 +96,6 @@ CommandLineRunner initDataBaseProd(UserRepository userRepository, FileSystemRepo
9596
.name("HOME_1")
9697
.size(420)
9798
.typeId(FOLDER.getId())
98-
.visibleForGroupIds(new long[]{UNDEFINED.getGroupId(), FAMILY.getGroupId(), ADMIN.getGroupId()})
9999
.itemIds(new long[]{1})
100100
.build()),
101101
fileSystemRepository.save(FileSystemEntity.builder()
@@ -108,8 +108,6 @@ CommandLineRunner initDataBaseProd(UserRepository userRepository, FileSystemRepo
108108
.size(420)
109109
.typeId(TEXT.getId())
110110
.mimeType("text/plain")
111-
.editableFoGroupIds(new long[]{FAMILY.getGroupId()})
112-
.visibleForGroupIds(new long[]{FAMILY.getGroupId()})
113111
.build()));
114112

115113
if (userRepository.findAll().size() == 2) {
@@ -180,6 +178,11 @@ CommandLineRunner initDataBaseDev(UserRepository userRepository, AccessTokenRepo
180178
};
181179
}
182180

181+
@Bean
182+
CommandLineRunner finishDatabaseWork(IdGenerationService idGenerationService) {
183+
return args -> idGenerationService.initializeService();
184+
}
185+
183186
private void addDevUsers(UserRepository userRepository) {
184187
log.info("Inserting system runtime user. {}", userRepository.save(UserEntity
185188
.builder()

src/main/java/de/filefighter/rest/domain/filesystem/business/FileSystemHelperService.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,14 @@ public class FileSystemHelperService {
3434
private final FileSystemTypeRepository fileSystemTypeRepository;
3535
private final UserBusinessService userBusinessService;
3636
private final MongoTemplate mongoTemplate;
37+
private final IdGenerationService idGenerationService;
3738

38-
public FileSystemHelperService(FileSystemRepository fileSystemRepository, FileSystemTypeRepository fileSystemTypeRepository, UserBusinessService userBusinessService, MongoTemplate mongoTemplate) {
39+
public FileSystemHelperService(FileSystemRepository fileSystemRepository, FileSystemTypeRepository fileSystemTypeRepository, UserBusinessService userBusinessService, MongoTemplate mongoTemplate, IdGenerationService idGenerationService) {
3940
this.fileSystemRepository = fileSystemRepository;
4041
this.fileSystemTypeRepository = fileSystemTypeRepository;
4142
this.userBusinessService = userBusinessService;
4243
this.mongoTemplate = mongoTemplate;
44+
this.idGenerationService = idGenerationService;
4345
}
4446

4547
public FileSystemEntity sumUpAllPermissionsOfFileSystemEntities(FileSystemEntity parentFileSystemEntity, List<FileSystemEntity> fileSystemEntities) {
@@ -224,7 +226,7 @@ public FileSystemItem createDTO(FileSystemEntity fileSystemEntity, User authenti
224226
public void createBasicFilesForNewUser(UserEntity registeredUserEntity) {
225227
fileSystemRepository.save(FileSystemEntity
226228
.builder()
227-
.fileSystemId(generateNextFileSystemId())
229+
.fileSystemId(idGenerationService.consumeNext())
228230
.ownerId(registeredUserEntity.getUserId())
229231
.lastUpdatedBy(RestConfiguration.RUNTIME_USER_ID)
230232
.lastUpdated(getCurrentTimeStamp())
@@ -365,11 +367,6 @@ public long getFileSystemEntityCount() {
365367
return fileSystemRepository.count();
366368
}
367369

368-
// This will update the field. -> Everytime this function gets called a id gets taken. Which means some ids could be lost, when calling this function and not creating something.
369-
public long generateNextFileSystemId() {
370-
return getFileSystemEntityCount() + 1;
371-
}
372-
373370
public long getCurrentTimeStamp() {
374371
return Instant.now().getEpochSecond();
375372
}

src/main/java/de/filefighter/rest/domain/filesystem/business/FileSystemUploadService.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,16 @@ public class FileSystemUploadService {
3737
private final FileSystemTypeRepository fileSystemTypeRepository;
3838
private final MongoTemplate mongoTemplate;
3939
private final UserBusinessService userBusinessService;
40+
private final IdGenerationService idGenerationService;
4041

41-
public FileSystemUploadService(FileSystemRepository fileSystemRepository, FileSystemHelperService fileSystemHelperService, InputSanitizerService inputSanitizerService, FileSystemTypeRepository fileSystemTypeRepository, MongoTemplate mongoTemplate, UserBusinessService userBusinessService) {
42+
public FileSystemUploadService(FileSystemRepository fileSystemRepository, FileSystemHelperService fileSystemHelperService, InputSanitizerService inputSanitizerService, FileSystemTypeRepository fileSystemTypeRepository, MongoTemplate mongoTemplate, UserBusinessService userBusinessService, IdGenerationService idGenerationService) {
4243
this.fileSystemRepository = fileSystemRepository;
4344
this.fileSystemHelperService = fileSystemHelperService;
4445
this.inputSanitizerService = inputSanitizerService;
4546
this.fileSystemTypeRepository = fileSystemTypeRepository;
4647
this.mongoTemplate = mongoTemplate;
4748
this.userBusinessService = userBusinessService;
49+
this.idGenerationService = idGenerationService;
4850
}
4951

5052
public List<FileSystemItem> uploadFileSystemItem(long rootItemId, FileSystemUpload fileSystemUpload, User authenticatedUser) {
@@ -77,7 +79,6 @@ public List<FileSystemItem> uploadFileSystemItem(long rootItemId, FileSystemUplo
7779

7880
FileSystemEntity latestEntity = uploadParent;
7981
long timeStamp = fileSystemHelperService.getCurrentTimeStamp();
80-
long latestFileSystemId = fileSystemHelperService.generateNextFileSystemId();
8182

8283
for (int i = 0; i < paths.length - 1; i++) {
8384
String currentAbsolutePath = paths[i];
@@ -102,7 +103,7 @@ public List<FileSystemItem> uploadFileSystemItem(long rootItemId, FileSystemUplo
102103

103104
// create empty folder
104105
FileSystemEntity newFolder = FileSystemEntity.builder()
105-
.fileSystemId(latestFileSystemId)
106+
.fileSystemId(idGenerationService.consumeNext())
106107
.isFile(false)
107108
.visibleForUserIds(latestEntity.getVisibleForUserIds())
108109
.visibleForGroupIds(latestEntity.getVisibleForGroupIds())
@@ -116,14 +117,12 @@ public List<FileSystemItem> uploadFileSystemItem(long rootItemId, FileSystemUplo
116117
.lastUpdated(fileSystemHelperService.getCurrentTimeStamp())
117118
.build();
118119

119-
// update id
120-
latestFileSystemId++;
121-
122120
// add latestEntityTo list and add current id to itemids array.
123121
latestEntity.setItemIds(fileSystemHelperService.addLongToLongArray(latestEntity.getItemIds(), newFolder.getFileSystemId()));
124122
entitiesToUpdate.add(latestEntity);
125123

126124
// set new folder entity as latest folder entity
125+
log.debug("Creating new Folder {}", newFolder);
127126
latestEntity = newFolder;
128127
entitiesToCreate.add(newFolder);
129128
returnItems.add(fileSystemHelperService.createDTO(newFolder, authenticatedUser, "/" + ownerOfParent.getUsername() + currentAbsolutePath));
@@ -134,6 +133,7 @@ public List<FileSystemItem> uploadFileSystemItem(long rootItemId, FileSystemUplo
134133
throw new FileSystemItemCouldNotBeUploadedException();
135134

136135
// if yes add alreadyExistingFolder to latest Folder entity
136+
log.debug("Merging existing Folder {}", alreadyExistingFolder);
137137
entitiesToUpdate.add(latestEntity);
138138
returnItems.add(fileSystemHelperService.createDTO(alreadyExistingFolder, authenticatedUser, "/" + ownerOfParent.getUsername() + currentAbsolutePath));
139139
latestEntity = alreadyExistingFolder;
@@ -159,11 +159,12 @@ public List<FileSystemItem> uploadFileSystemItem(long rootItemId, FileSystemUplo
159159
throw new FileSystemItemCouldNotBeUploadedException("A Folder with the same name '" + fileSystemUpload.getName() + "' already exists.");
160160
}
161161
FileSystemEntity fileToOverwrite = alreadyExistingFilesWithSameName.get(0);
162+
log.debug("Found file to overwrite. Deleting it now. {}", fileToOverwrite);
162163
fileSystemHelperService.deleteAndUnbindFileSystemEntity(fileToOverwrite);
163164
}
164165

165166
FileSystemEntity newFile = FileSystemEntity.builder()
166-
.fileSystemId(latestFileSystemId)
167+
.fileSystemId(idGenerationService.consumeNext())
167168
.isFile(true)
168169
.visibleForUserIds(latestEntity.getVisibleForUserIds())
169170
.visibleForGroupIds(latestEntity.getVisibleForGroupIds())
@@ -184,6 +185,7 @@ public List<FileSystemItem> uploadFileSystemItem(long rootItemId, FileSystemUplo
184185
if (!alreadyExistingFilesWithSameName.isEmpty()) {
185186
newIds = Arrays.stream(latestEntity.getItemIds()).filter(id -> id != alreadyExistingFilesWithSameName.get(0).getFileSystemId()).toArray();
186187
}
188+
log.debug("Creating new File {}", newFile);
187189
latestEntity.setItemIds(fileSystemHelperService.addLongToLongArray(newIds, newFile.getFileSystemId()));
188190
entitiesToUpdate.add(latestEntity);
189191
entitiesToCreate.add(newFile);
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package de.filefighter.rest.domain.filesystem.business;
2+
3+
import de.filefighter.rest.domain.filesystem.data.persistence.FileSystemEntity;
4+
import de.filefighter.rest.domain.filesystem.data.persistence.FileSystemRepository;
5+
import lombok.extern.log4j.Log4j2;
6+
import org.springframework.stereotype.Service;
7+
8+
import java.util.List;
9+
import java.util.Optional;
10+
11+
@Log4j2
12+
@Service
13+
public class IdGenerationService {
14+
15+
private final FileSystemRepository fileSystemRepository;
16+
private long counter;
17+
18+
public IdGenerationService(FileSystemRepository fileSystemRepository) {
19+
this.fileSystemRepository = fileSystemRepository;
20+
}
21+
22+
@SuppressWarnings("java:S3655")
23+
public void initializeService() {
24+
// we could optimize the fileSystemIds by looking at the free ids between 0 and the max id.
25+
List<FileSystemEntity> entityList = fileSystemRepository.findAll();
26+
Optional<Long> max = entityList
27+
.stream()
28+
.map(FileSystemEntity::getFileSystemId)
29+
.max(Long::compare);
30+
31+
if (entityList.isEmpty() && max.isEmpty()) {
32+
log.warn("Database was empty. If this happens during production please contact the developers!");
33+
counter = -1;
34+
} else {
35+
counter = max.get();
36+
}
37+
38+
log.debug("Found {} entities in the db.", entityList.size());
39+
log.debug("IdGeneration start set to {}.", counter);
40+
}
41+
42+
public long peekNext() {
43+
return counter + 1;
44+
}
45+
46+
public long consumeNext() {
47+
counter++;
48+
return counter;
49+
}
50+
}

src/test/java/de/filefighter/rest/domain/filesystem/business/FileSystemHelperServiceUnitTest.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,14 @@ class FileSystemHelperServiceUnitTest {
3535
private final FileSystemRepository fileSystemRepositoryMock = mock(FileSystemRepository.class);
3636
private final FileSystemTypeRepository fileSystemTypeRepositoryMock = mock(FileSystemTypeRepository.class);
3737
private final MongoTemplate mongoTemplateMock = mock(MongoTemplate.class);
38-
39-
private final FileSystemHelperService fileSystemHelperService = new FileSystemHelperService(fileSystemRepositoryMock, fileSystemTypeRepositoryMock, userBusinessServiceMock, mongoTemplateMock);
38+
private final IdGenerationService idGenerationServiceMock = mock(IdGenerationService.class);
39+
40+
private final FileSystemHelperService fileSystemHelperService = new FileSystemHelperService(
41+
fileSystemRepositoryMock,
42+
fileSystemTypeRepositoryMock,
43+
userBusinessServiceMock,
44+
mongoTemplateMock,
45+
idGenerationServiceMock);
4046

4147
@Test
4248
void sumUpAllPermissionsOfFileSystemEntitiesWorks() {
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package de.filefighter.rest.domain.filesystem.business;
2+
3+
import de.filefighter.rest.domain.filesystem.data.persistence.FileSystemEntity;
4+
import de.filefighter.rest.domain.filesystem.data.persistence.FileSystemRepository;
5+
import org.junit.jupiter.api.Test;
6+
7+
import java.util.Arrays;
8+
import java.util.Collections;
9+
import java.util.List;
10+
11+
import static org.junit.jupiter.api.Assertions.assertEquals;
12+
import static org.mockito.Mockito.mock;
13+
import static org.mockito.Mockito.when;
14+
15+
class IdGenerationServiceUnitTest {
16+
17+
private final FileSystemRepository fileSystemRepositoryMock = mock(FileSystemRepository.class);
18+
private final IdGenerationService idGenerationService = new IdGenerationService(fileSystemRepositoryMock);
19+
20+
private final List<FileSystemEntity> mockData = Arrays.asList(
21+
FileSystemEntity.builder().fileSystemId(1).build(),
22+
FileSystemEntity.builder().fileSystemId(10).build(),
23+
FileSystemEntity.builder().fileSystemId(11).build(),
24+
FileSystemEntity.builder().fileSystemId(100).build()
25+
);
26+
27+
@Test
28+
void initializeServiceWorks() {
29+
when(fileSystemRepositoryMock.findAll()).thenReturn(mockData);
30+
31+
idGenerationService.initializeService();
32+
long nextId = idGenerationService.peekNext();
33+
34+
assertEquals(101, nextId);
35+
}
36+
37+
@Test
38+
void initializeServiceWorksWhenDatabaseIsEmpty() {
39+
when(fileSystemRepositoryMock.findAll()).thenReturn(Collections.emptyList());
40+
41+
idGenerationService.initializeService();
42+
long nextId = idGenerationService.peekNext();
43+
44+
assertEquals(0, nextId);
45+
}
46+
47+
@Test
48+
void peekNextWorks() {
49+
when(fileSystemRepositoryMock.findAll()).thenReturn(mockData);
50+
idGenerationService.initializeService();
51+
52+
for (int i = 0; i < 100; i++) {
53+
long nextId = idGenerationService.peekNext();
54+
assertEquals(101, nextId);
55+
}
56+
}
57+
58+
@Test
59+
void consumeNextWorks() {
60+
when(fileSystemRepositoryMock.findAll()).thenReturn(mockData);
61+
idGenerationService.initializeService();
62+
63+
for (int i = 0; i < 100; i++) {
64+
long nextId = idGenerationService.consumeNext();
65+
assertEquals(101 + i, nextId);
66+
}
67+
}
68+
}

0 commit comments

Comments
 (0)