import org.sonar.db.component.KeyWithUuidDto;
public class ComponentUuidFactoryWithMigration implements ComponentUuidFactory {
- private final Map<String, String> uuidsByKey = new HashMap<>();
+ private final Map<String, String> uuidsByDbKey = new HashMap<>();
+ private final Map<String, String> uuidsByMigratedKey = new HashMap<>();
public ComponentUuidFactoryWithMigration(DbClient dbClient, DbSession dbSession, String rootKey, Function<String, String> pathToKey, Map<String, String> reportModulesPath) {
Map<String, String> modulePathsByUuid;
+ List<KeyWithUuidDto> keys = dbClient.componentDao().selectUuidsByKeyFromProjectKey(dbSession, rootKey);
+ keys.forEach(dto -> uuidsByDbKey.put(dto.key(), dto.uuid()));
- if (reportModulesPath.isEmpty()) {
- noMigration(dbClient, dbSession, rootKey);
- } else {
+ if (!reportModulesPath.isEmpty()) {
modulePathsByUuid = loadModulePathsByUuid(dbClient, dbSession, rootKey, reportModulesPath);
- if (modulePathsByUuid.isEmpty()) {
- noMigration(dbClient, dbSession, rootKey);
- } else {
+ if (!modulePathsByUuid.isEmpty()) {
doMigration(dbClient, dbSession, rootKey, pathToKey, modulePathsByUuid);
}
}
}
- private void noMigration(DbClient dbClient, DbSession dbSession, String rootKey) {
- List<KeyWithUuidDto> keys = dbClient.componentDao().selectUuidsByKeyFromProjectKey(dbSession, rootKey);
- keys.forEach(dto -> uuidsByKey.put(dto.key(), dto.uuid()));
- }
-
private void doMigration(DbClient dbClient, DbSession dbSession, String rootKey, Function<String, String> pathToKey, Map<String, String> modulePathsByUuid) {
List<ComponentWithModuleUuidDto> dtos = loadComponentsWithModuleUuid(dbClient, dbSession, rootKey);
for (ComponentWithModuleUuidDto dto : dtos) {
if (modulePathFromRootProject != null || StringUtils.isEmpty(dto.moduleUuid())) {
// means that it's a root or a module with a valid path (to avoid overwriting key of root)
pathToKey.apply(modulePathFromRootProject);
- uuidsByKey.put(pathToKey.apply(modulePathFromRootProject), dto.uuid());
+ uuidsByMigratedKey.put(pathToKey.apply(modulePathFromRootProject), dto.uuid());
}
} else {
String modulePathFromRootProject = modulePathsByUuid.get(dto.moduleUuid());
String componentPath = createComponentPath(dto, modulePathFromRootProject);
- uuidsByKey.put(pathToKey.apply(componentPath), dto.uuid());
+ uuidsByMigratedKey.put(pathToKey.apply(componentPath), dto.uuid());
}
}
}
}
/**
- * Get UUID from database if it exists, otherwise generate a new one.
+ * Get UUID from component having the same key in database if it exists, otherwise look for migrated keys, and finally generate a new one.
*/
@Override
public String getOrCreateForKey(String key) {
- return uuidsByKey.computeIfAbsent(key, k -> Uuids.create());
+ return uuidsByDbKey.computeIfAbsent(key, k1 -> uuidsByMigratedKey.computeIfAbsent(k1, k2 -> Uuids.create()));
}
}
ComponentUuidFactoryWithMigration underTest = new ComponentUuidFactoryWithMigration(db.getDbClient(), db.getSession(), project.getDbKey(), pathToKey, reportModulesPath);
assertThat(underTest.getOrCreateForKey(project.getDbKey())).isEqualTo(project.uuid());
- assertThat(underTest.getOrCreateForKey(module.getDbKey())).isNotIn(project.uuid(), module.uuid());
+ assertThat(underTest.getOrCreateForKey(module.getDbKey())).isEqualTo(module.uuid());
}
@Test
// project remains the same
assertThat(underTest.getOrCreateForKey(project.getDbKey())).isEqualTo(project.uuid());
-
- // old keys with modules don't exist
- assertThat(underTest.getOrCreateForKey(module1.getDbKey())).isNotIn(project.uuid(), module1.uuid(), module2.uuid(), file1.uuid(), file2.uuid());
- assertThat(underTest.getOrCreateForKey(module2.getDbKey())).isNotIn(project.uuid(), module1.uuid(), module2.uuid(), file1.uuid(), file2.uuid());
- assertThat(underTest.getOrCreateForKey(file1.getDbKey())).isNotIn(project.uuid(), module1.uuid(), module2.uuid(), file1.uuid(), file2.uuid());
- assertThat(underTest.getOrCreateForKey(file2.getDbKey())).isNotIn(project.uuid(), module1.uuid(), module2.uuid(), file1.uuid(), file2.uuid());
}
@Test
assertThat(underTest.getOrCreateForKey(project.getDbKey())).isEqualTo(project.uuid());
}
+ @Test
+ public void prefers_component_having_same_key() {
+ ComponentDto project = db.components().insertPrivateProject(dto -> dto.setDbKey("project"));
+ ComponentDto module1 = db.components().insertComponent(ComponentTesting.newModuleDto(project)
+ .setDbKey("project:module1"));
+ ComponentDto file1 = db.components().insertComponent(ComponentTesting.newFileDto(module1)
+ .setDbKey("project:module1:file1")
+ .setPath("file1"));
+ ComponentDto disabledFileSameKey = db.components().insertComponent(ComponentTesting.newFileDto(project)
+ .setDbKey("project:module1/file1")
+ .setPath("module1_path/file1")
+ .setEnabled(false));
+
+ Map<String, String> modulesRelativePaths = new HashMap<>();
+ modulesRelativePaths.put("project:module1", "module1_path");
+ ComponentUuidFactoryWithMigration underTest = new ComponentUuidFactoryWithMigration(db.getDbClient(), db.getSession(), project.getDbKey(), pathToKey, modulesRelativePaths);
+
+ // in theory we should migrate file1. But since disabledFileSameKey already have the expected migrated key, let's reuse it.
+ assertThat(underTest.getOrCreateForKey("project:module1/file1")).isEqualTo(disabledFileSameKey.uuid());
+
+ // project remains the same
+ assertThat(underTest.getOrCreateForKey(project.getDbKey())).isEqualTo(project.uuid());
+ }
+
@Test
public void migrate_branch_with_modules() {
pathToKey = path -> path != null ? "project:" + path + ":BRANCH:branch1" : "project:BRANCH:branch1";
// project remains the same
assertThat(underTest.getOrCreateForKey(project.getDbKey())).isEqualTo(project.uuid());
-
- // old keys with modules don't exist
- assertThat(underTest.getOrCreateForKey(module1.getDbKey())).isNotIn(project.uuid(), module1.uuid(), module2.uuid(), file1.uuid(), file2.uuid());
- assertThat(underTest.getOrCreateForKey(module2.getDbKey())).isNotIn(project.uuid(), module1.uuid(), module2.uuid(), file1.uuid(), file2.uuid());
- assertThat(underTest.getOrCreateForKey(file1.getDbKey())).isNotIn(project.uuid(), module1.uuid(), module2.uuid(), file1.uuid(), file2.uuid());
- assertThat(underTest.getOrCreateForKey(file2.getDbKey())).isNotIn(project.uuid(), module1.uuid(), module2.uuid(), file1.uuid(), file2.uuid());
-
}
@Test
// module migrated to folder
assertThat(underTest.getOrCreateForKey("project:module1_path")).isEqualTo(module1.uuid());
-
- // doesnt exist
- assertThat(underTest.getOrCreateForKey("project:module1_path/")).isNotIn(project.uuid(), module1.uuid(), dir1.uuid());
- assertThat(underTest.getOrCreateForKey("project:module1")).isNotIn(project.uuid(), module1.uuid(), dir1.uuid());
}
@Test