From: Julien HENRY Date: Tue, 27 Jan 2015 09:50:00 +0000 (+0100) Subject: SONAR-6088 Remove old preview/h2 mode X-Git-Tag: latest-silver-master-#65~55 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=edb5e139309f4ce46a9dcd30813ae7a56b9761a1;p=sonarqube.git SONAR-6088 Remove old preview/h2 mode --- diff --git a/plugins/sonar-core-plugin/pom.xml b/plugins/sonar-core-plugin/pom.xml index 52f91a93700..090c34c4901 100644 --- a/plugins/sonar-core-plugin/pom.xml +++ b/plugins/sonar-core-plugin/pom.xml @@ -78,6 +78,13 @@ dbunit test + + + com.h2database + h2 + test + + org.codehaus.sonar sonar-testing-harness diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java index a2a86e37fd5..7aae1ad7932 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java @@ -51,9 +51,7 @@ import org.sonar.plugins.core.sensors.ManualMeasureDecorator; import org.sonar.plugins.core.sensors.OverallBranchCoverageDecorator; import org.sonar.plugins.core.sensors.OverallCoverageDecorator; import org.sonar.plugins.core.sensors.OverallLineCoverageDecorator; -import org.sonar.plugins.core.sensors.ProjectLinksSensor; import org.sonar.plugins.core.sensors.UnitTestDecorator; -import org.sonar.plugins.core.sensors.VersionEventsSensor; import org.sonar.plugins.core.timemachine.NewCoverageAggregator; import org.sonar.plugins.core.timemachine.NewCoverageFileAnalyzer; import org.sonar.plugins.core.timemachine.NewItCoverageFileAnalyzer; @@ -322,9 +320,7 @@ public final class CorePlugin extends SonarPlugin { IssueTagCloudWidget.class, // batch - ProjectLinksSensor.class, UnitTestDecorator.class, - VersionEventsSensor.class, LineCoverageDecorator.class, CoverageDecorator.class, BranchCoverageDecorator.class, diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/ApplyProjectRolesDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/ApplyProjectRolesDecorator.java index 7e997924fda..c93eb0e1228 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/ApplyProjectRolesDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/security/ApplyProjectRolesDecorator.java @@ -19,11 +19,12 @@ */ package org.sonar.plugins.core.security; +import org.sonar.api.batch.RequiresDB; + import com.google.common.collect.ImmutableSet; import org.slf4j.LoggerFactory; import org.sonar.api.batch.Decorator; import org.sonar.api.batch.DecoratorContext; -import org.sonar.core.DryRunIncompatible; import org.sonar.api.resources.Project; import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.Resource; @@ -31,7 +32,7 @@ import org.sonar.api.security.ResourcePermissions; import java.util.Set; -@DryRunIncompatible +@RequiresDB public class ApplyProjectRolesDecorator implements Decorator { private static final Set QUALIFIERS = ImmutableSet.of(Qualifiers.PROJECT, Qualifiers.VIEW, Qualifiers.SUBVIEW); diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProjectLinksSensor.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProjectLinksSensor.java deleted file mode 100644 index aef7a2153ad..00000000000 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/ProjectLinksSensor.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.plugins.core.sensors; - -import org.apache.commons.lang.StringUtils; -import org.sonar.api.CoreProperties; -import org.sonar.api.batch.Sensor; -import org.sonar.api.batch.SensorContext; -import org.sonar.api.config.Settings; -import org.sonar.api.resources.Project; -import org.sonar.api.resources.ProjectLink; -import org.sonar.core.i18n.DefaultI18n; - -import java.util.Locale; - -public class ProjectLinksSensor implements Sensor { - - private Settings settings; - private DefaultI18n defaultI18n; - - public ProjectLinksSensor(Settings settings, DefaultI18n defaultI18n) { - this.settings = settings; - this.defaultI18n = defaultI18n; - } - - @Override - public boolean shouldExecuteOnProject(Project project) { - return true; - } - - @Override - public void analyse(Project project, SensorContext context) { - handleLink(context, CoreProperties.LINKS_HOME_PAGE); - handleLink(context, CoreProperties.LINKS_CI); - handleLink(context, CoreProperties.LINKS_ISSUE_TRACKER); - handleLink(context, CoreProperties.LINKS_SOURCES); - handleLink(context, CoreProperties.LINKS_SOURCES_DEV); - } - - private void handleLink(SensorContext context, String linkProperty) { - String home = settings.getString(linkProperty); - String linkType = StringUtils.substringAfterLast(linkProperty, "."); - String name = defaultI18n.message(Locale.getDefault(), "project_links." + linkType, linkProperty); - updateLink(context, linkType, name, home); - } - - private void updateLink(SensorContext context, String key, String name, String url) { - if (StringUtils.isBlank(url)) { - context.deleteLink(key); - } else { - context.saveLink(new ProjectLink(key, name, url)); - } - } - - @Override - public String toString() { - return getClass().getSimpleName(); - } -} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/VersionEventsSensor.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/VersionEventsSensor.java deleted file mode 100644 index 6a02a2065cc..00000000000 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/sensors/VersionEventsSensor.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.plugins.core.sensors; - -import org.apache.commons.lang.StringUtils; -import org.sonar.core.DryRunIncompatible; -import org.sonar.api.batch.Event; -import org.sonar.api.batch.Sensor; -import org.sonar.api.batch.SensorContext; -import org.sonar.api.resources.Project; - -import java.util.Iterator; - -@DryRunIncompatible -public class VersionEventsSensor implements Sensor { - - @Override - public boolean shouldExecuteOnProject(Project project) { - return true; - } - - @Override - public void analyse(Project project, SensorContext context) { - if (StringUtils.isBlank(project.getAnalysisVersion())) { - return; - } - deleteDeprecatedEvents(project, context); - context.createEvent(project, project.getAnalysisVersion(), null, Event.CATEGORY_VERSION, null); - } - - private void deleteDeprecatedEvents(Project project, SensorContext context) { - String version = project.getAnalysisVersion(); - for (Iterator it = context.getEvents(project).iterator(); it.hasNext();) { - Event event = it.next(); - if (event.isVersionCategory() && version.equals(event.getName())) { - it.remove(); - context.deleteEvent(event); - } - } - } - - @Override - public String toString() { - return getClass().getSimpleName(); - } -} diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/AbstractNewCoverageFileAnalyzer.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/AbstractNewCoverageFileAnalyzer.java index d7eec1da075..90435de8f3b 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/AbstractNewCoverageFileAnalyzer.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/AbstractNewCoverageFileAnalyzer.java @@ -19,6 +19,8 @@ */ package org.sonar.plugins.core.timemachine; +import org.sonar.api.batch.RequiresDB; + import com.google.common.collect.Lists; import com.google.common.collect.Maps; import org.apache.commons.lang.ObjectUtils; @@ -33,7 +35,6 @@ import org.sonar.api.resources.Scopes; import org.sonar.api.utils.KeyValueFormat; import org.sonar.batch.components.Period; import org.sonar.batch.components.TimeMachineConfiguration; -import org.sonar.core.DryRunIncompatible; import javax.annotation.Nullable; @@ -45,7 +46,7 @@ import java.util.Map; /** * @since 2.7 */ -@DryRunIncompatible +@RequiresDB @DependedUpon(DecoratorBarriers.END_OF_TIME_MACHINE) public abstract class AbstractNewCoverageFileAnalyzer implements Decorator { diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TendencyDecorator.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TendencyDecorator.java index 0bbe4badd2f..44684523efd 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TendencyDecorator.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/timemachine/TendencyDecorator.java @@ -19,6 +19,8 @@ */ package org.sonar.plugins.core.timemachine; +import org.sonar.api.batch.RequiresDB; + import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ListMultimap; import com.google.common.collect.Lists; @@ -38,11 +40,10 @@ import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; import org.sonar.api.resources.Scopes; import org.sonar.batch.components.PeriodsDefinition; -import org.sonar.core.DryRunIncompatible; import java.util.List; -@DryRunIncompatible +@RequiresDB @DependedUpon(DecoratorBarriers.END_OF_TIME_MACHINE) public class TendencyDecorator implements Decorator { diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ProjectLinksSensorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ProjectLinksSensorTest.java deleted file mode 100644 index 0d51d4a55ac..00000000000 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/ProjectLinksSensorTest.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.plugins.core.sensors; - -import org.apache.commons.lang.StringUtils; -import org.junit.Test; -import org.mockito.ArgumentMatcher; -import org.sonar.api.CoreProperties; -import org.sonar.api.batch.SensorContext; -import org.sonar.api.config.Settings; -import org.sonar.api.resources.Project; -import org.sonar.api.resources.ProjectLink; -import org.sonar.core.i18n.DefaultI18n; - -import java.util.Locale; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.argThat; -import static org.mockito.Mockito.*; - -public class ProjectLinksSensorTest { - - @Test - public void testToString() { - assertThat(new ProjectLinksSensor(null, null).toString()).isEqualTo("ProjectLinksSensor"); - } - - @Test - public void shouldExecuteOnlyForLatestAnalysis() { - Project project = mock(Project.class); - assertThat(new ProjectLinksSensor(null, null).shouldExecuteOnProject(project)).isTrue(); - } - - @Test - public void shouldSaveLinks() { - Settings settings = new Settings(); - settings.setProperty(CoreProperties.LINKS_HOME_PAGE, "http://home"); - DefaultI18n defaultI18n = mock(DefaultI18n.class); - when(defaultI18n.message(Locale.getDefault(), "project_links.homepage", CoreProperties.LINKS_HOME_PAGE)).thenReturn("HOME"); - Project project = mock(Project.class); - SensorContext context = mock(SensorContext.class); - - new ProjectLinksSensor(settings, defaultI18n).analyse(project, context); - - verify(context).saveLink(argThat(new MatchLink("homepage", "HOME", "http://home"))); - } - - @Test - public void shouldDeleteLink() { - Settings settings = new Settings(); - settings.setProperty(CoreProperties.LINKS_HOME_PAGE, ""); - DefaultI18n defaultI18n = mock(DefaultI18n.class); - when(defaultI18n.message(Locale.getDefault(), "project_links.homepage", CoreProperties.LINKS_HOME_PAGE)).thenReturn("HOME"); - Project project = mock(Project.class); - SensorContext context = mock(SensorContext.class); - - new ProjectLinksSensor(settings, defaultI18n).analyse(project, context); - - verify(context).deleteLink("homepage"); - } - - private class MatchLink extends ArgumentMatcher { - private String key; - private String name; - private String url; - - private MatchLink(String key, String name, String url) { - this.key = key; - this.name = name; - this.url = url; - } - - @Override - public boolean matches(Object o) { - ProjectLink link = (ProjectLink) o; - return StringUtils.equals(link.getHref(), url) && StringUtils.equals(link.getKey(), key) && StringUtils.equals(link.getName(), name); - } - } - -} diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/VersionEventsSensorTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/VersionEventsSensorTest.java deleted file mode 100644 index 84a4103599c..00000000000 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/sensors/VersionEventsSensorTest.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.plugins.core.sensors; - -import com.google.common.collect.Lists; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.batch.Event; -import org.sonar.api.batch.SensorContext; -import org.sonar.api.resources.Project; -import org.sonar.api.resources.Resource; - -import java.util.Date; - -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; -import static org.mockito.Matchers.isNull; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -public class VersionEventsSensorTest { - - @Rule - public ExpectedException thrown = ExpectedException.none(); - - @Test - public void shouldExecuteOnProject() throws Exception { - assertThat(new VersionEventsSensor().shouldExecuteOnProject(null), is(true)); - } - - @Test - public void testToString() throws Exception { - assertThat(new VersionEventsSensor().toString(), is("VersionEventsSensor")); - } - - @Test - public void shouldDoNothingIfNoVersion() { - VersionEventsSensor sensor = new VersionEventsSensor(); - SensorContext context = mock(SensorContext.class); - Project project = mock(Project.class); - when(project.getAnalysisVersion()).thenReturn(null); - - sensor.analyse(project, context); - - verify(context, never()).createEvent(any(Resource.class), anyString(), anyString(), anyString(), any(Date.class)); - verify(context, never()).deleteEvent(any(Event.class)); - } - - @Test - public void shouldCreateVersionEvent() { - VersionEventsSensor sensor = new VersionEventsSensor(); - SensorContext context = mock(SensorContext.class); - - Project project = mock(Project.class); - when(project.getAnalysisVersion()).thenReturn("1.5-SNAPSHOT"); - - sensor.analyse(project, context); - - verify(context).createEvent(eq(project), eq("1.5-SNAPSHOT"), (String) isNull(), eq(Event.CATEGORY_VERSION), (Date) isNull()); - } - - @Test - public void shouldHaveOnlyOneEventByVersion() { - Event sameVersionEvent = mockVersionEvent("1.5-SNAPSHOT"); - Event otherEvent = mockVersionEvent("1.4"); - Event anotherEvent = mockVersionEvent("1.3-SNAPSHOT"); - - VersionEventsSensor sensor = new VersionEventsSensor(); - SensorContext context = mock(SensorContext.class); - - Project project = mock(Project.class); - when(project.getAnalysisVersion()).thenReturn("1.5-SNAPSHOT"); - - when(context.getEvents(project)).thenReturn(Lists.newArrayList(sameVersionEvent, otherEvent, anotherEvent)); - - sensor.analyse(project, context); - - verify(context).deleteEvent(sameVersionEvent); - verify(context).createEvent(eq(project), eq("1.5-SNAPSHOT"), (String) isNull(), eq(Event.CATEGORY_VERSION), (Date) isNull()); - } - - private Event mockVersionEvent(String version) { - Event event = mock(Event.class); - when(event.isVersionCategory()).thenReturn(true); - when(event.getName()).thenReturn(version); - return event; - } - -} diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdSensor.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdSensor.java index ab01bf6974b..611658c26c2 100644 --- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdSensor.java +++ b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/CpdSensor.java @@ -49,8 +49,8 @@ public class CpdSensor implements Sensor { @Override public void describe(SensorDescriptor descriptor) { - descriptor.name("CPD Sensor"); - + descriptor.name("CPD Sensor") + .disabledInPreview(); } @VisibleForTesting diff --git a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/IndexFactory.java b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/IndexFactory.java index 34a6110c32f..769e05bf2c3 100644 --- a/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/IndexFactory.java +++ b/plugins/sonar-cpd-plugin/src/main/java/org/sonar/plugins/cpd/index/IndexFactory.java @@ -28,7 +28,7 @@ import org.sonar.api.CoreProperties; import org.sonar.api.config.Settings; import org.sonar.api.database.DatabaseSession; import org.sonar.api.resources.Project; -import org.sonar.batch.bootstrap.AnalysisMode; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; import org.sonar.batch.index.ResourceCache; import org.sonar.core.duplication.DuplicationDao; @@ -40,11 +40,11 @@ public class IndexFactory implements BatchComponent { private final Settings settings; private final DuplicationDao dao; - private final AnalysisMode mode; + private final DefaultAnalysisMode mode; private final DatabaseSession session; private final ResourceCache resourceCache; - public IndexFactory(AnalysisMode mode, Settings settings, @Nullable DuplicationDao dao, @Nullable DatabaseSession session, ResourceCache resourceCache) { + public IndexFactory(DefaultAnalysisMode mode, Settings settings, @Nullable DuplicationDao dao, @Nullable DatabaseSession session, ResourceCache resourceCache) { this.mode = mode; this.settings = settings; this.dao = dao; @@ -55,7 +55,7 @@ public class IndexFactory implements BatchComponent { /** * Used by new sensor mode */ - public IndexFactory(AnalysisMode mode, Settings settings, ResourceCache resourceCache) { + public IndexFactory(DefaultAnalysisMode mode, Settings settings, ResourceCache resourceCache) { this(mode, settings, null, null, resourceCache); } diff --git a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/index/IndexFactoryTest.java b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/index/IndexFactoryTest.java index 2dc24d171d5..b515d48e2cf 100644 --- a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/index/IndexFactoryTest.java +++ b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/index/IndexFactoryTest.java @@ -26,7 +26,7 @@ import org.sonar.api.CoreProperties; import org.sonar.api.config.Settings; import org.sonar.api.database.DatabaseSession; import org.sonar.api.resources.Project; -import org.sonar.batch.bootstrap.AnalysisMode; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; import org.sonar.batch.index.ResourceCache; import org.sonar.core.duplication.DuplicationDao; @@ -41,13 +41,13 @@ public class IndexFactoryTest { Settings settings; IndexFactory factory; Logger logger; - private AnalysisMode analysisMode; + private DefaultAnalysisMode analysisMode; @Before public void setUp() { project = new Project("foo"); settings = new Settings(); - analysisMode = mock(AnalysisMode.class); + analysisMode = mock(DefaultAnalysisMode.class); factory = new IndexFactory(analysisMode, settings, mock(DuplicationDao.class), mock(DatabaseSession.class), new ResourceCache()); logger = mock(Logger.class); } diff --git a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/medium/CpdMediumTest.java b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/medium/CpdMediumTest.java index e7de8cb8625..43043e35eea 100644 --- a/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/medium/CpdMediumTest.java +++ b/plugins/sonar-cpd-plugin/src/test/java/org/sonar/plugins/cpd/medium/CpdMediumTest.java @@ -53,7 +53,6 @@ public class CpdMediumTest { .registerPlugin("xoo", new XooPlugin()) .registerPlugin("cpd", new CpdPlugin()) .addDefaultQProfile("xoo", "Sonar Way") - .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor")) .build(); private File baseDir; diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java index 1a16d8204a2..a5a36f8bab2 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java @@ -33,7 +33,6 @@ import org.sonar.core.component.ComponentDto; import org.sonar.core.component.ComponentKeys; import org.sonar.core.permission.GlobalPermissions; import org.sonar.core.persistence.DbSession; -import org.sonar.core.preview.PreviewCache; import org.sonar.core.resource.ResourceIndexerDao; import org.sonar.core.resource.ResourceKeyUpdaterDao; import org.sonar.server.db.DbClient; @@ -45,7 +44,11 @@ import org.sonar.server.user.UserSession; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import java.util.*; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.Map; import static com.google.common.collect.Lists.newArrayList; @@ -54,16 +57,14 @@ public class ComponentService implements ServerComponent { private final DbClient dbClient; private final ResourceKeyUpdaterDao resourceKeyUpdaterDao; - private final PreviewCache previewCache; private final I18n i18n; private final ResourceIndexerDao resourceIndexerDao; private final InternalPermissionService permissionService; - public ComponentService(DbClient dbClient, ResourceKeyUpdaterDao resourceKeyUpdaterDao, PreviewCache previewCache, I18n i18n, ResourceIndexerDao resourceIndexerDao, - InternalPermissionService permissionService) { + public ComponentService(DbClient dbClient, ResourceKeyUpdaterDao resourceKeyUpdaterDao, I18n i18n, ResourceIndexerDao resourceIndexerDao, + InternalPermissionService permissionService) { this.dbClient = dbClient; this.resourceKeyUpdaterDao = resourceKeyUpdaterDao; - this.previewCache = previewCache; this.i18n = i18n; this.resourceIndexerDao = resourceIndexerDao; this.permissionService = permissionService; @@ -116,8 +117,6 @@ public class ComponentService implements ServerComponent { resourceKeyUpdaterDao.updateKey(projectOrModule.getId(), newKey); session.commit(); - previewCache.reportResourceModification(newKey); - session.commit(); } finally { session.close(); @@ -145,7 +144,6 @@ public class ComponentService implements ServerComponent { resourceKeyUpdaterDao.bulkUpdateKey(session, project.getId(), stringToReplace, replacementString); ComponentDto newProject = dbClient.componentDao().getById(project.getId(), session); - previewCache.reportResourceModification(session, newProject.key()); session.commit(); } finally { @@ -237,7 +235,7 @@ public class ComponentService implements ServerComponent { private String formatMessage(String message, String qualifier, String key) { return String.format(message, i18n.message(Locale.getDefault(), "qualifier." + qualifier, "Project"), key); - } + } @CheckForNull private ComponentDto getNullableByKey(DbSession session, String key) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java index 7aa2dff8e7c..a2d1f605334 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/step/ComputationSteps.java @@ -39,7 +39,6 @@ public class ComputationSteps { SwitchSnapshotStep.class, IndexComponentsStep.class, PurgeDatastoresStep.class, - InvalidateBatchCacheStep.class, // ES indexing is done after all db changes ApplyPermissionsStep.class, diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/step/InvalidateBatchCacheStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/step/InvalidateBatchCacheStep.java deleted file mode 100644 index 89ac2fc5937..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/step/InvalidateBatchCacheStep.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package org.sonar.server.computation.step; - -import org.sonar.core.preview.PreviewCache; -import org.sonar.core.properties.PropertiesDao; -import org.sonar.core.properties.PropertyDto; -import org.sonar.server.computation.ComputationContext; - -public class InvalidateBatchCacheStep implements ComputationStep { - private final PropertiesDao propertiesDao; - - public InvalidateBatchCacheStep(PropertiesDao propertiesDao) { - this.propertiesDao = propertiesDao; - } - - @Override - public void execute(ComputationContext context) { - PropertyDto property = new PropertyDto() - .setKey(PreviewCache.SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY) - .setResourceId(context.getProject().getId()) - .setValue(String.valueOf(System.currentTimeMillis())); - propertiesDao.setProperty(property); - } - - @Override - public String getDescription() { - return "Invalidate batch cache"; - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueBulkChangeService.java b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueBulkChangeService.java index 28ec5704bb0..46cdbdd63a2 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueBulkChangeService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueBulkChangeService.java @@ -31,13 +31,12 @@ import org.sonar.api.issue.internal.IssueChangeContext; import org.sonar.api.rule.RuleKey; import org.sonar.api.rules.Rule; import org.sonar.core.component.ComponentDto; -import org.sonar.server.issue.notification.IssueNotifications; import org.sonar.core.issue.db.IssueDto; import org.sonar.core.issue.db.IssueStorage; import org.sonar.core.persistence.DbSession; -import org.sonar.core.preview.PreviewCache; import org.sonar.server.db.DbClient; import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.issue.notification.IssueNotifications; import org.sonar.server.rule.DefaultRuleFinder; import org.sonar.server.search.QueryContext; import org.sonar.server.user.UserSession; @@ -45,7 +44,11 @@ import org.sonar.server.user.UserSession; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import java.util.*; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Maps.newHashMap; @@ -60,18 +63,16 @@ public class IssueBulkChangeService { private final IssueStorage issueStorage; private final DefaultRuleFinder ruleFinder; private final IssueNotifications issueNotifications; - private final PreviewCache dryRunCache; private final List actions; public IssueBulkChangeService(DbClient dbClient, IssueService issueService, IssueStorage issueStorage, DefaultRuleFinder ruleFinder, - IssueNotifications issueNotifications, List actions, PreviewCache dryRunCache) { + IssueNotifications issueNotifications, List actions) { this.dbClient = dbClient; this.issueService = issueService; this.issueStorage = issueStorage; this.ruleFinder = ruleFinder; this.issueNotifications = issueNotifications; this.actions = actions; - this.dryRunCache = dryRunCache; } public IssueBulkChangeResult execute(IssueBulkChangeQuery issueBulkChangeQuery, UserSession userSession) { @@ -111,10 +112,6 @@ public class IssueBulkChangeService { concernedProjects.add(issue.projectKey()); } } - // Purge dryRun cache - for (String projectKey : concernedProjects) { - dryRunCache.reportResourceModification(projectKey); - } LOG.debug("BulkChange execution time : {} ms", System.currentTimeMillis() - start); return result; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java index 9790530b312..92012d6ad7b 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java +++ b/server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java @@ -45,7 +45,6 @@ import org.sonar.core.issue.db.IssueStorage; import org.sonar.core.issue.workflow.IssueWorkflow; import org.sonar.core.issue.workflow.Transition; import org.sonar.core.persistence.DbSession; -import org.sonar.core.preview.PreviewCache; import org.sonar.core.rule.RuleDto; import org.sonar.server.db.DbClient; import org.sonar.server.exceptions.NotFoundException; @@ -64,7 +63,12 @@ import org.sonar.server.user.index.UserIndex; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; import static com.google.common.collect.Maps.newLinkedHashMap; @@ -81,7 +85,6 @@ public class IssueService implements ServerComponent { private final RuleFinder ruleFinder; private final IssueDao deprecatedIssueDao; private final UserFinder userFinder; - private final PreviewCache dryRunCache; private final UserIndex userIndex; private final SourceLineIndex sourceLineIndex; @@ -94,7 +97,6 @@ public class IssueService implements ServerComponent { RuleFinder ruleFinder, IssueDao deprecatedIssueDao, UserFinder userFinder, - PreviewCache dryRunCache, UserIndex userIndex, SourceLineIndex sourceLineIndex) { this.dbClient = dbClient; this.indexClient = indexClient; @@ -106,7 +108,6 @@ public class IssueService implements ServerComponent { this.issueNotifications = issueNotifications; this.deprecatedIssueDao = deprecatedIssueDao; this.userFinder = userFinder; - this.dryRunCache = dryRunCache; this.userIndex = userIndex; this.sourceLineIndex = sourceLineIndex; } @@ -278,7 +279,6 @@ public class IssueService implements ServerComponent { issue.setCreationDate(now); issue.setUpdateDate(now); issueStorage.save(issue); - dryRunCache.reportResourceModification(component.getKey()); return issue; } finally { session.close(); @@ -338,7 +338,6 @@ public class IssueService implements ServerComponent { dbClient.componentDao().getByKey(session, projectKey), dbClient.componentDao().getNullableByKey(session, issue.componentKey()), comment, false); - dryRunCache.reportResourceModification(issue.componentKey()); } /** diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java index be14410d363..1a2169026e7 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java @@ -53,8 +53,12 @@ import org.sonar.core.measure.db.MeasureFilterDao; import org.sonar.core.metric.DefaultMetricFinder; import org.sonar.core.notification.DefaultNotificationManager; import org.sonar.core.permission.PermissionFacade; -import org.sonar.core.persistence.*; -import org.sonar.core.preview.PreviewCache; +import org.sonar.core.persistence.DaoUtils; +import org.sonar.core.persistence.DatabaseVersion; +import org.sonar.core.persistence.DefaultDatabase; +import org.sonar.core.persistence.MyBatis; +import org.sonar.core.persistence.SemaphoreUpdater; +import org.sonar.core.persistence.SemaphoresImpl; import org.sonar.core.profiling.Profiling; import org.sonar.core.purge.PurgeProfiler; import org.sonar.core.qualitygate.db.ProjectQgateAssociationDao; @@ -79,7 +83,12 @@ import org.sonar.server.activity.index.ActivityNormalizer; import org.sonar.server.activity.ws.ActivitiesWebService; import org.sonar.server.activity.ws.ActivityMapping; import org.sonar.server.authentication.ws.AuthenticationWs; -import org.sonar.server.batch.*; +import org.sonar.server.batch.BatchIndex; +import org.sonar.server.batch.BatchWs; +import org.sonar.server.batch.GlobalRepositoryAction; +import org.sonar.server.batch.IssuesAction; +import org.sonar.server.batch.ProjectRepositoryAction; +import org.sonar.server.batch.ProjectRepositoryLoader; import org.sonar.server.charts.ChartFactory; import org.sonar.server.component.ComponentCleanerService; import org.sonar.server.component.ComponentService; @@ -87,12 +96,20 @@ import org.sonar.server.component.DefaultComponentFinder; import org.sonar.server.component.DefaultRubyComponentService; import org.sonar.server.component.db.ComponentDao; import org.sonar.server.component.db.SnapshotDao; -import org.sonar.server.component.ws.*; +import org.sonar.server.component.ws.ComponentAppAction; +import org.sonar.server.component.ws.ComponentsWs; +import org.sonar.server.component.ws.EventsWs; +import org.sonar.server.component.ws.ProjectsWs; +import org.sonar.server.component.ws.ResourcesWs; import org.sonar.server.computation.AnalysisReportQueue; import org.sonar.server.computation.AnalysisReportQueueCleaner; import org.sonar.server.computation.ComputationThreadLauncher; import org.sonar.server.computation.db.AnalysisReportDao; -import org.sonar.server.computation.ws.*; +import org.sonar.server.computation.ws.ComputationWebService; +import org.sonar.server.computation.ws.HistoryWsAction; +import org.sonar.server.computation.ws.IsQueueEmptyWebService; +import org.sonar.server.computation.ws.QueueWsAction; +import org.sonar.server.computation.ws.SubmitReportWsAction; import org.sonar.server.config.ws.PropertiesWs; import org.sonar.server.dashboard.db.DashboardDao; import org.sonar.server.dashboard.db.WidgetDao; @@ -104,7 +121,14 @@ import org.sonar.server.db.DbClient; import org.sonar.server.db.EmbeddedDatabaseFactory; import org.sonar.server.db.migrations.DatabaseMigrations; import org.sonar.server.db.migrations.DatabaseMigrator; -import org.sonar.server.debt.*; +import org.sonar.server.debt.DebtCharacteristicsXMLImporter; +import org.sonar.server.debt.DebtModelBackup; +import org.sonar.server.debt.DebtModelLookup; +import org.sonar.server.debt.DebtModelOperations; +import org.sonar.server.debt.DebtModelPluginRepository; +import org.sonar.server.debt.DebtModelService; +import org.sonar.server.debt.DebtModelXMLExporter; +import org.sonar.server.debt.DebtRulesXMLImporter; import org.sonar.server.design.FileDesignWidget; import org.sonar.server.duplication.ws.DuplicationsJsonWriter; import org.sonar.server.duplication.ws.DuplicationsParser; @@ -112,7 +136,22 @@ import org.sonar.server.duplication.ws.DuplicationsWs; import org.sonar.server.es.EsClient; import org.sonar.server.es.IndexCreator; import org.sonar.server.es.IndexRegistry; -import org.sonar.server.issue.*; +import org.sonar.server.issue.ActionService; +import org.sonar.server.issue.AddTagsAction; +import org.sonar.server.issue.AssignAction; +import org.sonar.server.issue.CommentAction; +import org.sonar.server.issue.InternalRubyIssueService; +import org.sonar.server.issue.IssueBulkChangeService; +import org.sonar.server.issue.IssueChangelogFormatter; +import org.sonar.server.issue.IssueChangelogService; +import org.sonar.server.issue.IssueCommentService; +import org.sonar.server.issue.IssueQueryService; +import org.sonar.server.issue.IssueService; +import org.sonar.server.issue.PlanAction; +import org.sonar.server.issue.RemoveTagsAction; +import org.sonar.server.issue.ServerIssueStorage; +import org.sonar.server.issue.SetSeverityAction; +import org.sonar.server.issue.TransitionAction; import org.sonar.server.issue.actionplan.ActionPlanService; import org.sonar.server.issue.actionplan.ActionPlanWs; import org.sonar.server.issue.db.IssueDao; @@ -123,8 +162,17 @@ import org.sonar.server.issue.index.IssueAuthorizationIndexer; import org.sonar.server.issue.index.IssueIndex; import org.sonar.server.issue.index.IssueIndexDefinition; import org.sonar.server.issue.index.IssueIndexer; -import org.sonar.server.issue.notification.*; -import org.sonar.server.issue.ws.*; +import org.sonar.server.issue.notification.ChangesOnMyIssueNotificationDispatcher; +import org.sonar.server.issue.notification.IssueChangesEmailTemplate; +import org.sonar.server.issue.notification.IssueNotifications; +import org.sonar.server.issue.notification.NewFalsePositiveNotificationDispatcher; +import org.sonar.server.issue.notification.NewIssuesEmailTemplate; +import org.sonar.server.issue.notification.NewIssuesNotificationDispatcher; +import org.sonar.server.issue.ws.ComponentTagsAction; +import org.sonar.server.issue.ws.IssueActionsWriter; +import org.sonar.server.issue.ws.IssueShowAction; +import org.sonar.server.issue.ws.IssuesWs; +import org.sonar.server.issue.ws.SetTagsAction; import org.sonar.server.language.ws.LanguageWs; import org.sonar.server.language.ws.ListAction; import org.sonar.server.measure.MeasureFilterEngine; @@ -145,35 +193,117 @@ import org.sonar.server.platform.ws.L10nWs; import org.sonar.server.platform.ws.RestartHandler; import org.sonar.server.platform.ws.ServerWs; import org.sonar.server.platform.ws.SystemWs; -import org.sonar.server.plugins.*; +import org.sonar.server.plugins.InstalledPluginReferentialFactory; +import org.sonar.server.plugins.PluginDownloader; +import org.sonar.server.plugins.ServerExtensionInstaller; +import org.sonar.server.plugins.ServerPluginJarInstaller; +import org.sonar.server.plugins.ServerPluginJarsInstaller; +import org.sonar.server.plugins.ServerPluginRepository; +import org.sonar.server.plugins.UpdateCenterClient; +import org.sonar.server.plugins.UpdateCenterMatrixFactory; import org.sonar.server.properties.ProjectSettingsFactory; import org.sonar.server.qualitygate.QgateProjectFinder; import org.sonar.server.qualitygate.QualityGates; import org.sonar.server.qualitygate.RegisterQualityGates; -import org.sonar.server.qualitygate.ws.*; -import org.sonar.server.qualityprofile.*; +import org.sonar.server.qualitygate.ws.QGatesAppAction; +import org.sonar.server.qualitygate.ws.QGatesCopyAction; +import org.sonar.server.qualitygate.ws.QGatesCreateAction; +import org.sonar.server.qualitygate.ws.QGatesCreateConditionAction; +import org.sonar.server.qualitygate.ws.QGatesDeleteConditionAction; +import org.sonar.server.qualitygate.ws.QGatesDeselectAction; +import org.sonar.server.qualitygate.ws.QGatesDestroyAction; +import org.sonar.server.qualitygate.ws.QGatesListAction; +import org.sonar.server.qualitygate.ws.QGatesRenameAction; +import org.sonar.server.qualitygate.ws.QGatesSearchAction; +import org.sonar.server.qualitygate.ws.QGatesSelectAction; +import org.sonar.server.qualitygate.ws.QGatesSetAsDefaultAction; +import org.sonar.server.qualitygate.ws.QGatesShowAction; +import org.sonar.server.qualitygate.ws.QGatesUnsetDefaultAction; +import org.sonar.server.qualitygate.ws.QGatesUpdateConditionAction; +import org.sonar.server.qualitygate.ws.QGatesWs; +import org.sonar.server.qualityprofile.BuiltInProfiles; +import org.sonar.server.qualityprofile.QProfileBackuper; +import org.sonar.server.qualityprofile.QProfileCopier; +import org.sonar.server.qualityprofile.QProfileExporters; +import org.sonar.server.qualityprofile.QProfileFactory; +import org.sonar.server.qualityprofile.QProfileLoader; +import org.sonar.server.qualityprofile.QProfileLookup; +import org.sonar.server.qualityprofile.QProfileProjectLookup; +import org.sonar.server.qualityprofile.QProfileProjectOperations; +import org.sonar.server.qualityprofile.QProfileReset; +import org.sonar.server.qualityprofile.QProfileService; +import org.sonar.server.qualityprofile.QProfiles; +import org.sonar.server.qualityprofile.RegisterQualityProfiles; +import org.sonar.server.qualityprofile.RuleActivator; +import org.sonar.server.qualityprofile.RuleActivatorContextFactory; import org.sonar.server.qualityprofile.db.ActiveRuleDao; import org.sonar.server.qualityprofile.index.ActiveRuleIndex; import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer; -import org.sonar.server.qualityprofile.ws.*; -import org.sonar.server.rule.*; +import org.sonar.server.qualityprofile.ws.BulkRuleActivationActions; +import org.sonar.server.qualityprofile.ws.ProfilesWs; +import org.sonar.server.qualityprofile.ws.QProfileRestoreBuiltInAction; +import org.sonar.server.qualityprofile.ws.QProfilesWs; +import org.sonar.server.qualityprofile.ws.RuleActivationActions; +import org.sonar.server.rule.DefaultRuleFinder; +import org.sonar.server.rule.DeprecatedRulesDefinitionLoader; +import org.sonar.server.rule.RegisterRules; +import org.sonar.server.rule.RubyRuleService; +import org.sonar.server.rule.RuleCreator; +import org.sonar.server.rule.RuleDefinitionsLoader; +import org.sonar.server.rule.RuleDeleter; +import org.sonar.server.rule.RuleOperations; +import org.sonar.server.rule.RuleRepositories; +import org.sonar.server.rule.RuleService; +import org.sonar.server.rule.RuleUpdater; import org.sonar.server.rule.db.RuleDao; import org.sonar.server.rule.index.RuleIndex; import org.sonar.server.rule.index.RuleNormalizer; -import org.sonar.server.rule.ws.*; +import org.sonar.server.rule.ws.ActiveRuleCompleter; +import org.sonar.server.rule.ws.AppAction; +import org.sonar.server.rule.ws.DeleteAction; +import org.sonar.server.rule.ws.RepositoriesAction; +import org.sonar.server.rule.ws.RuleMapping; +import org.sonar.server.rule.ws.RulesWebService; import org.sonar.server.rule.ws.SearchAction; import org.sonar.server.rule.ws.TagsAction; -import org.sonar.server.search.*; +import org.sonar.server.rule.ws.UpdateAction; +import org.sonar.server.search.IndexClient; +import org.sonar.server.search.IndexQueue; +import org.sonar.server.search.IndexSynchronizer; +import org.sonar.server.search.SearchClient; +import org.sonar.server.search.SearchHealth; import org.sonar.server.source.HtmlSourceDecorator; import org.sonar.server.source.SourceService; import org.sonar.server.source.index.SourceLineIndex; import org.sonar.server.source.index.SourceLineIndexDefinition; import org.sonar.server.source.index.SourceLineIndexer; -import org.sonar.server.source.ws.*; +import org.sonar.server.source.ws.HashAction; +import org.sonar.server.source.ws.IndexAction; +import org.sonar.server.source.ws.LinesAction; +import org.sonar.server.source.ws.RawAction; +import org.sonar.server.source.ws.ScmAction; +import org.sonar.server.source.ws.ScmWriter; import org.sonar.server.source.ws.ShowAction; -import org.sonar.server.startup.*; +import org.sonar.server.source.ws.SourcesWs; +import org.sonar.server.startup.CopyRequirementsFromCharacteristicsToRules; +import org.sonar.server.startup.GeneratePluginIndex; +import org.sonar.server.startup.JdbcDriverDeployer; +import org.sonar.server.startup.LogServerId; +import org.sonar.server.startup.RegisterDashboards; +import org.sonar.server.startup.RegisterDebtModel; +import org.sonar.server.startup.RegisterMetrics; +import org.sonar.server.startup.RegisterNewMeasureFilters; +import org.sonar.server.startup.RegisterPermissionTemplates; +import org.sonar.server.startup.RegisterServletFilters; +import org.sonar.server.startup.RenameDeprecatedPropertyKeys; +import org.sonar.server.startup.ServerMetadataPersister; import org.sonar.server.test.CoverageService; -import org.sonar.server.test.ws.*; +import org.sonar.server.test.ws.CoverageShowAction; +import org.sonar.server.test.ws.CoverageWs; +import org.sonar.server.test.ws.TestsCoveredFilesAction; +import org.sonar.server.test.ws.TestsShowAction; +import org.sonar.server.test.ws.TestsTestCasesAction; +import org.sonar.server.test.ws.TestsWs; import org.sonar.server.text.MacroInterpreter; import org.sonar.server.text.RubyTextService; import org.sonar.server.ui.JRubyI18n; @@ -181,7 +311,14 @@ import org.sonar.server.ui.JRubyProfiling; import org.sonar.server.ui.PageDecorations; import org.sonar.server.ui.Views; import org.sonar.server.updatecenter.ws.UpdateCenterWs; -import org.sonar.server.user.*; +import org.sonar.server.user.DefaultUserService; +import org.sonar.server.user.DoPrivileged; +import org.sonar.server.user.GroupMembershipFinder; +import org.sonar.server.user.GroupMembershipService; +import org.sonar.server.user.NewUserNotifier; +import org.sonar.server.user.SecurityRealmFactory; +import org.sonar.server.user.UserService; +import org.sonar.server.user.UserUpdater; import org.sonar.server.user.db.GroupDao; import org.sonar.server.user.db.UserDao; import org.sonar.server.user.db.UserGroupDao; @@ -191,7 +328,13 @@ import org.sonar.server.user.index.UserIndexer; import org.sonar.server.user.ws.FavoritesWs; import org.sonar.server.user.ws.UserPropertiesWs; import org.sonar.server.user.ws.UsersWs; -import org.sonar.server.util.*; +import org.sonar.server.util.BooleanTypeValidation; +import org.sonar.server.util.FloatTypeValidation; +import org.sonar.server.util.IntegerTypeValidation; +import org.sonar.server.util.StringListTypeValidation; +import org.sonar.server.util.StringTypeValidation; +import org.sonar.server.util.TextTypeValidation; +import org.sonar.server.util.TypeValidations; import org.sonar.server.view.index.ViewIndexDefinition; import org.sonar.server.view.index.ViewIndexer; import org.sonar.server.ws.ListingWs; @@ -232,7 +375,6 @@ class ServerComponents { DatabaseVersion.class, PurgeProfiler.class, DefaultServerFileSystem.class, - PreviewDatabaseFactory.class, SemaphoreUpdater.class, SemaphoresImpl.class, TempFolderCleaner.class, @@ -343,7 +485,6 @@ class ServerComponents { pico.addSingleton(ResourceTypes.class); pico.addSingleton(SettingsChangeNotifier.class); pico.addSingleton(PageDecorations.class); - pico.addSingleton(PreviewCache.class); pico.addSingleton(DefaultResourcePermissions.class); pico.addSingleton(Periods.class); pico.addSingleton(ServerWs.class); @@ -684,7 +825,6 @@ class ServerComponents { startupContainer.addSingleton(RenameDeprecatedPropertyKeys.class); startupContainer.addSingleton(LogServerId.class); startupContainer.addSingleton(RegisterServletFilters.class); - startupContainer.addSingleton(CleanPreviewAnalysisCache.class); startupContainer.addSingleton(CopyRequirementsFromCharacteristicsToRules.class); startupContainer.addSingleton(AnalysisReportQueueCleaner.class); diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileFactory.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileFactory.java index f789f957028..47e23895ba4 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileFactory.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileFactory.java @@ -24,7 +24,6 @@ import org.apache.commons.lang.RandomStringUtils; import org.apache.commons.lang.StringUtils; import org.sonar.api.ServerComponent; import org.sonar.core.persistence.DbSession; -import org.sonar.core.preview.PreviewCache; import org.sonar.core.properties.PropertyDto; import org.sonar.core.qualityprofile.db.QualityProfileDto; import org.sonar.server.db.DbClient; @@ -46,11 +45,9 @@ public class QProfileFactory implements ServerComponent { private static final String PROFILE_PROPERTY_PREFIX = "sonar.profile."; private final DbClient db; - private final PreviewCache previewCache; - public QProfileFactory(DbClient db, PreviewCache previewCache) { + public QProfileFactory(DbClient db) { this.db = db; - this.previewCache = previewCache; } // ------------- CREATION @@ -122,7 +119,6 @@ public class QProfileFactory implements ServerComponent { doDelete(session, descendant); } doDelete(session, profile); - previewCache.reportGlobalModification(session); } private void doDelete(DbSession session, QualityProfileDto profile) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java index aa24975d6a9..96bc7511f2f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java @@ -25,7 +25,6 @@ import org.sonar.api.ServerComponent; import org.sonar.api.server.rule.RuleParamType; import org.sonar.core.activity.Activity; import org.sonar.core.persistence.DbSession; -import org.sonar.core.preview.PreviewCache; import org.sonar.core.qualityprofile.db.ActiveRuleDto; import org.sonar.core.qualityprofile.db.ActiveRuleKey; import org.sonar.core.qualityprofile.db.ActiveRuleParamDto; @@ -63,18 +62,16 @@ public class RuleActivator implements ServerComponent { private final DbClient db; private final TypeValidations typeValidations; private final RuleActivatorContextFactory contextFactory; - private final PreviewCache previewCache; private final IndexClient index; private final ActivityService log; public RuleActivator(DbClient db, IndexClient index, - RuleActivatorContextFactory contextFactory, TypeValidations typeValidations, - PreviewCache previewCache, ActivityService log) { + RuleActivatorContextFactory contextFactory, TypeValidations typeValidations, + ActivityService log) { this.db = db; this.index = index; this.contextFactory = contextFactory; this.typeValidations = typeValidations; - this.previewCache = previewCache; this.log = log; } @@ -147,7 +144,6 @@ public class RuleActivator implements ServerComponent { if (!changes.isEmpty()) { updateProfileDate(dbSession, context); - previewCache.reportGlobalModification(dbSession); } return changes; } @@ -370,7 +366,6 @@ public class RuleActivator implements ServerComponent { if (!changes.isEmpty()) { updateProfileDate(dbSession, context); - previewCache.reportGlobalModification(dbSession); } return changes; diff --git a/server/sonar-server/src/main/java/org/sonar/server/startup/CleanPreviewAnalysisCache.java b/server/sonar-server/src/main/java/org/sonar/server/startup/CleanPreviewAnalysisCache.java deleted file mode 100644 index 7168d93c271..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/startup/CleanPreviewAnalysisCache.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.startup; - -import org.picocontainer.Startable; -import org.sonar.core.preview.PreviewCache; - -/** - * @since 4.0 - */ -public class CleanPreviewAnalysisCache implements Startable { - - private final PreviewCache cache; - - public CleanPreviewAnalysisCache(PreviewCache cache) { - this.cache = cache; - } - - @Override - public void start() { - cache.cleanAll(); - } - - @Override - public void stop() { - // nothing - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/startup/JdbcDriverDeployer.java b/server/sonar-server/src/main/java/org/sonar/server/startup/JdbcDriverDeployer.java index 44ca9a8f3e4..289d94cab7e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/startup/JdbcDriverDeployer.java +++ b/server/sonar-server/src/main/java/org/sonar/server/startup/JdbcDriverDeployer.java @@ -22,6 +22,7 @@ package org.sonar.server.startup; import org.apache.commons.io.FileUtils; import org.sonar.api.config.Settings; import org.sonar.home.cache.FileHashes; +import org.sonar.process.ProcessConstants; import org.sonar.server.platform.DefaultServerFileSystem; import javax.annotation.Nullable; @@ -40,20 +41,20 @@ public class JdbcDriverDeployer { } public void start() { - File deployedDriver = null; // see initialization of this property in sonar-application - String driverPath = settings.getString("sonar.jdbc.driverPath"); - // Driver can be null for H2, in that case we write an empty jdbc-driver.txt file - if (driverPath != null) { - File driver = new File(driverPath); - deployedDriver = new File(fileSystem.getDeployDir(), driver.getName()); - if (!deployedDriver.exists() || FileUtils.sizeOf(deployedDriver) != FileUtils.sizeOf(driver)) { - try { - FileUtils.copyFile(driver, deployedDriver); - } catch (IOException e) { - throw new IllegalStateException( - String.format("Can not copy the JDBC driver from %s to %s", driver, deployedDriver), e); - } + String driverPath = settings.getString(ProcessConstants.JDBC_DRIVER_PATH); + if (driverPath == null) { + // Medium tests + return; + } + File driver = new File(driverPath); + File deployedDriver = new File(fileSystem.getDeployDir(), driver.getName()); + if (!deployedDriver.exists() || FileUtils.sizeOf(deployedDriver) != FileUtils.sizeOf(driver)) { + try { + FileUtils.copyFile(driver, deployedDriver); + } catch (IOException e) { + throw new IllegalStateException( + String.format("Can not copy the JDBC driver from %s to %s", driver, deployedDriver), e); } } @@ -65,7 +66,7 @@ public class JdbcDriverDeployer { } } - private String driverIndexContent(@Nullable File deployedDriver){ + private String driverIndexContent(@Nullable File deployedDriver) { if (deployedDriver != null) { String hash = new FileHashes().of(deployedDriver); return deployedDriver.getName() + "|" + hash; diff --git a/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java b/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java index 89ad70b2c9c..9318df53313 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java +++ b/server/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java @@ -35,7 +35,6 @@ import org.sonar.api.web.Page; import org.sonar.api.web.RubyRailsWebservice; import org.sonar.api.web.Widget; import org.sonar.core.persistence.Database; -import org.sonar.core.preview.PreviewCache; import org.sonar.core.resource.ResourceIndexerDao; import org.sonar.core.timemachine.Periods; import org.sonar.process.ProcessConstants; @@ -360,10 +359,6 @@ public final class JRubyFacade { } } - public String pathToPreviewDbFile(@Nullable Long projectId) { - return get(PreviewCache.class).getPathToDatabaseFile(projectId); - } - public String getPeriodLabel(int periodIndex) { return get(Periods.class).label(periodIndex); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ComputationStepsTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ComputationStepsTest.java index bb8e2787582..7d911c7dde1 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/ComputationStepsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/step/ComputationStepsTest.java @@ -36,7 +36,6 @@ public class ComputationStepsTest { mock(DigestReportStep.class), mock(IndexSourceLinesStep.class), mock(IndexViewsStep.class), - mock(InvalidateBatchCacheStep.class), mock(PersistIssuesStep.class), mock(IndexIssuesStep.class), mock(SwitchSnapshotStep.class), @@ -44,9 +43,9 @@ public class ComputationStepsTest { mock(SendIssueNotificationsStep.class), mock(IndexComponentsStep.class)); - assertThat(registry.orderedSteps()).hasSize(11); + assertThat(registry.orderedSteps()).hasSize(10); assertThat(registry.orderedSteps().get(0)).isInstanceOf(DigestReportStep.class); - assertThat(registry.orderedSteps().get(10)).isInstanceOf(SendIssueNotificationsStep.class); + assertThat(registry.orderedSteps().get(9)).isInstanceOf(SendIssueNotificationsStep.class); } @Test diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/step/InvalidateBatchCacheStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/step/InvalidateBatchCacheStepTest.java deleted file mode 100644 index ef07bd445d3..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/step/InvalidateBatchCacheStepTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -package org.sonar.server.computation.step; - -import org.junit.Before; -import org.junit.Test; -import org.sonar.core.component.ComponentDto; -import org.sonar.core.computation.db.AnalysisReportDto; -import org.sonar.core.properties.PropertiesDao; -import org.sonar.core.properties.PropertyDto; -import org.sonar.server.computation.ComputationContext; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -public class InvalidateBatchCacheStepTest { - private InvalidateBatchCacheStep sut; - private PropertiesDao propertiesDao; - - @Before - public void before() { - this.propertiesDao = mock(PropertiesDao.class); - this.sut = new InvalidateBatchCacheStep(propertiesDao); - } - - @Test - public void update_property_to_invalidate_cache() { - ComputationContext context = new ComputationContext(mock(AnalysisReportDto.class), mock(ComponentDto.class), null); - - sut.execute(context); - - verify(propertiesDao).setProperty(any(PropertyDto.class)); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceTest.java index 7236b66ec86..40df25eea5c 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceTest.java @@ -33,7 +33,6 @@ import org.sonar.core.component.ComponentDto; import org.sonar.core.issue.db.IssueDto; import org.sonar.core.issue.db.IssueStorage; import org.sonar.core.persistence.DbSession; -import org.sonar.core.preview.PreviewCache; import org.sonar.server.component.db.ComponentDao; import org.sonar.server.db.DbClient; import org.sonar.server.exceptions.BadRequestException; @@ -57,9 +56,15 @@ import static org.junit.Assert.fail; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyListOf; import static org.mockito.Matchers.anyMap; +import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.anyString; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; public class IssueBulkChangeServiceTest { @@ -117,7 +122,7 @@ public class IssueBulkChangeServiceTest { when(issueDao.selectByKeys(dbSession, newArrayList(issue.key()))).thenReturn(newArrayList(issueDto)); actions = newArrayList(); - service = new IssueBulkChangeService(dbClient, issueService, issueStorage, ruleFinder, issueNotifications, actions, mock(PreviewCache.class)); + service = new IssueBulkChangeService(dbClient, issueService, issueStorage, ruleFinder, issueNotifications, actions); } @Test @@ -135,7 +140,7 @@ public class IssueBulkChangeServiceTest { verify(issueStorage).save(eq(issue)); verifyNoMoreInteractions(issueStorage); - verify(issueNotifications).sendChanges(eq(issue), anyString(), eq("the rule name"), eq(project), eq(file), eq((String)null), eq(false)); + verify(issueNotifications).sendChanges(eq(issue), anyString(), eq("the rule name"), eq(project), eq(file), eq((String) null), eq(false)); verifyNoMoreInteractions(issueNotifications); } @@ -239,7 +244,7 @@ public class IssueBulkChangeServiceTest { verify(issueStorage, times(1)).save(eq(issue)); verifyNoMoreInteractions(issueStorage); - verify(issueNotifications).sendChanges(eq(issue), anyString(), eq("the rule name"), eq(project), eq(file), eq((String)null), eq(false)); + verify(issueNotifications).sendChanges(eq(issue), anyString(), eq("the rule name"), eq(project), eq(file), eq((String) null), eq(false)); verifyNoMoreInteractions(issueNotifications); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/startup/CleanPreviewAnalysisCacheTest.java b/server/sonar-server/src/test/java/org/sonar/server/startup/CleanPreviewAnalysisCacheTest.java deleted file mode 100644 index fbc58236987..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/startup/CleanPreviewAnalysisCacheTest.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.server.startup; - -import org.junit.Test; -import org.sonar.core.preview.PreviewCache; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -public class CleanPreviewAnalysisCacheTest { - @Test - public void clean_cache_on_startup() throws Exception { - PreviewCache cache = mock(PreviewCache.class); - CleanPreviewAnalysisCache cleaner = new CleanPreviewAnalysisCache(cache); - - cleaner.start(); - verify(cache).cleanAll(); - cleaner.stop(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/startup/JdbcDriverDeployerTest.java b/server/sonar-server/src/test/java/org/sonar/server/startup/JdbcDriverDeployerTest.java index d95498ecb60..642b55c7147 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/startup/JdbcDriverDeployerTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/startup/JdbcDriverDeployerTest.java @@ -64,19 +64,12 @@ public class JdbcDriverDeployerTest { } @Test - public void create_empty_file_when_no_jdbc_driver() throws Exception { + public void dont_fail_when_medium_test() throws Exception { Settings settings = new Settings(); DefaultServerFileSystem fs = mock(DefaultServerFileSystem.class); - File deployDir = temp.newFolder("deploy"); - when(fs.getDeployDir()).thenReturn(deployDir); - File deployedIndex = new File(deployDir, "jdbc-driver.txt"); - assertThat(deployedIndex).doesNotExist(); - when(fs.getDeployedJdbcDriverIndex()).thenReturn(deployedIndex); + // No sonar.jdbc.driverPath property new JdbcDriverDeployer(fs, settings).start(); - - assertThat(deployedIndex).exists(); - assertThat(Files.toString(deployedIndex, Charsets.UTF_8)).isEqualTo(""); } } diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/batch_bootstrap_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/batch_bootstrap_controller.rb deleted file mode 100644 index 3b96ee03de6..00000000000 --- a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/batch_bootstrap_controller.rb +++ /dev/null @@ -1,70 +0,0 @@ -# -# SonarQube, open source software quality management tool. -# Copyright (C) 2008-2014 SonarSource -# mailto:contact AT sonarsource DOT com -# -# SonarQube is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 3 of the License, or (at your option) any later version. -# -# SonarQube is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# - -# Since 3.4 -class BatchBootstrapController < Api::ApiController - - # SONAR-4211 Access to index should not require authentication - skip_before_filter :check_authentication, :only => 'index' - - # GET /batch_bootstrap/db?project= - def db - has_dryrun_role = has_role?('dryRunScan') - return render_unauthorized("You're not authorized to execute a dry run analysis. Please contact your SonarQube administrator.") if !has_dryrun_role - project = load_project() - return render_unauthorized("You're not authorized to access to project '" + project.name + "', please contact your SonarQube administrator") if project && !has_role?(:user, project) - db_file = java_facade.pathToPreviewDbFile(project && project.id) - - send_file db_file - end - - - private - - def render_unauthorized(message, status=403) - respond_to do |format| - format.json { render :text => message, :status => status } - format.xml { render :text => message, :status => status } - format.text { render :text => message, :status => status } - end - end - - def load_project - if params[:project].present? - Project.by_key(params[:project]) - else - nil - end - end - - def to_json_property(property, project_key=nil) - hash={:k => property.key, :v => property.text_value.to_s} - hash[:p]=project_key if project_key - hash - end - - def allowed?(property_key, dryRun, has_scan_role) - if property_key.end_with?('.secured') - property_key.include?('.license') ? true : (!dryRun && has_scan_role) - else - true - end - end -end diff --git a/sonar-application/assembly.xml b/sonar-application/assembly.xml index 17ff70213c6..3773b757155 100644 --- a/sonar-application/assembly.xml +++ b/sonar-application/assembly.xml @@ -143,6 +143,14 @@ false provided + + lib/jdbc/h2/ + + com.h2database:h2 + + false + provided + bin diff --git a/sonar-application/pom.xml b/sonar-application/pom.xml index 4a21e030492..98dec35edfe 100644 --- a/sonar-application/pom.xml +++ b/sonar-application/pom.xml @@ -82,6 +82,11 @@ jtds provided + + com.h2database + h2 + provided + diff --git a/sonar-application/src/main/java/org/sonar/application/JdbcSettings.java b/sonar-application/src/main/java/org/sonar/application/JdbcSettings.java index 4a34e55a642..c949b1fae45 100644 --- a/sonar-application/src/main/java/org/sonar/application/JdbcSettings.java +++ b/sonar-application/src/main/java/org/sonar/application/JdbcSettings.java @@ -26,8 +26,6 @@ import org.sonar.process.MessageException; import org.sonar.process.ProcessConstants; import org.sonar.process.Props; -import javax.annotation.CheckForNull; -import javax.annotation.Nullable; import java.io.File; import java.util.ArrayList; import java.util.List; @@ -37,12 +35,12 @@ import java.util.regex.Pattern; public class JdbcSettings { static enum Provider { - H2(null), JTDS("lib/jdbc/jtds"), MYSQL("lib/jdbc/mysql"), ORACLE("extensions/jdbc-driver/oracle"), + H2("lib/jdbc/h2"), JTDS("lib/jdbc/jtds"), MYSQL("lib/jdbc/mysql"), ORACLE("extensions/jdbc-driver/oracle"), POSTGRESQL("lib/jdbc/postgresql"); final String path; - Provider(@Nullable String path) { + Provider(String path) { this.path = path; } } @@ -52,17 +50,11 @@ public class JdbcSettings { Provider provider = driverProvider(url); checkUrlParameters(provider, url); String driverPath = driverPath(homeDir, provider); - if (driverPath != null) { - props.set(ProcessConstants.JDBC_DRIVER_PATH, driverPath); - } + props.set(ProcessConstants.JDBC_DRIVER_PATH, driverPath); } - @CheckForNull String driverPath(File homeDir, Provider provider) { String dirPath = provider.path; - if (dirPath == null) { - return null; - } File dir = new File(homeDir, dirPath); if (!dir.exists()) { throw new MessageException("Directory does not exist: " + dirPath); diff --git a/sonar-batch/pom.xml b/sonar-batch/pom.xml index c7f63892495..6a1cae560b1 100644 --- a/sonar-batch/pom.xml +++ b/sonar-batch/pom.xml @@ -118,11 +118,6 @@ com.google.code.gson gson - - - com.h2database - h2 - com.github.kevinsawicki http-request @@ -153,6 +148,12 @@ dbunit test + + + com.h2database + h2 + test + com.google.code.bean-matchers bean-matchers diff --git a/sonar-batch/src/main/java/org/sonar/batch/DeprecatedSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/DeprecatedSensorContext.java index 35d329627f3..49998b1d2f7 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/DeprecatedSensorContext.java +++ b/sonar-batch/src/main/java/org/sonar/batch/DeprecatedSensorContext.java @@ -22,6 +22,7 @@ package org.sonar.batch; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.Event; import org.sonar.api.batch.SensorContext; import org.sonar.api.batch.SonarIndex; @@ -65,9 +66,9 @@ public class DeprecatedSensorContext extends DefaultSensorContext implements Sen private final CoverageExclusions coverageFilter; public DeprecatedSensorContext(SonarIndex index, Project project, Settings settings, FileSystem fs, ActiveRules activeRules, - ComponentDataCache componentDataCache, CoverageExclusions coverageFilter, + AnalysisMode analysisMode, ComponentDataCache componentDataCache, CoverageExclusions coverageFilter, BlockCache blockCache, DuplicationCache duplicationCache, SensorStorage sensorStorage) { - super(settings, fs, activeRules, componentDataCache, blockCache, duplicationCache, sensorStorage); + super(settings, fs, activeRules, analysisMode, componentDataCache, blockCache, duplicationCache, sensorStorage); this.index = index; this.project = project; this.coverageFilter = coverageFilter; diff --git a/sonar-batch/src/main/java/org/sonar/batch/ServerMetadata.java b/sonar-batch/src/main/java/org/sonar/batch/ServerMetadata.java deleted file mode 100644 index 9ec3fcf2be7..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/ServerMetadata.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch; - -import org.sonar.api.BatchComponent; - -import java.util.Date; - -/** - * @deprecated in 3.4. Replaced by {@link org.sonar.batch.bootstrap.ServerMetadata}. Plugins should use {@link org.sonar.api.platform.Server}. - */ -@Deprecated -public class ServerMetadata implements BatchComponent { - private org.sonar.batch.bootstrap.ServerMetadata metadata; - - public ServerMetadata(org.sonar.batch.bootstrap.ServerMetadata metadata) { - this.metadata = metadata; - } - - public String getId() { - return metadata.getId(); - } - - public String getVersion() { - return metadata.getVersion(); - } - - public Date getStartedAt() { - return metadata.getStartedAt(); - } - - public String getURL() { - return metadata.getURL(); - } - - public String getPermanentServerId() { - return metadata.getPermanentServerId(); - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/AnalysisMode.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/AnalysisMode.java deleted file mode 100644 index 89640219562..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/AnalysisMode.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch.bootstrap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.BatchComponent; -import org.sonar.api.CoreProperties; - -import java.text.MessageFormat; - -/** - * @since 4.0 - */ -public class AnalysisMode implements BatchComponent { - - private static final Logger LOG = LoggerFactory.getLogger(AnalysisMode.class); - - private static final int DEFAULT_PREVIEW_READ_TIMEOUT_SEC = 60; - - private boolean preview; - private boolean incremental; - private int previewReadTimeoutSec; - private boolean sensorMode; - - public AnalysisMode(BootstrapProperties bootstrapProps) { - init(bootstrapProps); - } - - public boolean isPreview() { - return preview || incremental; - } - - public boolean isIncremental() { - return incremental; - } - - public boolean isSensorMode() { - return sensorMode; - } - - private void init(BootstrapProperties bootstrapProps) { - if (bootstrapProps.properties().containsKey(CoreProperties.DRY_RUN)) { - LOG.warn(MessageFormat.format("Property {0} is deprecated. Please use {1} instead.", CoreProperties.DRY_RUN, CoreProperties.ANALYSIS_MODE)); - preview = "true".equals(bootstrapProps.property(CoreProperties.DRY_RUN)); - incremental = false; - sensorMode = false; - } else { - String mode = bootstrapProps.property(CoreProperties.ANALYSIS_MODE); - preview = CoreProperties.ANALYSIS_MODE_PREVIEW.equals(mode); - incremental = CoreProperties.ANALYSIS_MODE_INCREMENTAL.equals(mode); - sensorMode = CoreProperties.ANALYSIS_MODE_SENSOR.equals(mode); - } - if (incremental) { - LOG.info("Incremental mode"); - } else if (preview) { - LOG.info("Preview mode"); - } else if (sensorMode) { - LOG.info("Sensor mode"); - } - // To stay compatible with plugins that use the old property to check mode - if (incremental || preview) { - bootstrapProps.properties().put(CoreProperties.DRY_RUN, "true"); - previewReadTimeoutSec = loadPreviewReadTimeout(bootstrapProps); - } - } - - // SONAR-4488 Allow to increase preview read timeout - private int loadPreviewReadTimeout(BootstrapProperties bootstrapProps) { - int readTimeoutSec; - if (bootstrapProps.property(CoreProperties.DRY_RUN_READ_TIMEOUT_SEC) != null) { - LOG.warn("Property {} is deprecated. Please use {} instead.", CoreProperties.DRY_RUN_READ_TIMEOUT_SEC, CoreProperties.PREVIEW_READ_TIMEOUT_SEC); - readTimeoutSec = Integer.parseInt(bootstrapProps.property(CoreProperties.DRY_RUN_READ_TIMEOUT_SEC)); - } else if (bootstrapProps.property(CoreProperties.PREVIEW_READ_TIMEOUT_SEC) != null) { - readTimeoutSec = Integer.parseInt(bootstrapProps.property(CoreProperties.PREVIEW_READ_TIMEOUT_SEC)); - } else { - readTimeoutSec = DEFAULT_PREVIEW_READ_TIMEOUT_SEC; - } - return readTimeoutSec; - } - - /** - * Read timeout used by HTTP request done in preview mode (SONAR-4488, SONAR-5028) - */ - public int getPreviewReadTimeoutSec() { - return previewReadTimeoutSec; - } - -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java index 34df9a2e678..c1801298afc 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchComponents.java @@ -37,6 +37,8 @@ import org.sonar.batch.scan.report.IssuesReportBuilder; import org.sonar.batch.scan.report.JSONReport; import org.sonar.batch.scan.report.RuleNameProvider; import org.sonar.batch.scan.report.SourceProvider; +import org.sonar.batch.scan.sensor.ProjectLinksSensor; +import org.sonar.batch.scan.sensor.VersionEventsSensor; import org.sonar.batch.scm.ScmConfiguration; import org.sonar.batch.scm.ScmSensor; import org.sonar.batch.source.LinesSensor; @@ -52,7 +54,7 @@ public class BatchComponents { // only static stuff } - public static Collection all(AnalysisMode analysisMode) { + public static Collection all(DefaultAnalysisMode analysisMode) { List components = Lists.newArrayList( // Maven MavenProjectBootstrapper.class, DefaultMavenPluginExecutor.class, MavenProjectConverter.class, MavenProjectBuilder.class, @@ -69,6 +71,8 @@ public class BatchComponents { ScmSensor.class, LinesSensor.class, + ProjectLinksSensor.class, + VersionEventsSensor.class, // Issues tracking IssueTracking.class, @@ -86,7 +90,7 @@ public class BatchComponents { DefaultPurgeTask.class ); components.addAll(CorePropertyDefinitions.all()); - if (!analysisMode.isSensorMode()) { + if (!analysisMode.isMediumTest()) { components.add(MavenDependenciesSensor.class); } return components; diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchDatabase.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchDatabase.java index e4944f5bd5d..a2ed089ee18 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchDatabase.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchDatabase.java @@ -29,17 +29,6 @@ import java.util.Properties; */ public class BatchDatabase extends DefaultDatabase { - public BatchDatabase(Settings settings, - // The dependency on JdbcDriverHolder is required to be sure that the JDBC driver - // has been downloaded and injected into classloader - JdbcDriverHolder jdbcDriverHolder, - - // The dependency on DryRunDatabase is required to be sure that the dryRun mode - // changed settings - PreviewDatabase dryRun) { - super(settings); - } - public BatchDatabase(Settings settings, // The dependency on JdbcDriverHolder is required to be sure that the JDBC driver // has been downloaded and injected into classloader diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java index 909c3a057ca..c62ec99bd1c 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java @@ -56,10 +56,10 @@ public class BatchPluginRepository implements PluginRepository { private Map metadataByKey; private Settings settings; private PluginClassloaders classLoaders; - private final AnalysisMode analysisMode; + private final DefaultAnalysisMode analysisMode; private final BatchPluginJarInstaller pluginInstaller; - public BatchPluginRepository(PluginsReferential pluginsReferential, Settings settings, AnalysisMode analysisMode, + public BatchPluginRepository(PluginsReferential pluginsReferential, Settings settings, DefaultAnalysisMode analysisMode, BatchPluginJarInstaller pluginInstaller) { this.pluginsReferential = pluginsReferential; this.settings = settings; @@ -134,9 +134,9 @@ public class BatchPluginRepository implements PluginRepository { static class PluginFilter { private static final String PROPERTY_IS_DEPRECATED_MSG = "Property {0} is deprecated. Please use {1} instead."; Set whites = newHashSet(), blacks = newHashSet(); - private AnalysisMode mode; + private DefaultAnalysisMode mode; - PluginFilter(Settings settings, AnalysisMode mode) { + PluginFilter(Settings settings, DefaultAnalysisMode mode) { this.mode = mode; if (settings.hasKey(CoreProperties.BATCH_INCLUDE_PLUGINS)) { whites.addAll(Arrays.asList(settings.getStringArray(CoreProperties.BATCH_INCLUDE_PLUGINS))); @@ -179,7 +179,7 @@ public class BatchPluginRepository implements PluginRepository { boolean accepts(String pluginKey) { if (CORE_PLUGIN.equals(pluginKey)) { - return !mode.isSensorMode(); + return !mode.isMediumTest(); } List mergeList = newArrayList(blacks); diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java deleted file mode 100644 index c49e4c1fef1..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch.bootstrap; - -import org.sonar.api.CoreProperties; -import org.sonar.api.Plugin; -import org.sonar.api.config.EmailSettings; -import org.sonar.api.platform.ComponentContainer; -import org.sonar.api.platform.PluginMetadata; -import org.sonar.api.utils.Durations; -import org.sonar.api.utils.HttpDownloader; -import org.sonar.api.utils.System2; -import org.sonar.api.utils.UriReader; -import org.sonar.api.utils.internal.TempFolderCleaner; -import org.sonar.batch.components.PastSnapshotFinder; -import org.sonar.batch.components.PastSnapshotFinderByDate; -import org.sonar.batch.components.PastSnapshotFinderByDays; -import org.sonar.batch.components.PastSnapshotFinderByPreviousAnalysis; -import org.sonar.batch.components.PastSnapshotFinderByPreviousVersion; -import org.sonar.batch.components.PastSnapshotFinderByVersion; -import org.sonar.batch.repository.DefaultGlobalRepositoriesLoader; -import org.sonar.batch.repository.DefaultPreviousIssuesLoader; -import org.sonar.batch.repository.DefaultProjectRepositoriesLoader; -import org.sonar.batch.repository.GlobalRepositoriesLoader; -import org.sonar.batch.repository.GlobalRepositoriesProvider; -import org.sonar.batch.repository.PreviousIssuesLoader; -import org.sonar.batch.repository.ProjectRepositoriesLoader; -import org.sonar.batch.user.UserRepository; -import org.sonar.core.cluster.NullQueue; -import org.sonar.core.config.Logback; -import org.sonar.core.i18n.DefaultI18n; -import org.sonar.core.i18n.RuleI18nManager; -import org.sonar.core.persistence.DaoUtils; -import org.sonar.core.persistence.DatabaseVersion; -import org.sonar.core.persistence.MyBatis; -import org.sonar.core.persistence.SemaphoreUpdater; -import org.sonar.core.persistence.SemaphoresImpl; -import org.sonar.core.purge.PurgeProfiler; -import org.sonar.core.rule.CacheRuleFinder; -import org.sonar.core.user.HibernateUserFinder; -import org.sonar.jpa.dao.MeasuresDao; -import org.sonar.jpa.session.DefaultDatabaseConnector; -import org.sonar.jpa.session.JpaDatabaseSession; - -import java.util.List; -import java.util.Map; - -public class BootstrapContainer extends ComponentContainer { - - private final Map bootstrapProperties; - private final boolean sensorMode; - - private BootstrapContainer(Map bootstrapProperties) { - super(); - this.sensorMode = CoreProperties.ANALYSIS_MODE_SENSOR.equals(bootstrapProperties.get(CoreProperties.ANALYSIS_MODE)); - this.bootstrapProperties = bootstrapProperties; - } - - public static BootstrapContainer create(Map bootstrapProperties, List extensions) { - BootstrapContainer container = new BootstrapContainer(bootstrapProperties); - container.add(extensions); - return container; - } - - @Override - protected void doBeforeStart() { - addBootstrapComponents(); - if (!sensorMode) { - addDatabaseComponents(); - addCoreComponents(); - } - - } - - private void addBootstrapComponents() { - add( - new BootstrapProperties(bootstrapProperties), - AnalysisMode.class, - BatchPluginRepository.class, - BatchPluginJarInstaller.class, - GlobalSettings.class, - ServerClient.class, - ExtensionInstaller.class, - Logback.class, - ServerMetadata.class, - org.sonar.batch.ServerMetadata.class, - new TempFolderProvider(), - TempFolderCleaner.class, - HttpDownloader.class, - UriReader.class, - new FileCacheProvider(), - System2.INSTANCE, - new GlobalRepositoriesProvider(), - UserRepository.class); - if (getComponentByType(PluginsReferential.class) == null) { - add(DefaultPluginsReferential.class); - } - if (getComponentByType(GlobalRepositoriesLoader.class) == null) { - add(DefaultGlobalRepositoriesLoader.class); - } - if (getComponentByType(ProjectRepositoriesLoader.class) == null) { - add(DefaultProjectRepositoriesLoader.class); - } - if (getComponentByType(PreviousIssuesLoader.class) == null) { - add(DefaultPreviousIssuesLoader.class); - } - } - - private void addDatabaseComponents() { - add( - PreviewDatabase.class, - JdbcDriverHolder.class, - BatchDatabase.class, - MyBatis.class, - NullQueue.class, - DatabaseVersion.class, - // TODO check that it still works (see @Freddy) - DatabaseCompatibility.class, - DefaultDatabaseConnector.class, - JpaDatabaseSession.class, - BatchDatabaseSessionFactory.class, - DaoUtils.getDaoClasses(), - PurgeProfiler.class, - CacheRuleFinder.class); - } - - /** - * These components MUST not depend on extensions provided by plugins - */ - private void addCoreComponents() { - add( - EmailSettings.class, - DefaultI18n.class, - RuleI18nManager.class, - MeasuresDao.class, - HibernateUserFinder.class, - SemaphoreUpdater.class, - SemaphoresImpl.class, - PastSnapshotFinderByDate.class, - PastSnapshotFinderByDays.class, - PastSnapshotFinderByPreviousAnalysis.class, - PastSnapshotFinderByVersion.class, - PastSnapshotFinderByPreviousVersion.class, - PastSnapshotFinder.class, - Durations.class); - } - - @Override - protected void doAfterStart() { - installPlugins(); - } - - private void installPlugins() { - for (Map.Entry entry : getComponentByType(BatchPluginRepository.class).getPluginsByMetadata().entrySet()) { - PluginMetadata metadata = entry.getKey(); - Plugin plugin = entry.getValue(); - addExtension(metadata, plugin); - } - } - - public void executeTask(Map taskProperties, Object... components) { - new TaskContainer(this, taskProperties, components).execute(); - } - -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DatabaseCompatibility.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DatabaseCompatibility.java index e2e9ccc1ada..856cf505642 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DatabaseCompatibility.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DatabaseCompatibility.java @@ -19,6 +19,8 @@ */ package org.sonar.batch.bootstrap; +import com.google.common.annotations.VisibleForTesting; +import org.apache.commons.lang.StringUtils; import org.sonar.api.BatchComponent; import org.sonar.api.CoreProperties; import org.sonar.api.config.Settings; @@ -35,10 +37,10 @@ public class DatabaseCompatibility implements BatchComponent { private DatabaseVersion version; private Settings settings; private PropertiesDao propertiesDao; - private ServerMetadata server; - private AnalysisMode analysisMode; + private ServerClient server; + private DefaultAnalysisMode analysisMode; - public DatabaseCompatibility(DatabaseVersion version, ServerMetadata server, Settings settings, PropertiesDao propertiesDao, AnalysisMode mode) { + public DatabaseCompatibility(DatabaseVersion version, ServerClient server, Settings settings, PropertiesDao propertiesDao, DefaultAnalysisMode mode) { this.version = version; this.server = server; this.settings = settings; @@ -54,7 +56,7 @@ public class DatabaseCompatibility implements BatchComponent { } private void checkCorrectServerId() { - if (!propertiesDao.selectGlobalProperty(CoreProperties.SERVER_ID).getValue().equals(server.getServerId())) { + if (!propertiesDao.selectGlobalProperty(CoreProperties.SERVER_ID).getValue().equals(getServerId())) { StringBuilder message = new StringBuilder("The current batch process and the configured remote server do not share the same DB configuration.\n"); message.append("\t- Batch side: "); message.append(settings.getString(DatabaseProperties.PROP_URL)); @@ -68,6 +70,18 @@ public class DatabaseCompatibility implements BatchComponent { } } + private String getServerId() { + String remoteServerInfo = server.request("/api/server"); + // don't use JSON utilities to extract ID from such a small string + return extractServerId(remoteServerInfo); + } + + @VisibleForTesting + String extractServerId(String remoteServerInfo) { + String partialId = StringUtils.substringAfter(remoteServerInfo, "\"id\":\""); + return StringUtils.substringBefore(partialId, "\""); + } + private void checkDatabaseStatus() { DatabaseVersion.Status status = version.getStatus(); if (status == DatabaseVersion.Status.REQUIRES_DOWNGRADE) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DefaultAnalysisMode.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DefaultAnalysisMode.java new file mode 100644 index 00000000000..e97dce7da40 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DefaultAnalysisMode.java @@ -0,0 +1,87 @@ +/* + * 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.batch.bootstrap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.CoreProperties; +import org.sonar.api.batch.AnalysisMode; + +import java.text.MessageFormat; + +/** + * @since 4.0 + */ +public class DefaultAnalysisMode implements AnalysisMode { + + private static final Logger LOG = LoggerFactory.getLogger(DefaultAnalysisMode.class); + + private boolean preview; + private boolean incremental; + private boolean mediumTestMode; + + public DefaultAnalysisMode(BootstrapProperties bootstrapProps) { + init(bootstrapProps); + } + + public boolean isDb() { + return !preview && !incremental && !mediumTestMode; + } + + @Override + public boolean isPreview() { + return preview || incremental; + } + + @Override + public boolean isIncremental() { + return incremental; + } + + public boolean isMediumTest() { + return mediumTestMode; + } + + private void init(BootstrapProperties bootstrapProps) { + if (bootstrapProps.properties().containsKey(CoreProperties.DRY_RUN)) { + LOG.warn(MessageFormat.format("Property {0} is deprecated. Please use {1} instead.", CoreProperties.DRY_RUN, CoreProperties.ANALYSIS_MODE)); + preview = "true".equals(bootstrapProps.property(CoreProperties.DRY_RUN)); + incremental = false; + mediumTestMode = false; + } else { + String mode = bootstrapProps.property(CoreProperties.ANALYSIS_MODE); + preview = CoreProperties.ANALYSIS_MODE_PREVIEW.equals(mode); + incremental = CoreProperties.ANALYSIS_MODE_INCREMENTAL.equals(mode); + mediumTestMode = CoreProperties.ANALYSIS_MODE_MEDIUM_TEST.equals(mode); + } + if (incremental) { + LOG.info("Incremental mode"); + } else if (preview) { + LOG.info("Preview mode"); + } else if (mediumTestMode) { + LOG.info("Medium test mode"); + } + // To stay compatible with plugins that use the old property to check mode + if (incremental || preview) { + bootstrapProps.properties().put(CoreProperties.DRY_RUN, "true"); + } + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionInstaller.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionInstaller.java index 765d138c9b3..86599f96774 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionInstaller.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionInstaller.java @@ -34,9 +34,9 @@ public class ExtensionInstaller { private final BatchPluginRepository pluginRepository; private final EnvironmentInformation env; - private final AnalysisMode analysisMode; + private final DefaultAnalysisMode analysisMode; - public ExtensionInstaller(BatchPluginRepository pluginRepository, EnvironmentInformation env, AnalysisMode analysisMode) { + public ExtensionInstaller(BatchPluginRepository pluginRepository, EnvironmentInformation env, DefaultAnalysisMode analysisMode) { this.pluginRepository = pluginRepository; this.env = env; this.analysisMode = analysisMode; @@ -73,7 +73,7 @@ public class ExtensionInstaller { private void doInstall(ComponentContainer container, ExtensionMatcher matcher, @Nullable PluginMetadata metadata, Object extension) { if (ExtensionUtils.supportsEnvironment(extension, env) - && (!analysisMode.isPreview() || ExtensionUtils.supportsPreview(extension)) + && (analysisMode.isDb() || !ExtensionUtils.requiresDB(extension)) && matcher.accept(extension)) { container.addExtension(metadata, extension); } else { diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionUtils.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionUtils.java index 540b7142b6c..61bc80e6538 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionUtils.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ExtensionUtils.java @@ -22,10 +22,10 @@ package org.sonar.batch.bootstrap; import org.apache.commons.lang.StringUtils; import org.sonar.api.BatchExtension; import org.sonar.api.batch.InstantiationStrategy; +import org.sonar.api.batch.RequiresDB; import org.sonar.api.batch.SupportedEnvironment; import org.sonar.api.utils.AnnotationUtils; import org.sonar.batch.bootstrapper.EnvironmentInformation; -import org.sonar.core.DryRunIncompatible; public class ExtensionUtils { @@ -58,8 +58,8 @@ public class ExtensionUtils { return false; } - public static boolean supportsPreview(Object extension) { - return AnnotationUtils.getAnnotation(extension, DryRunIncompatible.class) == null; + public static boolean requiresDB(Object extension) { + return AnnotationUtils.getAnnotation(extension, RequiresDB.class) != null; } public static boolean isMavenExtensionOnly(Object extension) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java new file mode 100644 index 00000000000..f30a891be30 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java @@ -0,0 +1,170 @@ +/* + * 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.batch.bootstrap; + +import org.sonar.api.Plugin; +import org.sonar.api.config.EmailSettings; +import org.sonar.api.platform.ComponentContainer; +import org.sonar.api.platform.PluginMetadata; +import org.sonar.api.utils.Durations; +import org.sonar.api.utils.HttpDownloader; +import org.sonar.api.utils.System2; +import org.sonar.api.utils.UriReader; +import org.sonar.api.utils.internal.TempFolderCleaner; +import org.sonar.batch.components.PastSnapshotFinder; +import org.sonar.batch.components.PastSnapshotFinderByDate; +import org.sonar.batch.components.PastSnapshotFinderByDays; +import org.sonar.batch.components.PastSnapshotFinderByPreviousAnalysis; +import org.sonar.batch.components.PastSnapshotFinderByPreviousVersion; +import org.sonar.batch.components.PastSnapshotFinderByVersion; +import org.sonar.batch.platform.DefaultServer; +import org.sonar.batch.repository.DefaultGlobalRepositoriesLoader; +import org.sonar.batch.repository.DefaultPreviousIssuesLoader; +import org.sonar.batch.repository.DefaultProjectRepositoriesLoader; +import org.sonar.batch.repository.GlobalRepositoriesLoader; +import org.sonar.batch.repository.GlobalRepositoriesProvider; +import org.sonar.batch.repository.PreviousIssuesLoader; +import org.sonar.batch.repository.ProjectRepositoriesLoader; +import org.sonar.batch.user.UserRepository; +import org.sonar.core.cluster.NullQueue; +import org.sonar.core.config.Logback; +import org.sonar.core.i18n.DefaultI18n; +import org.sonar.core.i18n.RuleI18nManager; +import org.sonar.core.persistence.DaoUtils; +import org.sonar.core.persistence.DatabaseVersion; +import org.sonar.core.persistence.MyBatis; +import org.sonar.core.persistence.SemaphoreUpdater; +import org.sonar.core.persistence.SemaphoresImpl; +import org.sonar.core.purge.PurgeProfiler; +import org.sonar.core.rule.CacheRuleFinder; +import org.sonar.core.user.HibernateUserFinder; +import org.sonar.jpa.dao.MeasuresDao; +import org.sonar.jpa.session.DefaultDatabaseConnector; +import org.sonar.jpa.session.JpaDatabaseSession; + +import java.util.List; +import java.util.Map; + +public class GlobalContainer extends ComponentContainer { + + private final Map bootstrapProperties; + + private GlobalContainer(Map bootstrapProperties) { + super(); + this.bootstrapProperties = bootstrapProperties; + } + + public static GlobalContainer create(Map bootstrapProperties, List extensions) { + GlobalContainer container = new GlobalContainer(bootstrapProperties); + container.add(extensions); + return container; + } + + @Override + protected void doBeforeStart() { + BootstrapProperties bootstrapProps = new BootstrapProperties(bootstrapProperties); + DefaultAnalysisMode analysisMode = new DefaultAnalysisMode(bootstrapProps); + add(bootstrapProps, analysisMode); + addBootstrapComponents(); + if (analysisMode.isDb()) { + addDatabaseComponents(); + } + + } + + private void addBootstrapComponents() { + add( + BatchPluginRepository.class, + BatchPluginJarInstaller.class, + GlobalSettings.class, + ServerClient.class, + ExtensionInstaller.class, + Logback.class, + DefaultServer.class, + new TempFolderProvider(), + TempFolderCleaner.class, + HttpDownloader.class, + UriReader.class, + new FileCacheProvider(), + System2.INSTANCE, + DefaultI18n.class, + new GlobalRepositoriesProvider(), + UserRepository.class); + if (getComponentByType(PluginsReferential.class) == null) { + add(DefaultPluginsReferential.class); + } + if (getComponentByType(GlobalRepositoriesLoader.class) == null) { + add(DefaultGlobalRepositoriesLoader.class); + } + if (getComponentByType(ProjectRepositoriesLoader.class) == null) { + add(DefaultProjectRepositoriesLoader.class); + } + if (getComponentByType(PreviousIssuesLoader.class) == null) { + add(DefaultPreviousIssuesLoader.class); + } + } + + private void addDatabaseComponents() { + add( + JdbcDriverHolder.class, + BatchDatabase.class, + MyBatis.class, + NullQueue.class, + DatabaseVersion.class, + DatabaseCompatibility.class, + DefaultDatabaseConnector.class, + JpaDatabaseSession.class, + BatchDatabaseSessionFactory.class, + DaoUtils.getDaoClasses(), + PurgeProfiler.class, + CacheRuleFinder.class, + EmailSettings.class, + RuleI18nManager.class, + MeasuresDao.class, + HibernateUserFinder.class, + SemaphoreUpdater.class, + SemaphoresImpl.class, + PastSnapshotFinderByDate.class, + PastSnapshotFinderByDays.class, + PastSnapshotFinderByPreviousAnalysis.class, + PastSnapshotFinderByVersion.class, + PastSnapshotFinderByPreviousVersion.class, + PastSnapshotFinder.class, + Durations.class); + } + + @Override + protected void doAfterStart() { + installPlugins(); + } + + private void installPlugins() { + for (Map.Entry entry : getComponentByType(BatchPluginRepository.class).getPluginsByMetadata().entrySet()) { + PluginMetadata metadata = entry.getKey(); + Plugin plugin = entry.getValue(); + addExtension(metadata, plugin); + } + } + + public void executeTask(Map taskProperties, Object... components) { + new TaskContainer(this, taskProperties, components).execute(); + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalSettings.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalSettings.java index 5752c5c0f55..58e6e6e747a 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalSettings.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalSettings.java @@ -29,10 +29,10 @@ public class GlobalSettings extends Settings { private final BootstrapProperties bootstrapProps; private final GlobalRepositories globalReferentials; - private final AnalysisMode mode; + private final DefaultAnalysisMode mode; public GlobalSettings(BootstrapProperties bootstrapProps, PropertyDefinitions propertyDefinitions, - GlobalRepositories globalReferentials, AnalysisMode mode) { + GlobalRepositories globalReferentials, DefaultAnalysisMode mode) { super(propertyDefinitions); this.mode = mode; diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/JdbcDriverHolder.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/JdbcDriverHolder.java index 849c5269da7..b47590b75a7 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/JdbcDriverHolder.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/JdbcDriverHolder.java @@ -41,13 +41,13 @@ public class JdbcDriverHolder { private static final Logger LOG = LoggerFactory.getLogger(JdbcDriverHolder.class); private ServerClient serverClient; - private AnalysisMode analysisMode; + private DefaultAnalysisMode analysisMode; private FileCache fileCache; // initialized in start() private JdbcDriverClassLoader classLoader = null; - public JdbcDriverHolder(FileCache fileCache, AnalysisMode analysisMode, ServerClient serverClient) { + public JdbcDriverHolder(FileCache fileCache, DefaultAnalysisMode analysisMode, ServerClient serverClient) { this.serverClient = serverClient; this.analysisMode = analysisMode; this.fileCache = fileCache; diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/PreviewDatabase.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/PreviewDatabase.java deleted file mode 100644 index ae01712f712..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/PreviewDatabase.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch.bootstrap; - -import com.google.common.base.Throwables; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.BatchComponent; -import org.sonar.api.CoreProperties; -import org.sonar.api.config.Settings; -import org.sonar.api.database.DatabaseProperties; -import org.sonar.api.utils.HttpDownloader.HttpException; -import org.sonar.api.utils.SonarException; -import org.sonar.api.utils.TempFolder; - -import java.io.File; -import java.net.SocketTimeoutException; - -/** - * @since 3.4 - */ -public class PreviewDatabase implements BatchComponent { - private static final Logger LOG = LoggerFactory.getLogger(PreviewDatabase.class); - - private static final String DIALECT = "h2"; - private static final String DRIVER = "org.h2.Driver"; - private static final String URL = "jdbc:h2:"; - private static final String USER = "sonar"; - private static final String PASSWORD = USER; - - private final Settings settings; - private final ServerClient server; - private final TempFolder tempUtils; - private final AnalysisMode mode; - - public PreviewDatabase(Settings settings, ServerClient server, TempFolder tempUtils, AnalysisMode mode) { - this.settings = settings; - this.server = server; - this.tempUtils = tempUtils; - this.mode = mode; - } - - public void start() { - if (mode.isPreview()) { - File databaseFile = tempUtils.newFile("preview", ".h2.db"); - - int readTimeoutSec = mode.getPreviewReadTimeoutSec(); - downloadDatabase(databaseFile, readTimeoutSec * 1000); - - String databasePath = StringUtils.removeEnd(databaseFile.getAbsolutePath(), ".h2.db"); - replaceSettings(databasePath); - } - } - - private void downloadDatabase(File toFile, int readTimeoutMillis) { - String projectKey = null; - try { - projectKey = settings.getString(CoreProperties.PROJECT_KEY_PROPERTY); - String branch = settings.getString(CoreProperties.PROJECT_BRANCH_PROPERTY); - if (StringUtils.isNotBlank(branch)) { - projectKey = String.format("%s:%s", projectKey, branch); - } - if (StringUtils.isBlank(projectKey)) { - server.download("/batch_bootstrap/db", toFile, readTimeoutMillis); - } else { - server.download("/batch_bootstrap/db?project=" + projectKey, toFile, readTimeoutMillis); - } - LOG.debug("Dry Run database size: {}", FileUtils.byteCountToDisplaySize(FileUtils.sizeOf(toFile))); - } catch (SonarException e) { - handleException(readTimeoutMillis, projectKey, e); - throw e; - } - } - - private void handleException(int readTimeout, String projectKey, SonarException e) { - Throwable rootCause = Throwables.getRootCause(e); - if (rootCause instanceof SocketTimeoutException) { - // Pico will unwrap the first runtime exception - throw new SonarException(new SonarException(String.format("Preview database read timed out after %s ms. You can try to increase read timeout with property -D" - + CoreProperties.PREVIEW_READ_TIMEOUT_SEC + " (in seconds)", - readTimeout), e)); - } - if (projectKey != null && (rootCause instanceof HttpException) && (((HttpException) rootCause).getResponseCode() == 401)) { - // Pico will unwrap the first runtime exception - throw new SonarException(new SonarException(String.format("You don't have access rights to project [%s]", projectKey), e)); - } - } - - private void replaceSettings(String databasePath) { - settings - .setProperty(DatabaseProperties.PROP_DIALECT, DIALECT) - .setProperty(DatabaseProperties.PROP_DRIVER, DRIVER) - .setProperty(DatabaseProperties.PROP_USER, USER) - .setProperty(DatabaseProperties.PROP_PASSWORD, PASSWORD) - .setProperty(DatabaseProperties.PROP_URL, URL + databasePath); - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java index 3b53ae97c19..2fed7682233 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java @@ -121,7 +121,7 @@ public class ServerClient implements BatchComponent { } } - private RuntimeException handleHttpException(HttpDownloader.HttpException he) { + public RuntimeException handleHttpException(HttpDownloader.HttpException he) { if (he.getResponseCode() == 401) { return new IllegalStateException(String.format(getMessageWhenNotAuthorized(), CoreProperties.LOGIN, CoreProperties.PASSWORD)); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerMetadata.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerMetadata.java deleted file mode 100644 index 01d2b5915c1..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerMetadata.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch.bootstrap; - -import com.google.common.annotations.VisibleForTesting; -import org.apache.commons.lang.StringUtils; -import org.slf4j.LoggerFactory; -import org.sonar.api.BatchComponent; -import org.sonar.api.CoreProperties; -import org.sonar.api.config.Settings; -import org.sonar.api.platform.Server; - -import java.io.File; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; - -/** - * @deprecated in 3.4. Replaced by {@link org.sonar.batch.bootstrap.ServerClient} - */ -@Deprecated -public class ServerMetadata extends Server implements BatchComponent { - - private Settings settings; - private ServerClient client; - - public ServerMetadata(Settings settings, ServerClient client) { - this.settings = settings; - this.client = client; - } - - @Override - public String getId() { - return settings.getString(CoreProperties.SERVER_ID); - } - - @Override - public String getVersion() { - return settings.getString(CoreProperties.SERVER_VERSION); - } - - @Override - public Date getStartedAt() { - String dateString = settings.getString(CoreProperties.SERVER_STARTTIME); - if (dateString != null) { - try { - return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(dateString); - - } catch (ParseException e) { - LoggerFactory.getLogger(getClass()).error("The property " + CoreProperties.SERVER_STARTTIME + " is badly formatted.", e); - } - } - return null; - } - - @Override - public File getRootDir() { - return null; - } - - @Override - public File getDeployDir() { - return null; - } - - @Override - public String getContextPath() { - return null; - } - - @Override - public String getURL() { - return client.getURL(); - } - - @Override - public String getPermanentServerId() { - return settings.getString(CoreProperties.PERMANENT_SERVER_ID); - } - - public String getServerId() { - String remoteServerInfo = client.request("/api/server"); - // don't use JSON utilities to extract ID from such a small string - return extractServerId(remoteServerInfo); - } - - @VisibleForTesting - String extractServerId(String remoteServerInfo) { - String partialId = StringUtils.substringAfter(remoteServerInfo, "\"id\":\""); - return StringUtils.substringBefore(partialId, "\""); - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java index 21fd5c214e1..d301f1aa476 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/TaskContainer.java @@ -45,11 +45,13 @@ public class TaskContainer extends ComponentContainer { private final Map taskProperties; private final Object[] components; + private final DefaultAnalysisMode analysisMode; public TaskContainer(ComponentContainer parent, Map taskProperties, Object... components) { super(parent); this.taskProperties = taskProperties; this.components = components; + analysisMode = parent.getComponentByType(DefaultAnalysisMode.class); } @Override @@ -58,20 +60,21 @@ public class TaskContainer extends ComponentContainer { installTaskExtensions(); installComponentsUsingTaskExtensions(); addCoreComponents(); + if (analysisMode.isDb()) { + addDataBaseComponents(); + } for (Object component : components) { add(component); } } - private void addCoreComponents() { - // Metrics - if (!getParent().getComponentByType(AnalysisMode.class).isSensorMode()) { - // Needed by dev cockpit task - add(DeprecatedMetricFinder.class, - PastMeasuresLoader.class); - } - add(DefaultMetricFinder.class); + private void addDataBaseComponents() { + add(PastMeasuresLoader.class); + } + private void addCoreComponents() { + add(DefaultMetricFinder.class, + DeprecatedMetricFinder.class); } void installCoreTasks() { diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java index b448c2ad076..8bcae6dcc1f 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java @@ -21,7 +21,7 @@ package org.sonar.batch.bootstrapper; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import org.sonar.batch.bootstrap.BootstrapContainer; +import org.sonar.batch.bootstrap.GlobalContainer; import java.util.Collections; import java.util.List; @@ -38,7 +38,7 @@ public final class Batch { private LoggingConfiguration logging; private List components; private Map bootstrapProperties = Maps.newHashMap(); - private BootstrapContainer bootstrapContainer; + private GlobalContainer bootstrapContainer; private Batch(Builder builder) { components = Lists.newArrayList(); @@ -77,7 +77,7 @@ public final class Batch { } configureLogging(); - bootstrapContainer = BootstrapContainer.create(bootstrapProperties, components); + bootstrapContainer = GlobalContainer.create(bootstrapProperties, components); bootstrapContainer.startComponents(); this.started = true; diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java b/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java index 5b8f5f3c278..6cfd61dcabe 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/components/PastMeasuresLoader.java @@ -22,7 +22,7 @@ package org.sonar.batch.components; import com.google.common.collect.Maps; import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringUtils; -import org.sonar.api.BatchExtension; +import org.sonar.api.BatchComponent; import org.sonar.api.database.DatabaseSession; import org.sonar.api.database.model.Snapshot; import org.sonar.api.measures.Metric; @@ -38,7 +38,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; -public class PastMeasuresLoader implements BatchExtension { +public class PastMeasuresLoader implements BatchComponent { private Map metricByIds; private DatabaseSession session; diff --git a/sonar-batch/src/main/java/org/sonar/batch/components/TimeMachineConfiguration.java b/sonar-batch/src/main/java/org/sonar/batch/components/TimeMachineConfiguration.java index 09968ee9426..f5685852497 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/components/TimeMachineConfiguration.java +++ b/sonar-batch/src/main/java/org/sonar/batch/components/TimeMachineConfiguration.java @@ -19,10 +19,12 @@ */ package org.sonar.batch.components; +import org.sonar.api.batch.RequiresDB; + import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sonar.api.BatchExtension; +import org.sonar.api.BatchComponent; import org.sonar.api.database.DatabaseSession; import org.sonar.api.database.model.Snapshot; import org.sonar.api.resources.Qualifiers; @@ -33,7 +35,8 @@ import java.util.List; import static com.google.common.collect.Lists.newLinkedList; -public class TimeMachineConfiguration implements BatchExtension { +@RequiresDB +public class TimeMachineConfiguration implements BatchComponent { private static final Logger LOG = LoggerFactory.getLogger(TimeMachineConfiguration.class); diff --git a/sonar-batch/src/main/java/org/sonar/batch/design/MavenDependenciesSensor.java b/sonar-batch/src/main/java/org/sonar/batch/design/MavenDependenciesSensor.java index b0c37d4e82b..4d04022e509 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/design/MavenDependenciesSensor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/design/MavenDependenciesSensor.java @@ -19,6 +19,8 @@ */ package org.sonar.batch.design; +import org.sonar.api.batch.RequiresDB; + import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; @@ -55,7 +57,6 @@ import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; import org.sonar.api.utils.SonarException; import org.sonar.batch.index.ResourcePersister; -import org.sonar.core.DryRunIncompatible; import java.lang.reflect.Type; import java.util.ArrayList; @@ -63,7 +64,7 @@ import java.util.Collection; import java.util.List; @SupportedEnvironment("maven") -@DryRunIncompatible +@RequiresDB public class MavenDependenciesSensor implements Sensor { private static final String SONAR_MAVEN_PROJECT_DEPENDENCY = "sonar.maven.projectDependencies"; diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/BatchResource.java b/sonar-batch/src/main/java/org/sonar/batch/index/BatchResource.java index 7e2859d6d94..4d3479368d4 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/index/BatchResource.java +++ b/sonar-batch/src/main/java/org/sonar/batch/index/BatchResource.java @@ -59,8 +59,12 @@ public class BatchResource { return this; } - public int snapshotId() { - return s.getId(); + /** + * @return null in database less mode + */ + @CheckForNull + public Integer snapshotId() { + return s != null ? s.getId() : null; } public Snapshot snapshot() { diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesSensor.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesSensor.java index a58f5c93a80..507e5cbd2f0 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesSensor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesSensor.java @@ -19,13 +19,14 @@ */ package org.sonar.batch.issue.tracking; +import org.sonar.api.batch.RequiresDB; + import org.apache.commons.lang.time.DateUtils; import org.apache.ibatis.session.ResultContext; import org.apache.ibatis.session.ResultHandler; import org.sonar.api.batch.Sensor; import org.sonar.api.batch.SensorContext; import org.sonar.api.resources.Project; -import org.sonar.core.DryRunIncompatible; import org.sonar.core.issue.db.IssueChangeDao; import org.sonar.core.issue.db.IssueChangeDto; import org.sonar.core.issue.db.IssueDao; @@ -37,7 +38,7 @@ import java.util.Date; /** * Load all the issues referenced during the previous scan. */ -@DryRunIncompatible +@RequiresDB public class InitialOpenIssuesSensor implements Sensor { private final InitialOpenIssuesStack initialOpenIssuesStack; diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingDecorator.java index 8bc86e35fa7..c3826cbd391 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingDecorator.java +++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingDecorator.java @@ -19,6 +19,8 @@ */ package org.sonar.batch.issue.tracking; +import org.sonar.api.batch.RequiresDB; + import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Strings; import com.google.common.collect.Lists; @@ -50,7 +52,6 @@ import org.sonar.api.utils.KeyValueFormat; import org.sonar.batch.issue.IssueCache; import org.sonar.batch.scan.LastLineHashes; import org.sonar.batch.scan.filesystem.InputPathCache; -import org.sonar.core.DryRunIncompatible; import org.sonar.core.issue.IssueUpdater; import org.sonar.core.issue.db.IssueChangeDto; import org.sonar.core.issue.db.IssueDto; @@ -60,7 +61,7 @@ import java.util.Collection; @DependsUpon(DecoratorBarriers.ISSUES_ADDED) @DependedUpon(DecoratorBarriers.ISSUES_TRACKED) -@DryRunIncompatible +@RequiresDB public class IssueTrackingDecorator implements Decorator { private static final Logger LOG = LoggerFactory.getLogger(IssueTrackingDecorator.class); diff --git a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java index e5ac2e3046f..8930a759b91 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java +++ b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java @@ -21,6 +21,7 @@ package org.sonar.batch.mediumtest; import com.google.common.base.Function; import org.apache.commons.io.Charsets; +import org.sonar.api.CoreProperties; import org.sonar.api.SonarPlugin; import org.sonar.api.batch.bootstrap.ProjectReactor; import org.sonar.api.batch.debt.internal.DefaultDebtModel; @@ -61,7 +62,9 @@ public class BatchMediumTester { private Batch batch; public static BatchMediumTesterBuilder builder() { - return new BatchMediumTesterBuilder().registerCoreMetrics(); + BatchMediumTesterBuilder builder = new BatchMediumTesterBuilder().registerCoreMetrics(); + builder.bootstrapProperties.put(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_MEDIUM_TEST); + return builder; } public static class BatchMediumTesterBuilder { diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseLessPhaseExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseLessPhaseExecutor.java new file mode 100644 index 00000000000..9ab360e7f44 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseLessPhaseExecutor.java @@ -0,0 +1,169 @@ +/* + * 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.batch.phases; + +import org.sonar.api.batch.SensorContext; +import org.sonar.api.resources.Project; +import org.sonar.batch.events.BatchStepEvent; +import org.sonar.batch.events.EventBus; +import org.sonar.batch.index.DefaultIndex; +import org.sonar.batch.issue.ignore.scanner.IssueExclusionsLoader; +import org.sonar.batch.issue.tracking.LocalIssueTracking; +import org.sonar.batch.report.PublishReportJob; +import org.sonar.batch.rule.QProfileVerifier; +import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; +import org.sonar.batch.scan.filesystem.FileSystemLogger; +import org.sonar.batch.scan.maven.MavenPluginsConfigurator; +import org.sonar.batch.scan.report.IssuesReports; + +public final class DatabaseLessPhaseExecutor implements PhaseExecutor { + + private final EventBus eventBus; + private final Phases phases; + private final MavenPluginsConfigurator mavenPluginsConfigurator; + private final InitializersExecutor initializersExecutor; + private final SensorsExecutor sensorsExecutor; + private final SensorContext sensorContext; + private final DefaultIndex index; + private final ProjectInitializer pi; + private final FileSystemLogger fsLogger; + private final DefaultModuleFileSystem fs; + private final QProfileVerifier profileVerifier; + private final IssueExclusionsLoader issueExclusionsLoader; + private final IssuesReports issuesReport; + private final LocalIssueTracking localIssueTracking; + private final PublishReportJob publishReportJob; + + public DatabaseLessPhaseExecutor(Phases phases, + MavenPluginsConfigurator mavenPluginsConfigurator, InitializersExecutor initializersExecutor, + SensorsExecutor sensorsExecutor, + SensorContext sensorContext, DefaultIndex index, + EventBus eventBus, ProjectInitializer pi, FileSystemLogger fsLogger, IssuesReports jsonReport, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier, + IssueExclusionsLoader issueExclusionsLoader, LocalIssueTracking localIssueTracking, PublishReportJob publishReportJob) { + this.phases = phases; + this.mavenPluginsConfigurator = mavenPluginsConfigurator; + this.initializersExecutor = initializersExecutor; + this.sensorsExecutor = sensorsExecutor; + this.sensorContext = sensorContext; + this.index = index; + this.eventBus = eventBus; + this.pi = pi; + this.fsLogger = fsLogger; + this.issuesReport = jsonReport; + this.fs = fs; + this.profileVerifier = profileVerifier; + this.issueExclusionsLoader = issueExclusionsLoader; + this.localIssueTracking = localIssueTracking; + this.publishReportJob = publishReportJob; + } + + /** + * Executed on each module + */ + @Override + public void execute(Project module) { + pi.execute(module); + + eventBus.fireEvent(new ProjectAnalysisEvent(module, true)); + + executeMavenPhase(module); + + executeInitializersPhase(); + + if (phases.isEnabled(Phases.Phase.SENSOR)) { + // Index and lock the filesystem + indexFs(); + + // Log detected languages and their profiles after FS is indexed and languages detected + profileVerifier.execute(); + + // Initialize issue exclusions + initIssueExclusions(); + + sensorsExecutor.execute(sensorContext); + } + + if (module.isRoot()) { + localIssueTracking(); + issuesReport(); + publishReportJob(); + } + + cleanMemory(); + eventBus.fireEvent(new ProjectAnalysisEvent(module, false)); + } + + private void publishReportJob() { + String stepName = "Publish report"; + eventBus.fireEvent(new BatchStepEvent(stepName, true)); + this.publishReportJob.execute(); + eventBus.fireEvent(new BatchStepEvent(stepName, false)); + } + + private void localIssueTracking() { + String stepName = "Local Issue Tracking"; + eventBus.fireEvent(new BatchStepEvent(stepName, true)); + localIssueTracking.execute(); + eventBus.fireEvent(new BatchStepEvent(stepName, false)); + } + + private void issuesReport() { + String stepName = "Issues Reports"; + eventBus.fireEvent(new BatchStepEvent(stepName, true)); + issuesReport.execute(); + eventBus.fireEvent(new BatchStepEvent(stepName, false)); + } + + private void initIssueExclusions() { + String stepName = "Init issue exclusions"; + eventBus.fireEvent(new BatchStepEvent(stepName, true)); + issueExclusionsLoader.execute(); + eventBus.fireEvent(new BatchStepEvent(stepName, false)); + } + + private void indexFs() { + String stepName = "Index filesystem and store sources"; + eventBus.fireEvent(new BatchStepEvent(stepName, true)); + fs.index(); + eventBus.fireEvent(new BatchStepEvent(stepName, false)); + } + + private void executeInitializersPhase() { + if (phases.isEnabled(Phases.Phase.INIT)) { + initializersExecutor.execute(); + fsLogger.log(); + } + } + + private void executeMavenPhase(Project module) { + if (phases.isEnabled(Phases.Phase.MAVEN)) { + eventBus.fireEvent(new MavenPhaseEvent(true)); + mavenPluginsConfigurator.execute(module); + eventBus.fireEvent(new MavenPhaseEvent(false)); + } + } + + private void cleanMemory() { + String cleanMemory = "Clean memory"; + eventBus.fireEvent(new BatchStepEvent(cleanMemory, true)); + index.clear(); + eventBus.fireEvent(new BatchStepEvent(cleanMemory, false)); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseModePhaseExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseModePhaseExecutor.java new file mode 100644 index 00000000000..e4e8443dd05 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseModePhaseExecutor.java @@ -0,0 +1,219 @@ +/* + * 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.batch.phases; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.resources.Project; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; +import org.sonar.batch.events.BatchStepEvent; +import org.sonar.batch.events.EventBus; +import org.sonar.batch.index.DefaultIndex; +import org.sonar.batch.index.ResourcePersister; +import org.sonar.batch.index.ScanPersister; +import org.sonar.batch.issue.ignore.scanner.IssueExclusionsLoader; +import org.sonar.batch.report.PublishReportJob; +import org.sonar.batch.rule.QProfileVerifier; +import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; +import org.sonar.batch.scan.filesystem.FileSystemLogger; +import org.sonar.batch.scan.maven.MavenPluginsConfigurator; +import org.sonar.batch.scan.report.IssuesReports; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public final class DatabaseModePhaseExecutor implements PhaseExecutor { + + private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseModePhaseExecutor.class); + + private final EventBus eventBus; + private final Phases phases; + private final DecoratorsExecutor decoratorsExecutor; + private final MavenPluginsConfigurator mavenPluginsConfigurator; + private final PostJobsExecutor postJobsExecutor; + private final InitializersExecutor initializersExecutor; + private final SensorsExecutor sensorsExecutor; + private final PublishReportJob publishReportJob; + private final SensorContext sensorContext; + private final DefaultIndex index; + private final ProjectInitializer pi; + private final ScanPersister[] persisters; + private final FileSystemLogger fsLogger; + private final IssuesReports jsonReport; + private final DefaultModuleFileSystem fs; + private final QProfileVerifier profileVerifier; + private final IssueExclusionsLoader issueExclusionsLoader; + private final DefaultAnalysisMode analysisMode; + private final DatabaseSession session; + private final ResourcePersister resourcePersister; + + public DatabaseModePhaseExecutor(Phases phases, DecoratorsExecutor decoratorsExecutor, + MavenPluginsConfigurator mavenPluginsConfigurator, InitializersExecutor initializersExecutor, + PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor, + SensorContext sensorContext, DefaultIndex index, + EventBus eventBus, PublishReportJob publishReportJob, ProjectInitializer pi, + ScanPersister[] persisters, FileSystemLogger fsLogger, IssuesReports jsonReport, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier, + IssueExclusionsLoader issueExclusionsLoader, DefaultAnalysisMode analysisMode, DatabaseSession session, ResourcePersister resourcePersister) { + this.phases = phases; + this.decoratorsExecutor = decoratorsExecutor; + this.mavenPluginsConfigurator = mavenPluginsConfigurator; + this.postJobsExecutor = postJobsExecutor; + this.initializersExecutor = initializersExecutor; + this.sensorsExecutor = sensorsExecutor; + this.sensorContext = sensorContext; + this.index = index; + this.eventBus = eventBus; + this.publishReportJob = publishReportJob; + this.pi = pi; + this.persisters = persisters; + this.fsLogger = fsLogger; + this.jsonReport = jsonReport; + this.fs = fs; + this.profileVerifier = profileVerifier; + this.issueExclusionsLoader = issueExclusionsLoader; + this.analysisMode = analysisMode; + this.session = session; + this.resourcePersister = resourcePersister; + } + + /** + * Executed on each module + */ + @Override + public void execute(Project module) { + pi.execute(module); + + eventBus.fireEvent(new ProjectAnalysisEvent(module, true)); + + executeMavenPhase(module); + + executeInitializersPhase(); + + if (phases.isEnabled(Phases.Phase.SENSOR)) { + // Index and lock the filesystem + indexFs(); + + // Log detected languages and their profiles after FS is indexed and languages detected + profileVerifier.execute(); + + // Initialize issue exclusions + initIssueExclusions(); + + // SONAR-2965 In case the sensor takes too much time we close the session to not face a timeout + session.commitAndClose(); + sensorsExecutor.execute(sensorContext); + } + + // Special case for views. + resourcePersister.persist(); + + if (phases.isEnabled(Phases.Phase.DECORATOR)) { + decoratorsExecutor.execute(); + } + + if (module.isRoot()) { + jsonReport.execute(); + + executePersisters(); + publishReportJob(); + if (phases.isEnabled(Phases.Phase.POSTJOB)) { + postJobsExecutor.execute(sensorContext); + } + } + cleanMemory(); + eventBus.fireEvent(new ProjectAnalysisEvent(module, false)); + } + + private void initIssueExclusions() { + String stepName = "Init issue exclusions"; + eventBus.fireEvent(new BatchStepEvent(stepName, true)); + issueExclusionsLoader.execute(); + eventBus.fireEvent(new BatchStepEvent(stepName, false)); + } + + private void indexFs() { + String stepName = "Index filesystem and store sources"; + eventBus.fireEvent(new BatchStepEvent(stepName, true)); + fs.index(); + eventBus.fireEvent(new BatchStepEvent(stepName, false)); + } + + private void executePersisters() { + if (!analysisMode.isPreview()) { + LOGGER.info("Store results in database"); + List sortedPersisters = sortedPersisters(); + eventBus.fireEvent(new PersistersPhaseEvent(sortedPersisters, true)); + for (ScanPersister persister : sortedPersisters) { + LOGGER.debug("Execute {}", persister.getClass().getName()); + eventBus.fireEvent(new PersisterExecutionEvent(persister, true)); + persister.persist(); + eventBus.fireEvent(new PersisterExecutionEvent(persister, false)); + } + + eventBus.fireEvent(new PersistersPhaseEvent(sortedPersisters, false)); + } + } + + List sortedPersisters() { + // Sort by reverse name so that ResourcePersister is executed before MeasurePersister + List sortedPersisters = new ArrayList<>(Arrays.asList(persisters)); + Collections.sort(sortedPersisters, new Comparator() { + @Override + public int compare(ScanPersister o1, ScanPersister o2) { + return o2.getClass().getName().compareTo(o1.getClass().getName()); + } + }); + return sortedPersisters; + } + + private void publishReportJob() { + String stepName = "Publish report"; + eventBus.fireEvent(new BatchStepEvent(stepName, true)); + this.publishReportJob.execute(); + eventBus.fireEvent(new BatchStepEvent(stepName, false)); + } + + private void executeInitializersPhase() { + if (phases.isEnabled(Phases.Phase.INIT)) { + initializersExecutor.execute(); + fsLogger.log(); + } + } + + private void executeMavenPhase(Project module) { + if (phases.isEnabled(Phases.Phase.MAVEN)) { + eventBus.fireEvent(new MavenPhaseEvent(true)); + mavenPluginsConfigurator.execute(module); + eventBus.fireEvent(new MavenPhaseEvent(false)); + } + } + + private void cleanMemory() { + String cleanMemory = "Clean memory"; + eventBus.fireEvent(new BatchStepEvent(cleanMemory, true)); + index.clear(); + eventBus.fireEvent(new BatchStepEvent(cleanMemory, false)); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/DefaultPhaseExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/phases/DefaultPhaseExecutor.java deleted file mode 100644 index 8e1ad8ad1c3..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/phases/DefaultPhaseExecutor.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch.phases; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.batch.SensorContext; -import org.sonar.api.database.DatabaseSession; -import org.sonar.api.resources.Project; -import org.sonar.batch.bootstrap.AnalysisMode; -import org.sonar.batch.events.BatchStepEvent; -import org.sonar.batch.events.EventBus; -import org.sonar.batch.index.DefaultIndex; -import org.sonar.batch.index.ResourcePersister; -import org.sonar.batch.index.ScanPersister; -import org.sonar.batch.issue.ignore.scanner.IssueExclusionsLoader; -import org.sonar.batch.report.PublishReportJob; -import org.sonar.batch.rule.QProfileVerifier; -import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; -import org.sonar.batch.scan.filesystem.FileSystemLogger; -import org.sonar.batch.scan.maven.MavenPluginsConfigurator; -import org.sonar.batch.scan.report.IssuesReports; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -public final class DefaultPhaseExecutor implements PhaseExecutor { - - private static final Logger LOGGER = LoggerFactory.getLogger(DefaultPhaseExecutor.class); - - private final EventBus eventBus; - private final Phases phases; - private final DecoratorsExecutor decoratorsExecutor; - private final MavenPluginsConfigurator mavenPluginsConfigurator; - private final PostJobsExecutor postJobsExecutor; - private final InitializersExecutor initializersExecutor; - private final SensorsExecutor sensorsExecutor; - private final PublishReportJob publishReportJob; - private final SensorContext sensorContext; - private final DefaultIndex index; - private final ProjectInitializer pi; - private final ScanPersister[] persisters; - private final FileSystemLogger fsLogger; - private final IssuesReports jsonReport; - private final DefaultModuleFileSystem fs; - private final QProfileVerifier profileVerifier; - private final IssueExclusionsLoader issueExclusionsLoader; - private final AnalysisMode analysisMode; - private final DatabaseSession session; - private final ResourcePersister resourcePersister; - - public DefaultPhaseExecutor(Phases phases, DecoratorsExecutor decoratorsExecutor, - MavenPluginsConfigurator mavenPluginsConfigurator, InitializersExecutor initializersExecutor, - PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor, - SensorContext sensorContext, DefaultIndex index, - EventBus eventBus, PublishReportJob publishReportJob, ProjectInitializer pi, - ScanPersister[] persisters, FileSystemLogger fsLogger, IssuesReports jsonReport, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier, - IssueExclusionsLoader issueExclusionsLoader, AnalysisMode analysisMode, DatabaseSession session, ResourcePersister resourcePersister) { - this.phases = phases; - this.decoratorsExecutor = decoratorsExecutor; - this.mavenPluginsConfigurator = mavenPluginsConfigurator; - this.postJobsExecutor = postJobsExecutor; - this.initializersExecutor = initializersExecutor; - this.sensorsExecutor = sensorsExecutor; - this.sensorContext = sensorContext; - this.index = index; - this.eventBus = eventBus; - this.publishReportJob = publishReportJob; - this.pi = pi; - this.persisters = persisters; - this.fsLogger = fsLogger; - this.jsonReport = jsonReport; - this.fs = fs; - this.profileVerifier = profileVerifier; - this.issueExclusionsLoader = issueExclusionsLoader; - this.analysisMode = analysisMode; - this.session = session; - this.resourcePersister = resourcePersister; - } - - /** - * Executed on each module - */ - @Override - public void execute(Project module) { - pi.execute(module); - - eventBus.fireEvent(new ProjectAnalysisEvent(module, true)); - - executeMavenPhase(module); - - executeInitializersPhase(); - - if (phases.isEnabled(Phases.Phase.SENSOR)) { - // Index and lock the filesystem - indexFs(); - - // Log detected languages and their profiles after FS is indexed and languages detected - profileVerifier.execute(); - - // Initialize issue exclusions - initIssueExclusions(); - - // SONAR-2965 In case the sensor takes too much time we close the session to not face a timeout - session.commitAndClose(); - sensorsExecutor.execute(sensorContext); - } - - // Special case for views. - resourcePersister.persist(); - - if (phases.isEnabled(Phases.Phase.DECORATOR)) { - decoratorsExecutor.execute(); - } - - if (module.isRoot()) { - jsonReport.execute(); - - executePersisters(); - publishReportJob(); - if (phases.isEnabled(Phases.Phase.POSTJOB)) { - postJobsExecutor.execute(sensorContext); - } - } - cleanMemory(); - eventBus.fireEvent(new ProjectAnalysisEvent(module, false)); - } - - private void initIssueExclusions() { - String stepName = "Init issue exclusions"; - eventBus.fireEvent(new BatchStepEvent(stepName, true)); - issueExclusionsLoader.execute(); - eventBus.fireEvent(new BatchStepEvent(stepName, false)); - } - - private void indexFs() { - String stepName = "Index filesystem and store sources"; - eventBus.fireEvent(new BatchStepEvent(stepName, true)); - fs.index(); - eventBus.fireEvent(new BatchStepEvent(stepName, false)); - } - - private void executePersisters() { - if (!analysisMode.isPreview()) { - LOGGER.info("Store results in database"); - List sortedPersisters = sortedPersisters(); - eventBus.fireEvent(new PersistersPhaseEvent(sortedPersisters, true)); - for (ScanPersister persister : sortedPersisters) { - LOGGER.debug("Execute {}", persister.getClass().getName()); - eventBus.fireEvent(new PersisterExecutionEvent(persister, true)); - persister.persist(); - eventBus.fireEvent(new PersisterExecutionEvent(persister, false)); - } - - eventBus.fireEvent(new PersistersPhaseEvent(sortedPersisters, false)); - } - } - - List sortedPersisters() { - // Sort by reverse name so that ResourcePersister is executed before MeasurePersister - List sortedPersisters = new ArrayList<>(Arrays.asList(persisters)); - Collections.sort(sortedPersisters, new Comparator() { - @Override - public int compare(ScanPersister o1, ScanPersister o2) { - return o2.getClass().getName().compareTo(o1.getClass().getName()); - } - }); - return sortedPersisters; - } - - private void publishReportJob() { - String stepName = "Publish report"; - eventBus.fireEvent(new BatchStepEvent(stepName, true)); - this.publishReportJob.execute(); - eventBus.fireEvent(new BatchStepEvent(stepName, false)); - } - - private void executeInitializersPhase() { - if (phases.isEnabled(Phases.Phase.INIT)) { - initializersExecutor.execute(); - fsLogger.log(); - } - } - - private void executeMavenPhase(Project module) { - if (phases.isEnabled(Phases.Phase.MAVEN)) { - eventBus.fireEvent(new MavenPhaseEvent(true)); - mavenPluginsConfigurator.execute(module); - eventBus.fireEvent(new MavenPhaseEvent(false)); - } - } - - private void cleanMemory() { - String cleanMemory = "Clean memory"; - eventBus.fireEvent(new BatchStepEvent(cleanMemory, true)); - index.clear(); - eventBus.fireEvent(new BatchStepEvent(cleanMemory, false)); - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/PreviewPhaseExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/phases/PreviewPhaseExecutor.java deleted file mode 100644 index 80c2fe8c078..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/phases/PreviewPhaseExecutor.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch.phases; - -import org.sonar.api.batch.SensorContext; -import org.sonar.api.resources.Project; -import org.sonar.batch.events.BatchStepEvent; -import org.sonar.batch.events.EventBus; -import org.sonar.batch.index.DefaultIndex; -import org.sonar.batch.issue.ignore.scanner.IssueExclusionsLoader; -import org.sonar.batch.issue.tracking.LocalIssueTracking; -import org.sonar.batch.rule.QProfileVerifier; -import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; -import org.sonar.batch.scan.filesystem.FileSystemLogger; -import org.sonar.batch.scan.maven.MavenPluginsConfigurator; -import org.sonar.batch.scan.report.IssuesReports; - -public final class PreviewPhaseExecutor implements PhaseExecutor { - - private final EventBus eventBus; - private final Phases phases; - private final MavenPluginsConfigurator mavenPluginsConfigurator; - private final InitializersExecutor initializersExecutor; - private final SensorsExecutor sensorsExecutor; - private final SensorContext sensorContext; - private final DefaultIndex index; - private final ProjectInitializer pi; - private final FileSystemLogger fsLogger; - private final DefaultModuleFileSystem fs; - private final QProfileVerifier profileVerifier; - private final IssueExclusionsLoader issueExclusionsLoader; - private final IssuesReports issuesReport; - private final LocalIssueTracking localIssueTracking; - - public PreviewPhaseExecutor(Phases phases, - MavenPluginsConfigurator mavenPluginsConfigurator, InitializersExecutor initializersExecutor, - SensorsExecutor sensorsExecutor, - SensorContext sensorContext, DefaultIndex index, - EventBus eventBus, ProjectInitializer pi, FileSystemLogger fsLogger, IssuesReports jsonReport, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier, - IssueExclusionsLoader issueExclusionsLoader, LocalIssueTracking localIssueTracking) { - this.phases = phases; - this.mavenPluginsConfigurator = mavenPluginsConfigurator; - this.initializersExecutor = initializersExecutor; - this.sensorsExecutor = sensorsExecutor; - this.sensorContext = sensorContext; - this.index = index; - this.eventBus = eventBus; - this.pi = pi; - this.fsLogger = fsLogger; - this.issuesReport = jsonReport; - this.fs = fs; - this.profileVerifier = profileVerifier; - this.issueExclusionsLoader = issueExclusionsLoader; - this.localIssueTracking = localIssueTracking; - } - - /** - * Executed on each module - */ - @Override - public void execute(Project module) { - pi.execute(module); - - eventBus.fireEvent(new ProjectAnalysisEvent(module, true)); - - executeMavenPhase(module); - - executeInitializersPhase(); - - if (phases.isEnabled(Phases.Phase.SENSOR)) { - // Index and lock the filesystem - indexFs(); - - // Log detected languages and their profiles after FS is indexed and languages detected - profileVerifier.execute(); - - // Initialize issue exclusions - initIssueExclusions(); - - sensorsExecutor.execute(sensorContext); - } - - if (module.isRoot()) { - - localIssueTracking(); - - issuesReport(); - } - - cleanMemory(); - eventBus.fireEvent(new ProjectAnalysisEvent(module, false)); - } - - private void localIssueTracking() { - String stepName = "Local Issue Tracking"; - eventBus.fireEvent(new BatchStepEvent(stepName, true)); - localIssueTracking.execute(); - eventBus.fireEvent(new BatchStepEvent(stepName, false)); - } - - private void issuesReport() { - String stepName = "Issues Reports"; - eventBus.fireEvent(new BatchStepEvent(stepName, true)); - issuesReport.execute(); - eventBus.fireEvent(new BatchStepEvent(stepName, false)); - } - - private void initIssueExclusions() { - String stepName = "Init issue exclusions"; - eventBus.fireEvent(new BatchStepEvent(stepName, true)); - issueExclusionsLoader.execute(); - eventBus.fireEvent(new BatchStepEvent(stepName, false)); - } - - private void indexFs() { - String stepName = "Index filesystem and store sources"; - eventBus.fireEvent(new BatchStepEvent(stepName, true)); - fs.index(); - eventBus.fireEvent(new BatchStepEvent(stepName, false)); - } - - private void executeInitializersPhase() { - if (phases.isEnabled(Phases.Phase.INIT)) { - initializersExecutor.execute(); - fsLogger.log(); - } - } - - private void executeMavenPhase(Project module) { - if (phases.isEnabled(Phases.Phase.MAVEN)) { - eventBus.fireEvent(new MavenPhaseEvent(true)); - mavenPluginsConfigurator.execute(module); - eventBus.fireEvent(new MavenPhaseEvent(false)); - } - } - - private void cleanMemory() { - String cleanMemory = "Clean memory"; - eventBus.fireEvent(new BatchStepEvent(cleanMemory, true)); - index.clear(); - eventBus.fireEvent(new BatchStepEvent(cleanMemory, false)); - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/platform/DefaultServer.java b/sonar-batch/src/main/java/org/sonar/batch/platform/DefaultServer.java new file mode 100644 index 00000000000..4c18063f574 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/platform/DefaultServer.java @@ -0,0 +1,93 @@ +/* + * 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.batch.platform; + +import org.sonar.batch.bootstrap.ServerClient; + +import org.slf4j.LoggerFactory; +import org.sonar.api.BatchComponent; +import org.sonar.api.CoreProperties; +import org.sonar.api.config.Settings; +import org.sonar.api.platform.Server; + +import java.io.File; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class DefaultServer extends Server implements BatchComponent { + + private Settings settings; + private ServerClient client; + + public DefaultServer(Settings settings, ServerClient client) { + this.settings = settings; + this.client = client; + } + + @Override + public String getId() { + return settings.getString(CoreProperties.SERVER_ID); + } + + @Override + public String getVersion() { + return settings.getString(CoreProperties.SERVER_VERSION); + } + + @Override + public Date getStartedAt() { + String dateString = settings.getString(CoreProperties.SERVER_STARTTIME); + if (dateString != null) { + try { + return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(dateString); + + } catch (ParseException e) { + LoggerFactory.getLogger(getClass()).error("The property " + CoreProperties.SERVER_STARTTIME + " is badly formatted.", e); + } + } + return null; + } + + @Override + public File getRootDir() { + return null; + } + + @Override + public File getDeployDir() { + return null; + } + + @Override + public String getContextPath() { + return null; + } + + @Override + public String getURL() { + return client.getURL(); + } + + @Override + public String getPermanentServerId() { + return settings.getString(CoreProperties.PERMANENT_SERVER_ID); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/platform/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/platform/package-info.java new file mode 100644 index 00000000000..7851b8651d9 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/platform/package-info.java @@ -0,0 +1,24 @@ +/* + * 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. + */ +@ParametersAreNonnullByDefault +package org.sonar.batch.platform; + +import javax.annotation.ParametersAreNonnullByDefault; + diff --git a/sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java b/sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java index 5917d9d0d43..9330a21066f 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java +++ b/sonar-batch/src/main/java/org/sonar/batch/report/ComponentsPublisher.java @@ -19,9 +19,6 @@ */ package org.sonar.batch.report; -import org.sonar.batch.protocol.output.component.ReportComponent; -import org.sonar.batch.protocol.output.component.ReportComponents; - import org.sonar.api.batch.bootstrap.ProjectReactor; import org.sonar.api.resources.Language; import org.sonar.api.resources.Project; @@ -30,6 +27,8 @@ import org.sonar.api.resources.ResourceUtils; import org.sonar.batch.index.BatchResource; import org.sonar.batch.index.ResourceCache; import org.sonar.batch.protocol.output.ReportHelper; +import org.sonar.batch.protocol.output.component.ReportComponent; +import org.sonar.batch.protocol.output.component.ReportComponents; import javax.annotation.CheckForNull; @@ -56,10 +55,12 @@ public class ComponentsPublisher implements ReportPublisher { private ReportComponent buildResourceForReport(BatchResource batchResource) { Resource r = batchResource.resource(); + Integer snapshotId = batchResource.snapshotId(); + Integer id = r.getId(); ReportComponent result = new ReportComponent() .setBatchId(batchResource.batchId()) - .setSnapshotId(batchResource.snapshotId()) - .setId(r.getId()) + .setSnapshotId(snapshotId != null ? snapshotId.intValue() : -1) + .setId(id != null ? id : -1) .setName(getName(r)) .setPath(r.getPath()) .setUuid(r.getUuid()) diff --git a/sonar-batch/src/main/java/org/sonar/batch/report/PublishReportJob.java b/sonar-batch/src/main/java/org/sonar/batch/report/PublishReportJob.java index 3469f1dd262..3ac79ee4187 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/report/PublishReportJob.java +++ b/sonar-batch/src/main/java/org/sonar/batch/report/PublishReportJob.java @@ -31,7 +31,7 @@ import org.sonar.api.platform.Server; import org.sonar.api.resources.Project; import org.sonar.api.utils.TempFolder; import org.sonar.api.utils.ZipUtils; -import org.sonar.batch.bootstrap.AnalysisMode; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; import org.sonar.batch.bootstrap.ServerClient; import org.sonar.batch.index.ResourceCache; import org.sonar.batch.protocol.output.ReportHelper; @@ -49,14 +49,14 @@ public class PublishReportJob implements BatchComponent { private final Server server; private final Settings settings; private final Project project; - private final AnalysisMode analysisMode; + private final DefaultAnalysisMode analysisMode; private final ResourceCache resourceCache; private final TempFolder temp; private ReportPublisher[] publishers; public PublishReportJob(Settings settings, ServerClient serverClient, Server server, - Project project, AnalysisMode analysisMode, TempFolder temp, ResourceCache resourceCache, ReportPublisher[] publishers) { + Project project, DefaultAnalysisMode analysisMode, TempFolder temp, ResourceCache resourceCache, ReportPublisher[] publishers) { this.serverClient = serverClient; this.server = server; this.project = project; @@ -68,7 +68,7 @@ public class PublishReportJob implements BatchComponent { } public PublishReportJob(Settings settings, ServerClient serverClient, Server server, - Project project, AnalysisMode analysisMode, TempFolder temp, ResourceCache resourceCache) { + Project project, DefaultAnalysisMode analysisMode, TempFolder temp, ResourceCache resourceCache) { this(settings, serverClient, server, project, analysisMode, temp, resourceCache, new ReportPublisher[0]); } @@ -76,7 +76,9 @@ public class PublishReportJob implements BatchComponent { // If this is a preview analysis then we should not upload reports if (!analysisMode.isPreview()) { File report = prepareReport(); - uploadMultiPartReport(report); + if (!analysisMode.isMediumTest()) { + uploadMultiPartReport(report); + } } logSuccess(LoggerFactory.getLogger(getClass())); } @@ -138,7 +140,7 @@ public class PublishReportJob implements BatchComponent { @VisibleForTesting void logSuccess(Logger logger) { - if (analysisMode.isPreview()) { + if (analysisMode.isPreview() || analysisMode.isMediumTest()) { logger.info("ANALYSIS SUCCESSFUL"); } else { diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultPreviousIssuesLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultPreviousIssuesLoader.java index d2831e4a8f2..f9ea0792c7f 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultPreviousIssuesLoader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultPreviousIssuesLoader.java @@ -23,6 +23,7 @@ import com.google.common.base.Charsets; import com.google.common.base.Function; import com.google.common.io.InputSupplier; import org.sonar.api.batch.bootstrap.ProjectReactor; +import org.sonar.api.utils.HttpDownloader; import org.sonar.batch.bootstrap.ServerClient; import org.sonar.batch.protocol.input.issues.PreviousIssue; import org.sonar.batch.protocol.input.issues.PreviousIssueHelper; @@ -47,6 +48,8 @@ public class DefaultPreviousIssuesLoader implements PreviousIssuesLoader { for (PreviousIssue issue : PreviousIssueHelper.getIssues(reader)) { consumer.apply(issue); } + } catch (HttpDownloader.HttpException e) { + throw serverClient.handleHttpException(e); } catch (IOException e) { throw new IllegalStateException("Unable to get previous issues", e); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoader.java index 922e9a82adf..87cc1f19954 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoader.java @@ -31,7 +31,7 @@ import org.sonar.api.database.model.Snapshot; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Metric; import org.sonar.api.resources.Qualifiers; -import org.sonar.batch.bootstrap.AnalysisMode; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; import org.sonar.batch.bootstrap.ServerClient; import org.sonar.batch.bootstrap.TaskProperties; import org.sonar.batch.protocol.input.FileData; @@ -55,16 +55,16 @@ public class DefaultProjectRepositoriesLoader implements ProjectRepositoriesLoad private static final String BATCH_PROJECT_URL = "/batch/project"; private final ServerClient serverClient; - private final AnalysisMode analysisMode; + private final DefaultAnalysisMode analysisMode; private final DatabaseSession session; - public DefaultProjectRepositoriesLoader(DatabaseSession session, ServerClient serverClient, AnalysisMode analysisMode) { + public DefaultProjectRepositoriesLoader(DatabaseSession session, ServerClient serverClient, DefaultAnalysisMode analysisMode) { this.session = session; this.serverClient = serverClient; this.analysisMode = analysisMode; } - public DefaultProjectRepositoriesLoader(ServerClient serverClient, AnalysisMode analysisMode) { + public DefaultProjectRepositoriesLoader(ServerClient serverClient, DefaultAnalysisMode analysisMode) { this.session = null; this.serverClient = serverClient; this.analysisMode = analysisMode; diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java index c54806dd347..1bbd1915a19 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java @@ -22,7 +22,6 @@ package org.sonar.batch.scan; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.BatchComponent; -import org.sonar.api.CoreProperties; import org.sonar.api.batch.InstantiationStrategy; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.rule.CheckFactory; @@ -35,8 +34,8 @@ import org.sonar.batch.DefaultTimeMachine; import org.sonar.batch.DeprecatedSensorContext; import org.sonar.batch.ProjectTree; import org.sonar.batch.ResourceFilters; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; import org.sonar.batch.bootstrap.BatchExtensionDictionnary; -import org.sonar.batch.bootstrap.BootstrapProperties; import org.sonar.batch.bootstrap.ExtensionInstaller; import org.sonar.batch.bootstrap.ExtensionMatcher; import org.sonar.batch.bootstrap.ExtensionUtils; @@ -62,12 +61,12 @@ import org.sonar.batch.issue.tracking.IssueHandlers; import org.sonar.batch.issue.tracking.IssueTrackingDecorator; import org.sonar.batch.language.LanguageDistributionDecorator; import org.sonar.batch.phases.DecoratorsExecutor; -import org.sonar.batch.phases.DefaultPhaseExecutor; +import org.sonar.batch.phases.DatabaseModePhaseExecutor; import org.sonar.batch.phases.InitializersExecutor; import org.sonar.batch.phases.PhaseExecutor; import org.sonar.batch.phases.PhasesTimeProfiler; import org.sonar.batch.phases.PostJobsExecutor; -import org.sonar.batch.phases.PreviewPhaseExecutor; +import org.sonar.batch.phases.DatabaseLessPhaseExecutor; import org.sonar.batch.phases.ProjectInitializer; import org.sonar.batch.phases.SensorsExecutor; import org.sonar.batch.qualitygate.GenerateQualityGateEvents; @@ -106,19 +105,19 @@ import org.sonar.core.component.ScanPerspectives; public class ModuleScanContainer extends ComponentContainer { private static final Logger LOG = LoggerFactory.getLogger(ModuleScanContainer.class); private final Project module; - private boolean sensorMode; + private DefaultAnalysisMode analysisMode; public ModuleScanContainer(ProjectScanContainer parent, Project module) { super(parent); this.module = module; - this.sensorMode = CoreProperties.ANALYSIS_MODE_SENSOR.equals(parent.getComponentByType(BootstrapProperties.class).property(CoreProperties.ANALYSIS_MODE)); + analysisMode = parent.getComponentByType(DefaultAnalysisMode.class); } @Override protected void doBeforeStart() { LOG.info("------------- Scan {}", module.getName()); addCoreComponents(); - if (!sensorMode) { + if (analysisMode.isDb()) { addDataBaseComponents(); } addExtensions(); @@ -135,11 +134,11 @@ public class ModuleScanContainer extends ComponentContainer { ModuleSettings moduleSettings = getComponentByType(ModuleSettings.class); module.setSettings(moduleSettings); - if (!sensorMode) { - add(DefaultPhaseExecutor.class); + if (analysisMode.isDb()) { + add(DatabaseModePhaseExecutor.class); } else { add(RuleFinderCompatibility.class, - PreviewPhaseExecutor.class); + DatabaseLessPhaseExecutor.class); } add( diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java index 6d52c45efad..851417e7705 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java @@ -25,7 +25,7 @@ import org.sonar.api.CoreProperties; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.config.Settings; import org.sonar.api.utils.MessageException; -import org.sonar.batch.bootstrap.AnalysisMode; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; import org.sonar.batch.bootstrap.GlobalSettings; import org.sonar.batch.protocol.input.ProjectRepositories; @@ -37,10 +37,10 @@ import java.util.List; public class ModuleSettings extends Settings { private final ProjectRepositories projectReferentials; - private AnalysisMode analysisMode; + private DefaultAnalysisMode analysisMode; public ModuleSettings(GlobalSettings batchSettings, ProjectDefinition project, ProjectRepositories projectReferentials, - AnalysisMode analysisMode) { + DefaultAnalysisMode analysisMode) { super(batchSettings.getDefinitions()); this.projectReferentials = projectReferentials; this.analysisMode = analysisMode; diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectLock.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectLock.java index aca2fd1de29..35fe0952eee 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectLock.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectLock.java @@ -27,7 +27,7 @@ import org.sonar.api.resources.Project; import org.sonar.api.utils.Semaphores; import org.sonar.api.utils.SonarException; import org.sonar.batch.ProjectTree; -import org.sonar.batch.bootstrap.AnalysisMode; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; import java.util.Locale; @@ -37,10 +37,10 @@ public class ProjectLock { private final Semaphores semaphores; private final ProjectTree projectTree; - private final AnalysisMode analysisMode; + private final DefaultAnalysisMode analysisMode; private final I18n i18n; - public ProjectLock(Semaphores semaphores, ProjectTree projectTree, AnalysisMode analysisMode, I18n i18n) { + public ProjectLock(Semaphores semaphores, ProjectTree projectTree, DefaultAnalysisMode analysisMode, I18n i18n) { this.semaphores = semaphores; this.projectTree = projectTree; this.analysisMode = analysisMode; diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java index 8ab80233084..7a76e684ae7 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java @@ -35,7 +35,7 @@ import org.sonar.batch.DefaultFileLinesContextFactory; import org.sonar.batch.DefaultResourceCreationLock; import org.sonar.batch.ProjectConfigurator; import org.sonar.batch.ProjectTree; -import org.sonar.batch.bootstrap.BootstrapProperties; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; import org.sonar.batch.bootstrap.ExtensionInstaller; import org.sonar.batch.bootstrap.ExtensionMatcher; import org.sonar.batch.bootstrap.ExtensionUtils; @@ -89,18 +89,19 @@ import org.sonar.core.test.TestablePerspectiveLoader; import org.sonar.core.user.DefaultUserFinder; public class ProjectScanContainer extends ComponentContainer { - private boolean sensorMode; + + private DefaultAnalysisMode analysisMode; public ProjectScanContainer(ComponentContainer taskContainer) { super(taskContainer); - sensorMode = CoreProperties.ANALYSIS_MODE_SENSOR.equals(taskContainer.getComponentByType(BootstrapProperties.class).property(CoreProperties.ANALYSIS_MODE)); + analysisMode = taskContainer.getComponentByType(DefaultAnalysisMode.class); } @Override protected void doBeforeStart() { projectBootstrap(); addBatchComponents(); - if (!sensorMode) { + if (analysisMode.isDb()) { addDataBaseComponents(); } fixMavenExecutor(); @@ -236,7 +237,7 @@ public class ProjectScanContainer extends ComponentContainer { protected void doAfterStart() { ProjectTree tree = getComponentByType(ProjectTree.class); scanRecursively(tree.getRootProject()); - if (sensorMode) { + if (analysisMode.isMediumTest()) { getComponentByType(ScanTaskObservers.class).notifyEndOfScanTask(); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectSettings.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectSettings.java index badac95a081..07194809cc8 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectSettings.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectSettings.java @@ -26,7 +26,7 @@ import org.sonar.api.batch.bootstrap.ProjectReactor; import org.sonar.api.config.PropertyDefinitions; import org.sonar.api.config.Settings; import org.sonar.api.utils.MessageException; -import org.sonar.batch.bootstrap.AnalysisMode; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; import org.sonar.batch.bootstrap.GlobalSettings; import org.sonar.batch.protocol.input.ProjectRepositories; @@ -36,10 +36,10 @@ public class ProjectSettings extends Settings { private final GlobalSettings globalSettings; private final ProjectRepositories projectReferentials; - private final AnalysisMode mode; + private final DefaultAnalysisMode mode; public ProjectSettings(ProjectReactor reactor, GlobalSettings globalSettings, PropertyDefinitions propertyDefinitions, - ProjectRepositories projectReferentials, AnalysisMode mode) { + ProjectRepositories projectReferentials, DefaultAnalysisMode mode) { super(propertyDefinitions); this.mode = mode; getEncryption().setPathToSecretKey(globalSettings.getString(CoreProperties.ENCRYPTION_SECRET_KEY_PATH)); diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileBuilder.java index b5941d83070..748410fea36 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileBuilder.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileBuilder.java @@ -28,7 +28,7 @@ import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import org.sonar.api.config.Settings; import org.sonar.api.scan.filesystem.PathResolver; -import org.sonar.batch.bootstrap.AnalysisMode; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; import org.sonar.batch.util.DeprecatedKeyUtils; import javax.annotation.CheckForNull; @@ -45,11 +45,11 @@ class InputFileBuilder { private final LanguageDetection langDetection; private final StatusDetection statusDetection; private final DefaultModuleFileSystem fs; - private final AnalysisMode analysisMode; + private final DefaultAnalysisMode analysisMode; private final Settings settings; InputFileBuilder(String moduleKey, PathResolver pathResolver, LanguageDetection langDetection, - StatusDetection statusDetection, DefaultModuleFileSystem fs, AnalysisMode analysisMode, Settings settings) { + StatusDetection statusDetection, DefaultModuleFileSystem fs, DefaultAnalysisMode analysisMode, Settings settings) { this.moduleKey = moduleKey; this.pathResolver = pathResolver; this.langDetection = langDetection; diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileBuilderFactory.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileBuilderFactory.java index ac8c79db2ab..c3dde447e01 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileBuilderFactory.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/InputFileBuilderFactory.java @@ -23,7 +23,7 @@ import org.sonar.api.BatchComponent; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.config.Settings; import org.sonar.api.scan.filesystem.PathResolver; -import org.sonar.batch.bootstrap.AnalysisMode; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; public class InputFileBuilderFactory implements BatchComponent { @@ -31,16 +31,16 @@ public class InputFileBuilderFactory implements BatchComponent { private final PathResolver pathResolver; private final LanguageDetectionFactory langDetectionFactory; private final StatusDetectionFactory statusDetectionFactory; - private final AnalysisMode analysisMode; + private final DefaultAnalysisMode analysisMode; private final Settings settings; public InputFileBuilderFactory(ProjectDefinition def, PathResolver pathResolver, LanguageDetectionFactory langDetectionFactory, - StatusDetectionFactory statusDetectionFactory, AnalysisMode analysisMode, Settings settings) { + StatusDetectionFactory statusDetectionFactory, DefaultAnalysisMode analysisMode, Settings settings) { this(def.getKeyWithBranch(), pathResolver, langDetectionFactory, statusDetectionFactory, analysisMode, settings); } private InputFileBuilderFactory(String effectiveKey, PathResolver pathResolver, LanguageDetectionFactory langDetectionFactory, - StatusDetectionFactory statusDetectionFactory, AnalysisMode analysisMode, Settings settings) { + StatusDetectionFactory statusDetectionFactory, DefaultAnalysisMode analysisMode, Settings settings) { this.moduleKey = effectiveKey; this.pathResolver = pathResolver; this.langDetectionFactory = langDetectionFactory; diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReports.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReports.java index 803871d2bc0..986ba12d7e6 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReports.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReports.java @@ -20,20 +20,20 @@ package org.sonar.batch.scan.report; import org.sonar.api.BatchComponent; -import org.sonar.batch.bootstrap.AnalysisMode; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; public class IssuesReports implements BatchComponent { - private final AnalysisMode analysisMode; + private final DefaultAnalysisMode analysisMode; private final Reporter[] reporters; - public IssuesReports(AnalysisMode analysisMode, Reporter... reporters) { + public IssuesReports(DefaultAnalysisMode analysisMode, Reporter... reporters) { this.reporters = reporters; this.analysisMode = analysisMode; } public void execute() { - if (analysisMode.isPreview() || analysisMode.isSensorMode()) { + if (analysisMode.isPreview() || analysisMode.isMediumTest()) { for (Reporter reporter : reporters) { reporter.execute(); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/ProjectLinksSensor.java b/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/ProjectLinksSensor.java new file mode 100644 index 00000000000..c04d0f5cc5e --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/ProjectLinksSensor.java @@ -0,0 +1,79 @@ +/* + * 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.batch.scan.sensor; + +import org.apache.commons.lang.StringUtils; +import org.sonar.api.CoreProperties; +import org.sonar.api.batch.AnalysisMode; +import org.sonar.api.batch.Sensor; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.config.Settings; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.ProjectLink; +import org.sonar.core.i18n.DefaultI18n; + +import java.util.Locale; + +public class ProjectLinksSensor implements Sensor { + + private Settings settings; + private DefaultI18n defaultI18n; + private AnalysisMode analysisMode; + + public ProjectLinksSensor(Settings settings, DefaultI18n defaultI18n, AnalysisMode analysisMode) { + this.settings = settings; + this.defaultI18n = defaultI18n; + this.analysisMode = analysisMode; + } + + @Override + public boolean shouldExecuteOnProject(Project project) { + return !analysisMode.isPreview(); + } + + @Override + public void analyse(Project project, SensorContext context) { + handleLink(context, CoreProperties.LINKS_HOME_PAGE); + handleLink(context, CoreProperties.LINKS_CI); + handleLink(context, CoreProperties.LINKS_ISSUE_TRACKER); + handleLink(context, CoreProperties.LINKS_SOURCES); + handleLink(context, CoreProperties.LINKS_SOURCES_DEV); + } + + private void handleLink(SensorContext context, String linkProperty) { + String home = settings.getString(linkProperty); + String linkType = StringUtils.substringAfterLast(linkProperty, "."); + String name = defaultI18n.message(Locale.getDefault(), "project_links." + linkType, linkProperty); + updateLink(context, linkType, name, home); + } + + private void updateLink(SensorContext context, String key, String name, String url) { + if (StringUtils.isBlank(url)) { + context.deleteLink(key); + } else { + context.saveLink(new ProjectLink(key, name, url)); + } + } + + @Override + public String toString() { + return getClass().getSimpleName(); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/VersionEventsSensor.java b/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/VersionEventsSensor.java new file mode 100644 index 00000000000..351eca3facd --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/VersionEventsSensor.java @@ -0,0 +1,70 @@ +/* + * 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.batch.scan.sensor; + +import org.apache.commons.lang.StringUtils; +import org.sonar.api.batch.AnalysisMode; +import org.sonar.api.batch.Event; +import org.sonar.api.batch.RequiresDB; +import org.sonar.api.batch.Sensor; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.resources.Project; + +import java.util.Iterator; + +@RequiresDB +public class VersionEventsSensor implements Sensor { + + private final AnalysisMode analysisMode; + + public VersionEventsSensor(AnalysisMode analysisMode) { + this.analysisMode = analysisMode; + } + + @Override + public boolean shouldExecuteOnProject(Project project) { + return !analysisMode.isPreview(); + } + + @Override + public void analyse(Project project, SensorContext context) { + if (StringUtils.isBlank(project.getAnalysisVersion())) { + return; + } + deleteDeprecatedEvents(project, context); + context.createEvent(project, project.getAnalysisVersion(), null, Event.CATEGORY_VERSION, null); + } + + private void deleteDeprecatedEvents(Project project, SensorContext context) { + String version = project.getAnalysisVersion(); + for (Iterator it = context.getEvents(project).iterator(); it.hasNext();) { + Event event = it.next(); + if (event.isVersionCategory() && version.equals(event.getName())) { + it.remove(); + context.deleteEvent(event); + } + } + } + + @Override + public String toString() { + return getClass().getSimpleName(); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/package-info.java new file mode 100644 index 00000000000..b8fb1b58126 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/sensor/package-info.java @@ -0,0 +1,23 @@ +/* + * 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. + */ +@ParametersAreNonnullByDefault +package org.sonar.batch.scan.sensor; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultIssueValueCoder.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultIssueValueCoder.java deleted file mode 100644 index 53b7cb34b05..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultIssueValueCoder.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch.scan2; - -import com.persistit.Value; -import com.persistit.encoding.CoderContext; -import com.persistit.encoding.ValueCoder; -import org.sonar.api.batch.fs.InputDir; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.InputPath; -import org.sonar.api.batch.fs.internal.DefaultInputDir; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.sensor.issue.Issue.Severity; -import org.sonar.api.batch.sensor.issue.internal.DefaultIssue; -import org.sonar.api.rule.RuleKey; -import org.sonar.batch.scan.filesystem.InputPathCache; - -class DefaultIssueValueCoder implements ValueCoder { - - private final InputPathCache inputPathCache; - - public DefaultIssueValueCoder(InputPathCache inputPathCache) { - this.inputPathCache = inputPathCache; - } - - @Override - public void put(Value value, Object object, CoderContext context) { - DefaultIssue issue = (DefaultIssue) object; - value.putString(issue.key()); - InputPath inputPath = issue.inputPath(); - if (inputPath != null) { - if (inputPath instanceof InputDir) { - value.put(0); - value.putString(((DefaultInputDir) inputPath).moduleKey()); - value.putString(inputPath.relativePath()); - } else { - value.put(1); - value.putString(((DefaultInputFile) inputPath).moduleKey()); - value.putString(inputPath.relativePath()); - value.put(issue.line()); - } - } else { - value.putNull(); - } - value.put(issue.message()); - value.put(issue.effortToFix()); - value.put(issue.ruleKey().repository()); - value.put(issue.ruleKey().rule()); - Severity overridenSeverity = issue.overridenSeverity(); - if (overridenSeverity == null) { - value.putNull(); - } else { - value.put(overridenSeverity.ordinal()); - } - } - - @Override - public Object get(Value value, Class clazz, CoderContext context) { - DefaultIssue newIssue = new DefaultIssue(); - newIssue.withKey(value.getString()); - if (value.isNull(true)) { - newIssue.onProject(); - } else { - int type = value.getInt(); - String moduleKey = value.getString(); - String relativePath = value.getString(); - if (type == 0) { - InputDir dir = inputPathCache.getDir(moduleKey, relativePath); - newIssue.onDir(dir); - } else { - InputFile f = inputPathCache.getFile(moduleKey, relativePath); - newIssue.onFile(f); - if (!value.isNull(true)) { - newIssue.atLine(value.getInt()); - } - } - } - newIssue.message(value.getString()); - newIssue.effortToFix(value.isNull(true) ? null : value.getDouble()); - String repo = value.getString(); - String rule = value.getString(); - newIssue.ruleKey(RuleKey.of(repo, rule)); - newIssue.overrideSeverity(value.isNull(true) ? null : Severity.values()[value.getInt()]); - return newIssue; - } - -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultMeasureValueCoder.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultMeasureValueCoder.java deleted file mode 100644 index e0beb814130..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultMeasureValueCoder.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch.scan2; - -import com.persistit.Value; -import com.persistit.encoding.CoderContext; -import com.persistit.encoding.ValueCoder; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.measure.Metric; -import org.sonar.api.batch.measure.MetricFinder; -import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; -import org.sonar.batch.scan.filesystem.InputPathCache; - -import java.io.Serializable; - -class DefaultMeasureValueCoder implements ValueCoder { - - private final MetricFinder metricFinder; - private final InputPathCache inputPathCache; - - public DefaultMeasureValueCoder(MetricFinder metricFinder, InputPathCache inputPathCache) { - this.metricFinder = metricFinder; - this.inputPathCache = inputPathCache; - } - - @Override - public void put(Value value, Object object, CoderContext context) { - DefaultMeasure m = (DefaultMeasure) object; - DefaultInputFile inputFile = (DefaultInputFile) m.inputFile(); - if (inputFile != null) { - value.putString(inputFile.moduleKey()); - value.putString(inputFile.relativePath()); - } else { - value.putNull(); - } - value.putString(m.metric().key()); - value.put(m.value()); - } - - @Override - public Object get(Value value, Class clazz, CoderContext context) { - DefaultMeasure newMeasure = new DefaultMeasure(null); - String moduleKey = value.getString(); - if (moduleKey != null) { - String relativePath = value.getString(); - InputFile f = inputPathCache.getFile(moduleKey, relativePath); - newMeasure.onFile(f); - } else { - newMeasure.onProject(); - } - Metric m = metricFinder.findByKey(value.getString()); - newMeasure.forMetric(m); - newMeasure.withValue((Serializable) value.get()); - return newMeasure; - } - -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/ModuleScanExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/ModuleScanExecutor.java deleted file mode 100644 index 943f93e1db0..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/ModuleScanExecutor.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch.scan2; - -import com.google.common.collect.Lists; -import org.sonar.api.batch.sensor.SensorContext; -import org.sonar.batch.issue.ignore.scanner.IssueExclusionsLoader; -import org.sonar.batch.rule.QProfileVerifier; -import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; -import org.sonar.batch.scan.filesystem.FileSystemLogger; - -import java.util.Collection; - -public final class ModuleScanExecutor { - - private final SensorsExecutor analyzersExecutor; - private final SensorContext analyzerContext; - private final FileSystemLogger fsLogger; - private final DefaultModuleFileSystem fs; - private final QProfileVerifier profileVerifier; - private final IssueExclusionsLoader issueExclusionsLoader; - - public ModuleScanExecutor(SensorsExecutor analyzersExecutor, - SensorContext analyzerContext, - FileSystemLogger fsLogger, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier, - IssueExclusionsLoader issueExclusionsLoader) { - this.analyzersExecutor = analyzersExecutor; - this.analyzerContext = analyzerContext; - this.fsLogger = fsLogger; - this.fs = fs; - this.profileVerifier = profileVerifier; - this.issueExclusionsLoader = issueExclusionsLoader; - } - - public static Collection getPhaseClasses() { - return Lists.newArrayList(SensorsExecutor.class); - } - - /** - * Executed on each module - */ - public void execute() { - fsLogger.log(); - - // Index and lock the filesystem - fs.index(); - - // Log detected languages and their profiles after FS is indexed and languages detected - profileVerifier.execute(); - - // Initialize issue exclusions - issueExclusionsLoader.execute(); - - analyzersExecutor.execute(analyzerContext); - - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/SensorsExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/SensorsExecutor.java deleted file mode 100644 index dc68e4d41f4..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan2/SensorsExecutor.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch.scan2; - -import org.sonar.batch.sensor.AnalyzerOptimizer; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.BatchComponent; -import org.sonar.api.batch.sensor.Sensor; -import org.sonar.api.batch.sensor.SensorContext; -import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; -import org.sonar.batch.bootstrap.BatchExtensionDictionnary; - -import java.util.Collection; - -public class SensorsExecutor implements BatchComponent { - - private static final Logger LOG = LoggerFactory.getLogger(SensorsExecutor.class); - - private BatchExtensionDictionnary selector; - private AnalyzerOptimizer optimizer; - - public SensorsExecutor(BatchExtensionDictionnary selector, AnalyzerOptimizer optimizer) { - this.selector = selector; - this.optimizer = optimizer; - } - - public void execute(SensorContext context) { - Collection analyzers = selector.select(Sensor.class, null, true, null); - - for (Sensor analyzer : analyzers) { - - DefaultSensorDescriptor descriptor = new DefaultSensorDescriptor(); - analyzer.describe(descriptor); - - if (!optimizer.shouldExecute(descriptor)) { - continue; - } - - LOG.info("Execute sensor: " + descriptor.name()); - - executeSensor(context, analyzer); - } - - } - - private void executeSensor(SensorContext context, Sensor analyzer) { - analyzer.execute(context); - } - -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scm/ScmConfiguration.java b/sonar-batch/src/main/java/org/sonar/batch/scm/ScmConfiguration.java index 468b29e04a5..d600a3d4ba2 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scm/ScmConfiguration.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scm/ScmConfiguration.java @@ -25,19 +25,18 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.BatchComponent; import org.sonar.api.CoreProperties; +import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.InstantiationStrategy; import org.sonar.api.batch.bootstrap.ProjectReactor; import org.sonar.api.batch.scm.ScmProvider; import org.sonar.api.config.Settings; import org.sonar.batch.phases.Phases; -import org.sonar.core.DryRunIncompatible; import javax.annotation.Nullable; import java.util.LinkedHashMap; import java.util.Map; -@DryRunIncompatible @InstantiationStrategy(InstantiationStrategy.PER_BATCH) public final class ScmConfiguration implements BatchComponent, Startable { private static final Logger LOG = LoggerFactory.getLogger(ScmConfiguration.class); @@ -46,11 +45,13 @@ public final class ScmConfiguration implements BatchComponent, Startable { private final Settings settings; private final Map providerPerKey = new LinkedHashMap(); private final Phases phases; + private final AnalysisMode analysisMode; private ScmProvider provider; - public ScmConfiguration(ProjectReactor projectReactor, Settings settings, @Nullable Phases phases, ScmProvider... providers) { + public ScmConfiguration(ProjectReactor projectReactor, AnalysisMode analysisMode, Settings settings, @Nullable Phases phases, ScmProvider... providers) { this.projectReactor = projectReactor; + this.analysisMode = analysisMode; this.settings = settings; this.phases = phases; for (ScmProvider scmProvider : providers) { @@ -59,22 +60,22 @@ public final class ScmConfiguration implements BatchComponent, Startable { } // Scan 2 - public ScmConfiguration(ProjectReactor projectReactor, Settings settings, ScmProvider... providers) { - this(projectReactor, settings, null, providers); + public ScmConfiguration(ProjectReactor projectReactor, AnalysisMode analysisMode, Settings settings, ScmProvider... providers) { + this(projectReactor, analysisMode, settings, null, providers); } - public ScmConfiguration(ProjectReactor projectReactor, Settings settings, Phases phases) { - this(projectReactor, settings, phases, new ScmProvider[0]); + public ScmConfiguration(ProjectReactor projectReactor, AnalysisMode analysisMode, Settings settings, Phases phases) { + this(projectReactor, analysisMode, settings, phases, new ScmProvider[0]); } // Scan2 - public ScmConfiguration(ProjectReactor projectReactor, Settings settings) { - this(projectReactor, settings, null, new ScmProvider[0]); + public ScmConfiguration(ProjectReactor projectReactor, AnalysisMode analysisMode, Settings settings) { + this(projectReactor, analysisMode, settings, null, new ScmProvider[0]); } @Override public void start() { - if (phases != null && !phases.isEnabled(Phases.Phase.SENSOR)) { + if (analysisMode.isPreview() || (phases != null && !phases.isEnabled(Phases.Phase.SENSOR))) { return; } if (isDisabled()) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/scm/ScmSensor.java b/sonar-batch/src/main/java/org/sonar/batch/scm/ScmSensor.java index 77fcd34cb20..6e4207d410b 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scm/ScmSensor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scm/ScmSensor.java @@ -35,12 +35,10 @@ import org.sonar.api.measures.CoreMetrics; import org.sonar.api.utils.TimeProfiler; import org.sonar.batch.protocol.input.FileData; import org.sonar.batch.protocol.input.ProjectRepositories; -import org.sonar.core.DryRunIncompatible; import java.util.LinkedList; import java.util.List; -@DryRunIncompatible public final class ScmSensor implements Sensor { private static final Logger LOG = LoggerFactory.getLogger(ScmSensor.class); @@ -60,7 +58,8 @@ public final class ScmSensor implements Sensor { @Override public void describe(SensorDescriptor descriptor) { - descriptor.name("SCM Sensor"); + descriptor.name("SCM Sensor") + .disabledInPreview(); } @Override diff --git a/sonar-batch/src/main/java/org/sonar/batch/sensor/AnalyzerOptimizer.java b/sonar-batch/src/main/java/org/sonar/batch/sensor/AnalyzerOptimizer.java index ed085a73db9..f114e4a24e7 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/sensor/AnalyzerOptimizer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/sensor/AnalyzerOptimizer.java @@ -22,6 +22,7 @@ package org.sonar.batch.sensor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.BatchComponent; +import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.fs.FilePredicate; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.rule.ActiveRules; @@ -35,11 +36,13 @@ public class AnalyzerOptimizer implements BatchComponent { private final FileSystem fs; private final ActiveRules activeRules; private final Settings settings; + private final AnalysisMode analysisMode; - public AnalyzerOptimizer(FileSystem fs, ActiveRules activeRules, Settings settings) { + public AnalyzerOptimizer(FileSystem fs, ActiveRules activeRules, Settings settings, AnalysisMode analysisMode) { this.fs = fs; this.activeRules = activeRules; this.settings = settings; + this.analysisMode = analysisMode; } /** @@ -58,6 +61,10 @@ public class AnalyzerOptimizer implements BatchComponent { LOG.debug("'{}' skipped because one of the required properties is missing", descriptor.name()); return false; } + if (descriptor.isDisabledInPreview() && analysisMode.isPreview()) { + LOG.debug("'{}' skipped in preview mode", descriptor.name()); + return false; + } return true; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java index e02fe9e1f90..d4ed8b2972b 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java +++ b/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java @@ -20,6 +20,7 @@ package org.sonar.batch.sensor; import com.google.common.base.Preconditions; +import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultInputFile; @@ -70,12 +71,14 @@ public class DefaultSensorContext implements SensorContext { private final BlockCache blockCache; private final DuplicationCache duplicationCache; private final SensorStorage sensorStorage; + private final AnalysisMode analysisMode; - public DefaultSensorContext(Settings settings, FileSystem fs, ActiveRules activeRules, ComponentDataCache componentDataCache, + public DefaultSensorContext(Settings settings, FileSystem fs, ActiveRules activeRules, AnalysisMode analysisMode, ComponentDataCache componentDataCache, BlockCache blockCache, DuplicationCache duplicationCache, SensorStorage sensorStorage) { this.settings = settings; this.fs = fs; this.activeRules = activeRules; + this.analysisMode = analysisMode; this.componentDataCache = componentDataCache; this.blockCache = blockCache; this.duplicationCache = duplicationCache; @@ -97,6 +100,11 @@ public class DefaultSensorContext implements SensorContext { return activeRules; } + @Override + public AnalysisMode analysisMode() { + return analysisMode; + } + @Override public NewMeasure newMeasure() { return new DefaultMeasure(sensorStorage); diff --git a/sonar-batch/src/test/java/org/sonar/batch/ServerMetadataTest.java b/sonar-batch/src/test/java/org/sonar/batch/ServerMetadataTest.java deleted file mode 100644 index 4c15e5de14d..00000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/ServerMetadataTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch; - -import org.junit.Test; -import org.sonar.api.utils.DateUtils; - -import java.util.Date; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class ServerMetadataTest { - @Test - public void should_proxy_target() { - org.sonar.batch.bootstrap.ServerMetadata client = mock(org.sonar.batch.bootstrap.ServerMetadata.class); - when(client.getId()).thenReturn("id1"); - when(client.getPermanentServerId()).thenReturn("pid1"); - Date startedAt = DateUtils.parseDate("2012-05-18"); - when(client.getStartedAt()).thenReturn(startedAt); - when(client.getURL()).thenReturn("http://foo"); - when(client.getVersion()).thenReturn("v1"); - - ServerMetadata metadata = new ServerMetadata(client); - - assertThat(metadata.getId()).isEqualTo("id1"); - assertThat(metadata.getPermanentServerId()).isEqualTo("pid1"); - assertThat(metadata.getStartedAt()).isEqualTo(startedAt); - assertThat(metadata.getURL()).isEqualTo("http://foo"); - assertThat(metadata.getVersion()).isEqualTo("v1"); - - } -} diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/AnalysisModeTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/AnalysisModeTest.java deleted file mode 100644 index 9863d9421e1..00000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/AnalysisModeTest.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch.bootstrap; - -import com.google.common.collect.ImmutableMap; -import org.junit.Test; -import org.sonar.api.CoreProperties; - -import java.util.Collections; - -import static org.assertj.core.api.Assertions.assertThat; - -public class AnalysisModeTest { - - @Test - public void regular_analysis_by_default() { - AnalysisMode mode = new AnalysisMode(new BootstrapProperties(Collections.emptyMap())); - - assertThat(mode.isPreview()).isFalse(); - assertThat(mode.isIncremental()).isFalse(); - - BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, "pouet")); - mode = new AnalysisMode(bootstrapProps); - - assertThat(mode.isPreview()).isFalse(); - assertThat(mode.isIncremental()).isFalse(); - } - - @Test - public void support_analysis_mode() { - BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_ANALYSIS)); - AnalysisMode mode = new AnalysisMode(bootstrapProps); - - assertThat(mode.isPreview()).isFalse(); - assertThat(mode.isIncremental()).isFalse(); - } - - @Test - public void support_preview_mode() { - BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_PREVIEW)); - AnalysisMode mode = new AnalysisMode(bootstrapProps); - - assertThat(mode.isPreview()).isTrue(); - assertThat(mode.isIncremental()).isFalse(); - - assertThat(bootstrapProps.property(CoreProperties.DRY_RUN)).isEqualTo("true"); - } - - @Test - public void support_incremental_mode() { - BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_INCREMENTAL)); - AnalysisMode mode = new AnalysisMode(bootstrapProps); - - assertThat(mode.isPreview()).isTrue(); - assertThat(mode.isIncremental()).isTrue(); - - assertThat(bootstrapProps.property(CoreProperties.DRY_RUN)).isEqualTo("true"); - } - - @Test - public void support_deprecated_dryrun_property() { - BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.DRY_RUN, "true")); - AnalysisMode mode = new AnalysisMode(bootstrapProps); - - assertThat(mode.isPreview()).isTrue(); - assertThat(mode.isIncremental()).isFalse(); - } - - @Test - public void should_get_default_preview_read_timeout() { - BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_PREVIEW)); - AnalysisMode mode = new AnalysisMode(bootstrapProps); - - assertThat(mode.getPreviewReadTimeoutSec()).isEqualTo(60); - } - - @Test - public void should_download_database_with_deprecated_overriden_timeout() { - BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.DRY_RUN, "true", CoreProperties.DRY_RUN_READ_TIMEOUT_SEC, "80")); - AnalysisMode mode = new AnalysisMode(bootstrapProps); - - assertThat(mode.getPreviewReadTimeoutSec()).isEqualTo(80); - } - - @Test - public void should_download_database_with_overriden_timeout() { - BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_PREVIEW, - CoreProperties.PREVIEW_READ_TIMEOUT_SEC, "80")); - AnalysisMode mode = new AnalysisMode(bootstrapProps); - - assertThat(mode.getPreviewReadTimeoutSec()).isEqualTo(80); - } -} diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchDatabaseTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchDatabaseTest.java index c2db3bf384e..ed3d0dc1f06 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchDatabaseTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchDatabaseTest.java @@ -30,7 +30,7 @@ import static org.mockito.Mockito.mock; public class BatchDatabaseTest { @Test public void should_init_at_least_two_connections() { - BatchDatabase db = new BatchDatabase(new Settings(), mock(JdbcDriverHolder.class), mock(PreviewDatabase.class)); + BatchDatabase db = new BatchDatabase(new Settings(), mock(JdbcDriverHolder.class)); Properties props = new Properties(); db.doCompleteProperties(props); diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java index 9563fafd318..d0c959abb87 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java @@ -46,13 +46,13 @@ public class BatchPluginRepositoryTest { public TemporaryFolder temp = new TemporaryFolder(); private BatchPluginRepository repository; - private AnalysisMode mode; + private DefaultAnalysisMode mode; private FileCache cache; private File userHome; @Before public void before() throws IOException { - mode = mock(AnalysisMode.class); + mode = mock(DefaultAnalysisMode.class); userHome = temp.newFolder(); cache = new FileCacheBuilder().setUserHome(userHome).build(); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapContainerTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapContainerTest.java deleted file mode 100644 index 8a4ca2f24b6..00000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapContainerTest.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch.bootstrap; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; -import org.junit.Test; -import org.sonar.api.BatchExtension; -import org.sonar.api.Plugin; -import org.sonar.api.SonarPlugin; -import org.sonar.api.platform.PluginMetadata; -import org.sonar.api.utils.TempFolder; -import org.sonar.core.config.Logback; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -public class BootstrapContainerTest { - @Test - public void should_add_components() { - BootstrapContainer container = BootstrapContainer.create(Collections.emptyMap(), Collections.emptyList()); - container.doBeforeStart(); - - assertThat(container.getComponentByType(Logback.class)).isNotNull(); - assertThat(container.getComponentByType(TempFolder.class)).isNotNull(); - } - - @Test - public void should_add_bootstrap_extensions() { - BootstrapContainer container = BootstrapContainer.create(Collections.emptyMap(), Lists.newArrayList(Foo.class, new Bar())); - container.doBeforeStart(); - - assertThat(container.getComponentByType(Foo.class)).isNotNull(); - assertThat(container.getComponentByType(Bar.class)).isNotNull(); - } - - @Test - public void should_install_plugins() { - PluginMetadata metadata = mock(PluginMetadata.class); - FakePlugin plugin = new FakePlugin(); - BatchPluginRepository pluginRepository = mock(BatchPluginRepository.class); - when(pluginRepository.getPluginsByMetadata()).thenReturn(ImmutableMap.of( - metadata, plugin - )); - - BootstrapContainer container = spy(BootstrapContainer.create(Collections.emptyMap(), Lists.newArrayList(pluginRepository))); - doNothing().when(container).executeTask(Collections.emptyMap()); - container.doAfterStart(); - - assertThat(container.getComponentsByType(Plugin.class)).containsOnly(plugin); - } - - public static class Foo implements BatchExtension { - - } - - public static class Bar implements BatchExtension { - - } - - public static class FakePlugin extends SonarPlugin { - - public List getExtensions() { - return Arrays.asList(Foo.class, Bar.class); - } - } -} diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/DatabaseCompatibilityTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/DatabaseCompatibilityTest.java index 98c9391d5be..97402b8a913 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/DatabaseCompatibilityTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/DatabaseCompatibilityTest.java @@ -40,17 +40,17 @@ public class DatabaseCompatibilityTest { public ExpectedException thrown = ExpectedException.none(); DatabaseVersion databaseVersion; - ServerMetadata server; + ServerClient server; Settings settings; PropertiesDao propertiesDao; - private AnalysisMode mode; + private DefaultAnalysisMode mode; @Before public void init() { - server = mock(ServerMetadata.class); + server = mock(ServerClient.class); when(server.getURL()).thenReturn("http://localhost:9000"); - when(server.getServerId()).thenReturn("123456"); + when(server.request("/api/server")).thenReturn("{\"id\":\"123456\",\"version\":\"3.1\",\"status\":\"UP\"}"); settings = new Settings(); settings.setProperty(DatabaseProperties.PROP_URL, "jdbc:postgresql://localhost/foo"); @@ -59,7 +59,7 @@ public class DatabaseCompatibilityTest { propertiesDao = mock(PropertiesDao.class); when(propertiesDao.selectGlobalProperty(CoreProperties.SERVER_ID)).thenReturn(new PropertyDto().setValue("123456")); - mode = mock(AnalysisMode.class); + mode = mock(DefaultAnalysisMode.class); databaseVersion = mock(DatabaseVersion.class); } @@ -110,7 +110,7 @@ public class DatabaseCompatibilityTest { @Test public void shouldFailIfCantGetServerId() throws Exception { - when(server.getServerId()).thenThrow(new IllegalStateException()); + when(server.request("/api/server")).thenThrow(new IllegalStateException()); thrown.expect(IllegalStateException.class); diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/DefaultAnalysisModeTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/DefaultAnalysisModeTest.java new file mode 100644 index 00000000000..f4d129bb4ff --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/DefaultAnalysisModeTest.java @@ -0,0 +1,85 @@ +/* + * 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.batch.bootstrap; + +import com.google.common.collect.ImmutableMap; +import org.junit.Test; +import org.sonar.api.CoreProperties; + +import java.util.Collections; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DefaultAnalysisModeTest { + + @Test + public void regular_analysis_by_default() { + DefaultAnalysisMode mode = new DefaultAnalysisMode(new BootstrapProperties(Collections.emptyMap())); + + assertThat(mode.isPreview()).isFalse(); + assertThat(mode.isIncremental()).isFalse(); + + BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, "pouet")); + mode = new DefaultAnalysisMode(bootstrapProps); + + assertThat(mode.isPreview()).isFalse(); + assertThat(mode.isIncremental()).isFalse(); + } + + @Test + public void support_analysis_mode() { + BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_ANALYSIS)); + DefaultAnalysisMode mode = new DefaultAnalysisMode(bootstrapProps); + + assertThat(mode.isPreview()).isFalse(); + assertThat(mode.isIncremental()).isFalse(); + } + + @Test + public void support_preview_mode() { + BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_PREVIEW)); + DefaultAnalysisMode mode = new DefaultAnalysisMode(bootstrapProps); + + assertThat(mode.isPreview()).isTrue(); + assertThat(mode.isIncremental()).isFalse(); + + assertThat(bootstrapProps.property(CoreProperties.DRY_RUN)).isEqualTo("true"); + } + + @Test + public void support_incremental_mode() { + BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_INCREMENTAL)); + DefaultAnalysisMode mode = new DefaultAnalysisMode(bootstrapProps); + + assertThat(mode.isPreview()).isTrue(); + assertThat(mode.isIncremental()).isTrue(); + + assertThat(bootstrapProps.property(CoreProperties.DRY_RUN)).isEqualTo("true"); + } + + @Test + public void support_deprecated_dryrun_property() { + BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.DRY_RUN, "true")); + DefaultAnalysisMode mode = new DefaultAnalysisMode(bootstrapProps); + + assertThat(mode.isPreview()).isTrue(); + assertThat(mode.isIncremental()).isFalse(); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ExtensionInstallerTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ExtensionInstallerTest.java index 401d2da433f..c6bc80c9862 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ExtensionInstallerTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ExtensionInstallerTest.java @@ -42,7 +42,7 @@ import static org.mockito.Mockito.when; public class ExtensionInstallerTest { - private AnalysisMode mode; + private DefaultAnalysisMode mode; PluginMetadata metadata = mock(PluginMetadata.class); Map newPlugin(final Object... extensions) { @@ -59,7 +59,7 @@ public class ExtensionInstallerTest { @Before public void setUp() throws Exception { - mode = mock(AnalysisMode.class); + mode = mock(DefaultAnalysisMode.class); } @Test diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ExtensionUtilsTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ExtensionUtilsTest.java index 23b0196947b..95138b2e904 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ExtensionUtilsTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ExtensionUtilsTest.java @@ -22,8 +22,8 @@ package org.sonar.batch.bootstrap; import org.junit.Test; import org.sonar.api.BatchExtension; import org.sonar.api.ServerExtension; -import org.sonar.core.DryRunIncompatible; import org.sonar.api.batch.InstantiationStrategy; +import org.sonar.api.batch.RequiresDB; import org.sonar.api.batch.SupportedEnvironment; import org.sonar.batch.bootstrapper.EnvironmentInformation; @@ -80,11 +80,11 @@ public class ExtensionUtilsTest { } @Test - public void shouldSupportDryRun() { - assertThat(ExtensionUtils.supportsPreview(BatchService.class)).isTrue(); - assertThat(ExtensionUtils.supportsPreview(new BatchService())).isTrue(); - assertThat(ExtensionUtils.supportsPreview(PersistentService.class)).isFalse(); - assertThat(ExtensionUtils.supportsPreview(new PersistentService())).isFalse(); + public void shouldRequiresDB() { + assertThat(ExtensionUtils.requiresDB(BatchService.class)).isFalse(); + assertThat(ExtensionUtils.requiresDB(new BatchService())).isFalse(); + assertThat(ExtensionUtils.requiresDB(PersistentService.class)).isTrue(); + assertThat(ExtensionUtils.requiresDB(new PersistentService())).isTrue(); } @InstantiationStrategy(InstantiationStrategy.PER_BATCH) @@ -115,7 +115,7 @@ public class ExtensionUtilsTest { } - @DryRunIncompatible + @RequiresDB public static class PersistentService implements BatchExtension { } diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/GlobalContainerTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/GlobalContainerTest.java new file mode 100644 index 00000000000..9fce2c7a951 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/GlobalContainerTest.java @@ -0,0 +1,91 @@ +/* + * 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.batch.bootstrap; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import org.junit.Test; +import org.sonar.api.BatchExtension; +import org.sonar.api.Plugin; +import org.sonar.api.SonarPlugin; +import org.sonar.api.platform.PluginMetadata; +import org.sonar.api.utils.TempFolder; +import org.sonar.core.config.Logback; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +public class GlobalContainerTest { + @Test + public void should_add_components() { + GlobalContainer container = GlobalContainer.create(Collections.emptyMap(), Collections.emptyList()); + container.doBeforeStart(); + + assertThat(container.getComponentByType(Logback.class)).isNotNull(); + assertThat(container.getComponentByType(TempFolder.class)).isNotNull(); + } + + @Test + public void should_add_bootstrap_extensions() { + GlobalContainer container = GlobalContainer.create(Collections.emptyMap(), Lists.newArrayList(Foo.class, new Bar())); + container.doBeforeStart(); + + assertThat(container.getComponentByType(Foo.class)).isNotNull(); + assertThat(container.getComponentByType(Bar.class)).isNotNull(); + } + + @Test + public void should_install_plugins() { + PluginMetadata metadata = mock(PluginMetadata.class); + FakePlugin plugin = new FakePlugin(); + BatchPluginRepository pluginRepository = mock(BatchPluginRepository.class); + when(pluginRepository.getPluginsByMetadata()).thenReturn(ImmutableMap.of( + metadata, plugin + )); + + GlobalContainer container = spy(GlobalContainer.create(Collections.emptyMap(), Lists.newArrayList(pluginRepository))); + doNothing().when(container).executeTask(Collections.emptyMap()); + container.doAfterStart(); + + assertThat(container.getComponentsByType(Plugin.class)).containsOnly(plugin); + } + + public static class Foo implements BatchExtension { + + } + + public static class Bar implements BatchExtension { + + } + + public static class FakePlugin extends SonarPlugin { + + public List getExtensions() { + return Arrays.asList(Foo.class, Bar.class); + } + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/GlobalSettingsTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/GlobalSettingsTest.java index 47bdb3e1db6..738bd0d5fa0 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/GlobalSettingsTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/GlobalSettingsTest.java @@ -41,13 +41,13 @@ public class GlobalSettingsTest { ProjectDefinition project = ProjectDefinition.create().setKey("struts"); BootstrapProperties bootstrapProps; - private AnalysisMode mode; + private DefaultAnalysisMode mode; @Before public void prepare() { globalRef = new GlobalRepositories(); bootstrapProps = new BootstrapProperties(Collections.emptyMap()); - mode = mock(AnalysisMode.class); + mode = mock(DefaultAnalysisMode.class); } @Test diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/JdbcDriverHolderTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/JdbcDriverHolderTest.java index c3c2ba86b8e..a5040b47f35 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/JdbcDriverHolderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/JdbcDriverHolderTest.java @@ -44,12 +44,12 @@ public class JdbcDriverHolderTest { public ExpectedException thrown = ExpectedException.none(); ClassLoader initialThreadClassloader; - private AnalysisMode mode; + private DefaultAnalysisMode mode; @Before public void before() { initialThreadClassloader = Thread.currentThread().getContextClassLoader(); - mode = mock(AnalysisMode.class); + mode = mock(DefaultAnalysisMode.class); } @After diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/PreviewDatabaseTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/PreviewDatabaseTest.java deleted file mode 100644 index 8be7e4a6fa3..00000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/PreviewDatabaseTest.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch.bootstrap; - -import org.apache.commons.lang.StringUtils; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; -import org.sonar.api.CoreProperties; -import org.sonar.api.config.Settings; -import org.sonar.api.database.DatabaseProperties; -import org.sonar.api.utils.HttpDownloader; -import org.sonar.api.utils.SonarException; -import org.sonar.api.utils.TempFolder; - -import java.io.File; -import java.net.SocketTimeoutException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; - -public class PreviewDatabaseTest { - Settings settings; - ServerClient server = mock(ServerClient.class); - TempFolder tempUtils = mock(TempFolder.class); - File databaseFile; - private AnalysisMode mode; - - @Rule - public ExpectedException thrown = ExpectedException.none(); - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - @Before - public void setUp() throws Exception { - databaseFile = temp.newFile("preview.h2.db"); - when(tempUtils.newFile("preview", ".h2.db")).thenReturn(databaseFile); - settings = new Settings(); - settings.setProperty(CoreProperties.PROJECT_KEY_PROPERTY, "group:project"); - - mode = mock(AnalysisMode.class); - when(mode.isPreview()).thenReturn(true); - when(mode.getPreviewReadTimeoutSec()).thenReturn(60); - } - - @Test - public void should_be_disabled_if_not_preview() { - when(mode.isPreview()).thenReturn(false); - new PreviewDatabase(settings, server, tempUtils, mode).start(); - - verifyZeroInteractions(tempUtils, server); - } - - @Test - public void should_download_database() { - new PreviewDatabase(settings, server, tempUtils, mode).start(); - - verify(server).download("/batch_bootstrap/db?project=group:project", databaseFile, 60000); - } - - @Test - public void should_download_database_on_branch() { - settings.setProperty(CoreProperties.PROJECT_BRANCH_PROPERTY, "mybranch"); - new PreviewDatabase(settings, server, tempUtils, mode).start(); - - verify(server).download("/batch_bootstrap/db?project=group:project:mybranch", databaseFile, 60000); - } - - @Test - public void should_replace_database_settings() { - new PreviewDatabase(settings, server, tempUtils, mode).start(); - - assertThat(settings.getString(DatabaseProperties.PROP_DIALECT)).isEqualTo("h2"); - assertThat(settings.getString(DatabaseProperties.PROP_DRIVER)).isEqualTo("org.h2.Driver"); - assertThat(settings.getString(DatabaseProperties.PROP_USER)).isEqualTo("sonar"); - assertThat(settings.getString(DatabaseProperties.PROP_PASSWORD)).isEqualTo("sonar"); - assertThat(settings.getString(DatabaseProperties.PROP_URL)).isEqualTo("jdbc:h2:" + StringUtils.removeEnd(databaseFile.getAbsolutePath(), ".h2.db")); - } - - @Test - public void should_fail_on_invalid_role() { - doThrow(new SonarException(new HttpDownloader.HttpException(null, 401))).when(server).download("/batch_bootstrap/db?project=group:project", databaseFile, 60000); - - thrown.expect(SonarException.class); - thrown.expectMessage("You don't have access rights to project [group:project]"); - - new PreviewDatabase(settings, server, tempUtils, mode).start(); - } - - @Test - public void should_fail_on_read_timeout() { - doThrow(new SonarException(new SocketTimeoutException())).when(server).download("/batch_bootstrap/db?project=group:project", databaseFile, 60000); - - thrown.expect(SonarException.class); - thrown.expectMessage("Preview database read timed out after 60000 ms. You can try to increase read timeout with property -Dsonar.preview.readTimeout (in seconds)"); - - new PreviewDatabase(settings, server, tempUtils, mode).start(); - } - - @Test - public void should_fail() { - doThrow(new SonarException("BUG")).when(server).download("/batch_bootstrap/db?project=group:project", databaseFile, 60000); - - thrown.expect(SonarException.class); - thrown.expectMessage("BUG"); - - new PreviewDatabase(settings, server, tempUtils, mode).start(); - } - - @Test - public void project_should_be_optional() { - // on non-scan tasks - settings.removeProperty(CoreProperties.PROJECT_KEY_PROPERTY); - new PreviewDatabase(settings, server, tempUtils, mode).start(); - verify(server).download("/batch_bootstrap/db", databaseFile, 60000); - } -} diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ServerMetadataTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ServerMetadataTest.java deleted file mode 100644 index 6425547672e..00000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ServerMetadataTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch.bootstrap; - -import org.junit.Test; -import org.sonar.api.CoreProperties; -import org.sonar.api.config.Settings; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class ServerMetadataTest { - - @Test - public void shouldExtractId() throws Exception { - ServerMetadata metadata = new ServerMetadata(new Settings(), mock(ServerClient.class)); - assertThat(metadata.extractServerId("{\"id\":\"123456\",\"version\":\"3.1\",\"status\":\"UP\"}")).isEqualTo("123456"); - } - - @Test - public void shouldLoadServerProperties() { - Settings settings = new Settings(); - settings.setProperty(CoreProperties.SERVER_ID, "123"); - settings.setProperty(CoreProperties.SERVER_VERSION, "2.2"); - settings.setProperty(CoreProperties.SERVER_STARTTIME, "2010-05-18T17:59:00+0000"); - settings.setProperty(CoreProperties.PERMANENT_SERVER_ID, "abcde"); - ServerClient client = mock(ServerClient.class); - when(client.getURL()).thenReturn("http://foo.com"); - - ServerMetadata metadata = new ServerMetadata(settings, client); - - assertThat(metadata.getId()).isEqualTo("123"); - assertThat(metadata.getVersion()).isEqualTo("2.2"); - assertThat(metadata.getStartedAt().getDate()).isEqualTo(18); - assertThat(metadata.getURL()).isEqualTo("http://foo.com"); - assertThat(metadata.getPermanentServerId()).isEqualTo("abcde"); - } -} diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/TaskContainerTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/TaskContainerTest.java index 95ca145c161..9d5ff90cb72 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/TaskContainerTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/TaskContainerTest.java @@ -33,14 +33,14 @@ public class TaskContainerTest { @Test public void should_add_project_reactor_builder_by_default() { - BootstrapContainer container = BootstrapContainer.create(Collections.emptyMap(), + GlobalContainer container = GlobalContainer.create(Collections.emptyMap(), Lists.newArrayList(new BootstrapProperties(Collections.emptyMap()))); TaskContainer taskContainer = new TaskContainer(container, Collections.emptyMap()); taskContainer.installCoreTasks(); assertThat(taskContainer.getComponentByType(ProjectReactorBuilder.class)).isNotNull().isInstanceOf(ProjectReactorBuilder.class); - container = BootstrapContainer.create(Collections.emptyMap(), + container = GlobalContainer.create(Collections.emptyMap(), Lists.newArrayList(new BootstrapProperties(Collections.emptyMap()), new EnvironmentInformation("SonarQubeRunner", "2.4"))); taskContainer = new TaskContainer(container, Collections.emptyMap()); taskContainer.installCoreTasks(); @@ -50,7 +50,7 @@ public class TaskContainerTest { @Test public void should_add_deprecated_project_reactor_builder_if_old_runner() { - BootstrapContainer container = BootstrapContainer.create(Collections.emptyMap(), + GlobalContainer container = GlobalContainer.create(Collections.emptyMap(), Lists.newArrayList(new BootstrapProperties(Collections.emptyMap()), new EnvironmentInformation("SonarRunner", "2.3"))); TaskContainer taskContainer = new TaskContainer(container, Collections.emptyMap()); taskContainer.installCoreTasks(); diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/dependency/DependencyMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/dependency/DependencyMediumTest.java index 606b4d6ea3f..4d562d4de87 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/dependency/DependencyMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/dependency/DependencyMediumTest.java @@ -45,7 +45,6 @@ public class DependencyMediumTest { public BatchMediumTester tester = BatchMediumTester.builder() .registerPlugin("xoo", new XooPlugin()) .addDefaultQProfile("xoo", "Sonar Way") - .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor")) .build(); @Before diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/FileSystemMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/FileSystemMediumTest.java index 811a24870b7..03c40181906 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/FileSystemMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/FileSystemMediumTest.java @@ -51,7 +51,6 @@ public class FileSystemMediumTest { public BatchMediumTester tester = BatchMediumTester.builder() .registerPlugin("xoo", new XooPlugin()) .addDefaultQProfile("xoo", "Sonar Way") - .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor")) .build(); private File baseDir; diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/highlighting/HighlightingMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/highlighting/HighlightingMediumTest.java index 3572e2d2691..9b95241d26e 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/highlighting/HighlightingMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/highlighting/HighlightingMediumTest.java @@ -19,8 +19,6 @@ */ package org.sonar.batch.mediumtest.highlighting; -import org.sonar.batch.mediumtest.TaskResult; - import com.google.common.collect.ImmutableMap; import org.apache.commons.io.FileUtils; import org.junit.After; @@ -32,6 +30,7 @@ import org.junit.rules.TestName; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.sensor.highlighting.TypeOfText; import org.sonar.batch.mediumtest.BatchMediumTester; +import org.sonar.batch.mediumtest.TaskResult; import org.sonar.xoo.XooPlugin; import java.io.File; @@ -50,7 +49,6 @@ public class HighlightingMediumTest { public BatchMediumTester tester = BatchMediumTester.builder() .registerPlugin("xoo", new XooPlugin()) .addDefaultQProfile("xoo", "Sonar Way") - .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor")) .build(); @Before diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java index a6bed59f2fd..994fdaa676c 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java @@ -45,7 +45,6 @@ public class IssuesMediumTest { .registerPlugin("xoo", new XooPlugin()) .addDefaultQProfile("xoo", "Sonar Way") .activateRule(new ActiveRule("xoo", "OneIssuePerLine", "One issue per line", "MAJOR", "OneIssuePerLine.internal", "xoo")) - .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor")) .build(); @Before diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesOnDirMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesOnDirMediumTest.java index ac15f4c67c1..c6156e4cecc 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesOnDirMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesOnDirMediumTest.java @@ -44,7 +44,6 @@ public class IssuesOnDirMediumTest { .registerPlugin("xoo", new XooPlugin()) .addDefaultQProfile("xoo", "Sonar Way") .activateRule(new ActiveRule("xoo", "OneIssueOnDirPerFile", "One issue per line", "MINOR", "xoo", "xoo")) - .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor")) .build(); @Before diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/ReportsMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/ReportsMediumTest.java deleted file mode 100644 index 71929a9686f..00000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/ReportsMediumTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch.mediumtest.issues; - -import com.google.common.collect.ImmutableMap; -import org.apache.commons.codec.digest.DigestUtils; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.sonar.batch.mediumtest.BatchMediumTester; -import org.sonar.batch.mediumtest.TaskResult; -import org.sonar.batch.protocol.input.ActiveRule; -import org.sonar.batch.protocol.input.issues.PreviousIssue; -import org.sonar.xoo.XooPlugin; - -import java.io.File; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; - -import static org.assertj.core.api.Assertions.assertThat; - -public class ReportsMediumTest { - - @org.junit.Rule - public TemporaryFolder temp = new TemporaryFolder(); - - private static SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); - - private static Date date(String date) { - try { - return sdf.parse(date); - } catch (ParseException e) { - throw new IllegalStateException(e); - } - } - - public BatchMediumTester tester = BatchMediumTester.builder() - .registerPlugin("xoo", new XooPlugin()) - .addDefaultQProfile("xoo", "Sonar Way") - .activateRule(new ActiveRule("xoo", "OneIssuePerLine", "One issue per line", "MAJOR", "OneIssuePerLine.internal", "xoo")) - .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor")) - // Existing issue - .addPreviousIssue(new PreviousIssue().setKey("xyz") - .setComponentKey("sample:xources/hello/HelloJava.xoo") - .setRuleKey("xoo", "OneIssuePerLine") - .setLine(1) - .setSeverity("MAJOR") - .setCreationDate(date("14/03/2004")) - .setChecksum(DigestUtils.md5Hex("packagehello;")) - .setStatus("OPEN")) - // Resolved issue - .addPreviousIssue(new PreviousIssue().setKey("resolved") - .setComponentKey("sample:xources/hello/HelloJava.xoo") - .setRuleKey("xoo", "OneIssuePerLine") - .setLine(1) - .setSeverity("MAJOR") - .setCreationDate(date("14/03/2004")) - .setChecksum(DigestUtils.md5Hex("dontexist")) - .setStatus("OPEN")) - .build(); - - @Before - public void prepare() { - tester.start(); - } - - @After - public void stop() { - tester.stop(); - } - - @Test - public void testConsoleReport() throws Exception { - File projectDir = new File(ReportsMediumTest.class.getResource("/mediumtest/xoo/sample").toURI()); - - TaskResult result = tester - .newScanTask(new File(projectDir, "sonar-project.properties")) - .property("sonar.issuesReport.console.enable", "true") - .start(); - - assertThat(result.issues()).hasSize(15); - } - - @Test - public void testHtmlReport() throws Exception { - File projectDir = new File(ReportsMediumTest.class.getResource("/mediumtest/xoo/sample").toURI()); - - TaskResult result = tester - .newScanTask(new File(projectDir, "sonar-project.properties")) - .property("sonar.issuesReport.html.enable", "true") - .start(); - - assertThat(result.issues()).hasSize(15); - } - -} diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java index e1226a9849e..6656f5dd7c7 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java @@ -45,7 +45,6 @@ public class MeasuresMediumTest { public BatchMediumTester tester = BatchMediumTester.builder() .registerPlugin("xoo", new XooPlugin()) .addDefaultQProfile("xoo", "Sonar Way") - .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor")) .build(); @Before diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/ReportsMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/ReportsMediumTest.java new file mode 100644 index 00000000000..16d4f7350fb --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/ReportsMediumTest.java @@ -0,0 +1,112 @@ +/* + * 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.batch.mediumtest.preview; + +import com.google.common.collect.ImmutableMap; +import org.apache.commons.codec.digest.DigestUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.CoreProperties; +import org.sonar.batch.mediumtest.BatchMediumTester; +import org.sonar.batch.mediumtest.TaskResult; +import org.sonar.batch.protocol.input.ActiveRule; +import org.sonar.batch.protocol.input.issues.PreviousIssue; +import org.sonar.xoo.XooPlugin; + +import java.io.File; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class ReportsMediumTest { + + @org.junit.Rule + public TemporaryFolder temp = new TemporaryFolder(); + + private static SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); + + private static Date date(String date) { + try { + return sdf.parse(date); + } catch (ParseException e) { + throw new IllegalStateException(e); + } + } + + public BatchMediumTester tester = BatchMediumTester.builder() + .bootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_PREVIEW)) + .registerPlugin("xoo", new XooPlugin()) + .addDefaultQProfile("xoo", "Sonar Way") + .activateRule(new ActiveRule("xoo", "OneIssuePerLine", "One issue per line", "MAJOR", "OneIssuePerLine.internal", "xoo")) + // Existing issue + .addPreviousIssue(new PreviousIssue().setKey("xyz") + .setComponentKey("sample:xources/hello/HelloJava.xoo") + .setRuleKey("xoo", "OneIssuePerLine") + .setLine(1) + .setSeverity("MAJOR") + .setCreationDate(date("14/03/2004")) + .setChecksum(DigestUtils.md5Hex("packagehello;")) + .setStatus("OPEN")) + // Resolved issue + .addPreviousIssue(new PreviousIssue().setKey("resolved") + .setComponentKey("sample:xources/hello/HelloJava.xoo") + .setRuleKey("xoo", "OneIssuePerLine") + .setLine(1) + .setSeverity("MAJOR") + .setCreationDate(date("14/03/2004")) + .setChecksum(DigestUtils.md5Hex("dontexist")) + .setStatus("OPEN")) + .build(); + + @Before + public void prepare() { + tester.start(); + } + + @After + public void stop() { + tester.stop(); + } + + @Test + public void testConsoleReport() throws Exception { + File projectDir = new File(ReportsMediumTest.class.getResource("/mediumtest/xoo/sample").toURI()); + + TaskResult result = tester + .newScanTask(new File(projectDir, "sonar-project.properties")) + .property("sonar.issuesReport.console.enable", "true") + .start(); + + } + + @Test + public void testHtmlReport() throws Exception { + File projectDir = new File(ReportsMediumTest.class.getResource("/mediumtest/xoo/sample").toURI()); + + TaskResult result = tester + .newScanTask(new File(projectDir, "sonar-project.properties")) + .property("sonar.issuesReport.html.enable", "true") + .start(); + + } + +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java index c8456c6c803..13994e0081c 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/scm/ScmMediumTest.java @@ -50,7 +50,6 @@ public class ScmMediumTest { public BatchMediumTester tester = BatchMediumTester.builder() .registerPlugin("xoo", new XooPlugin()) .addDefaultQProfile("xoo", "Sonar Way") - .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor")) .build(); @Before diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/symbol/SymbolMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/symbol/SymbolMediumTest.java index ec00c3a288b..a231c93f69b 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/symbol/SymbolMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/symbol/SymbolMediumTest.java @@ -19,8 +19,6 @@ */ package org.sonar.batch.mediumtest.symbol; -import org.sonar.batch.mediumtest.TaskResult; - import com.google.common.collect.ImmutableMap; import org.apache.commons.io.FileUtils; import org.junit.After; @@ -29,6 +27,7 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.InputFile; import org.sonar.batch.mediumtest.BatchMediumTester; +import org.sonar.batch.mediumtest.TaskResult; import org.sonar.xoo.XooPlugin; import java.io.File; @@ -44,7 +43,6 @@ public class SymbolMediumTest { public BatchMediumTester tester = BatchMediumTester.builder() .registerPlugin("xoo", new XooPlugin()) .addDefaultQProfile("xoo", "Sonar Way") - .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor")) .build(); @Before diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/test/TestMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/test/TestMediumTest.java index b5478a5faab..700aa0aaee8 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/test/TestMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/test/TestMediumTest.java @@ -45,7 +45,6 @@ public class TestMediumTest { public BatchMediumTester tester = BatchMediumTester.builder() .registerPlugin("xoo", new XooPlugin()) .addDefaultQProfile("xoo", "Sonar Way") - .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor")) .build(); @Before diff --git a/sonar-batch/src/test/java/org/sonar/batch/phases/DatabaseModePhaseExecutorTest.java b/sonar-batch/src/test/java/org/sonar/batch/phases/DatabaseModePhaseExecutorTest.java new file mode 100644 index 00000000000..d3bc6b2f86e --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/phases/DatabaseModePhaseExecutorTest.java @@ -0,0 +1,53 @@ +/* + * 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.batch.phases; + +import org.junit.Test; +import org.sonar.batch.index.MeasurePersister; +import org.sonar.batch.index.ResourcePersister; +import org.sonar.batch.index.ScanPersister; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +public class DatabaseModePhaseExecutorTest { + + @Test + public void shouldSortPersisters() { + ScanPersister otherPersister = mock(ScanPersister.class); + MeasurePersister measurePersister = new MeasurePersister(null, null, null, null, null); + ResourcePersister resourcePersister = new ResourcePersister(null, null, null, null, null); + ScanPersister[] persisters = new ScanPersister[] {otherPersister, measurePersister, resourcePersister}; + DatabaseModePhaseExecutor executor = new DatabaseModePhaseExecutor(null, null, null, null, null, null, + null, null, null, null, null, persisters, null, null, null, null, null, null, null, null); + assertThat(executor.sortedPersisters()).containsSubsequence(resourcePersister, measurePersister); + + persisters = new ScanPersister[] {measurePersister, resourcePersister, otherPersister}; + executor = new DatabaseModePhaseExecutor(null, null, null, null, null, null, + null, null, null, null, null, persisters, null, null, null, null, null, null, null, null); + assertThat(executor.sortedPersisters()).containsSubsequence(resourcePersister, measurePersister); + + persisters = new ScanPersister[] {measurePersister, otherPersister, resourcePersister}; + executor = new DatabaseModePhaseExecutor(null, null, null, null, null, null, + null, null, null, null, null, persisters, null, null, null, null, null, null, null, null); + assertThat(executor.sortedPersisters()).containsSubsequence(resourcePersister, measurePersister); + } + +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/phases/DefaultPhaseExecutorTest.java b/sonar-batch/src/test/java/org/sonar/batch/phases/DefaultPhaseExecutorTest.java deleted file mode 100644 index 262cc1da068..00000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/phases/DefaultPhaseExecutorTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.batch.phases; - -import org.junit.Test; -import org.sonar.batch.index.MeasurePersister; -import org.sonar.batch.index.ResourcePersister; -import org.sonar.batch.index.ScanPersister; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -public class DefaultPhaseExecutorTest { - - @Test - public void shouldSortPersisters() { - ScanPersister otherPersister = mock(ScanPersister.class); - MeasurePersister measurePersister = new MeasurePersister(null, null, null, null, null); - ResourcePersister resourcePersister = new ResourcePersister(null, null, null, null, null); - ScanPersister[] persisters = new ScanPersister[] {otherPersister, measurePersister, resourcePersister}; - DefaultPhaseExecutor executor = new DefaultPhaseExecutor(null, null, null, null, null, null, - null, null, null, null, null, persisters, null, null, null, null, null, null, null, null); - assertThat(executor.sortedPersisters()).containsSubsequence(resourcePersister, measurePersister); - - persisters = new ScanPersister[] {measurePersister, resourcePersister, otherPersister}; - executor = new DefaultPhaseExecutor(null, null, null, null, null, null, - null, null, null, null, null, persisters, null, null, null, null, null, null, null, null); - assertThat(executor.sortedPersisters()).containsSubsequence(resourcePersister, measurePersister); - - persisters = new ScanPersister[] {measurePersister, otherPersister, resourcePersister}; - executor = new DefaultPhaseExecutor(null, null, null, null, null, null, - null, null, null, null, null, persisters, null, null, null, null, null, null, null, null); - assertThat(executor.sortedPersisters()).containsSubsequence(resourcePersister, measurePersister); - } - -} diff --git a/sonar-batch/src/test/java/org/sonar/batch/platform/DefaultServerTest.java b/sonar-batch/src/test/java/org/sonar/batch/platform/DefaultServerTest.java new file mode 100644 index 00000000000..8c5e2a74752 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/platform/DefaultServerTest.java @@ -0,0 +1,51 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.batch.platform; + +import org.junit.Test; +import org.sonar.api.CoreProperties; +import org.sonar.api.config.Settings; +import org.sonar.batch.bootstrap.ServerClient; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class DefaultServerTest { + + @Test + public void shouldLoadServerProperties() { + Settings settings = new Settings(); + settings.setProperty(CoreProperties.SERVER_ID, "123"); + settings.setProperty(CoreProperties.SERVER_VERSION, "2.2"); + settings.setProperty(CoreProperties.SERVER_STARTTIME, "2010-05-18T17:59:00+0000"); + settings.setProperty(CoreProperties.PERMANENT_SERVER_ID, "abcde"); + ServerClient client = mock(ServerClient.class); + when(client.getURL()).thenReturn("http://foo.com"); + + DefaultServer metadata = new DefaultServer(settings, client); + + assertThat(metadata.getId()).isEqualTo("123"); + assertThat(metadata.getVersion()).isEqualTo("2.2"); + assertThat(metadata.getStartedAt().getDate()).isEqualTo(18); + assertThat(metadata.getURL()).isEqualTo("http://foo.com"); + assertThat(metadata.getPermanentServerId()).isEqualTo("abcde"); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/report/PublishReportJobTest.java b/sonar-batch/src/test/java/org/sonar/batch/report/PublishReportJobTest.java index e28e0643fb0..924f05d25f2 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/report/PublishReportJobTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/report/PublishReportJobTest.java @@ -27,7 +27,7 @@ import org.sonar.api.config.Settings; import org.sonar.api.platform.Server; import org.sonar.api.resources.Project; import org.sonar.api.utils.TempFolder; -import org.sonar.batch.bootstrap.AnalysisMode; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; import org.sonar.batch.bootstrap.ServerClient; import org.sonar.batch.index.ResourceCache; import org.sonar.jpa.test.AbstractDbUnitTestCase; @@ -38,13 +38,13 @@ import static org.mockito.Mockito.when; public class PublishReportJobTest extends AbstractDbUnitTestCase { - private AnalysisMode mode; + private DefaultAnalysisMode mode; ResourceCache resourceCache = mock(ResourceCache.class); @Before public void setUp() { - mode = mock(AnalysisMode.class); + mode = mock(DefaultAnalysisMode.class); } @Test diff --git a/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest.java index 27e07d7edc0..3cb1f9ba462 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/repository/DefaultProjectRepositoriesLoaderTest.java @@ -27,7 +27,7 @@ import org.junit.Test; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.bootstrap.ProjectReactor; import org.sonar.api.database.DatabaseSession; -import org.sonar.batch.bootstrap.AnalysisMode; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; import org.sonar.batch.bootstrap.ServerClient; import org.sonar.batch.bootstrap.TaskProperties; import org.sonar.batch.rule.ModuleQProfiles; @@ -42,14 +42,14 @@ public class DefaultProjectRepositoriesLoaderTest { private DefaultProjectRepositoriesLoader loader; private ServerClient serverClient; - private AnalysisMode analysisMode; + private DefaultAnalysisMode analysisMode; private ProjectReactor reactor; private TaskProperties taskProperties; @Before public void prepare() { serverClient = mock(ServerClient.class); - analysisMode = mock(AnalysisMode.class); + analysisMode = mock(DefaultAnalysisMode.class); loader = new DefaultProjectRepositoriesLoader(mock(DatabaseSession.class), serverClient, analysisMode); loader = spy(loader); doReturn(null).when(loader).lastSnapshotCreationDate(anyString()); diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java index 7215d7b1940..abf12abc034 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java @@ -27,7 +27,7 @@ import org.junit.rules.ExpectedException; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.config.PropertyDefinitions; import org.sonar.api.utils.MessageException; -import org.sonar.batch.bootstrap.AnalysisMode; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; import org.sonar.batch.bootstrap.GlobalSettings; import org.sonar.batch.protocol.input.ProjectRepositories; @@ -43,12 +43,12 @@ public class ModuleSettingsTest { public ExpectedException thrown = ExpectedException.none(); ProjectRepositories projectRef; - private AnalysisMode mode; + private DefaultAnalysisMode mode; @Before public void before() { projectRef = new ProjectRepositories(); - mode = mock(AnalysisMode.class); + mode = mock(DefaultAnalysisMode.class); } @Test diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectLockTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectLockTest.java index 5424028b132..f0570150c82 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectLockTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectLockTest.java @@ -26,7 +26,7 @@ import org.sonar.api.resources.Project; import org.sonar.api.utils.Semaphores; import org.sonar.api.utils.SonarException; import org.sonar.batch.ProjectTree; -import org.sonar.batch.bootstrap.AnalysisMode; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; import java.util.Locale; @@ -44,11 +44,11 @@ public class ProjectLockTest { ProjectTree projectTree = mock(ProjectTree.class); I18n i18n = mock(I18n.class); Project project; - private AnalysisMode mode; + private DefaultAnalysisMode mode; @Before public void setUp() { - mode = mock(AnalysisMode.class); + mode = mock(DefaultAnalysisMode.class); project = new Project("my-project-key"); when(projectTree.getRootProject()).thenReturn(project); diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectScanContainerTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectScanContainerTest.java index bbfa7acefd4..cc3a1158427 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectScanContainerTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectScanContainerTest.java @@ -36,7 +36,7 @@ import org.sonar.api.platform.ComponentContainer; import org.sonar.api.task.TaskExtension; import org.sonar.api.utils.System2; import org.sonar.api.utils.TempFolder; -import org.sonar.batch.bootstrap.AnalysisMode; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; import org.sonar.batch.bootstrap.BootstrapProperties; import org.sonar.batch.bootstrap.ExtensionInstaller; import org.sonar.batch.bootstrap.GlobalSettings; @@ -64,7 +64,7 @@ public class ProjectScanContainerTest { public void prepare() { projectBootstrapper = mock(ProjectBootstrapper.class); bootstrapProperties = new BootstrapProperties(Collections.emptyMap()); - AnalysisMode analysisMode = new AnalysisMode(bootstrapProperties); + DefaultAnalysisMode analysisMode = new DefaultAnalysisMode(bootstrapProperties); when(projectBootstrapper.bootstrap()).thenReturn(new ProjectReactor(ProjectDefinition.create())); parentContainer = new ComponentContainer(); parentContainer.add(System2.INSTANCE); diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectSettingsTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectSettingsTest.java index 58ade46e025..6ba93100ea0 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectSettingsTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectSettingsTest.java @@ -29,7 +29,7 @@ import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.bootstrap.ProjectReactor; import org.sonar.api.config.PropertyDefinitions; import org.sonar.api.utils.MessageException; -import org.sonar.batch.bootstrap.AnalysisMode; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; import org.sonar.batch.bootstrap.BootstrapProperties; import org.sonar.batch.bootstrap.GlobalSettings; import org.sonar.batch.protocol.input.GlobalRepositories; @@ -50,12 +50,12 @@ public class ProjectSettingsTest { ProjectDefinition project = ProjectDefinition.create().setKey("struts"); GlobalSettings bootstrapProps; - private AnalysisMode mode; + private DefaultAnalysisMode mode; @Before public void prepare() { projectRef = new ProjectRepositories(); - mode = mock(AnalysisMode.class); + mode = mock(DefaultAnalysisMode.class); bootstrapProps = new GlobalSettings(new BootstrapProperties(Collections.emptyMap()), new PropertyDefinitions(), new GlobalRepositories(), mode); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileBuilderFactoryTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileBuilderFactoryTest.java index 9a753c7e66f..e702dbbfa81 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileBuilderFactoryTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileBuilderFactoryTest.java @@ -24,7 +24,7 @@ import org.mockito.Mockito; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.config.Settings; import org.sonar.api.scan.filesystem.PathResolver; -import org.sonar.batch.bootstrap.AnalysisMode; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -36,7 +36,7 @@ public class InputFileBuilderFactoryTest { LanguageDetectionFactory langDetectionFactory = mock(LanguageDetectionFactory.class, Mockito.RETURNS_MOCKS); StatusDetectionFactory statusDetectionFactory = mock(StatusDetectionFactory.class, Mockito.RETURNS_MOCKS); DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class); - AnalysisMode analysisMode = mock(AnalysisMode.class); + DefaultAnalysisMode analysisMode = mock(DefaultAnalysisMode.class); InputFileBuilderFactory factory = new InputFileBuilderFactory(ProjectDefinition.create().setKey("struts"), pathResolver, langDetectionFactory, statusDetectionFactory, analysisMode, new Settings()); diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileBuilderTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileBuilderTest.java index 3d1eb9b050d..36682184b37 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileBuilderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileBuilderTest.java @@ -29,7 +29,7 @@ import org.sonar.api.batch.fs.internal.DeprecatedDefaultInputFile; import org.sonar.api.config.Settings; import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.api.utils.PathUtils; -import org.sonar.batch.bootstrap.AnalysisMode; +import org.sonar.batch.bootstrap.DefaultAnalysisMode; import java.io.File; import java.util.Arrays; @@ -47,7 +47,7 @@ public class InputFileBuilderTest { LanguageDetection langDetection = mock(LanguageDetection.class); StatusDetection statusDetection = mock(StatusDetection.class); DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class); - AnalysisMode analysisMode = mock(AnalysisMode.class); + DefaultAnalysisMode analysisMode = mock(DefaultAnalysisMode.class); @Test public void complete_input_file() throws Exception { diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/sensor/ProjectLinksSensorTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/sensor/ProjectLinksSensorTest.java new file mode 100644 index 00000000000..6e44bc572f4 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/sensor/ProjectLinksSensorTest.java @@ -0,0 +1,105 @@ +/* + * 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.batch.scan.sensor; + +import org.sonar.batch.scan.sensor.ProjectLinksSensor; + +import org.apache.commons.lang.StringUtils; +import org.junit.Test; +import org.mockito.ArgumentMatcher; +import org.sonar.api.CoreProperties; +import org.sonar.api.batch.AnalysisMode; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.config.Settings; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.ProjectLink; +import org.sonar.core.i18n.DefaultI18n; + +import java.util.Locale; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class ProjectLinksSensorTest { + + @Test + public void testToString() { + assertThat(new ProjectLinksSensor(null, null, null).toString()).isEqualTo("ProjectLinksSensor"); + } + + @Test + public void shouldNotExecuteInPreview() { + Project project = mock(Project.class); + AnalysisMode analysisMode = mock(AnalysisMode.class); + assertThat(new ProjectLinksSensor(null, null, analysisMode).shouldExecuteOnProject(project)).isTrue(); + when(analysisMode.isPreview()).thenReturn(true); + assertThat(new ProjectLinksSensor(null, null, analysisMode).shouldExecuteOnProject(project)).isFalse(); + } + + @Test + public void shouldSaveLinks() { + Settings settings = new Settings(); + settings.setProperty(CoreProperties.LINKS_HOME_PAGE, "http://home"); + DefaultI18n defaultI18n = mock(DefaultI18n.class); + when(defaultI18n.message(Locale.getDefault(), "project_links.homepage", CoreProperties.LINKS_HOME_PAGE)).thenReturn("HOME"); + Project project = mock(Project.class); + SensorContext context = mock(SensorContext.class); + + new ProjectLinksSensor(settings, defaultI18n, null).analyse(project, context); + + verify(context).saveLink(argThat(new MatchLink("homepage", "HOME", "http://home"))); + } + + @Test + public void shouldDeleteLink() { + Settings settings = new Settings(); + settings.setProperty(CoreProperties.LINKS_HOME_PAGE, ""); + DefaultI18n defaultI18n = mock(DefaultI18n.class); + when(defaultI18n.message(Locale.getDefault(), "project_links.homepage", CoreProperties.LINKS_HOME_PAGE)).thenReturn("HOME"); + Project project = mock(Project.class); + SensorContext context = mock(SensorContext.class); + + new ProjectLinksSensor(settings, defaultI18n, null).analyse(project, context); + + verify(context).deleteLink("homepage"); + } + + private class MatchLink extends ArgumentMatcher { + private String key; + private String name; + private String url; + + private MatchLink(String key, String name, String url) { + this.key = key; + this.name = name; + this.url = url; + } + + @Override + public boolean matches(Object o) { + ProjectLink link = (ProjectLink) o; + return StringUtils.equals(link.getHref(), url) && StringUtils.equals(link.getKey(), key) && StringUtils.equals(link.getName(), name); + } + } + +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/sensor/VersionEventsSensorTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/sensor/VersionEventsSensorTest.java new file mode 100644 index 00000000000..d70932f673c --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/sensor/VersionEventsSensorTest.java @@ -0,0 +1,119 @@ +/* + * 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.batch.scan.sensor; + +import org.sonar.batch.scan.sensor.VersionEventsSensor; + +import com.google.common.collect.Lists; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.batch.AnalysisMode; +import org.sonar.api.batch.Event; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; + +import java.util.Date; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.isNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class VersionEventsSensorTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void shouldExecuteOnProject() throws Exception { + AnalysisMode analysisMode = mock(AnalysisMode.class); + assertThat(new VersionEventsSensor(analysisMode).shouldExecuteOnProject(null)).isTrue(); + when(analysisMode.isPreview()).thenReturn(true); + assertThat(new VersionEventsSensor(analysisMode).shouldExecuteOnProject(null)).isFalse(); + } + + @Test + public void testToString() throws Exception { + assertThat(new VersionEventsSensor(null).toString(), is("VersionEventsSensor")); + } + + @Test + public void shouldDoNothingIfNoVersion() { + VersionEventsSensor sensor = new VersionEventsSensor(null); + SensorContext context = mock(SensorContext.class); + Project project = mock(Project.class); + when(project.getAnalysisVersion()).thenReturn(null); + + sensor.analyse(project, context); + + verify(context, never()).createEvent(any(Resource.class), anyString(), anyString(), anyString(), any(Date.class)); + verify(context, never()).deleteEvent(any(Event.class)); + } + + @Test + public void shouldCreateVersionEvent() { + VersionEventsSensor sensor = new VersionEventsSensor(null); + SensorContext context = mock(SensorContext.class); + + Project project = mock(Project.class); + when(project.getAnalysisVersion()).thenReturn("1.5-SNAPSHOT"); + + sensor.analyse(project, context); + + verify(context).createEvent(eq(project), eq("1.5-SNAPSHOT"), (String) isNull(), eq(Event.CATEGORY_VERSION), (Date) isNull()); + } + + @Test + public void shouldHaveOnlyOneEventByVersion() { + Event sameVersionEvent = mockVersionEvent("1.5-SNAPSHOT"); + Event otherEvent = mockVersionEvent("1.4"); + Event anotherEvent = mockVersionEvent("1.3-SNAPSHOT"); + + VersionEventsSensor sensor = new VersionEventsSensor(null); + SensorContext context = mock(SensorContext.class); + + Project project = mock(Project.class); + when(project.getAnalysisVersion()).thenReturn("1.5-SNAPSHOT"); + + when(context.getEvents(project)).thenReturn(Lists.newArrayList(sameVersionEvent, otherEvent, anotherEvent)); + + sensor.analyse(project, context); + + verify(context).deleteEvent(sameVersionEvent); + verify(context).createEvent(eq(project), eq("1.5-SNAPSHOT"), (String) isNull(), eq(Event.CATEGORY_VERSION), (Date) isNull()); + } + + private Event mockVersionEvent(String version) { + Event event = mock(Event.class); + when(event.isVersionCategory()).thenReturn(true); + when(event.getName()).thenReturn(version); + return event; + } + +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/sensor/AnalyzerOptimizerTest.java b/sonar-batch/src/test/java/org/sonar/batch/sensor/AnalyzerOptimizerTest.java index fb8e564f11d..882bc1aadc7 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/sensor/AnalyzerOptimizerTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/sensor/AnalyzerOptimizerTest.java @@ -23,6 +23,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.batch.fs.internal.DefaultInputFile; @@ -33,6 +34,8 @@ import org.sonar.api.config.Settings; import org.sonar.api.rule.RuleKey; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class AnalyzerOptimizerTest { @@ -44,10 +47,13 @@ public class AnalyzerOptimizerTest { private Settings settings; + private AnalysisMode analysisMode; + @Before public void prepare() { settings = new Settings(); - optimizer = new AnalyzerOptimizer(fs, new ActiveRulesBuilder().build(), settings); + analysisMode = mock(AnalysisMode.class); + optimizer = new AnalyzerOptimizer(fs, new ActiveRulesBuilder().build(), settings, analysisMode); } @Test @@ -105,7 +111,7 @@ public class AnalyzerOptimizerTest { .create(RuleKey.of("repo1", "foo")) .activate() .build(); - optimizer = new AnalyzerOptimizer(fs, activeRules, settings); + optimizer = new AnalyzerOptimizer(fs, activeRules, settings, analysisMode); assertThat(optimizer.shouldExecute(descriptor)).isFalse(); @@ -115,7 +121,7 @@ public class AnalyzerOptimizerTest { .create(RuleKey.of("squid", "rule")) .activate() .build(); - optimizer = new AnalyzerOptimizer(fs, activeRules, settings); + optimizer = new AnalyzerOptimizer(fs, activeRules, settings, analysisMode); assertThat(optimizer.shouldExecute(descriptor)).isTrue(); } @@ -128,4 +134,15 @@ public class AnalyzerOptimizerTest { settings.setProperty("sonar.foo.reportPath", "foo"); assertThat(optimizer.shouldExecute(descriptor)).isTrue(); } + + @Test + public void should_disabled_in_preview() throws Exception { + DefaultSensorDescriptor descriptor = new DefaultSensorDescriptor() + .disabledInPreview(); + assertThat(optimizer.shouldExecute(descriptor)).isTrue(); + + when(analysisMode.isPreview()).thenReturn(true); + + assertThat(optimizer.shouldExecute(descriptor)).isFalse(); + } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorContextTest.java b/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorContextTest.java index b51dccd8f05..0995806e053 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorContextTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorContextTest.java @@ -23,6 +23,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.batch.measure.MetricFinder; import org.sonar.api.batch.rule.ActiveRules; @@ -48,6 +49,7 @@ public class DefaultSensorContextTest { private DefaultSensorContext adaptor; private Settings settings; private SensorStorage sensorStorage; + private AnalysisMode analysisMode; @Before public void prepare() { @@ -60,7 +62,8 @@ public class DefaultSensorContextTest { ComponentDataCache componentDataCache = mock(ComponentDataCache.class); BlockCache blockCache = mock(BlockCache.class); sensorStorage = mock(SensorStorage.class); - adaptor = new DefaultSensorContext(settings, fs, activeRules, componentDataCache, blockCache, mock(DuplicationCache.class), sensorStorage); + analysisMode = mock(AnalysisMode.class); + adaptor = new DefaultSensorContext(settings, fs, activeRules, analysisMode, componentDataCache, blockCache, mock(DuplicationCache.class), sensorStorage); } @Test @@ -68,6 +71,7 @@ public class DefaultSensorContextTest { assertThat(adaptor.activeRules()).isEqualTo(activeRules); assertThat(adaptor.fileSystem()).isEqualTo(fs); assertThat(adaptor.settings()).isEqualTo(settings); + assertThat(adaptor.analysisMode()).isEqualTo(analysisMode); assertThat(adaptor.newIssue()).isNotNull(); assertThat(adaptor.newMeasure()).isNotNull(); diff --git a/sonar-core/src/main/java/org/sonar/core/DryRunIncompatible.java b/sonar-core/src/main/java/org/sonar/core/DryRunIncompatible.java deleted file mode 100644 index b4e459f9ab5..00000000000 --- a/sonar-core/src/main/java/org/sonar/core/DryRunIncompatible.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.core; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * The presence of this annotation on an extension class indicates that the extension - * may be disabled when the dry-run mode is enabled (-Dsonar.dryRun=true). - * It's generally used by the extensions that push data to external systems, for example : - *
    - *
  • Send emails
  • - *
  • Create a JIRA issue
  • - *
