From 08f807ca759212e6f6b2c05063bc2d32e5383615 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Wed, 3 Jun 2015 10:15:21 +0200 Subject: [PATCH] SONAR-6253 Cache of component ids do not contains anymore key and uuid Instead, use TreeRootHolder to get component key and uuid --- .../benchmark/PersistFileSourcesStepTest.java | 26 +- ...entsRefCache.java => DbIdsRepository.java} | 56 ++--- .../container/ComputeEngineContainerImpl.java | 4 +- .../step/ApplyPermissionsStep.java | 10 +- .../computation/step/IndexComponentsStep.java | 17 +- .../step/IndexSourceLinesStep.java | 13 +- .../computation/step/IndexTestsStep.java | 13 +- .../step/PersistComponentsStep.java | 22 +- .../step/PersistDuplicationsStep.java | 152 ++++++------ .../computation/step/PersistEventsStep.java | 126 ++++++---- .../step/PersistFileSourcesStep.java | 144 +++++------ .../computation/step/PersistMeasuresStep.java | 77 +++--- ...ersistNumberOfDaysSinceLastCommitStep.java | 80 +++--- .../step/PersistProjectLinksStep.java | 106 ++++---- .../computation/step/PersistTestsStep.java | 22 +- .../computation/step/PurgeDatastoresStep.java | 21 +- .../step/SendIssueNotificationsStep.java | 16 +- .../computation/batch/ComponentTreeRule.java | 127 ++++++++++ ...acheTest.java => DbIdsRepositoryTest.java} | 35 ++- .../step/ApplyPermissionsStepTest.java | 22 +- .../step/IndexComponentsStepTest.java | 27 +- .../step/IndexSourceLinesStepTest.java | 22 +- .../computation/step/IndexTestsStepTest.java | 20 +- .../step/PersistComponentsStepTest.java | 234 +++++++++--------- .../step/PersistDuplicationsStepTest.java | 109 ++++---- .../step/PersistEventsStepTest.java | 32 ++- .../step/PersistFileSourcesStepTest.java | 34 ++- .../step/PersistMeasuresStepTest.java | 86 +++---- ...stNumberOfDaysSinceLastCommitStepTest.java | 21 +- .../step/PersistProjectLinksStepTest.java | 72 ++---- .../step/PersistTestsStepTest.java | 21 +- .../step/PurgeDatastoresStepTest.java | 17 +- .../step/SendIssueNotificationsStepTest.java | 15 +- 33 files changed, 974 insertions(+), 825 deletions(-) rename server/sonar-server/src/main/java/org/sonar/server/computation/component/{DbComponentsRefCache.java => DbIdsRepository.java} (51%) create mode 100644 server/sonar-server/src/test/java/org/sonar/server/computation/batch/ComponentTreeRule.java rename server/sonar-server/src/test/java/org/sonar/server/computation/component/{DbComponentsRefCacheTest.java => DbIdsRepositoryTest.java} (54%) diff --git a/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/PersistFileSourcesStepTest.java b/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/PersistFileSourcesStepTest.java index 4919aa890d4..d4bad3f9b50 100644 --- a/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/PersistFileSourcesStepTest.java +++ b/server/sonar-server-benchmarks/src/test/java/org/sonar/server/benchmark/PersistFileSourcesStepTest.java @@ -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 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/DbIdsRepository.java similarity index 51% rename from server/sonar-server/src/main/java/org/sonar/server/computation/component/DbComponentsRefCache.java rename to server/sonar-server/src/main/java/org/sonar/server/computation/component/DbIdsRepository.java index 3c9dda687f4..a07059b1e43 100644 --- 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/DbIdsRepository.java @@ -24,53 +24,33 @@ 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 + * Cache of persisted component (component id) that can be used in the persistence steps */ -public class DbComponentsRefCache { +public class DbIdsRepository { - private final Map componentsByRef; + private final Map componentIdsByRef; - public DbComponentsRefCache() { - componentsByRef = new HashMap<>(); + public DbIdsRepository() { + componentIdsByRef = new HashMap<>(); } - public DbComponentsRefCache addComponent(Integer ref, DbComponent component) { - componentsByRef.put(ref, component); + 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 DbComponent getByRef(Integer ref) { - DbComponent component = componentsByRef.get(ref); - if (component == null) { - throw new IllegalArgumentException(String.format("Component ref '%s' does not exists", ref)); + 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 componentsByRef.get(ref); + return componentId; } - 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/container/ComputeEngineContainerImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainerImpl.java index 2dd0c519cc3..897160138c1 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainerImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainerImpl.java @@ -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, diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ApplyPermissionsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ApplyPermissionsStep.java index e67e6b15809..0b30dbf19e5 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ApplyPermissionsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ApplyPermissionsStep.java @@ -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(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexComponentsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexComponentsStep.java index 75b8d6acb2b..53285259121 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexComponentsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexComponentsStep.java @@ -21,26 +21,27 @@ 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 diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexSourceLinesStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexSourceLinesStep.java index ee709b8e154..237871065bf 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexSourceLinesStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexSourceLinesStep.java @@ -19,25 +19,22 @@ */ 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 diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexTestsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexTestsStep.java index bd5666e539a..663b0c2030e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexTestsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/IndexTestsStep.java @@ -20,25 +20,22 @@ 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 diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsStep.java index 629b883697b..98d0c2dce3c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistComponentsStep.java @@ -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; } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistDuplicationsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistDuplicationsStep.java index 5cd1ae314cc..f635806afd1 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistDuplicationsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistDuplicationsStep.java @@ -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 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 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 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 duplications) { + private void saveDuplications(BatchReport.Component batchComponent, Component component, List 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(""); - for (BatchReport.Duplication duplication : duplications) { - xml.append(""); - appendDuplication(xml, componentKey, duplication.getOriginPosition()); - for (BatchReport.Duplicate duplicationBlock : duplication.getDuplicateList()) { - processDuplicationBlock(duplicationContext, xml, duplicationBlock, componentKey); + private String createXmlDuplications(String componentKey, Iterable duplications) { + StringBuilder xml = new StringBuilder(); + xml.append(""); + for (BatchReport.Duplication duplication : duplications) { + xml.append(""); + appendDuplication(xml, componentKey, duplication.getOriginPosition()); + for (BatchReport.Duplicate duplicationBlock : duplication.getDuplicateList()) { + processDuplicationBlock(xml, duplicationBlock, componentKey); + } + xml.append(""); } - xml.append(""); + xml.append(""); + return xml.toString(); } - xml.append(""); - 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(""); - } - - 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(""); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistEventsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistEventsStep.java index 45c9aef8f3b..e1a6af7af2e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistEventsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistEventsStep.java @@ -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 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 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())); + } } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistFileSourcesStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistFileSourcesStep.java index e988b39d41b..523f4a3d608 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistFileSourcesStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistFileSourcesStep.java @@ -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 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 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 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 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 previousFileSourcesByUuid; - String projectUuid; - - public FileSourcesContext(DbSession session, Map previousFileSourcesByUuid, String projectUuid) { - this.previousFileSourcesByUuid = previousFileSourcesByUuid; - this.session = session; - this.projectUuid = projectUuid; - } - } - private static class LineReaders { private final List readers = new ArrayList<>(); private final List> iterators = new ArrayList<>(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistMeasuresStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistMeasuresStep.java index b9e4129ff7a..f6f51d04271 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistMeasuresStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistMeasuresStep.java @@ -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 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 measures = reportReader.readComponentMeasures(componentRef); + persistMeasures(measures, dbIdsRepository.getComponentId(component), batchComponent.getSnapshotId()); + } - } - private void persistMeasures(DbSession dbSession, List 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 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; - } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStep.java index 8b1262c3af0..74f9bd8258e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStep.java @@ -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(); + } + } + } } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistProjectLinksStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistProjectLinksStep.java index fa446ef3ea4..949c73698de 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistProjectLinksStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistProjectLinksStep.java @@ -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 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 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 links) { List previousLinks = dbClient.componentLinkDao().selectByComponentUuid(session, componentUuid); mergeLinks(session, componentUuid, links, previousLinks); } - } - private void mergeLinks(DbSession session, String componentUuid, List links, List previousLinks) { - Set 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 links, List previousLinks) { + Set 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() { - @Override - public boolean apply(@Nullable ComponentLinkDto input) { - return input != null && input.getType().equals(convertType(link.getType())); + ComponentLinkDto previousLink = Iterables.find(previousLinks, new Predicate() { + @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()); + } } } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistTestsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistTestsStep.java index aee6d513529..6a2beaf529a 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistTestsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PersistTestsStep.java @@ -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 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; } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PurgeDatastoresStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PurgeDatastoresStep.java index 781835c4d88..9dddd4cf078 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/PurgeDatastoresStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/PurgeDatastoresStep.java @@ -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); diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/SendIssueNotificationsStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/SendIssueNotificationsStep.java index f5ec9173f2f..cbc929306ea 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/SendIssueNotificationsStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/SendIssueNotificationsStep.java @@ -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 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 index 00000000000..db6e2bc5710 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/batch/ComponentTreeRule.java @@ -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() { + @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/DbIdsRepositoryTest.java similarity index 54% rename from server/sonar-server/src/test/java/org/sonar/server/computation/component/DbComponentsRefCacheTest.java rename to server/sonar-server/src/test/java/org/sonar/server/computation/component/DbIdsRepositoryTest.java index 67c20dfa9b2..d2c30aae8b4 100644 --- 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/DbIdsRepositoryTest.java @@ -20,26 +20,43 @@ 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 DbComponentsRefCacheTest { +public class DbIdsRepositoryTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + Component component = DumbComponent.DUMB_PROJECT; @Test public void add_and_get_component() throws Exception { - DbComponentsRefCache cache = new DbComponentsRefCache(); - cache.addComponent(1, new DbComponentsRefCache.DbComponent(10L, "Key", "Uuid")); + DbIdsRepository cache = new DbIdsRepository(); + cache.setComponentId(component, 10L); - 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"); + assertThat(cache.getComponentId(component)).isEqualTo(10L); } - @Test(expected = IllegalArgumentException.class) + @Test public void fail_on_unknown_ref() throws Exception { - new DbComponentsRefCache().getByRef(1); + 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); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ApplyPermissionsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ApplyPermissionsStepTest.java index 286f58c79cd..e77c23cfff9 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ApplyPermissionsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ApplyPermissionsStepTest.java @@ -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(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexComponentsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexComponentsStepTest.java index c28d1a7a30c..de876131970 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexComponentsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexComponentsStepTest.java @@ -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(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexSourceLinesStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexSourceLinesStepTest.java index 9ff56d86d8c..d088251659c 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexSourceLinesStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexSourceLinesStepTest.java @@ -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(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexTestsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexTestsStepTest.java index 3970cbcc031..b36e572c090 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexTestsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/IndexTestsStepTest.java @@ -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(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsStepTest.java index e91e84168f9..53ce81eb0c2 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistComponentsStepTest.java @@ -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"))); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistDuplicationsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistDuplicationsStepTest.java index 04b283d6a83..c61cfb73622 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistDuplicationsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistDuplicationsStepTest.java @@ -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) diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistEventsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistEventsStepTest.java index d2e0cef4d6c..d359abcec66 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistEventsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistEventsStepTest.java @@ -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()); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistFileSourcesStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistFileSourcesStepTest.java index fd140226a40..355b1b5dd9d 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistFileSourcesStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistFileSourcesStepTest.java @@ -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()); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java index 3f056cd33fd..81ac6888078 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistMeasuresStepTest.java @@ -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 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; } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStepTest.java index 31496f7335d..ff51c4d33ef 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistNumberOfDaysSinceLastCommitStepTest.java @@ -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()); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistProjectLinksStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistProjectLinksStepTest.java index 7f89e57ee36..a7ec2f5be22 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistProjectLinksStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistProjectLinksStepTest.java @@ -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) diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistTestsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistTestsStepTest.java index 31afd166b45..9306b3b0566 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistTestsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PersistTestsStepTest.java @@ -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) diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeDatastoresStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeDatastoresStepTest.java index 3852abbb4df..38925d25ed5 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeDatastoresStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/PurgeDatastoresStepTest.java @@ -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) diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/SendIssueNotificationsStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/SendIssueNotificationsStepTest.java index cf1ca6f6a36..7fb81786e6c 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/SendIssueNotificationsStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/SendIssueNotificationsStepTest.java @@ -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); -- 2.39.5