Skip to content

Commit

Permalink
SONAR-6014 Remove/Postpone DB dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
henryju committed Jan 7, 2015
1 parent f45c276 commit 2432235
Show file tree
Hide file tree
Showing 11 changed files with 58 additions and 42 deletions.
28 changes: 18 additions & 10 deletions sonar-batch/src/main/java/org/sonar/batch/ProjectConfigurator.java
Expand Up @@ -35,6 +35,8 @@
import org.sonar.api.utils.SonarException; import org.sonar.api.utils.SonarException;
import org.sonar.api.utils.System2; import org.sonar.api.utils.System2;


import javax.annotation.Nullable;

import java.util.Date; import java.util.Date;


public class ProjectConfigurator implements BatchComponent { public class ProjectConfigurator implements BatchComponent {
Expand All @@ -45,12 +47,16 @@ public class ProjectConfigurator implements BatchComponent {
private Settings settings; private Settings settings;
private final System2 system2; private final System2 system2;


public ProjectConfigurator(DatabaseSession databaseSession, Settings settings, System2 system2) { public ProjectConfigurator(@Nullable DatabaseSession databaseSession, Settings settings, System2 system2) {
this.databaseSession = databaseSession; this.databaseSession = databaseSession;
this.settings = settings; this.settings = settings;
this.system2 = system2; this.system2 = system2;
} }


public ProjectConfigurator(Settings settings, System2 system2) {
this(null, settings, system2);
}

public Project create(ProjectDefinition definition) { public Project create(ProjectDefinition definition) {
Project project = new Project(definition.getKey(), loadProjectBranch(), definition.getName()); Project project = new Project(definition.getKey(), loadProjectBranch(), definition.getName());


Expand Down Expand Up @@ -84,15 +90,17 @@ public ProjectConfigurator configure(Project project) {
} }


private void checkCurrentAnalysisIsTheLatestOne(String projectKey, Date analysisDate) { private void checkCurrentAnalysisIsTheLatestOne(String projectKey, Date analysisDate) {
ResourceModel persistedProject = databaseSession.getSingleResult(ResourceModel.class, "key", projectKey, "enabled", true); if (databaseSession != null) {
if (persistedProject != null) { ResourceModel persistedProject = databaseSession.getSingleResult(ResourceModel.class, "key", projectKey, "enabled", true);
Snapshot lastSnapshot = databaseSession.getSingleResult(Snapshot.class, "resourceId", persistedProject.getId(), "last", true); if (persistedProject != null) {
if (lastSnapshot != null && !lastSnapshot.getCreatedAt().before(analysisDate)) { Snapshot lastSnapshot = databaseSession.getSingleResult(Snapshot.class, "resourceId", persistedProject.getId(), "last", true);
throw new IllegalArgumentException( if (lastSnapshot != null && !lastSnapshot.getCreatedAt().before(analysisDate)) {
"'sonar.projectDate' property cannot be older than the date of the last known quality snapshot on this project. Value: '" + throw new IllegalArgumentException(
settings.getString(CoreProperties.PROJECT_DATE_PROPERTY) + "'. " + "'sonar.projectDate' property cannot be older than the date of the last known quality snapshot on this project. Value: '" +
"Latest quality snapshot: '" + DateUtils.formatDateTime(lastSnapshot.getCreatedAt()) settings.getString(CoreProperties.PROJECT_DATE_PROPERTY) + "'. " +
+ "'. This property may only be used to rebuild the past in a chronological order."); "Latest quality snapshot: '" + DateUtils.formatDateTime(lastSnapshot.getCreatedAt())
+ "'. This property may only be used to rebuild the past in a chronological order.");
}
} }
} }
} }
Expand Down
Expand Up @@ -31,12 +31,11 @@
import org.sonar.api.batch.Event; import org.sonar.api.batch.Event;
import org.sonar.api.batch.SonarIndex; import org.sonar.api.batch.SonarIndex;
import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.design.Dependency; import org.sonar.api.design.Dependency;
import org.sonar.api.measures.Measure; import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasuresFilter; import org.sonar.api.measures.MeasuresFilter;
import org.sonar.api.measures.MeasuresFilters; import org.sonar.api.measures.MeasuresFilters;
import org.sonar.api.measures.Metric;
import org.sonar.api.measures.MetricFinder;
import org.sonar.api.resources.Directory; import org.sonar.api.resources.Directory;
import org.sonar.api.resources.File; import org.sonar.api.resources.File;
import org.sonar.api.resources.Project; import org.sonar.api.resources.Project;
Expand Down Expand Up @@ -219,15 +218,14 @@ public <M> M getMeasures(Resource resource, MeasuresFilter<M> filter) {
public Measure addMeasure(Resource resource, Measure measure) { public Measure addMeasure(Resource resource, Measure measure) {
Bucket bucket = getBucket(resource); Bucket bucket = getBucket(resource);
if (bucket != null) { if (bucket != null) {
Metric metric = metricFinder.findByKey(measure.getMetricKey()); org.sonar.api.batch.measure.Metric metric = metricFinder.findByKey(measure.getMetricKey());
if (metric == null) { if (metric == null) {
throw new SonarException("Unknown metric: " + measure.getMetricKey()); throw new SonarException("Unknown metric: " + measure.getMetricKey());
} }
if (!isTechnicalProjectCopy(resource) && !measure.isFromCore() && DefaultSensorContext.INTERNAL_METRICS.contains(metric)) { if (!isTechnicalProjectCopy(resource) && !measure.isFromCore() && DefaultSensorContext.INTERNAL_METRICS.contains(metric)) {
LOG.debug("Metric " + metric.key() + " is an internal metric computed by SonarQube. Please update your plugin."); LOG.debug("Metric " + metric.key() + " is an internal metric computed by SonarQube. Please update your plugin.");
return measure; return measure;
} }
measure.setMetric(metric);
if (measureCache.contains(resource, measure)) { if (measureCache.contains(resource, measure)) {
throw new SonarException("Can not add the same measure twice on " + resource + ": " + measure); throw new SonarException("Can not add the same measure twice on " + resource + ": " + measure);
} }
Expand Down
Expand Up @@ -24,6 +24,8 @@
import org.sonar.api.database.model.MeasureModel; import org.sonar.api.database.model.MeasureModel;
import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure; import org.sonar.api.measures.Measure;
import org.sonar.api.measures.Metric;
import org.sonar.api.measures.MetricFinder;
import org.sonar.api.measures.PersistenceMode; import org.sonar.api.measures.PersistenceMode;
import org.sonar.api.rules.RuleFinder; import org.sonar.api.rules.RuleFinder;
import org.sonar.batch.duplication.DuplicationCache; import org.sonar.batch.duplication.DuplicationCache;
Expand All @@ -39,10 +41,10 @@ public final class DuplicationPersister implements ScanPersister {
private final RuleFinder ruleFinder; private final RuleFinder ruleFinder;
private final ResourceCache resourceCache; private final ResourceCache resourceCache;
private final DuplicationCache duplicationCache; private final DuplicationCache duplicationCache;
private final org.sonar.api.measures.MetricFinder metricFinder; private final MetricFinder metricFinder;


public DuplicationPersister(MyBatis mybatis, RuleFinder ruleFinder, ResourceCache resourceCache, public DuplicationPersister(MyBatis mybatis, RuleFinder ruleFinder, ResourceCache resourceCache,
DuplicationCache duplicationCache, org.sonar.api.measures.MetricFinder metricFinder) { DuplicationCache duplicationCache, MetricFinder metricFinder) {
this.mybatis = mybatis; this.mybatis = mybatis;
this.ruleFinder = ruleFinder; this.ruleFinder = ruleFinder;
this.resourceCache = resourceCache; this.resourceCache = resourceCache;
Expand All @@ -55,14 +57,14 @@ public void persist() {
// Don't use batch insert for duplications since keeping all data in memory can produce OOM // Don't use batch insert for duplications since keeping all data in memory can produce OOM
try (DbSession session = mybatis.openSession(false)) { try (DbSession session = mybatis.openSession(false)) {
MeasureMapper mapper = session.getMapper(MeasureMapper.class); MeasureMapper mapper = session.getMapper(MeasureMapper.class);
org.sonar.api.measures.Metric duplicationMetricWithId = metricFinder.findByKey(CoreMetrics.DUPLICATIONS_DATA_KEY); Metric duplicationMetricWithId = metricFinder.findByKey(CoreMetrics.DUPLICATIONS_DATA_KEY);
for (Entry<List<DuplicationGroup>> entry : duplicationCache.entries()) { for (Entry<List<DuplicationGroup>> entry : duplicationCache.entries()) {
String effectiveKey = entry.key()[0].toString(); String effectiveKey = entry.key()[0].toString();
Measure measure = new Measure(duplicationMetricWithId, DuplicationUtils.toXml(entry.value())).setPersistenceMode(PersistenceMode.DATABASE); Measure measure = new Measure(duplicationMetricWithId, DuplicationUtils.toXml(entry.value())).setPersistenceMode(PersistenceMode.DATABASE);
BatchResource batchResource = resourceCache.get(effectiveKey); BatchResource batchResource = resourceCache.get(effectiveKey);


if (MeasurePersister.shouldPersistMeasure(batchResource.resource(), measure)) { if (MeasurePersister.shouldPersistMeasure(batchResource.resource(), measure)) {
MeasureModel measureModel = MeasurePersister.model(measure, ruleFinder).setSnapshotId(batchResource.snapshotId()); MeasureModel measureModel = MeasurePersister.model(measure, ruleFinder, metricFinder).setSnapshotId(batchResource.snapshotId());
mapper.insert(measureModel); mapper.insert(measureModel);
session.commit(); session.commit();
} }
Expand Down
Expand Up @@ -23,6 +23,7 @@
import org.sonar.api.database.model.MeasureMapper; import org.sonar.api.database.model.MeasureMapper;
import org.sonar.api.database.model.MeasureModel; import org.sonar.api.database.model.MeasureModel;
import org.sonar.api.measures.Measure; import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MetricFinder;
import org.sonar.api.measures.RuleMeasure; import org.sonar.api.measures.RuleMeasure;
import org.sonar.api.resources.Resource; import org.sonar.api.resources.Resource;
import org.sonar.api.resources.ResourceUtils; import org.sonar.api.resources.ResourceUtils;
Expand All @@ -42,11 +43,13 @@ public final class MeasurePersister implements ScanPersister {
private final RuleFinder ruleFinder; private final RuleFinder ruleFinder;
private final MeasureCache measureCache; private final MeasureCache measureCache;
private final ResourceCache resourceCache; private final ResourceCache resourceCache;
private final MetricFinder metricFinder;


public MeasurePersister(MyBatis mybatis, RuleFinder ruleFinder, public MeasurePersister(MyBatis mybatis, RuleFinder ruleFinder, MetricFinder metricFinder,
MeasureCache measureCache, ResourceCache resourceCache) { MeasureCache measureCache, ResourceCache resourceCache) {
this.mybatis = mybatis; this.mybatis = mybatis;
this.ruleFinder = ruleFinder; this.ruleFinder = ruleFinder;
this.metricFinder = metricFinder;
this.measureCache = measureCache; this.measureCache = measureCache;
this.resourceCache = resourceCache; this.resourceCache = resourceCache;
} }
Expand All @@ -62,7 +65,7 @@ public void persist() {
BatchResource batchResource = resourceCache.get(effectiveKey); BatchResource batchResource = resourceCache.get(effectiveKey);


if (shouldPersistMeasure(batchResource.resource(), measure)) { if (shouldPersistMeasure(batchResource.resource(), measure)) {
MeasureModel measureModel = model(measure, ruleFinder).setSnapshotId(batchResource.snapshotId()); MeasureModel measureModel = model(measure, ruleFinder, metricFinder).setSnapshotId(batchResource.snapshotId());
mapper.insert(measureModel); mapper.insert(measureModel);
} }
} }
Expand Down Expand Up @@ -91,10 +94,9 @@ private static boolean isMeasureNotEmpty(Measure measure) {
|| isNotEmpty; || isNotEmpty;
} }


static MeasureModel model(Measure measure, RuleFinder ruleFinder) { static MeasureModel model(Measure measure, RuleFinder ruleFinder, MetricFinder metricFinder) {
MeasureModel model = new MeasureModel(); MeasureModel model = new MeasureModel();
// we assume that the index has updated the metric model.setMetricId(metricFinder.findByKey(measure.getMetricKey()).getId());
model.setMetricId(measure.getMetric().getId());
model.setDescription(measure.getDescription()); model.setDescription(measure.getDescription());
model.setData(measure.getData()); model.setData(measure.getData());
model.setAlertStatus(measure.getAlertStatus()); model.setAlertStatus(measure.getAlertStatus());
Expand Down
Expand Up @@ -46,11 +46,15 @@ public class ProjectReactorValidator {
private final Settings settings; private final Settings settings;
private final ResourceDao resourceDao; private final ResourceDao resourceDao;


public ProjectReactorValidator(Settings settings, ResourceDao resourceDao) { public ProjectReactorValidator(Settings settings, @Nullable ResourceDao resourceDao) {
this.settings = settings; this.settings = settings;
this.resourceDao = resourceDao; this.resourceDao = resourceDao;
} }


public ProjectReactorValidator(Settings settings) {
this(settings, null);
}

public void validate(ProjectReactor reactor) { public void validate(ProjectReactor reactor) {
preventAutomaticProjectCreationIfNeeded(reactor); preventAutomaticProjectCreationIfNeeded(reactor);


Expand All @@ -72,10 +76,12 @@ public void validate(ProjectReactor reactor) {
} }


private void preventAutomaticProjectCreationIfNeeded(ProjectReactor reactor) { private void preventAutomaticProjectCreationIfNeeded(ProjectReactor reactor) {
if (settings.getBoolean(CoreProperties.CORE_PREVENT_AUTOMATIC_PROJECT_CREATION)) { if (resourceDao != null) {
String projectKey = reactor.getRoot().getKeyWithBranch(); if (settings.getBoolean(CoreProperties.CORE_PREVENT_AUTOMATIC_PROJECT_CREATION)) {
if (resourceDao.findByKey(projectKey) == null) { String projectKey = reactor.getRoot().getKeyWithBranch();
throw new SonarException(String.format("Unable to scan non-existing project \"%s\"", projectKey)); if (resourceDao.findByKey(projectKey) == null) {
throw new SonarException(String.format("Unable to scan non-existing project \"%s\"", projectKey));
}
} }
} }
} }
Expand All @@ -84,7 +90,7 @@ private void validateModule(ProjectDefinition moduleDef, List<String> validation
if (!ComponentKeys.isValidModuleKey(moduleDef.getKey())) { if (!ComponentKeys.isValidModuleKey(moduleDef.getKey())) {
validationMessages.add(String.format("\"%s\" is not a valid project or module key. " validationMessages.add(String.format("\"%s\" is not a valid project or module key. "
+ "Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.", moduleDef.getKey())); + "Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.", moduleDef.getKey()));
} else if (isSubProject(moduleDef)) { } else if (resourceDao != null && isSubProject(moduleDef)) {
// SONAR-4692 Validate root project is the same than previous analysis to avoid module with same key in different projects // SONAR-4692 Validate root project is the same than previous analysis to avoid module with same key in different projects
String moduleKey = ComponentKeys.createKey(moduleDef.getKey(), branch); String moduleKey = ComponentKeys.createKey(moduleDef.getKey(), branch);
ResourceDto rootInDB = resourceDao.getRootProjectByComponentKey(moduleKey); ResourceDto rootInDB = resourceDao.getRootProjectByComponentKey(moduleKey);
Expand Down
3 changes: 1 addition & 2 deletions sonar-batch/src/main/java/org/sonar/batch/scan/ScanTask.java
Expand Up @@ -19,8 +19,6 @@
*/ */
package org.sonar.batch.scan; package org.sonar.batch.scan;


import org.sonar.batch.scan2.ProjectScanContainer;

import org.sonar.api.CoreProperties; import org.sonar.api.CoreProperties;
import org.sonar.api.platform.ComponentContainer; import org.sonar.api.platform.ComponentContainer;
import org.sonar.api.task.Task; import org.sonar.api.task.Task;
Expand All @@ -29,6 +27,7 @@
import org.sonar.batch.bootstrap.BootstrapProperties; import org.sonar.batch.bootstrap.BootstrapProperties;
import org.sonar.batch.bootstrap.TaskContainer; import org.sonar.batch.bootstrap.TaskContainer;
import org.sonar.batch.phases.Phases; import org.sonar.batch.phases.Phases;
import org.sonar.batch.scan2.ProjectScanContainer;


public class ScanTask implements Task { public class ScanTask implements Task {
public static final TaskDefinition DEFINITION = TaskDefinition.builder() public static final TaskDefinition DEFINITION = TaskDefinition.builder()
Expand Down
Expand Up @@ -24,11 +24,11 @@
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.database.model.Snapshot; import org.sonar.api.database.model.Snapshot;
import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure; import org.sonar.api.measures.Measure;
import org.sonar.api.measures.MeasuresFilters; import org.sonar.api.measures.MeasuresFilters;
import org.sonar.api.measures.MetricFinder;
import org.sonar.api.profiles.RulesProfile; import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Directory; import org.sonar.api.resources.Directory;
import org.sonar.api.resources.File; import org.sonar.api.resources.File;
Expand Down
Expand Up @@ -27,9 +27,9 @@
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import org.sonar.api.CoreProperties; import org.sonar.api.CoreProperties;
import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.config.Settings; import org.sonar.api.config.Settings;
import org.sonar.api.database.model.Snapshot; import org.sonar.api.database.model.Snapshot;
import org.sonar.api.measures.MetricFinder;
import org.sonar.api.resources.Directory; import org.sonar.api.resources.Directory;
import org.sonar.api.resources.File; import org.sonar.api.resources.File;
import org.sonar.api.resources.Library; import org.sonar.api.resources.Library;
Expand Down Expand Up @@ -218,7 +218,8 @@ public void shouldSaveNewMultiModulesProjectUsingIndex() throws IOException {
when(projectTree.getProjectDefinition(moduleB)).thenReturn(ProjectDefinition.create().setBaseDir(new java.io.File(baseDir, "moduleB"))); when(projectTree.getProjectDefinition(moduleB)).thenReturn(ProjectDefinition.create().setBaseDir(new java.io.File(baseDir, "moduleB")));
when(projectTree.getProjectDefinition(moduleB1)).thenReturn(ProjectDefinition.create().setBaseDir(new java.io.File(baseDir, "moduleB/moduleB1"))); when(projectTree.getProjectDefinition(moduleB1)).thenReturn(ProjectDefinition.create().setBaseDir(new java.io.File(baseDir, "moduleB/moduleB1")));


DefaultIndex index = new DefaultIndex(persister, null, null, null, projectTree, mock(MetricFinder.class), mock(ScanGraph.class), mock(DeprecatedViolations.class), DefaultIndex index = new DefaultIndex(persister, null, null, null, projectTree, mock(MetricFinder.class), mock(ScanGraph.class),
mock(DeprecatedViolations.class),
mock(ResourceKeyMigration.class), mock(ResourceKeyMigration.class),
mock(MeasureCache.class)); mock(MeasureCache.class));


Expand Down
Expand Up @@ -27,6 +27,7 @@
import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure; import org.sonar.api.measures.Measure;
import org.sonar.api.measures.Metric; import org.sonar.api.measures.Metric;
import org.sonar.api.measures.MetricFinder;
import org.sonar.api.measures.PersistenceMode; import org.sonar.api.measures.PersistenceMode;
import org.sonar.api.measures.RuleMeasure; import org.sonar.api.measures.RuleMeasure;
import org.sonar.api.resources.Directory; import org.sonar.api.resources.Directory;
Expand Down Expand Up @@ -75,7 +76,13 @@ public void mockResourcePersister() {
when(resourceCache.get("foo:org/foo/Bar.java")).thenReturn(fileResource); when(resourceCache.get("foo:org/foo/Bar.java")).thenReturn(fileResource);
when(resourceCache.get("foo:org/foo")).thenReturn(dirResource); when(resourceCache.get("foo:org/foo")).thenReturn(dirResource);


measurePersister = new MeasurePersister(getMyBatis(), ruleFinder, measureCache, resourceCache); MetricFinder metricFinder = mock(MetricFinder.class);
Metric ncloc = ncloc();
Metric coverage = coverage();
when(metricFinder.findByKey(ncloc.getKey())).thenReturn(ncloc);
when(metricFinder.findByKey(coverage.getKey())).thenReturn(coverage);

measurePersister = new MeasurePersister(getMyBatis(), ruleFinder, metricFinder, measureCache, resourceCache);
} }


@Test @Test
Expand Down
Expand Up @@ -19,15 +19,11 @@
*/ */
package org.sonar.api.batch.measure; package org.sonar.api.batch.measure;


import com.google.common.annotations.Beta;

import java.io.Serializable; import java.io.Serializable;


/** /**
* Experimental - do not use
* @since 4.4 * @since 4.4
*/ */
@Beta
public interface Metric<G extends Serializable> { public interface Metric<G extends Serializable> {


String key(); String key();
Expand Down
Expand Up @@ -19,7 +19,6 @@
*/ */
package org.sonar.api.batch.measure; package org.sonar.api.batch.measure;


import com.google.common.annotations.Beta;
import org.sonar.api.BatchComponent; import org.sonar.api.BatchComponent;


import javax.annotation.CheckForNull; import javax.annotation.CheckForNull;
Expand All @@ -28,10 +27,8 @@
import java.util.List; import java.util.List;


/** /**
* Experimental - do not use
* @since 4.5 * @since 4.5
*/ */
@Beta
public interface MetricFinder extends BatchComponent { public interface MetricFinder extends BatchComponent {


@CheckForNull @CheckForNull
Expand Down

0 comments on commit 2432235

Please sign in to comment.