- * - * - * @since 3.4 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -public @interface DryRunIncompatible { -} diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DbTemplate.java b/sonar-core/src/main/java/org/sonar/core/persistence/DbTemplate.java deleted file mode 100644 index 9c42c50fb96..00000000000 --- a/sonar-core/src/main/java/org/sonar/core/persistence/DbTemplate.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.core.persistence; - -import com.google.common.base.Joiner; -import org.apache.commons.dbcp.BasicDataSource; -import org.apache.commons.dbutils.DbUtils; -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.ServerComponent; -import org.sonar.api.utils.SonarException; -import org.sonar.core.profiling.Profiling; -import org.sonar.core.profiling.Profiling.Level; -import org.sonar.core.profiling.StopWatch; - -import javax.annotation.Nullable; -import javax.sql.DataSource; - -import java.sql.*; - -public class DbTemplate implements ServerComponent { - private static final Logger LOG = LoggerFactory.getLogger(DbTemplate.class); - - private Profiling profiling; - - public DbTemplate(Profiling profiling) { - this.profiling = profiling; - } - - public DbTemplate copyTable(DataSource source, DataSource dest, String table) { - return copyTableColumns(source, dest, table, null); - } - - public DbTemplate copyTableColumns(DataSource source, DataSource dest, String table, @Nullable String[] columnNames) { - String selectQuery = "SELECT * FROM " + table; - copyTableColumns(source, dest, table, selectQuery, columnNames); - - return this; - } - - public DbTemplate copyTable(DataSource source, DataSource dest, String table, String selectQuery) { - return copyTableColumns(source, dest, table, selectQuery, null); - } - - public DbTemplate copyTableColumns(DataSource source, DataSource dest, String table, String selectQuery, @Nullable String[] columnNames) { - LOG.debug("Copy table {}", table); - StopWatch watch = profiling.start("previewdb", Level.BASIC); - - truncate(dest, table); - - Connection sourceConnection = null; - Statement sourceStatement = null; - ResultSet sourceResultSet = null; - Connection destConnection = null; - ResultSet destResultSet = null; - PreparedStatement destStatement = null; - int count = 0; - try { - sourceConnection = source.getConnection(); - sourceStatement = sourceConnection.createStatement(); - sourceResultSet = sourceStatement.executeQuery(selectQuery); - - if (sourceResultSet.next()) { - if (columnNames == null) { - // Copy all columns - columnNames = columnNames(sourceResultSet); - } - int[] columnTypes = columnTypes(sourceResultSet); - - destConnection = dest.getConnection(); - destConnection.setAutoCommit(false); - - String insertSql = new StringBuilder().append("INSERT INTO ").append(table).append("(").append(Joiner.on(",").join(columnNames)) - .append(") VALUES(").append(StringUtils.repeat("?", ",", columnNames.length)).append(")").toString(); - destStatement = destConnection.prepareStatement(insertSql); - - do { - copyColumns(sourceResultSet, destStatement, columnNames, columnTypes); - count++; - destStatement.addBatch(); - if (count % BatchSession.MAX_BATCH_SIZE == 0) { - destStatement.executeBatch(); - destConnection.commit(); - - } - } while (sourceResultSet.next()); - - destStatement.executeBatch(); - destConnection.commit(); - } - } catch (SQLException e) { - LOG.error("Fail to copy table " + table, e); - throw new IllegalStateException("Fail to copy table " + table, e); - } finally { - watch.stop(" " + count + " rows of " + table + " copied"); - DbUtils.closeQuietly(destStatement); - DbUtils.closeQuietly(destResultSet); - DbUtils.closeQuietly(destConnection); - DbUtils.closeQuietly(sourceResultSet); - DbUtils.closeQuietly(sourceStatement); - DbUtils.closeQuietly(sourceConnection); - } - return this; - } - - private void copyColumns(ResultSet sourceResultSet, PreparedStatement destStatement, String[] columnNames, int[] columnTypes) throws SQLException { - for (int col = 1; col <= columnNames.length; col++) { - if (columnTypes[col - 1] == Types.TIMESTAMP) { - Timestamp value = sourceResultSet.getTimestamp(columnNames[col - 1]); - destStatement.setTimestamp(col, value); - } else { - Object value = sourceResultSet.getObject(columnNames[col - 1]); - destStatement.setObject(col, value); - } - } - } - - private String[] columnNames(ResultSet resultSet) throws SQLException { - int colCount = resultSet.getMetaData().getColumnCount(); - String[] columnNames = new String[colCount]; - for (int i = 1; i <= colCount; i++) { - columnNames[i - 1] = resultSet.getMetaData().getColumnName(i); - } - return columnNames; - } - - private int[] columnTypes(ResultSet resultSet) throws SQLException { - int colCount = resultSet.getMetaData().getColumnCount(); - int[] columnTypes = new int[colCount]; - for (int i = 1; i <= colCount; i++) { - columnTypes[i - 1] = resultSet.getMetaData().getColumnType(i); - } - return columnTypes; - } - - public DbTemplate truncate(DataSource dataSource, String table) { - Connection connection = null; - Statement statement = null; - try { - connection = dataSource.getConnection(); - statement = connection.createStatement(); - statement.executeUpdate("TRUNCATE TABLE " + table); - } catch (SQLException e) { - LOG.error("Fail to truncate table " + table, e); - throw new SonarException("Fail to truncate table " + table, e); - } finally { - DbUtils.closeQuietly(statement); - DbUtils.closeQuietly(connection); - } - - return this; - } - - public BasicDataSource dataSource(String driver, String user, String password, String url) { - BasicDataSource dataSource = new BasicDataSource(); - dataSource.setDriverClassName(driver); - dataSource.setUsername(user); - dataSource.setPassword(password); - dataSource.setUrl(url); - return dataSource; - } - - public DbTemplate createSchema(DataSource dataSource, String dialect) { - Connection connection = null; - try { - connection = dataSource.getConnection(); - DdlUtils.createSchema(connection, dialect); - } catch (SQLException e) { - LOG.error("Fail to createSchema local database schema", e); - throw new SonarException("Fail to createSchema local database schema", e); - } finally { - DbUtils.closeQuietly(connection); - } - - return this; - } -} diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/PreviewDatabaseFactory.java b/sonar-core/src/main/java/org/sonar/core/persistence/PreviewDatabaseFactory.java deleted file mode 100644 index e9996cf7201..00000000000 --- a/sonar-core/src/main/java/org/sonar/core/persistence/PreviewDatabaseFactory.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.core.persistence; - -import org.apache.commons.dbcp.BasicDataSource; -import org.sonar.api.ServerComponent; -import org.sonar.api.issue.Issue; -import org.sonar.api.utils.SonarException; -import org.sonar.core.profiling.Profiling; -import org.sonar.core.profiling.Profiling.Level; -import org.sonar.core.profiling.StopWatch; - -import javax.annotation.Nullable; -import javax.sql.DataSource; - -import java.io.File; -import java.sql.SQLException; - -public class PreviewDatabaseFactory implements ServerComponent { - public static final String H2_FILE_SUFFIX = ".h2.db"; - private static final String DIALECT = "h2"; - private static final String DRIVER = "org.h2.Driver"; - private static final String URL = "jdbc:h2:"; - private static final String SONAR = "sonar"; - private static final String USER = SONAR; - private static final String PASSWORD = SONAR; - - private final Database database; - private final Profiling profiling; - - public PreviewDatabaseFactory(Database database, Profiling profiling) { - this.database = database; - this.profiling = profiling; - } - - public File createNewDatabaseForDryRun(Long projectId, File destFolder, String dbFileName) { - StopWatch watch = profiling.start("previewdb", Level.BASIC); - - String h2Name = destFolder.getAbsolutePath() + File.separator + dbFileName; - - try { - DataSource source = database.getDataSource(); - BasicDataSource destination = create(DIALECT, DRIVER, USER, PASSWORD, URL + h2Name + ";LOG=0;CACHE_SIZE=65536;LOCK_MODE=0;UNDO_LOG=0"); - - copy(source, destination, projectId); - close(destination); - - File dbFile = new File(h2Name + H2_FILE_SUFFIX); - - long size = dbFile.length(); - String message = ""; - if (projectId == null) { - message = "Preview Database created, size is " + size + " bytes"; - } else { - message = "Preview Database for project " + projectId + " created, size is " + size + " bytes"; - } - watch.stop(message); - - return dbFile; - - } catch (SQLException e) { - throw new SonarException("Unable to create database for DryRun", e); - } - - } - - private void copy(DataSource source, DataSource dest, @Nullable Long projectId) { - DbTemplate template = new DbTemplate(profiling); - template - .copyTable(source, dest, "characteristics") - .copyTable(source, dest, "permission_templates") - .copyTable(source, dest, "perm_templates_users") - .copyTable(source, dest, "perm_templates_groups") - .copyTable(source, dest, "rules") - .copyTable(source, dest, "rules_parameters") - .copyTableColumns(source, dest, "users", new String[] {"id", "login", "name", "active"}); - if (projectId != null) { - template.copyTable(source, dest, "projects", projectQuery(projectId, false)); - - template.copyTable(source, dest, "events", "SELECT * FROM events WHERE resource_id=" + projectId); - - StringBuilder snapshotQuery = new StringBuilder() - // All snapshots of root_project for alerts on differential periods - .append("SELECT * FROM snapshots WHERE project_id=") - .append(projectId); - template.copyTable(source, dest, "snapshots", snapshotQuery.toString()); - - // All measures of snapshots of root project for alerts on differential periods - template.copyTable(source, dest, "project_measures", "SELECT m.* FROM project_measures m INNER JOIN snapshots s on m.snapshot_id=s.id " - + "WHERE s.project_id=" + projectId); - - StringBuilder issueQuery = new StringBuilder() - .append("SELECT issues.* FROM issues") - .append(" INNER JOIN (") - .append(projectQuery(projectId, true)) - .append(") resources") - .append(" ON issues.component_uuid=resources.uuid") - .append(" AND status <> '").append(Issue.STATUS_CLOSED).append("'"); - template.copyTable(source, dest, "issues", issueQuery.toString()); - } - } - - private String projectQuery(Long projectId, boolean returnOnlyIds) { - return new StringBuilder() - .append("SELECT p.").append(returnOnlyIds ? "id, p.uuid" : "*") - .append(" FROM projects p INNER JOIN snapshots s ON p.id = s.project_id") - .append(" WHERE s.islast=").append(database.getDialect().getTrueSqlValue()) - .append(" AND s.root_project_id=").append(projectId) - .append(" UNION") - .append(" SELECT p.").append(returnOnlyIds ? "id, p.uuid" : "*") - .append(" FROM projects p") - .append(" WHERE p.id=").append(projectId) - .append(" OR p.root_id=").append(projectId).toString(); - } - - private BasicDataSource create(String dialect, String driver, String user, String password, String url) { - BasicDataSource dataSource = new DbTemplate(profiling).dataSource(driver, user, password, url); - new DbTemplate(profiling).createSchema(dataSource, dialect); - return dataSource; - } - - private void close(BasicDataSource destination) throws SQLException { - destination.close(); - } - -} diff --git a/sonar-core/src/main/java/org/sonar/core/preview/PreviewCache.java b/sonar-core/src/main/java/org/sonar/core/preview/PreviewCache.java deleted file mode 100644 index 1e02ad829fe..00000000000 --- a/sonar-core/src/main/java/org/sonar/core/preview/PreviewCache.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.core.preview; - -import org.apache.commons.io.FileUtils; -import org.apache.ibatis.session.SqlSession; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.ServerExtension; -import org.sonar.api.platform.ServerFileSystem; -import org.sonar.api.utils.SonarException; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.MyBatis; -import org.sonar.core.persistence.PreviewDatabaseFactory; -import org.sonar.core.properties.PropertiesDao; -import org.sonar.core.properties.PropertyDto; -import org.sonar.core.resource.ResourceDao; -import org.sonar.core.resource.ResourceDto; - -import javax.annotation.Nullable; - -import java.io.File; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -/** - * @since 3.7.1 - */ -public class PreviewCache implements ServerExtension { - - private static final Logger LOG = LoggerFactory.getLogger(PreviewCache.class); - - public static final String SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY = "sonar.dryRun.cache.lastUpdate"; - - private MyBatis mybatis; - - private ServerFileSystem serverFileSystem; - private PropertiesDao propertiesDao; - private ResourceDao resourceDao; - - private Map lockPerProject = new HashMap(); - private Map lastTimestampPerProject = new HashMap(); - - private PreviewDatabaseFactory previewDatabaseFactory; - - public PreviewCache(MyBatis mybatis, ServerFileSystem serverFileSystem, PropertiesDao propertiesDao, ResourceDao resourceDao, PreviewDatabaseFactory previewDatabaseFactory) { - this.mybatis = mybatis; - this.serverFileSystem = serverFileSystem; - this.propertiesDao = propertiesDao; - this.resourceDao = resourceDao; - this.previewDatabaseFactory = previewDatabaseFactory; - } - - public String getPathToDatabaseFile(@Nullable Long projectId) { - long notNullProjectId = projectId != null ? projectId.longValue() : 0L; - ReadWriteLock rwl = getLock(notNullProjectId); - try { - rwl.readLock().lock(); - if (!isCacheValid(projectId)) { - // upgrade lock manually - // must unlock first to obtain writelock - rwl.readLock().unlock(); - rwl.writeLock().lock(); - // recheck - if (!isCacheValid(projectId)) { - generateNewDB(projectId); - } - // downgrade lock - // reacquire read without giving up write lock - rwl.readLock().lock(); - // unlock write, still hold read - rwl.writeLock().unlock(); - } - File dbFile = new File(getCacheLocation(projectId), lastTimestampPerProject.get(notNullProjectId) + PreviewDatabaseFactory.H2_FILE_SUFFIX); - return dbFile.getAbsolutePath(); - } finally { - rwl.readLock().unlock(); - } - } - - private boolean isCacheValid(@Nullable Long projectId) { - long notNullProjectId = projectId != null ? projectId.longValue() : 0L; - Long lastTimestampInCache = lastTimestampPerProject.get(notNullProjectId); - LOG.debug("Timestamp of last cached DB is {}", lastTimestampInCache); - if (lastTimestampInCache != null && isValid(projectId, lastTimestampInCache.longValue())) { - File dbFile = new File(getCacheLocation(projectId), lastTimestampInCache + PreviewDatabaseFactory.H2_FILE_SUFFIX); - LOG.debug("Look for existence of cached DB at {}", dbFile); - if (dbFile.exists()) { - LOG.debug("Found cached DB at {}", dbFile); - return true; - } - } - return false; - } - - private void generateNewDB(@Nullable Long projectId) { - if (projectId != null) { - LOG.debug("Generate new preview database for project [id={}]", projectId); - } else { - LOG.debug("Generate new preview database for new project"); - } - long notNullProjectId = projectId != null ? projectId.longValue() : 0L; - long newTimestamp = System.currentTimeMillis(); - File cacheLocation = getCacheLocation(projectId); - FileUtils.deleteQuietly(cacheLocation); - File dbFile = previewDatabaseFactory.createNewDatabaseForDryRun(projectId, cacheLocation, String.valueOf(newTimestamp)); - LOG.debug("Cached DB at {}", dbFile); - lastTimestampPerProject.put(notNullProjectId, newTimestamp); - } - - private synchronized ReadWriteLock getLock(long notNullProjectId) { - if (!lockPerProject.containsKey(notNullProjectId)) { - lockPerProject.put(notNullProjectId, new ReentrantReadWriteLock(true)); - } - return lockPerProject.get(notNullProjectId); - } - - private File getRootCacheLocation() { - return new File(serverFileSystem.getTempDir(), "dryRun"); - } - - public File getCacheLocation(@Nullable Long projectId) { - return new File(getRootCacheLocation(), projectId != null ? projectId.toString() : "default"); - } - - private boolean isValid(@Nullable Long projectId, long lastTimestampInCache) { - long globalTimestamp = getModificationTimestamp(null); - if (globalTimestamp > lastTimestampInCache) { - return false; - } - if (projectId != null) { - long projectTimestamp = getModificationTimestamp(projectId); - if (projectTimestamp > lastTimestampInCache) { - return false; - } - } - return true; - } - - private long getModificationTimestamp(@Nullable Long projectId) { - if (projectId == null) { - PropertyDto dto = propertiesDao.selectGlobalProperty(SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY); - if (dto == null) { - return 0; - } - return Long.valueOf(dto.getValue()); - } - // For modules look for root project last modification timestamp - ResourceDto rootProject = resourceDao.getRootProjectByComponentId(projectId); - if (rootProject == null) { - throw new SonarException("Unable to find root project for project with [id=" + projectId + "]"); - } - PropertyDto dto = propertiesDao.selectProjectProperty(rootProject.getId(), SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY); - if (dto == null) { - return 0; - } - return Long.valueOf(dto.getValue()); - } - - public void cleanAll() { - // Delete folder where preview DBs are stored - FileUtils.deleteQuietly(getRootCacheLocation()); - // Delete all lastUpdate properties to force generation of new DB - propertiesDao.deleteAllProperties(SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY); - } - - public void reportGlobalModification() { - SqlSession session = mybatis.openSession(false); - try { - reportGlobalModification(session); - session.commit(); - } finally { - MyBatis.closeQuietly(session); - } - } - - public void reportGlobalModification(SqlSession session) { - propertiesDao.setProperty(new PropertyDto().setKey(SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY).setValue(String.valueOf(System.currentTimeMillis())), session); - } - - public void reportResourceModification(String resourceKey) { - DbSession session = mybatis.openSession(false); - try { - reportResourceModification(session, resourceKey); - session.commit(); - } finally { - MyBatis.closeQuietly(session); - } - } - - public void reportResourceModification(DbSession session, String resourceKey) { - ResourceDto rootProject = resourceDao.getRootProjectByComponentKey(session, resourceKey); - if (rootProject == null) { - throw new SonarException("Unable to find root project for component with [key=" + resourceKey + "]"); - } - propertiesDao.setProperty(new PropertyDto().setKey(SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY).setResourceId(rootProject.getId()) - .setValue(String.valueOf(System.currentTimeMillis())), session); - } -} diff --git a/sonar-core/src/main/java/org/sonar/core/preview/package-info.java b/sonar-core/src/main/java/org/sonar/core/preview/package-info.java deleted file mode 100644 index d6b318ef3d9..00000000000 --- a/sonar-core/src/main/java/org/sonar/core/preview/package-info.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -@ParametersAreNonnullByDefault -package org.sonar.core.preview; - -import javax.annotation.ParametersAreNonnullByDefault; - diff --git a/sonar-core/src/main/java/org/sonar/core/timemachine/Periods.java b/sonar-core/src/main/java/org/sonar/core/timemachine/Periods.java index d5932a7aba3..5c7b90def56 100644 --- a/sonar-core/src/main/java/org/sonar/core/timemachine/Periods.java +++ b/sonar-core/src/main/java/org/sonar/core/timemachine/Periods.java @@ -19,8 +19,10 @@ */ package org.sonar.core.timemachine; +import org.sonar.api.batch.RequiresDB; + import org.apache.commons.lang.StringUtils; -import org.sonar.api.BatchExtension; +import org.sonar.api.BatchComponent; import org.sonar.api.CoreProperties; import org.sonar.api.ServerComponent; import org.sonar.api.config.Settings; @@ -35,7 +37,8 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; -public class Periods implements BatchExtension, ServerComponent { +@RequiresDB +public class Periods implements BatchComponent, ServerComponent { private final Settings settings; private final I18n i18n; diff --git a/sonar-core/src/test/java/org/sonar/core/persistence/PreviewDatabaseFactoryTest.java b/sonar-core/src/test/java/org/sonar/core/persistence/PreviewDatabaseFactoryTest.java deleted file mode 100644 index de7a7241fb1..00000000000 --- a/sonar-core/src/test/java/org/sonar/core/persistence/PreviewDatabaseFactoryTest.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.core.persistence; - -import com.google.common.io.Files; -import org.apache.commons.dbcp.BasicDataSource; -import org.apache.commons.dbutils.DbUtils; -import org.apache.commons.io.FileUtils; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.sonar.api.config.Settings; -import org.sonar.core.profiling.Profiling; - -import javax.sql.DataSource; - -import java.io.File; -import java.io.IOException; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import static org.assertj.core.api.Assertions.assertThat; - -public class PreviewDatabaseFactoryTest extends AbstractDaoTestCase { - PreviewDatabaseFactory localDatabaseFactory; - BasicDataSource dataSource; - - @Rule - public TemporaryFolder temporaryFolder = new TemporaryFolder(); - - @Before - public void setUp() throws Exception { - localDatabaseFactory = new PreviewDatabaseFactory(getDatabase(), new Profiling(new Settings())); - } - - @After - public void closeDatabase() throws SQLException { - if (dataSource != null) { - dataSource.close(); - } - } - - @Test - public void should_create_database_without_project() throws Exception { - setupData("should_create_database"); - - byte[] db = createDb(null); - dataSource = createDatabase(db); - - assertThat(countRows("projects")).isZero(); - assertThat(countRows("events")).isZero(); - assertThat(countRows("users")).isEqualTo(3); - // Verify that password column was not exported into dryRun DB - assertThat(getUserPassword(dataSource, 1)).isNull(); - } - - private byte[] createDb(Long projectId) throws IOException { - return FileUtils.readFileToByteArray(localDatabaseFactory.createNewDatabaseForDryRun(projectId, temporaryFolder.newFolder(), "foo")); - } - - @Test - public void should_create_database_with_project() throws Exception { - setupData("should_create_database"); - - byte[] database = createDb(123L); - dataSource = createDatabase(database); - - assertThat(countRows("projects")).isEqualTo(1); - assertThat(countRows("snapshots")).isEqualTo(1); - assertThat(countRows("project_measures")).isEqualTo(1); - assertThat(countRows("events")).isEqualTo(2); - } - - @Test - public void should_create_database_with_issues() throws Exception { - setupData("should_create_database_with_issues"); - - byte[] database = createDb(399L); - dataSource = createDatabase(database); - - assertThat(countRows("issues")).isEqualTo(1); - } - - @Test - public void should_export_issues_of_project_tree() throws Exception { - setupData("multi-modules-with-issues"); - - // 300 : root module -> export issues of all modules - byte[] database = createDb(300L); - dataSource = createDatabase(database); - assertThat(countRows("issues")).isEqualTo(1); - assertThat(countRows("projects")).isEqualTo(4); - assertThat(countRows("snapshots")).isEqualTo(2); - assertThat(countRows("project_measures")).isEqualTo(4); - } - - @Test - public void should_export_issues_of_sub_module() throws Exception { - setupData("multi-modules-with-issues"); - - // 301 : sub module with 1 closed issue and 1 open issue - byte[] database = createDb(301L); - dataSource = createDatabase(database); - assertThat(countRows("issues")).isEqualTo(1); - assertThat(countRows("projects")).isEqualTo(2); - assertThat(countRows("snapshots")).isEqualTo(2); - assertThat(countRows("project_measures")).isEqualTo(4); - } - - @Test - public void should_export_issues_of_sub_module_2() throws Exception { - setupData("multi-modules-with-issues"); - - // 302 : sub module without any issues - byte[] database = createDb(302L); - dataSource = createDatabase(database); - assertThat(countRows("issues")).isEqualTo(0); - } - - @Test - public void should_copy_permission_templates_data() throws Exception { - setupData("should_copy_permission_templates"); - - byte[] database = createDb(null); - dataSource = createDatabase(database); - assertThat(countRows("permission_templates")).isEqualTo(1); - assertThat(countRows("perm_templates_users")).isEqualTo(1); - assertThat(countRows("perm_templates_groups")).isEqualTo(1); - } - - private BasicDataSource createDatabase(byte[] db) throws IOException { - File file = temporaryFolder.newFile("db.h2.db"); - Files.write(db, file); - return new DbTemplate(new Profiling(new Settings())).dataSource("org.h2.Driver", "sonar", "sonar", "jdbc:h2:" + file.getAbsolutePath().replaceAll(".h2.db", "")); - } - - private int countRows(String table) { - Connection connection = null; - Statement statement = null; - ResultSet resultSet = null; - try { - connection = dataSource.getConnection(); - statement = connection.createStatement(); - resultSet = statement.executeQuery("SELECT count(*) FROM " + table); - - return resultSet.next() ? resultSet.getInt(1) : 0; - } catch (SQLException e) { - throw new IllegalStateException("Fail to get row count for table " + table, e); - } finally { - DbUtils.closeQuietly(resultSet); - DbUtils.closeQuietly(statement); - DbUtils.closeQuietly(connection); - } - } - - public String getUserPassword(DataSource dataSource, int userId) { - Connection connection = null; - Statement statement = null; - ResultSet resultSet = null; - try { - connection = dataSource.getConnection(); - statement = connection.createStatement(); - resultSet = statement.executeQuery("SELECT crypted_password FROM users WHERE id=" + userId); - - return resultSet.next() ? resultSet.getString(1) : null; - } catch (SQLException e) { - throw new IllegalStateException(e); - } finally { - DbUtils.closeQuietly(resultSet); - DbUtils.closeQuietly(statement); - DbUtils.closeQuietly(connection); - } - } -} diff --git a/sonar-core/src/test/java/org/sonar/core/preview/PreviewCacheTest.java b/sonar-core/src/test/java/org/sonar/core/preview/PreviewCacheTest.java deleted file mode 100644 index 5440062cb3a..00000000000 --- a/sonar-core/src/test/java/org/sonar/core/preview/PreviewCacheTest.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * SonarQube, open source software quality management tool. - * Copyright (C) 2008-2014 SonarSource - * mailto:contact AT sonarsource DOT com - * - * SonarQube is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * SonarQube is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.core.preview; - -import org.apache.commons.io.FileUtils; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.sonar.api.platform.ServerFileSystem; -import org.sonar.core.persistence.DbSession; -import org.sonar.core.persistence.MyBatis; -import org.sonar.core.persistence.PreviewDatabaseFactory; -import org.sonar.core.properties.PropertiesDao; -import org.sonar.core.properties.PropertyDto; -import org.sonar.core.resource.ResourceDao; -import org.sonar.core.resource.ResourceDto; - -import java.io.File; -import java.io.IOException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; -import static org.mockito.Matchers.isNull; -import static org.mockito.Mockito.*; - -public class PreviewCacheTest { - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - private MyBatis myBatis; - - private DbSession session; - - private PreviewCache dryRunCache; - private ServerFileSystem serverFileSystem; - private PropertiesDao propertiesDao; - private ResourceDao resourceDao; - - private PreviewDatabaseFactory dryRunDatabaseFactory; - - private File dryRunCacheLocation; - - @Before - public void prepare() throws IOException { - myBatis = mock(MyBatis.class); - session = mock(DbSession.class); - when(myBatis.openSession(false)).thenReturn(session); - serverFileSystem = mock(ServerFileSystem.class); - propertiesDao = mock(PropertiesDao.class); - resourceDao = mock(ResourceDao.class); - dryRunDatabaseFactory = mock(PreviewDatabaseFactory.class); - - File tempLocation = temp.newFolder(); - when(serverFileSystem.getTempDir()).thenReturn(tempLocation); - dryRunCacheLocation = new File(tempLocation, "dryRun"); - - dryRunCache = new PreviewCache(myBatis, serverFileSystem, propertiesDao, resourceDao, dryRunDatabaseFactory); - } - - @Test - public void test_getDatabaseForDryRun_on_new_project() throws Exception { - when(dryRunDatabaseFactory.createNewDatabaseForDryRun(isNull(Long.class), any(File.class), anyString())).thenAnswer(new Answer() { - public File answer(InvocationOnMock invocation) throws IOException { - Object[] args = invocation.getArguments(); - File dbFile = new File(new File(dryRunCacheLocation, "default"), args[2] + ".h2.db"); - FileUtils.write(dbFile, "fake db content"); - return dbFile; - } - }); - String path = dryRunCache.getPathToDatabaseFile(null); - assertThat(FileUtils.readFileToString(new File(path))).isEqualTo("fake db content"); - - path = dryRunCache.getPathToDatabaseFile(null); - assertThat(FileUtils.readFileToString(new File(path))).isEqualTo("fake db content"); - - verify(dryRunDatabaseFactory, times(1)).createNewDatabaseForDryRun(anyLong(), any(File.class), anyString()); - } - - @Test - public void test_getDatabaseForDryRun_on_existing_project() throws Exception { - when(dryRunDatabaseFactory.createNewDatabaseForDryRun(eq(123L), any(File.class), anyString())).thenAnswer(new Answer() { - public File answer(InvocationOnMock invocation) throws IOException { - Object[] args = invocation.getArguments(); - File dbFile = new File(new File(dryRunCacheLocation, "123"), (String) args[2] + ".h2.db"); - FileUtils.write(dbFile, "fake db content"); - return dbFile; - } - }); - when(resourceDao.getRootProjectByComponentId(123L)).thenReturn(new ResourceDto().setId(123L)); - String path = dryRunCache.getPathToDatabaseFile(123L); - assertThat(FileUtils.readFileToString(new File(path))).isEqualTo("fake db content"); - - path = dryRunCache.getPathToDatabaseFile(123L); - assertThat(FileUtils.readFileToString(new File(path))).isEqualTo("fake db content"); - - verify(dryRunDatabaseFactory, times(1)).createNewDatabaseForDryRun(anyLong(), any(File.class), anyString()); - } - - @Test - public void test_getDatabaseForDryRun_global_invalidation() throws Exception { - when(dryRunDatabaseFactory.createNewDatabaseForDryRun(isNull(Long.class), any(File.class), anyString())) - .thenAnswer(new Answer() { - public File answer(InvocationOnMock invocation) throws IOException { - Object[] args = invocation.getArguments(); - File dbFile = new File(new File(dryRunCacheLocation, "default"), (String) args[2] + ".h2.db"); - FileUtils.write(dbFile, "fake db content 1"); - return dbFile; - } - }) - .thenAnswer(new Answer() { - public File answer(InvocationOnMock invocation) throws IOException { - Object[] args = invocation.getArguments(); - File dbFile = new File(new File(dryRunCacheLocation, "default"), (String) args[2] + ".h2.db"); - FileUtils.write(dbFile, "fake db content 2"); - return dbFile; - } - }); - String path = dryRunCache.getPathToDatabaseFile(null); - assertThat(FileUtils.readFileToString(new File(path))).isEqualTo("fake db content 1"); - - // Emulate invalidation of cache - Thread.sleep(100); - when(propertiesDao.selectGlobalProperty(PreviewCache.SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY)).thenReturn(new PropertyDto().setValue("" + System.currentTimeMillis())); - - path = dryRunCache.getPathToDatabaseFile(null); - assertThat(FileUtils.readFileToString(new File(path))).isEqualTo("fake db content 2"); - - verify(dryRunDatabaseFactory, times(2)).createNewDatabaseForDryRun(anyLong(), any(File.class), anyString()); - } - - @Test - public void test_getDatabaseForDryRun_project_invalidation() throws Exception { - when(dryRunDatabaseFactory.createNewDatabaseForDryRun(eq(123L), any(File.class), anyString())) - .thenAnswer(new Answer() { - public File answer(InvocationOnMock invocation) throws IOException { - Object[] args = invocation.getArguments(); - File dbFile = new File(new File(dryRunCacheLocation, "123"), (String) args[2] + ".h2.db"); - FileUtils.write(dbFile, "fake db content 1"); - return dbFile; - } - }) - .thenAnswer(new Answer() { - public File answer(InvocationOnMock invocation) throws IOException { - Object[] args = invocation.getArguments(); - File dbFile = new File(new File(dryRunCacheLocation, "123"), (String) args[2] + ".h2.db"); - FileUtils.write(dbFile, "fake db content 2"); - return dbFile; - } - }); - when(resourceDao.getRootProjectByComponentId(123L)).thenReturn(new ResourceDto().setId(123L)); - - String path = dryRunCache.getPathToDatabaseFile(123L); - assertThat(FileUtils.readFileToString(new File(path))).isEqualTo("fake db content 1"); - - // Emulate invalidation of cache - Thread.sleep(100); - when(propertiesDao.selectProjectProperty(123L, PreviewCache.SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY)).thenReturn(new PropertyDto().setValue("" + System.currentTimeMillis())); - - path = dryRunCache.getPathToDatabaseFile(123L); - assertThat(FileUtils.readFileToString(new File(path))).isEqualTo("fake db content 2"); - - verify(dryRunDatabaseFactory, times(2)).createNewDatabaseForDryRun(anyLong(), any(File.class), anyString()); - } - - @Test - public void test_get_cache_location() throws Exception { - File tempFolder = temp.newFolder(); - when(serverFileSystem.getTempDir()).thenReturn(tempFolder); - - assertThat(dryRunCache.getCacheLocation(null)).isEqualTo(new File(new File(tempFolder, "dryRun"), "default")); - assertThat(dryRunCache.getCacheLocation(123L)).isEqualTo(new File(new File(tempFolder, "dryRun"), "123")); - } - - @Test - public void test_clean_all() throws Exception { - File tempFolder = temp.newFolder(); - when(serverFileSystem.getTempDir()).thenReturn(tempFolder); - File cacheLocation = dryRunCache.getCacheLocation(null); - FileUtils.forceMkdir(cacheLocation); - - dryRunCache.cleanAll(); - verify(propertiesDao).deleteAllProperties(PreviewCache.SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY); - - assertThat(cacheLocation).doesNotExist(); - } - - @Test - public void test_report_global_modification() { - dryRunCache.reportGlobalModification(); - - ArgumentCaptor argument = ArgumentCaptor.forClass(PropertyDto.class); - verify(propertiesDao).setProperty(argument.capture(), eq(session)); - assertThat(argument.getValue().getKey()).isEqualTo(PreviewCache.SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY); - assertThat(argument.getValue().getValue()).isNotNull(); - - verify(session).commit(); - } - - @Test - public void test_report_resource_modification() { - when(resourceDao.getRootProjectByComponentKey(session, "foo")).thenReturn(new ResourceDto().setId(456L)); - - dryRunCache.reportResourceModification("foo"); - - verify(propertiesDao).setProperty( - new PropertyDto() - .setKey(PreviewCache.SONAR_PREVIEW_CACHE_LAST_UPDATE_KEY) - .setValue(anyString()) - .setResourceId(456L), eq(session)); - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java b/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java index e8eba564068..f7b2c06227f 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java @@ -19,6 +19,8 @@ */ package org.sonar.api; +import org.sonar.api.batch.AnalysisMode; + /** * Non-exhaustive list of constants of core properties. * @@ -369,7 +371,9 @@ public interface CoreProperties { /** * @since 3.4 + * @deprecated since 5.1 use {@link AnalysisMode} to check existing mode */ + @Deprecated String DRY_RUN = "sonar.dryRun"; /** @@ -396,13 +400,14 @@ public interface CoreProperties { /** * @since 3.7 - * @deprecated in 4.0 replaced by {@link CoreProperties#PREVIEW_READ_TIMEOUT_SEC} + * @deprecated in 4.0 no more used */ @Deprecated String DRY_RUN_READ_TIMEOUT_SEC = "sonar.dryRun.readTimeout"; /** * @since 4.0 + * @deprecated in 5.1 no more used */ String PREVIEW_READ_TIMEOUT_SEC = "sonar.preview.readTimeout"; @@ -432,9 +437,9 @@ public interface CoreProperties { String ANALYSIS_MODE_INCREMENTAL = "incremental"; /** - * @since 4.4 + * @since 5.1 */ - String ANALYSIS_MODE_SENSOR = "sensor"; + String ANALYSIS_MODE_MEDIUM_TEST = "mediumtest"; /** * @since 4.0 diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/AnalysisMode.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/AnalysisMode.java new file mode 100644 index 00000000000..300215a1591 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/AnalysisMode.java @@ -0,0 +1,34 @@ +/* + * 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.api.batch; + +import org.sonar.api.BatchComponent; + +/** + * Use this component to find the current running mode. + * @since 5.1 + */ +public interface AnalysisMode extends BatchComponent { + + boolean isPreview(); + + boolean isIncremental(); + +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/Decorator.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/Decorator.java index b3f2792b507..661135d1587 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/Decorator.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/Decorator.java @@ -25,6 +25,7 @@ import org.sonar.api.resources.Resource; /** * @since 1.10 */ +@RequiresDB public interface Decorator extends BatchExtension, CheckProject { /** diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/RequiresDB.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/RequiresDB.java new file mode 100644 index 00000000000..ea6f38cc371 --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/RequiresDB.java @@ -0,0 +1,37 @@ +/* + * 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.api.batch; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The presence of this annotation on an extension class indicates that the extension + * requires database access. As a result such extension will be disabled in preview mode. + * + * + * @since 3.4 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface RequiresDB { +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java index b32be9c7ab0..e5e403a43ec 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java @@ -19,6 +19,7 @@ */ package org.sonar.api.batch.sensor; +import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.rule.ActiveRules; @@ -60,6 +61,11 @@ public interface SensorContext { */ ActiveRules activeRules(); + /** + * Get analysis mode. + */ + AnalysisMode analysisMode(); + // ----------- MEASURES -------------- /** diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorDescriptor.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorDescriptor.java index 06abd08f58c..a247e392870 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorDescriptor.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorDescriptor.java @@ -79,4 +79,9 @@ public interface SensorDescriptor { */ SensorDescriptor requireProperties(String... propertyKeys); + /** + * Should this sensor be disabled in preview mode. Default is to run all sensors in preview mode. + */ + SensorDescriptor disabledInPreview(); + } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptor.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptor.java index 8f6925f814d..a5c2e6a387a 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptor.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/DefaultSensorDescriptor.java @@ -34,6 +34,7 @@ public class DefaultSensorDescriptor implements SensorDescriptor { private InputFile.Type type = null; private String[] ruleRepositories = new String[0]; private String[] properties = new String[0]; + private boolean disabledInPreview = false; public String name() { return name; @@ -56,6 +57,10 @@ public class DefaultSensorDescriptor implements SensorDescriptor { return Arrays.asList(properties); } + public boolean isDisabledInPreview() { + return disabledInPreview; + } + @Override public DefaultSensorDescriptor name(String name) { this.name = name; @@ -101,4 +106,10 @@ public class DefaultSensorDescriptor implements SensorDescriptor { return this; } + @Override + public DefaultSensorDescriptor disabledInPreview() { + this.disabledInPreview = true; + return this; + } + }