]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-12821 Fail to update an application branch name
authorZipeng WU <zipeng.wu@sonarsource.com>
Thu, 3 Dec 2020 13:34:56 +0000 (14:34 +0100)
committerMathieu Suen <mathieu.suen@sonarsource.com>
Thu, 10 Dec 2020 08:35:50 +0000 (09:35 +0100)
server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java
server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java

index 902f569766d85fd677c3c181bf1b298832dfab22..b15a1f85e6a99a9b1bff7d6ac7161008cf7d14b4 100644 (file)
@@ -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.");
+    }
+  }
 }
index c37af6ba61cf6bd5685d8e2d103187808b177e71..c9491da15c3eab6608f99cbfeec49e49c0578fe9 100644 (file)
@@ -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<Map<String, Object>> 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();