From cbb1f8571227cc9c36a9372f01d943eb061543e3 Mon Sep 17 00:00:00 2001 From: Zipeng WU Date: Thu, 3 Dec 2020 14:34:56 +0100 Subject: [PATCH] SONAR-12821 Fail to update an application branch name --- .../db/component/ComponentKeyUpdaterDao.java | 36 ++++++++++++--- .../component/ComponentKeyUpdaterDaoTest.java | 45 +++++++++++++++++++ 2 files changed, 75 insertions(+), 6 deletions(-) diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java index 902f569766d..b15a1f85e6a 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java @@ -40,6 +40,8 @@ import org.sonar.db.Dao; import org.sonar.db.DbSession; import static org.sonar.core.component.ComponentKeys.checkProjectKey; +import static org.sonar.db.component.ComponentDto.BRANCH_KEY_SEPARATOR; +import static org.sonar.db.component.ComponentDto.generateBranchKey; /** * Class used to rename the key of a project and its resources. @@ -50,9 +52,7 @@ public class ComponentKeyUpdaterDao implements Dao { public void updateKey(DbSession dbSession, String projectUuid, String newKey) { ComponentKeyUpdaterMapper mapper = dbSession.getMapper(ComponentKeyUpdaterMapper.class); - if (mapper.countResourceByKey(newKey) > 0) { - throw new IllegalArgumentException("Impossible to update key: a component with key \"" + newKey + "\" already exists."); - } + checkExistentKey(mapper, newKey); // must SELECT first everything ResourceDto project = mapper.selectProjectByUuid(projectUuid); @@ -73,6 +73,26 @@ public class ComponentKeyUpdaterDao implements Dao { }); } + public void updateApplicationBranchKey(DbSession dbSession, String appBranchUuid, String appKey, String newBranchName) { + ComponentKeyUpdaterMapper mapper = dbSession.getMapper(ComponentKeyUpdaterMapper.class); + + String newAppBranchKey = generateBranchKey(appKey, newBranchName); + checkExistentKey(mapper, newAppBranchKey); + + ResourceDto appBranch = mapper.selectProjectByUuid(appBranchUuid); + String appBranchOldKey = appBranch.getKey(); + appBranch.setKey(newAppBranchKey); + mapper.updateComponent(appBranch); + + String oldAppBranchFragment = appBranchOldKey.replace(BRANCH_KEY_SEPARATOR, ""); + String newAppBranchFragment = appKey + newBranchName; + for (ResourceDto appBranchResource : mapper.selectProjectResources(appBranchUuid)) { + String newKey = computeNewKey(appBranchResource.getKey(), oldAppBranchFragment, newAppBranchFragment); + appBranchResource.setKey(newKey); + mapper.updateComponent(appBranchResource); + } + } + /** * * @return a map with currentKey/newKey is a bulk update was executed @@ -227,13 +247,17 @@ public class ComponentKeyUpdaterDao implements Dao { for (ResourceDto module : modules) { String newKey = computeNewKey(module.getKey(), stringToReplace, replacementString); checkProjectKey(newKey); - if (mapper.countResourceByKey(newKey) > 0) { - throw new IllegalArgumentException("Impossible to update key: a component with key \"" + newKey + "\" already exists."); - } + checkExistentKey(mapper, newKey); } } private static ComponentKeyUpdaterMapper mapper(DbSession dbSession) { return dbSession.getMapper(ComponentKeyUpdaterMapper.class); } + + public static void checkExistentKey(ComponentKeyUpdaterMapper mapper, String resourceKey) { + if (mapper.countResourceByKey(resourceKey) > 0) { + throw new IllegalArgumentException("Impossible to update key: a component with key \"" + resourceKey + "\" already exists."); + } + } } diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java index c37af6ba61c..c9491da15c3 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java @@ -28,6 +28,7 @@ import org.assertj.core.groups.Tuple; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.sonar.api.resources.Qualifiers; import org.sonar.api.utils.System2; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -39,6 +40,8 @@ import static com.google.common.collect.Lists.newArrayList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; import static org.sonar.db.component.BranchType.PULL_REQUEST; +import static org.sonar.db.component.ComponentDto.BRANCH_KEY_SEPARATOR; +import static org.sonar.db.component.ComponentDto.generateBranchKey; import static org.sonar.db.component.ComponentKeyUpdaterDao.computeNewKey; import static org.sonar.db.component.ComponentTesting.newDirectory; import static org.sonar.db.component.ComponentTesting.newFileDto; @@ -99,6 +102,48 @@ public class ComponentKeyUpdaterDaoTest { .containsOnlyOnce("your_project", "your_project:directory", "your_project:directory/file", "your_project:inactive_directory", "your_project:inactive_directory/file"); } + @Test + public void update_application_branch_key() { + ComponentDto app = db.components().insertPublicProject(); + ComponentDto appBranch = db.components().insertProjectBranch(app); + ComponentDto appBranchProj1 = appBranch.copy() + .setDbKey(appBranch.getDbKey().replace(BRANCH_KEY_SEPARATOR, "") + "appBranchProj1:BRANCH:1").setUuid("appBranchProj1").setScope(Qualifiers.FILE); + ComponentDto appBranchProj2 = appBranch.copy() + .setDbKey(appBranch.getDbKey().replace(BRANCH_KEY_SEPARATOR, "") + "appBranchProj2:BRANCH:2").setUuid("appBranchProj2").setScope(Qualifiers.FILE); + db.components().insertComponent(appBranchProj1); + db.components().insertComponent(appBranchProj2); + int branchComponentCount = 3; + + String oldBranchKey = appBranch.getDbKey(); + assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldBranchKey)).hasSize(branchComponentCount); + + String newBranchName = "newKey"; + String newAppBranchKey = ComponentDto.generateBranchKey(app.getDbKey(), newBranchName); + String newAppBranchFragment = app.getDbKey() + newBranchName; + underTest.updateApplicationBranchKey(dbSession, appBranch.uuid(), app.getDbKey(), newBranchName); + + assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldBranchKey)).isEmpty(); + + assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, newAppBranchKey)).hasSize(branchComponentCount); + + List> result = db.select(dbSession, String.format("select kee from components where root_uuid = '%s' and scope != 'PRJ'", appBranch.uuid())); + + assertThat(result).hasSize(2); + result.forEach(map -> map.values().forEach(k -> assertThat(k.toString()).startsWith(newAppBranchFragment))); + } + + @Test + public void update_application_branch_key_will_fail_if_newKey_exist(){ + ComponentDto app = db.components().insertPublicProject(); + ComponentDto appBranch = db.components().insertProjectBranch(app); + db.components().insertProjectBranch(app, b -> b.setKey("newName")); + + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage(String.format("Impossible to update key: a component with key \"%s\" already exists.", generateBranchKey(app.getDbKey(), "newName"))); + + underTest.updateApplicationBranchKey(dbSession, appBranch.uuid(), app.getDbKey(), "newName"); + } + @Test public void updateKey_updates_branches_too() { ComponentDto project = db.components().insertPublicProject(); -- 2.39.5