]> source.dussan.org Git - sonarqube.git/commitdiff
Refactor issue indexer (project-agnostic approach)
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Thu, 4 Dec 2014 20:56:18 +0000 (21:56 +0100)
committerSimon Brandhof <simon.brandhof@sonarsource.com>
Thu, 4 Dec 2014 21:29:19 +0000 (22:29 +0100)
97 files changed:
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/InitialOpenIssuesSensor.java
server/sonar-data-test/src/test/java/org/sonar/server/benchmark/IssueIndexBenchmarkTest.java
server/sonar-server/src/main/java/org/sonar/server/component/ComponentCleanerService.java
server/sonar-server/src/main/java/org/sonar/server/computation/IndexProjectIssuesStep.java
server/sonar-server/src/main/java/org/sonar/server/db/migrations/DatabaseMigrations.java
server/sonar-server/src/main/java/org/sonar/server/db/migrations/v50/FeedIssueLongDates.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/es/NewIndex.java
server/sonar-server/src/main/java/org/sonar/server/issue/IssueBulkChangeService.java
server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java
server/sonar-server/src/main/java/org/sonar/server/issue/ServerIssueStorage.java
server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueDao.java
server/sonar-server/src/main/java/org/sonar/server/issue/index/FakeIssueDto.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueDoc.java
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndexer.java
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueNormalizer.java
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueResultSetIterator.java
server/sonar-server/src/main/java/org/sonar/server/search/IndexSynchronizer.java
server/sonar-server/src/test/java/org/sonar/server/component/ComponentCleanerServiceMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceMediumTest.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/FeedIssueLongDatesTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/IssueCommentServiceMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/IssueTesting.java
server/sonar-server/src/test/java/org/sonar/server/issue/ServerIssueStorageTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueBackendMediumTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueDaoTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueResultSetIteratorTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/platform/BackendCleanupMediumTest.java
server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedIssueLongDatesTest/before.xml [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedIssueLongDatesTest/schema.sql [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/issue/ServerIssueStorageTest/should_insert_new_issues-result.xml
server/sonar-server/src/test/resources/org/sonar/server/issue/ServerIssueStorageTest/should_update_issues-result.xml
server/sonar-server/src/test/resources/org/sonar/server/issue/ServerIssueStorageTest/should_update_issues.xml
server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/find_after_dates_with_project.xml [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/find_by_action_plan.xml
server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/get_by_key.xml
server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/insert-result.xml
server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/some_issues.xml [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/update-result.xml
server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/update.xml
server/sonar-server/src/test/resources/org/sonar/server/issue/index/IssueIndexerTest/index.xml
server/sonar-server/src/test/resources/org/sonar/server/issue/index/IssueResultSetIteratorTest/shared.xml
server/sonar-web/src/main/webapp/WEB-INF/db/migrate/718_add_issue_long_dates.rb [new file with mode: 0644]
server/sonar-web/src/main/webapp/WEB-INF/db/migrate/719_feed_issue_long_dates.rb [new file with mode: 0644]
server/sonar-web/src/main/webapp/WEB-INF/db/migrate/720_rename_issue_long_dates.rb [new file with mode: 0644]
sonar-batch/src/main/java/org/sonar/batch/issue/ScanIssueStorage.java
sonar-batch/src/test/java/org/sonar/batch/issue/ScanIssueStorageTest.java
sonar-batch/src/test/resources/org/sonar/batch/issue/ScanIssueStorageTest/should_resolve_conflicts_on_updates-result.xml
sonar-batch/src/test/resources/org/sonar/batch/issue/ScanIssueStorageTest/should_resolve_conflicts_on_updates.xml
sonar-batch/src/test/resources/org/sonar/batch/issue/ScanIssueStorageTest/should_update_issues-result.xml
sonar-batch/src/test/resources/org/sonar/batch/issue/ScanIssueStorageTest/should_update_issues.xml
sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java
sonar-core/src/main/java/org/sonar/core/issue/db/IssueDto.java
sonar-core/src/main/java/org/sonar/core/issue/db/IssueMapper.java
sonar-core/src/main/java/org/sonar/core/issue/db/IssueStorage.java
sonar-core/src/main/java/org/sonar/core/issue/db/UpdateConflictResolver.java
sonar-core/src/main/java/org/sonar/core/persistence/DatabaseVersion.java
sonar-core/src/main/java/org/sonar/core/purge/PurgeDao.java
sonar-core/src/main/java/org/sonar/core/purge/PurgeMapper.java
sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml
sonar-core/src/main/resources/org/sonar/core/persistence/rows-h2.sql
sonar-core/src/main/resources/org/sonar/core/persistence/schema-h2.ddl
sonar-core/src/main/resources/org/sonar/core/purge/PurgeMapper.xml
sonar-core/src/test/java/org/sonar/core/issue/db/IssueMapperTest.java
sonar-core/src/test/java/org/sonar/core/issue/db/IssueStorageTest.java
sonar-core/src/test/java/org/sonar/core/persistence/TestDatabase.java
sonar-core/src/test/java/org/sonar/core/purge/PurgeDaoTest.java
sonar-core/src/test/resources/org/sonar/core/issue/db/ActionPlanStatsDaoTest/should_find_by_project.xml
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueChangeDaoTest/select_issue_changelog_by_module.xml
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueChangeDaoTest/select_issue_changelog_by_module_are_sorted_by_creation_date.xml
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/find_rules_by_component.xml
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/find_severities_by_component.xml
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_by_key.xml
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_issue_and_component_ids.xml
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_non_closed_issues_by_module.xml
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_non_closed_issues_by_module_on_removed_project.xml
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueMapperTest/testInsert-result.xml
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueMapperTest/testUpdate-result.xml
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueMapperTest/testUpdate.xml
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueMapperTest/updateBeforeSelectedDate_with_conflict-result.xml
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueMapperTest/updateBeforeSelectedDate_with_conflict.xml
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueStorageTest/should_update_issues.xml
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/disable_resources_without_last_snapshot-result.xml
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/disable_resources_without_last_snapshot.xml
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/should_delete_all_closed_issues-result.xml
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/should_delete_all_closed_issues.xml
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/should_delete_old_closed_issues-result.xml
sonar-core/src/test/resources/org/sonar/core/purge/PurgeDaoTest/should_delete_old_closed_issues.xml
sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/DefaultIssue.java
sonar-plugin-api/src/test/java/org/sonar/api/issue/internal/DefaultIssueTest.java

index a6089aab0644cf3a81fb6e38dceef9e1699a1662..17f22757db874b0e49fb947721571340bfff73ea 100644 (file)
@@ -63,7 +63,7 @@ public class InitialOpenIssuesSensor implements Sensor {
       @Override
       public void handleResult(ResultContext rc) {
         IssueDto dto = (IssueDto) rc.getResultObject();
-        dto.setSelectedAt(now);
+        dto.setSelectedAt(now.getTime());
         initialOpenIssuesStack.addIssue(dto);
       }
     });
index 4a48f050968602811a5de22d1c0f56ad12582402..771155528f5d972ac11fefa7b75648d60f4ed096 100644 (file)
@@ -164,8 +164,8 @@ public class IssueIndexBenchmarkTest {
       issue.setAssignee(users.next());
       issue.setAuthorLogin(users.next());
       issue.setLine(RandomUtils.nextInt());
-      issue.setCreationDate(new Date());
-      issue.setUpdateDate(new Date());
+      issue.setTechnicalCreationDate(new Date());
+      issue.setTechnicalUpdateDate(new Date());
       issue.setFuncUpdateDate(new Date());
       issue.setFuncCreationDate(new Date());
       issue.setFuncCloseDate(null);
index b14b61793d68b3356b2ba53a741cd45fe6363265..7bf1872218379c34352ba52d074d7bfdaf588337 100644 (file)
@@ -65,7 +65,7 @@ public class ComponentCleanerService implements ServerComponent {
   }
 
   private void deleteFromIndices(String projectUuid) {
-    // optimization : index issues is refreshed once at the end
+    // optimization : index "issues" is refreshed once at the end
     issueAuthorizationIndexer.deleteProject(projectUuid, false);
     issueIndexer.deleteProject(projectUuid, true);
     sourceLineIndexer.deleteByProject(projectUuid);
index 34936e7febe3ef5c1c6e89deb0c892bf908b60a2..f7391b9963896d4c667e2150c9cfd451148834eb 100644 (file)
 
 package org.sonar.server.computation;
 
-import com.google.common.collect.ImmutableMap;
 import org.sonar.core.component.ComponentDto;
 import org.sonar.core.computation.db.AnalysisReportDto;
 import org.sonar.core.persistence.DbSession;
-import org.sonar.server.db.DbClient;
-import org.sonar.server.issue.index.IssueIndex;
-import org.sonar.server.issue.index.IssueNormalizer;
-import org.sonar.server.search.IndexClient;
-
-import java.util.Date;
+import org.sonar.server.issue.index.IssueAuthorizationIndexer;
+import org.sonar.server.issue.index.IssueIndexer;
 
 public class IndexProjectIssuesStep implements ComputationStep {
 
-  private final DbClient dbClient;
-  private final IndexClient index;
 
-  public IndexProjectIssuesStep(DbClient dbClient, IndexClient index) {
-    this.dbClient = dbClient;
-    this.index = index;
+  private final IssueAuthorizationIndexer authorizationIndexer;
+  private final IssueIndexer indexer;
+
+  public IndexProjectIssuesStep(IssueAuthorizationIndexer authorizationIndexer, IssueIndexer indexer) {
+    this.authorizationIndexer = authorizationIndexer;
+    this.indexer = indexer;
   }
 
   @Override
   public void execute(DbSession session, AnalysisReportDto report, ComponentDto project) {
-    indexProjectIssues(session, project);
+    authorizationIndexer.index();
+    indexer.index();
   }
 
   @Override
   public String getDescription() {
     return "Update issues index";
   }
-
-  private void indexProjectIssues(DbSession session, ComponentDto project) {
-    dbClient.issueDao().synchronizeAfter(session,
-      getLastIndexSynchronizationDate(project),
-      parameters(project));
-    session.commit();
-  }
-
-  private ImmutableMap<String, String> parameters(ComponentDto project) {
-    return ImmutableMap.of(IssueNormalizer.IssueField.PROJECT.field(), project.uuid());
-  }
-
-  private Date getLastIndexSynchronizationDate(ComponentDto project) {
-    return index.get(IssueIndex.class).getLastSynchronization(parameters(project));
-  }
 }
index 1533b430cfb473a37f1ebdbe2effcc72a5719d8d..6bbc494844d905485b159e981fa681ca38be8475 100644 (file)
@@ -71,7 +71,8 @@ public interface DatabaseMigrations {
     PopulateProjectsUuidColumnsMigration.class,
     ReplaceIssueFiltersProjectKeyByUuid.class,
     FeedSnapshotSourcesUpdatedAt.class,
-    FeedFileSources.class
+    FeedFileSources.class,
+    FeedIssueLongDates.class
   );
 
 }
diff --git a/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v50/FeedIssueLongDates.java b/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v50/FeedIssueLongDates.java
new file mode 100644 (file)
index 0000000..cc65ac8
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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.db.migrations.v50;
+
+import org.sonar.api.utils.System2;
+import org.sonar.core.persistence.Database;
+import org.sonar.server.db.migrations.BaseDataChange;
+import org.sonar.server.db.migrations.MassUpdate;
+import org.sonar.server.db.migrations.Select;
+import org.sonar.server.db.migrations.SqlStatement;
+
+import java.sql.SQLException;
+import java.util.Date;
+
+public class FeedIssueLongDates extends BaseDataChange {
+
+  private final System2 system;
+
+  public FeedIssueLongDates(Database db, System2 system) {
+    super(db);
+    this.system = system;
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    final long now = system.now();
+
+    MassUpdate massUpdate = context.prepareMassUpdate();
+    massUpdate.select("SELECT i.id, i.created_at, i.updated_at FROM issues i WHERE created_at_ms IS NULL");
+    massUpdate.update("UPDATE issues SET created_at_ms=?, updated_at_ms=? WHERE id=?");
+    massUpdate.rowPluralName("issues");
+    massUpdate.execute(new MassUpdate.Handler() {
+      @Override
+      public boolean handle(Select.Row row, SqlStatement update) throws SQLException {
+        Long id = row.getLong(1);
+        Date createdAt = row.getDate(2);
+        Date updatedAt = row.getDate(3);
+
+        update.setLong(1, Math.min(now, createdAt.getTime()));
+        update.setLong(2, Math.min(now, updatedAt.getTime()));
+        update.setLong(3, id);
+        return true;
+      }
+    });
+  }
+
+}
index 9dc4caab60cc7937ab19d8bcfdcef72ab05d8c77..b61e147b69eb3b19ee27a9f801aaeadd8e4770c8 100644 (file)
@@ -136,18 +136,24 @@ public class NewIndex {
     }
 
     /**
-     * Create a inner-field named "sort" with analyzer "sortable"
+     * Create an inner-field named "sort" with analyzer "sortable"
      */
     public StringFieldBuilder enableSorting() {
       this.sortable = true;
       return this;
     }
 
+    /**
+     * Create an inner-field named "words" with analyzer "words"
+     */
     public StringFieldBuilder enableWordSearch() {
       this.wordSearch = true;
       return this;
     }
 
+    /**
+     * Create a inner-field named "grams" with analyzer "grams"
+     */
     public StringFieldBuilder enableGramSearch() {
       this.gramSearch = true;
       return this;
index 1146566a93719ae8763318e836b5924442f89ee8..7383549eabbef36b28a007af51fb9caf41e8e32e 100644 (file)
@@ -130,7 +130,7 @@ public class IssueBulkChangeService {
 
     DbSession session = dbClient.openSession(false);
     try {
-      List<IssueDto> issueDtos = dbClient.issueDao().getByKeys(session, authorizedIssueKeys);
+      List<IssueDto> issueDtos = dbClient.issueDao().selectByKeys(session, authorizedIssueKeys);
       return newArrayList(Iterables.transform(issueDtos, new Function<IssueDto, Issue>() {
         @Override
         public Issue apply(@Nullable IssueDto input) {
index efa6867f785ab473262dce7e104ec58bdaa8c378..5d482b4632d5edccad1dc1bfb826641074ba27ed 100644 (file)
@@ -312,7 +312,7 @@ public class IssueService implements ServerComponent {
   IssueDto getByKeyForUpdate(DbSession session, String key) {
     // Load from index to check permission : if the user has no permission to see the issue an exception will be generated
     Issue authorizedIssueIndex = getByKey(key);
-    return dbClient.issueDao().getByKey(session, authorizedIssueIndex.key());
+    return dbClient.issueDao().selectByKey(session, authorizedIssueIndex.key());
   }
 
   void saveIssue(DbSession session, DefaultIssue issue, IssueChangeContext context, @Nullable String comment) {
index f10ef8d5c73f1c0e2f16711e2ba0836f193e70de..4eb8f3164ee822ab703473c77ad9316fb4733bd8 100644 (file)
@@ -28,8 +28,7 @@ import org.sonar.core.issue.db.IssueStorage;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.persistence.MyBatis;
 import org.sonar.server.db.DbClient;
-
-import java.util.Date;
+import org.sonar.server.issue.index.IssueIndexer;
 
 /**
  * @since 3.6
@@ -37,14 +36,16 @@ import java.util.Date;
 public class ServerIssueStorage extends IssueStorage implements ServerComponent {
 
   private final DbClient dbClient;
+  private final IssueIndexer indexer;
 
-  public ServerIssueStorage(MyBatis mybatis, RuleFinder ruleFinder, DbClient dbClient) {
+  public ServerIssueStorage(MyBatis mybatis, RuleFinder ruleFinder, DbClient dbClient, IssueIndexer indexer) {
     super(mybatis, ruleFinder);
     this.dbClient = dbClient;
+    this.indexer = indexer;
   }
 
   @Override
-  protected void doInsert(DbSession session, Date now, DefaultIssue issue) {
+  protected void doInsert(DbSession session, long now, DefaultIssue issue) {
     ComponentDto component = component(session, issue);
     ComponentDto project = project(session, issue);
     int ruleId = ruleId(issue);
@@ -54,12 +55,17 @@ public class ServerIssueStorage extends IssueStorage implements ServerComponent
   }
 
   @Override
-  protected void doUpdate(DbSession session, Date now, DefaultIssue issue) {
+  protected void doUpdate(DbSession session, long now, DefaultIssue issue) {
     IssueDto dto = IssueDto.toDtoForUpdate(issue, project(session, issue).getId(), now);
 
     dbClient.issueDao().update(session, dto);
   }
 
+  @Override
+  protected void doAfterSave() {
+    indexer.index();
+  }
+
   protected ComponentDto component(DbSession session, DefaultIssue issue) {
     return dbClient.componentDao().getByKey(session, issue.componentKey());
   }
index 9ac3f2022ca2d7a19442168ad81049c03e801f7a..0b2aba8a5a8ef5fccd92bfaf49cc7921b765ba60 100644 (file)
  */
 package org.sonar.server.issue.db;
 
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import org.sonar.api.utils.System2;
 import org.sonar.core.issue.db.IssueDto;
 import org.sonar.core.issue.db.IssueMapper;
 import org.sonar.core.persistence.DaoComponent;
 import org.sonar.core.persistence.DbSession;
-import org.sonar.server.db.BaseDao;
-import org.sonar.server.issue.index.IssueNormalizer;
-import org.sonar.server.search.IndexDefinition;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.server.exceptions.NotFoundException;
 
-import javax.annotation.Nullable;
+import javax.annotation.CheckForNull;
 
 import java.util.Collection;
-import java.util.Date;
 import java.util.List;
-import java.util.Map;
 
-public class IssueDao extends BaseDao<IssueMapper, IssueDto, String> implements DaoComponent {
+public class IssueDao extends org.sonar.core.issue.db.IssueDao implements DaoComponent {
 
-  public IssueDao() {
-    this(System2.INSTANCE);
+  public IssueDao(MyBatis mybatis) {
+    super(mybatis);
   }
 
-  @VisibleForTesting
-  public IssueDao(System2 system) {
-    super(IndexDefinition.ISSUES, IssueMapper.class, system);
-  }
-
-  @Override
-  protected IssueDto doGetNullableByKey(DbSession session, String key) {
+  @CheckForNull
+  public IssueDto selectNullableByKey(DbSession session, String key) {
     return mapper(session).selectByKey(key);
   }
 
-  @Override
-  protected List<IssueDto> doGetByKeys(DbSession session, Collection<String> keys) {
-    return mapper(session).selectByKeys(keys);
+  public IssueDto selectByKey(DbSession session, String key) {
+    IssueDto issue = selectNullableByKey(session, key);
+    if (issue == null) {
+      throw new NotFoundException(String.format("Key '%s' not found", key));
+    }
+    return issue;
   }
 
   public List<IssueDto> findByActionPlan(DbSession session, String actionPlan) {
     return mapper(session).selectByActionPlan(actionPlan);
   }
 
-  @Override
-  protected IssueDto doUpdate(DbSession session, IssueDto issue) {
-    mapper(session).update(issue);
-    return issue;
+  public List<IssueDto> selectByKeys(DbSession session, Collection<String> keys) {
+    return mapper(session).selectByKeys(keys);
   }
 
-  @Override
-  protected IssueDto doInsert(DbSession session, IssueDto issue) {
-    Preconditions.checkNotNull(issue.getKey(), "Cannot insert Issue with empty key!");
-    Preconditions.checkNotNull(issue.getComponentId(), "Cannot insert Issue with no Component!");
-    mapper(session).insert(issue);
-    return issue;
+  public void insert(DbSession session, IssueDto dto) {
+    mapper(session).insert(dto);
   }
 
-  @Override
-  protected String getSynchronizationStatementName() {
-    return "selectAfterDate";
+  public void insert(DbSession session, IssueDto dto, IssueDto... others) {
+    IssueMapper mapper = mapper(session);
+    mapper.insert(dto);
+    for (IssueDto other : others) {
+      mapper.insert(other);
+    }
   }
 
-  @Override
-  protected Map<String, Object> getSynchronizationParams(@Nullable Date date, Map<String, String> params) {
-    Map<String, Object> finalParams = super.getSynchronizationParams(date, params);
-    finalParams.put(IssueNormalizer.IssueField.PROJECT.field(), params.get(IssueNormalizer.IssueField.PROJECT.field()));
-    return finalParams;
+  public void update(DbSession session, IssueDto dto) {
+    mapper(session).update(dto);
   }
 }
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/index/FakeIssueDto.java b/server/sonar-server/src/main/java/org/sonar/server/issue/index/FakeIssueDto.java
new file mode 100644 (file)
index 0000000..0db9d5d
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * 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.issue.index;
+
+import org.sonar.core.persistence.Dto;
+
+public class FakeIssueDto extends Dto<String> {
+  @Override
+  public String getKey() {
+    throw new UnsupportedOperationException();
+  }
+}
index 5d8a3dbd5003870205b97ce6c43f19fa684e6404..7db14c4895f989a094537e665af1c364a5378900 100644 (file)
@@ -52,11 +52,11 @@ public class IssueDoc extends BaseDoc implements Issue {
 
   @Override
   public String componentUuid() {
-    return getField(IssueNormalizer.IssueField.COMPONENT.field());
+    return getField(IssueIndexDefinition.FIELD_ISSUE_COMPONENT_UUID);
   }
 
   public String moduleUuid() {
-    return getField(IssueNormalizer.IssueField.MODULE.field());
+    return getField(IssueIndexDefinition.FIELD_ISSUE_MODULE_UUID);
   }
 
   @Override
@@ -66,79 +66,85 @@ public class IssueDoc extends BaseDoc implements Issue {
 
   @Override
   public String projectUuid() {
-    return getField(IssueNormalizer.IssueField.PROJECT.field());
+    return getField(IssueIndexDefinition.FIELD_ISSUE_PROJECT_UUID);
   }
 
   @Override
   public RuleKey ruleKey() {
-    return RuleKey.parse((String) getField(IssueNormalizer.IssueField.RULE_KEY.field()));
+    return RuleKey.parse((String) getField(IssueIndexDefinition.FIELD_ISSUE_RULE_KEY));
   }
 
   @Override
   public String language() {
-    return getField(IssueNormalizer.IssueField.LANGUAGE.field());
+    return getField(IssueIndexDefinition.FIELD_ISSUE_LANGUAGE);
   }
 
   @Override
   public String severity() {
-    return getField(IssueNormalizer.IssueField.SEVERITY.field());
+    return getField(IssueIndexDefinition.FIELD_ISSUE_SEVERITY);
   }
 
   @Override
   @CheckForNull
   public String message() {
-    return getNullableField(IssueNormalizer.IssueField.MESSAGE.field());
+    return getNullableField(IssueIndexDefinition.FIELD_ISSUE_MESSAGE);
   }
 
   @Override
   @CheckForNull
   public Integer line() {
-    return getNullableField(IssueNormalizer.IssueField.LINE.field());
+    return getNullableField(IssueIndexDefinition.FIELD_ISSUE_LINE);
   }
 
   @Override
   @CheckForNull
   public Double effortToFix() {
-    return getNullableField(IssueNormalizer.IssueField.EFFORT.field());
+    return getNullableField(IssueIndexDefinition.FIELD_ISSUE_EFFORT);
   }
 
   @Override
   public String status() {
-    return getField(IssueNormalizer.IssueField.STATUS.field());
+    return getField(IssueIndexDefinition.FIELD_ISSUE_STATUS);
   }
 
   @Override
   @CheckForNull
   public String resolution() {
-    return getNullableField(IssueNormalizer.IssueField.RESOLUTION.field());
+    return getNullableField(IssueIndexDefinition.FIELD_ISSUE_RESOLUTION);
   }
 
   @Override
   @CheckForNull
   public String reporter() {
-    return getNullableField(IssueNormalizer.IssueField.REPORTER.field());
+    return getNullableField(IssueIndexDefinition.FIELD_ISSUE_REPORTER);
   }
 
   @Override
   @CheckForNull
   public String assignee() {
-    return getNullableField(IssueNormalizer.IssueField.ASSIGNEE.field());
+    return getNullableField(IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE);
   }
 
+  /**
+   * Functional date
+   */
   @Override
   public Date creationDate() {
-    return getFieldAsDate(IssueNormalizer.IssueField.ISSUE_CREATED_AT.field());
+    return getFieldAsDate(IssueIndexDefinition.FIELD_ISSUE_FUNC_CREATED_AT);
   }
 
+  /**
+   * Functional date
+   */
   @Override
   public Date updateDate() {
-    return getFieldAsDate(IssueNormalizer.IssueField.ISSUE_UPDATED_AT.field());
+    return getFieldAsDate(IssueIndexDefinition.FIELD_ISSUE_FUNC_UPDATED_AT);
   }
 
   @Override
   @CheckForNull
   public Date closeDate() {
-    return getNullableFieldAsDate(IssueNormalizer.IssueField.ISSUE_CLOSE_DATE.field());
+    return getNullableFieldAsDate(IssueIndexDefinition.FIELD_ISSUE_FUNC_CLOSED_AT);
   }
 
   @Override
@@ -149,7 +155,7 @@ public class IssueDoc extends BaseDoc implements Issue {
 
   @Override
   public Map<String, String> attributes() {
-    String data = getNullableField(IssueNormalizer.IssueField.ATTRIBUTES.field());
+    String data = getNullableField(IssueIndexDefinition.FIELD_ISSUE_ATTRIBUTES);
     if (data == null) {
       return Collections.emptyMap();
     } else {
@@ -160,13 +166,13 @@ public class IssueDoc extends BaseDoc implements Issue {
   @Override
   @CheckForNull
   public String authorLogin() {
-    return getNullableField(IssueNormalizer.IssueField.AUTHOR_LOGIN.field());
+    return getNullableField(IssueIndexDefinition.FIELD_ISSUE_AUTHOR_LOGIN);
   }
 
   @Override
   @CheckForNull
   public String actionPlanKey() {
-    return getNullableField(IssueNormalizer.IssueField.ACTION_PLAN.field());
+    return getNullableField(IssueIndexDefinition.FIELD_ISSUE_ACTION_PLAN);
   }
 
   @Override
@@ -182,13 +188,13 @@ public class IssueDoc extends BaseDoc implements Issue {
   @Override
   @CheckForNull
   public Duration debt() {
-    Number debt = getNullableField(IssueNormalizer.IssueField.DEBT.field());
+    Number debt = getNullableField(IssueIndexDefinition.FIELD_ISSUE_DEBT);
     return (debt != null) ? Duration.create(debt.longValue()) : null;
   }
 
   @CheckForNull
   public String filePath() {
-    return getNullableField(IssueNormalizer.IssueField.FILE_PATH.field());
+    return getNullableField(IssueIndexDefinition.FIELD_ISSUE_FILE_PATH);
   }
 
   public void setKey(@Nullable String s) {
@@ -248,20 +254,20 @@ public class IssueDoc extends BaseDoc implements Issue {
     setField(IssueIndexDefinition.FIELD_ISSUE_ASSIGNEE, s);
   }
 
-  public void setCreationDate(@Nullable Date d) {
-    setField(IssueIndexDefinition.FIELD_ISSUE_CREATED_AT, d);
+  public void setTechnicalCreationDate(@Nullable Date d) {
+    setField(IssueIndexDefinition.FIELD_ISSUE_TECHNICAL_CREATED_AT, d);
   }
 
-  public void setUpdateDate(@Nullable Date d) {
-    setField(IssueIndexDefinition.FIELD_ISSUE_UPDATED_AT, d);
+  public void setFuncUpdateDate(@Nullable Date d) {
+    setField(IssueIndexDefinition.FIELD_ISSUE_FUNC_UPDATED_AT, d);
   }
 
   public void setFuncCreationDate(@Nullable Date d) {
     setField(IssueIndexDefinition.FIELD_ISSUE_FUNC_CREATED_AT, d);
   }
 
-  public void setFuncUpdateDate(@Nullable Date d) {
-    setField(IssueIndexDefinition.FIELD_ISSUE_FUNC_UPDATED_AT, d);
+  public void setTechnicalUpdateDate(@Nullable Date d) {
+    setField(IssueIndexDefinition.FIELD_ISSUE_TECHNICAL_UPDATED_AT, d);
   }
 
   public void setFuncCloseDate(@Nullable Date d) {
index 9dbb93980494a6c86a652af65485d5b7b26f59c6..aac89c4cc5f016d45c656220bff525fbc5d7ec27 100644 (file)
@@ -45,7 +45,6 @@ import org.elasticsearch.search.sort.SortBuilders;
 import org.elasticsearch.search.sort.SortOrder;
 import org.sonar.api.issue.Issue;
 import org.sonar.api.rule.Severity;
-import org.sonar.core.issue.db.IssueDto;
 import org.sonar.server.issue.IssueQuery;
 import org.sonar.server.issue.filter.IssueFilterParameters;
 import org.sonar.server.search.BaseIndex;
@@ -59,7 +58,6 @@ import org.sonar.server.search.StickyFacetBuilder;
 import org.sonar.server.user.UserSession;
 
 import javax.annotation.Nullable;
-
 import java.util.Collection;
 import java.util.Date;
 import java.util.List;
@@ -68,7 +66,7 @@ import java.util.Set;
 
 import static com.google.common.collect.Lists.newArrayList;
 
-public class IssueIndex extends BaseIndex<Issue, IssueDto, String> {
+public class IssueIndex extends BaseIndex<Issue, FakeIssueDto, String> {
 
   private static final String FACET_SUFFIX_MISSING = "_missing";
 
@@ -76,8 +74,8 @@ public class IssueIndex extends BaseIndex<Issue, IssueDto, String> {
 
   private ListMultimap<String, IndexField> sortColumns = ArrayListMultimap.create();
 
-  public IssueIndex(IssueNormalizer normalizer, SearchClient client) {
-    super(IndexDefinition.ISSUES, normalizer, client);
+  public IssueIndex(SearchClient client) {
+    super(IndexDefinition.ISSUES, null, client);
 
     sortColumns.put(IssueQuery.SORT_BY_ASSIGNEE, IssueNormalizer.IssueField.ASSIGNEE);
     sortColumns.put(IssueQuery.SORT_BY_STATUS, IssueNormalizer.IssueField.STATUS);
@@ -126,15 +124,6 @@ public class IssueIndex extends BaseIndex<Issue, IssueDto, String> {
     return null;
   }
 
-  @Override
-  protected FilterBuilder getLastSynchronizationBuilder(Map<String, String> params) {
-    String projectUuid = params.get(IssueNormalizer.IssueField.PROJECT.field());
-    if (projectUuid != null) {
-      return FilterBuilders.boolFilter().must(FilterBuilders.termsFilter(IssueNormalizer.IssueField.PROJECT.field(), projectUuid));
-    }
-    return super.getLastSynchronizationBuilder(params);
-  }
-
   public List<FacetValue> listAssignees(IssueQuery query) {
     QueryContext queryContext = new QueryContext().setPage(1, 0);
 
index e620fdab286ddb58da05e8e1b5d30309e6d8d28d..ca7d0d9ed961566e63d8f40b2a43d7e811bbdafd 100644 (file)
@@ -25,7 +25,6 @@ import org.sonar.api.config.Settings;
 import org.sonar.process.ProcessConstants;
 import org.sonar.server.es.IndexDefinition;
 import org.sonar.server.es.NewIndex;
-import org.sonar.server.search.BaseNormalizer;
 
 /**
  * Definition of ES index "issues", including settings and fields.
@@ -40,19 +39,31 @@ public class IssueIndexDefinition implements IndexDefinition {
   public static final String FIELD_AUTHORIZATION_PROJECT_UUID = "project";
   public static final String FIELD_AUTHORIZATION_GROUPS = "groups";
   public static final String FIELD_AUTHORIZATION_USERS = "users";
-  public static final String FIELD_AUTHORIZATION_UPDATED_AT = BaseNormalizer.UPDATED_AT_FIELD;
+  public static final String FIELD_AUTHORIZATION_UPDATED_AT = "updatedAt";
 
   public static final String FIELD_ISSUE_ACTION_PLAN = "actionPlan";
   public static final String FIELD_ISSUE_ASSIGNEE = "assignee";
   public static final String FIELD_ISSUE_ATTRIBUTES = "attributes";
   public static final String FIELD_ISSUE_AUTHOR_LOGIN = "authorLogin";
   public static final String FIELD_ISSUE_COMPONENT_UUID = "component";
-  public static final String FIELD_ISSUE_CREATED_AT = "createdAt";
+  /**
+   * Technical date
+   */
+  public static final String FIELD_ISSUE_TECHNICAL_CREATED_AT = "createdAt";
   public static final String FIELD_ISSUE_DEBT = "debt";
   public static final String FIELD_ISSUE_EFFORT = "effort";
   public static final String FIELD_ISSUE_FILE_PATH = "filePath";
+  /**
+   * Functional date
+   */
   public static final String FIELD_ISSUE_FUNC_CREATED_AT = "issueCreatedAt";
+  /**
+   * Functional date
+   */
   public static final String FIELD_ISSUE_FUNC_UPDATED_AT = "issueUpdatedAt";
+  /**
+   * Functional date
+   */
   public static final String FIELD_ISSUE_FUNC_CLOSED_AT = "issueClosedAt";
   public static final String FIELD_ISSUE_KEY = "key";
   public static final String FIELD_ISSUE_LANGUAGE = "language";
@@ -67,7 +78,10 @@ public class IssueIndexDefinition implements IndexDefinition {
   public static final String FIELD_ISSUE_SEVERITY = "severity";
   public static final String FIELD_ISSUE_SEVERITY_VALUE = "severityValue";
   public static final String FIELD_ISSUE_STATUS = "status";
-  public static final String FIELD_ISSUE_UPDATED_AT = "updatedAt";
+  /**
+   * Technical date
+   */
+  public static final String FIELD_ISSUE_TECHNICAL_UPDATED_AT = "updatedAt";
 
   private final Settings settings;
 
@@ -131,7 +145,7 @@ public class IssueIndexDefinition implements IndexDefinition {
     // TODO do we really sort by status ? If yes, then we should sort by "int value", but not by string key
     issueMapping.stringFieldBuilder(FIELD_ISSUE_STATUS).enableSorting().build();
     // TODO is createdAt required ?
-    issueMapping.createDateTimeField(FIELD_ISSUE_CREATED_AT);
-    issueMapping.createDateTimeField(FIELD_ISSUE_UPDATED_AT);
+    issueMapping.createDateTimeField(FIELD_ISSUE_TECHNICAL_CREATED_AT);
+    issueMapping.createDateTimeField(FIELD_ISSUE_TECHNICAL_UPDATED_AT);
   }
 }
index 493635b55311fa7607a29d9ab66bf479601bed75..e43df41dd98c2ac290144de53ff391bb1ba54d6f 100644 (file)
@@ -44,8 +44,21 @@ public class IssueIndexer extends BaseIndexer {
 
   @Override
   protected long doIndex(long lastUpdatedAt) {
-    final BulkIndexer bulk = createBulkIndexer(lastUpdatedAt == 0L);
+    return doIndex(createBulkIndexer(false), lastUpdatedAt);
+  }
+
+  public void indexAll() {
+    doIndex(createBulkIndexer(true), 0L);
+  }
 
+  /**
+   * For benchmarks
+   */
+  public void index(Iterator<IssueDoc> issues) {
+    doIndex(createBulkIndexer(false), issues);
+  }
+
+  private long doIndex(BulkIndexer bulk, long lastUpdatedAt) {
     DbSession dbSession = dbClient.openSession(false);
     Connection dbConnection = dbSession.getConnection();
     long maxDate;
@@ -61,12 +74,7 @@ public class IssueIndexer extends BaseIndexer {
     }
   }
 
-  public void index(Iterator<IssueDoc> issues) {
-    final BulkIndexer bulk = createBulkIndexer(false);
-    doIndex(bulk, issues);
-  }
-
-  long doIndex(BulkIndexer bulk, Iterator<IssueDoc> issues) {
+  private long doIndex(BulkIndexer bulk, Iterator<IssueDoc> issues) {
     bulk.start();
     long maxDate = 0L;
     while (issues.hasNext()) {
index 490e9025b4be30c79348a01b1bac3d2c2200fceb..1ff008e91be9c2e87209d9f7e71593c05cecddc9 100644 (file)
  */
 package org.sonar.server.issue.index;
 
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
 import org.elasticsearch.action.update.UpdateRequest;
-import org.sonar.api.rule.Severity;
-import org.sonar.core.issue.db.IssueDto;
+import org.sonar.core.persistence.Dto;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.search.BaseNormalizer;
 import org.sonar.server.search.IndexField;
 import org.sonar.server.search.Indexable;
 
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
-import static com.google.common.collect.Maps.newHashMap;
-
-public class IssueNormalizer extends BaseNormalizer<IssueDto, String> {
+public class IssueNormalizer extends BaseNormalizer {
 
   public IssueNormalizer(DbClient db) {
     super(db);
   }
 
+  @Override
+  public List<UpdateRequest> normalize(Dto dto) {
+    throw new UnsupportedOperationException();
+  }
+
   public static final class IssueField extends Indexable {
 
     public static final IndexField KEY = addSortable(IndexField.Type.STRING, "key");
@@ -72,60 +69,6 @@ public class IssueNormalizer extends BaseNormalizer<IssueDto, String> {
     public static final IndexField LANGUAGE = add(IndexField.Type.STRING, "language");
     public static final IndexField RULE_KEY = add(IndexField.Type.STRING, "ruleKey");
     public static final IndexField FILE_PATH = addSortable(IndexField.Type.STRING, "filePath");
-
-    public static final Set<IndexField> ALL_FIELDS = ImmutableSet.of(KEY, CREATED_AT, UPDATED_AT, PROJECT, COMPONENT,
-      MODULE, MODULE_PATH, ACTION_PLAN, ASSIGNEE, ATTRIBUTES, AUTHOR_LOGIN, DEBT, EFFORT, ISSUE_CREATED_AT,
-      ISSUE_UPDATED_AT, ISSUE_CLOSE_DATE, LINE, MESSAGE, RESOLUTION, REPORTER, STATUS, SEVERITY, SEVERITY_VALUE,
-      LANGUAGE, RULE_KEY, FILE_PATH);
   }
 
-  @Override
-  public List<UpdateRequest> normalize(IssueDto dto) {
-    Map<String, Object> update = newHashMap();
-
-    Preconditions.checkNotNull(dto.getProjectUuid(), "Project uuid is null on issue %s", dto.getKey());
-    Preconditions.checkNotNull(dto.getComponentUuid(), "Component uuid is null on issue %s", dto.getKey());
-
-    update.put("_parent", dto.getProjectUuid());
-    update.put(IssueField.KEY.field(), dto.getKey());
-    update.put(IssueField.UPDATED_AT.field(), dto.getUpdatedAt());
-    update.put(IssueField.CREATED_AT.field(), dto.getCreatedAt());
-
-    update.put(IssueField.PROJECT.field(), dto.getProjectUuid());
-    update.put(IssueField.COMPONENT.field(), dto.getComponentUuid());
-    update.put(IssueField.MODULE.field(), dto.getModuleUuid());
-    update.put(IssueField.MODULE_PATH.field(), dto.getModuleUuidPath());
-
-    update.put(IssueField.ACTION_PLAN.field(), dto.getActionPlanKey());
-    update.put(IssueField.ATTRIBUTES.field(), dto.getIssueAttributes());
-    update.put(IssueField.ASSIGNEE.field(), dto.getAssignee());
-    update.put(IssueField.AUTHOR_LOGIN.field(), dto.getAuthorLogin());
-    update.put(IssueField.ISSUE_CLOSE_DATE.field(), dto.getIssueCloseDate());
-    update.put(IssueField.ISSUE_CREATED_AT.field(), dto.getIssueCreationDate());
-    update.put(IssueField.ISSUE_UPDATED_AT.field(), dto.getIssueUpdateDate());
-    update.put(IssueField.EFFORT.field(), dto.getEffortToFix());
-    update.put(IssueField.RESOLUTION.field(), dto.getResolution());
-    update.put(IssueField.LINE.field(), dto.getLine());
-    update.put(IssueField.MESSAGE.field(), dto.getMessage());
-    update.put(IssueField.REPORTER.field(), dto.getReporter());
-    update.put(IssueField.STATUS.field(), dto.getStatus());
-    update.put(IssueField.SEVERITY.field(), dto.getSeverity());
-    update.put(IssueField.SEVERITY_VALUE.field(), Severity.ALL.indexOf(dto.getSeverity()));
-    update.put(IssueField.DEBT.field(), dto.getDebt());
-    update.put(IssueField.LANGUAGE.field(), dto.getLanguage());
-    update.put(IssueField.RULE_KEY.field(), dto.getRuleKey().toString());
-    update.put(IssueField.FILE_PATH.field(), dto.getFilePath());
-
-    /** Upsert elements */
-    Map<String, Object> upsert = getUpsertFor(IssueField.ALL_FIELDS, update);
-    upsert.put(IssueField.KEY.field(), dto.getKey());
-
-    return ImmutableList.of(
-      new UpdateRequest()
-        .id(dto.getKey())
-        .routing(dto.getProjectUuid())
-        .parent(dto.getProjectUuid())
-        .doc(update)
-        .upsert(upsert));
-  }
 }
index 9b79ee9b68ef26774a835517a3af6a4885d0a954..3e0a962b78f289168ee0f33e857e0a551121453b 100644 (file)
@@ -30,7 +30,6 @@ import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.sql.Timestamp;
 import java.util.Date;
 
 /**
@@ -85,7 +84,7 @@ class IssueResultSetIterator extends ResultSetIterator<IssueDoc> {
       String sql = afterDate > 0L ? SQL_AFTER_DATE : SQL_ALL;
       PreparedStatement stmt = dbClient.newScrollingSelectStatement(connection, sql);
       if (afterDate > 0L) {
-        stmt.setTimestamp(1, new Timestamp(afterDate));
+        stmt.setLong(1, afterDate);
       }
       return new IssueResultSetIterator(stmt);
     } catch (SQLException e) {
@@ -107,8 +106,8 @@ class IssueResultSetIterator extends ResultSetIterator<IssueDoc> {
     // all the keys must be present, even if value is null
     doc.setKey(key);
     doc.setProjectUuid(projectUuid);
-    doc.setUpdateDate(SqlUtil.getDate(rs, 3));
-    doc.setCreationDate(new Date(rs.getTimestamp(4).getTime()));
+    doc.setTechnicalUpdateDate(new Date(rs.getLong(3)));
+    doc.setTechnicalCreationDate(new Date(rs.getLong(4)));
     doc.setActionPlanKey(rs.getString(5));
     doc.setAssignee(rs.getString(6));
     doc.setEffortToFix(SqlUtil.getDouble(rs, 7));
index cbeb9db3bd126ce568d072b633f83ea9026abed9..f6623cd3717bcf4bf4cf19785286cc752e26df7e 100644 (file)
@@ -19,7 +19,6 @@
  */
 package org.sonar.server.search;
 
-import com.google.common.collect.ImmutableMap;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.core.persistence.DbSession;
@@ -27,15 +26,12 @@ import org.sonar.server.activity.index.ActivityIndex;
 import org.sonar.server.db.Dao;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.issue.index.IssueAuthorizationIndexer;
-import org.sonar.server.issue.index.IssueIndex;
-import org.sonar.server.issue.index.IssueNormalizer;
+import org.sonar.server.issue.index.IssueIndexer;
 import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
 import org.sonar.server.rule.index.RuleIndex;
 import org.sonar.server.source.index.SourceLineIndexer;
 
 import java.util.Date;
-import java.util.List;
-import java.util.Map;
 
 /**
  * @since 4.4
@@ -48,28 +44,30 @@ public class IndexSynchronizer {
   private final IndexClient index;
   private final SourceLineIndexer sourceLineIndexer;
   private final IssueAuthorizationIndexer issueAuthorizationIndexer;
+  private final IssueIndexer issueIndexer;
 
   public IndexSynchronizer(DbClient db, IndexClient index, SourceLineIndexer sourceLineIndexer,
-                           IssueAuthorizationIndexer issueAuthorizationIndexer) {
+                           IssueAuthorizationIndexer issueAuthorizationIndexer, IssueIndexer issueIndexer) {
     this.db = db;
     this.index = index;
     this.sourceLineIndexer = sourceLineIndexer;
     this.issueAuthorizationIndexer = issueAuthorizationIndexer;
+    this.issueIndexer = issueIndexer;
   }
 
   public void execute() {
     /* synchronize all activeRules until we have mng tables in INDEX */
     DbSession session = db.openSession(true);
     try {
-      List<String> projectUuids = db.componentDao().findProjectUuids(session);
       synchronize(session, db.ruleDao(), index.get(RuleIndex.class));
-      issueAuthorizationIndexer.index();
-      synchronizeByProject(session, db.issueDao(), index.get(IssueIndex.class),
-        IssueNormalizer.IssueField.PROJECT.field(), projectUuids);
       synchronize(session, db.activeRuleDao(), index.get(ActiveRuleIndex.class));
       synchronize(session, db.activityDao(), index.get(ActivityIndex.class));
 
-      LOG.info("Indexing of sourceLine records");
+      LOG.info("Indexing issues");
+      issueAuthorizationIndexer.index();
+      issueIndexer.indexAll();
+
+      LOG.info("Indexing source files");
       sourceLineIndexer.index();
 
       session.commit();
@@ -89,18 +87,4 @@ public class IndexSynchronizer {
       dao.synchronizeAfter(session, lastSynch);
     }
   }
-
-  void synchronizeByProject(DbSession session, Dao dao, Index index, String projectField, List<String> projectUuids) {
-    Long count = index.getIndexStat().getDocumentCount();
-    if (count <= 0) {
-      LOG.info("Initial indexing of {} records", index.getIndexType());
-      dao.synchronizeAfter(session);
-    } else {
-      LOG.info("Synchronizing {} records for updates", index.getIndexType());
-      for (String projectUuid : projectUuids) {
-        Map<String, String> params = ImmutableMap.of(projectField, projectUuid);
-        dao.synchronizeAfter(session, index.getLastSynchronization(params), params);
-      }
-    }
-  }
 }
index 20866fbe3100ce89213c149dea166562a34a71e2..de5149cb00f3169bd605dc2853180f53bec1e957 100644 (file)
@@ -37,6 +37,7 @@ import org.sonar.server.issue.index.IssueIndexDefinition;
 import org.sonar.server.issue.IssueTesting;
 import org.sonar.server.issue.db.IssueDao;
 import org.sonar.server.issue.index.IssueIndex;
+import org.sonar.server.issue.index.IssueIndexer;
 import org.sonar.server.permission.InternalPermissionService;
 import org.sonar.server.permission.PermissionChange;
 import org.sonar.server.rule.RuleTesting;
@@ -115,6 +116,7 @@ public class ComponentCleanerServiceMediumTest {
 
     tester.get(IssueDao.class).insert(session, IssueTesting.newDto(rule, file, project));
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     assertThat(tester.get(IssueIndex.class).countAll()).isEqualTo(1);
 
index b351e374bf8b723c36ea4e08577d9681b882439e..adeb8d1370973a3326259330eb7f5dd5e17b695d 100644 (file)
@@ -27,21 +27,16 @@ import org.junit.Test;
 import org.sonar.api.security.DefaultGroups;
 import org.sonar.api.web.UserRole;
 import org.sonar.core.component.ComponentDto;
-import org.sonar.core.issue.db.IssueDto;
 import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.rule.RuleDto;
 import org.sonar.server.component.db.ComponentDao;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.issue.IssueTesting;
-import org.sonar.server.issue.index.IssueIndex;
 import org.sonar.server.permission.InternalPermissionService;
 import org.sonar.server.permission.PermissionChange;
 import org.sonar.server.rule.RuleTesting;
 import org.sonar.server.rule.db.RuleDao;
-import org.sonar.server.search.IndexDefinition;
-import org.sonar.server.search.SearchClient;
 import org.sonar.server.tester.ServerTester;
 import org.sonar.server.user.MockUserSession;
 
@@ -113,9 +108,6 @@ public class ComponentServiceMediumTest {
     ComponentDto file = ComponentTesting.newFileDto(project).setKey("sample:root:src/File.xoo");
     tester.get(ComponentDao.class).insert(session, file);
 
-    IssueDto issue = IssueTesting.newDto(rule, file, project);
-    db.issueDao().insert(session, issue);
-
     session.commit();
 
     MockUserSession.set().setLogin("john").addComponentPermission(UserRole.ADMIN, project.key(), project.key());
@@ -130,13 +122,6 @@ public class ComponentServiceMediumTest {
     assertThat(service.getNullableByKey(file.key())).isNull();
     assertThat(service.getNullableByKey("sample2:root:src/File.xoo")).isNotNull();
 
-    // Check issues are still here
-    assertThat(tester.get(IssueIndex.class).getNullableByKey(issue.getKey()).componentUuid()).isEqualTo(file.uuid());
-    assertThat(tester.get(IssueIndex.class).getNullableByKey(issue.getKey()).projectUuid()).isEqualTo(project.uuid());
-
-    // Check that no new issue has been added
-    assertThat(tester.get(SearchClient.class).prepareCount(IndexDefinition.ISSUES.getIndexName()).setTypes(IndexDefinition.ISSUES.getIndexType()).get().getCount()).isEqualTo(1);
-
     // Check dry run cache have been updated
     assertThat(db.propertiesDao().selectProjectProperties("sample2:root", session)).hasSize(1);
   }
@@ -149,9 +134,6 @@ public class ComponentServiceMediumTest {
     ComponentDto file = ComponentTesting.newFileDto(module).setKey("sample:root:module:src/File.xoo");
     tester.get(ComponentDao.class).insert(session, file);
 
-    IssueDto issue = IssueTesting.newDto(rule, file, project);
-    db.issueDao().insert(session, issue);
-
     session.commit();
 
     MockUserSession.set().setLogin("john").addComponentPermission(UserRole.ADMIN, project.key(), module.key());
@@ -169,10 +151,6 @@ public class ComponentServiceMediumTest {
     assertThat(service.getNullableByKey(file.key())).isNull();
     assertThat(service.getNullableByKey("sample:root2:module:src/File.xoo")).isNotNull();
 
-    // Check issues are still here
-    assertThat(tester.get(IssueIndex.class).getNullableByKey(issue.getKey()).componentUuid()).isEqualTo(file.uuid());
-    assertThat(tester.get(IssueIndex.class).getNullableByKey(issue.getKey()).projectUuid()).isEqualTo(project.uuid());
-
     // Check dry run cache have been updated -> on a module it's the project cache that is updated
     assertThat(db.propertiesDao().selectProjectProperties(project.key(), session)).hasSize(1);
   }
@@ -252,9 +230,6 @@ public class ComponentServiceMediumTest {
     ComponentDto file = ComponentTesting.newFileDto(module).setKey("sample:root:module:src/File.xoo");
     tester.get(ComponentDao.class).insert(session, file);
 
-    IssueDto issue = IssueTesting.newDto(rule, file, project);
-    db.issueDao().insert(session, issue);
-
     session.commit();
 
     MockUserSession.set().setLogin("john").addProjectPermissions(UserRole.ADMIN, project.key());
@@ -273,13 +248,6 @@ public class ComponentServiceMediumTest {
     assertThat(service.getNullableByKey(file.key())).isNull();
     assertThat(service.getNullableByKey("sample2:root:module:src/File.xoo")).isNotNull();
 
-    // Check issues are still here
-    assertThat(tester.get(IssueIndex.class).getNullableByKey(issue.getKey()).componentUuid()).isEqualTo(file.uuid());
-    assertThat(tester.get(IssueIndex.class).getNullableByKey(issue.getKey()).projectUuid()).isEqualTo(project.uuid());
-
-    // Check that no new issue has been added
-    assertThat(tester.get(SearchClient.class).prepareCount(IndexDefinition.ISSUES.getIndexName()).setTypes(IndexDefinition.ISSUES.getIndexType()).get().getCount()).isEqualTo(1);
-
     // Check dry run cache have been updated
     assertThat(db.propertiesDao().selectProjectProperties("sample2:root", session)).hasSize(1);
   }
index 708ca0cbad6679127148558727cc914c7cd9d6e7..4f1da87acaf167c747481e7401b6829c0b1048e1 100644 (file)
@@ -44,6 +44,23 @@ public class ComponentTesting {
       .setEnabled(true);
   }
 
+  public static ComponentDto newFileDto(ComponentDto module, String fileUuid) {
+    return new ComponentDto()
+      .setUuid(fileUuid)
+      .setProjectUuid(module.projectUuid())
+      .setModuleUuid(module.uuid())
+      .setModuleUuidPath(module.moduleUuidPath() == null ? module.uuid() : module.moduleUuidPath() + "." + module.uuid())
+      .setKey("KEY_" + fileUuid)
+      .setName("NAME_" + fileUuid)
+      .setLongName("LONG_NAME_" + fileUuid)
+      .setParentProjectId(module.getId())
+      .setScope(Scopes.FILE)
+      .setQualifier(Qualifiers.FILE)
+      .setPath("src/main/xoo/org/sonar/samples/File.xoo")
+      .setLanguage("xoo")
+      .setEnabled(true);
+  }
+
   public static ComponentDto newModuleDto(ComponentDto subProjectOrProject) {
     return new ComponentDto()
       .setUuid(Uuids.create())
@@ -77,4 +94,18 @@ public class ComponentTesting {
       .setEnabled(true);
   }
 
+  public static ComponentDto newProjectDto(String uuid) {
+    return new ComponentDto()
+      .setUuid(uuid)
+      .setProjectUuid(uuid)
+      .setKey("KEY_" + uuid)
+      .setName("NAME_" + uuid)
+      .setLongName("LONG_NAME_" + uuid)
+      .setParentProjectId(null)
+      .setScope(Scopes.PROJECT)
+      .setQualifier(Qualifiers.PROJECT)
+      .setPath(null)
+      .setLanguage(null)
+      .setEnabled(true);
+  }
 }
diff --git a/server/sonar-server/src/test/java/org/sonar/server/db/migrations/v50/FeedIssueLongDatesTest.java b/server/sonar-server/src/test/java/org/sonar/server/db/migrations/v50/FeedIssueLongDatesTest.java
new file mode 100644 (file)
index 0000000..91d47c7
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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.db.migrations.v50;
+
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.core.persistence.TestDatabase;
+import org.sonar.server.db.migrations.DatabaseMigration;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class FeedIssueLongDatesTest {
+
+  @ClassRule
+  public static TestDatabase db = new TestDatabase().schema(FeedIssueLongDatesTest.class, "schema.sql");
+
+  @Test
+  public void execute() throws Exception {
+    db.prepareDbUnit(getClass(), "before.xml");
+
+    System2 system = mock(System2.class);
+    when(system.now()).thenReturn(1500000000000L);
+    DatabaseMigration migration = new FeedIssueLongDates(db.database(), system);
+    migration.execute();
+
+    int count = db.count("select count(*) from issues where created_at_ms is not null and updated_at_ms is not null");
+    assertThat(count).isEqualTo(2);
+  }
+
+}
index 820a5c989ac3436c867d2136de7e6efcc0092f6e..345c68639f7f8fe3f238a28b534f523563107a26 100644 (file)
@@ -32,7 +32,6 @@ import org.sonar.api.web.UserRole;
 import org.sonar.core.component.ComponentDto;
 import org.sonar.core.issue.db.IssueDto;
 import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.core.permission.PermissionFacade;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.rule.RuleDto;
 import org.sonar.core.user.UserDto;
@@ -42,6 +41,7 @@ import org.sonar.server.component.db.ComponentDao;
 import org.sonar.server.component.db.SnapshotDao;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.issue.db.IssueDao;
+import org.sonar.server.issue.index.IssueIndexer;
 import org.sonar.server.permission.InternalPermissionService;
 import org.sonar.server.permission.PermissionChange;
 import org.sonar.server.rule.RuleTesting;
@@ -50,7 +50,6 @@ import org.sonar.server.tester.ServerTester;
 import org.sonar.server.user.MockUserSession;
 import org.sonar.server.user.UserSession;
 
-import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
@@ -115,6 +114,7 @@ public class IssueBulkChangeServiceMediumTest {
     IssueDto issue2 = IssueTesting.newDto(rule, file, project).setAssignee("simon");
     tester.get(IssueDao.class).insert(session, issue1, issue2);
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     Map<String, Object> properties = newHashMap();
     properties.put("issues", issue1.getKey() + "," + issue2.getKey());
@@ -136,6 +136,7 @@ public class IssueBulkChangeServiceMediumTest {
       issueKeys.add(issue.getKey());
     }
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     Map<String, Object> properties = newHashMap();
     properties.put("issues", Joiner.on(",").join(issueKeys));
index 147efc9ac91604e71561025c734ea40160a4cadc..75bb47d6536f215fa3092c0313b28fe7206d5539 100644 (file)
@@ -114,7 +114,7 @@ public class IssueBulkChangeServiceTest {
     org.sonar.server.search.Result<Issue> result = mock(org.sonar.server.search.Result.class);
     when(result.getHits()).thenReturn(newArrayList((Issue) issue));
     when(issueService.search(any(IssueQuery.class), any(QueryContext.class))).thenReturn(result);
-    when(issueDao.getByKeys(dbSession, newArrayList(issue.key()))).thenReturn(newArrayList(issueDto));
+    when(issueDao.selectByKeys(dbSession, newArrayList(issue.key()))).thenReturn(newArrayList(issueDto));
 
     actions = newArrayList();
     service = new IssueBulkChangeService(dbClient, issueService, issueStorage, ruleFinder, issueNotifications, actions, mock(PreviewCache.class));
@@ -189,7 +189,7 @@ public class IssueBulkChangeServiceTest {
     org.sonar.server.search.Result<Issue> resultIssues = mock(org.sonar.server.search.Result.class);
     when(resultIssues.getHits()).thenReturn(Lists.<Issue>newArrayList(issueDto1.toDefaultIssue(), issueDto2.toDefaultIssue()));
     when(issueService.search(any(IssueQuery.class), any(QueryContext.class))).thenReturn(resultIssues);
-    when(issueDao.getByKeys(dbSession, newArrayList("ABCD", "EFGH"))).thenReturn(newArrayList(issueDto1, issueDto2));
+    when(issueDao.selectByKeys(dbSession, newArrayList("ABCD", "EFGH"))).thenReturn(newArrayList(issueDto1, issueDto2));
 
     Map<String, Object> properties = newHashMap();
     properties.put("issues", "ABCD,EFGH");
index b1807af3a8757a42959e67fe29150091d4ad08f2..1b1fa83bcdff8a0a48f747dcf490d1cf99e61a92 100644 (file)
@@ -33,7 +33,6 @@ import org.sonar.api.web.UserRole;
 import org.sonar.core.component.ComponentDto;
 import org.sonar.core.issue.db.IssueDto;
 import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.core.permission.PermissionFacade;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.rule.RuleDto;
 import org.sonar.server.component.ComponentTesting;
@@ -42,6 +41,7 @@ import org.sonar.server.component.db.ComponentDao;
 import org.sonar.server.component.db.SnapshotDao;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.issue.db.IssueDao;
+import org.sonar.server.issue.index.IssueIndexer;
 import org.sonar.server.permission.InternalPermissionService;
 import org.sonar.server.permission.PermissionChange;
 import org.sonar.server.rule.RuleTesting;
@@ -50,7 +50,6 @@ import org.sonar.server.search.IndexClient;
 import org.sonar.server.tester.ServerTester;
 import org.sonar.server.user.MockUserSession;
 
-import java.util.Date;
 import java.util.List;
 
 import static org.fest.assertions.Assertions.assertThat;
@@ -108,6 +107,7 @@ public class IssueCommentServiceMediumTest {
     IssueDto issue = IssueTesting.newDto(rule, file, project);
     tester.get(IssueDao.class).insert(session, issue);
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     service.addComment(issue.getKey(), "my comment", MockUserSession.get());
 
@@ -124,6 +124,7 @@ public class IssueCommentServiceMediumTest {
     IssueDto issue = IssueTesting.newDto(removedRule, file, project).setStatus(Issue.STATUS_CLOSED).setResolution(Issue.RESOLUTION_REMOVED);
     tester.get(IssueDao.class).insert(session, issue);
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     service.addComment(issue.getKey(), "my comment", MockUserSession.get());
 
index e0f895ffdfe697d7e3cf9f83cfad046503548e4a..47668c6c9638184b80062c08e77a282e18a3c050 100644 (file)
@@ -49,6 +49,7 @@ import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.issue.db.IssueDao;
 import org.sonar.server.issue.index.IssueDoc;
 import org.sonar.server.issue.index.IssueIndex;
+import org.sonar.server.issue.index.IssueIndexer;
 import org.sonar.server.permission.InternalPermissionService;
 import org.sonar.server.permission.PermissionChange;
 import org.sonar.server.rule.RuleTesting;
@@ -59,7 +60,6 @@ import org.sonar.server.tester.ServerTester;
 import org.sonar.server.user.MockUserSession;
 
 import java.util.Arrays;
-import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
@@ -122,11 +122,16 @@ public class IssueServiceMediumTest {
     session.close();
   }
 
+  private void index() {
+    tester.get(IssueIndexer.class).indexAll();
+  }
+
   @Test
   public void get_by_key() throws Exception {
     IssueDto issue = newIssue();
     tester.get(IssueDao.class).insert(session, issue);
     session.commit();
+    index();
 
     assertThat(service.getByKey(issue.getKey())).isNotNull();
   }
@@ -137,6 +142,7 @@ public class IssueServiceMediumTest {
     IssueDto issue2 = newIssue().setActionPlanKey("P2").setResolution("NONE");
     tester.get(IssueDao.class).insert(session, issue1, issue2);
     session.commit();
+    index();
 
     org.sonar.server.search.Result<Issue> result = service.search(IssueQuery.builder().build(), new QueryContext());
     assertThat(result.getHits()).hasSize(2);
@@ -158,6 +164,7 @@ public class IssueServiceMediumTest {
     IssueDto issue = newIssue().setStatus(Issue.STATUS_RESOLVED).setResolution(Issue.RESOLUTION_FALSE_POSITIVE);
     tester.get(IssueDao.class).insert(session, issue);
     session.commit();
+    index();
 
     List<Transition> result = service.listTransitions(issue.getKey());
     assertThat(result).hasSize(1);
@@ -169,8 +176,9 @@ public class IssueServiceMediumTest {
     IssueDto issue = newIssue().setStatus(Issue.STATUS_OPEN);
     tester.get(IssueDao.class).insert(session, issue);
     session.commit();
+    index();
 
-    assertThat(db.issueDao().getByKey(session, issue.getKey())).isNotNull();
+    assertThat(db.issueDao().selectByKey(session, issue.getKey())).isNotNull();
     IssueTesting.assertIsEquivalent(issue, (IssueDoc) indexClient.get(IssueIndex.class).getByKey(issue.getKey()));
 
     assertThat(indexClient.get(IssueIndex.class).getByKey(issue.getKey()).status()).isEqualTo(Issue.STATUS_OPEN);
@@ -188,6 +196,7 @@ public class IssueServiceMediumTest {
     UserDto user = new UserDto().setLogin("perceval").setName("Perceval");
     db.userDao().insert(session, user);
     session.commit();
+    index();
 
     assertThat(indexClient.get(IssueIndex.class).getByKey(issue.getKey()).assignee()).isNull();
 
@@ -197,13 +206,14 @@ public class IssueServiceMediumTest {
   }
 
   @Test
-  public void un_assign() {
+  public void unassign() {
     IssueDto issue = newIssue().setAssignee("perceval");
     tester.get(IssueDao.class).insert(session, issue);
 
     UserDto user = new UserDto().setLogin("perceval").setName("Perceval");
     db.userDao().insert(session, user);
     session.commit();
+    index();
 
     assertThat(indexClient.get(IssueIndex.class).getByKey(issue.getKey()).assignee()).isEqualTo("perceval");
 
@@ -217,6 +227,7 @@ public class IssueServiceMediumTest {
     IssueDto issue = newIssue();
     tester.get(IssueDao.class).insert(session, issue);
     session.commit();
+    index();
 
     try {
       service.assign(issue.getKey(), "unknown");
@@ -234,6 +245,7 @@ public class IssueServiceMediumTest {
     String actionPlanKey = "EFGH";
     db.actionPlanDao().save(new ActionPlanDto().setKey(actionPlanKey).setProjectId(project.getId()));
     session.commit();
+    index();
 
     assertThat(indexClient.get(IssueIndex.class).getByKey(issue.getKey()).actionPlanKey()).isNull();
 
@@ -250,6 +262,7 @@ public class IssueServiceMediumTest {
     IssueDto issue = newIssue().setActionPlanKey(actionPlanKey);
     tester.get(IssueDao.class).insert(session, issue);
     session.commit();
+    index();
 
     assertThat(indexClient.get(IssueIndex.class).getByKey(issue.getKey()).actionPlanKey()).isEqualTo(actionPlanKey);
 
@@ -262,6 +275,7 @@ public class IssueServiceMediumTest {
   public void fail_plan_if_action_plan_not_found() {
     tester.get(IssueDao.class).insert(session, newIssue());
     session.commit();
+    index();
 
     try {
       service.plan("ABCD", "unknown");
@@ -276,6 +290,7 @@ public class IssueServiceMediumTest {
     IssueDto issue = newIssue().setSeverity(Severity.BLOCKER);
     tester.get(IssueDao.class).insert(session, issue);
     session.commit();
+    index();
 
     assertThat(indexClient.get(IssueIndex.class).getByKey(issue.getKey()).severity()).isEqualTo(Severity.BLOCKER);
 
@@ -387,6 +402,7 @@ public class IssueServiceMediumTest {
     IssueDto issue = newIssue();
     tester.get(IssueDao.class).insert(session, issue);
     session.commit();
+    index();
 
     List<Issue> result = service.search(IssueQuery.builder().build(), new QueryContext()).getHits();
     assertThat(result).hasSize(1);
@@ -400,6 +416,7 @@ public class IssueServiceMediumTest {
       IssueTesting.newDto(rule, file, project),
       IssueTesting.newDto(rule, file, project).setAssignee("steph"));
     session.commit();
+    index();
 
     Map<String, Long> results = service.findIssueAssignees(IssueQuery.builder().build());
 
index be19b18af402b4e1c243add63afb9a0c2ef907bf..48947ea610aab00170ed5547f722e779542614f0 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.server.issue;
 
+import com.google.common.collect.Maps;
 import org.sonar.api.issue.Issue;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rule.Severity;
@@ -29,6 +30,7 @@ import org.sonar.core.component.ComponentDto;
 import org.sonar.core.issue.db.IssueDto;
 import org.sonar.core.rule.RuleDto;
 import org.sonar.server.issue.index.IssueDoc;
+import org.sonar.server.rule.RuleTesting;
 
 import static org.fest.assertions.Assertions.assertThat;
 
@@ -53,7 +55,39 @@ public class IssueTesting {
       .setSeverity(Severity.MAJOR)
       .setDebt(10L)
       .setIssueCreationDate(DateUtils.parseDate("2014-09-04"))
-      .setIssueUpdateDate(DateUtils.parseDate("2014-12-04"));
+      .setIssueUpdateDate(DateUtils.parseDate("2014-12-04"))
+      .setCreatedAt(1400000000000L)
+      .setUpdatedAt(1400000000000L);
+  }
+
+  public static IssueDoc newDoc() {
+    IssueDoc doc = new IssueDoc(Maps.<String, Object>newHashMap());
+    doc.setKey("ABC");
+    doc.setRuleKey(RuleTesting.XOO_X1.toString());
+    doc.setActionPlanKey(null);
+    doc.setReporter(null);
+    doc.setAssignee("steve");
+    doc.setAuthorLogin("roger");
+    doc.setLanguage("xoo");
+    doc.setComponentUuid("FILE_1");
+    doc.setEffortToFix(3.14);
+    doc.setFilePath("src/Foo.xoo");
+    doc.setMessage("the message");
+    doc.setModuleUuid("MODULE_1");
+    doc.setModuleUuidPath("MODULE_1");
+    doc.setProjectUuid("PROJECT_1");
+    doc.setLine(42);
+    doc.setAttributes(null);
+    doc.setStatus(Issue.STATUS_OPEN);
+    doc.setResolution(null);
+    doc.setSeverity(Severity.MAJOR);
+    doc.setDebt(10L);
+    doc.setFuncCreationDate(DateUtils.parseDate("2014-09-04"));
+    doc.setFuncUpdateDate(DateUtils.parseDate("2014-12-04"));
+    doc.setFuncCloseDate(null);
+    doc.setTechnicalCreationDate(DateUtils.parseDate("2014-09-04"));
+    doc.setTechnicalUpdateDate(DateUtils.parseDate("2014-12-04"));
+    return doc;
   }
 
   public static void assertIsEquivalent(IssueDto dto, IssueDoc issue) {
index 044c2d529db1b99e291e6b863d2648a40d9c1d85..d4206b240130e78905f8c6dbfd5d5210ccb2afbe 100644 (file)
@@ -39,11 +39,14 @@ import org.sonar.core.resource.ResourceDao;
 import org.sonar.server.component.db.ComponentDao;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.issue.db.IssueDao;
+import org.sonar.server.issue.index.IssueIndexer;
 
 import java.util.Collection;
 import java.util.Date;
 
 import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public class ServerIssueStorageTest extends AbstractDaoTestCase {
 
@@ -54,13 +57,15 @@ public class ServerIssueStorageTest extends AbstractDaoTestCase {
 
   @Before
   public void setupDbClient() {
+    System2 system = mock(System2.class);
+    when(system.now()).thenReturn(2000000000L);
     dbClient = new DbClient(getDatabase(), getMyBatis(),
-      new ComponentDao(System2.INSTANCE),
-      new IssueDao(System2.INSTANCE),
-      new ResourceDao(getMyBatis(), System2.INSTANCE));
+      new ComponentDao(system),
+      new IssueDao(getMyBatis()),
+      new ResourceDao(getMyBatis(), system));
     session = dbClient.openSession(false);
 
-    storage = new ServerIssueStorage(getMyBatis(), new FakeRuleFinder(), dbClient);
+    storage = new ServerIssueStorage(getMyBatis(), new FakeRuleFinder(), dbClient, mock(IssueIndexer.class));
   }
 
   @After
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueBackendMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/db/IssueBackendMediumTest.java
deleted file mode 100644 (file)
index df16d65..0000000
+++ /dev/null
@@ -1,123 +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.issue.db;
-
-import com.google.common.collect.ImmutableMap;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Test;
-import org.sonar.api.issue.Issue;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.security.DefaultGroups;
-import org.sonar.api.utils.KeyValueFormat;
-import org.sonar.api.web.UserRole;
-import org.sonar.core.component.ComponentDto;
-import org.sonar.core.issue.db.IssueDto;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.core.persistence.DbSession;
-import org.sonar.core.rule.RuleDto;
-import org.sonar.server.component.ComponentTesting;
-import org.sonar.server.component.db.ComponentDao;
-import org.sonar.server.db.DbClient;
-import org.sonar.server.issue.IssueTesting;
-import org.sonar.server.issue.index.IssueIndex;
-import org.sonar.server.permission.InternalPermissionService;
-import org.sonar.server.permission.PermissionChange;
-import org.sonar.server.rule.RuleTesting;
-import org.sonar.server.rule.db.RuleDao;
-import org.sonar.server.search.IndexClient;
-import org.sonar.server.tester.ServerTester;
-import org.sonar.server.user.MockUserSession;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class IssueBackendMediumTest {
-
-  @ClassRule
-  public static ServerTester tester = new ServerTester();
-
-  DbClient dbClient;
-  IndexClient indexClient;
-  DbSession dbSession;
-
-  @Before
-  public void setUp() throws Exception {
-    dbClient = tester.get(DbClient.class);
-    indexClient = tester.get(IndexClient.class);
-    dbSession = dbClient.openSession(false);
-    tester.clearDbAndIndexes();
-  }
-
-  @After
-  public void tearDown() throws Exception {
-    if (dbSession != null) {
-      dbSession.close();
-    }
-  }
-
-  @Test
-  public void insert_and_find_by_key() throws Exception {
-    RuleDto rule = RuleTesting.newXooX1();
-    tester.get(RuleDao.class).insert(dbSession, rule);
-
-    ComponentDto project = ComponentTesting.newProjectDto();
-    tester.get(ComponentDao.class).insert(dbSession, project);
-
-    // project can be seen by anyone
-    dbSession.commit();
-    MockUserSession.set().setLogin("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
-    tester.get(InternalPermissionService.class).addPermission(new PermissionChange().setComponentKey(project.getKey()).setGroup(DefaultGroups.ANYONE).setPermission(UserRole.USER));
-
-    ComponentDto file = ComponentTesting.newFileDto(project);
-    tester.get(ComponentDao.class).insert(dbSession, file);
-
-    IssueDto issue = IssueTesting.newDto(rule, file, project).setIssueAttributes(KeyValueFormat.format(ImmutableMap.of("key", "value")));
-    dbClient.issueDao().insert(dbSession, issue);
-
-    dbSession.commit();
-
-    // Check that Issue is in Index
-    assertThat(indexClient.get(IssueIndex.class).countAll()).isEqualTo(1);
-
-    // should find by key
-    Issue issueDoc = indexClient.get(IssueIndex.class).getByKey(issue.getKey());
-
-    // Check all normalized fields
-    assertThat(issueDoc.actionPlanKey()).isEqualTo(issue.getActionPlanKey());
-    assertThat(issueDoc.assignee()).isEqualTo(issue.getAssignee());
-    assertThat(issueDoc.authorLogin()).isEqualTo(issue.getAuthorLogin());
-    assertThat(issueDoc.closeDate()).isEqualTo(issue.getIssueCloseDate());
-    assertThat(issueDoc.effortToFix()).isEqualTo(issue.getEffortToFix());
-    assertThat(issueDoc.resolution()).isEqualTo(issue.getResolution());
-    assertThat(issueDoc.ruleKey()).isEqualTo(RuleKey.of(issue.getRuleRepo(), issue.getRule()));
-    assertThat(issueDoc.line()).isEqualTo(issue.getLine());
-    assertThat(issueDoc.message()).isEqualTo(issue.getMessage());
-    assertThat(issueDoc.reporter()).isEqualTo(issue.getReporter());
-    assertThat(issueDoc.key()).isEqualTo(issue.getKey());
-    assertThat(issueDoc.updateDate()).isEqualTo(issue.getIssueUpdateDate());
-    assertThat(issueDoc.status()).isEqualTo(issue.getStatus());
-    assertThat(issueDoc.severity()).isEqualTo(issue.getSeverity());
-    assertThat(issueDoc.attributes()).isEqualTo(KeyValueFormat.parse(issue.getIssueAttributes()));
-    assertThat(issueDoc.attribute("key")).isEqualTo("value");
-  }
-
-}
index 89dee12057f689caef654ef4ae80bfc1cde6abae..4d4dfa34d10d50812c5392fcdf6c93ed5a063396 100644 (file)
@@ -19,7 +19,6 @@
  */
 package org.sonar.server.issue.db;
 
-import com.google.common.collect.ImmutableMap;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -32,12 +31,11 @@ import org.sonar.core.persistence.AbstractDaoTestCase;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.server.rule.RuleTesting;
 
-import java.util.Date;
+import java.util.Arrays;
 import java.util.List;
 
 import static org.fest.assertions.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
 
 public class IssueDaoTest extends AbstractDaoTestCase {
 
@@ -49,7 +47,7 @@ public class IssueDaoTest extends AbstractDaoTestCase {
   public void before() throws Exception {
     this.session = getMyBatis().openSession(false);
     this.system2 = mock(System2.class);
-    this.dao = new IssueDao(system2);
+    this.dao = new IssueDao(getMyBatis());
   }
 
   @After
@@ -61,7 +59,7 @@ public class IssueDaoTest extends AbstractDaoTestCase {
   public void get_by_key() {
     setupData("shared", "get_by_key");
 
-    IssueDto issue = dao.getByKey(session, "ABCDE");
+    IssueDto issue = dao.selectByKey(session, "ABCDE");
     assertThat(issue.getKee()).isEqualTo("ABCDE");
     assertThat(issue.getId()).isEqualTo(100L);
     assertThat(issue.getComponentId()).isEqualTo(401);
@@ -83,8 +81,8 @@ public class IssueDaoTest extends AbstractDaoTestCase {
     assertThat(issue.getIssueCreationDate()).isNotNull();
     assertThat(issue.getIssueUpdateDate()).isNotNull();
     assertThat(issue.getIssueCloseDate()).isNotNull();
-    assertThat(issue.getCreatedAt()).isNotNull();
-    assertThat(issue.getUpdatedAt()).isNotNull();
+    assertThat(issue.getCreatedAt()).isEqualTo(1400000000000L);
+    assertThat(issue.getUpdatedAt()).isEqualTo(1450000000000L);
     assertThat(issue.getRuleRepo()).isEqualTo("squid");
     assertThat(issue.getRule()).isEqualTo("AvoidCycle");
     assertThat(issue.getComponentKey()).isEqualTo("Action.java");
@@ -95,37 +93,8 @@ public class IssueDaoTest extends AbstractDaoTestCase {
   public void get_by_keys() {
     setupData("shared", "get_by_key");
 
-    List<IssueDto> issues = dao.getByKeys(session, "ABCDE");
+    List<IssueDto> issues = dao.selectByKeys(session, Arrays.asList("ABCDE"));
     assertThat(issues).hasSize(1);
-
-    IssueDto issue = issues.get(0);
-    assertThat(issue.getKee()).isEqualTo("ABCDE");
-    assertThat(issue.getId()).isEqualTo(100L);
-    assertThat(issue.getComponentId()).isEqualTo(401);
-    assertThat(issue.getProjectId()).isEqualTo(399);
-    assertThat(issue.getRuleId()).isEqualTo(500);
-    assertThat(issue.getLanguage()).isEqualTo("java");
-    assertThat(issue.getSeverity()).isEqualTo("BLOCKER");
-    assertThat(issue.isManualSeverity()).isFalse();
-    assertThat(issue.getMessage()).isNull();
-    assertThat(issue.getLine()).isEqualTo(200);
-    assertThat(issue.getEffortToFix()).isEqualTo(4.2);
-    assertThat(issue.getStatus()).isEqualTo("OPEN");
-    assertThat(issue.getResolution()).isEqualTo("FIXED");
-    assertThat(issue.getChecksum()).isEqualTo("XXX");
-    assertThat(issue.getAuthorLogin()).isEqualTo("karadoc");
-    assertThat(issue.getReporter()).isEqualTo("arthur");
-    assertThat(issue.getAssignee()).isEqualTo("perceval");
-    assertThat(issue.getIssueAttributes()).isEqualTo("JIRA=FOO-1234");
-    assertThat(issue.getIssueCreationDate()).isNotNull();
-    assertThat(issue.getIssueUpdateDate()).isNotNull();
-    assertThat(issue.getIssueCloseDate()).isNotNull();
-    assertThat(issue.getCreatedAt()).isNotNull();
-    assertThat(issue.getUpdatedAt()).isNotNull();
-    assertThat(issue.getRuleRepo()).isEqualTo("squid");
-    assertThat(issue.getRule()).isEqualTo("AvoidCycle");
-    assertThat(issue.getComponentKey()).isEqualTo("Action.java");
-    assertThat(issue.getProjectKey()).isEqualTo("struts");
   }
 
   @Test
@@ -165,28 +134,8 @@ public class IssueDaoTest extends AbstractDaoTestCase {
     assertThat(issue.getProjectKey()).isEqualTo("struts");
   }
 
-  @Test
-  public void find_after_dates() throws Exception {
-    setupData("shared", "some_issues");
-
-    Date t0 = new Date(0);
-    assertThat(dao.findAfterDate(session, t0)).hasSize(3);
-
-    Date t2014 = DateUtils.parseDate("2014-01-01");
-    assertThat(dao.findAfterDate(session, t2014)).hasSize(1);
-  }
-
-  @Test
-  public void find_after_dates_with_project() throws Exception {
-    setupData("shared", "find_after_dates_with_project");
-
-    assertThat(dao.findAfterDate(session, DateUtils.parseDate("2014-01-01"), ImmutableMap.of("project", "ABCD"))).hasSize(1);
-  }
-
   @Test
   public void insert() throws Exception {
-    when(system2.now()).thenReturn(DateUtils.parseDate("2013-05-22").getTime());
-
     IssueDto dto = new IssueDto();
     dto.setComponent(new ComponentDto().setKey("struts:Action").setId(123L));
     dto.setProject(new ComponentDto().setKey("struts").setId(100L));
@@ -209,8 +158,8 @@ public class IssueDaoTest extends AbstractDaoTestCase {
     dto.setIssueCreationDate(DateUtils.parseDate("2013-05-18"));
     dto.setIssueUpdateDate(DateUtils.parseDate("2013-05-19"));
     dto.setIssueCloseDate(DateUtils.parseDate("2013-05-20"));
-    dto.setCreatedAt(DateUtils.parseDate("2013-05-21"));
-    dto.setUpdatedAt(DateUtils.parseDate("2013-05-22"));
+    dto.setCreatedAt(1400000000000L);
+    dto.setUpdatedAt(1450000000000L);
 
     dao.insert(session, dto);
     session.commit();
@@ -220,8 +169,6 @@ public class IssueDaoTest extends AbstractDaoTestCase {
 
   @Test
   public void update() throws Exception {
-    when(system2.now()).thenReturn(DateUtils.parseDate("2013-05-22").getTime());
-
     setupData("update");
 
     IssueDto dto = new IssueDto();
@@ -246,8 +193,8 @@ public class IssueDaoTest extends AbstractDaoTestCase {
     dto.setIssueCreationDate(DateUtils.parseDate("2013-05-18"));
     dto.setIssueUpdateDate(DateUtils.parseDate("2013-05-19"));
     dto.setIssueCloseDate(DateUtils.parseDate("2013-05-20"));
-    dto.setCreatedAt(DateUtils.parseDate("2013-05-21"));
-    dto.setUpdatedAt(DateUtils.parseDate("2013-05-22"));
+    dto.setCreatedAt(1400000000000L);
+    dto.setUpdatedAt(1450000000000L);
 
     dao.update(session, dto);
     session.commit();
index 65743b7de1a32ccd806289507e3a3ff018641018..e9ffea46013ad301c2c224ab1dce47b89b22e100 100644 (file)
 package org.sonar.server.issue.index;
 
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterators;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.ClassRule;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.sonar.api.issue.Issue;
 import org.sonar.api.rule.RuleKey;
@@ -49,11 +51,9 @@ import org.sonar.server.issue.IssueTesting;
 import org.sonar.server.issue.db.IssueDao;
 import org.sonar.server.permission.InternalPermissionService;
 import org.sonar.server.permission.PermissionChange;
-import org.sonar.server.platform.BackendCleanup;
 import org.sonar.server.rule.RuleTesting;
 import org.sonar.server.rule.db.RuleDao;
 import org.sonar.server.search.FacetValue;
-import org.sonar.server.search.IndexDefinition;
 import org.sonar.server.search.QueryContext;
 import org.sonar.server.search.Result;
 import org.sonar.server.tester.ServerTester;
@@ -65,6 +65,7 @@ import java.util.List;
 import static com.google.common.collect.Lists.newArrayList;
 import static org.fest.assertions.Assertions.assertThat;
 
+@Ignore
 public class IssueIndexMediumTest {
 
   @ClassRule
@@ -73,9 +74,8 @@ public class IssueIndexMediumTest {
   DbClient db;
   DbSession session;
   IssueIndex index;
-
-  RuleDto rule;
-  ComponentDto project;
+  RuleDto rule = RuleTesting.newXooX1();
+  ComponentDto project = ComponentTesting.newProjectDto("P1");
   ComponentDto file;
 
   @Before
@@ -85,13 +85,9 @@ public class IssueIndexMediumTest {
     session = db.openSession(false);
     index = tester.get(IssueIndex.class);
 
-    rule = RuleTesting.newXooX1();
     tester.get(RuleDao.class).insert(session, rule);
-
-    project = ComponentTesting.newProjectDto();
     tester.get(ComponentDao.class).insert(session, project);
-
-    file = ComponentTesting.newFileDto(project);
+    file = ComponentTesting.newFileDto(project, "F1");
     tester.get(ComponentDao.class).insert(session, file);
     session.commit();
 
@@ -112,18 +108,19 @@ public class IssueIndexMediumTest {
 
   @Test
   public void get_by_key() throws Exception {
-    IssueDto issue = IssueTesting.newDto(rule, file, project);
-    db.issueDao().insert(session, issue);
-    session.commit();
+    IssueDoc issue = IssueTesting.newDoc();
+    tester.get(IssueIndexer.class).index(Iterators.singletonIterator(issue));
+
+    Issue loaded = index.getByKey(issue.key());
+    assertThat(loaded).isNotNull();
 
-    Issue result = index.getByKey(issue.getKey());
-    IssueTesting.assertIsEquivalent(issue, (IssueDoc) result);
   }
 
   @Test
   public void get_by_key_with_attributes() throws Exception {
     IssueDto issue = IssueTesting.newDto(rule, file, project);
-    db.issueDao().insert(session, issue).setIssueAttributes(KeyValueFormat.format(ImmutableMap.of("jira-issue-key", "SONAR-1234")));
+    issue.setIssueAttributes(KeyValueFormat.format(ImmutableMap.of("jira-issue-key", "SONAR-1234")));
+    db.issueDao().insert(session, issue);
     session.commit();
 
     Issue result = index.getByKey(issue.getKey());
@@ -615,8 +612,8 @@ public class IssueIndexMediumTest {
     session.commit();
     MockUserSession.set().setLogin("admin").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN);
     tester.get(InternalPermissionService.class).addPermission(new PermissionChange().setComponentKey(project1.getKey()).setGroup(userGroup.getName()).setPermission(UserRole.USER));
-    tester.get(InternalPermissionService.class).addPermission(new PermissionChange().setComponentKey(project2.getKey()).setGroup(adminGroup.getName()).setPermission(UserRole.USER));
-
+    tester.get(InternalPermissionService.class)
+      .addPermission(new PermissionChange().setComponentKey(project2.getKey()).setGroup(adminGroup.getName()).setPermission(UserRole.USER));
     db.issueDao().insert(session,
       IssueTesting.newDto(rule, file1, project1),
       IssueTesting.newDto(rule, file2, project2),
@@ -655,7 +652,6 @@ public class IssueIndexMediumTest {
 
     tester.get(ComponentDao.class).insert(session, project1, project2, project3, file1, file2, file3);
 
-
     // project1 can be seen by john and project2 by max. project3 cannot be seen by anyone
     UserDto john = new UserDto().setLogin("john").setName("john").setActive(true);
     UserDto max = new UserDto().setLogin("max").setName("max").setActive(true);
@@ -722,96 +718,6 @@ public class IssueIndexMediumTest {
     assertThat(index.search(query.build(), new QueryContext()).getHits()).hasSize(1);
   }
 
-  @Test
-  public void synchronize_issue() throws Exception {
-    IssueDto issue = IssueTesting.newDto(rule, file, project);
-    tester.get(IssueDao.class).insert(session, issue);
-    session.commit();
-
-    // 0 Assert that all issues are both in ES and DB
-    assertThat(db.issueDao().findAfterDate(session, new Date(0))).hasSize(1);
-    assertThat(index.countAll()).isEqualTo(1);
-
-    // Clear issue index in order to simulate these issues have been inserted without being indexed in E/S (from a previous version of SQ or
-    // from batch)
-    tester.get(BackendCleanup.class).clearIndex(IndexDefinition.ISSUES);
-    tester.clearIndexes();
-    assertThat(index.countAll()).isEqualTo(0);
-
-    DbSession newSession = db.openSession(true);
-    try {
-      db.issueDao().synchronizeAfter(newSession, index.getLastSynchronization());
-      newSession.commit();
-
-    } finally {
-      newSession.close();
-    }
-
-    assertThat(index.countAll()).isEqualTo(1);
-  }
-
-  @Test
-  public void synchronize_all_issues() throws Exception {
-    IssueDto issue = IssueTesting.newDto(rule, file, project);
-    tester.get(IssueDao.class).insert(session, issue);
-    session.commit();
-
-    // 0 Assert that all issues are both in ES and DB
-    assertThat(db.issueDao().findAfterDate(session, new Date(0))).hasSize(1);
-    assertThat(index.countAll()).isEqualTo(1);
-
-    // Clear issue index in order to simulate these issues have been inserted without being indexed in E/S (from a previous version of SQ or
-    // from batch)
-    tester.get(BackendCleanup.class).clearIndex(IndexDefinition.ISSUES);
-    tester.clearIndexes();
-    assertThat(index.countAll()).isEqualTo(0);
-
-    DbSession newSession = db.openSession(true);
-    try {
-      db.issueDao().synchronizeAfter(newSession);
-      newSession.commit();
-
-    } finally {
-      newSession.close();
-    }
-
-    assertThat(index.countAll()).isEqualTo(1);
-  }
-
-  @Test
-  public void synchronize_a_lot_of_issues() throws Exception {
-    Integer numberOfIssues = 1000;
-
-    List<String> issueKeys = newArrayList();
-    for (int i = 0; i < numberOfIssues; i++) {
-      IssueDto issue = IssueTesting.newDto(rule, file, project);
-      tester.get(IssueDao.class).insert(session, issue);
-      issueKeys.add(issue.getKey());
-    }
-    session.commit();
-
-    // 0 Assert that all issues are both in ES and DB
-    assertThat(db.issueDao().findAfterDate(session, new Date(0))).hasSize(numberOfIssues);
-    assertThat(index.countAll()).isEqualTo(numberOfIssues);
-
-    // Clear issue index in order to simulate these issues have been inserted without being indexed in E/S (from a previous version of SQ or
-    // from batch)
-    tester.get(BackendCleanup.class).clearIndex(IndexDefinition.ISSUES);
-    tester.clearIndexes();
-    assertThat(index.countAll()).isEqualTo(0);
-
-    DbSession newSession = db.openSession(true);
-    try {
-      db.issueDao().synchronizeAfter(newSession, index.getLastSynchronization());
-      newSession.commit();
-
-    } finally {
-      newSession.close();
-    }
-
-    assertThat(index.countAll()).isEqualTo(numberOfIssues);
-  }
-
   @Test
   public void list_assignees() throws Exception {
     db.issueDao().insert(session,
index 1c23f985f1efbd5ca3a5b328aba3a9cd299771d3..75431a8d7971ada76a700e24fdfcfb15b7e777e9 100644 (file)
@@ -24,12 +24,10 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.utils.DateUtils;
 import org.sonar.core.persistence.TestDatabase;
 import org.sonar.server.db.DbClient;
 
 import java.sql.Connection;
-import java.util.Date;
 
 import static org.fest.assertions.Assertions.assertThat;
 
@@ -80,8 +78,7 @@ public class IssueResultSetIteratorTest {
   @Test
   public void select_after_date() throws Exception {
     dbTester.prepareDbUnit(getClass(), "shared.xml");
-    Date date = DateUtils.parseDate("2014-01-01");
-    IssueResultSetIterator it = IssueResultSetIterator.create(client, connection, date.getTime());
+    IssueResultSetIterator it = IssueResultSetIterator.create(client, connection, 1420000000000L);
 
     assertThat(it.hasNext()).isTrue();
     IssueDoc issue = it.next();
index 83a4641e9d345d2ec51293a8c38a34470b900851..dbe7faa0002009d71c68441106a6678a754be697 100644 (file)
@@ -48,6 +48,7 @@ import org.sonar.server.issue.IssueQuery;
 import org.sonar.server.issue.IssueTesting;
 import org.sonar.server.issue.db.IssueDao;
 import org.sonar.server.issue.filter.IssueFilterParameters;
+import org.sonar.server.issue.index.IssueIndexer;
 import org.sonar.server.permission.InternalPermissionService;
 import org.sonar.server.permission.PermissionChange;
 import org.sonar.server.rule.RuleTesting;
@@ -161,6 +162,7 @@ public class SearchActionMediumTest {
       .setIssueUpdateDate(DateUtils.parseDate("2017-12-04"));
     db.issueDao().insert(session, issue);
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).execute();
     // TODO date assertion is complex to test, and components id are not predictable, that's why strict boolean is set to false
@@ -202,8 +204,8 @@ public class SearchActionMediumTest {
       .setIssueCreationDate(DateUtils.parseDate("2014-09-04"))
       .setIssueUpdateDate(DateUtils.parseDate("2017-12-04"));
     db.issueDao().insert(session, issue2);
-
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).execute();
     result.assertJson(this.getClass(), "issues_on_different_projects.json", false);
@@ -231,6 +233,7 @@ public class SearchActionMediumTest {
         .setUserLogin("fabrice")
         .setCreatedAt(DateUtils.parseDate("2014-09-10")));
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).execute();
     result.assertJson(this.getClass(), "issue_with_comment.json", false);
@@ -255,6 +258,7 @@ public class SearchActionMediumTest {
       .setActionPlanKey("AP-ABCD");
     db.issueDao().insert(session, issue);
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).execute();
     result.assertJson(this.getClass(), "issue_with_action_plan.json", false);
@@ -267,6 +271,7 @@ public class SearchActionMediumTest {
       .setIssueAttributes(KeyValueFormat.format(ImmutableMap.of("jira-issue-key", "SONAR-1234")));
     db.issueDao().insert(session, issue);
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).execute();
     result.assertJson(this.getClass(), "issue_with_attributes.json", false);
@@ -292,6 +297,7 @@ public class SearchActionMediumTest {
       .setActionPlanKey("AP-ABCD");
     db.issueDao().insert(session, issue);
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION)
       .setParam("extra_fields", "actions,transitions,assigneeName,reporterName,actionPlanName").execute();
@@ -315,6 +321,7 @@ public class SearchActionMediumTest {
       .setIssueUpdateDate(DateUtils.parseDate("2017-12-04"));
     db.issueDao().insert(session, issue);
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).execute();
     result.assertJson(this.getClass(), "issue_linked_on_removed_file.json", false);
@@ -325,6 +332,7 @@ public class SearchActionMediumTest {
     IssueDto issue = IssueTesting.newDto(rule, file, project);
     db.issueDao().insert(session, issue);
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).execute();
     assertThat(result.outputAsString()).contains("\"componentId\":" + file.getId() + ",");
@@ -334,6 +342,7 @@ public class SearchActionMediumTest {
   public void search_by_project_uuid() throws Exception {
     db.issueDao().insert(session, IssueTesting.newDto(rule, file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"));
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION)
       .setParam(IssueFilterParameters.PROJECT_UUIDS, project.uuid())
@@ -350,6 +359,7 @@ public class SearchActionMediumTest {
   public void search_by_component_uuid() throws Exception {
     db.issueDao().insert(session, IssueTesting.newDto(rule, file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"));
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION)
       .setParam(IssueFilterParameters.COMPONENT_UUIDS, file.uuid())
@@ -369,6 +379,7 @@ public class SearchActionMediumTest {
       tester.get(IssueDao.class).insert(session, issue);
     }
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION)
       .setParam(IssueFilterParameters.COMPONENTS, file.getKey())
@@ -384,6 +395,7 @@ public class SearchActionMediumTest {
       tester.get(IssueDao.class).insert(session, issue);
     }
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION)
       .setParam(IssueFilterParameters.COMPONENTS, file.getKey() + "," + otherFile.getKey())
@@ -399,6 +411,7 @@ public class SearchActionMediumTest {
       tester.get(IssueDao.class).insert(session, issue);
     }
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).setParam(IssueFilterParameters.COMPONENTS, file.getKey()).execute();
     result.assertJson(this.getClass(), "apply_paging_with_one_component.json", false);
@@ -427,6 +440,7 @@ public class SearchActionMediumTest {
     IssueDto issue = IssueTesting.newDto(rule, file, project);
     db.issueDao().insert(session, issue);
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).execute();
     result.assertJson(this.getClass(), "components_contains_sub_projects.json", false);
@@ -443,6 +457,7 @@ public class SearchActionMediumTest {
       .setSeverity("MAJOR");
     db.issueDao().insert(session, issue);
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION)
       .setParam("resolved", "false")
@@ -462,6 +477,7 @@ public class SearchActionMediumTest {
       .setSeverity("MAJOR");
     db.issueDao().insert(session, issue);
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).setParam(IssueFilterParameters.HIDE_RULES, "true").execute();
     result.assertJson(this.getClass(), "hide_rules.json", false);
@@ -473,6 +489,7 @@ public class SearchActionMediumTest {
     db.issueDao().insert(session, IssueTesting.newDto(rule, file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2").setIssueUpdateDate(DateUtils.parseDate("2014-11-01")));
     db.issueDao().insert(session, IssueTesting.newDto(rule, file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac3").setIssueUpdateDate(DateUtils.parseDate("2014-11-03")));
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION)
       .setParam("sort", IssueQuery.SORT_BY_UPDATE_DATE)
@@ -488,6 +505,7 @@ public class SearchActionMediumTest {
       tester.get(IssueDao.class).insert(session, issue);
     }
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION);
     request.setParam(SearchAction.PARAM_PAGE, "2");
@@ -504,6 +522,7 @@ public class SearchActionMediumTest {
       tester.get(IssueDao.class).insert(session, issue);
     }
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION);
     request.setParam(SearchAction.PARAM_PAGE, "1");
@@ -520,6 +539,7 @@ public class SearchActionMediumTest {
       tester.get(IssueDao.class).insert(session, issue);
     }
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
 
     WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION);
     request.setParam(IssueFilterParameters.PAGE_INDEX, "2");
index dd80fc03503f79f4fff0a08224ae4a763da3b57c..755fc4bbb75e50c3f08521639646dd1832a4d2e6 100644 (file)
@@ -38,6 +38,7 @@ import org.sonar.server.db.DbClient;
 import org.sonar.server.issue.IssueTesting;
 import org.sonar.server.issue.db.IssueDao;
 import org.sonar.server.issue.index.IssueIndex;
+import org.sonar.server.issue.index.IssueIndexer;
 import org.sonar.server.permission.InternalPermissionService;
 import org.sonar.server.permission.PermissionChange;
 import org.sonar.server.rule.RuleTesting;
@@ -87,6 +88,7 @@ public class BackendCleanupMediumTest {
     issue = IssueTesting.newDto(rule, file, project);
     tester.get(IssueDao.class).insert(session, issue);
     session.commit();
+    tester.get(IssueIndexer.class).indexAll();
   }
 
   @After
@@ -102,7 +104,7 @@ public class BackendCleanupMediumTest {
     // Everything should be removed from db
     assertThat(tester.get(ComponentDao.class).getNullableByKey(session, project.key())).isNull();
     assertThat(tester.get(ComponentDao.class).getNullableByKey(session, file.key())).isNull();
-    assertThat(tester.get(IssueDao.class).getNullableByKey(session, file.key())).isNull();
+    assertThat(tester.get(IssueDao.class).selectNullableByKey(session, file.key())).isNull();
     assertThat(tester.get(RuleDao.class).getNullableByKey(session, rule.getKey())).isNull();
 
     // Nothing should be removed from indexes
@@ -118,7 +120,7 @@ public class BackendCleanupMediumTest {
     // Nothing should be removed from db
     assertThat(tester.get(ComponentDao.class).getNullableByKey(session, project.key())).isNotNull();
     assertThat(tester.get(ComponentDao.class).getNullableByKey(session, file.key())).isNotNull();
-    assertThat(tester.get(IssueDao.class).getNullableByKey(session, issue.getKey())).isNotNull();
+    assertThat(tester.get(IssueDao.class).selectNullableByKey(session, issue.getKey())).isNotNull();
     assertThat(tester.get(RuleDao.class).getNullableByKey(session, rule.getKey())).isNotNull();
 
     // Everything should be removed from indexes
@@ -134,7 +136,7 @@ public class BackendCleanupMediumTest {
     // Everything should be removed from db
     assertThat(tester.get(ComponentDao.class).getNullableByKey(session, project.key())).isNull();
     assertThat(tester.get(ComponentDao.class).getNullableByKey(session, file.key())).isNull();
-    assertThat(tester.get(IssueDao.class).getNullableByKey(session, file.key())).isNull();
+    assertThat(tester.get(IssueDao.class).selectNullableByKey(session, file.key())).isNull();
     assertThat(tester.get(RuleDao.class).getNullableByKey(session, rule.getKey())).isNull();
 
     // Everything should be removed from indexes
@@ -150,7 +152,7 @@ public class BackendCleanupMediumTest {
     // Every projects and issues are removed (from db and indexes)
     assertThat(tester.get(ComponentDao.class).getNullableByKey(session, project.key())).isNull();
     assertThat(tester.get(ComponentDao.class).getNullableByKey(session, file.key())).isNull();
-    assertThat(tester.get(IssueDao.class).getNullableByKey(session, issue.getKey())).isNull();
+    assertThat(tester.get(IssueDao.class).selectNullableByKey(session, issue.getKey())).isNull();
     assertThat(tester.get(IssueIndex.class).getNullableByKey(issue.getKey())).isNull();
 
     // Every rules should not be removed (from db and indexes)
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedIssueLongDatesTest/before.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedIssueLongDatesTest/before.xml
new file mode 100644 (file)
index 0000000..2c029eb
--- /dev/null
@@ -0,0 +1,51 @@
+<dataset>
+
+  <issues id="1" kee="ABC" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+          assignee="[null]"
+          author_login="[null]"
+          checksum="[null]"
+          effort_to_fix="[null]"
+          technical_debt="10"
+          message="[null]"
+          line="5000"
+          component_id="100"
+          root_component_id="10"
+          rule_id="200"
+          reporter="emmerik"
+          issue_attributes="foo=bar"
+          action_plan_key="[null]"
+          issue_creation_date="2013-05-18"
+          issue_update_date="2013-05-18"
+          issue_close_date="2013-05-18"
+          created_at="2014-05-12"
+          updated_at="2014-05-13"
+          CREATED_AT_MS="[null]"
+          UPDATED_AT_MS="[null]"
+    />
+
+  <!-- re-entrant migration - ignore the issues that are already fed with new dates -->
+  <issues id="2" kee="DEF" resolution="OPEN" status="OPEN" severity="BLOCKER" manual_severity="[false]"
+          assignee="[null]"
+          author_login="[null]"
+          checksum="[null]"
+          effort_to_fix="[null]"
+          technical_debt="10"
+          message="[null]"
+          line="5000"
+          component_id="100"
+          root_component_id="10"
+          rule_id="200"
+          reporter="emmerik"
+          issue_attributes="foo=bar"
+          action_plan_key="[null]"
+          issue_creation_date="2013-05-18"
+          issue_update_date="2013-05-18"
+          issue_close_date="2013-05-18"
+
+          created_at="2014-05-12"
+          updated_at="2014-05-13"
+          CREATED_AT_MS="1500000000000"
+          UPDATED_AT_MS="1500000000000"
+    />
+
+</dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedIssueLongDatesTest/schema.sql b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedIssueLongDatesTest/schema.sql
new file mode 100644 (file)
index 0000000..66c7d3a
--- /dev/null
@@ -0,0 +1,28 @@
+CREATE TABLE "ISSUES" (
+  "ID" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "KEE" VARCHAR(50) UNIQUE NOT NULL,
+  "COMPONENT_ID" INTEGER NOT NULL,
+  "ROOT_COMPONENT_ID" INTEGER,
+  "RULE_ID" INTEGER,
+  "SEVERITY" VARCHAR(10),
+  "MANUAL_SEVERITY" BOOLEAN NOT NULL,
+  "MESSAGE" VARCHAR(4000),
+  "LINE" INTEGER,
+  "EFFORT_TO_FIX" DOUBLE,
+  "TECHNICAL_DEBT" INTEGER,
+  "STATUS" VARCHAR(20),
+  "RESOLUTION" VARCHAR(20),
+  "CHECKSUM" VARCHAR(1000),
+  "REPORTER" VARCHAR(255),
+  "ASSIGNEE" VARCHAR(255),
+  "AUTHOR_LOGIN" VARCHAR(255),
+  "ACTION_PLAN_KEY" VARCHAR(50) NULL,
+  "ISSUE_ATTRIBUTES" VARCHAR(4000),
+  "ISSUE_CREATION_DATE" TIMESTAMP,
+  "ISSUE_CLOSE_DATE" TIMESTAMP,
+  "ISSUE_UPDATE_DATE" TIMESTAMP,
+  "CREATED_AT" TIMESTAMP,
+  "UPDATED_AT" TIMESTAMP,
+  "CREATED_AT_MS" BIGINT,
+  "UPDATED_AT_MS" BIGINT
+);
index 59d288be419ec5a4db2e00b8a1ccfeb687510030..bae0752883b502dc45d20ca6b2010ff251bd7413 100644 (file)
@@ -10,8 +10,8 @@
       component_id="100"
       root_component_id="10"
       rule_id="200"
-      created_at="[null]"
-      updated_at="[null]"
+      created_at="1000000000"
+      updated_at="1000000000"
       reporter="emmerik"
       issue_attributes="foo=bar"
       action_plan_key="[null]"
index 82db8eecb314c8f221cef1f61885d2ff1be19e2f..21a6c8061e3d96377ba9ad827ecaa66345ec2acc 100644 (file)
@@ -15,8 +15,8 @@
           component_id="100"
           root_component_id="10"
           rule_id="200"
-          created_at="2013-05-18"
-          updated_at="2013-05-18"
+          created_at="1000000000"
+          updated_at="2000000000"
           reporter="emmerik"
           issue_attributes="foo=bar"
           action_plan_key="[null]"
index 15d6a321478fe905f4e25191329cda5d9b0caded..a655b0189219c05222d4fc6d9d0f34ec5b1c407d 100644 (file)
@@ -22,8 +22,8 @@
           component_id="100"
           root_component_id="10"
           rule_id="200"
-          created_at="2010-01-01"
-          updated_at="2011-02-02"
+          created_at="1000000000"
+          updated_at="1000000000"
           reporter="emmerik"
           issue_attributes="foo=bar"
           action_plan_key="[null]"
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/find_after_dates_with_project.xml b/server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/find_after_dates_with_project.xml
deleted file mode 100644 (file)
index d58c618..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-<dataset>
-
-  <projects id="1000" kee="other" root_id="[null]" qualifier="TRK" scope="PRJ" uuid="DBCA"/>
-
-  <snapshots id="1000" project_id="1000" root_snapshot_id="[null]" parent_snapshot_id="[null]" root_project_id="1000"
-             path="" islast="[true]"/>
-
-  <!-- On struts project -->
-  <issues
-          id="100"
-          kee="ABCDE-1"
-          component_id="399"
-          root_component_id="399"
-          rule_id="500"
-          severity="BLOCKER"
-          manual_severity="[false]"
-          message="[null]"
-          line="200"
-          effort_to_fix="4.2"
-          status="OPEN"
-          resolution="FIXED"
-          checksum="XXX"
-          reporter="arthur"
-          assignee="perceval"
-          author_login="[null]"
-          issue_attributes="JIRA=FOO-1234"
-          issue_creation_date="2013-04-16"
-          issue_update_date="2013-04-16"
-          issue_close_date="2013-04-16"
-          created_at="2013-04-16"
-          updated_at="2013-04-16"
-          />
-
-  <issues
-          id="101"
-          kee="ABCDE-2"
-          component_id="399"
-          root_component_id="399"
-          rule_id="500"
-          severity="BLOCKER"
-          manual_severity="[false]"
-          message="[null]"
-          line="200"
-          effort_to_fix="4.2"
-          status="OPEN"
-          resolution="FIXED"
-          checksum="XXX"
-          reporter="arthur"
-          assignee="perceval"
-          author_login="[null]"
-          issue_attributes="JIRA=FOO-1234"
-          issue_creation_date="2013-04-16"
-          issue_update_date="2013-04-16"
-          issue_close_date="2013-04-16"
-          created_at="2013-04-16"
-          updated_at="2014-04-16"
-          />
-
-
-  <!-- On other project -->
-  <issues
-          id="102"
-          kee="ABCDE-3"
-          component_id="1000"
-          root_component_id="1000"
-          rule_id="501"
-          severity="BLOCKER"
-          manual_severity="[false]"
-          message="[null]"
-          line="200"
-          effort_to_fix="4.2"
-          status="OPEN"
-          resolution="FIXED"
-          checksum="XXX"
-          reporter="arthur"
-          assignee="perceval"
-          author_login="[null]"
-          issue_attributes="JIRA=FOO-1234"
-          issue_creation_date="2014-04-16"
-          issue_update_date="2014-04-16"
-          issue_close_date="2014-04-16"
-          created_at="2014-04-16"
-          updated_at="2014-04-16"
-          />
-</dataset>
index 6ba7716170a778843576ee9a61eec4e8cd023bee..b9421a4cb4c5869f2ad881443003eb8e287324b1 100644 (file)
@@ -22,8 +22,8 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-16"
-      updated_at="2013-04-16"
+      created_at="1400000000000"
+      updated_at="1400000000000"
       />
 
 </dataset>
index 9a5cc94791766fa5910b354ad02063daba083fd0..21284a7aa0b2f51869b062f422feca88a35658dd 100644 (file)
@@ -21,8 +21,8 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-16"
-      updated_at="2013-04-16"
+      created_at="1400000000000"
+      updated_at="1450000000000"
       />
 
 </dataset>
index 3d736381a9e55b1400a9083acceab231120fe163..6e6ab5c5cfb430e6cfc9148a4c3e34ed0b1c59fd 100644 (file)
@@ -21,8 +21,8 @@
       issue_creation_date="2013-05-18"
       issue_update_date="2013-05-19"
       issue_close_date="2013-05-20"
-      created_at="2013-05-21"
-      updated_at="2013-05-22"
+      created_at="1400000000000"
+      updated_at="1450000000000"
       action_plan_key="current_sprint"
       />
 </dataset>
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/some_issues.xml b/server/sonar-server/src/test/resources/org/sonar/server/issue/db/IssueDaoTest/some_issues.xml
deleted file mode 100644 (file)
index 96ada68..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-<dataset>
-
-  <!-- rule 500 -->
-  <issues
-          id="100"
-          kee="ABCDE-1"
-          component_id="401"
-          root_component_id="399"
-          rule_id="500"
-          severity="BLOCKER"
-          manual_severity="[false]"
-          message="[null]"
-          line="200"
-          effort_to_fix="4.2"
-          status="OPEN"
-          resolution="FIXED"
-          checksum="XXX"
-          reporter="arthur"
-          assignee="perceval"
-          author_login="[null]"
-          issue_attributes="JIRA=FOO-1234"
-          issue_creation_date="2013-04-16"
-          issue_update_date="2013-04-16"
-          issue_close_date="2013-04-16"
-          created_at="2013-04-16"
-          updated_at="2013-04-16"
-          />
-
-  <issues
-          id="101"
-          kee="ABCDE-2"
-          component_id="401"
-          root_component_id="399"
-          rule_id="500"
-          severity="BLOCKER"
-          manual_severity="[false]"
-          message="[null]"
-          line="200"
-          effort_to_fix="4.2"
-          status="OPEN"
-          resolution="FIXED"
-          checksum="XXX"
-          reporter="arthur"
-          assignee="perceval"
-          author_login="[null]"
-          issue_attributes="JIRA=FOO-1234"
-          issue_creation_date="2013-04-16"
-          issue_update_date="2013-04-16"
-          issue_close_date="2013-04-16"
-          created_at="2013-04-16"
-          updated_at="2013-04-16"
-          />
-
-
-  <!-- rule 501 -->
-  <issues
-          id="102"
-          kee="ABCDE-3"
-          component_id="401"
-          root_component_id="399"
-          rule_id="501"
-          severity="BLOCKER"
-          manual_severity="[false]"
-          message="[null]"
-          line="200"
-          effort_to_fix="4.2"
-          status="OPEN"
-          resolution="FIXED"
-          checksum="XXX"
-          reporter="arthur"
-          assignee="perceval"
-          author_login="[null]"
-          issue_attributes="JIRA=FOO-1234"
-          issue_creation_date="2014-04-16"
-          issue_update_date="2014-04-16"
-          issue_close_date="2014-04-16"
-          created_at="2014-04-16"
-          updated_at="2014-04-16"
-          />
-</dataset>
index a923dfa54e0de4c9b31ae68d516c7e54dc089ee5..ea43e6e66eafc3942df075cdd5e6ec8ff677b321 100644 (file)
@@ -21,8 +21,8 @@
       issue_creation_date="2013-05-18"
       issue_update_date="2013-05-19"
       issue_close_date="2013-05-20"
-      created_at="[null]"
-      updated_at="2013-05-22"
+      created_at="1400000000000"
+      updated_at="1450000000000"
       action_plan_key="current_sprint"
       />
 </dataset>
index 4c6f701dc2ceb8b853a73d2b7ac4ea13c279a5c2..e4bf4848927c830d339aa67dc9dabd941e5a9eb1 100644 (file)
@@ -21,8 +21,8 @@
       issue_creation_date="[null]"
       issue_update_date="[null]"
       issue_close_date="[null]"
-      created_at="[null]"
-      updated_at="2009-01-01"
+      created_at="1400000000000"
+      updated_at="1400000000000"
       action_plan_key="[null]"
       />
 </dataset>
index 3dc5817d42578a89acb2a7a3a5e4c1bdd9cc0a82..f04a8fd87fe53c7e4ddb8ada49ff3b4011bbe33b 100644 (file)
@@ -26,8 +26,8 @@
           reporter="[null]"
           issue_attributes="JIRA=http://jira.com"
           action_plan_key="[null]"
-          created_at="2005-05-12"
-          updated_at="2013-05-18"
+          created_at="1000000000"
+          updated_at="2000000000"
           issue_creation_date="2005-05-12 00:00:00.0"
           issue_update_date="2013-05-18 00:00:00.0"
           issue_close_date="[null]"
index 8bf47afac4f94c9e17494280e5312f68fff3eed8..3341306e09d54f386f4b5170bca2ad0a1d75af02 100644 (file)
@@ -25,8 +25,8 @@
     reporter="[null]"
     issue_attributes="JIRA=http://jira.com"
     action_plan_key="PLAN1"
-    created_at="2005-05-12"
-    updated_at="2013-01-01"
+    created_at="1400000000000"
+    updated_at="1400000000000"
     issue_creation_date="2005-05-12 00:00:00.0"
     issue_update_date="2013-01-01 00:00:00.0"
     issue_close_date="[null]"/>
@@ -51,8 +51,8 @@
     reporter="[null]"
     issue_attributes="JIRA=http://jira.com"
     action_plan_key="PLAN2"
-    created_at="2005-05-12"
-    updated_at="2014-05-18"
+    created_at="1400000000000"
+    updated_at="1450000000000"
     issue_creation_date="2005-05-12 00:00:00.0"
     issue_update_date="2013-05-18 00:00:00.0"
     issue_close_date="[null]"/>
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/718_add_issue_long_dates.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/718_add_issue_long_dates.rb
new file mode 100644 (file)
index 0000000..bf0288c
--- /dev/null
@@ -0,0 +1,28 @@
+#
+# 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.
+#
+
+class AddIssueLongDates < ActiveRecord::Migration
+
+  def self.up
+    add_column 'issues', :created_at_ms, :big_integer, :null => true
+    add_column 'issues', :updated_at_ms, :big_integer, :null => true
+  end
+end
+
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/719_feed_issue_long_dates.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/719_feed_issue_long_dates.rb
new file mode 100644 (file)
index 0000000..fbabcaa
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# 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.
+#
+
+#
+# SonarQube 5.0
+#
+class FeedIssueLongDates < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.server.db.migrations.v50.FeedIssueLongDates')
+  end
+
+end
+
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/720_rename_issue_long_dates.rb b/server/sonar-web/src/main/webapp/WEB-INF/db/migrate/720_rename_issue_long_dates.rb
new file mode 100644 (file)
index 0000000..e81c565
--- /dev/null
@@ -0,0 +1,32 @@
+#
+# 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.
+#
+
+class RenameIssueLongDates < ActiveRecord::Migration
+
+  def self.up
+    remove_index 'issues', :name => 'issues_updated_at'
+    remove_column 'issues', 'created_at'
+    remove_column 'issues', 'updated_at'
+    rename_column 'issues', 'created_at_ms', 'created_at'
+    rename_column 'issues', 'updated_at_ms', 'updated_at'
+    add_index 'issues', 'updated_at', :name => 'issues_updated_at'
+  end
+end
+
index 1247db7f69ea2e20f707526a7023cfe81be3812c..fd8d97ec68c3190a2491e8ae1fae0944856a8554 100644 (file)
@@ -37,8 +37,6 @@ import org.sonar.core.resource.ResourceDao;
 import org.sonar.core.resource.ResourceDto;
 import org.sonar.core.resource.ResourceQuery;
 
-import java.util.Date;
-
 public class ScanIssueStorage extends IssueStorage implements BatchComponent {
 
   private final SnapshotCache snapshotCache;
@@ -54,7 +52,7 @@ public class ScanIssueStorage extends IssueStorage implements BatchComponent {
   }
 
   @Override
-  protected void doInsert(DbSession session, Date now, DefaultIssue issue) {
+  protected void doInsert(DbSession session, long now, DefaultIssue issue) {
     IssueMapper issueMapper = session.getMapper(IssueMapper.class);
     long componentId = componentId(issue);
     long projectId = projectId();
@@ -64,7 +62,7 @@ public class ScanIssueStorage extends IssueStorage implements BatchComponent {
   }
 
   @Override
-  protected void doUpdate(DbSession session, Date now, DefaultIssue issue) {
+  protected void doUpdate(DbSession session, long now, DefaultIssue issue) {
     IssueMapper issueMapper = session.getMapper(IssueMapper.class);
     IssueDto dto = IssueDto.toDtoForUpdate(issue, projectId(), now);
     if (Issue.STATUS_CLOSED.equals(issue.status()) || issue.selectedAt() == null) {
index 7c7972f75f2c4068533f25c4af02167f1617c0bb..386c4949251387877d5b89c12383f35220317aa8 100644 (file)
@@ -206,8 +206,8 @@ public class ScanIssueStorageTest extends AbstractDaoTestCase {
       .setRuleKey(RuleKey.of("squid", "AvoidCycles"))
       .setComponentKey("struts:Action")
 
-        // issue in database has been updated in 2013, after the loading by scan
-      .setSelectedAt(DateUtils.parseDate("2005-01-01"))
+        // issue in database has been updated in 2015, after the loading by scan
+      .setSelectedAt(1400000000000L)
 
         // fields to be updated
       .setLine(444)
index ce45d9f5bf469a67c354f832abb575b69e080b68..c18f807642706bc9b9664fa483685c59e9416465 100644 (file)
@@ -24,8 +24,8 @@
           reporter="[null]"
           issue_attributes="JIRA=http://jira.com"
           action_plan_key="[null]"
-          created_at="2005-05-12"
-          updated_at="2013-05-18"
+          created_at="1400000000000"
+          updated_at="1400000000000"
           issue_creation_date="2005-05-12 00:00:00.0"
           issue_update_date="2013-05-18 00:00:00.0"
           issue_close_date="[null]"
index 0e41f5007cd65f853e725f28436e89c07b99c763..0ddfc4586abeec4a28da87a0945d4b44d2ad0fa2 100644 (file)
@@ -25,8 +25,8 @@
           reporter="[null]"
           issue_attributes=""
           action_plan_key="[null]"
-          created_at="2005-05-12"
-          updated_at="2013-05-18"
+          created_at="1400000000000"
+          updated_at="1500000000000"
           issue_creation_date="2005-05-12 00:00:00.0"
           issue_update_date="2013-05-18 00:00:00.0"
           issue_close_date="[null]"
index 82db8eecb314c8f221cef1f61885d2ff1be19e2f..7cae675e9822e309a0d7546bf30f4a3f8f4f78c3 100644 (file)
@@ -15,8 +15,8 @@
           component_id="100"
           root_component_id="10"
           rule_id="200"
-          created_at="2013-05-18"
-          updated_at="2013-05-18"
+          created_at="1400000000000"
+          updated_at="1400000000000"
           reporter="emmerik"
           issue_attributes="foo=bar"
           action_plan_key="[null]"
index 3e603048abbe237f88c4e198d9cea801d13c2bcb..5fd4a9e813cb320b17d6f36c3fa8a6faa8f7128e 100644 (file)
@@ -19,8 +19,8 @@
           component_id="100"
           root_component_id="10"
           rule_id="200"
-          created_at="2010-01-01"
-          updated_at="2011-02-02"
+          created_at="1400000000000"
+          updated_at="1400000000000"
           reporter="emmerik"
           issue_attributes="foo=bar"
           action_plan_key="[null]"
index a8cd6443445887ead433a9cf264d389656217615..7363ea8426f7193aa19ae3ecf87afb5a6d5034bd 100644 (file)
@@ -47,10 +47,9 @@ public class IssueDao implements BatchComponent, ServerComponent {
 
   @CheckForNull
   public IssueDto selectByKey(String key) {
-    SqlSession session = mybatis.openSession(false);
+    DbSession session = mybatis.openSession(false);
     try {
-      IssueMapper mapper = session.getMapper(IssueMapper.class);
-      return mapper.selectByKey(key);
+      return mapper(session).selectByKey(key);
     } finally {
       MyBatis.closeQuietly(session);
     }
@@ -68,11 +67,16 @@ public class IssueDao implements BatchComponent, ServerComponent {
 
   // TODO replace by aggregation in IssueIndex
   public List<RuleDto> findRulesByComponent(String componentKey, @Nullable Date createdAtOrAfter, DbSession session) {
-    return session.getMapper(IssueMapper.class).findRulesByComponent(componentKey, createdAtOrAfter);
+    return mapper(session).findRulesByComponent(componentKey, createdAtOrAfter);
   }
 
   // TODO replace by aggregation in IssueIndex
   public List<String> findSeveritiesByComponent(String componentKey, @Nullable Date createdAtOrAfter, DbSession session) {
-    return session.getMapper(IssueMapper.class).findSeveritiesByComponent(componentKey, createdAtOrAfter);
+    return mapper(session).findSeveritiesByComponent(componentKey, createdAtOrAfter);
+  }
+
+  protected IssueMapper mapper(DbSession session) {
+    return session.getMapper(IssueMapper.class);
   }
+
 }
index 7cff2f63ff40d7ab0fc63b3d0e4af8f8396a19a9..b201abbf812124ae068e42b359af5eba9b9c31c4 100644 (file)
@@ -30,7 +30,6 @@ import org.sonar.api.utils.Duration;
 import org.sonar.api.utils.KeyValueFormat;
 import org.sonar.api.utils.internal.Uuids;
 import org.sonar.core.component.ComponentDto;
-import org.sonar.core.persistence.Dto;
 import org.sonar.core.rule.RuleDto;
 
 import javax.annotation.CheckForNull;
@@ -42,7 +41,7 @@ import java.util.Date;
 /**
  * @since 3.6
  */
-public final class IssueDto extends Dto<String> implements Serializable {
+public final class IssueDto implements Serializable {
 
   private Long id;
   private String kee;
@@ -63,6 +62,8 @@ public final class IssueDto extends Dto<String> implements Serializable {
   private String authorLogin;
   private String actionPlanKey;
   private String issueAttributes;
+  private long createdAt;
+  private long updatedAt;
 
   // functional dates
   private Date issueCreationDate;
@@ -72,7 +73,7 @@ public final class IssueDto extends Dto<String> implements Serializable {
   /**
    * Temporary date used only during scan
    */
-  private Date selectedAt;
+  private Long selectedAt;
 
   // joins
   private String ruleKey;
@@ -86,7 +87,6 @@ public final class IssueDto extends Dto<String> implements Serializable {
   private String projectUuid;
   private String filePath;
 
-  @Override
   public String getKey() {
     return getKee();
   }
@@ -308,15 +308,27 @@ public final class IssueDto extends Dto<String> implements Serializable {
     return this;
   }
 
-  @Override
-  public IssueDto setCreatedAt(Date createdAt) {
-    super.setCreatedAt(createdAt);
+  public long getCreatedAt() {
+    return createdAt;
+  }
+
+  /**
+   * Technical date
+   */
+  public IssueDto setCreatedAt(long createdAt) {
+    this.createdAt = createdAt;
     return this;
   }
 
-  @Override
-  public IssueDto setUpdatedAt(@Nullable Date updatedAt) {
-    super.setUpdatedAt(updatedAt);
+  public long getUpdatedAt() {
+    return updatedAt;
+  }
+
+  /**
+   * Technical date
+   */
+  public IssueDto setUpdatedAt(long updatedAt) {
+    this.updatedAt = updatedAt;
     return this;
   }
 
@@ -355,11 +367,11 @@ public final class IssueDto extends Dto<String> implements Serializable {
     return ruleRepo;
   }
 
-  public RuleKey getRuleKey(){
+  public RuleKey getRuleKey() {
     return RuleKey.of(ruleRepo, ruleKey);
   }
 
-  public String getLanguage(){
+  public String getLanguage() {
     return language;
   }
 
@@ -401,11 +413,11 @@ public final class IssueDto extends Dto<String> implements Serializable {
   }
 
   @CheckForNull
-  public Date getSelectedAt() {
+  public Long getSelectedAt() {
     return selectedAt;
   }
 
-  public IssueDto setSelectedAt(@Nullable Date d) {
+  public IssueDto setSelectedAt(@Nullable Long d) {
     this.selectedAt = d;
     return this;
   }
@@ -518,7 +530,7 @@ public final class IssueDto extends Dto<String> implements Serializable {
   /**
    * On batch side, component keys and uuid are useless
    */
-  public static IssueDto toDtoForBatchInsert(DefaultIssue issue, Long componentId, Long rootComponentId, Integer ruleId, Date now) {
+  public static IssueDto toDtoForBatchInsert(DefaultIssue issue, Long componentId, Long rootComponentId, Integer ruleId, long now) {
     return new IssueDto()
       .setKee(issue.key())
       .setLine(issue.line())
@@ -550,6 +562,8 @@ public final class IssueDto extends Dto<String> implements Serializable {
       .setIssueCloseDate(issue.closeDate())
       .setIssueUpdateDate(issue.updateDate())
       .setSelectedAt(issue.selectedAt())
+
+      // technical dates
       .setCreatedAt(now)
       .setUpdatedAt(now);
   }
@@ -557,13 +571,13 @@ public final class IssueDto extends Dto<String> implements Serializable {
   /**
    * On server side, we need component keys and uuid
    */
-  public static IssueDto toDtoForServerInsert(DefaultIssue issue, ComponentDto component, ComponentDto project, Integer ruleId, Date now) {
+  public static IssueDto toDtoForServerInsert(DefaultIssue issue, ComponentDto component, ComponentDto project, Integer ruleId, long now) {
     return toDtoForBatchInsert(issue, component.getId(), project.getId(), ruleId, now)
       .setComponent(component)
       .setProject(project);
   }
 
-  public static IssueDto toDtoForUpdate(DefaultIssue issue, Long rootComponentId, Date now) {
+  public static IssueDto toDtoForUpdate(DefaultIssue issue, Long rootComponentId, long now) {
     // Invariant fields, like key and rule, can't be updated
     return new IssueDto()
       .setKee(issue.key())
@@ -593,6 +607,8 @@ public final class IssueDto extends Dto<String> implements Serializable {
       .setIssueCloseDate(issue.closeDate())
       .setIssueUpdateDate(issue.updateDate())
       .setSelectedAt(issue.selectedAt())
+
+      // technical date
       .setUpdatedAt(now);
   }
 
index 5e51b8c3a568b760aeef6fce407c82c07ca0a25a..ac41ee8639e3af15f89facea40d39d4d9e5bd32a 100644 (file)
@@ -23,8 +23,6 @@ import org.apache.ibatis.annotations.Param;
 import org.sonar.core.rule.RuleDto;
 
 import javax.annotation.Nullable;
-
-import java.sql.Timestamp;
 import java.util.Collection;
 import java.util.Date;
 import java.util.List;
@@ -47,5 +45,4 @@ public interface IssueMapper {
 
   int updateIfBeforeSelectedDate(IssueDto issue);
 
-  List<IssueDto> selectAfterDate(@Nullable @Param("date") Timestamp timestamp, @Nullable @Param("project") String projectUuid);
 }
index c89c87b417d9ab14c6bcd42cd565b1b57a1cf7b2..7455bd4bd07f8a9ef562b8a78267423d6edcaed1 100644 (file)
@@ -30,7 +30,6 @@ import org.sonar.core.persistence.BatchSession;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.persistence.MyBatis;
 
-import java.util.Date;
 import java.util.List;
 
 import static com.google.common.collect.Lists.newArrayList;
@@ -59,28 +58,32 @@ public abstract class IssueStorage {
   }
 
   public void save(DbSession session, DefaultIssue issue) {
-    save(session, newArrayList(issue));
+    doSave(session, newArrayList(issue));
   }
 
   public void save(Iterable<DefaultIssue> issues) {
     DbSession session = mybatis.openSession(true);
     try {
-      save(session, issues);
-      session.commit();
+      doSave(session, issues);
     } finally {
       MyBatis.closeQuietly(session);
     }
   }
 
-  private void save(DbSession session, Iterable<DefaultIssue> issues) {
+  private void doSave(DbSession session, Iterable<DefaultIssue> issues) {
     // Batch session can not be used for updates. It does not return the number of updated rows,
     // required for detecting conflicts.
-    Date now = new Date();
+    long now = System.currentTimeMillis();
     List<DefaultIssue> toBeUpdated = batchInsert(session, issues, now);
     update(toBeUpdated, now);
+    doAfterSave();
   }
 
-  private List<DefaultIssue> batchInsert(DbSession session, Iterable<DefaultIssue> issues, Date now) {
+  protected void doAfterSave() {
+    // overridden on server-side to index ES
+  }
+
+  private List<DefaultIssue> batchInsert(DbSession session, Iterable<DefaultIssue> issues, long now) {
     List<DefaultIssue> toBeUpdated = newArrayList();
     int count = 0;
     IssueChangeMapper issueChangeMapper = session.getMapper(IssueChangeMapper.class);
@@ -96,12 +99,13 @@ public abstract class IssueStorage {
         toBeUpdated.add(issue);
       }
     }
+    session.commit();
     return toBeUpdated;
   }
 
-  protected abstract void doInsert(DbSession batchSession, Date now, DefaultIssue issue);
+  protected abstract void doInsert(DbSession batchSession, long now, DefaultIssue issue);
 
-  private void update(List<DefaultIssue> toBeUpdated, Date now) {
+  private void update(List<DefaultIssue> toBeUpdated, long now) {
     if (!toBeUpdated.isEmpty()) {
       DbSession session = mybatis.openSession(false);
       try {
@@ -117,7 +121,7 @@ public abstract class IssueStorage {
     }
   }
 
-  protected abstract void doUpdate(DbSession batchSession, Date now, DefaultIssue issue);
+  protected abstract void doUpdate(DbSession batchSession, long now, DefaultIssue issue);
 
   private void insertChanges(IssueChangeMapper mapper, DefaultIssue issue) {
     for (IssueComment comment : issue.comments()) {
index 622de1218421c44d83d9b778117fdd0ef6ff383b..a5fa56cfeb5d885ff8d93dcb406cd0582dc3de34 100644 (file)
@@ -24,8 +24,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.issue.internal.DefaultIssue;
 
-import java.util.Date;
-
 /**
  * See https://jira.codehaus.org/browse/SONAR-4309
  *
@@ -41,7 +39,7 @@ public class UpdateConflictResolver {
     IssueDto dbIssue = mapper.selectByKey(issue.key());
     if (dbIssue != null) {
       mergeFields(dbIssue, issue);
-      mapper.update(IssueDto.toDtoForUpdate(issue, dbIssue.getProjectId(), new Date()));
+      mapper.update(IssueDto.toDtoForUpdate(issue, dbIssue.getProjectId(), System.currentTimeMillis()));
     }
   }
 
index 783c74331418e1741c002ba72dea0cda943b05ca..a0677316258df7ed8af2c01c2b543a9b999b014b 100644 (file)
@@ -33,7 +33,8 @@ import java.util.List;
  */
 public class DatabaseVersion implements BatchComponent, ServerComponent {
 
-  public static final int LAST_VERSION = 717;
+  public static final int LAST_VERSION = 720;
+
   /**
    * List of all the tables.
    * This list is hardcoded because we didn't succeed in using java.sql.DatabaseMetaData#getTables() in the same way
index 71dc5863e1582bab4a36fbe7343480ec216766e4..2e9b914d6055b6271669600ee17cae17d854fe77 100644 (file)
@@ -195,7 +195,7 @@ public class PurgeDao {
     mapper.setSnapshotIsLastToFalse(resourceId);
     mapper.deleteFileSourcesByUuid(resourceIdUuid.getUuid());
     mapper.disableResource(resourceId);
-    mapper.resolveResourceIssuesNotAlreadyResolved(resourceId, new Date(system2.now()));
+    mapper.resolveResourceIssuesNotAlreadyResolved(resourceId, new Date(system2.now()), system2.now());
   }
 
   public PurgeDao deleteSnapshots(PurgeSnapshotQuery query) {
index 4ece70e8e4a90b912c675783f6f7ef6cab221429..81e0d2d973eababc0461a26b08f49e8bf0a43277 100644 (file)
@@ -60,7 +60,7 @@ public interface PurgeMapper {
 
   void disableResource(long resourceId);
 
-  void resolveResourceIssuesNotAlreadyResolved(@Param("resourceId") long resourceId, @Param("date") Date date);
+  void resolveResourceIssuesNotAlreadyResolved(@Param("resourceId") long resourceId, @Param("date") Date date, @Param("dateAsLong") Long dateAsLong);
 
   void deleteResourceIndex(@Param("resourceIds") List<Long> resourceIds);
 
index b781a3ff96282d9952c868595d0931e818ee6f67..26f0850046647cef061143068aeb6883d126bd79 100644 (file)
     where i.kee=#{kee}
   </select>
 
-  <select id="selectAfterDate" resultType="Issue" fetchSize="${_scrollFetchSize}" resultSetType="FORWARD_ONLY">
-    select
-    <include refid="issueColumns"/>
-    from issues i
-    inner join rules r on r.id=i.rule_id
-    inner join projects p on p.id=i.component_id
-    inner join projects root on root.id=i.root_component_id
-    <where>
-      <if test="date != null">
-        AND (i.updated_at IS NULL or i.updated_at &gt;= #{date})
-      </if>
-      <if test="project != null">
-        AND root.uuid = #{project}
-      </if>
-    </where>
-  </select>
-
   <select id="selectNonClosedIssuesByModule" parameterType="int" resultType="Issue">
     select
     i.id,
index eb87903bbb9e63e7ac7bb5060c0048f9ea3174e2..29605abdc40af860324676343edd0fcd5893f864 100644 (file)
@@ -275,6 +275,9 @@ INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('714');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('715');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('716');
 INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('717');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('718');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('719');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('720');
 
 INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT, REMEMBER_TOKEN, REMEMBER_TOKEN_EXPIRES_AT) VALUES (1, 'admin', 'Administrator', '', 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '2011-09-26 22:27:48.0', '2011-09-26 22:27:48.0', null, null);
 ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2;
index e221f8ee75be524fd255c040db91da4aba271887..0744edcbba50fdd285018ddd36cf5a21353df4cd 100644 (file)
@@ -461,9 +461,8 @@ CREATE TABLE "ISSUES" (
   "ISSUE_CREATION_DATE" TIMESTAMP,
   "ISSUE_CLOSE_DATE" TIMESTAMP,
   "ISSUE_UPDATE_DATE" TIMESTAMP,
-  "CREATED_AT" TIMESTAMP,
-  "UPDATED_AT" TIMESTAMP
-
+  "CREATED_AT" BIGINT,
+  "UPDATED_AT" BIGINT
 );
 
 CREATE TABLE "ISSUE_CHANGES" (
index 70acfa0df27297130b93514f8832b0c596fe1075..95aeeebeb3c952fc56e79925f1804b9bad8bd353 100644 (file)
   </update>
 
   <update id="resolveResourceIssuesNotAlreadyResolved" parameterType="map">
-    UPDATE issues SET status='CLOSED',resolution='REMOVED',updated_at=#{date},issue_close_date=#{date},
+    UPDATE issues SET status='CLOSED',resolution='REMOVED',updated_at=#{dateAsLong},issue_close_date=#{date},
     issue_update_date=#{date}
     WHERE component_id=#{resourceId} AND resolution IS NULL
   </update>
index eda114c938f9253e4bc0b5917f5e2996f6acf03e..2d55a55e13ba0ce4ca2ea2b91e60e360f74d11c8 100644 (file)
@@ -69,8 +69,8 @@ public class IssueMapperTest extends AbstractDaoTestCase {
     dto.setIssueCreationDate(DateUtils.parseDate("2013-05-18"));
     dto.setIssueUpdateDate(DateUtils.parseDate("2013-05-19"));
     dto.setIssueCloseDate(DateUtils.parseDate("2013-05-20"));
-    dto.setCreatedAt(DateUtils.parseDate("2013-05-21"));
-    dto.setUpdatedAt(DateUtils.parseDate("2013-05-22"));
+    dto.setCreatedAt(1400000000000L);
+    dto.setUpdatedAt(1500000000000L);
 
     mapper.insert(dto);
     session.commit();
@@ -104,8 +104,8 @@ public class IssueMapperTest extends AbstractDaoTestCase {
     dto.setIssueCreationDate(DateUtils.parseDate("2013-05-18"));
     dto.setIssueUpdateDate(DateUtils.parseDate("2013-05-19"));
     dto.setIssueCloseDate(DateUtils.parseDate("2013-05-20"));
-    dto.setCreatedAt(DateUtils.parseDate("2013-05-21"));
-    dto.setUpdatedAt(DateUtils.parseDate("2013-05-22"));
+    dto.setCreatedAt(1400000000000L);
+    dto.setUpdatedAt(1500000000000L);
 
     mapper.update(dto);
     session.commit();
@@ -138,11 +138,11 @@ public class IssueMapperTest extends AbstractDaoTestCase {
     dto.setIssueCreationDate(DateUtils.parseDate("2013-05-18"));
     dto.setIssueUpdateDate(DateUtils.parseDate("2013-05-19"));
     dto.setIssueCloseDate(DateUtils.parseDate("2013-05-20"));
-    dto.setCreatedAt(DateUtils.parseDate("2013-05-21"));
-    dto.setUpdatedAt(DateUtils.parseDate("2013-05-22"));
+    dto.setCreatedAt(1400000000000L);
+    dto.setUpdatedAt(1500000000000L);
 
     // selected after last update -> ok
-    dto.setSelectedAt(DateUtils.parseDate("2015-01-01"));
+    dto.setSelectedAt(1500000000000L);
 
     int count = mapper.updateIfBeforeSelectedDate(dto);
     assertThat(count).isEqualTo(1);
@@ -176,11 +176,11 @@ public class IssueMapperTest extends AbstractDaoTestCase {
     dto.setIssueCreationDate(DateUtils.parseDate("2013-05-18"));
     dto.setIssueUpdateDate(DateUtils.parseDate("2013-05-19"));
     dto.setIssueCloseDate(DateUtils.parseDate("2013-05-20"));
-    dto.setCreatedAt(DateUtils.parseDate("2013-05-21"));
-    dto.setUpdatedAt(DateUtils.parseDate("2013-05-22"));
+    dto.setCreatedAt(1400000000000L);
+    dto.setUpdatedAt(1460000000000L);
 
     // selected before last update -> ko
-    dto.setSelectedAt(DateUtils.parseDate("2009-01-01"));
+    dto.setSelectedAt(1400000000000L);
 
     int count = mapper.updateIfBeforeSelectedDate(dto);
     assertThat(count).isEqualTo(0);
index 59ed7c49e4033601a9d4cff2c7f58eccf6def386..4bb99232413814585dfdf9fe84941d0c8ac61c00 100644 (file)
@@ -251,7 +251,7 @@ public class IssueStorageTest extends AbstractDaoTestCase {
     }
 
     @Override
-    protected void doInsert(DbSession session, Date now, DefaultIssue issue) {
+    protected void doInsert(DbSession session, long now, DefaultIssue issue) {
       int ruleId = ruleId(issue);
       IssueDto dto = IssueDto.toDtoForBatchInsert(issue, 100l, 10l, ruleId, now);
 
@@ -259,7 +259,7 @@ public class IssueStorageTest extends AbstractDaoTestCase {
     }
 
     @Override
-    protected void doUpdate(DbSession session, Date now, DefaultIssue issue) {
+    protected void doUpdate(DbSession session, long now, DefaultIssue issue) {
       IssueDto dto = IssueDto.toDtoForUpdate(issue, 10l, now);
       session.getMapper(IssueMapper.class).update(dto);
     }
@@ -277,7 +277,7 @@ public class IssueStorageTest extends AbstractDaoTestCase {
     }
 
     @Override
-    protected void doInsert(DbSession session, Date now, DefaultIssue issue) {
+    protected void doInsert(DbSession session, long now, DefaultIssue issue) {
       int ruleId = ruleId(issue);
       IssueDto dto = IssueDto.toDtoForServerInsert(issue, component, project, ruleId, now);
 
@@ -285,7 +285,7 @@ public class IssueStorageTest extends AbstractDaoTestCase {
     }
 
     @Override
-    protected void doUpdate(DbSession session, Date now, DefaultIssue issue) {
+    protected void doUpdate(DbSession session, long now, DefaultIssue issue) {
       IssueDto dto = IssueDto.toDtoForUpdate(issue, 10l, now);
       session.getMapper(IssueMapper.class).update(dto);
     }
index d8d1f7655bf8113be439cc59f63e52e79b03403e..4a52ab4ecb086814c6f6a27d372422c2cdfa9c8f 100644 (file)
@@ -47,7 +47,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.config.Settings;
 import org.sonar.core.cluster.NullQueue;
-import org.sonar.core.cluster.WorkQueue;
 import org.sonar.core.config.Logback;
 import org.sonar.core.persistence.dialect.Dialect;
 
@@ -80,7 +79,6 @@ public class TestDatabase extends ExternalResource {
   private DatabaseCommands commands;
   private IDatabaseTester tester;
   private MyBatis myBatis;
-  private WorkQueue queue = new NullQueue();
   private String schemaPath = null;
 
   public TestDatabase schema(Class baseClass, String filename) {
@@ -89,11 +87,6 @@ public class TestDatabase extends ExternalResource {
     return this;
   }
 
-  public TestDatabase setQueue(WorkQueue queue) {
-    this.queue = queue;
-    return this;
-  }
-
   @Override
   protected void before() throws Throwable {
     Settings settings = new Settings().setProperties(Maps.fromProperties(System.getProperties()));
@@ -124,7 +117,7 @@ public class TestDatabase extends ExternalResource {
     commands = DatabaseCommands.forDialect(db.getDialect());
     tester = new DataSourceDatabaseTester(db.getDataSource());
 
-    myBatis = new MyBatis(db, new Logback(), queue);
+    myBatis = new MyBatis(db, new Logback(), new NullQueue());
     myBatis.start();
 
     truncateTables();
@@ -198,7 +191,6 @@ public class TestDatabase extends ExternalResource {
     }
   }
 
-
   public void prepareDbUnit(Class testClass, String... testNames) {
     InputStream[] streams = new InputStream[testNames.length];
     try {
index 3c1e080a25c41c85b78cca754c5d34d5c8aa901f..421b536228300dba21289c45c63ef6fa092f6c72 100644 (file)
@@ -23,7 +23,6 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.resources.Scopes;
-import org.sonar.api.utils.DateUtils;
 import org.sonar.api.utils.System2;
 import org.sonar.core.persistence.AbstractDaoTestCase;
 import org.sonar.core.persistence.DbSession;
@@ -54,12 +53,11 @@ public class PurgeDaoTest extends AbstractDaoTestCase {
   @Before
   public void before() {
     system2 = mock(System2.class);
-    when(system2.now()).thenReturn(DateUtils.parseDate("2014-04-09").getTime());
+    when(system2.now()).thenReturn(1450000000000L);
     dbSession = getMyBatis().openSession(false);
 
     sut = new PurgeDao(getMyBatis(), new ResourceDao(getMyBatis(), system2), new PurgeProfiler(), system2);
   }
-
   @After
   public void after() {
     MyBatis.closeQuietly(dbSession);
@@ -97,7 +95,7 @@ public class PurgeDaoTest extends AbstractDaoTestCase {
   public void disable_resources_without_last_snapshot() {
     setupData("disable_resources_without_last_snapshot");
     sut.purge(new PurgeConfiguration(1L, new String[0], 30, system2), PurgeListener.EMPTY);
-    checkTables("disable_resources_without_last_snapshot", "projects", "snapshots", "issues");
+    checkTables("disable_resources_without_last_snapshot", new String[]{"issue_close_date", "issue_update_date"}, "projects", "snapshots", "issues");
   }
 
   @Test
index 5ab673b9e26a1a1c90501ec4921e6dee5b7de7d2..de7167141e70254ce29063f0bd6fa5ed4c3e5616 100644 (file)
@@ -23,8 +23,8 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-16"
-      updated_at="2013-04-16"
+      created_at="1400000000000"
+      updated_at="1400000000000"
       />
 
   <issues
@@ -47,8 +47,8 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-16"
-      updated_at="2013-04-16"
+      created_at="1400000000000"
+      updated_at="1400000000000"
       />
 
   <issues
@@ -71,8 +71,8 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-16"
-      updated_at="2013-04-16"
+      created_at="1400000000000"
+      updated_at="1400000000000"
       />
 
 </dataset>
index 27bbb7806d2f9b7001fdd33a2dd0b9ebfda11fca..c93aea039d9caa8eb4c2578a712c8d188b060c17 100644 (file)
@@ -27,7 +27,7 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-16"
+      created_at="1400000000000"
       updated_at="[null]"
       />
 
@@ -89,7 +89,7 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-10"
+      created_at="1400000000000"
       updated_at="[null]"
       />
 
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-10"
+      created_at="1400000000000"
       updated_at="[null]"
       />
 
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-10"
+      created_at="1400000000000"
       updated_at="[null]"
       />
 
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-10"
+      created_at="1400000000000"
       updated_at="[null]"
       />
 
index 9407812d43754f82131813d1725e15180e476f81..f36d8c96a59533acabd5b30145d55c8c36dd837d 100644 (file)
@@ -24,7 +24,7 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-10"
+      created_at="1400000000000"
       updated_at="[null]"
       />
 
index 50ef94fe5671fa9cf9de567b0aee3e5b47451246..8e7e6de33552f02096be715121d6a4b96f232ddf 100644 (file)
@@ -22,8 +22,8 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-16"
-      updated_at="2013-04-16"
+      created_at="1400000000000"
+      updated_at="1400000000000"
       />
 
   <issues
@@ -47,8 +47,8 @@
       issue_creation_date="2013-04-17"
       issue_update_date="2013-04-17"
       issue_close_date="2013-04-17"
-      created_at="2013-04-17"
-      updated_at="2013-04-17"
+      created_at="1400000000000"
+      updated_at="1400000000000"
       />
 
 
@@ -74,7 +74,7 @@
       issue_creation_date="2013-04-18"
       issue_update_date="2013-04-18"
       issue_close_date="2013-04-18"
-      created_at="2013-04-18"
-      updated_at="2013-04-18"
+      created_at="1400000000000"
+      updated_at="1400000000000"
       />
 </dataset>
index 2d7e237e3ed4d05c046ee90fa37f5b5eb7aa8213..12615141a32394c88191ec32a82b97168e9f3e25 100644 (file)
@@ -22,8 +22,8 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-16"
-      updated_at="2013-04-16"
+      created_at="1400000000000"
+      updated_at="1400000000000"
       />
 
   <issues
@@ -47,8 +47,8 @@
       issue_creation_date="2013-04-17"
       issue_update_date="2013-04-17"
       issue_close_date="2013-04-17"
-      created_at="2013-04-16"
-      updated_at="2013-04-16"
+      created_at="1400000000000"
+      updated_at="1400000000000"
       />
 
 
@@ -74,7 +74,7 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-16"
-      updated_at="2013-04-16"
+      created_at="1400000000000"
+      updated_at="1400000000000"
       />
 </dataset>
index 9a5cc94791766fa5910b354ad02063daba083fd0..b8f264193f04d3155480ab03759759094e2696da 100644 (file)
@@ -21,8 +21,8 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-16"
-      updated_at="2013-04-16"
+      created_at="1400000000000"
+      updated_at="1400000000000"
       />
 
 </dataset>
index 1d48a7733efdd8b643e58c0a6cf2c486d13077b2..aeb1fc63497accbcd14e13e2383c5a8ef0334b0d 100644 (file)
@@ -22,8 +22,8 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-16"
-      updated_at="2013-04-16"
+      created_at="1400000000000"
+      updated_at="1400000000000"
       />
 
   <issues
@@ -47,8 +47,8 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-16"
-      updated_at="2013-04-16"
+      created_at="1400000000000"
+      updated_at="1400000000000"
       />
 
 
@@ -74,7 +74,7 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-16"
-      updated_at="2013-04-16"
+      created_at="1400000000000"
+      updated_at="1400000000000"
       />
 </dataset>
index c036dc7c7808c476c52d6bf732d9db742ce2c8e7..59044e8bc31dffaf885f48f6089c437ee6db304b 100644 (file)
@@ -22,7 +22,7 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-16"
+      created_at="1400000000000"
       updated_at="[null]"
       />
 
@@ -48,7 +48,7 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-10"
+      created_at="1400000000000"
       updated_at="[null]"
       />
 
@@ -74,7 +74,7 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-10"
+      created_at="1400000000000"
       updated_at="[null]"
       />
 
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-10"
+      created_at="1400000000000"
       updated_at="[null]"
       />
 
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-10"
+      created_at="1400000000000"
       updated_at="[null]"
       />
 
index ec2c35e66d9f868a23585b601c20c7e0f1df8626..95f98bc0584099a3d581f0529f0ae95059a2313d 100644 (file)
@@ -42,7 +42,7 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-16"
+      created_at="1400000000000"
       updated_at="[null]"
       />
 
@@ -68,7 +68,7 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-10"
+      created_at="1400000000000"
       updated_at="[null]"
       />
 
@@ -94,7 +94,7 @@
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-10"
+      created_at="1400000000000"
       updated_at="[null]"
       />
 
       issue_creation_date="2013-04-16"
       issue_update_date="2013-04-16"
       issue_close_date="2013-04-16"
-      created_at="2013-04-10"
+      created_at="1400000000000"
       updated_at="[null]"
       />
 
index 3d736381a9e55b1400a9083acceab231120fe163..e82a348320776d34feba089ea98f085b10723735 100644 (file)
@@ -21,8 +21,8 @@
       issue_creation_date="2013-05-18"
       issue_update_date="2013-05-19"
       issue_close_date="2013-05-20"
-      created_at="2013-05-21"
-      updated_at="2013-05-22"
+      created_at="1400000000000"
+      updated_at="1500000000000"
       action_plan_key="current_sprint"
       />
 </dataset>
index a923dfa54e0de4c9b31ae68d516c7e54dc089ee5..2bb025d6f549bbaa2325db617195ecbd3808b396 100644 (file)
@@ -21,8 +21,8 @@
       issue_creation_date="2013-05-18"
       issue_update_date="2013-05-19"
       issue_close_date="2013-05-20"
-      created_at="[null]"
-      updated_at="2013-05-22"
+      created_at="1400000000000"
+      updated_at="1500000000000"
       action_plan_key="current_sprint"
       />
 </dataset>
index 4c6f701dc2ceb8b853a73d2b7ac4ea13c279a5c2..e4bf4848927c830d339aa67dc9dabd941e5a9eb1 100644 (file)
@@ -21,8 +21,8 @@
       issue_creation_date="[null]"
       issue_update_date="[null]"
       issue_close_date="[null]"
-      created_at="[null]"
-      updated_at="2009-01-01"
+      created_at="1400000000000"
+      updated_at="1400000000000"
       action_plan_key="[null]"
       />
 </dataset>
index 5163092c4243ffc0f1622aab3b76427f47bce8c9..d60c33118867b3bf866738969307346b942e0757 100644 (file)
@@ -22,8 +22,8 @@
       issue_creation_date="[null]"
       issue_update_date="[null]"
       issue_close_date="[null]"
-      created_at="[null]"
-      updated_at="2013-06-01"
+      created_at="1400000000000"
+      updated_at="1450000000000"
       action_plan_key="[null]"
       />
 </dataset>
index d2a7e749e7891e2d255590c4c11794132538043a..6de2cc7d038a912929c8c21f87d1096831063a71 100644 (file)
@@ -21,8 +21,8 @@
       issue_creation_date="[null]"
       issue_update_date="[null]"
       issue_close_date="[null]"
-      created_at="[null]"
-      updated_at="2013-06-01"
+      created_at="1400000000000"
+      updated_at="1450000000000"
       action_plan_key="[null]"
       />
 </dataset>
index edab1651a43ba67106185e8af0474463fb3361b9..eff6dd5f3742a5471499c1891d171e89616a8c6a 100644 (file)
@@ -15,8 +15,8 @@
           component_id="100"
           root_component_id="10"
           rule_id="200"
-          created_at="2010-01-01"
-          updated_at="2011-02-02"
+          created_at="1400000000000"
+          updated_at="1400000000000"
           reporter="emmerik"
           issue_attributes="foo=bar"
           action_plan_key="[null]"
index 02faf07c5e9951612e2313c46b4bad33ff0fdc4d..0499ea1c91c1010f3301745fd773c5dc5744dc4f 100644 (file)
@@ -62,7 +62,7 @@ What has been changed :
           issue_close_date="2014-04-09"
           resolution="REMOVED" line="200" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="2014-04-09" issue_creation_date="2013-04-16" issue_update_date="2014-04-09" created_at="2013-04-16"/>
+          updated_at="1450000000000" issue_creation_date="2013-04-16" issue_update_date="2014-04-09" created_at="1450000000000"/>
 
   <!-- Open issue on directory -->
   <issues id="2" kee="ISSUE-2"
@@ -72,7 +72,7 @@ What has been changed :
           issue_close_date="2014-04-09"
           resolution="REMOVED" line="[null]" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="2014-04-09" issue_creation_date="2013-04-16" issue_update_date="2014-04-09" created_at="2013-04-16"/>
+          updated_at="1450000000000" issue_creation_date="2013-04-16" issue_update_date="2014-04-09" created_at="1450000000000"/>
 
   <!-- Open issue on project -->
   <issues id="3" kee="ISSUE-3"
@@ -82,16 +82,16 @@ What has been changed :
           issue_close_date="2014-04-09"
           resolution="REMOVED" line="[null]" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="2014-04-09" issue_creation_date="2013-04-16" issue_update_date="2014-04-09" created_at="2013-04-16"/>
+          updated_at="1450000000000" issue_creation_date="2013-04-16" issue_update_date="2014-04-09" created_at="1450000000000"/>
 
   <!-- Resolved issue on file -> not to be updated -->
   <issues id="4" kee="ISSUE-4"
           component_id="3"
           root_component_id="1"
           status="CLOSED"
-          issue_close_date="2014-04-08"
+          issue_close_date="2015-12-08"
           resolution="FIXED" line="200" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2014-04-08" created_at="2013-04-16"/>
+          updated_at="1450000000000" issue_creation_date="2013-04-16" issue_update_date="2014-04-08" created_at="1450000000000"/>
 
 </dataset>
index 84cbc0ffda11172aef4f1ec4d2097152c5f155b3..f9a281c0fd28b69b1159dd7bdea18f7602574036 100644 (file)
@@ -54,7 +54,7 @@
           issue_close_date="[null]"
           resolution="[null]" line="200" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="2013-04-16"/>
+          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="1450000000000"/>
 
   <!-- Open issue on directory -->
   <issues id="2" kee="ISSUE-2"
@@ -64,7 +64,7 @@
           issue_close_date="[null]"
           resolution="[null]" line="[null]" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="2013-04-16"/>
+          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="1450000000000"/>
 
   <!-- Open issue on project -->
   <issues id="3" kee="ISSUE-3"
           issue_close_date="[null]"
           resolution="[null]" line="[null]" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="2013-04-16"/>
+          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="1450000000000"/>
 
   <!-- Resolved issue on file -> not to be updated -->
   <issues id="4" kee="ISSUE-4"
           component_id="3"
           root_component_id="1"
           status="CLOSED"
-          issue_close_date="2014-04-08"
+          issue_close_date="2015-12-08"
           resolution="FIXED" line="200" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2014-04-08" created_at="2013-04-16"/>
+          updated_at="1450000000000" issue_creation_date="2013-04-16" issue_update_date="2014-04-08" created_at="1450000000000"/>
 
 </dataset>
index 05e8216a312169041cd149183412913e03f8e496..b72b131316b88c18bae4a2b3a7373e8f9beeedba 100644 (file)
@@ -51,7 +51,7 @@
           issue_close_date="[null]"
           resolution="[null]" line="200" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="2013-04-16"/>
+          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="1400000000000"/>
   <issue_changes id="3" kee="[null]" issue_key="ISSUE-3" created_at="[null]" updated_at="[null]" user_login="admin" change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
 
   <!-- recent open and closed issues -->
@@ -62,7 +62,7 @@
           issue_close_date="[null]"
           resolution="[null]" line="200" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="2013-04-16"/>
+          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="1400000000000"/>
   <issue_changes id="4" kee="[null]" issue_key="ISSUE-4" created_at="[null]" updated_at="[null]" user_login="admin" change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
 
   <!--
index c47968373a5a064950caab40676d9d0e0a9ed52b..c9e3e76b6f39b14b6a07825f3a32ddcd2c33f5ea 100644 (file)
@@ -23,7 +23,7 @@
           issue_close_date="2010-01-01"
           resolution="FIXED" line="200" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="2013-04-16"/>
+          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="1400000000000"/>
   <issue_changes id="1" kee="[null]" issue_key="ISSUE-1" created_at="[null]" updated_at="[null]" user_login="admin" change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
 
   <issues id="2" kee="ISSUE-2"
@@ -33,7 +33,7 @@
           issue_close_date="2010-01-01"
           resolution="FIXED" line="200" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="2013-04-16"/>
+          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="1400000000000"/>
   <issue_changes id="2" kee="[null]" issue_key="ISSUE-2" created_at="[null]" updated_at="[null]" user_login="admin" change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
 
 
@@ -45,7 +45,7 @@
           issue_close_date="[null]"
           resolution="[null]" line="200" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="2013-04-16"/>
+          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="1400000000000"/>
   <issue_changes id="3" kee="[null]" issue_key="ISSUE-3" created_at="[null]" updated_at="[null]" user_login="admin" change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
 
   <!-- recent open and closed issues -->
@@ -56,7 +56,7 @@
           issue_close_date="[null]"
           resolution="[null]" line="200" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="2013-04-16"/>
+          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="1400000000000"/>
   <issue_changes id="4" kee="[null]" issue_key="ISSUE-4" created_at="[null]" updated_at="[null]" user_login="admin" change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
 
   <issues id="5" kee="ISSUE-5"
@@ -66,7 +66,7 @@
           issue_close_date="2025-01-01"
           resolution="FIXED" line="200" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="2013-04-16"/>
+          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="1400000000000"/>
   <issue_changes id="5" kee="[null]" issue_key="ISSUE-5" created_at="[null]" updated_at="[null]" user_login="admin" change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
 
 </dataset>
index 7e09946714b09e1ac5540a9916bac8ab7ee035c6..e9a164a0ec960e419710ff57e6eb54e6ecf1f798 100644 (file)
@@ -45,7 +45,7 @@
           issue_close_date="[null]"
           resolution="[null]" line="200" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="2013-04-16"/>
+          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="1400000000000"/>
   <issue_changes id="3" kee="[null]" issue_key="ISSUE-3" created_at="[null]" updated_at="[null]" user_login="admin" change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
 
   <!-- recent open and closed issues -> do not purge -->
@@ -56,7 +56,7 @@
           issue_close_date="[null]"
           resolution="[null]" line="200" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="2013-04-16"/>
+          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="1400000000000"/>
   <issue_changes id="4" kee="[null]" issue_key="ISSUE-4" created_at="[null]" updated_at="[null]" user_login="admin" change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
 
   <issues id="5" kee="ISSUE-5"
@@ -66,7 +66,7 @@
           issue_close_date="2025-01-01"
           resolution="FIXED" line="200" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="2013-04-16"/>
+          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="1400000000000"/>
   <issue_changes id="5" kee="[null]" issue_key="ISSUE-5" created_at="[null]" updated_at="[null]" user_login="admin" change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
 
 </dataset>
index ab6382bb22b76547746b8f079a0ebc9e6c2ce85c..0a70926c003b268878510a1e71cf037174f67b99 100644 (file)
@@ -22,7 +22,7 @@
           issue_close_date="2010-01-01"
           resolution="FIXED" line="200" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="2013-04-16"/>
+          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="1400000000000"/>
   <issue_changes id="1" kee="[null]" issue_key="ISSUE-1" created_at="[null]" updated_at="[null]" user_login="admin" change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
 
   <issues id="2" kee="ISSUE-2"
@@ -32,7 +32,7 @@
           issue_close_date="2010-01-01"
           resolution="FIXED" line="200" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="2013-04-16"/>
+          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="1400000000000"/>
   <issue_changes id="2" kee="[null]" issue_key="ISSUE-2" created_at="[null]" updated_at="[null]" user_login="admin" change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
 
 
@@ -44,7 +44,7 @@
           issue_close_date="[null]"
           resolution="[null]" line="200" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="2013-04-16"/>
+          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="1400000000000"/>
   <issue_changes id="3" kee="[null]" issue_key="ISSUE-3" created_at="[null]" updated_at="[null]" user_login="admin" change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
 
   <!-- recent open and closed issues -> do not purge -->
@@ -55,7 +55,7 @@
           issue_close_date="[null]"
           resolution="[null]" line="200" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="2013-04-16"/>
+          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="1400000000000"/>
   <issue_changes id="4" kee="[null]" issue_key="ISSUE-4" created_at="[null]" updated_at="[null]" user_login="admin" change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
 
   <issues id="5" kee="ISSUE-5"
@@ -65,7 +65,7 @@
           issue_close_date="2025-01-01"
           resolution="FIXED" line="200" severity="BLOCKER" reporter="perceval" assignee="arthur" rule_id="500" manual_severity="[false]"
           message="[null]" action_plan_key="[null]" effort_to_fix="[null]" technical_debt="[null]" issue_attributes="[null]" checksum="[null]" author_login="[null]"
-          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="2013-04-16"/>
+          updated_at="[null]" issue_creation_date="2013-04-16" issue_update_date="2013-04-16" created_at="1400000000000"/>
   <issue_changes id="5" kee="[null]" issue_key="ISSUE-5" created_at="[null]" updated_at="[null]" user_login="admin" change_type="comment" change_data="abc" issue_change_creation_date="[null]"/>
 
 </dataset>
index 48199bb19d071d28099900a9590bd61cffa633ee..e0f151ac9d0b24813dfb5a8783482e8d7ab8bb62 100644 (file)
@@ -109,7 +109,7 @@ public class DefaultIssue implements Issue {
   private boolean sendNotifications = false;
 
   // Date when issue was loaded from db (only when isNew=false)
-  private Date selectedAt;
+  private Long selectedAt;
 
   @Override
   public String key() {
@@ -548,11 +548,11 @@ public class DefaultIssue implements Issue {
   }
 
   @CheckForNull
-  public Date selectedAt() {
+  public Long selectedAt() {
     return selectedAt;
   }
 
-  public DefaultIssue setSelectedAt(@Nullable Date d) {
+  public DefaultIssue setSelectedAt(@Nullable Long d) {
     this.selectedAt = d;
     return this;
   }
index 4ee5587d843ecd98d16aee3887c59987ab3a8dd4..0f145f0f2c8da2269a6ca4c983e73ca6ccbe3ed0 100644 (file)
@@ -68,7 +68,7 @@ public class DefaultIssueTest {
       .setCreationDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-19"))
       .setUpdateDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-20"))
       .setCloseDate(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-21"))
-      .setSelectedAt(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-22"))
+      .setSelectedAt(1400000000000L)
     ;
 
     assertThat(issue.key()).isEqualTo("ABCD");
@@ -98,7 +98,7 @@ public class DefaultIssueTest {
     assertThat(issue.creationDate()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-19"));
     assertThat(issue.updateDate()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-20"));
     assertThat(issue.closeDate()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-21"));
-    assertThat(issue.selectedAt()).isEqualTo(new SimpleDateFormat("yyyy-MM-dd").parse("2013-08-22"));
+    assertThat(issue.selectedAt()).isEqualTo(1400000000000L);
   }
 
   @Test