]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5561 Only synchronize issue permission index since last indexation was done
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 11 Sep 2014 09:06:13 +0000 (11:06 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 11 Sep 2014 09:06:13 +0000 (11:06 +0200)
14 files changed:
server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueAuthorizationDao.java
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueAuthorizationDoc.java
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueAuthorizationNormalizer.java
server/sonar-server/src/test/java/org/sonar/server/component/persistence/ComponentDaoTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueAuthorizationDaoTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueAuthorizationIndexMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/search/IndexSynchronizerMediumTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/search/IndexSynchronizerTest.java [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/component/persistence/ComponentDaoTest/insert-result.xml
server/sonar-server/src/test/resources/org/sonar/server/component/persistence/ComponentDaoTest/shared.xml
sonar-core/src/main/java/org/sonar/core/component/ComponentDto.java
sonar-core/src/main/resources/org/sonar/core/component/db/ComponentMapper.xml
sonar-core/src/main/resources/org/sonar/core/issue/db/IssueAuthorizationMapper.xml
sonar-core/src/test/java/org/sonar/core/component/ComponentDtoTest.java

index 39d4cb6280c75dddd72d8bde215e1ca749909db1..2a819600370ad9855dbdc312e0b3ceccbdc23a09 100644 (file)
@@ -66,15 +66,17 @@ public class IssueAuthorizationDao extends BaseDao<IssueAuthorizationMapper, Iss
 
       @Override
       public void handleResult(ResultContext context) {
-        Map<String, String> row = (Map<String, String>) context.getResultObject();
-        String project = row.get("project");
-        String user = row.get("user");
-        String group = row.get("permission_group");
+        Map<String, Object> row = (Map<String, Object>) context.getResultObject();
+        String project = (String) row.get("project");
+        String user = (String) row.get("user");
+        String group = (String) row.get("permission_group");
+        Date updatedAt = (Date) row.get("updated_at");
         IssueAuthorizationDto issueAuthorizationDto = authorizationDtoMap.get(project);
         if (issueAuthorizationDto == null) {
           issueAuthorizationDto = new IssueAuthorizationDto()
             .setProject(project)
             .setPermission(UserRole.USER);
+          issueAuthorizationDto.setUpdatedAt(updatedAt);
         }
         if (group != null) {
           issueAuthorizationDto.addGroup(group);
@@ -106,16 +108,18 @@ public class IssueAuthorizationDao extends BaseDao<IssueAuthorizationMapper, Iss
 
     Map<String, IssueAuthorizationDto> authorizationDtoMap = newHashMap();
 
-    List<Map<String, String>> rows = session.selectList("org.sonar.core.issue.db.IssueAuthorizationMapper.selectAfterDate", params);
-    for (Map<String, String> row : rows) {
-      String project = row.get("project");
-      String user = row.get("user");
-      String group = row.get("permission_group");
+    List<Map<String, Object>> rows = session.selectList("org.sonar.core.issue.db.IssueAuthorizationMapper.selectAfterDate", params);
+    for (Map<String, Object> row : rows) {
+      String project = (String) row.get("project");
+      String user = (String) row.get("user");
+      String group = (String) row.get("permission_group");
+      Date updatedAt = (Date) row.get("updated_at");
       IssueAuthorizationDto issueAuthorizationDto = authorizationDtoMap.get(project);
       if (issueAuthorizationDto == null) {
         issueAuthorizationDto = new IssueAuthorizationDto()
           .setProject(project)
           .setPermission(UserRole.USER);
+        issueAuthorizationDto.setUpdatedAt(updatedAt);
       }
       if (group != null) {
         issueAuthorizationDto.addGroup(group);
index f0f9fd79973fc93451025ffa284a3c4f8d66d605..ab5574d0c71aeebe8efd940b1197d42b001017e8 100644 (file)
@@ -21,7 +21,9 @@
 package org.sonar.server.issue.index;
 
 import org.sonar.server.search.BaseDoc;
+import org.sonar.server.search.IndexUtils;
 
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
@@ -47,4 +49,8 @@ public class IssueAuthorizationDoc extends BaseDoc {
     return (List<String>) getField(IssueAuthorizationNormalizer.IssueAuthorizationField.USERS.field());
   }
 
+  public Date updatedAt() {
+    return IndexUtils.parseDateTime((String) getNullableField(IssueAuthorizationNormalizer.IssueAuthorizationField.UPDATED_AT.field()));
+  }
+
 }
index 001ad5f6d908b6ae516009d9ca7e21c2383ae3ad..737f906cabdd4a12bb41e97c3c2025db6e07b188 100644 (file)
@@ -44,6 +44,7 @@ public class IssueAuthorizationNormalizer extends BaseNormalizer<IssueAuthorizat
     public static final IndexField PERMISSION = add(IndexField.Type.STRING, "permission");
     public static final IndexField GROUPS = add(IndexField.Type.STRING, "groups");
     public static final IndexField USERS = add(IndexField.Type.STRING, "users");
+    public static final IndexField UPDATED_AT = add(IndexField.Type.DATE, BaseNormalizer.UPDATED_AT_FIELD);
 
     public static final Set<IndexField> ALL_FIELDS = getAllFields();
 
@@ -79,6 +80,7 @@ public class IssueAuthorizationNormalizer extends BaseNormalizer<IssueAuthorizat
     update.put(IssueAuthorizationField.PERMISSION.field(), dto.getPermission());
     update.put(IssueAuthorizationField.USERS.field(), dto.getUsers());
     update.put(IssueAuthorizationField.GROUPS.field(), dto.getGroups());
+    update.put(IssueAuthorizationField.UPDATED_AT.field(), dto.getUpdatedAt());
 
     /** Upsert elements */
     Map<String, Object> upsert = getUpsertFor(IssueAuthorizationField.ALL_FIELDS, update);
index 5296d905c942780895eb6848450d214b2778fa83..cbb7d8ece5904ed33c654fa7411a7af214037ca9 100644 (file)
@@ -91,6 +91,7 @@ public class ComponentDaoTest extends AbstractDaoTestCase {
     assertThat(result.language()).isNull();
     assertThat(result.subProjectId()).isNull();
     assertThat(result.projectId()).isEqualTo(1);
+    assertThat(result.getAuthorizationUpdatedAt()).isEqualTo(DateUtils.parseDate("2014-06-18"));
   }
 
   @Test
@@ -245,7 +246,8 @@ public class ComponentDaoTest extends AbstractDaoTestCase {
       .setLanguage("java")
       .setPath("src/org/struts/RequestContext.java")
       .setSubProjectId(3L)
-      .setEnabled(true);
+      .setEnabled(true)
+      .setAuthorizationUpdatedAt(DateUtils.parseDate("2014-06-18"));
 
     dao.insert(session, componentDto);
     session.commit();
index ff7415bdc0232733572861905a16ffd660c30e89..c8fe6f2514220d83c9005f7800c7c26569b7ed02 100644 (file)
@@ -67,6 +67,7 @@ public class IssueAuthorizationDaoTest extends AbstractDaoTestCase {
     assertThat(dto.getPermission()).isEqualTo("user");
     assertThat(dto.getGroups()).containsExactly("Anyone", "devs");
     assertThat(dto.getUsers()).containsExactly("user1");
+    assertThat(dto.getUpdatedAt()).isNotNull();
   }
 
   @Test
index 14eaa3fc1ac51634cb5d4c8e3f480dddaded37cb..94ee04595c13f343cb4cf4cf2ad73a5463739015 100644 (file)
@@ -24,6 +24,7 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.ClassRule;
 import org.junit.Test;
+import org.sonar.api.utils.DateUtils;
 import org.sonar.api.web.UserRole;
 import org.sonar.core.component.ComponentDto;
 import org.sonar.core.permission.PermissionFacade;
@@ -66,7 +67,8 @@ public class IssueAuthorizationIndexMediumTest {
   public void synchronize() throws Exception {
     project = new ComponentDto()
       .setKey("Sample")
-      .setProjectId(1L);
+      .setProjectId(1L)
+      .setAuthorizationUpdatedAt(DateUtils.parseDate("2014-09-11"));
     db.componentDao().insert(session, project);
 
     GroupDto sonarUsers = new GroupDto().setName("devs");
@@ -91,6 +93,7 @@ public class IssueAuthorizationIndexMediumTest {
     assertThat(issueAuthorizationDoc.permission()).isEqualTo("user");
     assertThat(issueAuthorizationDoc.groups()).containsExactly("devs");
     assertThat(issueAuthorizationDoc.users()).containsExactly("john");
+    assertThat(issueAuthorizationDoc.updatedAt()).isNotNull();
 
     tester.clearIndexes();
     tester.get(Platform.class).executeStartupTasks();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/search/IndexSynchronizerMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/search/IndexSynchronizerMediumTest.java
new file mode 100644 (file)
index 0000000..dc45b65
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.search;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.platform.Platform;
+import org.sonar.server.rule.RuleTesting;
+import org.sonar.server.rule.index.RuleIndex;
+import org.sonar.server.tester.ServerTester;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class IndexSynchronizerMediumTest {
+
+  @ClassRule
+  public static ServerTester tester = new ServerTester();
+
+  IndexSynchronizer synchronizer;
+  DbClient dbClient;
+  IndexClient indexClient;
+  Platform platform;
+  DbSession dbSession;
+
+  @Before
+  public void setUp() throws Exception {
+    dbClient = tester.get(DbClient.class);
+    indexClient = tester.get(IndexClient.class);
+    platform = tester.get(Platform.class);
+    dbSession = dbClient.openSession(false);
+    synchronizer = new IndexSynchronizer(dbClient, indexClient);
+    tester.clearDbAndIndexes();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    if (dbSession != null) {
+      dbSession.close();
+    }
+  }
+
+  @Test
+  public void can_synchronize() throws Exception {
+
+    int numberOfRules = 100;
+
+    for (int i = 0; i < numberOfRules; i++) {
+      dbClient.ruleDao().insert(dbSession, RuleTesting.newDto(RuleKey.of("test", "x" + i)));
+    }
+    dbSession.commit();
+
+    assertThat(indexClient.get(RuleIndex.class).countAll()).isEqualTo(numberOfRules);
+    tester.clearIndexes();
+    assertThat(indexClient.get(RuleIndex.class).countAll()).isEqualTo(0);
+
+    synchronizer.synchronize(dbSession, dbClient.ruleDao(), indexClient.get(RuleIndex.class));
+    assertThat(indexClient.get(RuleIndex.class).countAll()).isEqualTo(numberOfRules);
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/search/IndexSynchronizerTest.java b/server/sonar-server/src/test/java/org/sonar/server/search/IndexSynchronizerTest.java
deleted file mode 100644 (file)
index 911d53a..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.search;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.server.db.DbClient;
-import org.sonar.server.platform.Platform;
-import org.sonar.server.rule.RuleTesting;
-import org.sonar.server.rule.index.RuleIndex;
-import org.sonar.server.tester.ServerTester;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class IndexSynchronizerTest {
-
-  @ClassRule
-  public static ServerTester tester = new ServerTester();
-
-  IndexSynchronizer synchronizer;
-  DbClient dbClient;
-  IndexClient indexClient;
-  Platform platform;
-  DbSession dbSession;
-
-  @Before
-  public void setUp() throws Exception {
-    dbClient = tester.get(DbClient.class);
-    indexClient = tester.get(IndexClient.class);
-    platform = tester.get(Platform.class);
-    dbSession = dbClient.openSession(false);
-    synchronizer = new IndexSynchronizer(dbClient, indexClient);
-    tester.clearDbAndIndexes();
-  }
-
-  @After
-  public void tearDown() throws Exception {
-    if (dbSession != null) {
-      dbSession.close();
-    }
-  }
-
-  @Test
-  public void can_synchronize() throws Exception {
-
-    int numberOfRules = 100;
-
-    for (int i = 0; i < numberOfRules; i++) {
-      dbClient.ruleDao().insert(dbSession, RuleTesting.newDto(RuleKey.of("test", "x" + i)));
-    }
-    dbSession.commit();
-
-    assertThat(indexClient.get(RuleIndex.class).countAll()).isEqualTo(numberOfRules);
-    tester.clearIndexes();
-    assertThat(indexClient.get(RuleIndex.class).countAll()).isEqualTo(0);
-
-    synchronizer.synchronize(dbSession, dbClient.ruleDao(), indexClient.get(RuleIndex.class));
-    assertThat(indexClient.get(RuleIndex.class).countAll()).isEqualTo(numberOfRules);
-  }
-}
\ No newline at end of file
index 397d2ae97fcc48b15868dcb6aad4d247477e59e3..741a3eb7d8427e297c4a67ec8279faa54245a1bf 100644 (file)
@@ -3,7 +3,7 @@
   <projects id="1" kee="org.struts:struts-core:src/org/struts/RequestContext.java" name="RequestContext.java" long_name="org.struts.RequestContext"
       qualifier="FIL" scope="FIL" language="java" path="src/org/struts/RequestContext.java" root_id="3"
       description="[null]" enabled="[true]" copy_resource_id="[null]" person_id="[null]" deprecated_kee="[null]"
-      authorization_updated_at="[null]" created_at="2014-06-18"
+      authorization_updated_at="2014-06-18" created_at="2014-06-18"
       />
 
 </dataset>
index 0730d8ed1b39fba4a99ebb00cd72297d7375f93f..77ef9f1bdbcd800c7ce90d2d977688f9e600e2f3 100644 (file)
@@ -7,7 +7,7 @@
   <!-- root project -->
   <projects id="1" root_id="[null]" scope="PRJ" qualifier="TRK" kee="org.struts:struts" name="Struts"
             description="the description" long_name="Apache Struts"
-            enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" authorization_updated_at="[null]" />
+            enabled="[true]" language="[null]" copy_resource_id="[null]" person_id="[null]" path="[null]" 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]"
index 6691124af8a8711c092df0be0f264dbfe1594873..62aa4acbb0c8249c2903a536707e27ae264ebf99 100644 (file)
@@ -24,6 +24,8 @@ import org.sonar.api.component.Component;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 
+import java.util.Date;
+
 public class ComponentDto extends AuthorizedComponentDto implements Component {
 
   private String path;
@@ -35,6 +37,7 @@ public class ComponentDto extends AuthorizedComponentDto implements Component {
   private Long projectId;
   private Long subProjectId;
   private boolean enabled = true;
+  private Date authorizationUpdatedAt;
 
   public ComponentDto setId(Long id) {
     super.setId(id);
@@ -133,4 +136,16 @@ public class ComponentDto extends AuthorizedComponentDto implements Component {
     return this;
   }
 
+  /**
+   * Only available on projects
+   */
+  @CheckForNull
+  public Date getAuthorizationUpdatedAt() {
+    return authorizationUpdatedAt;
+  }
+
+  public ComponentDto setAuthorizationUpdatedAt(@Nullable Date authorizationUpdatedAt) {
+    this.authorizationUpdatedAt = authorizationUpdatedAt;
+    return this;
+  }
 }
index c9c614f8c80e8c249adbca25a14ae3eb3fb7da85..20685eb708e5b9b60847acd6bf524df680652022 100644 (file)
@@ -12,7 +12,8 @@
     p.language as language,
     s.root_project_id as projectId,
     p.root_id as subProjectId,
-    p.path as path
+    p.path as path,
+    p.authorization_updated_at as authorizationUpdatedAt
   </sql>
 
   <sql id="authorizedComponentColumns">
   </select>
 
   <sql id="insertColumns">
-    (kee, name, long_name, qualifier, scope, language, root_id, path, created_at)
+    (kee, name, long_name, qualifier, scope, language, root_id, path, created_at, authorization_updated_at)
   </sql>
 
   <insert id="insert" parameterType="Component" keyColumn="id" useGeneratedKeys="true" keyProperty="id">
     insert into projects <include refid="insertColumns"/>
-    values (#{kee}, #{name}, #{longName}, #{qualifier}, #{scope}, #{language}, #{subProjectId}, #{path}, #{createdAt})
+    values (#{kee}, #{name}, #{longName}, #{qualifier}, #{scope}, #{language}, #{subProjectId}, #{path}, #{createdAt}, #{authorizationUpdatedAt})
   </insert>
 
 </mapper>
index 1b741c8f211d3e99f4e97995d83f0ef03e4c34bf..e516c13ec397e4b707144555351cf841d20a97b5 100644 (file)
@@ -9,11 +9,13 @@
       project_authorization.project as "project",
       project_authorization.login as "user",
       project_authorization.permission_group as "permission_group",
-      project_authorization.permission_role as "permission_role"
+      project_authorization.permission_role as "permission_role",
+      project_authorization.updated_at as "updated_at"
     FROM (
       -- users
       SELECT
       projects.kee AS project,
+      projects.authorization_updated_at AS updated_at,
       users.login  AS login,
       NULL  AS permission_group,
       user_roles.role as permission_role
@@ -26,6 +28,7 @@
       -- groups without Anyone
       SELECT
       projects.kee AS project,
+      projects.authorization_updated_at AS updated_at,
       NULL  AS login,
       groups.name  AS permission_group,
       group_roles.role as permission_role
@@ -39,6 +42,7 @@
       -- Anyone groups
       SELECT
       projects.kee AS project,
+      projects.authorization_updated_at AS updated_at,
       NULL         AS login,
       #{anyone}     AS permission_group,
       group_roles.role as permission_role
index b71779f0e06ee4a578ea8473f3d969a920ebd4d6..7341139e2e186f3e67e1bf70e998d9aa99bde649 100644 (file)
@@ -21,6 +21,7 @@
 package org.sonar.core.component;
 
 import org.junit.Test;
+import org.sonar.api.utils.DateUtils;
 
 import static org.fest.assertions.Assertions.assertThat;
 
@@ -38,7 +39,8 @@ public class ComponentDtoTest {
       .setLanguage("java")
       .setPath("src/org/struts/RequestContext.java")
       .setProjectId(2L)
-      .setSubProjectId(3L);
+      .setSubProjectId(3L)
+      .setAuthorizationUpdatedAt(DateUtils.parseDate("2014-09-11"));
 
     assertThat(componentDto.getId()).isEqualTo(1L);
     assertThat(componentDto.key()).isEqualTo("org.struts:struts-core:src/org/struts/RequestContext.java");
@@ -50,6 +52,7 @@ public class ComponentDtoTest {
     assertThat(componentDto.language()).isEqualTo("java");
     assertThat(componentDto.projectId()).isEqualTo(2L);
     assertThat(componentDto.subProjectId()).isEqualTo(3L);
+    assertThat(componentDto.getAuthorizationUpdatedAt()).isEqualTo(DateUtils.parseDate("2014-09-11"));
   }
 
   @Test