]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5755 Manage UUID in Views and Devs
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Mon, 27 Oct 2014 10:18:44 +0000 (11:18 +0100)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Mon, 27 Oct 2014 10:30:16 +0000 (11:30 +0100)
18 files changed:
server/sonar-server/src/main/java/org/sonar/server/component/ComponentCleanerService.java
server/sonar-server/src/main/java/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigration.java
server/sonar-server/src/main/java/org/sonar/server/duplication/ws/DuplicationsJsonWriter.java
server/sonar-server/src/main/java/org/sonar/server/issue/ws/SearchAction.java
server/sonar-server/src/main/java/org/sonar/server/permission/InternalPermissionService.java
server/sonar-server/src/test/java/org/sonar/server/component/ComponentCleanerServiceMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/component/ComponentTesting.java
server/sonar-server/src/test/java/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/InternalPermissionServiceMediumTest.java
server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_components.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_components_without_uuid.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_projects.xml [deleted file]
sonar-core/src/main/java/org/sonar/core/component/AuthorizedComponentDto.java
sonar-core/src/main/java/org/sonar/core/component/ComponentDto.java
sonar-core/src/main/java/org/sonar/core/persistence/migration/v50/Migration50Mapper.java
sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl
sonar-core/src/test/java/org/sonar/core/resource/ResourceDaoTest.java
sonar-core/src/test/resources/org/sonar/core/resource/ResourceDaoTest/fixture.xml

index 49885ce2be8277dd52b5929ad128752370bfc1fb..f03ec5a6cb42e5a421577ee5ceeb6411ffc4751e 100644 (file)
@@ -45,10 +45,7 @@ public class ComponentCleanerService implements ServerComponent {
         throw new IllegalArgumentException("Only project can be deleted");
       }
       purgeDao.deleteResourceTree(project.getId());
-      String uuid = project.uuid();
-      if (uuid != null) {
-        deletePermissionIndexes(session, uuid);
-      }
+      deletePermissionIndexes(session, project.uuid());
       session.commit();
     } finally {
       session.close();
index 3d969db2f136d4f6b4b593ce71f9d3e0c35768c8..9619825745cde1e3be1e3ab294ea2a56f75bb072 100644 (file)
@@ -67,6 +67,7 @@ public class PopulateProjectsUuidColumnsMigration implements DatabaseMigration {
         migrateEnabledComponents(session, mapper, project, uuidByComponentId);
         migrateDisabledComponents(session, mapper, project, uuidByComponentId);
       }
+      migrateComponentsWithoutUuid(session, mapper);
 
       session.commit();
       // log the total number of process rows
@@ -118,8 +119,8 @@ public class PopulateProjectsUuidColumnsMigration implements DatabaseMigration {
       component.setModuleUuidPath(moduleUuidPath.toString());
     }
 
-    // Module UUID should contains direct module of a component, but it should be null on the first module
-    if (lastModule != null && !lastModule.getId().equals(project.getId())) {
+    // Module UUID contains direct module of a component
+    if (lastModule != null) {
       component.setModuleUuid(getOrCreateUuid(lastModule, uuidByComponentId));
     }
   }
@@ -134,6 +135,16 @@ public class PopulateProjectsUuidColumnsMigration implements DatabaseMigration {
     }
   }
 
+  private void migrateComponentsWithoutUuid(DbSession session, Migration50Mapper mapper) {
+    for (Component component : mapper.selectComponentsWithoutUuid()) {
+      String uuid = UUID.randomUUID().toString();
+      component.setUuid(uuid);
+
+      mapper.updateComponentUuids(component);
+      counter.getAndIncrement();
+    }
+  }
+
   private static String getOrCreateUuid(Component component, Map<Long, String> uuidByComponentId) {
     String existingUuid = component.getUuid();
     String uuid = existingUuid == null ? uuidByComponentId.get(component.getId()) : existingUuid;
index 51a90baf9e00e84e486a70a832d51f5187a877f5..9a72cef19167c6ea9159b71f23355235f1c2ef0c 100644 (file)
@@ -122,9 +122,9 @@ public class DuplicationsJsonWriter implements ServerComponent {
     }
   }
 
