]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6253 Cache of component ids do not contains anymore key and uuid 348/head
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Wed, 3 Jun 2015 08:15:21 +0000 (10:15 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Wed, 3 Jun 2015 08:50:00 +0000 (10:50 +0200)
Instead, use TreeRootHolder to get component key and uuid

35 files changed:
server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/PersistFileSourcesStepTest.java
server/sonar-server/src/main/java/org/sonar/server/computation/component/DbComponentsRefCache.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/component/DbIdsRepository.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainerImpl.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/ApplyPermissionsStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexComponentsStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexSourceLinesStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexTestsStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistDuplicationsStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistEventsStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistFileSourcesStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistMeasuresStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistProjectLinksStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistTestsStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/PurgeDatastoresStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/step/SendIssueNotificationsStep.java
server/sonar-server/src/test/java/org/sonar/server/computation/batch/ComponentTreeRule.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/computation/component/DbComponentsRefCacheTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/computation/component/DbIdsRepositoryTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/computation/step/ApplyPermissionsStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexComponentsStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexSourceLinesStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexTestsStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistDuplicationsStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistEventsStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistFileSourcesStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistProjectLinksStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistTestsStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeDatastoresStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/step/SendIssueNotificationsStepTest.java

index 4919aa890d4afa06f5d1dec7d818aa2acf838401..d4bad3f9b502987288891d58ce9898d93f05c72e 100644 (file)
@@ -33,8 +33,9 @@ import org.sonar.batch.protocol.Constants;
 import org.sonar.batch.protocol.output.BatchReport;
 import org.sonar.core.persistence.DbTester;
 import org.sonar.server.computation.batch.BatchReportReaderRule;
-import org.sonar.server.computation.component.DbComponentsRefCache;
-import org.sonar.server.computation.component.DbComponentsRefCache.DbComponent;
+import org.sonar.server.computation.batch.TreeRootHolderRule;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DumbComponent;
 import org.sonar.server.computation.step.PersistFileSourcesStep;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.source.db.FileSourceDao;
@@ -49,12 +50,15 @@ public class PersistFileSourcesStepTest {
   public static final int NUMBER_OF_LINES = 1000;
   public static final String PROJECT_UUID = Uuids.create();
 
-  DbComponentsRefCache dbComponentsRefCache = new DbComponentsRefCache();
-
   @Rule
   public DbTester dbTester = new DbTester();
+
   @Rule
   public Benchmark benchmark = new Benchmark();
+
+  @Rule
+  public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
+
   @Rule
   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
 
@@ -70,7 +74,7 @@ public class PersistFileSourcesStepTest {
 
     long start = System.currentTimeMillis();
 
-    PersistFileSourcesStep step = new PersistFileSourcesStep(dbClient, System2.INSTANCE, dbComponentsRefCache, reportReader);
+    PersistFileSourcesStep step = new PersistFileSourcesStep(dbClient, System2.INSTANCE, treeRootHolder, reportReader);
     step.execute();
 
     long end = System.currentTimeMillis();
@@ -92,17 +96,17 @@ public class PersistFileSourcesStepTest {
       .setRef(1)
       .setType(Constants.ComponentType.PROJECT);
 
-    dbComponentsRefCache.addComponent(1, new DbComponent(1L, "PROJECT", PROJECT_UUID));
-
+    List<Component> components = new ArrayList<>();
     for (int fileRef = 2; fileRef <= NUMBER_OF_FILES + 1; fileRef++) {
-      generateFileReport(fileRef);
+      components.add(generateFileReport(fileRef));
       project.addChildRef(fileRef);
     }
+    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, PROJECT_UUID, "PROJECT", components.toArray(new Component[components.size()])));
 
     reportReader.putComponent(project.build());
   }
 
-  private void generateFileReport(int fileRef) throws IOException {
+  private Component generateFileReport(int fileRef) throws IOException {
     LineData lineData = new LineData();
     for (int line = 1; line <= NUMBER_OF_LINES; line++) {
       lineData.generateLineData(line);
@@ -113,14 +117,14 @@ public class PersistFileSourcesStepTest {
       .setLines(NUMBER_OF_LINES)
       .build());
 
-    dbComponentsRefCache.addComponent(fileRef, new DbComponent((long) fileRef, "PROJECT:" + fileRef, Uuids.create()));
-
     reportReader.putFileSourceLines(fileRef, lineData.lines);
     reportReader.putCoverage(fileRef, lineData.coverages);
     reportReader.putChangesets(lineData.changesetsBuilder.setComponentRef(fileRef).build());
     reportReader.putSyntaxHighlighting(fileRef, lineData.highlightings);
     reportReader.putSymbols(fileRef, lineData.symbols);
     reportReader.putDuplications(fileRef, lineData.duplications);
+
+    return new DumbComponent(Component.Type.FILE, fileRef, Uuids.create(), "PROJECT:" + fileRef);
   }
 
   private static class LineData {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/component/DbComponentsRefCache.java b/server/sonar-server/src/main/java/org/sonar/server/computation/component/DbComponentsRefCache.java
deleted file mode 100644 (file)
index 3c9dda6..0000000
+++ /dev/null
@@ -1,76 +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.computation.component;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Cache of components (id, uuid and key) that can be used in the persistence steps
- * Snapshot id will also be added in this cache
- */
-public class DbComponentsRefCache {
-
-  private final Map<Integer, DbComponent> componentsByRef;
-
-  public DbComponentsRefCache() {
-    componentsByRef = new HashMap<>();
-  }
-
-  public DbComponentsRefCache addComponent(Integer ref, DbComponent component) {
-    componentsByRef.put(ref, component);
-    return this;
-  }
-
-  public DbComponent getByRef(Integer ref) {
-    DbComponent component = componentsByRef.get(ref);
-    if (component == null) {
-      throw new IllegalArgumentException(String.format("Component ref '%s' does not exists", ref));
-    }
-    return componentsByRef.get(ref);
-  }
-
-  public static class DbComponent {
-
-    private Long id;
-    private String uuid;
-    private String key;
-
-    public DbComponent(Long id, String key, String uuid) {
-      this.id = id;
-      this.key = key;
-      this.uuid = uuid;
-    }
-
-    public Long getId() {
-      return id;
-    }
-
-    public String getKey() {
-      return key;
-    }
-
-    public String getUuid() {
-      return uuid;
-    }
-
-  }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/component/DbIdsRepository.java b/server/sonar-server/src/main/java/org/sonar/server/computation/component/DbIdsRepository.java
new file mode 100644 (file)
index 0000000..a07059b
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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.computation.component;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Cache of persisted component (component id) that can be used in the persistence steps
+ */
+public class DbIdsRepository {
+
+  private final Map<Integer, Long> componentIdsByRef;
+
+  public DbIdsRepository() {
+    componentIdsByRef = new HashMap<>();
+  }
+
+  public DbIdsRepository setComponentId(Component component, long componentId) {
+    int ref = component.getRef();
+    Long existingComponentId = componentIdsByRef.get(ref);
+    if (existingComponentId != null) {
+      throw new IllegalArgumentException(String.format("Component ref '%s' has already a component id", ref));
+    }
+    componentIdsByRef.put(ref, componentId);
+    return this;
+  }
+
+  public long getComponentId(Component component) {
+    int ref = component.getRef();
+    Long componentId = componentIdsByRef.get(ref);
+    if (componentId == null) {
+      throw new IllegalArgumentException(String.format("Component ref '%s' has no component id", ref));
+    }
+    return componentId;
+  }
+
+}
index 2dd0c519cc327f916ce77b8182bfd12957df2e11..897160138c18da0a637e70a5b4c8469874da9512 100644 (file)
@@ -36,7 +36,7 @@ import org.sonar.server.computation.ReportQueue;
 import org.sonar.server.computation.activity.ActivityManager;
 import org.sonar.server.computation.batch.BatchReportDirectoryHolderImpl;
 import org.sonar.server.computation.batch.BatchReportReaderImpl;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.component.DbIdsRepository;
 import org.sonar.server.computation.component.ProjectSettingsRepository;
 import org.sonar.server.computation.component.TreeRootHolderImpl;
 import org.sonar.server.computation.event.EventRepositoryImpl;
@@ -126,7 +126,7 @@ public class ComputeEngineContainerImpl extends ComponentContainer implements Co
       ProjectSettingsRepository.class,
 
       // component caches
-      DbComponentsRefCache.class,
+      DbIdsRepository.class,
 
       // issues
       ScmAccountCacheLoader.class,
index e67e6b15809619c10c916b5c89766b173fb65a36..0b30dbf19e5fdb3487b96f0e2d5b8cc164c02e5d 100644 (file)
@@ -24,7 +24,7 @@ import org.sonar.api.resources.Qualifiers;
 import org.sonar.core.permission.PermissionFacade;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.persistence.MyBatis;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.component.DbIdsRepository;
 import org.sonar.server.computation.component.TreeRootHolder;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.issue.index.IssueAuthorizationIndexer;
@@ -35,15 +35,15 @@ import org.sonar.server.issue.index.IssueAuthorizationIndexer;
 public class ApplyPermissionsStep implements ComputationStep {
 
   private final DbClient dbClient;
-  private final DbComponentsRefCache dbComponentsRefCache;
+  private final DbIdsRepository dbIdsRepository;
   private final IssueAuthorizationIndexer indexer;
   private final PermissionFacade permissionFacade;
   private final TreeRootHolder treeRootHolder;
 
-  public ApplyPermissionsStep(DbClient dbClient, DbComponentsRefCache dbComponentsRefCache, IssueAuthorizationIndexer indexer,
+  public ApplyPermissionsStep(DbClient dbClient, DbIdsRepository dbIdsRepository, IssueAuthorizationIndexer indexer,
     PermissionFacade permissionFacade, TreeRootHolder treeRootHolder) {
     this.dbClient = dbClient;
-    this.dbComponentsRefCache = dbComponentsRefCache;
+    this.dbIdsRepository = dbIdsRepository;
     this.indexer = indexer;
     this.permissionFacade = permissionFacade;
     this.treeRootHolder = treeRootHolder;
@@ -53,7 +53,7 @@ public class ApplyPermissionsStep implements ComputationStep {
   public void execute() {
     DbSession session = dbClient.openSession(false);
     try {
-      long projectId = dbComponentsRefCache.getByRef(treeRootHolder.getRoot().getRef()).getId();
+      long projectId = dbIdsRepository.getComponentId(treeRootHolder.getRoot());
       if (permissionFacade.countComponentPermissions(session, projectId) == 0) {
         permissionFacade.grantDefaultRoles(session, projectId, Qualifiers.PROJECT);
         session.commit();
index 75b8d6acb2be144dd7d5eeb2eca2128cecf1be9b..5328525912192a2faaf2d767657a04f768497d0e 100644 (file)
 package org.sonar.server.computation.step;
 
 import org.sonar.core.resource.ResourceIndexerDao;
-import org.sonar.server.computation.batch.BatchReportReader;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.component.DbIdsRepository;
+import org.sonar.server.computation.component.TreeRootHolder;
 
 /**
  * Components are currently indexed in db table RESOURCE_INDEX, not in Elasticsearch
  */
 public class IndexComponentsStep implements ComputationStep {
+
   private final ResourceIndexerDao resourceIndexerDao;
-  private final DbComponentsRefCache dbComponentsRefCache;
-  private final BatchReportReader reportReader;
+  private final DbIdsRepository dbIdsRepository;
+  private final TreeRootHolder treeRootHolder;
 
-  public IndexComponentsStep(ResourceIndexerDao resourceIndexerDao, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) {
+  public IndexComponentsStep(ResourceIndexerDao resourceIndexerDao, DbIdsRepository dbIdsRepository, TreeRootHolder treeRootHolder) {
     this.resourceIndexerDao = resourceIndexerDao;
-    this.dbComponentsRefCache = dbComponentsRefCache;
-    this.reportReader = reportReader;
+    this.dbIdsRepository = dbIdsRepository;
+    this.treeRootHolder = treeRootHolder;
   }
 
   @Override
   public void execute() {
-    resourceIndexerDao.indexProject(dbComponentsRefCache.getByRef(reportReader.readMetadata().getRootComponentRef()).getId());
+    resourceIndexerDao.indexProject(dbIdsRepository.getComponentId(treeRootHolder.getRoot()));
   }
 
   @Override
index ee709b8e1541f13b97669e9f6e3febb4b423bcbb..237871065bf68019aaf28f2e53935ab8af051925 100644 (file)
  */
 package org.sonar.server.computation.step;
 
-import org.sonar.server.computation.batch.BatchReportReader;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.component.TreeRootHolder;
 import org.sonar.server.source.index.SourceLineIndexer;
 
 public class IndexSourceLinesStep implements ComputationStep {
 
   private final SourceLineIndexer indexer;
-  private final DbComponentsRefCache dbComponentsRefCache;
-  private final BatchReportReader reportReader;
+  private final TreeRootHolder treeRootHolder;
 
-  public IndexSourceLinesStep(SourceLineIndexer indexer, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) {
+  public IndexSourceLinesStep(SourceLineIndexer indexer, TreeRootHolder treeRootHolder) {
     this.indexer = indexer;
-    this.dbComponentsRefCache = dbComponentsRefCache;
-    this.reportReader = reportReader;
+    this.treeRootHolder = treeRootHolder;
   }
 
   @Override
   public void execute() {
-    indexer.index(dbComponentsRefCache.getByRef(reportReader.readMetadata().getRootComponentRef()).getUuid());
+    indexer.index(treeRootHolder.getRoot().getUuid());
   }
 
   @Override
index bd5666e539a93b2ba2217be47a7c302cacb49b57..663b0c2030e74dc0892098c6940df0ba746117a5 100644 (file)
 
 package org.sonar.server.computation.step;
 
-import org.sonar.server.computation.batch.BatchReportReader;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.component.TreeRootHolder;
 import org.sonar.server.test.index.TestIndexer;
 
 public class IndexTestsStep implements ComputationStep {
 
   private final TestIndexer indexer;
-  private final DbComponentsRefCache dbComponentsRefCache;
-  private final BatchReportReader reportReader;
+  private final TreeRootHolder treeRootHolder;
 
-  public IndexTestsStep(TestIndexer indexer, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) {
+  public IndexTestsStep(TestIndexer indexer, TreeRootHolder treeRootHolder) {
     this.indexer = indexer;
-    this.dbComponentsRefCache = dbComponentsRefCache;
-    this.reportReader = reportReader;
+    this.treeRootHolder = treeRootHolder;
   }
 
   @Override
   public void execute() {
-    indexer.index(dbComponentsRefCache.getByRef(reportReader.readMetadata().getRootComponentRef()).getUuid());
+    indexer.index(treeRootHolder.getRoot().getUuid());
   }
 
   @Override
index 629b883697b21da57ee09a050b94a276830dc263..98d0c2dce3c3a98ec3d7594765f49c3d8e0635f1 100644 (file)
@@ -34,20 +34,20 @@ import org.sonar.core.persistence.DbSession;
 import org.sonar.core.util.NonNullInputFunction;
 import org.sonar.server.computation.batch.BatchReportReader;
 import org.sonar.server.computation.component.Component;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.component.DbIdsRepository;
 import org.sonar.server.computation.component.TreeRootHolder;
 import org.sonar.server.db.DbClient;
 
 public class PersistComponentsStep implements ComputationStep {
 
   private final DbClient dbClient;
-  private final DbComponentsRefCache dbComponentsRefCache;
+  private final DbIdsRepository dbIdsRepository;
   private final BatchReportReader reportReader;
   private final TreeRootHolder treeRootHolder;
 
-  public PersistComponentsStep(DbClient dbClient, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader, TreeRootHolder treeRootHolder) {
+  public PersistComponentsStep(DbClient dbClient, DbIdsRepository dbIdsRepository, BatchReportReader reportReader, TreeRootHolder treeRootHolder) {
     this.dbClient = dbClient;
-    this.dbComponentsRefCache = dbComponentsRefCache;
+    this.dbIdsRepository = dbIdsRepository;
     this.reportReader = reportReader;
     this.treeRootHolder = treeRootHolder;
   }
@@ -109,7 +109,7 @@ public class PersistComponentsStep implements ComputationStep {
     componentDto.setProjectUuid(componentDto.uuid());
     componentDto.setModuleUuidPath(ComponentDto.MODULE_UUID_PATH_SEP + componentDto.uuid() + ComponentDto.MODULE_UUID_PATH_SEP);
 
-    return persistComponent(project.getRef(), componentDto, componentContext);
+    return persistComponent(project, componentDto, componentContext);
   }
 
   public ComponentDto processModule(Component module, BatchReport.Component reportComponent, ComponentContext componentContext, ComponentDto lastModule, long projectId) {
@@ -130,7 +130,7 @@ public class PersistComponentsStep implements ComputationStep {
     componentDto.setModuleUuid(lastModule.uuid());
     componentDto.setModuleUuidPath((lastModule.moduleUuidPath() + componentDto.uuid() + ComponentDto.MODULE_UUID_PATH_SEP));
 
-    return persistComponent(module.getRef(), componentDto, componentContext);
+    return persistComponent(module, componentDto, componentContext);
   }
 
   public void processDirectory(Component directory, BatchReport.Component reportComponent, ComponentContext componentContext, ComponentDto lastModule, long projectId) {
@@ -149,7 +149,7 @@ public class PersistComponentsStep implements ComputationStep {
     componentDto.setModuleUuid(lastModule.uuid());
     componentDto.setModuleUuidPath(lastModule.moduleUuidPath());
 
-    persistComponent(directory.getRef(), componentDto, componentContext);
+    persistComponent(directory, componentDto, componentContext);
   }
 
   public void processFile(Component file, BatchReport.Component reportComponent, ComponentContext componentContext, ComponentDto lastModule, long projectId) {
@@ -171,7 +171,7 @@ public class PersistComponentsStep implements ComputationStep {
     componentDto.setModuleUuid(lastModule.uuid());
     componentDto.setModuleUuidPath(lastModule.moduleUuidPath());
 
-    persistComponent(file.getRef(), componentDto, componentContext);
+    persistComponent(file, componentDto, componentContext);
   }
 
   private ComponentDto createComponentDto(Component component) {
@@ -186,17 +186,17 @@ public class PersistComponentsStep implements ComputationStep {
     return componentDto;
   }
 
-  private ComponentDto persistComponent(int componentRef, ComponentDto componentDto, ComponentContext componentContext) {
+  private ComponentDto persistComponent(Component component, ComponentDto componentDto, ComponentContext componentContext) {
     ComponentDto existingComponent = componentContext.componentDtosByKey.get(componentDto.getKey());
     if (existingComponent == null) {
       dbClient.componentDao().insert(componentContext.dbSession, componentDto);
-      dbComponentsRefCache.addComponent(componentRef, new DbComponentsRefCache.DbComponent(componentDto.getId(), componentDto.getKey(), componentDto.uuid()));
+      dbIdsRepository.setComponentId(component, componentDto.getId());
       return componentDto;
     } else {
       if (updateComponent(existingComponent, componentDto)) {
         dbClient.componentDao().update(componentContext.dbSession, existingComponent);
       }
-      dbComponentsRefCache.addComponent(componentRef, new DbComponentsRefCache.DbComponent(existingComponent.getId(), existingComponent.getKey(), existingComponent.uuid()));
+      dbIdsRepository.setComponentId(component, existingComponent.getId());
       return existingComponent;
     }
   }
index 5cd1ae314cc8717d19d20e044017e5e3d08a6953..f635806afd1d9a53a9493f69baea9e2d25f137ef 100644 (file)
@@ -30,21 +30,28 @@ import org.sonar.core.metric.db.MetricDto;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.persistence.MyBatis;
 import org.sonar.server.computation.batch.BatchReportReader;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DbIdsRepository;
+import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
+import org.sonar.server.computation.component.TreeRootHolder;
 import org.sonar.server.db.DbClient;
 
+import static org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor.Order.PRE_ORDER;
+
 /**
  * Persist duplications into
  */
 public class PersistDuplicationsStep implements ComputationStep {
 
   private final DbClient dbClient;
-  private final DbComponentsRefCache dbComponentsRefCache;
+  private final DbIdsRepository dbIdsRepository;
+  private final TreeRootHolder treeRootHolder;
   private final BatchReportReader reportReader;
 
-  public PersistDuplicationsStep(DbClient dbClient, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) {
+  public PersistDuplicationsStep(DbClient dbClient, DbIdsRepository dbIdsRepository, TreeRootHolder treeRootHolder, BatchReportReader reportReader) {
     this.dbClient = dbClient;
-    this.dbComponentsRefCache = dbComponentsRefCache;
+    this.dbIdsRepository = dbIdsRepository;
+    this.treeRootHolder = treeRootHolder;
     this.reportReader = reportReader;
   }
 
@@ -52,102 +59,89 @@ public class PersistDuplicationsStep implements ComputationStep {
   public void execute() {
     DbSession session = dbClient.openSession(true);
     try {
-      MetricDto duplicationMetric = dbClient.metricDao().selectNullableByKey(session, CoreMetrics.DUPLICATIONS_DATA_KEY);
-      DuplicationContext duplicationContext = new DuplicationContext(duplicationMetric, session);
-      int rootComponentRef = reportReader.readMetadata().getRootComponentRef();
-      recursivelyProcessComponent(duplicationContext, rootComponentRef);
+      MetricDto duplicationMetric = dbClient.metricDao().selectByKey(session, CoreMetrics.DUPLICATIONS_DATA_KEY);
+      new DuplicationVisitor(session, duplicationMetric).visit(treeRootHolder.getRoot());
       session.commit();
     } finally {
       MyBatis.closeQuietly(session);
     }
   }
 
-  private void recursivelyProcessComponent(DuplicationContext duplicationContext, int componentRef) {
-    BatchReport.Component component = reportReader.readComponent(componentRef);
-    List<BatchReport.Duplication> duplications = reportReader.readComponentDuplications(componentRef);
-    if (!duplications.isEmpty()) {
-      saveDuplications(duplicationContext, component, duplications);
-    }
+  private class DuplicationVisitor extends DepthTraversalTypeAwareVisitor {
+
+    private final DbSession session;
+    private final MetricDto duplicationMetric;
 
-    for (Integer childRef : component.getChildRefList()) {
-      recursivelyProcessComponent(duplicationContext, childRef);
+    private DuplicationVisitor(DbSession session, MetricDto duplicationMetric) {
+      super(Component.Type.FILE, PRE_ORDER);
+      this.session = session;
+      this.duplicationMetric = duplicationMetric;
     }
-  }
 
-  private void saveDuplications(DuplicationContext duplicationContext, BatchReport.Component component, List<BatchReport.Duplication> duplications) {
+    @Override
+    public void visitFile(Component file) {
+      visitComponent(file);
+    }
 
-    DbComponentsRefCache.DbComponent dbComponent = dbComponentsRefCache.getByRef(component.getRef());
-    String duplicationXml = createXmlDuplications(duplicationContext, dbComponent.getKey(), duplications);
-    MeasureDto measureDto = new MeasureDto()
-      .setMetricId(duplicationContext.metric().getId())
-      .setData(duplicationXml)
-      .setComponentId(dbComponent.getId())
-      .setSnapshotId(component.getSnapshotId());
-    dbClient.measureDao().insert(duplicationContext.session(), measureDto);
-  }
+    private void visitComponent(Component component) {
+      List<BatchReport.Duplication> duplications = reportReader.readComponentDuplications(component.getRef());
+      if (!duplications.isEmpty()) {
+        BatchReport.Component batchComponent = reportReader.readComponent(component.getRef());
+        saveDuplications(batchComponent, component, duplications);
+      }
+    }
 
-  private String createXmlDuplications(DuplicationContext duplicationContext, String componentKey, Iterable<BatchReport.Duplication> duplications) {
+    private void saveDuplications(BatchReport.Component batchComponent, Component component, List<BatchReport.Duplication> duplications) {
+      String duplicationXml = createXmlDuplications(component.getKey(), duplications);
+      MeasureDto measureDto = new MeasureDto()
+        .setMetricId(duplicationMetric.getId())
+        .setData(duplicationXml)
+        .setComponentId(dbIdsRepository.getComponentId(component))
+        .setSnapshotId(batchComponent.getSnapshotId());
+      dbClient.measureDao().insert(session, measureDto);
+    }
 
-    StringBuilder xml = new StringBuilder();
-    xml.append("<duplications>");
-    for (BatchReport.Duplication duplication : duplications) {
-      xml.append("<g>");
-      appendDuplication(xml, componentKey, duplication.getOriginPosition());
-      for (BatchReport.Duplicate duplicationBlock : duplication.getDuplicateList()) {
-        processDuplicationBlock(duplicationContext, xml, duplicationBlock, componentKey);
+    private String createXmlDuplications(String componentKey, Iterable<BatchReport.Duplication> duplications) {
+      StringBuilder xml = new StringBuilder();
+      xml.append("<duplications>");
+      for (BatchReport.Duplication duplication : duplications) {
+        xml.append("<g>");
+        appendDuplication(xml, componentKey, duplication.getOriginPosition());
+        for (BatchReport.Duplicate duplicationBlock : duplication.getDuplicateList()) {
+          processDuplicationBlock(xml, duplicationBlock, componentKey);
+        }
+        xml.append("</g>");
       }
-      xml.append("</g>");
+      xml.append("</duplications>");
+      return xml.toString();
     }
-    xml.append("</duplications>");
-    return xml.toString();
-  }
 
-  private void processDuplicationBlock(DuplicationContext duplicationContext, StringBuilder xml, BatchReport.Duplicate duplicate, String componentKey) {
-
-    if (duplicate.hasOtherFileKey()) {
-      // componentKey is only set for cross project duplications
-      String crossProjectComponentKey = duplicate.getOtherFileKey();
-      appendDuplication(xml, crossProjectComponentKey, duplicate);
-    } else {
-      if (duplicate.hasOtherFileRef()) {
-        // Duplication is on a different file
-        BatchReport.Component duplicationComponent = reportReader.readComponent(duplicate.getOtherFileRef());
-        DbComponentsRefCache.DbComponent dbComponent = dbComponentsRefCache.getByRef(duplicationComponent.getRef());
-        appendDuplication(xml, dbComponent.getKey(), duplicate);
+    private void processDuplicationBlock(StringBuilder xml, BatchReport.Duplicate duplicate, String componentKey) {
+      if (duplicate.hasOtherFileKey()) {
+        // componentKey is only set for cross project duplications
+        String crossProjectComponentKey = duplicate.getOtherFileKey();
+        appendDuplication(xml, crossProjectComponentKey, duplicate);
       } else {
-        // Duplication is on a the same file
-        appendDuplication(xml, componentKey, duplicate);
+        if (duplicate.hasOtherFileRef()) {
+          // Duplication is on a different file
+          appendDuplication(xml, treeRootHolder.getComponentByRef(duplicate.getOtherFileRef()).getKey(), duplicate);
+        } else {
+          // Duplication is on a the same file
+          appendDuplication(xml, componentKey, duplicate);
+        }
       }
     }
-  }
-
-  private static void appendDuplication(StringBuilder xml, String componentKey, BatchReport.Duplicate duplicate) {
-    appendDuplication(xml, componentKey, duplicate.getRange());
-  }
-
-  private static void appendDuplication(StringBuilder xml, String componentKey, Range range) {
-    int length = range.getEndLine() - range.getStartLine() + 1;
-    xml.append("<b s=\"").append(range.getStartLine())
-      .append("\" l=\"").append(length)
-      .append("\" r=\"").append(StringEscapeUtils.escapeXml(componentKey))
-      .append("\"/>");
-  }
-
-  private static class DuplicationContext {
-    private DbSession session;
-    private MetricDto duplicationMetric;
-
-    DuplicationContext(MetricDto duplicationMetric, DbSession session) {
-      this.duplicationMetric = duplicationMetric;
-      this.session = session;
-    }
 
-    public MetricDto metric() {
-      return duplicationMetric;
+    private void appendDuplication(StringBuilder xml, String componentKey, BatchReport.Duplicate duplicate) {
+      appendDuplication(xml, componentKey, duplicate.getRange());
     }
 
-    public DbSession session() {
-      return session;
+    private void appendDuplication(StringBuilder xml, String componentKey, Range range) {
+      int length = range.getEndLine() - range.getStartLine() + 1;
+      xml.append("<b s=\"").append(range.getStartLine())
+        .append("\" l=\"").append(length)
+        .append("\" r=\"").append(StringEscapeUtils.escapeXml(componentKey))
+        .append("\"/>");
     }
   }
 
index 45c9aef8f3b0c4bb5872109e72dc716ca4942e72..e1a6af7af2e09c9b221f7e5d98c41c4b97bd7fe0 100644 (file)
@@ -28,20 +28,24 @@ import org.sonar.core.event.EventDto;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.persistence.MyBatis;
 import org.sonar.server.computation.batch.BatchReportReader;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
+import org.sonar.server.computation.component.TreeRootHolder;
 import org.sonar.server.db.DbClient;
 
+import static org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor.Order.PRE_ORDER;
+
 public class PersistEventsStep implements ComputationStep {
 
   private final DbClient dbClient;
   private final System2 system2;
-  private final DbComponentsRefCache dbComponentsRefCache;
+  private final TreeRootHolder treeRootHolder;
   private final BatchReportReader reportReader;
 
-  public PersistEventsStep(DbClient dbClient, System2 system2, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) {
+  public PersistEventsStep(DbClient dbClient, System2 system2, TreeRootHolder treeRootHolder, BatchReportReader reportReader) {
     this.dbClient = dbClient;
     this.system2 = system2;
-    this.dbComponentsRefCache = dbComponentsRefCache;
+    this.treeRootHolder = treeRootHolder;
     this.reportReader = reportReader;
   }
 
@@ -49,73 +53,89 @@ public class PersistEventsStep implements ComputationStep {
   public void execute() {
     DbSession session = dbClient.openSession(false);
     try {
-      int rootComponentRef = reportReader.readMetadata().getRootComponentRef();
-      recursivelyProcessComponent(session, rootComponentRef);
+      new EventVisitor(session, reportReader.readMetadata().getAnalysisDate()).visit(treeRootHolder.getRoot());
       session.commit();
     } finally {
       MyBatis.closeQuietly(session);
     }
   }
 
-  private void recursivelyProcessComponent(DbSession session, int componentRef) {
-    BatchReport.Component component = reportReader.readComponent(componentRef);
-    long analysisDate = reportReader.readMetadata().getAnalysisDate();
-    processEvents(session, component, analysisDate);
-    saveVersionEvent(session, component, analysisDate);
+  private class EventVisitor extends DepthTraversalTypeAwareVisitor {
+
+    private final DbSession session;
+    private final long analysisDate;
 
-    for (Integer childRef : component.getChildRefList()) {
-      recursivelyProcessComponent(session, childRef);
+    private EventVisitor(DbSession session, long analysisDate) {
+      super(Component.Type.FILE, PRE_ORDER);
+      this.session = session;
+      this.analysisDate = analysisDate;
     }
-  }
 
-  private void processEvents(DbSession session, BatchReport.Component component, Long analysisDate) {
-    List<BatchReport.Event> events = component.getEventList();
-    if (!events.isEmpty()) {
-      for (BatchReport.Event event : component.getEventList()) {
-        dbClient.eventDao().insert(session, newBaseEvent(component, analysisDate)
-          .setName(event.getName())
-          .setCategory(convertCategory(event.getCategory()))
-          .setDescription(event.hasDescription() ? event.getDescription() : null)
-          .setData(event.hasEventData() ? event.getEventData() : null)
-          );
+    @Override
+    public void visitModule(Component module) {
+      visitProjectOrModule(module);
+    }
+
+    @Override
+    public void visitProject(Component project) {
+      visitProjectOrModule(project);
+    }
+
+    private void visitProjectOrModule(Component component) {
+      BatchReport.Component batchComponent = reportReader.readComponent(component.getRef());
+      processEvents(batchComponent, component);
+      saveVersionEvent(batchComponent, component);
+    }
+
+    private void processEvents(BatchReport.Component batchComponent, Component component) {
+      List<BatchReport.Event> events = batchComponent.getEventList();
+      if (!events.isEmpty()) {
+        for (BatchReport.Event event : events) {
+          dbClient.eventDao().insert(session, newBaseEvent(component, batchComponent.getSnapshotId())
+            .setName(event.getName())
+            .setCategory(convertCategory(event.getCategory()))
+            .setDescription(event.hasDescription() ? event.getDescription() : null)
+            .setData(event.hasEventData() ? event.getEventData() : null)
+            );
+        }
       }
     }
-  }
 
-  private void saveVersionEvent(DbSession session, BatchReport.Component component, Long analysisDate) {
-    if (component.hasVersion()) {
-      deletePreviousEventsHavingSameVersion(session, component);
-      dbClient.eventDao().insert(session, newBaseEvent(component, analysisDate)
-        .setName(component.getVersion())
-        .setCategory(EventDto.CATEGORY_VERSION)
-        );
+    private void saveVersionEvent(BatchReport.Component batchComponent, Component component) {
+      if (batchComponent.hasVersion()) {
+        deletePreviousEventsHavingSameVersion(batchComponent, component);
+        dbClient.eventDao().insert(session, newBaseEvent(component, batchComponent.getSnapshotId())
+          .setName(batchComponent.getVersion())
+          .setCategory(EventDto.CATEGORY_VERSION)
+          );
+      }
     }
-  }
 
-  private void deletePreviousEventsHavingSameVersion(DbSession session, BatchReport.Component component) {
-    for (EventDto dto : dbClient.eventDao().selectByComponentUuid(session, dbComponentsRefCache.getByRef(component.getRef()).getUuid())) {
-      if (dto.getCategory().equals(EventDto.CATEGORY_VERSION) && dto.getName().equals(component.getVersion())) {
-        dbClient.eventDao().delete(session, dto.getId());
+    private void deletePreviousEventsHavingSameVersion(BatchReport.Component batchComponent, Component component) {
+      for (EventDto dto : dbClient.eventDao().selectByComponentUuid(session, component.getUuid())) {
+        if (dto.getCategory().equals(EventDto.CATEGORY_VERSION) && dto.getName().equals(batchComponent.getVersion())) {
+          dbClient.eventDao().delete(session, dto.getId());
+        }
       }
     }
-  }
 
-  private EventDto newBaseEvent(BatchReport.Component component, Long analysisDate) {
-    return new EventDto()
-      .setComponentUuid(dbComponentsRefCache.getByRef(component.getRef()).getUuid())
-      .setSnapshotId(component.getSnapshotId())
-      .setCreatedAt(system2.now())
-      .setDate(analysisDate);
-  }
+    private EventDto newBaseEvent(Component component, long snapshotId) {
+      return new EventDto()
+        .setComponentUuid(component.getUuid())
+        .setSnapshotId(snapshotId)
+        .setCreatedAt(system2.now())
+        .setDate(analysisDate);
+    }
 
-  private static String convertCategory(Constants.EventCategory category) {
-    switch (category) {
-      case ALERT:
-        return EventDto.CATEGORY_ALERT;
-      case PROFILE:
-        return EventDto.CATEGORY_PROFILE;
-      default:
-        throw new IllegalArgumentException(String.format("Unsupported category %s", category.name()));
+    private String convertCategory(Constants.EventCategory category) {
+      switch (category) {
+        case ALERT:
+          return EventDto.CATEGORY_ALERT;
+        case PROFILE:
+          return EventDto.CATEGORY_PROFILE;
+        default:
+          throw new IllegalArgumentException(String.format("Unsupported category %s", category.name()));
+      }
     }
   }
 
index e988b39d41b619a8bfda4a1975ab83c6c6d6fa8a..523f4a3d608cd604add4b2d0ad0f01371b19f0c6 100644 (file)
@@ -29,14 +29,15 @@ import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.ibatis.session.ResultContext;
 import org.apache.ibatis.session.ResultHandler;
 import org.sonar.api.utils.System2;
-import org.sonar.batch.protocol.Constants;
 import org.sonar.batch.protocol.output.BatchReport;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.persistence.MyBatis;
 import org.sonar.core.source.db.FileSourceDto;
 import org.sonar.core.source.db.FileSourceDto.Type;
 import org.sonar.server.computation.batch.BatchReportReader;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
+import org.sonar.server.computation.component.TreeRootHolder;
 import org.sonar.server.computation.source.ComputeFileSourceData;
 import org.sonar.server.computation.source.CoverageLineReader;
 import org.sonar.server.computation.source.DuplicationLineReader;
@@ -48,28 +49,48 @@ import org.sonar.server.db.DbClient;
 import org.sonar.server.source.db.FileSourceDb;
 import org.sonar.server.util.CloseableIterator;
 
+import static org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor.Order.PRE_ORDER;
+
 public class PersistFileSourcesStep implements ComputationStep {
 
   private final DbClient dbClient;
   private final System2 system2;
-  private final DbComponentsRefCache dbComponentsRefCache;
+  private final TreeRootHolder treeRootHolder;
   private final BatchReportReader reportReader;
 
-  public PersistFileSourcesStep(DbClient dbClient, System2 system2, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) {
+  public PersistFileSourcesStep(DbClient dbClient, System2 system2, TreeRootHolder treeRootHolder, BatchReportReader reportReader) {
     this.dbClient = dbClient;
     this.system2 = system2;
-    this.dbComponentsRefCache = dbComponentsRefCache;
+    this.treeRootHolder = treeRootHolder;
     this.reportReader = reportReader;
   }
 
   @Override
   public void execute() {
-    int rootComponentRef = reportReader.readMetadata().getRootComponentRef();
     // Don't use batch insert for file_sources since keeping all data in memory can produce OOM for big files
     DbSession session = dbClient.openSession(false);
     try {
-      final Map<String, FileSourceDto> previousFileSourcesByUuid = new HashMap<>();
-      String projectUuid = dbComponentsRefCache.getByRef(rootComponentRef).getUuid();
+      new FileSourceVisitor(session).visit(treeRootHolder.getRoot());
+    } finally {
+      MyBatis.closeQuietly(session);
+    }
+  }
+
+  private class FileSourceVisitor extends DepthTraversalTypeAwareVisitor {
+
+    private final DbSession session;
+
+    private Map<String, FileSourceDto> previousFileSourcesByUuid = new HashMap<>();
+    private String projectUuid;
+
+    private FileSourceVisitor(DbSession session) {
+      super(Component.Type.FILE, PRE_ORDER);
+      this.session = session;
+    }
+
+    @Override
+    public void visitProject(Component project) {
+      this.projectUuid = project.getUuid();
       session.select("org.sonar.core.source.db.FileSourceMapper.selectHashesForProject", ImmutableMap.of("projectUuid", projectUuid, "dataType", Type.SOURCE),
         new ResultHandler() {
           @Override
@@ -78,90 +99,69 @@ public class PersistFileSourcesStep implements ComputationStep {
             previousFileSourcesByUuid.put(dto.getFileUuid(), dto);
           }
         });
-
-      recursivelyProcessComponent(new FileSourcesContext(session, previousFileSourcesByUuid, projectUuid), rootComponentRef);
-    } finally {
-      MyBatis.closeQuietly(session);
     }
-  }
 
-  private void recursivelyProcessComponent(FileSourcesContext fileSourcesContext, int componentRef) {
-    BatchReport.Component component = reportReader.readComponent(componentRef);
-    if (component.getType().equals(Constants.ComponentType.FILE)) {
-      CloseableIterator<String> linesIterator = reportReader.readFileSource(componentRef);
-      LineReaders lineReaders = new LineReaders(reportReader, componentRef);
+    @Override
+    public void visitFile(Component file) {
+      int fileRef = file.getRef();
+      BatchReport.Component component = reportReader.readComponent(fileRef);
+      CloseableIterator<String> linesIterator = reportReader.readFileSource(fileRef);
+      LineReaders lineReaders = new LineReaders(reportReader, fileRef);
       try {
         ComputeFileSourceData computeFileSourceData = new ComputeFileSourceData(linesIterator, lineReaders.readers(), component.getLines());
         ComputeFileSourceData.Data fileSourceData = computeFileSourceData.compute();
-        persistSource(fileSourcesContext, fileSourceData, component);
+        persistSource(fileSourceData, file.getUuid());
       } catch (Exception e) {
-        throw new IllegalStateException(String.format("Cannot persist sources of %s", component.getPath()), e);
+        throw new IllegalStateException(String.format("Cannot persist sources of %s", file.getKey()), e);
       } finally {
         linesIterator.close();
         lineReaders.close();
       }
     }
 
-    for (Integer childRef : component.getChildRefList()) {
-      recursivelyProcessComponent(fileSourcesContext, childRef);
-    }
-  }
+    private void persistSource(ComputeFileSourceData.Data fileSourceData, String componentUuid) {
+      FileSourceDb.Data fileData = fileSourceData.getFileSourceData();
 
-  private void persistSource(FileSourcesContext fileSourcesContext, ComputeFileSourceData.Data fileSourceData, BatchReport.Component component) {
-    FileSourceDb.Data fileData = fileSourceData.getFileSourceData();
-
-    byte[] data = FileSourceDto.encodeSourceData(fileData);
-    String dataHash = DigestUtils.md5Hex(data);
-    String srcHash = fileSourceData.getSrcHash();
-    String lineHashes = fileSourceData.getLineHashes();
-    String componentUuid = dbComponentsRefCache.getByRef(component.getRef()).getUuid();
-    FileSourceDto previousDto = fileSourcesContext.previousFileSourcesByUuid.get(componentUuid);
-
-    if (previousDto == null) {
-      FileSourceDto dto = new FileSourceDto()
-        .setProjectUuid(fileSourcesContext.projectUuid)
-        .setFileUuid(componentUuid)
-        .setDataType(Type.SOURCE)
-        .setBinaryData(data)
-        .setSrcHash(srcHash)
-        .setDataHash(dataHash)
-        .setLineHashes(lineHashes)
-        .setCreatedAt(system2.now())
-        .setUpdatedAt(system2.now());
-      dbClient.fileSourceDao().insert(fileSourcesContext.session, dto);
-      fileSourcesContext.session.commit();
-    } else {
-      // Update only if data_hash has changed or if src_hash is missing (progressive migration)
-      boolean binaryDataUpdated = !dataHash.equals(previousDto.getDataHash());
-      boolean srcHashUpdated = !srcHash.equals(previousDto.getSrcHash());
-      if (binaryDataUpdated || srcHashUpdated) {
-        previousDto
+      byte[] data = FileSourceDto.encodeSourceData(fileData);
+      String dataHash = DigestUtils.md5Hex(data);
+      String srcHash = fileSourceData.getSrcHash();
+      String lineHashes = fileSourceData.getLineHashes();
+      FileSourceDto previousDto = previousFileSourcesByUuid.get(componentUuid);
+
+      if (previousDto == null) {
+        FileSourceDto dto = new FileSourceDto()
+          .setProjectUuid(projectUuid)
+          .setFileUuid(componentUuid)
+          .setDataType(Type.SOURCE)
           .setBinaryData(data)
-          .setDataHash(dataHash)
           .setSrcHash(srcHash)
-          .setLineHashes(lineHashes);
-        // Optimization only change updated at when updating binary data to avoid unnecessary indexation by E/S
-        if (binaryDataUpdated) {
-          previousDto.setUpdatedAt(system2.now());
+          .setDataHash(dataHash)
+          .setLineHashes(lineHashes)
+          .setCreatedAt(system2.now())
+          .setUpdatedAt(system2.now());
+        dbClient.fileSourceDao().insert(session, dto);
+        session.commit();
+      } else {
+        // Update only if data_hash has changed or if src_hash is missing (progressive migration)
+        boolean binaryDataUpdated = !dataHash.equals(previousDto.getDataHash());
+        boolean srcHashUpdated = !srcHash.equals(previousDto.getSrcHash());
+        if (binaryDataUpdated || srcHashUpdated) {
+          previousDto
+            .setBinaryData(data)
+            .setDataHash(dataHash)
+            .setSrcHash(srcHash)
+            .setLineHashes(lineHashes);
+          // Optimization only change updated at when updating binary data to avoid unnecessary indexation by E/S
+          if (binaryDataUpdated) {
+            previousDto.setUpdatedAt(system2.now());
+          }
+          dbClient.fileSourceDao().update(previousDto);
+          session.commit();
         }
-        dbClient.fileSourceDao().update(previousDto);
-        fileSourcesContext.session.commit();
       }
     }
   }
 
-  private static class FileSourcesContext {
-    DbSession session;
-    Map<String, FileSourceDto> previousFileSourcesByUuid;
-    String projectUuid;
-
-    public FileSourcesContext(DbSession session, Map<String, FileSourceDto> previousFileSourcesByUuid, String projectUuid) {
-      this.previousFileSourcesByUuid = previousFileSourcesByUuid;
-      this.session = session;
-      this.projectUuid = projectUuid;
-    }
-  }
-
   private static class LineReaders {
     private final List<LineReader> readers = new ArrayList<>();
     private final List<CloseableIterator<?>> iterators = new ArrayList<>();
index b9e4129ff7a7aaf84b50a6b986fa8462b87aaa9e..f6f51d04271719e3445a5784710d0bacff4fc29b 100644 (file)
@@ -29,12 +29,16 @@ import org.sonar.batch.protocol.output.BatchReport;
 import org.sonar.core.measure.db.MeasureDto;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.server.computation.batch.BatchReportReader;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DbIdsRepository;
+import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
+import org.sonar.server.computation.component.TreeRootHolder;
 import org.sonar.server.computation.issue.RuleCache;
 import org.sonar.server.computation.measure.MetricCache;
 import org.sonar.server.db.DbClient;
 
 import static com.google.common.collect.Lists.newArrayList;
+import static org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor.Order.PRE_ORDER;
 
 public class PersistMeasuresStep implements ComputationStep {
 
@@ -46,15 +50,17 @@ public class PersistMeasuresStep implements ComputationStep {
   private final DbClient dbClient;
   private final RuleCache ruleCache;
   private final MetricCache metricCache;
-  private final DbComponentsRefCache dbComponentsRefCache;
+  private final DbIdsRepository dbIdsRepository;
+  private final TreeRootHolder treeRootHolder;
   private final BatchReportReader reportReader;
 
   public PersistMeasuresStep(DbClient dbClient, RuleCache ruleCache, MetricCache metricCache,
-    DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) {
+    DbIdsRepository dbIdsRepository, TreeRootHolder treeRootHolder, BatchReportReader reportReader) {
     this.dbClient = dbClient;
     this.ruleCache = ruleCache;
     this.metricCache = metricCache;
-    this.dbComponentsRefCache = dbComponentsRefCache;
+    this.dbIdsRepository = dbIdsRepository;
+    this.treeRootHolder = treeRootHolder;
     this.reportReader = reportReader;
   }
 
@@ -65,33 +71,45 @@ public class PersistMeasuresStep implements ComputationStep {
 
   @Override
   public void execute() {
-    int rootComponentRef = reportReader.readMetadata().getRootComponentRef();
-    try (DbSession dbSession = dbClient.openSession(true)) {
-      recursivelyProcessComponent(dbSession, rootComponentRef);
+    DbSession dbSession = dbClient.openSession(true);
+    try {
+      new MeasureVisitor(dbSession).visit(treeRootHolder.getRoot());
       dbSession.commit();
+    } finally {
+      dbSession.close();
     }
   }
 
-  private void recursivelyProcessComponent(DbSession dbSession, int componentRef) {
-    BatchReport.Component component = reportReader.readComponent(componentRef);
-    List<BatchReport.Measure> measures = reportReader.readComponentMeasures(componentRef);
-    persistMeasures(dbSession, measures, component);
-    for (Integer childRef : component.getChildRefList()) {
-      recursivelyProcessComponent(dbSession, childRef);
+  private class MeasureVisitor extends DepthTraversalTypeAwareVisitor {
+
+    private final DbSession session;
+
+    private MeasureVisitor(DbSession session) {
+      super(Component.Type.FILE, PRE_ORDER);
+      this.session = session;
+    }
+
+    @Override
+    protected void visitAny(Component component) {
+      int componentRef = component.getRef();
+      BatchReport.Component batchComponent = reportReader.readComponent(componentRef);
+      List<BatchReport.Measure> measures = reportReader.readComponentMeasures(componentRef);
+      persistMeasures(measures, dbIdsRepository.getComponentId(component), batchComponent.getSnapshotId());
+
     }
-  }
 
-  private void persistMeasures(DbSession dbSession, List<BatchReport.Measure> batchReportMeasures, final BatchReport.Component component) {
-    for (BatchReport.Measure measure : batchReportMeasures) {
-      if (FORBIDDEN_METRIC_KEYS.contains(measure.getMetricKey())) {
-        throw new IllegalStateException(String.format("Measures on metric '%s' cannot be send in the report", measure.getMetricKey()));
+    private void persistMeasures(List<BatchReport.Measure> batchReportMeasures, long componentId, long snapshotId) {
+      for (BatchReport.Measure measure : batchReportMeasures) {
+        if (FORBIDDEN_METRIC_KEYS.contains(measure.getMetricKey())) {
+          throw new IllegalStateException(String.format("Measures on metric '%s' cannot be send in the report", measure.getMetricKey()));
+        }
+        dbClient.measureDao().insert(session, toMeasureDto(measure, componentId, snapshotId));
       }
-      dbClient.measureDao().insert(dbSession, toMeasureDto(measure, component));
     }
   }
 
   @VisibleForTesting
-  MeasureDto toMeasureDto(BatchReport.Measure in, BatchReport.Component component) {
+  MeasureDto toMeasureDto(BatchReport.Measure in, long componentId, long snapshotId) {
     if (!in.hasValueType()) {
       throw new IllegalStateException(String.format("Measure %s does not have value type", in));
     }
@@ -109,8 +127,8 @@ public class PersistMeasuresStep implements ComputationStep {
     out.setAlertText(in.hasAlertText() ? in.getAlertText() : null);
     out.setDescription(in.hasDescription() ? in.getDescription() : null);
     out.setSeverity(in.hasSeverity() ? in.getSeverity().name() : null);
-    out.setComponentId(dbComponentsRefCache.getByRef(component.getRef()).getId());
-    out.setSnapshotId(component.getSnapshotId());
+    out.setComponentId(componentId);
+    out.setSnapshotId(snapshotId);
     out.setMetricId(metricCache.get(in.getMetricKey()).getId());
     out.setRuleId(in.hasRuleKey() ? ruleCache.get(RuleKey.parse(in.getRuleKey())).getId() : null);
     out.setCharacteristicId(in.hasCharactericId() ? in.getCharactericId() : null);
@@ -120,6 +138,13 @@ public class PersistMeasuresStep implements ComputationStep {
     return out;
   }
 
+  private MeasureDto setData(BatchReport.Measure in, MeasureDto out) {
+    if (in.hasStringValue()) {
+      out.setData(in.getStringValue());
+    }
+    return out;
+  }
+
   /**
    * return the numerical value as a double. It's the type used in db.
    * Returns null if no numerical value found
@@ -139,12 +164,4 @@ public class PersistMeasuresStep implements ComputationStep {
         return null;
     }
   }
-
-  private MeasureDto setData(BatchReport.Measure in, MeasureDto out) {
-    if (in.hasStringValue()) {
-      out.setData(in.getStringValue());
-    }
-
-    return out;
-  }
 }
index 8b1262c3af0af0a668a34ef21772350b7f4f12cd..74f9bd8258ee5782639e9a1dcb5fa9df84677388 100644 (file)
@@ -30,13 +30,15 @@ import org.sonar.core.measure.db.MeasureDto;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.persistence.MyBatis;
 import org.sonar.server.computation.batch.BatchReportReader;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
+import org.sonar.server.computation.component.TreeRootHolder;
 import org.sonar.server.computation.measure.MetricCache;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.source.index.SourceLineIndex;
 
 import static com.google.common.base.Objects.firstNonNull;
-import static com.google.common.base.Preconditions.checkState;
+import static org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor.Order.PRE_ORDER;
 
 public class PersistNumberOfDaysSinceLastCommitStep implements ComputationStep {
 
@@ -46,18 +48,16 @@ public class PersistNumberOfDaysSinceLastCommitStep implements ComputationStep {
   private final SourceLineIndex sourceLineIndex;
   private final MetricCache metricCache;
   private final System2 system;
-  private final DbComponentsRefCache dbComponentsRefCache;
+  private final TreeRootHolder treeRootHolder;
   private final BatchReportReader reportReader;
 
-  private long lastCommitTimestamp = 0L;
-
   public PersistNumberOfDaysSinceLastCommitStep(System2 system, DbClient dbClient, SourceLineIndex sourceLineIndex, MetricCache metricCache,
-                                                DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) {
+    TreeRootHolder treeRootHolder, BatchReportReader reportReader) {
     this.dbClient = dbClient;
     this.sourceLineIndex = sourceLineIndex;
     this.metricCache = metricCache;
     this.system = system;
-    this.dbComponentsRefCache = dbComponentsRefCache;
+    this.treeRootHolder = treeRootHolder;
     this.reportReader = reportReader;
   }
 
@@ -68,38 +68,17 @@ public class PersistNumberOfDaysSinceLastCommitStep implements ComputationStep {
 
   @Override
   public void execute() {
-    int rootComponentRef = reportReader.readMetadata().getRootComponentRef();
-    recursivelyProcessComponent(rootComponentRef);
+    NumberOfDaysSinceLastCommitVisitor visitor = new NumberOfDaysSinceLastCommitVisitor();
+    visitor.visit(treeRootHolder.getRoot());
 
-    if (!commitFound()) {
-      Long lastCommitFromIndex = lastCommitFromIndex(dbComponentsRefCache.getByRef(rootComponentRef).getUuid());
+    long lastCommitTimestamp = visitor.lastCommitTimestampFromReport;
+    if (lastCommitTimestamp == 0L) {
+      Long lastCommitFromIndex = lastCommitFromIndex(treeRootHolder.getRoot().getUuid());
       lastCommitTimestamp = firstNonNull(lastCommitFromIndex, lastCommitTimestamp);
     }
 
-    if (commitFound()) {
-      persistNumberOfDaysSinceLastCommit();
-    }
-  }
-
-  private void recursivelyProcessComponent(int componentRef) {
-    BatchReport.Component component = reportReader.readComponent(componentRef);
-    BatchReport.Changesets scm = reportReader.readChangesets(componentRef);
-    processScm(scm);
-
-    for (Integer childRef : component.getChildRefList()) {
-      recursivelyProcessComponent(childRef);
-    }
-  }
-
-  private void processScm(@Nullable BatchReport.Changesets scm) {
-    if (scm == null) {
-      return;
-    }
-
-    for (BatchReport.Changesets.Changeset changeset : scm.getChangesetList()) {
-      if (changeset.hasDate() && changeset.getDate() > lastCommitTimestamp) {
-        lastCommitTimestamp = changeset.getDate();
-      }
+    if (lastCommitTimestamp != 0L) {
+      persistNumberOfDaysSinceLastCommit(lastCommitTimestamp);
     }
   }
 
@@ -109,9 +88,7 @@ public class PersistNumberOfDaysSinceLastCommitStep implements ComputationStep {
     return lastCommitDate == null ? null : lastCommitDate.getTime();
   }
 
-  private void persistNumberOfDaysSinceLastCommit() {
-    checkState(commitFound(), "The last commit time should exist");
-
+  private void persistNumberOfDaysSinceLastCommit(long lastCommitTimestamp) {
     long numberOfDaysSinceLastCommit = (system.now() - lastCommitTimestamp) / MILLISECONDS_PER_DAY;
     DbSession dbSession = dbClient.openSession(true);
     try {
@@ -125,7 +102,30 @@ public class PersistNumberOfDaysSinceLastCommitStep implements ComputationStep {
     }
   }
 
-  private boolean commitFound() {
-    return lastCommitTimestamp != 0L;
+  private class NumberOfDaysSinceLastCommitVisitor extends DepthTraversalTypeAwareVisitor {
+
+    private long lastCommitTimestampFromReport = 0L;
+
+    private NumberOfDaysSinceLastCommitVisitor() {
+      super(Component.Type.FILE, PRE_ORDER);
+    }
+
+    @Override
+    public void visitFile(Component component) {
+      BatchReport.Changesets scm = reportReader.readChangesets(component.getRef());
+      processScm(scm);
+    }
+
+    private void processScm(@Nullable BatchReport.Changesets scm) {
+      if (scm == null) {
+        return;
+      }
+
+      for (BatchReport.Changesets.Changeset changeset : scm.getChangesetList()) {
+        if (changeset.hasDate() && changeset.getDate() > lastCommitTimestampFromReport) {
+          lastCommitTimestampFromReport = changeset.getDate();
+        }
+      }
+    }
   }
 }
index fa446ef3ea45eb57548d30a79891aeb698a272a2..949c73698de8875ec28e2fb1945cd9ca102aa8dd 100644 (file)
@@ -35,10 +35,13 @@ import org.sonar.core.component.ComponentLinkDto;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.persistence.MyBatis;
 import org.sonar.server.computation.batch.BatchReportReader;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
+import org.sonar.server.computation.component.TreeRootHolder;
 import org.sonar.server.db.DbClient;
 
 import static com.google.common.collect.Sets.newHashSet;
+import static org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor.Order.PRE_ORDER;
 
 /**
  * Persist project and module links
@@ -47,7 +50,7 @@ public class PersistProjectLinksStep implements ComputationStep {
 
   private final DbClient dbClient;
   private final I18n i18n;
-  private final DbComponentsRefCache dbComponentsRefCache;
+  private final TreeRootHolder treeRootHolder;
   private final BatchReportReader reportReader;
 
   private static final Map<Constants.ComponentLinkType, String> typesConverter = ImmutableMap.of(
@@ -58,10 +61,10 @@ public class PersistProjectLinksStep implements ComputationStep {
     Constants.ComponentLinkType.ISSUE, ComponentLinkDto.TYPE_ISSUE_TRACKER
     );
 
-  public PersistProjectLinksStep(DbClient dbClient, I18n i18n, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader) {
+  public PersistProjectLinksStep(DbClient dbClient, I18n i18n, TreeRootHolder treeRootHolder, BatchReportReader reportReader) {
     this.dbClient = dbClient;
     this.i18n = i18n;
-    this.dbComponentsRefCache = dbComponentsRefCache;
+    this.treeRootHolder = treeRootHolder;
     this.reportReader = reportReader;
   }
 
@@ -69,65 +72,76 @@ public class PersistProjectLinksStep implements ComputationStep {
   public void execute() {
     DbSession session = dbClient.openSession(false);
     try {
-      int rootComponentRef = reportReader.readMetadata().getRootComponentRef();
-      recursivelyProcessComponent(session, rootComponentRef);
+      new PorjectLinkVisitor(session).visit(treeRootHolder.getRoot());
       session.commit();
     } finally {
       MyBatis.closeQuietly(session);
     }
   }
 
-  private void recursivelyProcessComponent(DbSession session, int componentRef) {
-    BatchReport.Component component = reportReader.readComponent(componentRef);
-    processLinks(session, component);
+  private class PorjectLinkVisitor extends DepthTraversalTypeAwareVisitor {
 
-    for (Integer childRef : component.getChildRefList()) {
-      recursivelyProcessComponent(session, childRef);
+    private final DbSession session;
+
+    private PorjectLinkVisitor(DbSession session) {
+      super(Component.Type.FILE, PRE_ORDER);
+      this.session = session;
+    }
+
+    @Override
+    public void visitProject(Component project) {
+      processComponent(project);
     }
-  }
 
-  private void processLinks(DbSession session, BatchReport.Component component) {
-    if (component.getType().equals(Constants.ComponentType.PROJECT) || component.getType().equals(Constants.ComponentType.MODULE)) {
-      List<BatchReport.ComponentLink> links = component.getLinkList();
-      String componentUuid = dbComponentsRefCache.getByRef(component.getRef()).getUuid();
+    @Override
+    public void visitModule(Component module) {
+      processComponent(module);
+    }
+
+    private void processComponent(Component component) {
+      BatchReport.Component batchComponent = reportReader.readComponent(component.getRef());
+      processLinks(component.getUuid(), batchComponent.getLinkList());
+    }
+
+    private void processLinks(String componentUuid, List<BatchReport.ComponentLink> links) {
       List<ComponentLinkDto> previousLinks = dbClient.componentLinkDao().selectByComponentUuid(session, componentUuid);
       mergeLinks(session, componentUuid, links, previousLinks);
     }
-  }
 
-  private void mergeLinks(DbSession session, String componentUuid, List<BatchReport.ComponentLink> links, List<ComponentLinkDto> previousLinks) {
-    Set<String> linkType = newHashSet();
-    for (final BatchReport.ComponentLink link : links) {
-      String type = convertType(link.getType());
-      if (!linkType.contains(type)) {
-        linkType.add(type);
-      } else {
-        throw new IllegalArgumentException(String.format("Link of type '%s' has already been declared on component '%s'", type, componentUuid));
-      }
+    private void mergeLinks(DbSession session, String componentUuid, List<BatchReport.ComponentLink> links, List<ComponentLinkDto> previousLinks) {
+      Set<String> linkType = newHashSet();
+      for (final BatchReport.ComponentLink link : links) {
+        String type = convertType(link.getType());
+        if (!linkType.contains(type)) {
+          linkType.add(type);
+        } else {
+          throw new IllegalArgumentException(String.format("Link of type '%s' has already been declared on component '%s'", type, componentUuid));
+        }
 
-      ComponentLinkDto previousLink = Iterables.find(previousLinks, new Predicate<ComponentLinkDto>() {
-        @Override
-        public boolean apply(@Nullable ComponentLinkDto input) {
-          return input != null && input.getType().equals(convertType(link.getType()));
+        ComponentLinkDto previousLink = Iterables.find(previousLinks, new Predicate<ComponentLinkDto>() {
+          @Override
+          public boolean apply(@Nullable ComponentLinkDto input) {
+            return input != null && input.getType().equals(convertType(link.getType()));
+          }
+        }, null);
+        if (previousLink == null) {
+          dbClient.componentLinkDao().insert(session,
+            new ComponentLinkDto()
+              .setComponentUuid(componentUuid)
+              .setType(type)
+              .setName(i18n.message(Locale.ENGLISH, "project_links." + type, null))
+              .setHref(link.getHref())
+            );
+        } else {
+          previousLink.setHref(link.getHref());
+          dbClient.componentLinkDao().update(session, previousLink);
         }
-      }, null);
-      if (previousLink == null) {
-        dbClient.componentLinkDao().insert(session,
-          new ComponentLinkDto()
-            .setComponentUuid(componentUuid)
-            .setType(type)
-            .setName(i18n.message(Locale.ENGLISH, "project_links." + type, null))
-            .setHref(link.getHref())
-          );
-      } else {
-        previousLink.setHref(link.getHref());
-        dbClient.componentLinkDao().update(session, previousLink);
       }
-    }
 
-    for (ComponentLinkDto dto : previousLinks) {
-      if (!linkType.contains(dto.getType()) && ComponentLinkDto.PROVIDED_TYPES.contains(dto.getType())) {
-        dbClient.componentLinkDao().delete(session, dto.getId());
+      for (ComponentLinkDto dto : previousLinks) {
+        if (!linkType.contains(dto.getType()) && ComponentLinkDto.PROVIDED_TYPES.contains(dto.getType())) {
+          dbClient.componentLinkDao().delete(session, dto.getId());
+        }
       }
     }
   }
index aee6d5135295a82a893911316b7748ab88f037ac..6a2beaf529acc88f91e907c361d31f823875930b 100644 (file)
@@ -46,7 +46,6 @@ import org.sonar.core.source.db.FileSourceDto;
 import org.sonar.core.source.db.FileSourceDto.Type;
 import org.sonar.server.computation.batch.BatchReportReader;
 import org.sonar.server.computation.component.Component;
-import org.sonar.server.computation.component.DbComponentsRefCache;
 import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
 import org.sonar.server.computation.component.TreeRootHolder;
 import org.sonar.server.db.DbClient;
@@ -60,14 +59,12 @@ public class PersistTestsStep implements ComputationStep {
 
   private final DbClient dbClient;
   private final System2 system;
-  private final DbComponentsRefCache dbComponentsRefCache;
   private final BatchReportReader reportReader;
   private final TreeRootHolder treeRootHolder;
 
-  public PersistTestsStep(DbClient dbClient, System2 system, DbComponentsRefCache dbComponentsRefCache, BatchReportReader reportReader, TreeRootHolder treeRootHolder) {
+  public PersistTestsStep(DbClient dbClient, System2 system, BatchReportReader reportReader, TreeRootHolder treeRootHolder) {
     this.dbClient = dbClient;
     this.system = system;
-    this.dbComponentsRefCache = dbComponentsRefCache;
     this.reportReader = reportReader;
     this.treeRootHolder = treeRootHolder;
   }
@@ -76,12 +73,11 @@ public class PersistTestsStep implements ComputationStep {
   public void execute() {
     DbSession session = dbClient.openSession(true);
     try {
-      TestDepthTraversalTypeAwareVisitor visitor = new TestDepthTraversalTypeAwareVisitor(session, dbComponentsRefCache);
+      TestDepthTraversalTypeAwareVisitor visitor = new TestDepthTraversalTypeAwareVisitor(session);
       visitor.visit(treeRootHolder.getRoot());
       session.commit();
       if (visitor.hasUnprocessedCoverageDetails) {
-        String projectKey = dbComponentsRefCache.getByRef(reportReader.readMetadata().getRootComponentRef()).getKey();
-        LOG.warn("Some coverage tests are not taken into account during analysis of project '{}'", projectKey);
+        LOG.warn("Some coverage tests are not taken into account during analysis of project '{}'", visitor.getProjectKey());
       }
     } finally {
       MyBatis.closeQuietly(session);
@@ -95,17 +91,17 @@ public class PersistTestsStep implements ComputationStep {
 
   private class TestDepthTraversalTypeAwareVisitor extends DepthTraversalTypeAwareVisitor {
     final DbSession session;
-    final DbComponentsRefCache dbComponentsRefCache;
     final Map<String, FileSourceDto> existingFileSourcesByUuid;
     final String projectUuid;
+    final String projectKey;
     boolean hasUnprocessedCoverageDetails = false;
 
-    public TestDepthTraversalTypeAwareVisitor(DbSession session, DbComponentsRefCache dbComponentsRefCache) {
+    public TestDepthTraversalTypeAwareVisitor(DbSession session) {
       super(Component.Type.FILE, Order.PRE_ORDER);
       this.session = session;
-      this.dbComponentsRefCache = dbComponentsRefCache;
       this.existingFileSourcesByUuid = new HashMap<>();
       this.projectUuid = treeRootHolder.getRoot().getUuid();
+      this.projectKey = treeRootHolder.getRoot().getKey();
       session.select("org.sonar.core.source.db.FileSourceMapper.selectHashesForProject",
         ImmutableMap.of("projectUuid", treeRootHolder.getRoot().getUuid(), "dataType", Type.TEST),
         new ResultHandler() {
@@ -247,7 +243,11 @@ public class PersistTestsStep implements ComputationStep {
     }
 
     private String getUuid(int fileRef) {
-      return dbComponentsRefCache.getByRef(fileRef).getUuid();
+      return treeRootHolder.getComponentByRef(fileRef).getUuid();
+    }
+
+    public String getProjectKey() {
+      return projectKey;
     }
   }
 
index 781835c4d8813337369323ce073992e1298ce4be..9dddd4cf0784fe0bcf38e338cc6730b5a89d1eba 100644 (file)
@@ -24,34 +24,35 @@ import org.sonar.core.computation.dbcleaner.ProjectCleaner;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.persistence.MyBatis;
 import org.sonar.core.purge.IdUuidPair;
-import org.sonar.server.computation.batch.BatchReportReader;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DbIdsRepository;
 import org.sonar.server.computation.component.ProjectSettingsRepository;
+import org.sonar.server.computation.component.TreeRootHolder;
 import org.sonar.server.db.DbClient;
 
 public class PurgeDatastoresStep implements ComputationStep {
 
   private final ProjectCleaner projectCleaner;
   private final DbClient dbClient;
-  private final DbComponentsRefCache dbComponentsRefCache;
+  private final DbIdsRepository dbIdsRepository;
+  private final TreeRootHolder treeRootHolder;
   private final ProjectSettingsRepository projectSettingsRepository;
-  private final BatchReportReader reportReader;
 
-  public PurgeDatastoresStep(DbClient dbClient, ProjectCleaner projectCleaner, DbComponentsRefCache dbComponentsRefCache,
-    ProjectSettingsRepository projectSettingsRepository, BatchReportReader reportReader) {
+  public PurgeDatastoresStep(DbClient dbClient, ProjectCleaner projectCleaner, DbIdsRepository dbIdsRepository, TreeRootHolder treeRootHolder,
+    ProjectSettingsRepository projectSettingsRepository) {
     this.projectCleaner = projectCleaner;
     this.dbClient = dbClient;
-    this.dbComponentsRefCache = dbComponentsRefCache;
+    this.dbIdsRepository = dbIdsRepository;
+    this.treeRootHolder = treeRootHolder;
     this.projectSettingsRepository = projectSettingsRepository;
-    this.reportReader = reportReader;
   }
 
   @Override
   public void execute() {
     DbSession session = dbClient.openSession(true);
     try {
-      DbComponentsRefCache.DbComponent project = dbComponentsRefCache.getByRef(reportReader.readMetadata().getRootComponentRef());
-      projectCleaner.purge(session, new IdUuidPair(project.getId(), project.getUuid()), projectSettingsRepository.getProjectSettings(project.getKey()));
+      Component project = treeRootHolder.getRoot();
+      projectCleaner.purge(session, new IdUuidPair(dbIdsRepository.getComponentId(project), project.getUuid()), projectSettingsRepository.getProjectSettings(project.getKey()));
       session.commit();
     } finally {
       MyBatis.closeQuietly(session);
index f5ec9173f2f0d0d7a5956feaf82b8e371e6cf171..cbc929306eaa33e2262fe2575884e4006fb05538 100644 (file)
@@ -25,8 +25,8 @@ import java.util.Map;
 import java.util.Set;
 import org.sonar.api.issue.internal.DefaultIssue;
 import org.sonar.server.computation.batch.BatchReportReader;
-import org.sonar.server.computation.component.DbComponentsRefCache;
-import org.sonar.server.computation.component.DbComponentsRefCache.DbComponent;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.TreeRootHolder;
 import org.sonar.server.computation.issue.IssueCache;
 import org.sonar.server.computation.issue.RuleCache;
 import org.sonar.server.issue.notification.IssueChangeNotification;
@@ -50,16 +50,16 @@ public class SendIssueNotificationsStep implements ComputationStep {
 
   private final IssueCache issueCache;
   private final RuleCache rules;
-  private final DbComponentsRefCache dbComponentsRefCache;
+  private final TreeRootHolder treeRootHolder;
   private final NotificationService service;
   private final BatchReportReader reportReader;
   private NewIssuesNotificationFactory newIssuesNotificationFactory;
 
-  public SendIssueNotificationsStep(IssueCache issueCache, RuleCache rules, DbComponentsRefCache dbComponentsRefCache, NotificationService service,
+  public SendIssueNotificationsStep(IssueCache issueCache, RuleCache rules, TreeRootHolder treeRootHolder, NotificationService service,
     BatchReportReader reportReader, NewIssuesNotificationFactory newIssuesNotificationFactory) {
     this.issueCache = issueCache;
     this.rules = rules;
-    this.dbComponentsRefCache = dbComponentsRefCache;
+    this.treeRootHolder = treeRootHolder;
     this.service = service;
     this.reportReader = reportReader;
     this.newIssuesNotificationFactory = newIssuesNotificationFactory;
@@ -67,13 +67,13 @@ public class SendIssueNotificationsStep implements ComputationStep {
 
   @Override
   public void execute() {
-    DbComponent project = dbComponentsRefCache.getByRef(reportReader.readMetadata().getRootComponentRef());
+    Component project = treeRootHolder.getRoot();
     if (service.hasProjectSubscribersForTypes(project.getUuid(), NOTIF_TYPES)) {
       doExecute(project);
     }
   }
 
-  private void doExecute(DbComponent project) {
+  private void doExecute(Component project) {
     NewIssuesStatistics newIssuesStats = new NewIssuesStatistics();
     CloseableIterator<DefaultIssue> issues = issueCache.traverse();
     String projectName = reportReader.readComponent(reportReader.readMetadata().getRootComponentRef()).getName();
@@ -97,7 +97,7 @@ public class SendIssueNotificationsStep implements ComputationStep {
     sendNewIssuesStatistics(newIssuesStats, project, projectName);
   }
 
-  private void sendNewIssuesStatistics(NewIssuesStatistics statistics, DbComponent project, String projectName) {
+  private void sendNewIssuesStatistics(NewIssuesStatistics statistics, Component project, String projectName) {
     if (statistics.hasIssues()) {
       NewIssuesStatistics.Stats globalStatistics = statistics.globalStatistics();
       long analysisDate = reportReader.readMetadata().getAnalysisDate();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/batch/ComponentTreeRule.java b/server/sonar-server/src/test/java/org/sonar/server/computation/batch/ComponentTreeRule.java
new file mode 100644 (file)
index 0000000..db6e2bc
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * 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.computation.batch;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
+import java.util.Objects;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nonnull;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import org.sonar.batch.protocol.output.BatchReport;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.ComponentImpl;
+import org.sonar.server.computation.component.DumbComponent;
+
+public class ComponentTreeRule implements TestRule {
+
+  @CheckForNull
+  private final BatchReportReader batchReportReader;
+  private final BUILD_OPTIONS buildOptions;
+
+  private Component root;
+
+  private ComponentTreeRule(BatchReportReader batchReportReader, BUILD_OPTIONS buildOptions) {
+    this.batchReportReader = batchReportReader;
+    this.buildOptions = buildOptions;
+  }
+
+  public static ComponentTreeRule from(BatchReportReader batchReportReader, BUILD_OPTIONS buildOptions) {
+    return new ComponentTreeRule(Objects.requireNonNull(batchReportReader), buildOptions);
+  }
+
+  public static ComponentTreeRule from(BatchReportReader batchReportReader) {
+    return new ComponentTreeRule(Objects.requireNonNull(batchReportReader), BUILD_OPTIONS.NONE);
+  }
+
+  @Override
+  public Statement apply(final Statement statement, Description description) {
+    return new Statement() {
+      @Override
+      public void evaluate() throws Throwable {
+        try {
+          statement.evaluate();
+        } finally {
+          clear();
+        }
+      }
+    };
+  }
+
+  private void clear() {
+    this.root = null;
+  }
+
+  public enum BUILD_OPTIONS {
+    NONE(false, false), KEY(false, true), UUID(true, false), KEY_AND_UUID(true, true);
+    private final boolean uuid;
+    private final boolean key;
+
+    BUILD_OPTIONS(boolean uuid, boolean key) {
+      this.uuid = uuid;
+      this.key = key;
+    }
+  }
+
+  public Component getRoot() {
+    if (root == null) {
+      buildComponentRoot(buildOptions);
+    }
+    return this.root;
+  }
+
+  private Component buildComponentRoot(BUILD_OPTIONS build_options) {
+    int rootComponentRef = batchReportReader.readMetadata().getRootComponentRef();
+    return newComponent(batchReportReader.readComponent(rootComponentRef), build_options);
+  }
+
+  private DumbComponent newComponent(BatchReport.Component component, BUILD_OPTIONS build_options) {
+    return new DumbComponent(
+      ComponentImpl.convertType(component.getType()),
+      component.getRef(),
+      build_options.uuid ? uuidOf(component.getRef()) : null,
+      build_options.key ? keyOf(component.getRef()) : null,
+      buildChildren(component, build_options));
+  }
+
+  private Component[] buildChildren(BatchReport.Component component, final BUILD_OPTIONS build_options) {
+    return Iterables.toArray(
+      Iterables.transform(
+        component.getChildRefList(),
+        new Function<Integer, Component>() {
+          @Override
+          public Component apply(@Nonnull Integer componentRef) {
+            return newComponent(batchReportReader.readComponent(componentRef), build_options);
+          }
+        }
+        ), Component.class);
+  }
+
+  public String keyOf(int ref) {
+    return "key_" + ref;
+  }
+
+  public String uuidOf(int ref) {
+    return "uuid_" + ref;
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/component/DbComponentsRefCacheTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/component/DbComponentsRefCacheTest.java
deleted file mode 100644 (file)
index 67c20df..0000000
+++ /dev/null
@@ -1,45 +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.computation.component;
-
-import org.junit.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class DbComponentsRefCacheTest {
-
-  @Test
-  public void add_and_get_component() throws Exception {
-    DbComponentsRefCache cache = new DbComponentsRefCache();
-    cache.addComponent(1, new DbComponentsRefCache.DbComponent(10L, "Key", "Uuid"));
-
-    assertThat(cache.getByRef(1)).isNotNull();
-    assertThat(cache.getByRef(1).getId()).isEqualTo(10L);
-    assertThat(cache.getByRef(1).getKey()).isEqualTo("Key");
-    assertThat(cache.getByRef(1).getUuid()).isEqualTo("Uuid");
-  }
-
-  @Test(expected = IllegalArgumentException.class)
-  public void fail_on_unknown_ref() throws Exception {
-    new DbComponentsRefCache().getByRef(1);
-  }
-
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/component/DbIdsRepositoryTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/component/DbIdsRepositoryTest.java
new file mode 100644 (file)
index 0000000..d2c30aa
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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.computation.component;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class DbIdsRepositoryTest {
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  Component component = DumbComponent.DUMB_PROJECT;
+
+  @Test
+  public void add_and_get_component() throws Exception {
+    DbIdsRepository cache = new DbIdsRepository();
+    cache.setComponentId(component, 10L);
+
+    assertThat(cache.getComponentId(component)).isEqualTo(10L);
+  }
+
+  @Test
+  public void fail_on_unknown_ref() throws Exception {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("Component ref '" + component.getRef() + "' has no component id");
+
+    new DbIdsRepository().getComponentId(DumbComponent.DUMB_PROJECT);
+  }
+
+  @Test
+  public void fail_if_component_id_already_set() throws Exception {
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("Component ref '" + component.getRef() + "' has already a component id");
+
+    DbIdsRepository cache = new DbIdsRepository();
+    cache.setComponentId(component, 10L);
+    cache.setComponentId(component, 11L);
+  }
+
+}
index 286f58c79cdf589851805de581ea14c551cb954d..e77c23cfff9a65decb77d2255fedf42fba6847dd 100644 (file)
@@ -45,7 +45,7 @@ import org.sonar.server.component.ComponentTesting;
 import org.sonar.server.component.db.ComponentDao;
 import org.sonar.server.computation.batch.TreeRootHolderRule;
 import org.sonar.server.computation.component.Component;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.component.DbIdsRepository;
 import org.sonar.server.computation.component.DumbComponent;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.es.EsTester;
@@ -63,8 +63,10 @@ public class ApplyPermissionsStepTest extends BaseStepTest {
 
   @ClassRule
   public static EsTester esTester = new EsTester().addDefinitions(new IssueIndexDefinition(new Settings()));
+
   @ClassRule
   public static DbTester dbTester = new DbTester();
+
   @Rule
   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
 
@@ -74,7 +76,7 @@ public class ApplyPermissionsStepTest extends BaseStepTest {
 
   Settings settings;
 
-  DbComponentsRefCache dbComponentsRefCache;
+  DbIdsRepository dbIdsRepository;
 
   IssueAuthorizationIndexer issueAuthorizationIndexer;
   ApplyPermissionsStep step;
@@ -94,10 +96,10 @@ public class ApplyPermissionsStepTest extends BaseStepTest {
     issueAuthorizationIndexer = new IssueAuthorizationIndexer(dbClient, esTester.client());
     issueAuthorizationIndexer.setEnabled(true);
 
-    dbComponentsRefCache = new DbComponentsRefCache();
+    dbIdsRepository = new DbIdsRepository();
 
-    step = new ApplyPermissionsStep(dbClient, dbComponentsRefCache, issueAuthorizationIndexer, new PermissionFacade(roleDao, null,
-        new ResourceDao(dbTester.myBatis(), System2.INSTANCE), permissionTemplateDao, settings), treeRootHolder);
+    step = new ApplyPermissionsStep(dbClient, dbIdsRepository, issueAuthorizationIndexer, new PermissionFacade(roleDao, null,
+      new ResourceDao(dbTester.myBatis(), System2.INSTANCE), permissionTemplateDao, settings), treeRootHolder);
   }
 
   @After
@@ -116,8 +118,9 @@ public class ApplyPermissionsStepTest extends BaseStepTest {
     dbClient.permissionTemplateDao().addGroupPermission(permissionTemplateDto.getId(), null, UserRole.USER);
     dbSession.commit();
 
-    dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(projectDto.getId(), PROJECT_KEY, PROJECT_UUID));
-    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, PROJECT_KEY, PROJECT_UUID));
+    Component project = new DumbComponent(Component.Type.PROJECT, 1, PROJECT_UUID, PROJECT_KEY);
+    dbIdsRepository.setComponentId(project, projectDto.getId());
+    treeRootHolder.setRoot(project);
 
     step.execute();
     dbSession.commit();
@@ -143,8 +146,9 @@ public class ApplyPermissionsStepTest extends BaseStepTest {
 
     dbSession.commit();
 
-    dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(projectDto.getId(), PROJECT_KEY, PROJECT_UUID));
-    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, PROJECT_KEY, PROJECT_UUID));
+    Component project = new DumbComponent(Component.Type.PROJECT, 1, PROJECT_UUID, PROJECT_KEY);
+    dbIdsRepository.setComponentId(project, projectDto.getId());
+    treeRootHolder.setRoot(project);
 
     step.execute();
     dbSession.commit();
index c28d1a7a30c48ed021ce775c01fd280f3efdc32f..de876131970d8d55c7cbbc91ed5208f10baec304 100644 (file)
@@ -23,38 +23,35 @@ package org.sonar.server.computation.step;
 import java.io.IOException;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.batch.protocol.output.BatchReport;
-import org.sonar.core.component.ComponentDto;
 import org.sonar.core.resource.ResourceIndexerDao;
 import org.sonar.server.computation.batch.BatchReportReaderRule;
-import org.sonar.server.computation.component.DbComponentsRefCache;
-import org.sonar.server.computation.component.DbComponentsRefCache.DbComponent;
+import org.sonar.server.computation.batch.TreeRootHolderRule;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DbIdsRepository;
+import org.sonar.server.computation.component.DumbComponent;
 
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
 public class IndexComponentsStepTest extends BaseStepTest {
 
   private static final String PROJECT_KEY = "PROJECT_KEY";
 
+  @Rule
+  public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
+
   @Rule
   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
 
   ResourceIndexerDao resourceIndexerDao = mock(ResourceIndexerDao.class);
-  DbComponentsRefCache dbComponentsRefCache = new DbComponentsRefCache();
-  IndexComponentsStep sut = new IndexComponentsStep(resourceIndexerDao, dbComponentsRefCache, reportReader);
+  DbIdsRepository dbIdsRepository = new DbIdsRepository();
+  IndexComponentsStep sut = new IndexComponentsStep(resourceIndexerDao, dbIdsRepository, treeRootHolder);
 
   @Test
   public void call_indexProject_of_dao() throws IOException {
-    dbComponentsRefCache.addComponent(1, new DbComponent(123L, PROJECT_KEY, "PROJECT_UUID"));
-
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .build());
-
-    ComponentDto project = mock(ComponentDto.class);
-    when(project.getId()).thenReturn(123L);
+    Component project = new DumbComponent(Component.Type.PROJECT, 1, "PROJECT_UUID", PROJECT_KEY);
+    dbIdsRepository.setComponentId(project, 123L);
+    treeRootHolder.setRoot(project);
 
     sut.execute();
 
index 9ff56d86d8c2c1b899910bea94273b75a0717263..d088251659c57990cae2bae763d158a545f54022 100644 (file)
@@ -27,10 +27,10 @@ import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.config.Settings;
-import org.sonar.batch.protocol.output.BatchReport;
 import org.sonar.core.persistence.DbTester;
-import org.sonar.server.computation.batch.BatchReportReaderRule;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.batch.TreeRootHolderRule;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DumbComponent;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.es.EsTester;
 import org.sonar.server.source.db.FileSourceDao;
@@ -43,43 +43,37 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 public class IndexSourceLinesStepTest extends BaseStepTest {
 
-  private static final String PROJECT_KEY = "PROJECT_KEY";
-
   @ClassRule
   public static DbTester dbTester = new DbTester();
+
   @ClassRule
   public static EsTester esTester = new EsTester().addDefinitions(new SourceLineIndexDefinition(new Settings()));
+
   @Rule
-  public BatchReportReaderRule reportReader = new BatchReportReaderRule();
+  public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
 
   DbClient dbClient;
-  DbComponentsRefCache dbComponentsRefCache;
 
   @Before
   public void setUp() {
     dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new FileSourceDao(null));
-    dbComponentsRefCache = new DbComponentsRefCache();
   }
 
   @Override
   protected ComputationStep step() {
     SourceLineIndexer sourceLineIndexer = new SourceLineIndexer(dbClient, esTester.client());
     sourceLineIndexer.setEnabled(true);
-    return new IndexSourceLinesStep(sourceLineIndexer, dbComponentsRefCache, reportReader);
+    return new IndexSourceLinesStep(sourceLineIndexer, treeRootHolder);
   }
 
   @Test
   public void index_source() throws Exception {
-    dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD"));
-
     dbTester.prepareDbUnit(getClass(), "index_source.xml");
     Connection connection = dbTester.openConnection();
     FileSourceTesting.updateDataColumn(connection, "FILE1_UUID", FileSourceTesting.newRandomData(1).build());
     connection.close();
 
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .build());
+    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", "PROJECT_KEY"));
 
     step().execute();
 
index 3970cbcc0310bc27c3e1c50829652957b65a5baf..b36e572c090eea2c179800008da5d784eb40bc3c 100644 (file)
@@ -28,10 +28,10 @@ import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.config.Settings;
-import org.sonar.batch.protocol.output.BatchReport;
 import org.sonar.core.persistence.DbTester;
-import org.sonar.server.computation.batch.BatchReportReaderRule;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.batch.TreeRootHolderRule;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DumbComponent;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.es.EsTester;
 import org.sonar.server.source.db.FileSourceDao;
@@ -46,40 +46,36 @@ public class IndexTestsStepTest extends BaseStepTest {
 
   @ClassRule
   public static DbTester dbTester = new DbTester();
+
   @ClassRule
   public static EsTester esTester = new EsTester().addDefinitions(new TestIndexDefinition(new Settings()));
+
   @Rule
-  public BatchReportReaderRule reportReader = new BatchReportReaderRule();
+  public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
 
   DbClient dbClient;
-  DbComponentsRefCache dbComponentsRefCache;
 
   @Before
   public void setUp() {
     dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new FileSourceDao(null));
     esTester.truncateIndices();
-    dbComponentsRefCache = new DbComponentsRefCache();
   }
 
   @Override
   protected ComputationStep step() {
     TestIndexer testIndexer = new TestIndexer(dbClient, esTester.client());
     testIndexer.setEnabled(true);
-    return new IndexTestsStep(testIndexer, dbComponentsRefCache, reportReader);
+    return new IndexTestsStep(testIndexer, treeRootHolder);
   }
 
   @Test
   public void index_test() throws Exception {
-    dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, "PROJECT_KEY", "ABCD"));
-
     dbTester.prepareDbUnit(getClass(), "index_source.xml");
     Connection connection = dbTester.openConnection();
     TestTesting.updateDataColumn(connection, "FILE1_UUID", TestTesting.newRandomTests(1));
     connection.close();
 
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .build());
+    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", "PROJECT_KEY"));
 
     step().execute();
 
index e91e84168f9632cc865fe46e872c9c68566f88b5..53ce81eb0c22bfa5a98f8f773f8cfd995f9df541 100644 (file)
@@ -36,13 +36,12 @@ import org.sonar.server.component.db.ComponentDao;
 import org.sonar.server.computation.batch.BatchReportReaderRule;
 import org.sonar.server.computation.batch.TreeRootHolderRule;
 import org.sonar.server.computation.component.Component;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.component.DbIdsRepository;
 import org.sonar.server.computation.component.DumbComponent;
 import org.sonar.server.db.DbClient;
 import org.sonar.test.DbTests;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
 
 @Category(DbTests.class)
 public class PersistComponentsStepTest extends BaseStepTest {
@@ -51,14 +50,17 @@ public class PersistComponentsStepTest extends BaseStepTest {
 
   @ClassRule
   public static DbTester dbTester = new DbTester();
+
   @Rule
   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
+
   @Rule
   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
 
+  DbIdsRepository dbIdsRepository;
+
   DbSession session;
   DbClient dbClient;
-  DbComponentsRefCache dbComponentsRefCache;
 
   PersistComponentsStep sut;
 
@@ -68,8 +70,8 @@ public class PersistComponentsStepTest extends BaseStepTest {
     session = dbTester.myBatis().openSession(false);
     dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new ComponentDao());
 
-    dbComponentsRefCache = new DbComponentsRefCache();
-    sut = new PersistComponentsStep(dbClient, dbComponentsRefCache, reportReader, treeRootHolder);
+    dbIdsRepository = new DbIdsRepository();
+    sut = new PersistComponentsStep(dbClient, dbIdsRepository, reportReader, treeRootHolder);
   }
 
   @Override
@@ -118,71 +120,73 @@ public class PersistComponentsStepTest extends BaseStepTest {
       .setLanguage("java")
       .build());
 
-    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY,
-      new DumbComponent(Component.Type.MODULE, 2, "BCDE", "MODULE_KEY",
-        new DumbComponent(Component.Type.DIRECTORY, 3, "CDEF", "MODULE_KEY:src/main/java/dir",
-          new DumbComponent(Component.Type.FILE, 4, "DEFG", "MODULE_KEY:src/main/java/dir/Foo.java")))));
+    Component file = new DumbComponent(Component.Type.FILE, 4, "DEFG", "MODULE_KEY:src/main/java/dir/Foo.java");
+    Component directory = new DumbComponent(Component.Type.DIRECTORY, 3, "CDEF", "MODULE_KEY:src/main/java/dir", file);
+    Component module = new DumbComponent(Component.Type.MODULE, 2, "BCDE", "MODULE_KEY", directory);
+    Component project = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, module);
+    treeRootHolder.setRoot(project);
+
     sut.execute();
 
     assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(4);
 
-    ComponentDto project = dbClient.componentDao().selectNullableByKey(session, PROJECT_KEY);
-    assertThat(project).isNotNull();
-    assertThat(project.name()).isEqualTo("Project");
-    assertThat(project.description()).isEqualTo("Project description");
-    assertThat(project.path()).isNull();
-    assertThat(project.uuid()).isEqualTo("ABCD");
-    assertThat(project.moduleUuid()).isNull();
-    assertThat(project.moduleUuidPath()).isEqualTo("." + project.uuid() + ".");
-    assertThat(project.projectUuid()).isEqualTo(project.uuid());
-    assertThat(project.qualifier()).isEqualTo("TRK");
-    assertThat(project.scope()).isEqualTo("PRJ");
-    assertThat(project.parentProjectId()).isNull();
-
-    ComponentDto module = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY");
-    assertThat(module).isNotNull();
-    assertThat(module.name()).isEqualTo("Module");
-    assertThat(module.description()).isEqualTo("Module description");
-    assertThat(module.path()).isEqualTo("module");
-    assertThat(module.uuid()).isEqualTo("BCDE");
-    assertThat(module.moduleUuid()).isEqualTo(project.uuid());
-    assertThat(module.moduleUuidPath()).isEqualTo(project.moduleUuidPath() + module.uuid() + ".");
-    assertThat(module.projectUuid()).isEqualTo(project.uuid());
-    assertThat(module.qualifier()).isEqualTo("BRC");
-    assertThat(module.scope()).isEqualTo("PRJ");
-    assertThat(module.parentProjectId()).isEqualTo(project.getId());
-
-    ComponentDto directory = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:src/main/java/dir");
-    assertThat(directory).isNotNull();
-    assertThat(directory.name()).isEqualTo("src/main/java/dir");
-    assertThat(directory.description()).isNull();
-    assertThat(directory.path()).isEqualTo("src/main/java/dir");
-    assertThat(directory.uuid()).isEqualTo("CDEF");
-    assertThat(directory.moduleUuid()).isEqualTo(module.uuid());
-    assertThat(directory.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
-    assertThat(directory.projectUuid()).isEqualTo(project.uuid());
-    assertThat(directory.qualifier()).isEqualTo("DIR");
-    assertThat(directory.scope()).isEqualTo("DIR");
-    assertThat(directory.parentProjectId()).isEqualTo(module.getId());
-
-    ComponentDto file = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:src/main/java/dir/Foo.java");
-    assertThat(file).isNotNull();
-    assertThat(file.name()).isEqualTo("Foo.java");
-    assertThat(file.description()).isNull();
-    assertThat(file.path()).isEqualTo("src/main/java/dir/Foo.java");
-    assertThat(file.language()).isEqualTo("java");
-    assertThat(file.uuid()).isEqualTo("DEFG");
-    assertThat(file.moduleUuid()).isEqualTo(module.uuid());
-    assertThat(file.moduleUuidPath()).isEqualTo(module.moduleUuidPath());
-    assertThat(file.projectUuid()).isEqualTo(project.uuid());
-    assertThat(file.qualifier()).isEqualTo("FIL");
-    assertThat(file.scope()).isEqualTo("FIL");
-    assertThat(file.parentProjectId()).isEqualTo(module.getId());
-
-    assertThat(dbComponentsRefCache.getByRef(1).getId()).isEqualTo(project.getId());
-    assertThat(dbComponentsRefCache.getByRef(2).getId()).isEqualTo(module.getId());
-    assertThat(dbComponentsRefCache.getByRef(3).getId()).isEqualTo(directory.getId());
-    assertThat(dbComponentsRefCache.getByRef(4).getId()).isEqualTo(file.getId());
+    ComponentDto projectDto = dbClient.componentDao().selectNullableByKey(session, PROJECT_KEY);
+    assertThat(projectDto).isNotNull();
+    assertThat(projectDto.name()).isEqualTo("Project");
+    assertThat(projectDto.description()).isEqualTo("Project description");
+    assertThat(projectDto.path()).isNull();
+    assertThat(projectDto.uuid()).isEqualTo("ABCD");
+    assertThat(projectDto.moduleUuid()).isNull();
+    assertThat(projectDto.moduleUuidPath()).isEqualTo("." + projectDto.uuid() + ".");
+    assertThat(projectDto.projectUuid()).isEqualTo(projectDto.uuid());
+    assertThat(projectDto.qualifier()).isEqualTo("TRK");
+    assertThat(projectDto.scope()).isEqualTo("PRJ");
+    assertThat(projectDto.parentProjectId()).isNull();
+
+    ComponentDto moduleDto = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY");
+    assertThat(moduleDto).isNotNull();
+    assertThat(moduleDto.name()).isEqualTo("Module");
+    assertThat(moduleDto.description()).isEqualTo("Module description");
+    assertThat(moduleDto.path()).isEqualTo("module");
+    assertThat(moduleDto.uuid()).isEqualTo("BCDE");
+    assertThat(moduleDto.moduleUuid()).isEqualTo(projectDto.uuid());
+    assertThat(moduleDto.moduleUuidPath()).isEqualTo(projectDto.moduleUuidPath() + moduleDto.uuid() + ".");
+    assertThat(moduleDto.projectUuid()).isEqualTo(projectDto.uuid());
+    assertThat(moduleDto.qualifier()).isEqualTo("BRC");
+    assertThat(moduleDto.scope()).isEqualTo("PRJ");
+    assertThat(moduleDto.parentProjectId()).isEqualTo(projectDto.getId());
+
+    ComponentDto directoryDto = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:src/main/java/dir");
+    assertThat(directoryDto).isNotNull();
+    assertThat(directoryDto.name()).isEqualTo("src/main/java/dir");
+    assertThat(directoryDto.description()).isNull();
+    assertThat(directoryDto.path()).isEqualTo("src/main/java/dir");
+    assertThat(directoryDto.uuid()).isEqualTo("CDEF");
+    assertThat(directoryDto.moduleUuid()).isEqualTo(moduleDto.uuid());
+    assertThat(directoryDto.moduleUuidPath()).isEqualTo(moduleDto.moduleUuidPath());
+    assertThat(directoryDto.projectUuid()).isEqualTo(projectDto.uuid());
+    assertThat(directoryDto.qualifier()).isEqualTo("DIR");
+    assertThat(directoryDto.scope()).isEqualTo("DIR");
+    assertThat(directoryDto.parentProjectId()).isEqualTo(moduleDto.getId());
+
+    ComponentDto fileDto = dbClient.componentDao().selectNullableByKey(session, "MODULE_KEY:src/main/java/dir/Foo.java");
+    assertThat(fileDto).isNotNull();
+    assertThat(fileDto.name()).isEqualTo("Foo.java");
+    assertThat(fileDto.description()).isNull();
+    assertThat(fileDto.path()).isEqualTo("src/main/java/dir/Foo.java");
+    assertThat(fileDto.language()).isEqualTo("java");
+    assertThat(fileDto.uuid()).isEqualTo("DEFG");
+    assertThat(fileDto.moduleUuid()).isEqualTo(moduleDto.uuid());
+    assertThat(fileDto.moduleUuidPath()).isEqualTo(moduleDto.moduleUuidPath());
+    assertThat(fileDto.projectUuid()).isEqualTo(projectDto.uuid());
+    assertThat(fileDto.qualifier()).isEqualTo("FIL");
+    assertThat(fileDto.scope()).isEqualTo("FIL");
+    assertThat(fileDto.parentProjectId()).isEqualTo(moduleDto.getId());
+
+    assertThat(dbIdsRepository.getComponentId(project)).isEqualTo(projectDto.getId());
+    assertThat(dbIdsRepository.getComponentId(module)).isEqualTo(moduleDto.getId());
+    assertThat(dbIdsRepository.getComponentId(directory)).isEqualTo(directoryDto.getId());
+    assertThat(dbIdsRepository.getComponentId(file)).isEqualTo(fileDto.getId());
   }
 
   @Test
@@ -286,23 +290,23 @@ public class PersistComponentsStepTest extends BaseStepTest {
       .addChildRef(2)
       .build());
     reportReader.putComponent(BatchReport.Component.newBuilder()
-        .setRef(2)
-        .setType(Constants.ComponentType.MODULE)
-        .setKey("MODULE_KEY")
-        .setName("Module")
-        .addChildRef(3)
-        .build());
+      .setRef(2)
+      .setType(Constants.ComponentType.MODULE)
+      .setKey("MODULE_KEY")
+      .setName("Module")
+      .addChildRef(3)
+      .build());
     reportReader.putComponent(BatchReport.Component.newBuilder()
-        .setRef(3)
-        .setType(Constants.ComponentType.DIRECTORY)
-        .setPath("src/main/java/dir")
-        .addChildRef(4)
-        .build());
+      .setRef(3)
+      .setType(Constants.ComponentType.DIRECTORY)
+      .setPath("src/main/java/dir")
+      .addChildRef(4)
+      .build());
     reportReader.putComponent(BatchReport.Component.newBuilder()
-        .setRef(4)
-        .setType(Constants.ComponentType.FILE)
-        .setPath("src/main/java/dir/Foo.java")
-        .build());
+      .setRef(4)
+      .setType(Constants.ComponentType.FILE)
+      .setPath("src/main/java/dir/Foo.java")
+      .build());
 
     treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY,
       new DumbComponent(Component.Type.MODULE, 2, "BCDE", "MODULE_KEY",
@@ -488,16 +492,16 @@ public class PersistComponentsStepTest extends BaseStepTest {
     session.commit();
 
     reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-        .setRootComponentRef(1)
-        .build());
+      .setRootComponentRef(1)
+      .build());
 
     reportReader.putComponent(BatchReport.Component.newBuilder()
-        .setRef(1)
-        .setType(Constants.ComponentType.PROJECT)
-        .setKey(PROJECT_KEY)
-        .setName("Project")
-        .addChildRef(2)
-        .build());
+      .setRef(1)
+      .setType(Constants.ComponentType.PROJECT)
+      .setKey(PROJECT_KEY)
+      .setName("Project")
+      .addChildRef(2)
+      .build());
     reportReader.putComponent(BatchReport.Component.newBuilder()
       .setRef(2)
       .setType(Constants.ComponentType.MODULE)
@@ -506,16 +510,16 @@ public class PersistComponentsStepTest extends BaseStepTest {
       .addChildRef(3)
       .build());
     reportReader.putComponent(BatchReport.Component.newBuilder()
-        .setRef(3)
-        .setType(Constants.ComponentType.DIRECTORY)
-        .setPath("src/main/java/dir")
-        .addChildRef(4)
-        .build());
+      .setRef(3)
+      .setType(Constants.ComponentType.DIRECTORY)
+      .setPath("src/main/java/dir")
+      .addChildRef(4)
+      .build());
     reportReader.putComponent(BatchReport.Component.newBuilder()
-        .setRef(4)
-        .setType(Constants.ComponentType.FILE)
-        .setPath("src/main/java/dir/Foo.java")
-        .build());
+      .setRef(4)
+      .setType(Constants.ComponentType.FILE)
+      .setPath("src/main/java/dir/Foo.java")
+      .build());
 
     treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY,
       new DumbComponent(Component.Type.MODULE, 2, "BCDE", "MODULE_KEY",
@@ -575,23 +579,23 @@ public class PersistComponentsStepTest extends BaseStepTest {
     session.commit();
 
     reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-        .setRootComponentRef(1)
-        .build());
-
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-        .setRef(1)
-        .setType(Constants.ComponentType.PROJECT)
-        .setKey(PROJECT_KEY)
-        .setName("New project name")
-        .addChildRef(2)
-        .build());
-    reportReader.putComponent(BatchReport.Component.newBuilder()
-        .setRef(2)
-        .setType(Constants.ComponentType.MODULE)
-        .setKey("MODULE_KEY")
-        .setName("New module name")
-        .setPath("New path")
-        .build());
+      .setRootComponentRef(1)
+      .build());
+
+    reportReader.putComponent(BatchReport.Component.newBuilder()
+      .setRef(1)
+      .setType(Constants.ComponentType.PROJECT)
+      .setKey(PROJECT_KEY)
+      .setName("New project name")
+      .addChildRef(2)
+      .build());
+    reportReader.putComponent(BatchReport.Component.newBuilder()
+      .setRef(2)
+      .setType(Constants.ComponentType.MODULE)
+      .setKey("MODULE_KEY")
+      .setName("New module name")
+      .setPath("New path")
+      .build());
 
     treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY,
       new DumbComponent(Component.Type.MODULE, 2, "BCDE", "MODULE_KEY")));
index 04b283d6a83f57e34fb98c734c5ae9bf3c907a49..c61cfb736228e8a83c55d0b067a424a2ac5b886d 100644 (file)
@@ -27,7 +27,6 @@ import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
-import org.sonar.api.config.Settings;
 import org.sonar.api.measures.CoreMetrics;
 import org.sonar.batch.protocol.Constants;
 import org.sonar.batch.protocol.output.BatchReport;
@@ -36,9 +35,10 @@ import org.sonar.core.metric.db.MetricDto;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.persistence.DbTester;
 import org.sonar.server.computation.batch.BatchReportReaderRule;
-import org.sonar.server.computation.component.DbComponentsRefCache;
-import org.sonar.server.computation.component.DbComponentsRefCache.DbComponent;
-import org.sonar.server.computation.language.LanguageRepository;
+import org.sonar.server.computation.batch.TreeRootHolderRule;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DbIdsRepository;
+import org.sonar.server.computation.component.DumbComponent;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.measure.persistence.MeasureDao;
 import org.sonar.server.metric.persistence.MetricDao;
@@ -46,7 +46,6 @@ import org.sonar.test.DbTests;
 
 import static com.google.common.collect.Lists.newArrayList;
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
 
 @Category(DbTests.class)
 public class PersistDuplicationsStepTest extends BaseStepTest {
@@ -59,14 +58,14 @@ public class PersistDuplicationsStepTest extends BaseStepTest {
   @Rule
   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
 
-  DbSession session;
+  @Rule
+  public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
 
-  DbClient dbClient;
+  DbIdsRepository dbIdsRepository = new DbIdsRepository();
 
-  Settings projectSettings;
-  LanguageRepository languageRepository;
+  DbSession session;
 
-  DbComponentsRefCache dbComponentsRefCache;
+  DbClient dbClient;
 
   PersistDuplicationsStep sut;
 
@@ -76,10 +75,7 @@ public class PersistDuplicationsStepTest extends BaseStepTest {
     session = dbTester.myBatis().openSession(false);
     dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new MeasureDao(), new MetricDao());
 
-    projectSettings = new Settings();
-    dbComponentsRefCache = new DbComponentsRefCache();
-    languageRepository = mock(LanguageRepository.class);
-    sut = new PersistDuplicationsStep(dbClient, dbComponentsRefCache, reportReader);
+    sut = new PersistDuplicationsStep(dbClient, dbIdsRepository, treeRootHolder, reportReader);
   }
 
   @Override
@@ -135,16 +131,18 @@ public class PersistDuplicationsStepTest extends BaseStepTest {
 
   @Test
   public void persist_duplications_on_same_file_linked_on_a_module() throws Exception {
-    dbComponentsRefCache.addComponent(1, new DbComponent(1L, PROJECT_KEY, "ABCD"));
-    dbComponentsRefCache.addComponent(2, new DbComponent(2L, "MODULE_KEY", "BCDE"));
-    dbComponentsRefCache.addComponent(3, new DbComponent(3L, "MODULE_KEY:file", "CDEF"));
+    Component file = new DumbComponent(Component.Type.FILE, 3, "CDEF", "MODULE_KEY:file");
+    Component module = new DumbComponent(Component.Type.MODULE, 2, "BCDE", "MODULE_KEY", file);
+    Component project = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, module);
+    treeRootHolder.setRoot(project);
 
-    saveDuplicationMetric();
+    dbIdsRepository.setComponentId(project, 1);
+    dbIdsRepository.setComponentId(module, 3);
+    dbIdsRepository.setComponentId(file, 2);
 
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .build());
+    saveDuplicationMetric();
 
+    // TODO remove this when snapshot id will come from the DbIdsRepo
     reportReader.putComponent(BatchReport.Component.newBuilder()
       .setRef(1)
       .setType(Constants.ComponentType.PROJECT)
@@ -192,17 +190,18 @@ public class PersistDuplicationsStepTest extends BaseStepTest {
 
   @Test
   public void persist_duplications_on_same_file_linked_on_a_folder() {
-    dbComponentsRefCache.addComponent(1, new DbComponent(1L, PROJECT_KEY, "ABCD"));
-    dbComponentsRefCache.addComponent(2, new DbComponent(2L, "PROJECT_KEY:dir", "BCDE"));
-    dbComponentsRefCache.addComponent(3, new DbComponent(3L, "PROJECT_KEY:file", "CDEF"));
+    Component file = new DumbComponent(Component.Type.FILE, 3, "CDEF", "PROJECT_KEY:file");
+    Component directory = new DumbComponent(Component.Type.DIRECTORY, 2, "BCDE", "PROJECT_KEY:dir", file);
+    Component project = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, directory);
+    treeRootHolder.setRoot(project);
 
+    dbIdsRepository.setComponentId(project, 1);
+    dbIdsRepository.setComponentId(directory, 3);
+    dbIdsRepository.setComponentId(file, 2);
 
     saveDuplicationMetric();
 
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .build());
-
+    // TODO remove this when snapshot id will come from the DbIdsRepo
     reportReader.putComponent(BatchReport.Component.newBuilder()
       .setRef(1)
       .setType(Constants.ComponentType.PROJECT)
@@ -250,17 +249,20 @@ public class PersistDuplicationsStepTest extends BaseStepTest {
 
   @Test
   public void persist_duplications_on_same_file_linked_on_sub_folder() {
-    dbComponentsRefCache.addComponent(1, new DbComponent(1L, PROJECT_KEY, "ABCD"));
-    dbComponentsRefCache.addComponent(2, new DbComponent(2L, "PROJECT_KEY:dir", "BCDE"));
-    dbComponentsRefCache.addComponent(3, new DbComponent(3L, "PROJECT_KEY:dir", "CDEF"));
-    dbComponentsRefCache.addComponent(10, new DbComponent(10L, "PROJECT_KEY:file", "DEFG"));
+    Component file = new DumbComponent(Component.Type.FILE, 10, "DEFG", "PROJECT_KEY:file");
+    Component directory1 = new DumbComponent(Component.Type.DIRECTORY, 3, "CDEF", "PROJECT_KEY:dir1", file);
+    Component directory2 = new DumbComponent(Component.Type.DIRECTORY, 2, "BCDE", "PROJECT_KEY:dir2", directory1);
+    Component project = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, directory2);
+    treeRootHolder.setRoot(project);
 
-    saveDuplicationMetric();
+    dbIdsRepository.setComponentId(project, 1);
+    dbIdsRepository.setComponentId(directory1, 2);
+    dbIdsRepository.setComponentId(directory2, 3);
+    dbIdsRepository.setComponentId(file, 10);
 
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .build());
+    saveDuplicationMetric();
 
+    // TODO remove this when snapshot id will come from the DbIdsRepo
     reportReader.putComponent(BatchReport.Component.newBuilder()
       .setRef(1)
       .setType(Constants.ComponentType.PROJECT)
@@ -314,10 +316,30 @@ public class PersistDuplicationsStepTest extends BaseStepTest {
 
   @Test
   public void persist_duplications_on_different_files() {
-    dbComponentsRefCache.addComponent(3, new DbComponent(3L, "PROJECT_KEY:file2", "CDEF"));
     saveDuplicationMetric();
-    initReportWithProjectAndFile();
 
+    Component file2 = new DumbComponent(Component.Type.FILE, 3, "CDEF", "PROJECT_KEY:file2");
+    Component file = new DumbComponent(Component.Type.FILE, 2, "BCDE", "PROJECT_KEY:file");
+    Component project = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, file, file2);
+    treeRootHolder.setRoot(project);
+
+    dbIdsRepository.setComponentId(project, 1);
+    dbIdsRepository.setComponentId(file, 2);
+
+    // TODO remove this when snapshot id will come from the DbIdsRepo
+    reportReader.putComponent(BatchReport.Component.newBuilder()
+      .setRef(1)
+      .setType(Constants.ComponentType.PROJECT)
+      .setKey(PROJECT_KEY)
+      .setSnapshotId(10L)
+      .addChildRef(2)
+      .build());
+    reportReader.putComponent(BatchReport.Component.newBuilder()
+      .setRef(2)
+      .setType(Constants.ComponentType.FILE)
+      .setSnapshotId(11L)
+      .setPath("file")
+      .build());
     reportReader.putComponent(BatchReport.Component.newBuilder()
       .setRef(3)
       .setType(Constants.ComponentType.FILE)
@@ -379,13 +401,14 @@ public class PersistDuplicationsStepTest extends BaseStepTest {
   }
 
   private void initReportWithProjectAndFile() {
-    dbComponentsRefCache.addComponent(1, new DbComponent(1L, PROJECT_KEY, "ABCD"));
-    dbComponentsRefCache.addComponent(2, new DbComponent(2L, "PROJECT_KEY:file", "BCDE"));
+    Component file = new DumbComponent(Component.Type.FILE, 2, "BCDE", "PROJECT_KEY:file");
+    Component project = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, file);
+    treeRootHolder.setRoot(project);
 
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .build());
+    dbIdsRepository.setComponentId(project, 1);
+    dbIdsRepository.setComponentId(file, 2);
 
+    // TODO remove this when snapshot id will come from the DbIdsRepo
     reportReader.putComponent(BatchReport.Component.newBuilder()
       .setRef(1)
       .setType(Constants.ComponentType.PROJECT)
index d2e0cef4d6cad49be07062f46cf66f7458a0d95d..d359abcec66c9d14def065cbe516e5feaea58f6c 100644 (file)
@@ -32,8 +32,9 @@ import org.sonar.batch.protocol.output.BatchReport;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.persistence.DbTester;
 import org.sonar.server.computation.batch.BatchReportReaderRule;
-import org.sonar.server.computation.component.DbComponentsRefCache;
-import org.sonar.server.computation.component.DbComponentsRefCache.DbComponent;
+import org.sonar.server.computation.batch.TreeRootHolderRule;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DumbComponent;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.event.db.EventDao;
 import org.sonar.test.DbTests;
@@ -44,15 +45,16 @@ import static org.mockito.Mockito.when;
 @Category(DbTests.class)
 public class PersistEventsStepTest extends BaseStepTest {
 
-  private static final String PROJECT_KEY = "PROJECT_KEY";
-
   @ClassRule
   public static DbTester dbTester = new DbTester();
+
+  @Rule
+  public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
+
   @Rule
   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
 
   DbSession session;
-  DbComponentsRefCache dbComponentsRefCache;
   PersistEventsStep step;
 
   @Before
@@ -63,8 +65,7 @@ public class PersistEventsStepTest extends BaseStepTest {
     System2 system2 = mock(System2.class);
     when(system2.now()).thenReturn(1225630680000L);
 
-    dbComponentsRefCache = new DbComponentsRefCache();
-    step = new PersistEventsStep(dbClient, system2, dbComponentsRefCache, reportReader);
+    step = new PersistEventsStep(dbClient, system2, treeRootHolder, reportReader);
   }
 
   @Override
@@ -81,11 +82,10 @@ public class PersistEventsStepTest extends BaseStepTest {
   public void nothing_to_do_when_no_events_in_report() throws Exception {
     dbTester.prepareDbUnit(getClass(), "nothing_to_do_when_no_events_in_report.xml");
 
-    dbComponentsRefCache.addComponent(1, new DbComponent(1L, PROJECT_KEY, "ABCD"));
+    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null));
 
     reportReader.setMetadata(BatchReport.Metadata.newBuilder()
       .setRootComponentRef(1)
-      .setProjectKey(PROJECT_KEY)
       .setAnalysisDate(150000000L)
       .build());
 
@@ -103,11 +103,10 @@ public class PersistEventsStepTest extends BaseStepTest {
   public void persist_report_events() throws Exception {
     dbTester.prepareDbUnit(getClass(), "empty.xml");
 
-    dbComponentsRefCache.addComponent(1, new DbComponent(1L, PROJECT_KEY, "ABCD"));
+    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null));
 
     reportReader.setMetadata(BatchReport.Metadata.newBuilder()
       .setRootComponentRef(1)
-      .setProjectKey(PROJECT_KEY)
       .setAnalysisDate(150000000L)
       .build());
 
@@ -138,12 +137,11 @@ public class PersistEventsStepTest extends BaseStepTest {
   public void persist_report_events_with_component_children() throws Exception {
     dbTester.prepareDbUnit(getClass(), "empty.xml");
 
-    dbComponentsRefCache.addComponent(1, new DbComponent(1L, PROJECT_KEY, "ABCD"));
-    dbComponentsRefCache.addComponent(2, new DbComponent(2L, "MODULE_KEY", "BCDE"));
+    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null,
+      new DumbComponent(Component.Type.MODULE, 2, "BCDE", null)));
 
     reportReader.setMetadata(BatchReport.Metadata.newBuilder()
       .setRootComponentRef(1)
-      .setProjectKey(PROJECT_KEY)
       .setAnalysisDate(150000000L)
       .build());
 
@@ -179,11 +177,10 @@ public class PersistEventsStepTest extends BaseStepTest {
   public void create_version_event() throws Exception {
     dbTester.prepareDbUnit(getClass(), "empty.xml");
 
-    dbComponentsRefCache.addComponent(1, new DbComponent(1L, PROJECT_KEY, "ABCD"));
+    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null));
 
     reportReader.setMetadata(BatchReport.Metadata.newBuilder()
       .setRootComponentRef(1)
-      .setProjectKey(PROJECT_KEY)
       .setAnalysisDate(150000000L)
       .build());
 
@@ -203,11 +200,10 @@ public class PersistEventsStepTest extends BaseStepTest {
   public void keep_one_event_by_version() throws Exception {
     dbTester.prepareDbUnit(getClass(), "keep_one_event_by_version.xml");
 
-    dbComponentsRefCache.addComponent(1, new DbComponent(1L, PROJECT_KEY, "ABCD"));
+    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null));
 
     reportReader.setMetadata(BatchReport.Metadata.newBuilder()
       .setRootComponentRef(1)
-      .setProjectKey(PROJECT_KEY)
       .setAnalysisDate(150000000L)
       .build());
 
index fd140226a40a39194463c30ef618dc046ca1d4ea..355b1b5dd9d26adcc8746c4bb46e56c6bf215cc2 100644 (file)
@@ -39,7 +39,9 @@ import org.sonar.core.persistence.DbTester;
 import org.sonar.core.source.db.FileSourceDto;
 import org.sonar.core.source.db.FileSourceDto.Type;
 import org.sonar.server.computation.batch.BatchReportReaderRule;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.batch.TreeRootHolderRule;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DumbComponent;
 import org.sonar.server.computation.language.LanguageRepository;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.source.db.FileSourceDao;
@@ -63,6 +65,10 @@ public class PersistFileSourcesStepTest extends BaseStepTest {
 
   @ClassRule
   public static DbTester dbTester = new DbTester();
+
+  @Rule
+  public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
+
   @Rule
   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
 
@@ -71,7 +77,6 @@ public class PersistFileSourcesStepTest extends BaseStepTest {
 
   DbSession session;
   DbClient dbClient;
-  DbComponentsRefCache dbComponentsRefCache;
   PersistFileSourcesStep sut;
 
   long now = 123456789L;
@@ -84,8 +89,7 @@ public class PersistFileSourcesStepTest extends BaseStepTest {
 
     System2 system2 = mock(System2.class);
     when(system2.now()).thenReturn(now);
-    dbComponentsRefCache = new DbComponentsRefCache();
-    sut = new PersistFileSourcesStep(dbClient, system2, dbComponentsRefCache, reportReader);
+    sut = new PersistFileSourcesStep(dbClient, system2, treeRootHolder, reportReader);
   }
 
   @Override
@@ -124,13 +128,9 @@ public class PersistFileSourcesStepTest extends BaseStepTest {
 
   @Test
   public void persist_last_line() throws Exception {
-    dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, PROJECT_UUID));
-    dbComponentsRefCache.addComponent(FILE_REF, new DbComponentsRefCache.DbComponent(2L, "PROJECT_KEY:file", FILE_UUID));
+    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, PROJECT_UUID, PROJECT_KEY,
+      new DumbComponent(Component.Type.FILE, FILE_REF, FILE_UUID, "PROJECT_KEY:file")));
 
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .setProjectKey(PROJECT_KEY)
-      .build());
     reportReader.putComponent(BatchReport.Component.newBuilder()
       .setRef(1)
       .setType(Constants.ComponentType.PROJECT)
@@ -428,19 +428,14 @@ public class PersistFileSourcesStepTest extends BaseStepTest {
       sut.execute();
       failBecauseExceptionWasNotThrown(IllegalStateException.class);
     } catch (IllegalStateException e) {
-      assertThat(e).hasMessage("Cannot persist sources of src/Foo.java").hasCauseInstanceOf(IllegalArgumentException.class);
+      assertThat(e).hasMessage("Cannot persist sources of MODULE_KEY:src/Foo.java").hasCauseInstanceOf(IllegalArgumentException.class);
     }
   }
 
   private void initBasicReport(int numberOfLines) throws IOException {
-    dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, PROJECT_UUID));
-    dbComponentsRefCache.addComponent(2, new DbComponentsRefCache.DbComponent(2L, "MODULE_KEY", "MODULE"));
-    dbComponentsRefCache.addComponent(FILE_REF, new DbComponentsRefCache.DbComponent(3L, "MODULE_KEY:src/Foo.java", FILE_UUID));
-
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .setProjectKey(PROJECT_KEY)
-      .build());
+    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, PROJECT_UUID, PROJECT_KEY,
+      new DumbComponent(Component.Type.MODULE, 2, "MODULE", "MODULE_KEY",
+        new DumbComponent(Component.Type.FILE, FILE_REF, FILE_UUID, "MODULE_KEY:src/Foo.java"))));
 
     reportReader.putComponent(BatchReport.Component.newBuilder()
       .setRef(1)
@@ -455,7 +450,6 @@ public class PersistFileSourcesStepTest extends BaseStepTest {
     reportReader.putComponent(BatchReport.Component.newBuilder()
       .setRef(FILE_REF)
       .setType(Constants.ComponentType.FILE)
-      .setPath("src/Foo.java")
       .setLines(numberOfLines)
       .build());
 
index 3f056cd33fd8783a897b39e2b553d655ee2c710c..81ac6888078f46a08d7baa11b3130d7850129d16 100644 (file)
@@ -45,7 +45,10 @@ import org.sonar.core.persistence.DbTester;
 import org.sonar.core.rule.RuleDto;
 import org.sonar.server.component.db.ComponentDao;
 import org.sonar.server.computation.batch.BatchReportReaderRule;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.batch.TreeRootHolderRule;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DbIdsRepository;
+import org.sonar.server.computation.component.DumbComponent;
 import org.sonar.server.computation.issue.RuleCache;
 import org.sonar.server.computation.issue.RuleCacheLoader;
 import org.sonar.server.computation.measure.MetricCache;
@@ -65,14 +68,21 @@ public class PersistMeasuresStepTest extends BaseStepTest {
   private static final String METRIC_KEY = "metric-key";
   private static final RuleKey RULE_KEY = RuleKey.of("repo", "rule-key");
 
+  private static final long FILE_COMPONENT_ID = 3L;
+  private static final long FILE_SNAPSHOT_ID = 3L;
+
   @ClassRule
   public static DbTester dbTester = new DbTester();
+
+  @Rule
+  public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
+
   @Rule
   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
 
   DbClient dbClient;
   DbSession session;
-  DbComponentsRefCache dbComponentsRefCache;
+  DbIdsRepository dbIdsRepository = new DbIdsRepository();
   MetricDto metric;
   RuleDto rule;
 
@@ -82,8 +92,6 @@ public class PersistMeasuresStepTest extends BaseStepTest {
   public void setUp() {
     dbTester.truncateTables();
 
-    dbComponentsRefCache = new DbComponentsRefCache();
-
     dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), new MeasureDao(), new ComponentDao(), new MetricDao(), new RuleDao(System2.INSTANCE));
     session = dbClient.openSession(false);
 
@@ -97,7 +105,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
     MetricCache metricCache = new MetricCache(dbClient);
     session.commit();
 
-    sut = new PersistMeasuresStep(dbClient, ruleCache, metricCache, dbComponentsRefCache, reportReader);
+    sut = new PersistMeasuresStep(dbClient, ruleCache, metricCache, dbIdsRepository, treeRootHolder, reportReader);
   }
 
   @After
@@ -107,8 +115,15 @@ public class PersistMeasuresStepTest extends BaseStepTest {
 
   @Test
   public void insert_measures_from_report() throws Exception {
-    ComponentDto project = addComponent(1, "project-key");
-    ComponentDto file = addComponent(2, "file-key");
+    ComponentDto projectDto = addComponent(1, "project-key");
+    ComponentDto fileDto = addComponent(2, "file-key");
+
+    Component file = new DumbComponent(Component.Type.FILE, 2, "CDEF", "MODULE_KEY:file");
+    Component project = new DumbComponent(Component.Type.PROJECT, 1, "ABCD", PROJECT_KEY, file);
+    treeRootHolder.setRoot(project);
+
+    dbIdsRepository.setComponentId(project, projectDto.getId());
+    dbIdsRepository.setComponentId(file, fileDto.getId());
 
     reportReader.setMetadata(BatchReport.Metadata.newBuilder()
       .setAnalysisDate(new Date().getTime())
@@ -172,7 +187,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
 
     Map<String, Object> dto = dtos.get(0);
     assertThat(dto.get("snapshotId")).isNotNull();
-    assertThat(dto.get("componentId")).isEqualTo(project.getId());
+    assertThat(dto.get("componentId")).isEqualTo(projectDto.getId());
     assertThat(dto.get("metricId")).isEqualTo(metric.getId().longValue());
     assertThat(dto.get("ruleId")).isEqualTo(rule.getId().longValue());
     assertThat(dto.get("textValue")).isEqualTo("measure-data");
@@ -180,7 +195,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
 
     dto = dtos.get(1);
     assertThat(dto.get("snapshotId")).isNotNull();
-    assertThat(dto.get("componentId")).isEqualTo(file.getId());
+    assertThat(dto.get("componentId")).isEqualTo(fileDto.getId());
     assertThat(dto.get("metricId")).isEqualTo(metric.getId().longValue());
     assertThat(dto.get("ruleId")).isEqualTo(rule.getId().longValue());
     assertThat(dto.get("value")).isEqualTo(123.123d);
@@ -210,7 +225,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
       .setPersonId(5432)
       .build();
 
-    MeasureDto measure = sut.toMeasureDto(batchMeasure, component);
+    MeasureDto measure = sut.toMeasureDto(batchMeasure, componentDto.getId(), FILE_SNAPSHOT_ID);
 
     assertThat(measure).isEqualToComparingFieldByField(new MeasureDto()
       .setComponentId(componentDto.getId())
@@ -241,11 +256,11 @@ public class PersistMeasuresStepTest extends BaseStepTest {
       .setMetricKey(METRIC_KEY)
       .build();
 
-    MeasureDto measure = sut.toMeasureDto(batchMeasure, component);
+    MeasureDto measure = sut.toMeasureDto(batchMeasure, componentDto.getId(), FILE_SNAPSHOT_ID);
 
     assertThat(measure).isEqualToComparingFieldByField(new MeasureDto()
       .setComponentId(componentDto.getId())
-      .setSnapshotId(3L)
+      .setSnapshotId(FILE_SNAPSHOT_ID)
       .setMetricId(metric.getId()));
   }
 
@@ -260,7 +275,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
       .setMetricKey(METRIC_KEY)
       .build();
 
-    MeasureDto measure = sut.toMeasureDto(batchMeasure, component);
+    MeasureDto measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
 
     assertThat(measure.getValue()).isEqualTo(1.0);
 
@@ -270,7 +285,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
       .setMetricKey(METRIC_KEY)
       .build();
 
-    measure = sut.toMeasureDto(batchMeasure, component);
+    measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
 
     assertThat(measure.getValue()).isEqualTo(0.0);
 
@@ -279,7 +294,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
       .setMetricKey(METRIC_KEY)
       .build();
 
-    measure = sut.toMeasureDto(batchMeasure, component);
+    measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
 
     assertThat(measure.getValue()).isNull();
   }
@@ -295,7 +310,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
       .setMetricKey(METRIC_KEY)
       .build();
 
-    MeasureDto measure = sut.toMeasureDto(batchMeasure, component);
+    MeasureDto measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
 
     assertThat(measure.getValue()).isEqualTo(3.2);
 
@@ -304,7 +319,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
       .setMetricKey(METRIC_KEY)
       .build();
 
-    measure = sut.toMeasureDto(batchMeasure, component);
+    measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
 
     assertThat(measure.getValue()).isNull();
   }
@@ -320,7 +335,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
       .setMetricKey(METRIC_KEY)
       .build();
 
-    MeasureDto measure = sut.toMeasureDto(batchMeasure, component);
+    MeasureDto measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
 
     assertThat(measure.getValue()).isEqualTo(3.0);
 
@@ -329,7 +344,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
       .setMetricKey(METRIC_KEY)
       .build();
 
-    measure = sut.toMeasureDto(batchMeasure, component);
+    measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
 
     assertThat(measure.getValue()).isNull();
   }
@@ -345,7 +360,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
       .setMetricKey(METRIC_KEY)
       .build();
 
-    MeasureDto measure = sut.toMeasureDto(batchMeasure, component);
+    MeasureDto measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
 
     assertThat(measure.getValue()).isEqualTo(3.0);
 
@@ -354,7 +369,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
       .setMetricKey(METRIC_KEY)
       .build();
 
-    measure = sut.toMeasureDto(batchMeasure, component);
+    measure = sut.toMeasureDto(batchMeasure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
 
     assertThat(measure.getValue()).isNull();
   }
@@ -368,7 +383,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
     BatchReport.Component component = defaultComponent()
       .build();
     addComponent(component.getRef(), "component-key");
-    sut.toMeasureDto(measure, component);
+    sut.toMeasureDto(measure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
   }
 
   @Test(expected = IllegalStateException.class)
@@ -379,7 +394,7 @@ public class PersistMeasuresStepTest extends BaseStepTest {
     BatchReport.Component component = defaultComponent()
       .build();
     addComponent(component.getRef(), "component-key");
-    sut.toMeasureDto(measure, component);
+    sut.toMeasureDto(measure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
   }
 
   @Test(expected = IllegalStateException.class)
@@ -390,40 +405,19 @@ public class PersistMeasuresStepTest extends BaseStepTest {
     BatchReport.Component component = defaultComponent()
       .build();
     addComponent(component.getRef(), "component-key");
-    sut.toMeasureDto(measure, component);
-  }
-
-  private MeasureDto expectedFullMeasure() {
-    return new MeasureDto()
-      .setComponentId(2L)
-      .setSnapshotId(3L)
-      .setCharacteristicId(123456)
-      .setPersonId(5432)
-      .setValue(123.123d)
-      .setVariation(1, 1.1d)
-      .setVariation(2, 2.2d)
-      .setVariation(3, 3.3d)
-      .setVariation(4, 4.4d)
-      .setVariation(5, 5.5d)
-      .setAlertStatus("WARN")
-      .setAlertText("Open issues > 0")
-      .setDescription("measure-description")
-      .setSeverity(Severity.CRITICAL)
-      .setMetricId(metric.getId())
-      .setRuleId(rule.getId());
+    sut.toMeasureDto(measure, FILE_COMPONENT_ID, FILE_SNAPSHOT_ID);
   }
 
   private BatchReport.Component.Builder defaultComponent() {
     return BatchReport.Component.newBuilder()
       .setRef(1)
-      .setSnapshotId(3);
+      .setSnapshotId(FILE_SNAPSHOT_ID);
   }
 
   private ComponentDto addComponent(int ref, String key) {
     ComponentDto componentDto = new ComponentDto().setKey(key).setUuid(Uuids.create());
     dbClient.componentDao().insert(session, componentDto);
     session.commit();
-    dbComponentsRefCache.addComponent(ref, new DbComponentsRefCache.DbComponent(componentDto.getId(), key, componentDto.uuid()));
     return componentDto;
   }
 
index 31496f7335d08e43580eb4a3d33cdde0e35f9d69..ff51c4d33ef4705e75e1490678ed4e9630ef9b43 100644 (file)
@@ -33,7 +33,9 @@ import org.sonar.batch.protocol.output.BatchReport;
 import org.sonar.core.metric.db.MetricDto;
 import org.sonar.core.persistence.DbTester;
 import org.sonar.server.computation.batch.BatchReportReaderRule;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.batch.TreeRootHolderRule;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DumbComponent;
 import org.sonar.server.computation.language.LanguageRepository;
 import org.sonar.server.computation.measure.MetricCache;
 import org.sonar.server.db.DbClient;
@@ -48,6 +50,10 @@ public class PersistNumberOfDaysSinceLastCommitStepTest extends BaseStepTest {
 
   @ClassRule
   public static DbTester db = new DbTester();
+
+  @Rule
+  public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
+
   @Rule
   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
 
@@ -59,8 +65,6 @@ public class PersistNumberOfDaysSinceLastCommitStepTest extends BaseStepTest {
   Settings projectSettings;
   LanguageRepository languageRepository;
 
-  DbComponentsRefCache dbComponentsRefCache;
-
   @Before
   public void setUp() throws Exception {
     db.truncateTables();
@@ -70,9 +74,8 @@ public class PersistNumberOfDaysSinceLastCommitStepTest extends BaseStepTest {
     projectSettings = new Settings();
     languageRepository = mock(LanguageRepository.class);
     when(metricCache.get(anyString())).thenReturn(new MetricDto().setId(10));
-    dbComponentsRefCache = new DbComponentsRefCache();
 
-    sut = new PersistNumberOfDaysSinceLastCommitStep(System2.INSTANCE, dbClient, sourceLineIndex, metricCache, dbComponentsRefCache, reportReader);
+    sut = new PersistNumberOfDaysSinceLastCommitStep(System2.INSTANCE, dbClient, sourceLineIndex, metricCache, treeRootHolder, reportReader);
   }
 
   @Override
@@ -120,25 +123,21 @@ public class PersistNumberOfDaysSinceLastCommitStepTest extends BaseStepTest {
   }
 
   private void initReportWithProjectAndFile() {
-    dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, "PROJECT_KEY", "project-uuid"));
-    dbComponentsRefCache.addComponent(2, new DbComponentsRefCache.DbComponent(2L, "PROJECT_KEY:file", "file-uuid"));
+    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "project-uuid", null,
+      new DumbComponent(Component.Type.FILE, 2, "file-uuid", null)));
 
     reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
       .setSnapshotId(1000)
       .build());
 
     reportReader.putComponent(BatchReport.Component.newBuilder()
       .setRef(1)
       .setType(Constants.ComponentType.PROJECT)
-      .setKey("PROJECT_KEY")
-      .setSnapshotId(10L)
       .addChildRef(2)
       .build());
     reportReader.putComponent(BatchReport.Component.newBuilder()
       .setRef(2)
       .setType(Constants.ComponentType.FILE)
-      .setSnapshotId(11L)
       .build());
   }
 }
index 7f89e57ee36490dd4788a20396760a2c919c3864..a7ec2f5be22097eaed0d674aa872c0778e843f93 100644 (file)
@@ -34,7 +34,9 @@ import org.sonar.core.persistence.DbSession;
 import org.sonar.core.persistence.DbTester;
 import org.sonar.server.component.db.ComponentLinkDao;
 import org.sonar.server.computation.batch.BatchReportReaderRule;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.batch.TreeRootHolderRule;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DumbComponent;
 import org.sonar.server.db.DbClient;
 import org.sonar.test.DbTests;
 
@@ -46,15 +48,16 @@ import static org.mockito.Mockito.when;
 @Category(DbTests.class)
 public class PersistProjectLinksStepTest extends BaseStepTest {
 
-  private static final String PROJECT_KEY = "PROJECT_KEY";
-
   @ClassRule
   public static DbTester dbTester = new DbTester();
+
+  @Rule
+  public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
+
   @Rule
   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
 
   DbSession session;
-  DbComponentsRefCache dbComponentsRefCache;
 
   PersistProjectLinksStep step;
 
@@ -70,8 +73,7 @@ public class PersistProjectLinksStepTest extends BaseStepTest {
     when(i18n.message(Locale.ENGLISH, "project_links.ci", null)).thenReturn("Continuous integration");
     when(i18n.message(Locale.ENGLISH, "project_links.issue", null)).thenReturn("Issues");
 
-    dbComponentsRefCache = new DbComponentsRefCache();
-    step = new PersistProjectLinksStep(dbClient, i18n, dbComponentsRefCache, reportReader);
+    step = new PersistProjectLinksStep(dbClient, i18n, treeRootHolder, reportReader);
   }
 
   @Override
@@ -88,16 +90,10 @@ public class PersistProjectLinksStepTest extends BaseStepTest {
   public void add_links_on_project_and_module() throws Exception {
     dbTester.prepareDbUnit(getClass(), "empty.xml");
 
-    dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD"));
-    dbComponentsRefCache.addComponent(2, new DbComponentsRefCache.DbComponent(2L, "MODULE_KEY", "BCDE"));
+    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null,
+      new DumbComponent(Component.Type.MODULE, 2, "BCDE", null)));
 
     // project and 1 module
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .setProjectKey(PROJECT_KEY)
-      .setAnalysisDate(150000000L)
-      .build());
-
     reportReader.putComponent(BatchReport.Component.newBuilder()
       .setRef(1)
       .setType(Constants.ComponentType.PROJECT)
@@ -123,12 +119,7 @@ public class PersistProjectLinksStepTest extends BaseStepTest {
   public void nothing_to_do_when_link_already_exists() throws Exception {
     dbTester.prepareDbUnit(getClass(), "nothing_to_do_when_link_already_exists.xml");
 
-    dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD"));
-
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .setProjectKey(PROJECT_KEY)
-      .build());
+    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null));
 
     reportReader.putComponent(BatchReport.Component.newBuilder()
       .setRef(1)
@@ -145,15 +136,16 @@ public class PersistProjectLinksStepTest extends BaseStepTest {
   public void do_not_add_links_on_file() throws Exception {
     dbTester.prepareDbUnit(getClass(), "empty.xml");
 
-    dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD"));
-
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .setProjectKey(PROJECT_KEY)
-      .build());
+    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null,
+      new DumbComponent(Component.Type.FILE, 2, "BCDE", null)));
 
     reportReader.putComponent(BatchReport.Component.newBuilder()
       .setRef(1)
+      .setType(Constants.ComponentType.PROJECT)
+      .addChildRef(2)
+      .build());
+    reportReader.putComponent(BatchReport.Component.newBuilder()
+      .setRef(2)
       .setType(Constants.ComponentType.FILE)
       .addLink(BatchReport.ComponentLink.newBuilder().setType(Constants.ComponentLinkType.HOME).setHref("http://www.sonarqube.org").build())
       .build());
@@ -167,12 +159,7 @@ public class PersistProjectLinksStepTest extends BaseStepTest {
   public void update_link() throws Exception {
     dbTester.prepareDbUnit(getClass(), "update_link.xml");
 
-    dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD"));
-
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .setProjectKey(PROJECT_KEY)
-      .build());
+    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null));
 
     reportReader.putComponent(BatchReport.Component.newBuilder()
       .setRef(1)
@@ -189,12 +176,7 @@ public class PersistProjectLinksStepTest extends BaseStepTest {
   public void delete_link() throws Exception {
     dbTester.prepareDbUnit(getClass(), "delete_link.xml");
 
-    dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD"));
-
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .setProjectKey(PROJECT_KEY)
-      .build());
+    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null));
 
     reportReader.putComponent(BatchReport.Component.newBuilder()
       .setRef(1)
@@ -210,12 +192,7 @@ public class PersistProjectLinksStepTest extends BaseStepTest {
   public void not_delete_custom_link() throws Exception {
     dbTester.prepareDbUnit(getClass(), "not_delete_custom_link.xml");
 
-    dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD"));
-
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .setProjectKey(PROJECT_KEY)
-      .build());
+    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null));
 
     reportReader.putComponent(BatchReport.Component.newBuilder()
       .setRef(1)
@@ -231,12 +208,7 @@ public class PersistProjectLinksStepTest extends BaseStepTest {
   public void fail_when_trying_to_add_same_link_type_multiple_times() throws Exception {
     dbTester.prepareDbUnit(getClass(), "empty.xml");
 
-    dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, "ABCD"));
-
-    reportReader.setMetadata(BatchReport.Metadata.newBuilder()
-      .setRootComponentRef(1)
-      .setProjectKey(PROJECT_KEY)
-      .build());
+    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, "ABCD", null));
 
     reportReader.putComponent(BatchReport.Component.newBuilder()
       .setRef(1)
index 31afd166b457c01d8ca58e33acfbf8dfdd289463..9306b3b0566ac2bc8aec1a57f5f95edf32b6d867 100644 (file)
@@ -40,8 +40,6 @@ import org.sonar.core.source.db.FileSourceDto;
 import org.sonar.server.computation.batch.BatchReportReaderRule;
 import org.sonar.server.computation.batch.TreeRootHolderRule;
 import org.sonar.server.computation.component.Component;
-import org.sonar.server.computation.component.DbComponentsRefCache;
-import org.sonar.server.computation.component.DbComponentsRefCache.DbComponent;
 import org.sonar.server.computation.component.DumbComponent;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.source.db.FileSourceDao;
@@ -53,6 +51,7 @@ import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 public class PersistTestsStepTest extends BaseStepTest {
+
   private static final String PROJECT_UUID = "PROJECT";
   private static final String PROJECT_KEY = "PROJECT_KEY";
   private static final int TEST_FILE_REF_1 = 3;
@@ -68,16 +67,18 @@ public class PersistTestsStepTest extends BaseStepTest {
 
   @ClassRule
   public static DbTester db = new DbTester();
+
   @Rule
   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
+
   @Rule
   public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
+
   @Rule
   public LogTester log = new LogTester();
 
   DbSession session;
   DbClient dbClient;
-  DbComponentsRefCache dbComponentsRefCache;
   Component root;
 
   PersistTestsStep sut;
@@ -93,8 +94,7 @@ public class PersistTestsStepTest extends BaseStepTest {
     System2 system2 = mock(System2.class);
     when(system2.now()).thenReturn(now);
 
-    dbComponentsRefCache = new DbComponentsRefCache();
-    sut = new PersistTestsStep(dbClient, system2, dbComponentsRefCache, reportReader, treeRootHolder);
+    sut = new PersistTestsStep(dbClient, system2, reportReader, treeRootHolder);
 
     initBasicReport();
 
@@ -218,8 +218,8 @@ public class PersistTestsStepTest extends BaseStepTest {
   public void aggregate_coverage_details() {
     reportReader.putTests(TEST_FILE_REF_1, Arrays.asList(newTest(1)));
     reportReader.putCoverageDetails(TEST_FILE_REF_1, Arrays.asList(
-        newCoverageDetailWithLines(1, MAIN_FILE_REF_1, 1, 3),
-        newCoverageDetailWithLines(1, MAIN_FILE_REF_1, 2, 4)));
+      newCoverageDetailWithLines(1, MAIN_FILE_REF_1, 1, 3),
+      newCoverageDetailWithLines(1, MAIN_FILE_REF_1, 2, 4)));
 
     sut.execute();
 
@@ -300,13 +300,6 @@ public class PersistTestsStepTest extends BaseStepTest {
   }
 
   private void initBasicReport() {
-    dbComponentsRefCache.addComponent(1, new DbComponent(1L, "PROJECT_KEY", PROJECT_UUID));
-    dbComponentsRefCache.addComponent(2, new DbComponent(2L, "MODULE_KEY", "MODULE"));
-    dbComponentsRefCache.addComponent(3, new DbComponent(3L, "TEST_FILE1_KEY", TEST_FILE_UUID_1));
-    dbComponentsRefCache.addComponent(4, new DbComponent(4L, "TEST_FILE2_KEY", TEST_FILE_UUID_2));
-    dbComponentsRefCache.addComponent(5, new DbComponent(5L, "MAIN_FILE1_KEY", MAIN_FILE_UUID_1));
-    dbComponentsRefCache.addComponent(6, new DbComponent(6L, "MAIN_FILE2_KEY", MAIN_FILE_UUID_2));
-
     reportReader.setMetadata(BatchReport.Metadata.newBuilder()
       .setRootComponentRef(1)
       .setProjectKey(PROJECT_KEY)
index 3852abbb4df720ce9001e3668c08193562ed4d3b..38925d25ed54e1c15bbede86d36f143237947d34 100644 (file)
@@ -32,7 +32,10 @@ import org.sonar.core.computation.dbcleaner.ProjectCleaner;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.core.purge.IdUuidPair;
 import org.sonar.server.computation.batch.BatchReportReaderRule;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.batch.TreeRootHolderRule;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DbIdsRepository;
+import org.sonar.server.computation.component.DumbComponent;
 import org.sonar.server.computation.component.ProjectSettingsRepository;
 import org.sonar.server.db.DbClient;
 
@@ -49,11 +52,15 @@ public class PurgeDatastoresStepTest extends BaseStepTest {
   @Rule
   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
 
+  @Rule
+  public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
+
+  DbIdsRepository dbIdsRepository = new DbIdsRepository();
+
   ProjectCleaner projectCleaner = mock(ProjectCleaner.class);
-  DbComponentsRefCache dbComponentsRefCache = new DbComponentsRefCache();
   ProjectSettingsRepository projectSettingsRepository = mock(ProjectSettingsRepository.class);
 
-  PurgeDatastoresStep sut = new PurgeDatastoresStep(mock(DbClient.class, Mockito.RETURNS_DEEP_STUBS), projectCleaner, dbComponentsRefCache, projectSettingsRepository, reportReader);
+  PurgeDatastoresStep sut = new PurgeDatastoresStep(mock(DbClient.class, Mockito.RETURNS_DEEP_STUBS), projectCleaner, dbIdsRepository, treeRootHolder, projectSettingsRepository);
 
   @Before
   public void setUp() throws Exception {
@@ -62,7 +69,9 @@ public class PurgeDatastoresStepTest extends BaseStepTest {
 
   @Test
   public void call_purge_method_of_the_purge_task() throws IOException {
-    dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(123L, PROJECT_KEY, "UUID-1234"));
+    Component project = new DumbComponent(Component.Type.PROJECT, 1, "UUID-1234", PROJECT_KEY);
+    treeRootHolder.setRoot(project);
+    dbIdsRepository.setComponentId(project, 123L);
 
     reportReader.setMetadata(BatchReport.Metadata.newBuilder()
       .setRootComponentRef(1)
index cf1ca6f6a36ab4de2408a67c518dd0d4b8f797eb..7fb81786e6c91f08cdd0f5a05bb3bd49fffe1adf 100644 (file)
@@ -32,7 +32,9 @@ import org.sonar.api.utils.System2;
 import org.sonar.batch.protocol.Constants;
 import org.sonar.batch.protocol.output.BatchReport;
 import org.sonar.server.computation.batch.BatchReportReaderRule;
-import org.sonar.server.computation.component.DbComponentsRefCache;
+import org.sonar.server.computation.batch.TreeRootHolderRule;
+import org.sonar.server.computation.component.Component;
+import org.sonar.server.computation.component.DumbComponent;
 import org.sonar.server.computation.issue.IssueCache;
 import org.sonar.server.computation.issue.RuleCache;
 import org.sonar.server.issue.notification.IssueChangeNotification;
@@ -54,6 +56,10 @@ public class SendIssueNotificationsStepTest extends BaseStepTest {
 
   @Rule
   public BatchReportReaderRule reportReader = new BatchReportReaderRule();
+
+  @Rule
+  public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
+
   @Rule
   public TemporaryFolder temp = new TemporaryFolder();
 
@@ -64,11 +70,10 @@ public class SendIssueNotificationsStepTest extends BaseStepTest {
   @Before
   public void setUp() throws Exception {
     issueCache = new IssueCache(temp.newFile(), System2.INSTANCE);
-    DbComponentsRefCache dbComponentsRefCache = new DbComponentsRefCache();
     NewIssuesNotificationFactory newIssuesNotificationFactory = mock(NewIssuesNotificationFactory.class, Mockito.RETURNS_DEEP_STUBS);
-    sut = new SendIssueNotificationsStep(issueCache, mock(RuleCache.class), dbComponentsRefCache, notifService, reportReader, newIssuesNotificationFactory);
+    sut = new SendIssueNotificationsStep(issueCache, mock(RuleCache.class), treeRootHolder, notifService, reportReader, newIssuesNotificationFactory);
 
-    dbComponentsRefCache.addComponent(1, new DbComponentsRefCache.DbComponent(1L, PROJECT_KEY, PROJECT_UUID));
+    treeRootHolder.setRoot(new DumbComponent(Component.Type.PROJECT, 1, PROJECT_UUID, PROJECT_KEY));
 
     reportReader.setMetadata(BatchReport.Metadata.newBuilder()
       .setRootComponentRef(1)
@@ -93,7 +98,7 @@ public class SendIssueNotificationsStepTest extends BaseStepTest {
   @Test
   public void send_notifications_if_subscribers() {
     issueCache.newAppender().append(new DefaultIssue()
-        .setSeverity(Severity.BLOCKER)).close();
+      .setSeverity(Severity.BLOCKER)).close();
 
     when(notifService.hasProjectSubscribersForTypes(PROJECT_UUID, SendIssueNotificationsStep.NOTIF_TYPES)).thenReturn(true);