dependencies {
// please keep the list grouped by configuration and ordered by name
-// compile 'org.picocontainer:picocontainer'
compile 'org.slf4j:jul-to-slf4j'
compile 'org.slf4j:slf4j-api'
import org.sonar.ce.task.projectanalysis.container.ContainerFactoryImpl;
import org.sonar.ce.task.projectanalysis.taskprocessor.ReportTaskProcessor;
-import org.sonar.server.computation.queue.ReportSubmitter;
+import org.sonar.server.ce.queue.ReportSubmitter;
import org.sonar.core.platform.Module;
-import org.sonar.ce.task.projectanalysis.container.ContainerFactoryImpl;
-import org.sonar.ce.task.projectanalysis.taskprocessor.ReportTaskProcessor;
import org.sonar.server.computation.task.step.ComputationStepExecutor;
public class ProjectAnalysisTaskModule extends Module {
private static final Logger LOG = Loggers.get(PostProjectAnalysisTasksExecutor.class);
- private final org.sonar.ce.queue.CeTask ceTask;
+ private final org.sonar.server.computation.CeTask ceTask;
private final AnalysisMetadataHolder analysisMetadataHolder;
private final QualityGateHolder qualityGateHolder;
private final QualityGateStatusHolder qualityGateStatusHolder;
/**
* Constructor used by Pico when there is no {@link PostProjectAnalysisTask} in the container.
*/
- public PostProjectAnalysisTasksExecutor(org.sonar.ce.queue.CeTask ceTask,
- AnalysisMetadataHolder analysisMetadataHolder,
- QualityGateHolder qualityGateHolder, QualityGateStatusHolder qualityGateStatusHolder,
- BatchReportReader reportReader, System2 system2) {
+ public PostProjectAnalysisTasksExecutor(org.sonar.server.computation.CeTask ceTask,
+ AnalysisMetadataHolder analysisMetadataHolder,
+ QualityGateHolder qualityGateHolder, QualityGateStatusHolder qualityGateStatusHolder,
+ BatchReportReader reportReader, System2 system2) {
this(ceTask, analysisMetadataHolder, qualityGateHolder, qualityGateStatusHolder, reportReader, system2, null);
}
- public PostProjectAnalysisTasksExecutor(org.sonar.ce.queue.CeTask ceTask,
- AnalysisMetadataHolder analysisMetadataHolder,
- QualityGateHolder qualityGateHolder, QualityGateStatusHolder qualityGateStatusHolder,
- BatchReportReader reportReader, System2 system2,
- @Nullable PostProjectAnalysisTask[] postProjectAnalysisTasks) {
+ public PostProjectAnalysisTasksExecutor(org.sonar.server.computation.CeTask ceTask,
+ AnalysisMetadataHolder analysisMetadataHolder,
+ QualityGateHolder qualityGateHolder, QualityGateStatusHolder qualityGateStatusHolder,
+ BatchReportReader reportReader, System2 system2,
+ @Nullable PostProjectAnalysisTask[] postProjectAnalysisTasks) {
this.analysisMetadataHolder = analysisMetadataHolder;
this.qualityGateHolder = qualityGateHolder;
this.qualityGateStatusHolder = qualityGateStatusHolder;
}
}
- private static Project createProject(org.sonar.ce.queue.CeTask ceTask) {
+ private static Project createProject(org.sonar.server.computation.CeTask ceTask) {
return new ProjectImpl(
ceTask.getComponentUuid(),
ceTask.getComponentKey(),
package org.sonar.ce.task.projectanalysis.batch;
import java.io.File;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
public interface BatchReportDirectoryHolder {
/**
package org.sonar.ce.task.projectanalysis.container;
import javax.annotation.Nullable;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
import org.sonar.core.platform.ComponentContainer;
import org.sonar.plugin.ce.ReportAnalysisComponentProvider;
import org.sonar.server.computation.task.container.TaskContainer;
package org.sonar.ce.task.projectanalysis.container;
import javax.annotation.Nullable;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
import org.sonar.core.platform.ComponentContainer;
import org.sonar.plugin.ce.ReportAnalysisComponentProvider;
import org.sonar.server.computation.task.container.TaskContainer;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nullable;
-import org.sonar.ce.organization.DefaultOrganizationLoader;
-import org.sonar.ce.queue.CeTask;
-import org.sonar.ce.settings.SettingsLoader;
+import org.sonar.server.computation.organization.DefaultOrganizationLoader;
+import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.settings.SettingsLoader;
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderImpl;
import org.sonar.ce.task.projectanalysis.api.posttask.PostProjectAnalysisTasksExecutor;
import org.sonar.ce.task.projectanalysis.batch.BatchReportDirectoryHolderImpl;
import com.google.common.collect.Iterables;
import java.sql.SQLException;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
import org.sonar.db.Database;
import org.sonar.db.source.FileSourceDto;
import org.sonar.server.platform.db.migration.step.DataChange;
import org.sonar.api.config.Configuration;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
import static java.nio.charset.StandardCharsets.UTF_8;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.dbcleaner;
+
+import java.util.Collection;
+import java.util.List;
+import org.sonar.api.server.ServerSide;
+import org.sonar.db.purge.PurgeListener;
+import org.sonar.server.component.index.ComponentIndexer;
+import org.sonar.server.issue.index.IssueIndexer;
+import org.sonar.server.test.index.TestIndexer;
+
+@ServerSide
+public class IndexPurgeListener implements PurgeListener {
+ private final TestIndexer testIndexer;
+ private final IssueIndexer issueIndexer;
+ private final ComponentIndexer componentIndexer;
+
+ public IndexPurgeListener(TestIndexer testIndexer, IssueIndexer issueIndexer, ComponentIndexer componentIndexer) {
+ this.testIndexer = testIndexer;
+ this.issueIndexer = issueIndexer;
+ this.componentIndexer = componentIndexer;
+ }
+
+ @Override
+ public void onComponentsDisabling(String projectUuid, Collection<String> disabledComponentUuids) {
+ componentIndexer.delete(projectUuid, disabledComponentUuids);
+ disabledComponentUuids.forEach(this::onComponentDisabling);
+ }
+
+ private void onComponentDisabling(String uuid) {
+ testIndexer.deleteByFile(uuid);
+ }
+
+ @Override
+ public void onIssuesRemoval(String projectUuid, List<String> issueKeys) {
+ issueIndexer.deleteByKeys(projectUuid, issueKeys);
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.dbcleaner;
+
+import java.util.Collection;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.ce.ComputeEngineSide;
+import org.sonar.api.config.Configuration;
+import org.sonar.api.server.ServerSide;
+import org.sonar.api.utils.TimeUtils;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.db.DbSession;
+import org.sonar.db.purge.IdUuidPair;
+import org.sonar.db.purge.PurgeConfiguration;
+import org.sonar.db.purge.PurgeDao;
+import org.sonar.db.purge.PurgeListener;
+import org.sonar.db.purge.PurgeProfiler;
+import org.sonar.db.purge.period.DefaultPeriodCleaner;
+
+import static org.sonar.db.purge.PurgeConfiguration.newDefaultPurgeConfiguration;
+
+@ServerSide
+@ComputeEngineSide
+public class ProjectCleaner {
+ private static final Logger LOG = Loggers.get(ProjectCleaner.class);
+
+ private final PurgeProfiler profiler;
+ private final PurgeListener purgeListener;
+ private final PurgeDao purgeDao;
+ private final DefaultPeriodCleaner periodCleaner;
+
+ public ProjectCleaner(PurgeDao purgeDao, DefaultPeriodCleaner periodCleaner, PurgeProfiler profiler, PurgeListener purgeListener) {
+ this.purgeDao = purgeDao;
+ this.periodCleaner = periodCleaner;
+ this.profiler = profiler;
+ this.purgeListener = purgeListener;
+ }
+
+ public ProjectCleaner purge(DbSession session, IdUuidPair rootId, Configuration projectConfig, Collection<String> disabledComponentUuids) {
+ long start = System.currentTimeMillis();
+ profiler.reset();
+
+ PurgeConfiguration configuration = newDefaultPurgeConfiguration(projectConfig, rootId, disabledComponentUuids);
+
+ periodCleaner.clean(session, configuration.rootProjectIdUuid().getUuid(), projectConfig);
+ purgeDao.purge(session, configuration, purgeListener, profiler);
+
+ session.commit();
+ logProfiling(start, projectConfig);
+ return this;
+ }
+
+ private void logProfiling(long start, Configuration config) {
+ if (config.getBoolean(CoreProperties.PROFILING_LOG_PROPERTY).orElse(false)) {
+ long duration = System.currentTimeMillis() - start;
+ LOG.info("\n -------- Profiling for purge: " + TimeUtils.formatDuration(duration) + " --------\n");
+ profiler.dump(duration, LOG);
+ LOG.info("\n -------- End of profiling for purge --------\n");
+ }
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.ce.task.projectanalysis.purge;
+
+import org.sonar.ce.task.projectanalysis.component.Component;
+import org.sonar.ce.task.projectanalysis.component.ConfigurationRepository;
+import org.sonar.ce.task.projectanalysis.component.DbIdsRepository;
+import org.sonar.ce.task.projectanalysis.component.DepthTraversalTypeAwareCrawler;
+import org.sonar.ce.task.projectanalysis.component.DisabledComponentsHolder;
+import org.sonar.ce.task.projectanalysis.component.TreeRootHolder;
+import org.sonar.ce.task.projectanalysis.component.TypeAwareVisitorAdapter;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.purge.IdUuidPair;
+import org.sonar.server.computation.dbcleaner.ProjectCleaner;
+import org.sonar.server.computation.task.step.ComputationStep;
+
+import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT;
+import static org.sonar.ce.task.projectanalysis.component.Component.Type.VIEW;
+import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order.PRE_ORDER;
+import static org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit.reportMaxDepth;
+
+public class PurgeDatastoresStep implements ComputationStep {
+
+ private final ProjectCleaner projectCleaner;
+ private final DbClient dbClient;
+ private final DbIdsRepository dbIdsRepository;
+ private final TreeRootHolder treeRootHolder;
+ private final ConfigurationRepository configRepository;
+ private final DisabledComponentsHolder disabledComponentsHolder;
+
+ public PurgeDatastoresStep(DbClient dbClient, ProjectCleaner projectCleaner, DbIdsRepository dbIdsRepository, TreeRootHolder treeRootHolder,
+ ConfigurationRepository configRepository, DisabledComponentsHolder disabledComponentsHolder) {
+ this.projectCleaner = projectCleaner;
+ this.dbClient = dbClient;
+ this.dbIdsRepository = dbIdsRepository;
+ this.treeRootHolder = treeRootHolder;
+ this.configRepository = configRepository;
+ this.disabledComponentsHolder = disabledComponentsHolder;
+ }
+
+ @Override
+ public void execute() {
+ new DepthTraversalTypeAwareCrawler(
+ new TypeAwareVisitorAdapter(reportMaxDepth(PROJECT).withViewsMaxDepth(VIEW), PRE_ORDER) {
+ @Override
+ public void visitProject(Component project) {
+ execute(project);
+ }
+
+ @Override
+ public void visitView(Component view) {
+ execute(view);
+ }
+ }).visit(treeRootHolder.getRoot());
+ }
+
+ private void execute(Component root) {
+ try (DbSession dbSession = dbClient.openSession(true)) {
+ IdUuidPair idUuidPair = new IdUuidPair(dbIdsRepository.getComponentId(root), root.getUuid());
+ projectCleaner.purge(dbSession, idUuidPair, configRepository.getConfiguration(), disabledComponentsHolder.getUuids());
+ dbSession.commit();
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return "Purge db";
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.server.computation.dbcleaner;
+
+import javax.annotation.ParametersAreNonnullByDefault;
import org.sonar.api.utils.MessageException;
import org.sonar.api.utils.TempFolder;
import org.sonar.api.utils.ZipUtils;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.ce.CeTaskInputDao;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.utils.MessageException;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
import org.sonar.ce.task.projectanalysis.component.BranchLoader;
import org.sonar.core.component.ComponentKeys;
import org.sonar.core.platform.PluginRepository;
import org.sonar.ce.task.projectanalysis.analysis.Organization;
import org.sonar.ce.task.projectanalysis.analysis.ScannerPlugin;
import org.sonar.ce.task.projectanalysis.batch.BatchReportReader;
-import org.sonar.ce.task.projectanalysis.component.BranchLoader;
import org.sonar.server.computation.task.step.ComputationStep;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.organization.OrganizationFlags;
*/
package org.sonar.ce.task.projectanalysis.step;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
import org.sonar.core.util.CloseableIterator;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import java.util.Optional;
import javax.annotation.concurrent.Immutable;
-import org.sonar.ce.queue.CeTaskResult;
+import org.sonar.server.computation.CeTaskResult;
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.server.computation.task.step.ComputationStep;
import org.sonar.server.computation.taskprocessor.MutableTaskResultHolder;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.ce.task.projectanalysis.step;
-
-import org.sonar.ce.task.projectanalysis.component.Component;
-import org.sonar.ce.task.projectanalysis.component.ConfigurationRepository;
-import org.sonar.ce.task.projectanalysis.component.DbIdsRepository;
-import org.sonar.ce.task.projectanalysis.component.DepthTraversalTypeAwareCrawler;
-import org.sonar.ce.task.projectanalysis.component.DisabledComponentsHolder;
-import org.sonar.ce.task.projectanalysis.component.TreeRootHolder;
-import org.sonar.ce.task.projectanalysis.component.TypeAwareVisitorAdapter;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.purge.IdUuidPair;
-import org.sonar.server.computation.dbcleaner.ProjectCleaner;
-import org.sonar.server.computation.task.step.ComputationStep;
-
-import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT;
-import static org.sonar.ce.task.projectanalysis.component.Component.Type.VIEW;
-import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order.PRE_ORDER;
-import static org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit.reportMaxDepth;
-
-public class PurgeDatastoresStep implements ComputationStep {
-
- private final ProjectCleaner projectCleaner;
- private final DbClient dbClient;
- private final DbIdsRepository dbIdsRepository;
- private final TreeRootHolder treeRootHolder;
- private final ConfigurationRepository configRepository;
- private final DisabledComponentsHolder disabledComponentsHolder;
-
- public PurgeDatastoresStep(DbClient dbClient, ProjectCleaner projectCleaner, DbIdsRepository dbIdsRepository, TreeRootHolder treeRootHolder,
- ConfigurationRepository configRepository, DisabledComponentsHolder disabledComponentsHolder) {
- this.projectCleaner = projectCleaner;
- this.dbClient = dbClient;
- this.dbIdsRepository = dbIdsRepository;
- this.treeRootHolder = treeRootHolder;
- this.configRepository = configRepository;
- this.disabledComponentsHolder = disabledComponentsHolder;
- }
-
- @Override
- public void execute() {
- new DepthTraversalTypeAwareCrawler(
- new TypeAwareVisitorAdapter(reportMaxDepth(PROJECT).withViewsMaxDepth(VIEW), PRE_ORDER) {
- @Override
- public void visitProject(Component project) {
- execute(project);
- }
-
- @Override
- public void visitView(Component view) {
- execute(view);
- }
- }).visit(treeRootHolder.getRoot());
- }
-
- private void execute(Component root) {
- try (DbSession dbSession = dbClient.openSession(true)) {
- IdUuidPair idUuidPair = new IdUuidPair(dbIdsRepository.getComponentId(root), root.getUuid());
- projectCleaner.purge(dbSession, idUuidPair, configRepository.getConfiguration(), disabledComponentsHolder.getUuids());
- dbSession.commit();
- }
- }
-
- @Override
- public String getDescription() {
- return "Purge db";
- }
-}
import java.util.Arrays;
import java.util.List;
+import org.sonar.ce.task.projectanalysis.purge.PurgeDatastoresStep;
import org.sonar.server.computation.task.container.TaskContainer;
import org.sonar.ce.task.projectanalysis.filemove.FileMoveDetectionStep;
import org.sonar.server.computation.task.step.ComputationStep;
import java.util.Collections;
import java.util.Set;
import javax.annotation.CheckForNull;
-import org.sonar.ce.queue.CeTask;
-import org.sonar.ce.queue.CeTaskResult;
+import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.CeTaskResult;
import org.sonar.ce.task.projectanalysis.container.ContainerFactory;
import org.sonar.ce.taskprocessor.CeTaskProcessor;
import org.sonar.core.platform.ComponentContainer;
import org.sonar.api.ce.posttask.PostProjectAnalysisTask;
import org.sonar.api.ce.posttask.Project;
import org.sonar.api.utils.System2;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
import org.sonar.ce.task.projectanalysis.analysis.Branch;
import org.sonar.ce.task.projectanalysis.analysis.Organization;
import org.junit.Test;
import org.picocontainer.DefaultPicoContainer;
import org.picocontainer.PicoContainer;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
import org.sonar.ce.task.projectanalysis.step.PersistComponentsStep;
import org.sonar.core.platform.ComponentContainer;
import org.sonar.plugin.ce.ReportAnalysisComponentProvider;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.sonar.api.utils.System2;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
import org.sonar.db.DbTester;
import org.sonar.db.source.FileSourceDto;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
import org.sonar.db.Database;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.runner.RunWith;
import org.sonar.api.config.Configuration;
import org.sonar.api.config.internal.MapSettings;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
import org.sonar.ce.task.projectanalysis.filemove.ScoreMatrix.ScoreFile;
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.dbcleaner;
+
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Test;
+import org.sonar.server.component.index.ComponentIndexer;
+import org.sonar.server.issue.index.IssueIndexer;
+import org.sonar.server.test.index.TestIndexer;
+
+import static java.util.Arrays.asList;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class IndexPurgeListenerTest {
+
+ TestIndexer testIndexer = mock(TestIndexer.class);
+ IssueIndexer issueIndexer = mock(IssueIndexer.class);
+ ComponentIndexer componentIndexer = mock(ComponentIndexer.class);
+
+ IndexPurgeListener underTest = new IndexPurgeListener(testIndexer, issueIndexer, componentIndexer);
+
+ @Test
+ public void test_onComponentDisabling() {
+ String uuid = "123456";
+ String projectUuid = "P789";
+ List<String> uuids = Arrays.asList(uuid);
+ underTest.onComponentsDisabling(projectUuid, uuids);
+
+ verify(testIndexer).deleteByFile(uuid);
+ verify(componentIndexer).delete(projectUuid, uuids);
+ }
+
+ @Test
+ public void test_onIssuesRemoval() {
+ underTest.onIssuesRemoval("P1", asList("ISSUE1", "ISSUE2"));
+
+ verify(issueIndexer).deleteByKeys("P1", asList("ISSUE1", "ISSUE2"));
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.dbcleaner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.config.PropertyDefinitions;
+import org.sonar.api.config.internal.MapSettings;
+import org.sonar.core.config.PurgeConstants;
+import org.sonar.core.config.PurgeProperties;
+import org.sonar.db.DbSession;
+import org.sonar.db.purge.IdUuidPair;
+import org.sonar.db.purge.PurgeDao;
+import org.sonar.db.purge.PurgeListener;
+import org.sonar.db.purge.PurgeProfiler;
+import org.sonar.db.purge.period.DefaultPeriodCleaner;
+
+import static java.util.Collections.emptyList;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+public class ProjectCleanerTest {
+
+ private ProjectCleaner underTest;
+ private PurgeDao dao = mock(PurgeDao.class);
+ private PurgeProfiler profiler = mock(PurgeProfiler.class);
+ private DefaultPeriodCleaner periodCleaner = mock(DefaultPeriodCleaner.class);
+ private PurgeListener purgeListener = mock(PurgeListener.class);
+ private MapSettings settings = new MapSettings(new PropertyDefinitions(PurgeProperties.all()));
+
+ @Before
+ public void before() {
+ this.underTest = new ProjectCleaner(dao, periodCleaner, profiler, purgeListener);
+ }
+
+ @Test
+ public void no_profiling_when_property_is_false() {
+ settings.setProperty(CoreProperties.PROFILING_LOG_PROPERTY, false);
+
+ underTest.purge(mock(DbSession.class), mock(IdUuidPair.class), settings.asConfig(), emptyList());
+
+ verify(profiler, never()).dump(anyLong(), any());
+ }
+
+ @Test
+ public void profiling_when_property_is_true() {
+ settings.setProperty(CoreProperties.PROFILING_LOG_PROPERTY, true);
+
+ underTest.purge(mock(DbSession.class), mock(IdUuidPair.class), settings.asConfig(), emptyList());
+
+ verify(profiler).dump(anyLong(), any());
+ }
+
+ @Test
+ public void call_period_cleaner_index_client_and_purge_dao() {
+ settings.setProperty(PurgeConstants.DAYS_BEFORE_DELETING_CLOSED_ISSUES, 5);
+
+ underTest.purge(mock(DbSession.class), mock(IdUuidPair.class), settings.asConfig(), emptyList());
+
+ verify(periodCleaner).clean(any(), any(), any());
+ verify(dao).purge(any(), any(), any(), any());
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.ce.task.projectanalysis.purge;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import com.tngtech.java.junit.dataprovider.UseDataProvider;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+import org.sonar.api.config.internal.MapSettings;
+import org.sonar.ce.task.projectanalysis.component.Component;
+import org.sonar.ce.task.projectanalysis.component.ConfigurationRepository;
+import org.sonar.ce.task.projectanalysis.component.MutableDbIdsRepositoryRule;
+import org.sonar.ce.task.projectanalysis.component.MutableDisabledComponentsHolder;
+import org.sonar.ce.task.projectanalysis.component.ReportComponent;
+import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
+import org.sonar.ce.task.projectanalysis.component.ViewsComponent;
+import org.sonar.ce.task.projectanalysis.step.BaseStepTest;
+import org.sonar.db.DbClient;
+import org.sonar.db.purge.IdUuidPair;
+import org.sonar.server.computation.dbcleaner.ProjectCleaner;
+import org.sonar.server.computation.task.step.ComputationStep;
+import org.sonar.server.util.WrapInSingleElementArray;
+
+import static java.util.Arrays.asList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+@RunWith(DataProviderRunner.class)
+public class PurgeDatastoresStepTest extends BaseStepTest {
+
+ private static final String PROJECT_KEY = "PROJECT_KEY";
+ private static final long PROJECT_ID = 123L;
+ private static final String PROJECT_UUID = "UUID-1234";
+
+ @Rule
+ public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
+ @Rule
+ public MutableDbIdsRepositoryRule dbIdsRepository = MutableDbIdsRepositoryRule.standalone();
+
+ private ProjectCleaner projectCleaner = mock(ProjectCleaner.class);
+ private ConfigurationRepository settingsRepository = mock(ConfigurationRepository.class);
+ private MutableDisabledComponentsHolder disabledComponentsHolder = mock(MutableDisabledComponentsHolder.class, RETURNS_DEEP_STUBS);
+
+ private PurgeDatastoresStep underTest = new PurgeDatastoresStep(mock(DbClient.class, Mockito.RETURNS_DEEP_STUBS), projectCleaner, dbIdsRepository, treeRootHolder,
+ settingsRepository, disabledComponentsHolder);
+
+ @Test
+ public void call_purge_method_of_the_purge_task_for_project() {
+ Component project = ReportComponent.builder(Component.Type.PROJECT, 1).setUuid(PROJECT_UUID).setKey(PROJECT_KEY).build();
+
+ verify_call_purge_method_of_the_purge_task(project);
+ }
+
+ @Test
+ public void call_purge_method_of_the_purge_task_for_view() {
+ Component project = ViewsComponent.builder(Component.Type.VIEW, PROJECT_KEY).setUuid(PROJECT_UUID).build();
+
+ verify_call_purge_method_of_the_purge_task(project);
+ }
+
+ @DataProvider
+ public static Object[][] nonRootProjectComponentTypes() {
+ return dataproviderFromComponentTypeValues(new Predicate<Component.Type>() {
+ @Override
+ public boolean apply(Component.Type input) {
+ return input.isReportType() && input != Component.Type.PROJECT;
+ }
+ });
+ }
+
+ @Test
+ @UseDataProvider("nonRootProjectComponentTypes")
+ public void do_not_call_purge_method_of_the_purge_task_for_other_report_components(Component.Type type) {
+ Component component = ReportComponent.builder(type, 1).setUuid(PROJECT_UUID).setKey(PROJECT_KEY).build();
+
+ verify_do_not_call_purge_method_of_the_purge_task(component);
+ }
+
+ @DataProvider
+ public static Object[][] nonRootViewsComponentTypes() {
+ return dataproviderFromComponentTypeValues(new Predicate<Component.Type>() {
+ @Override
+ public boolean apply(Component.Type input) {
+ return input.isViewsType() && input != Component.Type.VIEW;
+ }
+ });
+ }
+
+ @Test
+ @UseDataProvider("nonRootViewsComponentTypes")
+ public void do_not_call_purge_method_of_the_purge_task_for_other_views_components(Component.Type type) {
+ Component component = ViewsComponent.builder(type, PROJECT_KEY).setUuid(PROJECT_UUID).build();
+
+ verify_do_not_call_purge_method_of_the_purge_task(component);
+ }
+
+ private void verify_do_not_call_purge_method_of_the_purge_task(Component component) {
+ treeRootHolder.setRoot(component);
+
+ underTest.execute();
+
+ verifyNoMoreInteractions(projectCleaner);
+ }
+
+ private void verify_call_purge_method_of_the_purge_task(Component project) {
+ treeRootHolder.setRoot(project);
+ when(settingsRepository.getConfiguration()).thenReturn(new MapSettings().asConfig());
+ dbIdsRepository.setComponentId(project, PROJECT_ID);
+
+ underTest.execute();
+
+ ArgumentCaptor<IdUuidPair> argumentCaptor = ArgumentCaptor.forClass(IdUuidPair.class);
+ verify(projectCleaner).purge(any(), argumentCaptor.capture(), any(), any());
+ assertThat(argumentCaptor.getValue().getId()).isEqualTo(PROJECT_ID);
+ assertThat(argumentCaptor.getValue().getUuid()).isEqualTo(PROJECT_UUID);
+ }
+
+ private static Object[][] dataproviderFromComponentTypeValues(Predicate<Component.Type> predicate) {
+ return FluentIterable.from(asList(Component.Type.values()))
+ .filter(predicate)
+ .transform(WrapInSingleElementArray.INSTANCE)
+ .toArray(Object[].class);
+ }
+
+ @Override
+ protected ComputationStep step() {
+ return underTest;
+ }
+
+}
import org.sonar.api.utils.internal.JUnitTempFolder;
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
import org.sonar.ce.task.projectanalysis.batch.BatchReportDirectoryHolderImpl;
import org.sonar.ce.task.projectanalysis.batch.MutableBatchReportDirectoryHolder;
import org.sonar.db.DbTester;
import org.sonar.api.Plugin;
import org.sonar.api.utils.MessageException;
import org.sonar.api.utils.System2;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
import org.sonar.ce.task.projectanalysis.analysis.MutableAnalysisMetadataHolderRule;
import org.sonar.ce.task.projectanalysis.analysis.Organization;
import org.sonar.ce.task.projectanalysis.analysis.ScannerPlugin;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.utils.System2;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
import org.sonar.ce.task.projectanalysis.batch.BatchReportReaderRule;
import org.sonar.core.util.CloseableIterator;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.ce.task.projectanalysis.step;
-
-import com.google.common.base.Predicate;
-import com.google.common.collect.FluentIterable;
-import com.tngtech.java.junit.dataprovider.DataProvider;
-import com.tngtech.java.junit.dataprovider.DataProviderRunner;
-import com.tngtech.java.junit.dataprovider.UseDataProvider;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
-import org.sonar.api.config.internal.MapSettings;
-import org.sonar.ce.task.projectanalysis.component.Component;
-import org.sonar.ce.task.projectanalysis.component.ConfigurationRepository;
-import org.sonar.ce.task.projectanalysis.component.MutableDbIdsRepositoryRule;
-import org.sonar.ce.task.projectanalysis.component.MutableDisabledComponentsHolder;
-import org.sonar.ce.task.projectanalysis.component.ReportComponent;
-import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule;
-import org.sonar.ce.task.projectanalysis.component.ViewsComponent;
-import org.sonar.db.DbClient;
-import org.sonar.db.purge.IdUuidPair;
-import org.sonar.server.computation.dbcleaner.ProjectCleaner;
-import org.sonar.server.computation.task.step.ComputationStep;
-import org.sonar.server.util.WrapInSingleElementArray;
-
-import static java.util.Arrays.asList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-@RunWith(DataProviderRunner.class)
-public class PurgeDatastoresStepTest extends BaseStepTest {
-
- private static final String PROJECT_KEY = "PROJECT_KEY";
- private static final long PROJECT_ID = 123L;
- private static final String PROJECT_UUID = "UUID-1234";
-
- @Rule
- public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
- @Rule
- public MutableDbIdsRepositoryRule dbIdsRepository = MutableDbIdsRepositoryRule.standalone();
-
- private ProjectCleaner projectCleaner = mock(ProjectCleaner.class);
- private ConfigurationRepository settingsRepository = mock(ConfigurationRepository.class);
- private MutableDisabledComponentsHolder disabledComponentsHolder = mock(MutableDisabledComponentsHolder.class, RETURNS_DEEP_STUBS);
-
- private PurgeDatastoresStep underTest = new PurgeDatastoresStep(mock(DbClient.class, Mockito.RETURNS_DEEP_STUBS), projectCleaner, dbIdsRepository, treeRootHolder,
- settingsRepository, disabledComponentsHolder);
-
- @Test
- public void call_purge_method_of_the_purge_task_for_project() {
- Component project = ReportComponent.builder(Component.Type.PROJECT, 1).setUuid(PROJECT_UUID).setKey(PROJECT_KEY).build();
-
- verify_call_purge_method_of_the_purge_task(project);
- }
-
- @Test
- public void call_purge_method_of_the_purge_task_for_view() {
- Component project = ViewsComponent.builder(Component.Type.VIEW, PROJECT_KEY).setUuid(PROJECT_UUID).build();
-
- verify_call_purge_method_of_the_purge_task(project);
- }
-
- @DataProvider
- public static Object[][] nonRootProjectComponentTypes() {
- return dataproviderFromComponentTypeValues(new Predicate<Component.Type>() {
- @Override
- public boolean apply(Component.Type input) {
- return input.isReportType() && input != Component.Type.PROJECT;
- }
- });
- }
-
- @Test
- @UseDataProvider("nonRootProjectComponentTypes")
- public void do_not_call_purge_method_of_the_purge_task_for_other_report_components(Component.Type type) {
- Component component = ReportComponent.builder(type, 1).setUuid(PROJECT_UUID).setKey(PROJECT_KEY).build();
-
- verify_do_not_call_purge_method_of_the_purge_task(component);
- }
-
- @DataProvider
- public static Object[][] nonRootViewsComponentTypes() {
- return dataproviderFromComponentTypeValues(new Predicate<Component.Type>() {
- @Override
- public boolean apply(Component.Type input) {
- return input.isViewsType() && input != Component.Type.VIEW;
- }
- });
- }
-
- @Test
- @UseDataProvider("nonRootViewsComponentTypes")
- public void do_not_call_purge_method_of_the_purge_task_for_other_views_components(Component.Type type) {
- Component component = ViewsComponent.builder(type, PROJECT_KEY).setUuid(PROJECT_UUID).build();
-
- verify_do_not_call_purge_method_of_the_purge_task(component);
- }
-
- private void verify_do_not_call_purge_method_of_the_purge_task(Component component) {
- treeRootHolder.setRoot(component);
-
- underTest.execute();
-
- verifyNoMoreInteractions(projectCleaner);
- }
-
- private void verify_call_purge_method_of_the_purge_task(Component project) {
- treeRootHolder.setRoot(project);
- when(settingsRepository.getConfiguration()).thenReturn(new MapSettings().asConfig());
- dbIdsRepository.setComponentId(project, PROJECT_ID);
-
- underTest.execute();
-
- ArgumentCaptor<IdUuidPair> argumentCaptor = ArgumentCaptor.forClass(IdUuidPair.class);
- verify(projectCleaner).purge(any(), argumentCaptor.capture(), any(), any());
- assertThat(argumentCaptor.getValue().getId()).isEqualTo(PROJECT_ID);
- assertThat(argumentCaptor.getValue().getUuid()).isEqualTo(PROJECT_UUID);
- }
-
- private static Object[][] dataproviderFromComponentTypeValues(Predicate<Component.Type> predicate) {
- return FluentIterable.from(asList(Component.Type.values()))
- .filter(predicate)
- .transform(WrapInSingleElementArray.INSTANCE)
- .toArray(Object[].class);
- }
-
- @Override
- protected ComputationStep step() {
- return underTest;
- }
-
-}
package org.sonar.ce;
import org.sonar.ce.configuration.CeConfigurationImpl;
-import org.sonar.ce.log.CeLogging;
+import org.sonar.server.computation.log.CeTaskLogging;
import org.sonar.ce.monitoring.CeDatabaseMBeanImpl;
import org.sonar.core.platform.Module;
import org.sonar.process.systeminfo.JvmPropertiesSection;
protected void configureModule() {
add(
CeConfigurationImpl.class,
- CeLogging.class,
+ CeTaskLogging.class,
CeDatabaseMBeanImpl.class,
new JvmStateSection("Compute Engine JVM State"),
new JvmPropertiesSection("Compute Engine JVM Properties"),
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Scopes;
import org.sonar.api.utils.System2;
-import org.sonar.ce.queue.CeTask;
-import org.sonar.ce.queue.CeTaskResult;
+import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.CeTaskResult;
import org.sonar.ce.taskprocessor.CeWorker;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import java.util.Set;
import javax.annotation.Nullable;
import org.sonar.db.ce.CeActivityDto.Status;
+import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.CeTaskResult;
/**
* Queue of pending Compute Engine tasks. Both producer and consumer actions
import org.sonar.db.ce.CeActivityDto;
import org.sonar.db.ce.CeQueueDao;
import org.sonar.db.ce.CeQueueDto;
+import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.CeTaskResult;
import org.sonar.server.computation.task.step.TypedException;
import org.sonar.server.organization.DefaultOrganizationProvider;
package org.sonar.ce.taskprocessor;
import javax.annotation.Nullable;
-import org.sonar.ce.log.CeLogging;
-import org.sonar.ce.queue.CeTask;
-import org.sonar.ce.queue.CeTaskResult;
+import org.sonar.server.computation.log.CeTaskLogging;
+import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.CeTaskResult;
import org.sonar.db.ce.CeActivityDto;
/**
- * {@link CeWorker.ExecutionListener} responsible of calling {@link CeLogging#initForTask(CeTask)} and
- * {@link CeLogging#clearForTask()}.
+ * {@link CeWorker.ExecutionListener} responsible of calling {@link CeTaskLogging#initForTask(CeTask)} and
+ * {@link CeTaskLogging#clearForTask()}.
*/
public class CeLoggingWorkerExecutionListener implements CeWorker.ExecutionListener {
- private final CeLogging ceLogging;
+ private final CeTaskLogging ceTaskLogging;
- public CeLoggingWorkerExecutionListener(CeLogging ceLogging) {
- this.ceLogging = ceLogging;
+ public CeLoggingWorkerExecutionListener(CeTaskLogging ceTaskLogging) {
+ this.ceTaskLogging = ceTaskLogging;
}
@Override
public void onStart(CeTask ceTask) {
- ceLogging.initForTask(ceTask);
+ ceTaskLogging.initForTask(ceTask);
}
@Override
public void onEnd(CeTask ceTask, CeActivityDto.Status status, @Nullable CeTaskResult taskResult, @Nullable Throwable error) {
- ceLogging.clearForTask();
+ ceTaskLogging.clearForTask();
}
}
package org.sonar.ce.taskprocessor;
import java.util.Optional;
-import org.sonar.ce.queue.CeTask;
-import org.sonar.ce.taskprocessor.CeTaskProcessor;
+import org.sonar.server.computation.CeTask;
public interface CeTaskProcessorRepository {
import java.util.Map;
import java.util.Optional;
import javax.annotation.Nonnull;
-import org.sonar.ce.queue.CeTask;
-import org.sonar.ce.taskprocessor.CeTaskProcessor;
+import org.sonar.server.computation.CeTask;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.FluentIterable.from;
import java.util.concurrent.Callable;
import javax.annotation.Nullable;
import org.sonar.ce.queue.CeQueue;
-import org.sonar.ce.queue.CeTask;
-import org.sonar.ce.queue.CeTaskResult;
+import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.CeTaskResult;
import org.sonar.db.ce.CeActivityDto;
/**
import org.sonar.api.utils.MessageException;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
-import org.sonar.ce.queue.CeTask;
-import org.sonar.ce.queue.CeTaskResult;
+import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.CeTaskResult;
import org.sonar.ce.queue.InternalCeQueue;
import org.sonar.core.util.logs.Profiler;
import org.sonar.db.ce.CeActivityDto;
import org.mockito.ArgumentCaptor;
import org.sonar.api.notifications.Notification;
import org.sonar.api.utils.System2;
-import org.sonar.ce.queue.CeTask;
-import org.sonar.ce.queue.CeTaskResult;
+import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.CeTaskResult;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.db.RowNotFoundException;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.organization.OrganizationDto;
+import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.CeTaskResult;
import org.sonar.server.computation.task.step.TypedException;
import org.sonar.server.organization.DefaultOrganization;
import org.sonar.server.organization.DefaultOrganizationProvider;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.ce.taskprocessor;
-
-import java.util.Random;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.sonar.ce.log.CeLogging;
-import org.sonar.ce.queue.CeTask;
-import org.sonar.db.ce.CeActivityDto;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-public class CeLoggingWorkerExecutionListenerTest {
- private CeLogging ceLogging = Mockito.spy(CeLogging.class);
- private CeLoggingWorkerExecutionListener underTest = new CeLoggingWorkerExecutionListener(ceLogging);
-
- @Test
- public void onStart_calls_initForTask_with_method_argument() {
- CeTask ceTask = Mockito.mock(CeTask.class);
-
- underTest.onStart(ceTask);
-
- verify(ceLogging).initForTask(ceTask);
- verifyNoMoreInteractions(ceLogging);
- }
-
- @Test
- public void onEnd_calls_clearForTask() {
- underTest.onEnd(mock(CeTask.class),
- CeActivityDto.Status.values()[new Random().nextInt(CeActivityDto.Status.values().length)],
- null, null);
-
- verify(ceLogging).clearForTask();
- verifyNoMoreInteractions(ceLogging);
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.ce.taskprocessor;
+
+import java.util.Random;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.sonar.server.computation.log.CeTaskLogging;
+import org.sonar.server.computation.CeTask;
+import org.sonar.db.ce.CeActivityDto;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+public class CeTaskLoggingWorkerExecutionListenerTest {
+ private CeTaskLogging ceTaskLogging = Mockito.spy(CeTaskLogging.class);
+ private CeLoggingWorkerExecutionListener underTest = new CeLoggingWorkerExecutionListener(ceTaskLogging);
+
+ @Test
+ public void onStart_calls_initForTask_with_method_argument() {
+ CeTask ceTask = Mockito.mock(CeTask.class);
+
+ underTest.onStart(ceTask);
+
+ verify(ceTaskLogging).initForTask(ceTask);
+ verifyNoMoreInteractions(ceTaskLogging);
+ }
+
+ @Test
+ public void onEnd_calls_clearForTask() {
+ underTest.onEnd(mock(CeTask.class),
+ CeActivityDto.Status.values()[new Random().nextInt(CeActivityDto.Status.values().length)],
+ null, null);
+
+ verify(ceTaskLogging).clearForTask();
+ verifyNoMoreInteractions(ceTaskLogging);
+ }
+}
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.sonar.ce.queue.CeTask;
-import org.sonar.ce.queue.CeTaskResult;
+import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.CeTaskResult;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Optional;
import java.util.Set;
import org.junit.rules.ExternalResource;
-import org.sonar.ce.queue.CeTask;
-import org.sonar.ce.queue.CeTaskResult;
+import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.CeTaskResult;
import static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;
import org.sonar.api.utils.MessageException;
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
import org.sonar.ce.queue.InternalCeQueue;
import org.sonar.db.ce.CeActivityDto;
import org.sonar.db.ce.CeTaskTypes;
package org.sonar.ce;
import org.sonar.ce.http.CeHttpClientImpl;
-import org.sonar.ce.log.CeLogging;
+import org.sonar.server.computation.log.CeTaskLogging;
import org.sonar.ce.queue.CeQueueImpl;
import org.sonar.ce.taskprocessor.ReportTaskProcessorDeclaration;
import org.sonar.core.platform.Module;
-import org.sonar.server.computation.queue.ReportSubmitter;
+import org.sonar.server.ce.queue.ReportSubmitter;
public class CeModule extends Module {
@Override
protected void configureModule() {
- add(CeLogging.class,
+ add(CeTaskLogging.class,
CeHttpClientImpl.class,
// Queue
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.ce.log;
-
-import org.slf4j.MDC;
-import org.sonar.ce.queue.CeTask;
-
-public class CeLogging {
-
- static final String MDC_CE_TASK_UUID = "ceTaskUuid";
-
- public void initForTask(CeTask task) {
- MDC.put(MDC_CE_TASK_UUID, task.getUuid());
- }
-
- public void clearForTask() {
- MDC.remove(MDC_CE_TASK_UUID);
- }
-
-}
import org.sonar.process.logging.LogLevelConfig;
import org.sonar.server.app.ServerProcessLogging;
-import static org.sonar.ce.log.CeLogging.MDC_CE_TASK_UUID;
+import static org.sonar.server.computation.log.CeTaskLogging.MDC_CE_TASK_UUID;
/**
* Configure logback for the Compute Engine process. Logs are written to file "ce.log" in SQ's log directory.
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.ce.organization;
-
-import org.picocontainer.Startable;
-import org.sonar.api.ce.ComputeEngineSide;
-import org.sonar.server.computation.task.container.EagerStart;
-import org.sonar.server.organization.DefaultOrganizationCache;
-
-@EagerStart
-@ComputeEngineSide
-public class DefaultOrganizationLoader implements Startable {
- private final DefaultOrganizationCache defaultOrganizationCache;
-
- public DefaultOrganizationLoader(DefaultOrganizationCache defaultOrganizationCache) {
- this.defaultOrganizationCache = defaultOrganizationCache;
- }
-
- @Override
- public void start() {
- defaultOrganizationCache.load();
- }
-
- @Override
- public void stop() {
- defaultOrganizationCache.unload();
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.ce.organization;
-
-import javax.annotation.ParametersAreNonnullByDefault;
import java.util.Optional;
import org.sonar.db.DbSession;
import org.sonar.db.ce.CeQueueDto;
+import org.sonar.server.computation.CeTask;
/**
* Queue of pending Compute Engine tasks. Both producer and consumer actions
import org.sonar.db.ce.CeActivityDto;
import org.sonar.db.ce.CeQueueDto;
import org.sonar.db.component.ComponentDto;
+import org.sonar.server.computation.CeTask;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.property.InternalProperties;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.ce.queue;
-
-import com.google.common.base.MoreObjects;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.Immutable;
-
-import static com.google.common.base.Strings.emptyToNull;
-import static java.util.Objects.requireNonNull;
-
-@Immutable
-public class CeTask {
-
- private final String organizationUuid;
- private final String type;
- private final String uuid;
- private final String componentUuid;
- private final String componentKey;
- private final String componentName;
- private final String submitterUuid;
-
- private CeTask(Builder builder) {
- this.organizationUuid = requireNonNull(emptyToNull(builder.organizationUuid), "organizationUuid can't be null nor empty");
- this.uuid = requireNonNull(emptyToNull(builder.uuid), "uuid can't be null nor empty");
- this.type = requireNonNull(emptyToNull(builder.type), "type can't be null nor empty");
- this.componentUuid = emptyToNull(builder.componentUuid);
- this.componentKey = emptyToNull(builder.componentKey);
- this.componentName = emptyToNull(builder.componentName);
- this.submitterUuid = emptyToNull(builder.submitterUuid);
- }
-
- public String getOrganizationUuid() {
- return organizationUuid;
- }
-
- public String getUuid() {
- return uuid;
- }
-
- public String getType() {
- return type;
- }
-
- @CheckForNull
- public String getComponentUuid() {
- return componentUuid;
- }
-
- @CheckForNull
- public String getComponentKey() {
- return componentKey;
- }
-
- @CheckForNull
- public String getComponentName() {
- return componentName;
- }
-
- @CheckForNull
- public String getSubmitterUuid() {
- return submitterUuid;
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this)
- .add("organizationUuid", organizationUuid)
- .add("type", type)
- .add("uuid", uuid)
- .add("componentUuid", componentUuid)
- .add("componentKey", componentKey)
- .add("componentName", componentName)
- .add("submitterUuid", submitterUuid)
- .toString();
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- CeTask ceTask = (CeTask) o;
- return uuid.equals(ceTask.uuid);
- }
-
- @Override
- public int hashCode() {
- return uuid.hashCode();
- }
-
- public static final class Builder {
- private String organizationUuid;
- private String uuid;
- private String type;
- private String componentUuid;
- private String componentKey;
- private String componentName;
- private String submitterUuid;
-
- public Builder setOrganizationUuid(String organizationUuid) {
- this.organizationUuid = organizationUuid;
- return this;
- }
-
- // FIXME remove this method when organization support is added to the Compute Engine queue
- public boolean hasOrganizationUuid() {
- return organizationUuid != null;
- }
-
- public Builder setUuid(String uuid) {
- this.uuid = uuid;
- return this;
- }
-
- public Builder setType(String type) {
- this.type = type;
- return this;
- }
-
- public Builder setComponentUuid(String componentUuid) {
- this.componentUuid = componentUuid;
- return this;
- }
-
- public Builder setComponentKey(@Nullable String s) {
- this.componentKey = s;
- return this;
- }
-
- public Builder setComponentName(@Nullable String s) {
- this.componentName = s;
- return this;
- }
-
- public Builder setSubmitterUuid(@Nullable String s) {
- this.submitterUuid = s;
- return this;
- }
-
- public CeTask build() {
- return new CeTask(this);
- }
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.ce.queue;
-
-import java.util.Optional;
-import org.sonar.ce.taskprocessor.CeTaskProcessor;
-
-/**
- * Represents the result of the processing of a {@link CeTask}.
- *
- * @see {@link CeTaskProcessor#process(CeTask)}
- */
-@FunctionalInterface
-public interface CeTaskResult {
- /**
- * The UUID of the analysis created, if any, for the Component in {@link CeTask}
- */
- Optional<String> getAnalysisUuid();
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.ce.settings;
-
-import org.picocontainer.Startable;
-import org.sonar.api.ce.ComputeEngineSide;
-import org.sonar.server.computation.task.container.EagerStart;
-import org.sonar.server.computation.task.container.TaskContainerImpl;
-import org.sonar.server.setting.ThreadLocalSettings;
-
-/**
- * Add this class as the first components in the {@link TaskContainerImpl}
- * to trigger loading of Thread local specific {@link org.sonar.api.config.Settings} in {@link ThreadLocalSettings}.
- */
-@EagerStart
-@ComputeEngineSide
-public class SettingsLoader implements Startable {
- private final ThreadLocalSettings threadLocalSettings;
-
- public SettingsLoader(ThreadLocalSettings threadLocalSettings) {
- this.threadLocalSettings = threadLocalSettings;
- }
-
- @Override
- public void start() {
- threadLocalSettings.load();
- }
-
- @Override
- public void stop() {
- threadLocalSettings.unload();
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.ce.settings;
-
-import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.CheckForNull;
import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.server.ServerSide;
-import org.sonar.ce.queue.CeTask;
-import org.sonar.ce.queue.CeTaskResult;
+import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.CeTaskResult;
/**
* This interface is used to provide the processing code for {@link CeTask}s of one or more type to be called by the
import java.util.Collections;
import java.util.Set;
-import org.sonar.ce.queue.CeTask;
-import org.sonar.ce.queue.CeTaskResult;
+import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.CeTaskResult;
import org.sonar.db.ce.CeTaskTypes;
/**
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.ce.queue;
+
+import com.google.common.base.Optional;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import javax.annotation.Nullable;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Scopes;
+import org.sonar.api.server.ServerSide;
+import org.sonar.ce.queue.CeQueue;
+import org.sonar.server.computation.CeTask;
+import org.sonar.ce.queue.CeTaskSubmit;
+import org.sonar.core.component.ComponentKeys;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.ce.CeTaskCharacteristicDto;
+import org.sonar.db.ce.CeTaskTypes;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.permission.OrganizationPermission;
+import org.sonar.server.component.ComponentUpdater;
+import org.sonar.server.component.NewComponent;
+import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.permission.PermissionTemplateService;
+import org.sonar.server.user.UserSession;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.lang.String.format;
+import static org.apache.commons.lang.StringUtils.defaultIfBlank;
+import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
+import static org.sonar.server.component.NewComponent.newComponentBuilder;
+import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;
+
+@ServerSide
+public class ReportSubmitter {
+
+ private final CeQueue queue;
+ private final UserSession userSession;
+ private final ComponentUpdater componentUpdater;
+ private final PermissionTemplateService permissionTemplateService;
+ private final DbClient dbClient;
+ private final UuidFactory uuidFactory;
+
+ public ReportSubmitter(CeQueue queue, UserSession userSession, ComponentUpdater componentUpdater,
+ PermissionTemplateService permissionTemplateService, UuidFactory uuidFactory, DbClient dbClient) {
+ this.queue = queue;
+ this.userSession = userSession;
+ this.componentUpdater = componentUpdater;
+ this.permissionTemplateService = permissionTemplateService;
+ this.uuidFactory = uuidFactory;
+ this.dbClient = dbClient;
+ }
+
+ public CeTask submit(String organizationKey, String projectKey, @Nullable String projectBranch, @Nullable String projectName, InputStream reportInput) {
+ return submit(organizationKey, projectKey, projectBranch, projectName, Collections.emptyMap(), reportInput);
+ }
+
+ /**
+ * @throws NotFoundException if the organization with the specified key does not exist
+ * @throws IllegalArgumentException if the organization with the specified key is not the organization of the specified project (when it already exists in DB)
+ */
+ public CeTask submit(String organizationKey, String projectKey, @Nullable String projectBranch, @Nullable String projectName, Map<String, String> characteristics,
+ InputStream reportInput) {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ OrganizationDto organizationDto = getOrganizationDtoOrFail(dbSession, organizationKey);
+ String effectiveProjectKey = ComponentKeys.createKey(projectKey, projectBranch);
+ Optional<ComponentDto> component = dbClient.componentDao().selectByKey(dbSession, effectiveProjectKey);
+ validateProject(dbSession, component, projectKey);
+ ensureOrganizationIsConsistent(component, organizationDto);
+ ComponentDto project = component.or(() -> createProject(dbSession, organizationDto, projectKey, projectBranch, projectName));
+ checkScanPermission(project);
+ return submitReport(dbSession, reportInput, project, characteristics);
+ }
+ }
+
+ private void checkScanPermission(ComponentDto project) {
+ // this is a specific and inconsistent behavior. For legacy reasons, "technical users"
+ // defined on an organization should be able to analyze a project even if
+ // they don't have the direct permission on the project.
+ // That means that dropping the permission on the project does not have any effects
+ // if user has still the permission on the organization
+ if (!userSession.hasComponentPermission(SCAN_EXECUTION, project) &&
+ !userSession.hasPermission(OrganizationPermission.SCAN, project.getOrganizationUuid())) {
+ throw insufficientPrivilegesException();
+ }
+ }
+
+ private OrganizationDto getOrganizationDtoOrFail(DbSession dbSession, String organizationKey) {
+ return dbClient.organizationDao().selectByKey(dbSession, organizationKey)
+ .orElseThrow(() -> new NotFoundException(format("Organization with key '%s' does not exist", organizationKey)));
+ }
+
+ private void validateProject(DbSession dbSession, Optional<ComponentDto> project, String rawProjectKey) {
+ List<String> errors = new ArrayList<>();
+ if (!project.isPresent()) {
+ return;
+ }
+
+ ComponentDto component = project.get();
+ if (!Qualifiers.PROJECT.equals(component.qualifier()) || !Scopes.PROJECT.equals(component.scope())) {
+ errors.add(format("Component '%s' is not a project", rawProjectKey));
+ }
+ if (!component.projectUuid().equals(component.uuid())) {
+ // Project key is already used as a module of another project
+ ComponentDto anotherBaseProject = dbClient.componentDao().selectOrFailByUuid(dbSession, component.projectUuid());
+ errors.add(format("The project '%s' is already defined in SonarQube but as a module of project '%s'. "
+ + "If you really want to stop directly analysing project '%s', please first delete it from SonarQube and then relaunch the analysis of project '%s'.",
+ rawProjectKey, anotherBaseProject.getKey(), anotherBaseProject.getKey(), rawProjectKey));
+ }
+ if (!errors.isEmpty()) {
+ throw BadRequestException.create(errors);
+ }
+ }
+
+ private static void ensureOrganizationIsConsistent(Optional<ComponentDto> project, OrganizationDto organizationDto) {
+ if (project.isPresent()) {
+ checkArgument(project.get().getOrganizationUuid().equals(organizationDto.getUuid()),
+ "Organization of component with key '%s' does not match specified organization '%s'",
+ project.get().getDbKey(), organizationDto.getKey());
+ }
+ }
+
+ private ComponentDto createProject(DbSession dbSession, OrganizationDto organization, String projectKey, @Nullable String deprecatedBranch, @Nullable String projectName) {
+ userSession.checkPermission(OrganizationPermission.PROVISION_PROJECTS, organization);
+ Integer userId = userSession.getUserId();
+
+ String effectiveProjectKey = ComponentKeys.createEffectiveKey(projectKey, deprecatedBranch);
+ boolean wouldCurrentUserHaveScanPermission = permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(
+ dbSession, organization.getUuid(), userId, effectiveProjectKey, Qualifiers.PROJECT);
+ if (!wouldCurrentUserHaveScanPermission) {
+ throw insufficientPrivilegesException();
+ }
+
+ boolean newProjectPrivate = dbClient.organizationDao().getNewProjectPrivate(dbSession, organization);
+
+ NewComponent newProject = newComponentBuilder()
+ .setOrganizationUuid(organization.getUuid())
+ .setKey(projectKey)
+ .setName(defaultIfBlank(projectName, projectKey))
+ .setBranch(deprecatedBranch)
+ .setQualifier(Qualifiers.PROJECT)
+ .setPrivate(newProjectPrivate)
+ .build();
+ return componentUpdater.create(dbSession, newProject, userId);
+ }
+
+ private CeTask submitReport(DbSession dbSession, InputStream reportInput, ComponentDto project, Map<String, String> characteristicsMap) {
+ CeTaskSubmit.Builder submit = queue.prepareSubmit();
+ List<CeTaskCharacteristicDto> characteristics = characteristicsMap.entrySet().stream()
+ .map(e -> toDto(submit.getUuid(), e.getKey(), e.getValue())).collect(Collectors.toList());
+
+ // the report file must be saved before submitting the task
+ dbClient.ceTaskInputDao().insert(dbSession, submit.getUuid(), reportInput);
+ if (!characteristics.isEmpty()) {
+ dbClient.ceTaskCharacteristicsDao().insert(dbSession, characteristics);
+ }
+ dbSession.commit();
+
+ submit.setType(CeTaskTypes.REPORT);
+ submit.setComponentUuid(project.uuid());
+ submit.setSubmitterUuid(userSession.getUuid());
+ return queue.submit(submit.build());
+ }
+
+ private CeTaskCharacteristicDto toDto(String taskUuid, String key, String value) {
+ CeTaskCharacteristicDto dto = new CeTaskCharacteristicDto();
+ dto.setTaskUuid(taskUuid);
+ dto.setKey(key);
+ dto.setValue(value);
+ dto.setUuid(uuidFactory.create());
+ return dto;
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.server.ce.queue;
+
+import javax.annotation.ParametersAreNonnullByDefault;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
-import org.sonar.ce.queue.CeTask;
-import org.sonar.server.computation.queue.ReportSubmitter;
+import org.sonar.server.computation.CeTask;
+import org.sonar.server.ce.queue.ReportSubmitter;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.ws.WsUtils;
import org.sonarqube.ws.Ce;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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;
+
+import com.google.common.base.MoreObjects;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+
+import static com.google.common.base.Strings.emptyToNull;
+import static java.util.Objects.requireNonNull;
+
+@Immutable
+public class CeTask {
+
+ private final String organizationUuid;
+ private final String type;
+ private final String uuid;
+ private final String componentUuid;
+ private final String componentKey;
+ private final String componentName;
+ private final String submitterUuid;
+
+ private CeTask(Builder builder) {
+ this.organizationUuid = requireNonNull(emptyToNull(builder.organizationUuid), "organizationUuid can't be null nor empty");
+ this.uuid = requireNonNull(emptyToNull(builder.uuid), "uuid can't be null nor empty");
+ this.type = requireNonNull(emptyToNull(builder.type), "type can't be null nor empty");
+ this.componentUuid = emptyToNull(builder.componentUuid);
+ this.componentKey = emptyToNull(builder.componentKey);
+ this.componentName = emptyToNull(builder.componentName);
+ this.submitterUuid = emptyToNull(builder.submitterUuid);
+ }
+
+ public String getOrganizationUuid() {
+ return organizationUuid;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ @CheckForNull
+ public String getComponentUuid() {
+ return componentUuid;
+ }
+
+ @CheckForNull
+ public String getComponentKey() {
+ return componentKey;
+ }
+
+ @CheckForNull
+ public String getComponentName() {
+ return componentName;
+ }
+
+ @CheckForNull
+ public String getSubmitterUuid() {
+ return submitterUuid;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("organizationUuid", organizationUuid)
+ .add("type", type)
+ .add("uuid", uuid)
+ .add("componentUuid", componentUuid)
+ .add("componentKey", componentKey)
+ .add("componentName", componentName)
+ .add("submitterUuid", submitterUuid)
+ .toString();
+ }
+
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ CeTask ceTask = (CeTask) o;
+ return uuid.equals(ceTask.uuid);
+ }
+
+ @Override
+ public int hashCode() {
+ return uuid.hashCode();
+ }
+
+ public static final class Builder {
+ private String organizationUuid;
+ private String uuid;
+ private String type;
+ private String componentUuid;
+ private String componentKey;
+ private String componentName;
+ private String submitterUuid;
+
+ public Builder setOrganizationUuid(String organizationUuid) {
+ this.organizationUuid = organizationUuid;
+ return this;
+ }
+
+ // FIXME remove this method when organization support is added to the Compute Engine queue
+ public boolean hasOrganizationUuid() {
+ return organizationUuid != null;
+ }
+
+ public Builder setUuid(String uuid) {
+ this.uuid = uuid;
+ return this;
+ }
+
+ public Builder setType(String type) {
+ this.type = type;
+ return this;
+ }
+
+ public Builder setComponentUuid(String componentUuid) {
+ this.componentUuid = componentUuid;
+ return this;
+ }
+
+ public Builder setComponentKey(@Nullable String s) {
+ this.componentKey = s;
+ return this;
+ }
+
+ public Builder setComponentName(@Nullable String s) {
+ this.componentName = s;
+ return this;
+ }
+
+ public Builder setSubmitterUuid(@Nullable String s) {
+ this.submitterUuid = s;
+ return this;
+ }
+
+ public CeTask build() {
+ return new CeTask(this);
+ }
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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;
+
+import java.util.Optional;
+
+/**
+ * Represents the result of the processing of a {@link CeTask}.
+ */
+@FunctionalInterface
+public interface CeTaskResult {
+ /**
+ * The UUID of the analysis created, if any, for the Component in {@link CeTask}
+ */
+ Optional<String> getAnalysisUuid();
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.dbcleaner;
-
-import java.util.Collection;
-import java.util.List;
-import org.sonar.api.server.ServerSide;
-import org.sonar.db.purge.PurgeListener;
-import org.sonar.server.component.index.ComponentIndexer;
-import org.sonar.server.issue.index.IssueIndexer;
-import org.sonar.server.test.index.TestIndexer;
-
-@ServerSide
-public class IndexPurgeListener implements PurgeListener {
- private final TestIndexer testIndexer;
- private final IssueIndexer issueIndexer;
- private final ComponentIndexer componentIndexer;
-
- public IndexPurgeListener(TestIndexer testIndexer, IssueIndexer issueIndexer, ComponentIndexer componentIndexer) {
- this.testIndexer = testIndexer;
- this.issueIndexer = issueIndexer;
- this.componentIndexer = componentIndexer;
- }
-
- @Override
- public void onComponentsDisabling(String projectUuid, Collection<String> disabledComponentUuids) {
- componentIndexer.delete(projectUuid, disabledComponentUuids);
- disabledComponentUuids.forEach(this::onComponentDisabling);
- }
-
- private void onComponentDisabling(String uuid) {
- testIndexer.deleteByFile(uuid);
- }
-
- @Override
- public void onIssuesRemoval(String projectUuid, List<String> issueKeys) {
- issueIndexer.deleteByKeys(projectUuid, issueKeys);
- }
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.dbcleaner;
-
-import java.util.Collection;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.ce.ComputeEngineSide;
-import org.sonar.api.config.Configuration;
-import org.sonar.api.server.ServerSide;
-import org.sonar.api.utils.TimeUtils;
-import org.sonar.api.utils.log.Logger;
-import org.sonar.api.utils.log.Loggers;
-import org.sonar.db.DbSession;
-import org.sonar.db.purge.IdUuidPair;
-import org.sonar.db.purge.PurgeConfiguration;
-import org.sonar.db.purge.PurgeDao;
-import org.sonar.db.purge.PurgeListener;
-import org.sonar.db.purge.PurgeProfiler;
-import org.sonar.db.purge.period.DefaultPeriodCleaner;
-
-import static org.sonar.db.purge.PurgeConfiguration.newDefaultPurgeConfiguration;
-
-@ServerSide
-@ComputeEngineSide
-public class ProjectCleaner {
- private static final Logger LOG = Loggers.get(ProjectCleaner.class);
-
- private final PurgeProfiler profiler;
- private final PurgeListener purgeListener;
- private final PurgeDao purgeDao;
- private final DefaultPeriodCleaner periodCleaner;
-
- public ProjectCleaner(PurgeDao purgeDao, DefaultPeriodCleaner periodCleaner, PurgeProfiler profiler, PurgeListener purgeListener) {
- this.purgeDao = purgeDao;
- this.periodCleaner = periodCleaner;
- this.profiler = profiler;
- this.purgeListener = purgeListener;
- }
-
- public ProjectCleaner purge(DbSession session, IdUuidPair rootId, Configuration projectConfig, Collection<String> disabledComponentUuids) {
- long start = System.currentTimeMillis();
- profiler.reset();
-
- PurgeConfiguration configuration = newDefaultPurgeConfiguration(projectConfig, rootId, disabledComponentUuids);
-
- periodCleaner.clean(session, configuration.rootProjectIdUuid().getUuid(), projectConfig);
- purgeDao.purge(session, configuration, purgeListener, profiler);
-
- session.commit();
- logProfiling(start, projectConfig);
- return this;
- }
-
- private void logProfiling(long start, Configuration config) {
- if (config.getBoolean(CoreProperties.PROFILING_LOG_PROPERTY).orElse(false)) {
- long duration = System.currentTimeMillis() - start;
- LOG.info("\n -------- Profiling for purge: " + TimeUtils.formatDuration(duration) + " --------\n");
- profiler.dump(duration, LOG);
- LOG.info("\n -------- End of profiling for purge --------\n");
- }
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.server.computation.dbcleaner;
-
-import javax.annotation.ParametersAreNonnullByDefault;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.log;
+
+import org.slf4j.MDC;
+import org.sonar.server.computation.CeTask;
+
+public class CeTaskLogging {
+
+ public static final String MDC_CE_TASK_UUID = "ceTaskUuid";
+
+ public void initForTask(CeTask task) {
+ MDC.put(MDC_CE_TASK_UUID, task.getUuid());
+ }
+
+ public void clearForTask() {
+ MDC.remove(MDC_CE_TASK_UUID);
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.server.computation.log;
+
+import javax.annotation.ParametersAreNonnullByDefault;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.organization;
+
+import org.picocontainer.Startable;
+import org.sonar.api.ce.ComputeEngineSide;
+import org.sonar.server.computation.task.container.EagerStart;
+import org.sonar.server.organization.DefaultOrganizationCache;
+
+@EagerStart
+@ComputeEngineSide
+public class DefaultOrganizationLoader implements Startable {
+ private final DefaultOrganizationCache defaultOrganizationCache;
+
+ public DefaultOrganizationLoader(DefaultOrganizationCache defaultOrganizationCache) {
+ this.defaultOrganizationCache = defaultOrganizationCache;
+ }
+
+ @Override
+ public void start() {
+ defaultOrganizationCache.load();
+ }
+
+ @Override
+ public void stop() {
+ defaultOrganizationCache.unload();
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.server.computation.organization;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.queue;
-
-import com.google.common.base.Optional;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-import javax.annotation.Nullable;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Scopes;
-import org.sonar.api.server.ServerSide;
-import org.sonar.ce.queue.CeQueue;
-import org.sonar.ce.queue.CeTask;
-import org.sonar.ce.queue.CeTaskSubmit;
-import org.sonar.core.component.ComponentKeys;
-import org.sonar.core.util.UuidFactory;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.ce.CeTaskCharacteristicDto;
-import org.sonar.db.ce.CeTaskTypes;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.organization.OrganizationDto;
-import org.sonar.db.permission.OrganizationPermission;
-import org.sonar.server.component.ComponentUpdater;
-import org.sonar.server.component.NewComponent;
-import org.sonar.server.exceptions.BadRequestException;
-import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.permission.PermissionTemplateService;
-import org.sonar.server.user.UserSession;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.lang.String.format;
-import static org.apache.commons.lang.StringUtils.defaultIfBlank;
-import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
-import static org.sonar.server.component.NewComponent.newComponentBuilder;
-import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException;
-
-@ServerSide
-public class ReportSubmitter {
-
- private final CeQueue queue;
- private final UserSession userSession;
- private final ComponentUpdater componentUpdater;
- private final PermissionTemplateService permissionTemplateService;
- private final DbClient dbClient;
- private final UuidFactory uuidFactory;
-
- public ReportSubmitter(CeQueue queue, UserSession userSession, ComponentUpdater componentUpdater,
- PermissionTemplateService permissionTemplateService, UuidFactory uuidFactory, DbClient dbClient) {
- this.queue = queue;
- this.userSession = userSession;
- this.componentUpdater = componentUpdater;
- this.permissionTemplateService = permissionTemplateService;
- this.uuidFactory = uuidFactory;
- this.dbClient = dbClient;
- }
-
- public CeTask submit(String organizationKey, String projectKey, @Nullable String projectBranch, @Nullable String projectName, InputStream reportInput) {
- return submit(organizationKey, projectKey, projectBranch, projectName, Collections.emptyMap(), reportInput);
- }
-
- /**
- * @throws NotFoundException if the organization with the specified key does not exist
- * @throws IllegalArgumentException if the organization with the specified key is not the organization of the specified project (when it already exists in DB)
- */
- public CeTask submit(String organizationKey, String projectKey, @Nullable String projectBranch, @Nullable String projectName, Map<String, String> characteristics,
- InputStream reportInput) {
- try (DbSession dbSession = dbClient.openSession(false)) {
- OrganizationDto organizationDto = getOrganizationDtoOrFail(dbSession, organizationKey);
- String effectiveProjectKey = ComponentKeys.createKey(projectKey, projectBranch);
- Optional<ComponentDto> component = dbClient.componentDao().selectByKey(dbSession, effectiveProjectKey);
- validateProject(dbSession, component, projectKey);
- ensureOrganizationIsConsistent(component, organizationDto);
- ComponentDto project = component.or(() -> createProject(dbSession, organizationDto, projectKey, projectBranch, projectName));
- checkScanPermission(project);
- return submitReport(dbSession, reportInput, project, characteristics);
- }
- }
-
- private void checkScanPermission(ComponentDto project) {
- // this is a specific and inconsistent behavior. For legacy reasons, "technical users"
- // defined on an organization should be able to analyze a project even if
- // they don't have the direct permission on the project.
- // That means that dropping the permission on the project does not have any effects
- // if user has still the permission on the organization
- if (!userSession.hasComponentPermission(SCAN_EXECUTION, project) &&
- !userSession.hasPermission(OrganizationPermission.SCAN, project.getOrganizationUuid())) {
- throw insufficientPrivilegesException();
- }
- }
-
- private OrganizationDto getOrganizationDtoOrFail(DbSession dbSession, String organizationKey) {
- return dbClient.organizationDao().selectByKey(dbSession, organizationKey)
- .orElseThrow(() -> new NotFoundException(format("Organization with key '%s' does not exist", organizationKey)));
- }
-
- private void validateProject(DbSession dbSession, Optional<ComponentDto> project, String rawProjectKey) {
- List<String> errors = new ArrayList<>();
- if (!project.isPresent()) {
- return;
- }
-
- ComponentDto component = project.get();
- if (!Qualifiers.PROJECT.equals(component.qualifier()) || !Scopes.PROJECT.equals(component.scope())) {
- errors.add(format("Component '%s' is not a project", rawProjectKey));
- }
- if (!component.projectUuid().equals(component.uuid())) {
- // Project key is already used as a module of another project
- ComponentDto anotherBaseProject = dbClient.componentDao().selectOrFailByUuid(dbSession, component.projectUuid());
- errors.add(format("The project '%s' is already defined in SonarQube but as a module of project '%s'. "
- + "If you really want to stop directly analysing project '%s', please first delete it from SonarQube and then relaunch the analysis of project '%s'.",
- rawProjectKey, anotherBaseProject.getKey(), anotherBaseProject.getKey(), rawProjectKey));
- }
- if (!errors.isEmpty()) {
- throw BadRequestException.create(errors);
- }
- }
-
- private static void ensureOrganizationIsConsistent(Optional<ComponentDto> project, OrganizationDto organizationDto) {
- if (project.isPresent()) {
- checkArgument(project.get().getOrganizationUuid().equals(organizationDto.getUuid()),
- "Organization of component with key '%s' does not match specified organization '%s'",
- project.get().getDbKey(), organizationDto.getKey());
- }
- }
-
- private ComponentDto createProject(DbSession dbSession, OrganizationDto organization, String projectKey, @Nullable String deprecatedBranch, @Nullable String projectName) {
- userSession.checkPermission(OrganizationPermission.PROVISION_PROJECTS, organization);
- Integer userId = userSession.getUserId();
-
- String effectiveProjectKey = ComponentKeys.createEffectiveKey(projectKey, deprecatedBranch);
- boolean wouldCurrentUserHaveScanPermission = permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(
- dbSession, organization.getUuid(), userId, effectiveProjectKey, Qualifiers.PROJECT);
- if (!wouldCurrentUserHaveScanPermission) {
- throw insufficientPrivilegesException();
- }
-
- boolean newProjectPrivate = dbClient.organizationDao().getNewProjectPrivate(dbSession, organization);
-
- NewComponent newProject = newComponentBuilder()
- .setOrganizationUuid(organization.getUuid())
- .setKey(projectKey)
- .setName(defaultIfBlank(projectName, projectKey))
- .setBranch(deprecatedBranch)
- .setQualifier(Qualifiers.PROJECT)
- .setPrivate(newProjectPrivate)
- .build();
- return componentUpdater.create(dbSession, newProject, userId);
- }
-
- private CeTask submitReport(DbSession dbSession, InputStream reportInput, ComponentDto project, Map<String, String> characteristicsMap) {
- CeTaskSubmit.Builder submit = queue.prepareSubmit();
- List<CeTaskCharacteristicDto> characteristics = characteristicsMap.entrySet().stream()
- .map(e -> toDto(submit.getUuid(), e.getKey(), e.getValue())).collect(Collectors.toList());
-
- // the report file must be saved before submitting the task
- dbClient.ceTaskInputDao().insert(dbSession, submit.getUuid(), reportInput);
- if (!characteristics.isEmpty()) {
- dbClient.ceTaskCharacteristicsDao().insert(dbSession, characteristics);
- }
- dbSession.commit();
-
- submit.setType(CeTaskTypes.REPORT);
- submit.setComponentUuid(project.uuid());
- submit.setSubmitterUuid(userSession.getUuid());
- return queue.submit(submit.build());
- }
-
- private CeTaskCharacteristicDto toDto(String taskUuid, String key, String value) {
- CeTaskCharacteristicDto dto = new CeTaskCharacteristicDto();
- dto.setTaskUuid(taskUuid);
- dto.setKey(key);
- dto.setValue(value);
- dto.setUuid(uuidFactory.create());
- return dto;
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.server.computation.queue;
-
-import javax.annotation.ParametersAreNonnullByDefault;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.settings;
+
+import org.picocontainer.Startable;
+import org.sonar.api.ce.ComputeEngineSide;
+import org.sonar.server.computation.task.container.EagerStart;
+import org.sonar.server.computation.task.container.TaskContainerImpl;
+import org.sonar.server.setting.ThreadLocalSettings;
+
+/**
+ * Add this class as the first components in the {@link TaskContainerImpl}
+ * to trigger loading of Thread local specific {@link org.sonar.api.config.Settings} in {@link ThreadLocalSettings}.
+ */
+@EagerStart
+@ComputeEngineSide
+public class SettingsLoader implements Startable {
+ private final ThreadLocalSettings threadLocalSettings;
+
+ public SettingsLoader(ThreadLocalSettings threadLocalSettings) {
+ this.threadLocalSettings = threadLocalSettings;
+ }
+
+ @Override
+ public void start() {
+ threadLocalSettings.load();
+ }
+
+ @Override
+ public void stop() {
+ threadLocalSettings.unload();
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.server.computation.settings;
+
+import javax.annotation.ParametersAreNonnullByDefault;
package org.sonar.server.computation.task.container;
import org.picocontainer.PicoContainer;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
import org.sonar.core.platform.ComponentContainer;
import org.sonar.core.platform.ContainerPopulator;
*/
package org.sonar.server.computation.taskprocessor;
-import org.sonar.ce.queue.CeTaskResult;
+import org.sonar.server.computation.CeTaskResult;
public interface MutableTaskResultHolder extends TaskResultHolder {
/**
package org.sonar.server.computation.taskprocessor;
import javax.annotation.CheckForNull;
-import org.sonar.ce.queue.CeTaskResult;
+import org.sonar.server.computation.CeTaskResult;
import static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;
*/
package org.sonar.server.computation.taskprocessor;
-import org.sonar.ce.queue.CeTaskResult;
+import org.sonar.server.computation.CeTaskResult;
public interface TaskResultHolder {
/**
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.ce.log;
-
-import ch.qos.logback.core.joran.spi.JoranException;
-import org.junit.After;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.mockito.Mockito;
-import org.slf4j.MDC;
-import org.sonar.ce.queue.CeTask;
-import org.sonar.process.logging.LogbackHelper;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.when;
-import static org.sonar.ce.log.CeLogging.MDC_CE_TASK_UUID;
-
-public class CeLoggingTest {
-
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- private LogbackHelper helper = new LogbackHelper();
- private CeLogging underTest = new CeLogging();
-
- @After
- public void resetLogback() throws JoranException {
- helper.resetFromXml("/logback-test.xml");
- }
-
- @After
- public void cleanMDC() {
- MDC.clear();
- }
-
- @Test
- public void initForTask_stores_task_uuid_in_MDC() {
- String uuid = "ce_task_uuid";
-
- underTest.initForTask(createCeTask(uuid));
-
- assertThat(MDC.get(MDC_CE_TASK_UUID)).isEqualTo(uuid);
- }
-
- private CeTask createCeTask(String uuid) {
- CeTask ceTask = Mockito.mock(CeTask.class);
- when(ceTask.getUuid()).thenReturn(uuid);
- return ceTask;
- }
-
- @Test
- public void clearForTask_removes_task_uuid_from_MDC() {
- MDC.put(MDC_CE_TASK_UUID, "some_value");
-
- underTest.clearForTask();
-
- assertThat(MDC.get(MDC_CE_TASK_UUID)).isNull();
- }
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.ce.organization;
-
-import org.junit.Test;
-import org.sonar.server.organization.DefaultOrganizationCache;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-public class DefaultOrganizationLoaderTest {
- private DefaultOrganizationCache defaultOrganizationCache = mock(DefaultOrganizationCache.class);
- private DefaultOrganizationLoader underTest = new DefaultOrganizationLoader(defaultOrganizationCache);
-
- @Test
- public void start_calls_cache_load_method() {
- underTest.start();
-
- verify(defaultOrganizationCache).load();
- verifyNoMoreInteractions(defaultOrganizationCache);
- }
-
- @Test
- public void stop_calls_cache_unload_method() {
- underTest.stop();
-
- verify(defaultOrganizationCache).unload();
- verifyNoMoreInteractions(defaultOrganizationCache);
- }
-}
import org.sonar.db.ce.CeTaskTypes;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
+import org.sonar.server.computation.CeTask;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.ce.queue;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class CeTaskTest {
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- private CeTask.Builder underTest = new CeTask.Builder();
-
- @Test
- public void build_fails_with_NPE_if_organizationUuid_is_null() {
- expectedException.expect(NullPointerException.class);
- expectedException.expectMessage("organizationUuid can't be null nor empty");
-
- underTest.build();
- }
-
- @Test
- public void build_fails_with_NPE_if_organizationUuid_is_empty() {
- underTest.setOrganizationUuid("");
-
- expectedException.expect(NullPointerException.class);
- expectedException.expectMessage("organizationUuid can't be null nor empty");
-
- underTest.build();
- }
-
- @Test
- public void build_fails_with_NPE_if_uid_is_null() {
- underTest.setOrganizationUuid("org1");
-
- expectedException.expect(NullPointerException.class);
- expectedException.expectMessage("uuid can't be null nor empty");
-
- underTest.build();
- }
-
- @Test
- public void build_fails_with_NPE_if_uuid_is_empty() {
- underTest.setOrganizationUuid("org1").setUuid("");
-
- expectedException.expect(NullPointerException.class);
- expectedException.expectMessage("uuid can't be null nor empty");
-
- underTest.build();
- }
-
- @Test
- public void build_fails_with_NPE_if_type_is_null() {
- underTest.setOrganizationUuid("org1").setUuid("uuid");
-
- expectedException.expect(NullPointerException.class);
- expectedException.expectMessage("type can't be null nor empty");
-
- underTest.build();
- }
-
- @Test
- public void build_fails_with_NPE_if_type_is_empty() {
- underTest.setOrganizationUuid("org1").setUuid("uuid").setType("");
-
- expectedException.expect(NullPointerException.class);
- expectedException.expectMessage("type can't be null nor empty");
-
- underTest.build();
- }
-
- @Test
- public void verify_getters() {
- underTest.setOrganizationUuid("org1");
- underTest.setType("TYPE_1");
- underTest.setUuid("UUID_1");
- underTest.setSubmitterUuid("LOGIN_1");
- underTest.setComponentKey("COMPONENT_KEY_1");
- underTest.setComponentUuid("COMPONENT_UUID_1");
- underTest.setComponentName("The component");
-
- CeTask task = underTest.build();
-
- assertThat(task.getOrganizationUuid()).isEqualTo("org1");
- assertThat(task.getUuid()).isEqualTo("UUID_1");
- assertThat(task.getType()).isEqualTo("TYPE_1");
- assertThat(task.getSubmitterUuid()).isEqualTo("LOGIN_1");
- assertThat(task.getComponentKey()).isEqualTo("COMPONENT_KEY_1");
- assertThat(task.getComponentUuid()).isEqualTo("COMPONENT_UUID_1");
- assertThat(task.getComponentName()).isEqualTo("The component");
- }
-
- @Test
- public void empty_in_component_properties_is_considered_as_null() {
- CeTask ceTask = underTest.setOrganizationUuid("org1").setUuid("uuid").setType("type")
- .setComponentKey("")
- .setComponentName("")
- .setComponentUuid("")
- .build();
-
- assertThat(ceTask.getComponentKey()).isNull();
- assertThat(ceTask.getComponentName()).isNull();
- assertThat(ceTask.getComponentUuid()).isNull();
- }
-
- @Test
- public void empty_in_submitterLogin_is_considered_as_null() {
- CeTask ceTask = underTest.setOrganizationUuid("org1").setUuid("uuid").setType("type")
- .setSubmitterUuid("")
- .build();
-
- assertThat(ceTask.getSubmitterUuid()).isNull();
- }
-
- @Test
- public void equals_and_hashCode_on_uuid() {
- underTest.setOrganizationUuid("org1").setType("TYPE_1").setUuid("UUID_1");
- CeTask task1 = underTest.build();
- CeTask task1bis = underTest.build();
- CeTask task2 = new CeTask.Builder().setOrganizationUuid("org1").setType("TYPE_1").setUuid("UUID_2").build();
-
- assertThat(task1.equals(task1)).isTrue();
- assertThat(task1.equals(task1bis)).isTrue();
- assertThat(task1.equals(task2)).isFalse();
- assertThat(task1.hashCode()).isEqualTo(task1.hashCode());
- assertThat(task1.hashCode()).isEqualTo(task1bis.hashCode());
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.ce.settings;
-
-import org.junit.Test;
-import org.sonar.server.setting.ThreadLocalSettings;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-public class SettingsLoaderTest {
- private ThreadLocalSettings threadLocalSettings = mock(ThreadLocalSettings.class);
- private SettingsLoader underTest = new SettingsLoader(threadLocalSettings);
-
- @Test
- public void start_calls_ThreadLocalSettings_load() {
- underTest.start();
-
- verify(threadLocalSettings).load();
- verifyNoMoreInteractions(threadLocalSettings);
- }
-
- @Test
- public void stop_calls_ThreadLocalSettings_remove() {
- underTest.stop();
-
- verify(threadLocalSettings).unload();
- verifyNoMoreInteractions(threadLocalSettings);
- }
-}
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.ce.queue;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.io.IOUtils;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.ArgumentCaptor;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.utils.System2;
+import org.sonar.ce.queue.CeQueue;
+import org.sonar.ce.queue.CeQueueImpl;
+import org.sonar.ce.queue.CeTaskSubmit;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.core.util.SequenceUuidFactory;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+import org.sonar.db.ce.CeTaskCharacteristicDto;
+import org.sonar.db.ce.CeTaskTypes;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentTesting;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.permission.OrganizationPermission;
+import org.sonar.db.user.UserDto;
+import org.sonar.server.component.ComponentUpdater;
+import org.sonar.server.component.NewComponent;
+import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.favorite.FavoriteUpdater;
+import org.sonar.server.permission.PermissionTemplateService;
+import org.sonar.server.tester.UserSessionRule;
+
+import static java.lang.String.format;
+import static java.util.Collections.singletonList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
+import static org.sonar.db.component.ComponentTesting.newModuleDto;
+import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
+import static org.sonar.db.permission.OrganizationPermission.PROVISION_PROJECTS;
+import static org.sonar.db.permission.OrganizationPermission.SCAN;
+
+public class ReportSubmitterTest {
+
+ private static final String PROJECT_KEY = "MY_PROJECT";
+ private static final String PROJECT_UUID = "P1";
+ private static final String PROJECT_NAME = "My Project";
+ private static final String TASK_UUID = "TASK_1";
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+ @Rule
+ public UserSessionRule userSession = UserSessionRule.standalone();
+ @Rule
+ public DbTester db = DbTester.create(System2.INSTANCE);
+
+ private String defaultOrganizationKey;
+ private String defaultOrganizationUuid;
+ private CeQueue queue = mock(CeQueueImpl.class);
+ private ComponentUpdater componentUpdater = mock(ComponentUpdater.class);
+ private PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class);
+ private FavoriteUpdater favoriteUpdater = mock(FavoriteUpdater.class);
+ private UuidFactory uuidFactory = new SequenceUuidFactory();
+
+ private ReportSubmitter underTest = new ReportSubmitter(queue, userSession, componentUpdater, permissionTemplateService, uuidFactory, db.getDbClient());
+
+ @Before
+ public void setUp() throws Exception {
+ defaultOrganizationKey = db.getDefaultOrganization().getKey();
+ defaultOrganizationUuid = db.getDefaultOrganization().getUuid();
+ }
+
+ @Test
+ public void submit_inserts_characteristics() {
+ userSession
+ .addPermission(OrganizationPermission.SCAN, db.getDefaultOrganization().getUuid())
+ .addPermission(PROVISION_PROJECTS, db.getDefaultOrganization());
+
+ mockSuccessfulPrepareSubmitCall();
+ ComponentDto project = newPrivateProjectDto(db.getDefaultOrganization(), PROJECT_UUID).setDbKey(PROJECT_KEY);
+ when(componentUpdater.create(any(), any(), any())).thenReturn(project);
+ when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(), eq(defaultOrganizationUuid), any(), eq(PROJECT_KEY),
+ eq(Qualifiers.PROJECT)))
+ .thenReturn(true);
+
+ Map<String, String> taskCharacteristics = new HashMap<>();
+ taskCharacteristics.put("incremental", "true");
+ taskCharacteristics.put("pr", "mypr");
+
+ underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, taskCharacteristics, IOUtils.toInputStream("{binary}"));
+
+ ArgumentCaptor<CeTaskSubmit> submittedTask = ArgumentCaptor.forClass(CeTaskSubmit.class);
+ verify(queue).submit(submittedTask.capture());
+ String taskUuid = submittedTask.getValue().getUuid();
+
+ List<CeTaskCharacteristicDto> insertedCharacteristics = db.getDbClient().ceTaskCharacteristicsDao().selectByTaskUuids(db.getSession(), singletonList(taskUuid));
+ assertThat(insertedCharacteristics)
+ .extracting(CeTaskCharacteristicDto::getKey, CeTaskCharacteristicDto::getValue)
+ .containsOnly(tuple("incremental", "true"), tuple("pr", "mypr"));
+ }
+
+ @Test
+ public void submit_a_report_on_existing_project() {
+ ComponentDto project = db.components().insertPrivateProject(db.getDefaultOrganization());
+ UserDto user = db.users().insertUser();
+ userSession.logIn(user).addProjectPermission(SCAN_EXECUTION, project);
+
+ mockSuccessfulPrepareSubmitCall();
+
+ underTest.submit(defaultOrganizationKey, project.getDbKey(), null, project.name(), IOUtils.toInputStream("{binary}"));
+
+ verifyReportIsPersisted(TASK_UUID);
+ verifyZeroInteractions(permissionTemplateService);
+ verifyZeroInteractions(favoriteUpdater);
+ verify(queue).submit(argThat(submit ->
+ submit.getType().equals(CeTaskTypes.REPORT)
+ && submit.getComponentUuid().equals(project.uuid())
+ && submit.getSubmitterUuid().equals(user.getUuid())
+ && submit.getUuid().equals(TASK_UUID)));
+ }
+
+ @Test
+ public void provision_project_if_does_not_exist() {
+ OrganizationDto organization = db.organizations().insert();
+ userSession
+ .addPermission(OrganizationPermission.SCAN, organization.getUuid())
+ .addPermission(PROVISION_PROJECTS, organization);
+
+ mockSuccessfulPrepareSubmitCall();
+ ComponentDto createdProject = newPrivateProjectDto(organization, PROJECT_UUID).setDbKey(PROJECT_KEY);
+ when(componentUpdater.create(any(), any(), isNull())).thenReturn(createdProject);
+ when(
+ permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(), eq(organization.getUuid()), any(), eq(PROJECT_KEY), eq(Qualifiers.PROJECT)))
+ .thenReturn(true);
+ when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(), eq(organization.getUuid()), any())).thenReturn(true);
+
+ underTest.submit(organization.getKey(), PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}"));
+
+ verifyReportIsPersisted(TASK_UUID);
+ verify(queue).submit(argThat(submit ->
+ submit.getType().equals(CeTaskTypes.REPORT) && submit.getComponentUuid().equals(PROJECT_UUID) && submit.getUuid().equals(TASK_UUID)));
+ }
+
+ @Test
+ public void no_favorite_when_no_project_creator_permission_on_permission_template() {
+ userSession
+ .addPermission(OrganizationPermission.SCAN, db.getDefaultOrganization().getUuid())
+ .addPermission(PROVISION_PROJECTS, db.getDefaultOrganization());
+
+ mockSuccessfulPrepareSubmitCall();
+ ComponentDto createdProject = newPrivateProjectDto(db.getDefaultOrganization(), PROJECT_UUID).setDbKey(PROJECT_KEY);
+ when(componentUpdater.create(any(), any(), isNull())).thenReturn(createdProject);
+ when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(), eq(defaultOrganizationUuid), any(),
+ eq(PROJECT_KEY), eq(Qualifiers.PROJECT)))
+ .thenReturn(true);
+ when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(), eq(defaultOrganizationUuid), any())).thenReturn(false);
+
+ underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}"));
+
+ verifyZeroInteractions(favoriteUpdater);
+ }
+
+ @Test
+ public void submit_a_report_on_new_project_with_scan_permission_on_organization() {
+ userSession
+ .addPermission(OrganizationPermission.SCAN, db.getDefaultOrganization().getUuid())
+ .addPermission(PROVISION_PROJECTS, db.getDefaultOrganization());
+
+ mockSuccessfulPrepareSubmitCall();
+ ComponentDto project = newPrivateProjectDto(db.getDefaultOrganization(), PROJECT_UUID).setDbKey(PROJECT_KEY);
+ when(componentUpdater.create(any(), any(), any())).thenReturn(project);
+ when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(), eq(defaultOrganizationUuid), any(),
+ eq(PROJECT_KEY), eq(Qualifiers.PROJECT)))
+ .thenReturn(true);
+
+ underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}"));
+
+ verify(queue).submit(any(CeTaskSubmit.class));
+ }
+
+ @Test
+ public void user_with_scan_permission_on_organization_is_allowed_to_submit_a_report_on_existing_project() {
+ OrganizationDto org = db.organizations().insert();
+ ComponentDto project = db.components().insertPrivateProject(org);
+ userSession.addPermission(SCAN, org);
+
+ mockSuccessfulPrepareSubmitCall();
+
+ underTest.submit(org.getKey(), project.getDbKey(), null, project.name(), IOUtils.toInputStream("{binary}"));
+
+ verify(queue).submit(any(CeTaskSubmit.class));
+ }
+
+ @Test
+ public void submit_a_report_on_existing_project_with_project_scan_permission() {
+ ComponentDto project = db.components().insertPrivateProject(db.getDefaultOrganization());
+ userSession.addProjectPermission(SCAN_EXECUTION, project);
+
+ mockSuccessfulPrepareSubmitCall();
+
+ underTest.submit(defaultOrganizationKey, project.getDbKey(), null, project.name(), IOUtils.toInputStream("{binary}"));
+
+ verify(queue).submit(any(CeTaskSubmit.class));
+ }
+
+ /**
+ * SONAR-8757
+ */
+ @Test
+ public void project_branch_must_not_benefit_from_the_scan_permission_on_main_project() {
+ ComponentDto mainProject = db.components().insertPrivateProject();
+ userSession.addProjectPermission(GlobalPermissions.SCAN_EXECUTION, mainProject);
+
+ // user does not have the "scan" permission on the branch, so it can't scan it
+ String branchName = "branchFoo";
+ ComponentDto branchProject = db.components().insertPrivateProject(p -> p.setDbKey(mainProject.getDbKey() + ":" + branchName));
+
+ expectedException.expect(ForbiddenException.class);
+ underTest.submit(defaultOrganizationKey, mainProject.getDbKey(), branchName, PROJECT_NAME, IOUtils.toInputStream("{binary}"));
+ }
+
+ @Test
+ public void fail_with_NotFoundException_if_organization_with_specified_key_does_not_exist() {
+ expectedException.expect(NotFoundException.class);
+ expectedException.expectMessage("Organization with key 'fop' does not exist");
+
+ underTest.submit("fop", PROJECT_KEY, null, null, null /* method will fail before parameter is used */);
+ }
+
+ @Test
+ public void fail_with_organizationKey_does_not_match_organization_of_specified_component() {
+ userSession.logIn().setRoot();
+ OrganizationDto organization = db.organizations().insert();
+ ComponentDto project = db.components().insertPrivateProject(organization);
+ mockSuccessfulPrepareSubmitCall();
+
+ underTest.submit(organization.getKey(), project.getDbKey(), null, project.name(), IOUtils.toInputStream("{binary}"));
+ }
+
+ @Test
+ public void fail_if_component_is_not_a_project() {
+ ComponentDto component = db.components().insertPublicPortfolio(db.getDefaultOrganization());
+ userSession.logIn().addProjectPermission(SCAN_EXECUTION, component);
+ mockSuccessfulPrepareSubmitCall();
+
+ expectedException.expect(BadRequestException.class);
+ expectedException.expectMessage(format("Component '%s' is not a project", component.getKey()));
+
+ underTest.submit(defaultOrganizationKey, component.getDbKey(), null, component.name(), IOUtils.toInputStream("{binary}"));
+ }
+
+ @Test
+ public void fail_if_project_key_already_exists_as_module() {
+ ComponentDto project = db.components().insertPrivateProject(db.getDefaultOrganization());
+ ComponentDto module = db.components().insertComponent(newModuleDto(project));
+ userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
+ mockSuccessfulPrepareSubmitCall();
+
+ try {
+ underTest.submit(defaultOrganizationKey, module.getDbKey(), null, module.name(), IOUtils.toInputStream("{binary}"));
+ fail();
+ } catch (BadRequestException e) {
+ assertThat(e.errors()).contains(
+ format("The project '%s' is already defined in SonarQube but as a module of project '%s'. " +
+ "If you really want to stop directly analysing project '%s', please first delete it from SonarQube and then relaunch the analysis of project '%s'.",
+ module.getKey(), project.getKey(), project.getKey(), module.getKey()));
+ }
+ }
+
+ @Test
+ public void fail_with_forbidden_exception_when_no_scan_permission() {
+ expectedException.expect(ForbiddenException.class);
+
+ underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}"));
+ }
+
+ @Test
+ public void fail_with_forbidden_exception_on_new_project_when_only_project_scan_permission() {
+ userSession.addProjectPermission(SCAN_EXECUTION, ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization(), PROJECT_UUID));
+
+ mockSuccessfulPrepareSubmitCall();
+ when(componentUpdater.create(any(DbSession.class), any(NewComponent.class), eq(null))).thenReturn(new ComponentDto().setUuid(PROJECT_UUID).setDbKey(PROJECT_KEY));
+
+ expectedException.expect(ForbiddenException.class);
+ underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}"));
+ }
+
+ private void verifyReportIsPersisted(String taskUuid) {
+ assertThat(db.selectFirst("select task_uuid from ce_task_input where task_uuid='" + taskUuid + "'")).isNotNull();
+ }
+
+ private void mockSuccessfulPrepareSubmitCall() {
+ when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder(TASK_UUID));
+ }
+
+}
import org.sonar.api.web.UserRole;
import org.sonar.ce.queue.CeQueue;
import org.sonar.ce.queue.CeQueueImpl;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
import org.sonar.ce.queue.CeTaskSubmit;
import org.sonar.core.util.UuidFactoryFast;
import org.sonar.db.DbTester;
import org.junit.Test;
import org.mockito.Mockito;
import org.sonar.api.server.ws.WebService;
-import org.sonar.server.computation.queue.ReportSubmitter;
+import org.sonar.server.ce.queue.ReportSubmitter;
import org.sonar.server.organization.DefaultOrganizationProvider;
import static org.assertj.core.api.Assertions.assertThat;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.MockitoAnnotations;
-import org.sonar.ce.queue.CeTask;
+import org.sonar.server.computation.CeTask;
import org.sonar.db.ce.CeTaskTypes;
-import org.sonar.server.computation.queue.ReportSubmitter;
+import org.sonar.server.ce.queue.ReportSubmitter;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.ws.TestResponse;
import com.google.common.collect.ImmutableSet;
import java.util.Set;
import org.junit.Test;
-import org.sonar.ce.queue.CeTask;
-import org.sonar.ce.queue.CeTaskResult;
+import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.CeTaskResult;
import org.sonar.ce.taskprocessor.CeTaskProcessor;
import org.sonar.server.ws.WsActionTester;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class CeTaskTest {
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private CeTask.Builder underTest = new CeTask.Builder();
+
+ @Test
+ public void build_fails_with_NPE_if_organizationUuid_is_null() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("organizationUuid can't be null nor empty");
+
+ underTest.build();
+ }
+
+ @Test
+ public void build_fails_with_NPE_if_organizationUuid_is_empty() {
+ underTest.setOrganizationUuid("");
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("organizationUuid can't be null nor empty");
+
+ underTest.build();
+ }
+
+ @Test
+ public void build_fails_with_NPE_if_uid_is_null() {
+ underTest.setOrganizationUuid("org1");
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("uuid can't be null nor empty");
+
+ underTest.build();
+ }
+
+ @Test
+ public void build_fails_with_NPE_if_uuid_is_empty() {
+ underTest.setOrganizationUuid("org1").setUuid("");
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("uuid can't be null nor empty");
+
+ underTest.build();
+ }
+
+ @Test
+ public void build_fails_with_NPE_if_type_is_null() {
+ underTest.setOrganizationUuid("org1").setUuid("uuid");
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("type can't be null nor empty");
+
+ underTest.build();
+ }
+
+ @Test
+ public void build_fails_with_NPE_if_type_is_empty() {
+ underTest.setOrganizationUuid("org1").setUuid("uuid").setType("");
+
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("type can't be null nor empty");
+
+ underTest.build();
+ }
+
+ @Test
+ public void verify_getters() {
+ underTest.setOrganizationUuid("org1");
+ underTest.setType("TYPE_1");
+ underTest.setUuid("UUID_1");
+ underTest.setSubmitterUuid("LOGIN_1");
+ underTest.setComponentKey("COMPONENT_KEY_1");
+ underTest.setComponentUuid("COMPONENT_UUID_1");
+ underTest.setComponentName("The component");
+
+ CeTask task = underTest.build();
+
+ assertThat(task.getOrganizationUuid()).isEqualTo("org1");
+ assertThat(task.getUuid()).isEqualTo("UUID_1");
+ assertThat(task.getType()).isEqualTo("TYPE_1");
+ assertThat(task.getSubmitterUuid()).isEqualTo("LOGIN_1");
+ assertThat(task.getComponentKey()).isEqualTo("COMPONENT_KEY_1");
+ assertThat(task.getComponentUuid()).isEqualTo("COMPONENT_UUID_1");
+ assertThat(task.getComponentName()).isEqualTo("The component");
+ }
+
+ @Test
+ public void empty_in_component_properties_is_considered_as_null() {
+ CeTask ceTask = underTest.setOrganizationUuid("org1").setUuid("uuid").setType("type")
+ .setComponentKey("")
+ .setComponentName("")
+ .setComponentUuid("")
+ .build();
+
+ assertThat(ceTask.getComponentKey()).isNull();
+ assertThat(ceTask.getComponentName()).isNull();
+ assertThat(ceTask.getComponentUuid()).isNull();
+ }
+
+ @Test
+ public void empty_in_submitterLogin_is_considered_as_null() {
+ CeTask ceTask = underTest.setOrganizationUuid("org1").setUuid("uuid").setType("type")
+ .setSubmitterUuid("")
+ .build();
+
+ assertThat(ceTask.getSubmitterUuid()).isNull();
+ }
+
+ @Test
+ public void equals_and_hashCode_on_uuid() {
+ underTest.setOrganizationUuid("org1").setType("TYPE_1").setUuid("UUID_1");
+ CeTask task1 = underTest.build();
+ CeTask task1bis = underTest.build();
+ CeTask task2 = new CeTask.Builder().setOrganizationUuid("org1").setType("TYPE_1").setUuid("UUID_2").build();
+
+ assertThat(task1.equals(task1)).isTrue();
+ assertThat(task1.equals(task1bis)).isTrue();
+ assertThat(task1.equals(task2)).isFalse();
+ assertThat(task1.hashCode()).isEqualTo(task1.hashCode());
+ assertThat(task1.hashCode()).isEqualTo(task1bis.hashCode());
+ }
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.dbcleaner;
-
-import java.util.Arrays;
-import java.util.List;
-import org.junit.Test;
-import org.sonar.server.component.index.ComponentIndexer;
-import org.sonar.server.issue.index.IssueIndexer;
-import org.sonar.server.test.index.TestIndexer;
-
-import static java.util.Arrays.asList;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-public class IndexPurgeListenerTest {
-
- TestIndexer testIndexer = mock(TestIndexer.class);
- IssueIndexer issueIndexer = mock(IssueIndexer.class);
- ComponentIndexer componentIndexer = mock(ComponentIndexer.class);
-
- IndexPurgeListener underTest = new IndexPurgeListener(testIndexer, issueIndexer, componentIndexer);
-
- @Test
- public void test_onComponentDisabling() {
- String uuid = "123456";
- String projectUuid = "P789";
- List<String> uuids = Arrays.asList(uuid);
- underTest.onComponentsDisabling(projectUuid, uuids);
-
- verify(testIndexer).deleteByFile(uuid);
- verify(componentIndexer).delete(projectUuid, uuids);
- }
-
- @Test
- public void test_onIssuesRemoval() {
- underTest.onIssuesRemoval("P1", asList("ISSUE1", "ISSUE2"));
-
- verify(issueIndexer).deleteByKeys("P1", asList("ISSUE1", "ISSUE2"));
- }
-
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.dbcleaner;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.config.PropertyDefinitions;
-import org.sonar.api.config.internal.MapSettings;
-import org.sonar.core.config.PurgeConstants;
-import org.sonar.core.config.PurgeProperties;
-import org.sonar.db.DbSession;
-import org.sonar.db.purge.IdUuidPair;
-import org.sonar.db.purge.PurgeDao;
-import org.sonar.db.purge.PurgeListener;
-import org.sonar.db.purge.PurgeProfiler;
-import org.sonar.db.purge.period.DefaultPeriodCleaner;
-
-import static java.util.Collections.emptyList;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-public class ProjectCleanerTest {
-
- private ProjectCleaner underTest;
- private PurgeDao dao = mock(PurgeDao.class);
- private PurgeProfiler profiler = mock(PurgeProfiler.class);
- private DefaultPeriodCleaner periodCleaner = mock(DefaultPeriodCleaner.class);
- private PurgeListener purgeListener = mock(PurgeListener.class);
- private MapSettings settings = new MapSettings(new PropertyDefinitions(PurgeProperties.all()));
-
- @Before
- public void before() {
- this.underTest = new ProjectCleaner(dao, periodCleaner, profiler, purgeListener);
- }
-
- @Test
- public void no_profiling_when_property_is_false() {
- settings.setProperty(CoreProperties.PROFILING_LOG_PROPERTY, false);
-
- underTest.purge(mock(DbSession.class), mock(IdUuidPair.class), settings.asConfig(), emptyList());
-
- verify(profiler, never()).dump(anyLong(), any());
- }
-
- @Test
- public void profiling_when_property_is_true() {
- settings.setProperty(CoreProperties.PROFILING_LOG_PROPERTY, true);
-
- underTest.purge(mock(DbSession.class), mock(IdUuidPair.class), settings.asConfig(), emptyList());
-
- verify(profiler).dump(anyLong(), any());
- }
-
- @Test
- public void call_period_cleaner_index_client_and_purge_dao() {
- settings.setProperty(PurgeConstants.DAYS_BEFORE_DELETING_CLOSED_ISSUES, 5);
-
- underTest.purge(mock(DbSession.class), mock(IdUuidPair.class), settings.asConfig(), emptyList());
-
- verify(periodCleaner).clean(any(), any(), any());
- verify(dao).purge(any(), any(), any(), any());
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.log;
+
+import ch.qos.logback.core.joran.spi.JoranException;
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.Mockito;
+import org.slf4j.MDC;
+import org.sonar.process.logging.LogbackHelper;
+import org.sonar.server.computation.CeTask;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.when;
+import static org.sonar.server.computation.log.CeTaskLogging.MDC_CE_TASK_UUID;
+
+public class CeTaskLoggingTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private LogbackHelper helper = new LogbackHelper();
+ private CeTaskLogging underTest = new CeTaskLogging();
+
+ @After
+ public void resetLogback() throws JoranException {
+ helper.resetFromXml("/logback-test.xml");
+ }
+
+ @After
+ public void cleanMDC() {
+ MDC.clear();
+ }
+
+ @Test
+ public void initForTask_stores_task_uuid_in_MDC() {
+ String uuid = "ce_task_uuid";
+
+ underTest.initForTask(createCeTask(uuid));
+
+ assertThat(MDC.get(MDC_CE_TASK_UUID)).isEqualTo(uuid);
+ }
+
+ private CeTask createCeTask(String uuid) {
+ CeTask ceTask = Mockito.mock(CeTask.class);
+ when(ceTask.getUuid()).thenReturn(uuid);
+ return ceTask;
+ }
+
+ @Test
+ public void clearForTask_removes_task_uuid_from_MDC() {
+ MDC.put(MDC_CE_TASK_UUID, "some_value");
+
+ underTest.clearForTask();
+
+ assertThat(MDC.get(MDC_CE_TASK_UUID)).isNull();
+ }
+
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.organization;
+
+import org.junit.Test;
+import org.sonar.server.organization.DefaultOrganizationCache;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+public class DefaultOrganizationLoaderTest {
+ private DefaultOrganizationCache defaultOrganizationCache = mock(DefaultOrganizationCache.class);
+ private DefaultOrganizationLoader underTest = new DefaultOrganizationLoader(defaultOrganizationCache);
+
+ @Test
+ public void start_calls_cache_load_method() {
+ underTest.start();
+
+ verify(defaultOrganizationCache).load();
+ verifyNoMoreInteractions(defaultOrganizationCache);
+ }
+
+ @Test
+ public void stop_calls_cache_unload_method() {
+ underTest.stop();
+
+ verify(defaultOrganizationCache).unload();
+ verifyNoMoreInteractions(defaultOrganizationCache);
+ }
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.queue;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.commons.io.IOUtils;
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.mockito.ArgumentCaptor;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.utils.System2;
-import org.sonar.ce.queue.CeQueue;
-import org.sonar.ce.queue.CeQueueImpl;
-import org.sonar.ce.queue.CeTaskSubmit;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.core.util.SequenceUuidFactory;
-import org.sonar.core.util.UuidFactory;
-import org.sonar.db.DbSession;
-import org.sonar.db.DbTester;
-import org.sonar.db.ce.CeTaskCharacteristicDto;
-import org.sonar.db.ce.CeTaskTypes;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ComponentTesting;
-import org.sonar.db.organization.OrganizationDto;
-import org.sonar.db.permission.OrganizationPermission;
-import org.sonar.db.user.UserDto;
-import org.sonar.server.component.ComponentUpdater;
-import org.sonar.server.component.NewComponent;
-import org.sonar.server.exceptions.BadRequestException;
-import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.exceptions.NotFoundException;
-import org.sonar.server.favorite.FavoriteUpdater;
-import org.sonar.server.permission.PermissionTemplateService;
-import org.sonar.server.tester.UserSessionRule;
-
-import static java.lang.String.format;
-import static java.util.Collections.singletonList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.tuple;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
-import static org.sonar.db.component.ComponentTesting.newModuleDto;
-import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
-import static org.sonar.db.permission.OrganizationPermission.PROVISION_PROJECTS;
-import static org.sonar.db.permission.OrganizationPermission.SCAN;
-
-public class ReportSubmitterTest {
-
- private static final String PROJECT_KEY = "MY_PROJECT";
- private static final String PROJECT_UUID = "P1";
- private static final String PROJECT_NAME = "My Project";
- private static final String TASK_UUID = "TASK_1";
-
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
- @Rule
- public UserSessionRule userSession = UserSessionRule.standalone();
- @Rule
- public DbTester db = DbTester.create(System2.INSTANCE);
-
- private String defaultOrganizationKey;
- private String defaultOrganizationUuid;
- private CeQueue queue = mock(CeQueueImpl.class);
- private ComponentUpdater componentUpdater = mock(ComponentUpdater.class);
- private PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class);
- private FavoriteUpdater favoriteUpdater = mock(FavoriteUpdater.class);
- private UuidFactory uuidFactory = new SequenceUuidFactory();
-
- private ReportSubmitter underTest = new ReportSubmitter(queue, userSession, componentUpdater, permissionTemplateService, uuidFactory, db.getDbClient());
-
- @Before
- public void setUp() throws Exception {
- defaultOrganizationKey = db.getDefaultOrganization().getKey();
- defaultOrganizationUuid = db.getDefaultOrganization().getUuid();
- }
-
- @Test
- public void submit_inserts_characteristics() {
- userSession
- .addPermission(OrganizationPermission.SCAN, db.getDefaultOrganization().getUuid())
- .addPermission(PROVISION_PROJECTS, db.getDefaultOrganization());
-
- mockSuccessfulPrepareSubmitCall();
- ComponentDto project = newPrivateProjectDto(db.getDefaultOrganization(), PROJECT_UUID).setDbKey(PROJECT_KEY);
- when(componentUpdater.create(any(), any(), any())).thenReturn(project);
- when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(), eq(defaultOrganizationUuid), any(), eq(PROJECT_KEY),
- eq(Qualifiers.PROJECT)))
- .thenReturn(true);
-
- Map<String, String> taskCharacteristics = new HashMap<>();
- taskCharacteristics.put("incremental", "true");
- taskCharacteristics.put("pr", "mypr");
-
- underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, taskCharacteristics, IOUtils.toInputStream("{binary}"));
-
- ArgumentCaptor<CeTaskSubmit> submittedTask = ArgumentCaptor.forClass(CeTaskSubmit.class);
- verify(queue).submit(submittedTask.capture());
- String taskUuid = submittedTask.getValue().getUuid();
-
- List<CeTaskCharacteristicDto> insertedCharacteristics = db.getDbClient().ceTaskCharacteristicsDao().selectByTaskUuids(db.getSession(), singletonList(taskUuid));
- assertThat(insertedCharacteristics)
- .extracting(CeTaskCharacteristicDto::getKey, CeTaskCharacteristicDto::getValue)
- .containsOnly(tuple("incremental", "true"), tuple("pr", "mypr"));
- }
-
- @Test
- public void submit_a_report_on_existing_project() {
- ComponentDto project = db.components().insertPrivateProject(db.getDefaultOrganization());
- UserDto user = db.users().insertUser();
- userSession.logIn(user).addProjectPermission(SCAN_EXECUTION, project);
-
- mockSuccessfulPrepareSubmitCall();
-
- underTest.submit(defaultOrganizationKey, project.getDbKey(), null, project.name(), IOUtils.toInputStream("{binary}"));
-
- verifyReportIsPersisted(TASK_UUID);
- verifyZeroInteractions(permissionTemplateService);
- verifyZeroInteractions(favoriteUpdater);
- verify(queue).submit(argThat(submit ->
- submit.getType().equals(CeTaskTypes.REPORT)
- && submit.getComponentUuid().equals(project.uuid())
- && submit.getSubmitterUuid().equals(user.getUuid())
- && submit.getUuid().equals(TASK_UUID)));
- }
-
- @Test
- public void provision_project_if_does_not_exist() {
- OrganizationDto organization = db.organizations().insert();
- userSession
- .addPermission(OrganizationPermission.SCAN, organization.getUuid())
- .addPermission(PROVISION_PROJECTS, organization);
-
- mockSuccessfulPrepareSubmitCall();
- ComponentDto createdProject = newPrivateProjectDto(organization, PROJECT_UUID).setDbKey(PROJECT_KEY);
- when(componentUpdater.create(any(), any(), isNull())).thenReturn(createdProject);
- when(
- permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(), eq(organization.getUuid()), any(), eq(PROJECT_KEY), eq(Qualifiers.PROJECT)))
- .thenReturn(true);
- when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(), eq(organization.getUuid()), any())).thenReturn(true);
-
- underTest.submit(organization.getKey(), PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}"));
-
- verifyReportIsPersisted(TASK_UUID);
- verify(queue).submit(argThat(submit ->
- submit.getType().equals(CeTaskTypes.REPORT) && submit.getComponentUuid().equals(PROJECT_UUID) && submit.getUuid().equals(TASK_UUID)));
- }
-
- @Test
- public void no_favorite_when_no_project_creator_permission_on_permission_template() {
- userSession
- .addPermission(OrganizationPermission.SCAN, db.getDefaultOrganization().getUuid())
- .addPermission(PROVISION_PROJECTS, db.getDefaultOrganization());
-
- mockSuccessfulPrepareSubmitCall();
- ComponentDto createdProject = newPrivateProjectDto(db.getDefaultOrganization(), PROJECT_UUID).setDbKey(PROJECT_KEY);
- when(componentUpdater.create(any(), any(), isNull())).thenReturn(createdProject);
- when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(), eq(defaultOrganizationUuid), any(),
- eq(PROJECT_KEY), eq(Qualifiers.PROJECT)))
- .thenReturn(true);
- when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(), eq(defaultOrganizationUuid), any())).thenReturn(false);
-
- underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}"));
-
- verifyZeroInteractions(favoriteUpdater);
- }
-
- @Test
- public void submit_a_report_on_new_project_with_scan_permission_on_organization() {
- userSession
- .addPermission(OrganizationPermission.SCAN, db.getDefaultOrganization().getUuid())
- .addPermission(PROVISION_PROJECTS, db.getDefaultOrganization());
-
- mockSuccessfulPrepareSubmitCall();
- ComponentDto project = newPrivateProjectDto(db.getDefaultOrganization(), PROJECT_UUID).setDbKey(PROJECT_KEY);
- when(componentUpdater.create(any(), any(), any())).thenReturn(project);
- when(permissionTemplateService.wouldUserHaveScanPermissionWithDefaultTemplate(any(), eq(defaultOrganizationUuid), any(),
- eq(PROJECT_KEY), eq(Qualifiers.PROJECT)))
- .thenReturn(true);
-
- underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}"));
-
- verify(queue).submit(any(CeTaskSubmit.class));
- }
-
- @Test
- public void user_with_scan_permission_on_organization_is_allowed_to_submit_a_report_on_existing_project() {
- OrganizationDto org = db.organizations().insert();
- ComponentDto project = db.components().insertPrivateProject(org);
- userSession.addPermission(SCAN, org);
-
- mockSuccessfulPrepareSubmitCall();
-
- underTest.submit(org.getKey(), project.getDbKey(), null, project.name(), IOUtils.toInputStream("{binary}"));
-
- verify(queue).submit(any(CeTaskSubmit.class));
- }
-
- @Test
- public void submit_a_report_on_existing_project_with_project_scan_permission() {
- ComponentDto project = db.components().insertPrivateProject(db.getDefaultOrganization());
- userSession.addProjectPermission(SCAN_EXECUTION, project);
-
- mockSuccessfulPrepareSubmitCall();
-
- underTest.submit(defaultOrganizationKey, project.getDbKey(), null, project.name(), IOUtils.toInputStream("{binary}"));
-
- verify(queue).submit(any(CeTaskSubmit.class));
- }
-
- /**
- * SONAR-8757
- */
- @Test
- public void project_branch_must_not_benefit_from_the_scan_permission_on_main_project() {
- ComponentDto mainProject = db.components().insertPrivateProject();
- userSession.addProjectPermission(GlobalPermissions.SCAN_EXECUTION, mainProject);
-
- // user does not have the "scan" permission on the branch, so it can't scan it
- String branchName = "branchFoo";
- ComponentDto branchProject = db.components().insertPrivateProject(p -> p.setDbKey(mainProject.getDbKey() + ":" + branchName));
-
- expectedException.expect(ForbiddenException.class);
- underTest.submit(defaultOrganizationKey, mainProject.getDbKey(), branchName, PROJECT_NAME, IOUtils.toInputStream("{binary}"));
- }
-
- @Test
- public void fail_with_NotFoundException_if_organization_with_specified_key_does_not_exist() {
- expectedException.expect(NotFoundException.class);
- expectedException.expectMessage("Organization with key 'fop' does not exist");
-
- underTest.submit("fop", PROJECT_KEY, null, null, null /* method will fail before parameter is used */);
- }
-
- @Test
- public void fail_with_organizationKey_does_not_match_organization_of_specified_component() {
- userSession.logIn().setRoot();
- OrganizationDto organization = db.organizations().insert();
- ComponentDto project = db.components().insertPrivateProject(organization);
- mockSuccessfulPrepareSubmitCall();
-
- underTest.submit(organization.getKey(), project.getDbKey(), null, project.name(), IOUtils.toInputStream("{binary}"));
- }
-
- @Test
- public void fail_if_component_is_not_a_project() {
- ComponentDto component = db.components().insertPublicPortfolio(db.getDefaultOrganization());
- userSession.logIn().addProjectPermission(SCAN_EXECUTION, component);
- mockSuccessfulPrepareSubmitCall();
-
- expectedException.expect(BadRequestException.class);
- expectedException.expectMessage(format("Component '%s' is not a project", component.getKey()));
-
- underTest.submit(defaultOrganizationKey, component.getDbKey(), null, component.name(), IOUtils.toInputStream("{binary}"));
- }
-
- @Test
- public void fail_if_project_key_already_exists_as_module() {
- ComponentDto project = db.components().insertPrivateProject(db.getDefaultOrganization());
- ComponentDto module = db.components().insertComponent(newModuleDto(project));
- userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
- mockSuccessfulPrepareSubmitCall();
-
- try {
- underTest.submit(defaultOrganizationKey, module.getDbKey(), null, module.name(), IOUtils.toInputStream("{binary}"));
- fail();
- } catch (BadRequestException e) {
- assertThat(e.errors()).contains(
- format("The project '%s' is already defined in SonarQube but as a module of project '%s'. " +
- "If you really want to stop directly analysing project '%s', please first delete it from SonarQube and then relaunch the analysis of project '%s'.",
- module.getKey(), project.getKey(), project.getKey(), module.getKey()));
- }
- }
-
- @Test
- public void fail_with_forbidden_exception_when_no_scan_permission() {
- expectedException.expect(ForbiddenException.class);
-
- underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}"));
- }
-
- @Test
- public void fail_with_forbidden_exception_on_new_project_when_only_project_scan_permission() {
- userSession.addProjectPermission(SCAN_EXECUTION, ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization(), PROJECT_UUID));
-
- mockSuccessfulPrepareSubmitCall();
- when(componentUpdater.create(any(DbSession.class), any(NewComponent.class), eq(null))).thenReturn(new ComponentDto().setUuid(PROJECT_UUID).setDbKey(PROJECT_KEY));
-
- expectedException.expect(ForbiddenException.class);
- underTest.submit(defaultOrganizationKey, PROJECT_KEY, null, PROJECT_NAME, IOUtils.toInputStream("{binary}"));
- }
-
- private void verifyReportIsPersisted(String taskUuid) {
- assertThat(db.selectFirst("select task_uuid from ce_task_input where task_uuid='" + taskUuid + "'")).isNotNull();
- }
-
- private void mockSuccessfulPrepareSubmitCall() {
- when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder(TASK_UUID));
- }
-
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.settings;
+
+import org.junit.Test;
+import org.sonar.server.setting.ThreadLocalSettings;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+public class SettingsLoaderTest {
+ private ThreadLocalSettings threadLocalSettings = mock(ThreadLocalSettings.class);
+ private SettingsLoader underTest = new SettingsLoader(threadLocalSettings);
+
+ @Test
+ public void start_calls_ThreadLocalSettings_load() {
+ underTest.start();
+
+ verify(threadLocalSettings).load();
+ verifyNoMoreInteractions(threadLocalSettings);
+ }
+
+ @Test
+ public void stop_calls_ThreadLocalSettings_remove() {
+ underTest.stop();
+
+ verify(threadLocalSettings).unload();
+ verifyNoMoreInteractions(threadLocalSettings);
+ }
+}
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.sonar.ce.queue.CeTaskResult;
+import org.sonar.server.computation.CeTaskResult;
import static org.mockito.Mockito.mock;