-  private ComponentDto getProject(@Nullable String projectUuid, Map<String, ComponentDto> projectsByUuid, DbSession session) {
+  private ComponentDto getProject(String projectUuid, Map<String, ComponentDto> projectsByUuid, DbSession session) {
     ComponentDto project = projectsByUuid.get(projectUuid);
-    if (project == null && projectUuid != null) {
+    if (project == null) {
       project = componentDao.getNullableByUuid(session, projectUuid);
       if (project != null) {
         projectsByUuid.put(project.uuid(), project);
index 21a4e04ebf14f82c7197bb8ddf812b7d20c28c12..b065883f0ca2eb50b8582509af1e49c648c861dc 100644 (file)
@@ -337,7 +337,7 @@ public class SearchAction extends SearchRequestHandler<IssueQuery, Issue> {
       json.beginObject();
 
       String actionPlanKey = issue.actionPlanKey();
-      ComponentDto file = componentsByUuid.get(((IssueDoc) issue).componentUuid());
+      ComponentDto file = componentsByUuid.get(issue.componentUuid());
       ComponentDto project = file != null ? projectsByComponentUuid.get(file.uuid()) : null;
       Duration debt = issue.debt();
       Date updateDate = issue.updateDate();
@@ -533,9 +533,7 @@ public class SearchAction extends SearchRequestHandler<IssueQuery, Issue> {
       projectsByComponentUuid.put(component.uuid(), Iterables.find(projects, new Predicate<ComponentDto>() {
         @Override
         public boolean apply(@Nullable ComponentDto input) {
-          String uuid = input != null ? input.uuid() : null;
-          String projectUuid = input != null ? input.projectUuid() : null;
-          return input != null && uuid != null && projectUuid != null && uuid.equals(projectUuid);
+          return input != null && input.uuid().equals(input.projectUuid());
         }
       }));
     }
index 663f38bfb7b2ce7871ad904558afcc4931c234a7..eda3b0b66af05ad107fd09b4c1b31f5987a0d876 100644 (file)
@@ -275,15 +275,9 @@ public class InternalPermissionService implements ServerComponent {
     }
   }
 
-  public void synchronizePermissions(DbSession session, @Nullable String projectUuid) {
-    if (projectUuid != null) {
-      // Views and Dev Cockpit have no uuid, but it's not an problem because they are not existing in the issue authorization index, so there's nothing to remove
-      dbClient.issueAuthorizationDao().synchronizeAfter(session,
-        index.get(IssueAuthorizationIndex.class).getLastSynchronization(),
-        ImmutableMap.of(IssueAuthorizationDao.PROJECT_UUID, projectUuid));
-    } else {
-      // TODO Set this log in debug mode to not poluate the logs.
-      LOG.warn("Try to synchronize issues permissions on a project without UUID, ignore");
-    }
+  public void synchronizePermissions(DbSession session, String projectUuid) {
+    dbClient.issueAuthorizationDao().synchronizeAfter(session,
+      index.get(IssueAuthorizationIndex.class).getLastSynchronization(),
+      ImmutableMap.of(IssueAuthorizationDao.PROJECT_UUID, projectUuid));
   }
 }
index 4cee6b86da3b28c14e61ce310531e9eeba32c7b2..5b2f5fce325c83e6a5c7baa78a993e35bff95cc8 100644 (file)
@@ -24,7 +24,6 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.ClassRule;
 import org.junit.Test;
-import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.security.DefaultGroups;
 import org.sonar.api.web.UserRole;
 import org.sonar.core.component.ComponentDto;
@@ -91,23 +90,6 @@ public class ComponentCleanerServiceMediumTest {
     assertThat(tester.get(IssueAuthorizationIndex.class).getNullableByKey(project.uuid())).isNull();
   }
 
-  @Test
-  public void not_fail_when_deleting_a_view() throws Exception {
-    ComponentDto project = ComponentTesting.newProjectDto()
-      .setQualifier(Qualifiers.VIEW)
-      .setUuid(null)
-      .setProjectUuid(null);
-    db.componentDao().insert(session, project);
-
-    // view can be seen by anyone
-    tester.get(PermissionFacade.class).insertGroupPermission(project.getId(), DefaultGroups.ANYONE, UserRole.USER, session);
-    db.issueAuthorizationDao().synchronizeAfter(session, new Date(0));
-
-    session.commit();
-
-    service.delete(project.getKey());
-  }
-
   @Test(expected = IllegalArgumentException.class)
   public void fail_to_delete_not_project() throws Exception {
     ComponentDto project = ComponentTesting.newProjectDto();
index 6a9948401b6ba5b2563b204a86a0753099989e60..2e90490d2d8759781988550d5b78652d53ab5a53 100644 (file)
@@ -33,7 +33,7 @@ public class ComponentTesting {
       .setUuid(UUID.randomUUID().toString())
       .setProjectUuid(subProjectOrProject.projectUuid())
       .setModuleUuid(!subProjectOrProject.scope().equals(Scopes.PROJECT) ? subProjectOrProject.uuid() : null)
-      .setModuleUuidPath(subProjectOrProject.moduleUuidPath() == null ? subProjectOrProject.uuid() + "." : subProjectOrProject.moduleUuidPath() + "." + subProjectOrProject.uuid())
+      .setModuleUuidPath(subProjectOrProject.moduleUuidPath() == null ? subProjectOrProject.uuid() : subProjectOrProject.moduleUuidPath() + "." + subProjectOrProject.uuid())
       .setKey("file")
       .setName("File")
       .setLongName("File")
@@ -50,7 +50,7 @@ public class ComponentTesting {
       .setUuid(UUID.randomUUID().toString())
       .setProjectUuid(subProjectOrProject.projectUuid())
       .setModuleUuid(!subProjectOrProject.scope().equals(Scopes.PROJECT) ? subProjectOrProject.uuid() : null)
-      .setModuleUuidPath(subProjectOrProject.moduleUuidPath() == null ? subProjectOrProject.uuid() + "." : subProjectOrProject.moduleUuidPath() + "." + subProjectOrProject.uuid())
+      .setModuleUuidPath(subProjectOrProject.moduleUuidPath() == null ? subProjectOrProject.uuid() : subProjectOrProject.moduleUuidPath() + "." + subProjectOrProject.uuid())
       .setKey("module")
       .setName("Module")
       .setLongName("Module")
index 16cccd6cf512f09712c7b9375c33416f765b425c..fe4b669c3200cfcf494f41721b2608e3a7f3935e 100644 (file)
@@ -63,8 +63,8 @@ public class PopulateProjectsUuidColumnsMigrationTest {
   }
 
   @Test
-  public void migrate_projects() throws Exception {
-    db.prepareDbUnit(getClass(), "migrate_projects.xml");
+  public void migrate_components() throws Exception {
+    db.prepareDbUnit(getClass(), "migrate_components.xml");
 
     migration.execute();
     session.commit();
@@ -78,7 +78,7 @@ public class PopulateProjectsUuidColumnsMigrationTest {
     Component module = mapper.selectComponentByKey("org.struts:struts-core");
     assertThat(module.getUuid()).isNotNull();
     assertThat(module.getProjectUuid()).isEqualTo(root.getUuid());
-    assertThat(module.getModuleUuid()).isNull();
+    assertThat(module.getModuleUuid()).isEqualTo(root.getUuid());
     assertThat(module.getModuleUuidPath()).isEqualTo(root.getUuid());
 
     Component subModule = mapper.selectComponentByKey("org.struts:struts-db");
@@ -209,7 +209,7 @@ public class PopulateProjectsUuidColumnsMigrationTest {
     Component subView = mapper.selectComponentByKey("subView");
     assertThat(subView.getUuid()).isNotNull();
     assertThat(subView.getProjectUuid()).isEqualTo(view.getUuid());
-    assertThat(subView.getModuleUuid()).isNull();
+    assertThat(subView.getModuleUuid()).isEqualTo(view.getUuid());
     assertThat(subView.getModuleUuidPath()).isEqualTo(view.getUuid());
 
     Component techProject = mapper.selectComponentByKey("vieworg.struts:struts");
@@ -235,8 +235,37 @@ public class PopulateProjectsUuidColumnsMigrationTest {
     Component techDev = mapper.selectComponentByKey("DEV:developer@company.net:org.struts:struts");
     assertThat(techDev.getUuid()).isNotNull();
     assertThat(techDev.getProjectUuid()).isEqualTo(dev.getUuid());
-    assertThat(techDev.getModuleUuid()).isNull();
+    assertThat(techDev.getModuleUuid()).isEqualTo(dev.getUuid());
     assertThat(techDev.getModuleUuidPath()).isEqualTo(dev.getUuid());
   }
 
+  @Test
+  public void migrate_components_without_uuid() throws Exception {
+    db.prepareDbUnit(getClass(), "migrate_components_without_uuid.xml");
+
+    migration.execute();
+    session.commit();
+
+    // Root project migrated
+    Component root = mapper.selectComponentByKey("org.struts:struts");
+    assertThat(root.getUuid()).isNotNull();
+    assertThat(root.getProjectUuid()).isEqualTo(root.getUuid());
+    assertThat(root.getModuleUuid()).isNull();
+    assertThat(root.getModuleUuidPath()).isNull();
+
+    // Module with a snapshot having no islast=true
+    Component module = mapper.selectComponentByKey("org.struts:struts-core");
+    assertThat(module.getUuid()).isNotNull();
+    assertThat(module.getProjectUuid()).isNull();
+    assertThat(module.getModuleUuid()).isNull();
+    assertThat(module.getModuleUuidPath()).isNull();
+
+    // File linked on a no more existing project
+     Component file = mapper.selectComponentByKey("org.struts:struts-core:src/org/struts/RequestContext.java");
+    assertThat(file.getUuid()).isNotNull();
+    assertThat(file.getProjectUuid()).isNull();
+    assertThat(file.getModuleUuid()).isNull();
+    assertThat(file.getModuleUuidPath()).isNull();
+  }
+
 }
index 2e15f30a63058a0cfd9d8f422c01cb5ce4bc5080..ed2c949691102ee16fd98150f15914f75e4b72a5 100644 (file)
@@ -25,7 +25,6 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.ClassRule;
 import org.junit.Test;
-import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.web.UserRole;
 import org.sonar.core.component.ComponentDto;
 import org.sonar.core.persistence.DbSession;
@@ -152,31 +151,6 @@ public class InternalPermissionServiceMediumTest {
     assertThat(issueAuthorizationDoc).isNull();
   }
 
-  @Test
-  public void add_component_user_permission_on_a_view() throws Exception {
-    ComponentDto view = ComponentTesting.newProjectDto()
-      .setKey("MASTER")
-      .setQualifier(Qualifiers.VIEW)
-      .setUuid(null)
-      .setProjectUuid(null);
-    db.componentDao().insert(session, view);
-    session.commit();
-    
-    MockUserSession.set().setLogin("admin").addProjectPermissions(UserRole.ADMIN, view.key());
-
-    UserDto user = new UserDto().setLogin("john").setName("John");
-    db.userDao().insert(session, user);
-    session.commit();
-
-    assertThat(tester.get(RoleDao.class).selectUserPermissions(session, user.getLogin(), view.getId())).isEmpty();
-
-    service.addPermission(params(user.getLogin(), null, view.key(), UserRole.USER));
-    session.commit();
-
-    // Check in db
-    assertThat(tester.get(RoleDao.class).selectUserPermissions(session, user.getLogin(), view.getId())).hasSize(1);
-  }
-
   private Map<String, Object> params(@Nullable String login, @Nullable String group, @Nullable String component, String permission) {
     Map<String, Object> params = Maps.newHashMap();
     params.put("user", login);
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_components.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_components.xml
new file mode 100644 (file)
index 0000000..14ba41f
--- /dev/null
@@ -0,0 +1,82 @@
+<dataset>
+
+  <!-- root project -->
+  <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+            uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+            description="the description" long_name="Apache Struts"
+            enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]"
+            created_at="2014-06-18" authorization_updated_at="2014-06-18" />
+  <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             status="P" islast="[true]" purge_status="[null]"
+             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+             version="[null]" path=""/>
+
+  <!-- module -->
+  <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core"
+            uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+            scope="PRJ" qualifier="BRC" long_name="Struts Core" deprecated_kee="[null]"
+            description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" created_at="2014-06-18" authorization_updated_at="[null]" />
+  <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+             status="P" islast="[true]" purge_status="[null]"
+             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+             version="[null]" path="1."/>
+
+  <!-- sub module -->
+  <projects id="3" root_id="2" kee="org.struts:struts-db" name="Struts Db"
+            uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+            scope="PRJ" qualifier="BRC" long_name="Struts Db" deprecated_kee="[null]"
+            description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" created_at="2014-06-18" authorization_updated_at="[null]" />
+  <snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1"
+             status="P" islast="[true]" purge_status="[null]"
+             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+             version="[null]" path="1.2."/>
+
+  <!-- directory -->
+  <projects long_name="org.struts" id="4" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts"
+            uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+            name="src/org/struts" root_id="2"
+            description="[null]" deprecated_kee="[null]"
+            enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" created_at="2014-06-18" authorization_updated_at="[null]" />
+  <snapshots id="4" project_id="4" parent_snapshot_id="3" root_project_id="1" root_snapshot_id="1"
+             status="P" islast="[true]" purge_status="[null]"
+             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             depth="[null]" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+             version="[null]" path="1.2.3."/>
+
+  <!-- file -->
+  <projects long_name="org.struts.RequestContext" id="5" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+            uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+            name="RequestContext.java" root_id="2"
+            description="[null]" deprecated_kee="[null]"
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts/RequestContext.java" created_at="2014-06-18" authorization_updated_at="[null]" />
+
+  <snapshots id="5" project_id="5" parent_snapshot_id="4" root_project_id="1" root_snapshot_id="1"
+             status="P" islast="[true]" purge_status="[null]"
+             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             depth="[null]" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+             version="[null]" path="1.2.3.4."/>
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_components_without_uuid.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_components_without_uuid.xml
new file mode 100644 (file)
index 0000000..806783d
--- /dev/null
@@ -0,0 +1,51 @@
+<dataset>
+
+  <!-- root project -->
+  <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
+            uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+            description="the description" long_name="Apache Struts"
+            enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]"
+            created_at="2014-06-18" authorization_updated_at="2014-06-18" />
+  <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
+             status="P" islast="[true]" purge_status="[null]"
+             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+             version="[null]" path=""/>
+
+  <!-- module with a snapshot having no islast=true -->
+  <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core"
+            uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+            scope="PRJ" qualifier="BRC" long_name="Struts Core" deprecated_kee="[null]"
+            description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" created_at="2014-06-18" authorization_updated_at="[null]" />
+  <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
+             status="P" islast="[false]" purge_status="[null]"
+             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+             version="[null]" path="1."/>
+
+  <!-- file linked on a no more existing project -->
+  <projects long_name="org.struts.RequestContext" id="5" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
+            uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
+            name="RequestContext.java" root_id="999"
+            description="[null]" deprecated_kee="[null]"
+            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts/RequestContext.java" created_at="2014-06-18" authorization_updated_at="[null]" />
+
+  <snapshots id="5" project_id="5" parent_snapshot_id="999" root_project_id="999" root_snapshot_id="999"
+             status="P" islast="[true]" purge_status="[null]"
+             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
+             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
+             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
+             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
+             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
+             depth="[null]" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
+             version="[null]" path="1.2.3.4."/>
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_projects.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/PopulateProjectsUuidColumnsMigrationTest/migrate_projects.xml
deleted file mode 100644 (file)
index 14ba41f..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-<dataset>
-
-  <!-- root project -->
-  <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
-            uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
-            description="the description" long_name="Apache Struts"
-            enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" deprecated_kee="[null]"
-            created_at="2014-06-18" authorization_updated_at="2014-06-18" />
-  <snapshots id="1" project_id="1" parent_snapshot_id="[null]" root_project_id="1" root_snapshot_id="[null]"
-             status="P" islast="[true]" purge_status="[null]"
-             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
-             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
-             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
-             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
-             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
-             depth="[null]" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
-             version="[null]" path=""/>
-
-  <!-- module -->
-  <projects id="2" root_id="1" kee="org.struts:struts-core" name="Struts Core"
-            uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
-            scope="PRJ" qualifier="BRC" long_name="Struts Core" deprecated_kee="[null]"
-            description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" created_at="2014-06-18" authorization_updated_at="[null]" />
-  <snapshots id="2" project_id="2" parent_snapshot_id="1" root_project_id="1" root_snapshot_id="1"
-             status="P" islast="[true]" purge_status="[null]"
-             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
-             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
-             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
-             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
-             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
-             depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
-             version="[null]" path="1."/>
-
-  <!-- sub module -->
-  <projects id="3" root_id="2" kee="org.struts:struts-db" name="Struts Db"
-            uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
-            scope="PRJ" qualifier="BRC" long_name="Struts Db" deprecated_kee="[null]"
-            description="[null]" enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" created_at="2014-06-18" authorization_updated_at="[null]" />
-  <snapshots id="3" project_id="3" parent_snapshot_id="2" root_project_id="1" root_snapshot_id="1"
-             status="P" islast="[true]" purge_status="[null]"
-             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
-             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
-             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
-             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
-             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
-             depth="[null]" scope="PRJ" qualifier="BRC" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
-             version="[null]" path="1.2."/>
-
-  <!-- directory -->
-  <projects long_name="org.struts" id="4" scope="DIR" qualifier="DIR" kee="org.struts:struts-core:src/org/struts"
-            uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
-            name="src/org/struts" root_id="2"
-            description="[null]" deprecated_kee="[null]"
-            enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="src/org/struts" created_at="2014-06-18" authorization_updated_at="[null]" />
-  <snapshots id="4" project_id="4" parent_snapshot_id="3" root_project_id="1" root_snapshot_id="1"
-             status="P" islast="[true]" purge_status="[null]"
-             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
-             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
-             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
-             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
-             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
-             depth="[null]" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
-             version="[null]" path="1.2.3."/>
-
-  <!-- file -->
-  <projects long_name="org.struts.RequestContext" id="5" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
-            uuid="[null]" project_uuid="[null]" module_uuid="[null]" module_uuid_path="[null]"
-            name="RequestContext.java" root_id="2"
-            description="[null]" deprecated_kee="[null]"
-            enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts/RequestContext.java" created_at="2014-06-18" authorization_updated_at="[null]" />
-
-  <snapshots id="5" project_id="5" parent_snapshot_id="4" root_project_id="1" root_snapshot_id="1"
-             status="P" islast="[true]" purge_status="[null]"
-             period1_mode="[null]" period1_param="[null]" period1_date="[null]"
-             period2_mode="[null]" period2_param="[null]" period2_date="[null]"
-             period3_mode="[null]" period3_param="[null]" period3_date="[null]"
-             period4_mode="[null]" period4_param="[null]" period4_date="[null]"
-             period5_mode="[null]" period5_param="[null]" period5_date="[null]"
-             depth="[null]" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" build_date="2008-12-02 13:58:00.00"
-             version="[null]" path="1.2.3.4."/>
-
-</dataset>
index 1be5940bd59875f34eda89d496abf9908ed57b4e..17bb40c1469fa7e27c6406608fa4865cc2d0ab21 100644 (file)
@@ -22,9 +22,6 @@ package org.sonar.core.component;
 
 import org.sonar.core.persistence.Dto;
 
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
 /**
  * Used to check that a project exists. Can return provisioned projects and projects from analysis.
  * The root project id is not available because no join on snapshot is done to retrieve it.
@@ -48,15 +45,11 @@ public class AuthorizedComponentDto extends Dto<String> {
     return this;
   }
 
-  /**
-   * Can be null on a view or a developer
-   */
-  @CheckForNull
   public String uuid() {
     return uuid;
   }
 
-  public AuthorizedComponentDto setAuthorizedUuid(@Nullable String uuid) {
+  public AuthorizedComponentDto setAuthorizedUuid(String uuid) {
     this.uuid = uuid;
     return this;
   }
index 11234cd9da741023c4c5ad980be527ae6de431d6..91510ea3c0f0e008de0af6cb136a57d2a48c8498 100644 (file)
@@ -63,7 +63,7 @@ public class ComponentDto extends AuthorizedComponentDto implements Component {
     return this;
   }
 
-  public ComponentDto setUuid(@Nullable String uuid) {
+  public ComponentDto setUuid(String uuid) {
     super.setAuthorizedUuid(uuid);
     return this;
   }
@@ -71,18 +71,17 @@ public class ComponentDto extends AuthorizedComponentDto implements Component {
   /**
    * Return the root project id. On a root project, return itself
    */
-  @CheckForNull
   public String projectUuid() {
     return projectUuid;
   }
 
-  public ComponentDto setProjectUuid(@Nullable String projectUuid) {
+  public ComponentDto setProjectUuid(String projectUuid) {
     this.projectUuid = projectUuid;
     return this;
   }
 
   /**
-   * Return the direct module of a component. Will be null on projects and on first modules
+   * Return the direct module of a component. Will be null on projects
    */
   @CheckForNull
   public String moduleUuid() {
index 398b415d87c1c74fc031b8e303ddd3a2b1437290..1a914314fdf23004a2376d970eae83da048d70a1 100644 (file)
@@ -78,6 +78,16 @@ public interface Migration50Mapper {
   @Result(javaType = Component.class)
   List<Component> selectDisabledComponentChildrenForProjects(@Param("id") Long projectId);
 
+  /**
+   * Return not migrated components
+   */
+  @Select("SELECT " +
+    "  p.id AS \"id\" " +
+    "FROM projects p " +
+    "  WHERE p.uuid IS NULL ")
+  @Result(javaType = Component.class)
+  List<Component> selectComponentsWithoutUuid();
+
   @Select("SELECT " +
     "  p.id AS \"id\", " +
     "  p.uuid AS \"uuid\", " +
index 9014be4eeab256f5c3867d48394cea0efc2e4e04..b4def3aa8f95f5237141e27d7b4d5e1e1ef7d086 100644 (file)
@@ -637,7 +637,7 @@ CREATE INDEX "PROJECTS_KEE" ON "PROJECTS" ("KEE", "ENABLED");
 
 CREATE INDEX "PROJECTS_ROOT_ID" ON "PROJECTS" ("ROOT_ID");
 
-CREATE INDEX "PROJECTS_UUID" ON "PROJECTS" ("UUID");
+CREATE UNIQUE INDEX "PROJECTS_UUID" ON "PROJECTS" ("UUID");
 
 CREATE INDEX "RESOURCE_INDEX_KEE" ON "RESOURCE_INDEX" ("KEE");
 
index 03e50c465e6f6d71c8b8c264f918a3810a825ddb..c5d66abe39d51cc8a7f3626de06499fd428e0033 100644 (file)
@@ -118,7 +118,7 @@ public class ResourceDaoTest extends AbstractDaoTestCase {
     setupData("fixture");
 
     ResourceDto file = dao.getResource(4L);
-    assertThat(file.getUuid()).isEqualTo("CDEF");
+    assertThat(file.getUuid()).isEqualTo("DEFG");
     assertThat(file.getProjectUuid()).isEqualTo("ABCD");
     assertThat(file.getModuleUuid()).isEqualTo("BCDE");
     assertThat(file.getModuleUuidPath()).isEqualTo("ABCD.BCDE");
index a9b088b96703e5609980f82d69acffc5ab046b70..1819dc696de70bac10ef7f843295f5e1eb0154d5 100644 (file)
@@ -64,7 +64,7 @@
 
   <!-- file -->
   <projects long_name="org.struts.RequestContext" id="4" scope="FIL" qualifier="FIL" kee="org.struts:struts-core:src/org/struts/RequestContext.java"
-            uuid="CDEF" project_uuid="ABCD" module_uuid="BCDE" module_uuid_path="ABCD.BCDE"
+            uuid="DEFG" project_uuid="ABCD" module_uuid="BCDE" module_uuid_path="ABCD.BCDE"
             name="RequestContext.java" root_id="2"
             description="[null]"
             enabled="[true]" language="java" copy_resource_id="[null]" person_id="[null]" path="src/org/struts/RequestContext.java"