]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6831 move queue related classes to their own package
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 21 Sep 2015 12:59:53 +0000 (14:59 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Mon, 28 Sep 2015 10:22:13 +0000 (12:22 +0200)
71 files changed:
server/sonar-server/src/main/java/org/sonar/server/computation/CeProcessingScheduler.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/CeProcessingSchedulerExecutorService.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/CeProcessingSchedulerExecutorServiceImpl.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/CeProcessingSchedulerImpl.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/CeQueue.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/CeQueueCleaner.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/CeQueueImpl.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/CeQueueInitializer.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/CeQueueListener.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/CeTask.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/CeTaskSubmit.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/CeWorkerRunnable.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/CleanReportQueueListener.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/ComputeEngineProcessingModule.java
server/sonar-server/src/main/java/org/sonar/server/computation/ReportSubmitter.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/ReportTaskProcessor.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/batch/BatchReportDirectoryHolder.java
server/sonar-server/src/main/java/org/sonar/server/computation/container/ComputeEngineContainer.java
server/sonar-server/src/main/java/org/sonar/server/computation/container/ContainerFactory.java
server/sonar-server/src/main/java/org/sonar/server/computation/container/ContainerFactoryImpl.java
server/sonar-server/src/main/java/org/sonar/server/computation/container/ReportComputeEngineContainerPopulator.java
server/sonar-server/src/main/java/org/sonar/server/computation/log/CeFileAppenderFactory.java
server/sonar-server/src/main/java/org/sonar/server/computation/log/CeLogging.java
server/sonar-server/src/main/java/org/sonar/server/computation/log/LogFileRef.java
server/sonar-server/src/main/java/org/sonar/server/computation/monitoring/ComputeEngineQueueMonitor.java
server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeProcessingScheduler.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeProcessingSchedulerExecutorService.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeProcessingSchedulerExecutorServiceImpl.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeProcessingSchedulerImpl.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeQueue.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeQueueCleaner.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeQueueImpl.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeQueueInitializer.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeQueueListener.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeTask.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeTaskSubmit.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeWorkerRunnable.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/queue/package-info.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/queue/report/CleanReportQueueListener.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/queue/report/ReportSubmitter.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/queue/report/ReportTaskProcessor.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/queue/report/package-info.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/computation/step/ExtractReportStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/ws/CancelAllWsAction.java
server/sonar-server/src/main/java/org/sonar/server/computation/ws/CancelWsAction.java
server/sonar-server/src/main/java/org/sonar/server/computation/ws/SubmitWsAction.java
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
server/sonar-server/src/test/java/org/sonar/server/computation/CeProcessingSchedulerImplTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/computation/CeQueueCleanerTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/computation/CeQueueImplTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/computation/CeQueueInitializerTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/computation/CeTaskTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/computation/CeWorkerRunnableTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/computation/CleanReportQueueListenerTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/computation/ReportSubmitterTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/computation/container/ReportComputeEngineContainerPopulatorTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/log/CeLoggingTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/monitoring/ComputeEngineQueueMonitorTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/queue/CeProcessingSchedulerImplTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/computation/queue/CeQueueCleanerTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/computation/queue/CeQueueImplTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/computation/queue/CeQueueInitializerTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/computation/queue/CeTaskTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/computation/queue/CeWorkerRunnableTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/computation/queue/report/CleanReportQueueListenerTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/computation/queue/report/ReportSubmitterTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/computation/step/ComputationStepsTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/ws/CancelAllWsActionTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/ws/CancelWsActionTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/ws/CeWsTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/ws/SubmitWsActionTest.java

diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/CeProcessingScheduler.java b/server/sonar-server/src/main/java/org/sonar/server/computation/CeProcessingScheduler.java
deleted file mode 100644 (file)
index 184b400..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-public interface CeProcessingScheduler {
-
-  void startScheduling();
-
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/CeProcessingSchedulerExecutorService.java b/server/sonar-server/src/main/java/org/sonar/server/computation/CeProcessingSchedulerExecutorService.java
deleted file mode 100644 (file)
index d3ff041..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import org.sonar.server.util.StoppableScheduledExecutorService;
-
-/**
- * The {@link java.util.concurrent.ExecutorService} responsible for running {@link CeWorkerRunnable}.
- */
-public interface CeProcessingSchedulerExecutorService extends StoppableScheduledExecutorService {
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/CeProcessingSchedulerExecutorServiceImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/CeProcessingSchedulerExecutorServiceImpl.java
deleted file mode 100644 (file)
index 8087038..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import org.sonar.server.util.AbstractStoppableScheduledExecutorServiceImpl;
-
-public class CeProcessingSchedulerExecutorServiceImpl extends AbstractStoppableScheduledExecutorServiceImpl<ScheduledExecutorService>
-  implements CeProcessingSchedulerExecutorService {
-  private static final String THREAD_NAME_PREFIX = "ce-processor-";
-
-  public CeProcessingSchedulerExecutorServiceImpl() {
-    super(
-      Executors.newSingleThreadScheduledExecutor(
-        new ThreadFactoryBuilder()
-          .setNameFormat(THREAD_NAME_PREFIX + "%d")
-          .setPriority(Thread.MIN_PRIORITY)
-          .build()));
-  }
-
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/CeProcessingSchedulerImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/CeProcessingSchedulerImpl.java
deleted file mode 100644 (file)
index 43bbca2..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import java.util.concurrent.TimeUnit;
-import org.sonar.server.computation.log.CeLogging;
-
-public class CeProcessingSchedulerImpl implements CeProcessingScheduler {
-  private final CeProcessingSchedulerExecutorService executorService;
-  private final CeQueue ceQueue;
-  private final ReportTaskProcessor reportTaskProcessor;
-  private final CeLogging ceLogging;
-
-  private final long delayBetweenTasks;
-  private final long delayForFirstStart;
-  private final TimeUnit timeUnit;
-
-  public CeProcessingSchedulerImpl(CeProcessingSchedulerExecutorService processingExecutorService, CeQueue ceQueue, ReportTaskProcessor reportTaskProcessor, CeLogging ceLogging) {
-    this.executorService = processingExecutorService;
-    this.ceQueue = ceQueue;
-    this.reportTaskProcessor = reportTaskProcessor;
-    this.ceLogging = ceLogging;
-
-    this.delayBetweenTasks = 10;
-    this.delayForFirstStart = 0;
-    this.timeUnit = TimeUnit.SECONDS;
-  }
-
-  @Override
-  public void startScheduling() {
-    executorService.scheduleAtFixedRate(new CeWorkerRunnable(ceQueue, reportTaskProcessor, ceLogging), delayForFirstStart, delayBetweenTasks, timeUnit);
-  }
-
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/CeQueue.java b/server/sonar-server/src/main/java/org/sonar/server/computation/CeQueue.java
deleted file mode 100644 (file)
index 7669bda..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import com.google.common.base.Optional;
-import org.sonar.db.ce.CeActivityDto;
-
-/**
- * Queue of pending Compute Engine tasks. Both producer and consumer actions
- * are implemented.
- * <p>
- *   This class is decoupled from the regular task type {@link org.sonar.db.ce.CeTaskTypes#REPORT}.
- * </p>
- */
-public interface CeQueue {
-  /**
-   * Build an instance of {@link CeTaskSubmit} required for {@link #submit(CeTaskSubmit)}. It allows
-   * to enforce that task ids are generated by the queue. It's used also for having access
-   * to the id before submitting the task to the queue.
-   */
-  CeTaskSubmit.Builder prepareSubmit();
-
-  /**
-   * Submits a task to the queue. The task is processed asynchronously.
-   * If submits are paused (see {@link #isSubmitPaused()}, then an
-   * unchecked exception is thrown.
-   */
-  CeTask submit(CeTaskSubmit submission);
-
-  /**
-   * Peek the oldest task in status {@link org.sonar.db.ce.CeQueueDto.Status#PENDING}.
-   * The task status is changed to {@link org.sonar.db.ce.CeQueueDto.Status#IN_PROGRESS}.
-   * Does not return anything if the queue is paused (see {@link #isPeekPaused()}.
-   *
-   * <p>Only a single task can be peeked by project.</p>
-   *
-   * <p>An unchecked exception may be thrown on technical errors (db connection, ...).</p>
-   */
-  Optional<CeTask> peek();
-
-  /**
-   * Cancels a task in status {@link org.sonar.db.ce.CeQueueDto.Status#PENDING}. An unchecked
-   * exception is thrown if the status is not {@link org.sonar.db.ce.CeQueueDto.Status#PENDING}.
-   * The method does nothing and returns {@code false} if the task does not exist.
-   *
-   * @return true if the task exists and is successfully canceled.
-   */
-  boolean cancel(String taskUuid);
-
-  /**
-   * Removes all the tasks from the queue, whatever their status. They are marked
-   * as {@link org.sonar.db.ce.CeActivityDto.Status#CANCELED} in past activity.
-   * This method can NOT be called when  workers are being executed, as in progress
-   * tasks can't be killed.
-   *
-   * @return the number of canceled tasks
-   */
-  int clear();
-
-  /**
-   * Similar as {@link #clear()}, except that the tasks with status
-   * {@link org.sonar.db.ce.CeQueueDto.Status#IN_PROGRESS} are ignored. This method
-   * can be called at runtime, even if workers are being executed.
-   *
-   * @return the number of canceled tasks
-   */
-  int cancelAll();
-
-  /**
-   * Removes a task from the queue and registers it to past activities. This method
-   * is called by Compute Engine workers when task is processed.
-   *
-   * <p>An unchecked exception is thrown if the task does not exist in the queue.</p>
-   */
-  void remove(CeTask task, CeActivityDto.Status status);
-
-  void pauseSubmit();
-
-  void resumeSubmit();
-
-  boolean isSubmitPaused();
-
-  void pausePeek();
-
-  void resumePeek();
-
-  boolean isPeekPaused();
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/CeQueueCleaner.java b/server/sonar-server/src/main/java/org/sonar/server/computation/CeQueueCleaner.java
deleted file mode 100644 (file)
index 7b67aa3..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import java.util.HashSet;
-import java.util.Set;
-import org.sonar.api.platform.ServerUpgradeStatus;
-import org.sonar.api.server.ServerSide;
-import org.sonar.api.utils.log.Logger;
-import org.sonar.api.utils.log.Loggers;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.ce.CeQueueDto;
-import org.sonar.db.ce.CeTaskTypes;
-
-/**
- * Cleans-up the Compute Engine queue and resets the JMX counters.
- * CE workers must not be started before execution of this class.
- */
-@ServerSide
-public class CeQueueCleaner {
-
-  private static final Logger LOGGER = Loggers.get(CeQueueCleaner.class);
-
-  private final DbClient dbClient;
-  private final ServerUpgradeStatus serverUpgradeStatus;
-  private final ReportFiles reportFiles;
-  private final CeQueueImpl queue;
-
-  public CeQueueCleaner(DbClient dbClient, ServerUpgradeStatus serverUpgradeStatus, ReportFiles reportFiles, CeQueueImpl queue) {
-    this.dbClient = dbClient;
-    this.serverUpgradeStatus = serverUpgradeStatus;
-    this.reportFiles = reportFiles;
-    this.queue = queue;
-  }
-
-  public void clean(DbSession dbSession) {
-    if (serverUpgradeStatus.isUpgraded()) {
-      cleanOnUpgrade();
-    } else {
-      verifyConsistency(dbSession);
-    }
-  }
-
-  private void cleanOnUpgrade() {
-    // we assume that pending tasks are not compatible with the new version
-    // and can't be processed
-    LOGGER.info("Cancel all pending tasks (due to upgrade)");
-    queue.clear();
-  }
-
-  private void verifyConsistency(DbSession dbSession) {
-    // server is not being upgraded
-    dbClient.ceQueueDao().resetAllToPendingStatus(dbSession);
-    dbSession.commit();
-
-    // verify that the report files are available for the tasks in queue
-    Set<String> uuidsInQueue = new HashSet<>();
-    for (CeQueueDto queueDto : dbClient.ceQueueDao().selectAllInAscOrder(dbSession)) {
-      uuidsInQueue.add(queueDto.getUuid());
-      if (CeTaskTypes.REPORT.equals(queueDto.getTaskType()) && !reportFiles.fileForUuid(queueDto.getUuid()).exists()) {
-        // the report is not available on file system
-        queue.cancel(dbSession, queueDto);
-      }
-    }
-
-    // clean-up filesystem
-    for (String uuid : reportFiles.listUuids()) {
-      if (!uuidsInQueue.contains(uuid)) {
-        reportFiles.deleteIfExists(uuid);
-      }
-    }
-  }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/CeQueueImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/CeQueueImpl.java
deleted file mode 100644 (file)
index 67cd61d..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import com.google.common.base.Optional;
-import java.util.concurrent.atomic.AtomicBoolean;
-import org.sonar.api.server.ServerSide;
-import org.sonar.api.utils.System2;
-import org.sonar.core.util.UuidFactory;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.ce.CeActivityDto;
-import org.sonar.db.ce.CeQueueDto;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.server.computation.monitoring.CEQueueStatus;
-
-import static com.google.common.base.Preconditions.checkState;
-import static java.lang.String.format;
-
-@ServerSide
-public class CeQueueImpl implements CeQueue {
-
-  private final System2 system2;
-  private final DbClient dbClient;
-  private final UuidFactory uuidFactory;
-  private final CEQueueStatus queueStatus;
-  private final CeQueueListener[] listeners;
-
-  // state
-  private AtomicBoolean submitPaused = new AtomicBoolean(false);
-  private AtomicBoolean peekPaused = new AtomicBoolean(false);
-
-  public CeQueueImpl(System2 system2, DbClient dbClient, UuidFactory uuidFactory,
-    CEQueueStatus queueStatus, CeQueueListener[] listeners) {
-    this.system2 = system2;
-    this.dbClient = dbClient;
-    this.uuidFactory = uuidFactory;
-    this.queueStatus = queueStatus;
-    this.listeners = listeners;
-  }
-
-  @Override
-  public CeTaskSubmit.Builder prepareSubmit() {
-    return new CeTaskSubmit.Builder(uuidFactory.create());
-  }
-
-  @Override
-  public CeTask submit(CeTaskSubmit submission) {
-    checkState(!submitPaused.get(), "Compute Engine does not currently accept new tasks");
-
-    DbSession dbSession = dbClient.openSession(false);
-    try {
-      CeQueueDto dto = new CeQueueDto();
-      dto.setUuid(submission.getUuid());
-      dto.setTaskType(submission.getType());
-      dto.setComponentUuid(submission.getComponentUuid());
-      dto.setStatus(CeQueueDto.Status.PENDING);
-      dto.setSubmitterLogin(submission.getSubmitterLogin());
-      dto.setStartedAt(null);
-      dbClient.ceQueueDao().insert(dbSession, dto);
-      CeTask task = loadTask(dbSession, dto);
-      dbSession.commit();
-      queueStatus.addReceived();
-      return task;
-
-    } finally {
-      dbClient.closeSession(dbSession);
-    }
-  }
-
-  @Override
-  public Optional<CeTask> peek() {
-    if (peekPaused.get()) {
-      return Optional.absent();
-    }
-    DbSession dbSession = dbClient.openSession(false);
-    try {
-      Optional<CeQueueDto> dto = dbClient.ceQueueDao().peek(dbSession);
-      CeTask task = null;
-      if (dto.isPresent()) {
-        task = loadTask(dbSession, dto.get());
-        queueStatus.addInProgress();
-      }
-      return Optional.fromNullable(task);
-
-    } finally {
-      dbClient.closeSession(dbSession);
-    }
-  }
-
-  private CeTask loadTask(DbSession dbSession, CeQueueDto dto) {
-    CeTask.Builder builder = new CeTask.Builder();
-    builder.setUuid(dto.getUuid());
-    builder.setType(dto.getTaskType());
-    builder.setSubmitterLogin(dto.getSubmitterLogin());
-    String componentUuid = dto.getComponentUuid();
-    if (componentUuid != null) {
-      builder.setComponentUuid(componentUuid);
-      Optional<ComponentDto> component = dbClient.componentDao().selectByUuid(dbSession, componentUuid);
-      if (component.isPresent()) {
-        builder.setComponentKey(component.get().getKey());
-        builder.setComponentName(component.get().name());
-      }
-    }
-    return builder.build();
-  }
-
-  @Override
-  public boolean cancel(String taskUuid) {
-    DbSession dbSession = dbClient.openSession(false);
-    try {
-      Optional<CeQueueDto> queueDto = dbClient.ceQueueDao().selectByUuid(dbSession, taskUuid);
-      if (queueDto.isPresent()) {
-        checkState(CeQueueDto.Status.PENDING.equals(queueDto.get().getStatus()), "Task is in progress and can't be canceled [uuid=%s]", taskUuid);
-        cancel(dbSession, queueDto.get());
-        return true;
-      }
-      return false;
-    } finally {
-      dbClient.closeSession(dbSession);
-    }
-  }
-
-  void cancel(DbSession dbSession, CeQueueDto q) {
-    CeTask task = loadTask(dbSession, q);
-    CeActivityDto activityDto = new CeActivityDto(q);
-    activityDto.setStatus(CeActivityDto.Status.CANCELED);
-    remove(dbSession, task, q, activityDto);
-  }
-
-  @Override
-  public int clear() {
-    return cancelAll(true);
-  }
-
-  @Override
-  public int cancelAll() {
-    return cancelAll(false);
-  }
-
-  private int cancelAll(boolean includeInProgress) {
-    int count = 0;
-    DbSession dbSession = dbClient.openSession(false);
-    try {
-      for (CeQueueDto queueDto : dbClient.ceQueueDao().selectAllInAscOrder(dbSession)) {
-        if (includeInProgress || !queueDto.getStatus().equals(CeQueueDto.Status.IN_PROGRESS)) {
-          cancel(dbSession, queueDto);
-          count++;
-        }
-      }
-      return count;
-    } finally {
-      dbClient.closeSession(dbSession);
-    }
-  }
-
-  @Override
-  public void remove(CeTask task, CeActivityDto.Status status) {
-    DbSession dbSession = dbClient.openSession(false);
-    try {
-      Optional<CeQueueDto> queueDto = dbClient.ceQueueDao().selectByUuid(dbSession, task.getUuid());
-      if (!queueDto.isPresent()) {
-        throw new IllegalStateException(format("Task does not exist anymore: %s", task));
-      }
-      CeActivityDto activityDto = new CeActivityDto(queueDto.get());
-      activityDto.setStatus(status);
-      updateQueueStatus(status, activityDto);
-      remove(dbSession, task, queueDto.get(), activityDto);
-
-    } finally {
-      dbClient.closeSession(dbSession);
-    }
-  }
-
-  private void updateQueueStatus(CeActivityDto.Status status, CeActivityDto activityDto) {
-    Long startedAt = activityDto.getStartedAt();
-    if (startedAt == null) {
-      return;
-    }
-    activityDto.setFinishedAt(system2.now());
-    long executionTime = activityDto.getFinishedAt() - startedAt;
-    activityDto.setExecutionTimeMs(executionTime);
-    if (status == CeActivityDto.Status.SUCCESS) {
-      queueStatus.addSuccess(executionTime);
-    } else {
-      queueStatus.addError(executionTime);
-    }
-  }
-
-  private void remove(DbSession dbSession, CeTask task, CeQueueDto queueDto, CeActivityDto activityDto) {
-    dbClient.ceActivityDao().insert(dbSession, activityDto);
-    dbClient.ceQueueDao().deleteByUuid(dbSession, queueDto.getUuid());
-    dbSession.commit();
-    for (CeQueueListener listener : listeners) {
-      listener.onRemoved(task, activityDto.getStatus());
-    }
-  }
-
-  @Override
-  public void pauseSubmit() {
-    this.submitPaused.set(true);
-  }
-
-  @Override
-  public void resumeSubmit() {
-    this.submitPaused.set(false);
-  }
-
-  @Override
-  public boolean isSubmitPaused() {
-    return submitPaused.get();
-  }
-
-  @Override
-  public void pausePeek() {
-    this.peekPaused.set(true);
-  }
-
-  @Override
-  public void resumePeek() {
-    this.peekPaused.set(false);
-  }
-
-  @Override
-  public boolean isPeekPaused() {
-    return peekPaused.get();
-  }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/CeQueueInitializer.java b/server/sonar-server/src/main/java/org/sonar/server/computation/CeQueueInitializer.java
deleted file mode 100644 (file)
index 8c75db5..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import org.picocontainer.Startable;
-import org.sonar.api.server.ServerSide;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.server.computation.monitoring.CEQueueStatus;
-
-/**
- * Cleans-up the queue, initializes JMX counters then schedule
- * the execution of workers. That allows to not prevent workers
- * from peeking the queue before it's ready.
- */
-@ServerSide
-public class CeQueueInitializer implements Startable {
-
-  private final DbClient dbClient;
-  private final CEQueueStatus queueStatus;
-  private final CeQueueCleaner cleaner;
-  private final CeProcessingScheduler scheduler;
-
-  public CeQueueInitializer(DbClient dbClient, CEQueueStatus queueStatus, CeQueueCleaner cleaner, CeProcessingScheduler scheduler) {
-    this.dbClient = dbClient;
-    this.queueStatus = queueStatus;
-    this.cleaner = cleaner;
-    this.scheduler = scheduler;
-  }
-
-  @Override
-  public void start() {
-    DbSession dbSession = dbClient.openSession(false);
-    try {
-      initJmxCounters(dbSession);
-      cleaner.clean(dbSession);
-      scheduler.startScheduling();
-
-    } finally {
-      dbClient.closeSession(dbSession);
-    }
-  }
-
-  @Override
-  public void stop() {
-    // nothing to do
-  }
-
-  private void initJmxCounters(DbSession dbSession) {
-    queueStatus.initPendingCount(dbClient.ceQueueDao().countAll(dbSession));
-  }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/CeQueueListener.java b/server/sonar-server/src/main/java/org/sonar/server/computation/CeQueueListener.java
deleted file mode 100644 (file)
index 420c660..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import org.sonar.db.ce.CeActivityDto;
-
-public interface CeQueueListener {
-
-  void onRemoved(CeTask task, CeActivityDto.Status status);
-
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/CeTask.java b/server/sonar-server/src/main/java/org/sonar/server/computation/CeTask.java
deleted file mode 100644 (file)
index 62ef351..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import com.google.common.base.Objects;
-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 type;
-  private final String uuid;
-  private final String componentUuid;
-  private final String componentKey;
-  private final String componentName;
-  private final String submitterLogin;
-
-  private CeTask(Builder builder) {
-    this.uuid = requireNonNull(emptyToNull(builder.uuid));
-    this.type = requireNonNull(emptyToNull(builder.type));
-    this.componentUuid = emptyToNull(builder.componentUuid);
-    this.componentKey = emptyToNull(builder.componentKey);
-    this.componentName = emptyToNull(builder.componentName);
-    this.submitterLogin = emptyToNull(builder.submitterLogin);
-  }
-
-  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 getSubmitterLogin() {
-    return submitterLogin;
-  }
-
-  @Override
-  public String toString() {
-    return Objects.toStringHelper(this)
-      .add("componentUuid", componentUuid)
-      .add("uuid", uuid)
-      .add("type", type)
-      .add("submitterLogin", submitterLogin)
-      .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 uuid;
-    private String type;
-    private String componentUuid;
-    private String componentKey;
-    private String componentName;
-    private String submitterLogin;
-
-    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 setSubmitterLogin(@Nullable String s) {
-      this.submitterLogin = s;
-      return this;
-    }
-
-    public CeTask build() {
-      return new CeTask(this);
-    }
-  }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/CeTaskSubmit.java b/server/sonar-server/src/main/java/org/sonar/server/computation/CeTaskSubmit.java
deleted file mode 100644 (file)
index d7d21f4..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import java.util.Objects;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import javax.annotation.concurrent.Immutable;
-
-import static com.google.common.base.Strings.emptyToNull;
-
-@Immutable
-public final class CeTaskSubmit {
-
-  private final String uuid;
-  private final String type;
-  private final String componentUuid;
-  private final String submitterLogin;
-
-  private CeTaskSubmit(Builder builder) {
-    this.uuid = Objects.requireNonNull(emptyToNull(builder.uuid));
-    this.type = Objects.requireNonNull(emptyToNull(builder.type));
-    this.componentUuid = emptyToNull(builder.componentUuid);
-    this.submitterLogin = emptyToNull(builder.submitterLogin);
-  }
-
-  public String getType() {
-    return type;
-  }
-
-  public String getUuid() {
-    return uuid;
-  }
-
-  @CheckForNull
-  public String getComponentUuid() {
-    return componentUuid;
-  }
-
-  @CheckForNull
-  public String getSubmitterLogin() {
-    return submitterLogin;
-  }
-
-  public static final class Builder {
-    private final String uuid;
-    private String type;
-    private String componentUuid;
-    private String submitterLogin;
-
-    Builder(String uuid) {
-      this.uuid = uuid;
-    }
-
-    public String getUuid() {
-      return uuid;
-    }
-
-    public Builder setType(String s) {
-      this.type = s;
-      return this;
-    }
-
-    public Builder setComponentUuid(@Nullable String s) {
-      this.componentUuid = s;
-      return this;
-    }
-
-    public Builder setSubmitterLogin(@Nullable String s) {
-      this.submitterLogin = s;
-      return this;
-    }
-
-    public CeTaskSubmit build() {
-      return new CeTaskSubmit(this);
-    }
-  }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/CeWorkerRunnable.java b/server/sonar-server/src/main/java/org/sonar/server/computation/CeWorkerRunnable.java
deleted file mode 100644 (file)
index 42d4741..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-
-package org.sonar.server.computation;
-
-import com.google.common.base.Optional;
-import org.sonar.api.utils.log.Logger;
-import org.sonar.api.utils.log.Loggers;
-import org.sonar.core.util.logs.Profiler;
-import org.sonar.db.ce.CeActivityDto;
-import org.sonar.server.computation.log.CeLogging;
-
-import static java.lang.String.format;
-
-class CeWorkerRunnable implements Runnable {
-
-  private static final Logger LOG = Loggers.get(CeWorkerRunnable.class);
-
-  private final CeQueue queue;
-  private final ReportTaskProcessor reportTaskProcessor;
-  private final CeLogging ceLogging;
-
-  public CeWorkerRunnable(CeQueue queue, ReportTaskProcessor reportTaskProcessor, CeLogging ceLogging) {
-    this.queue = queue;
-    this.reportTaskProcessor = reportTaskProcessor;
-    this.ceLogging = ceLogging;
-  }
-
-  @Override
-  public void run() {
-    Optional<CeTask> ceTask = tryAndFindTaskToExecute();
-    if (!ceTask.isPresent()) {
-      return;
-    }
-
-    executeTask(ceTask.get());
-  }
-
-  private Optional<CeTask> tryAndFindTaskToExecute() {
-    try {
-      return queue.peek();
-    } catch (Exception e) {
-      LOG.error("Failed to pop the queue of analysis reports", e);
-    }
-    return Optional.absent();
-  }
-
-  private void executeTask(CeTask task) {
-    ceLogging.initForTask(task);
-    Profiler profiler = Profiler.create(LOG).startInfo(format("Analysis of project %s (report %s)", task.getComponentKey(), task.getUuid()));
-    try {
-      // TODO delegate the message to the related task processor, according to task type
-      reportTaskProcessor.process(task);
-      queue.remove(task, CeActivityDto.Status.SUCCESS);
-    } catch (Throwable e) {
-      LOG.error(format("Failed to process task %s", task.getUuid()), e);
-      queue.remove(task, CeActivityDto.Status.FAILED);
-    } finally {
-      profiler.stopInfo(String.format("Total thread execution of project %s (report %s)", task.getComponentUuid(), task.getUuid()));
-      ceLogging.clearForTask();
-    }
-  }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/CleanReportQueueListener.java b/server/sonar-server/src/main/java/org/sonar/server/computation/CleanReportQueueListener.java
deleted file mode 100644 (file)
index 16a793e..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import org.sonar.db.ce.CeActivityDto;
-
-public class CleanReportQueueListener implements CeQueueListener {
-
-  private final ReportFiles reportFiles;
-
-  public CleanReportQueueListener(ReportFiles reportFiles) {
-    this.reportFiles = reportFiles;
-  }
-
-  @Override
-  public void onRemoved(CeTask task, CeActivityDto.Status status) {
-    reportFiles.deleteIfExists(task.getUuid());
-  }
-}
index a5d48d7db3185d1736972f3e574455a05587fa53..8766d7a8e27051bd8cb237601ff6a51fe2b33204 100644 (file)
@@ -21,6 +21,9 @@ package org.sonar.server.computation;
 
 import org.sonar.core.platform.Module;
 import org.sonar.server.computation.container.ContainerFactoryImpl;
+import org.sonar.server.computation.queue.CeProcessingSchedulerExecutorServiceImpl;
+import org.sonar.server.computation.queue.CeProcessingSchedulerImpl;
+import org.sonar.server.computation.queue.report.ReportTaskProcessor;
 
 public class ComputeEngineProcessingModule extends Module {
   @Override
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ReportSubmitter.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ReportSubmitter.java
deleted file mode 100644 (file)
index 0a564ab..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import java.io.InputStream;
-import javax.annotation.Nullable;
-import org.apache.commons.lang.StringUtils;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.server.ServerSide;
-import org.sonar.core.component.ComponentKeys;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.db.ce.CeTaskTypes;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.server.component.ComponentService;
-import org.sonar.server.component.NewComponent;
-import org.sonar.server.permission.PermissionService;
-import org.sonar.server.user.UserSession;
-
-@ServerSide
-public class ReportSubmitter {
-
-  private final CeQueue queue;
-  private final UserSession userSession;
-  private final ReportFiles reportFiles;
-  private final ComponentService componentService;
-  private final PermissionService permissionService;
-
-  public ReportSubmitter(CeQueue queue, UserSession userSession, ReportFiles reportFiles,
-    ComponentService componentService, PermissionService permissionService) {
-    this.queue = queue;
-    this.userSession = userSession;
-    this.reportFiles = reportFiles;
-    this.componentService = componentService;
-    this.permissionService = permissionService;
-  }
-
-  public CeTask submit(String projectKey, @Nullable String projectBranch, @Nullable String projectName, InputStream reportInput) {
-    userSession.checkGlobalPermission(GlobalPermissions.SCAN_EXECUTION);
-
-    String effectiveProjectKey = ComponentKeys.createKey(projectKey, projectBranch);
-    ComponentDto project = componentService.getNullableByKey(effectiveProjectKey);
-    if (project == null) {
-      // the project does not exist -> requires to provision it
-      NewComponent newProject = new NewComponent(projectKey, StringUtils.defaultIfBlank(projectName, projectKey));
-      newProject.setBranch(projectBranch);
-      newProject.setQualifier(Qualifiers.PROJECT);
-      // no need to verify the permission "provisioning" as it's already handled by componentService
-      project = componentService.create(newProject);
-      permissionService.applyDefaultPermissionTemplate(project.getKey());
-    }
-
-    // the report file must be saved before submitting the task
-    CeTaskSubmit.Builder submit = queue.prepareSubmit();
-    reportFiles.save(submit.getUuid(), reportInput);
-
-    submit.setType(CeTaskTypes.REPORT);
-    submit.setComponentUuid(project.uuid());
-    submit.setSubmitterLogin(userSession.getLogin());
-    return queue.submit(submit.build());
-  }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ReportTaskProcessor.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ReportTaskProcessor.java
deleted file mode 100644 (file)
index e8dc580..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import org.sonar.core.platform.ComponentContainer;
-import org.sonar.server.computation.container.ComputeEngineContainer;
-import org.sonar.server.computation.container.ContainerFactory;
-
-public class ReportTaskProcessor {
-
-  private final ContainerFactory containerFactory;
-  private final ComponentContainer serverContainer;
-
-  public ReportTaskProcessor(ContainerFactory containerFactory, ComponentContainer serverContainer) {
-    this.containerFactory = containerFactory;
-    this.serverContainer = serverContainer;
-  }
-
-  public void process(CeTask task) {
-    ComputeEngineContainer ceContainer = containerFactory.create(serverContainer, task);
-    try {
-      ceContainer.getComponentByType(ComputationStepExecutor.class).execute();
-    } finally {
-      ceContainer.cleanup();
-    }
-  }
-}
index bb76947dbda960f588e4707da5e3948ca46a9d51..e4fbb915ec305006b56d7ff0824f066f44fadb8a 100644 (file)
 package org.sonar.server.computation.batch;
 
 import java.io.File;
+import org.sonar.server.computation.queue.CeTask;
 
 public interface BatchReportDirectoryHolder {
   /**
-   * The File of the directory where the Batch report files for the current {@link org.sonar.server.computation.CeTask} are stored.
+   * The File of the directory where the Batch report files for the current {@link CeTask} are stored.
    *
    * @throws IllegalStateException if the holder is empty (ie. there is no directory yet)
    */
index 87c091348ab4c034ae26bc14cca089edb159e536..2c59268c8c0b22802a3e7e1a6644bacb46d8e507 100644 (file)
@@ -21,9 +21,10 @@ package org.sonar.server.computation.container;
 
 import org.sonar.core.platform.ComponentContainer;
 import org.sonar.core.platform.ContainerPopulator;
+import org.sonar.server.computation.queue.CeTask;
 
 /**
- * The Compute Engine container. Created for a specific parent {@link ComponentContainer} and a specific {@link org.sonar.server.computation.CeTask}.
+ * The Compute Engine container. Created for a specific parent {@link ComponentContainer} and a specific {@link CeTask}.
  */
 public interface ComputeEngineContainer extends ContainerPopulator.Container {
 
index c1011f6969f646ba684fb02133a005d97a519ad2..4c3a95763937ea9eaa1c6e11e3ed606573af0a1f 100644 (file)
@@ -20,7 +20,7 @@
 package org.sonar.server.computation.container;
 
 import org.sonar.core.platform.ComponentContainer;
-import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.queue.CeTask;
 
 /**
  * Compute
index ed41a1c1f11d090313fce9934dbfc7d1e8cbe10e..e1dfd4f2ac84a1944e78299c7180f0928b4053f0 100644 (file)
@@ -20,7 +20,7 @@
 package org.sonar.server.computation.container;
 
 import org.sonar.core.platform.ComponentContainer;
-import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.queue.CeTask;
 
 public class ContainerFactoryImpl implements ContainerFactory {
   @Override
index cc8f01c859cf6309f3f55a4b3c33f7c13867b824..bea465579420bb64cbc66a1a1672f378b210df50 100644 (file)
@@ -23,7 +23,7 @@ import java.util.Arrays;
 import java.util.List;
 import org.sonar.core.issue.tracking.Tracker;
 import org.sonar.core.platform.ContainerPopulator;
-import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.queue.CeTask;
 import org.sonar.server.computation.ComputationStepExecutor;
 import org.sonar.server.computation.ComputationTempFolderProvider;
 import org.sonar.server.computation.analysis.ReportAnalysisMetadataHolder;
index d2eaacc7d107bb0481c9efe931021049449f7087..29197d2992464e0f38f4e91c21d9e3d1162f39d0 100644 (file)
@@ -25,7 +25,7 @@ import ch.qos.logback.core.FileAppender;
 import ch.qos.logback.core.sift.AppenderFactory;
 import com.google.common.annotations.VisibleForTesting;
 import java.io.File;
-import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.queue.CeTask;
 
 import static java.lang.String.format;
 
@@ -47,7 +47,7 @@ public class CeFileAppenderFactory<E> implements AppenderFactory<E> {
   /**
    * @param context
    * @param discriminatingValue path of log file relative to the directory data/ce/logs
-   * @see CeLogging#initForTask(CeTask)
+   * @see CeLogging#initForTask(CeTask) 
    */
   @Override
   public FileAppender<E> buildAppender(Context context, String discriminatingValue) {
index f1c0d8095dbc29a67332767428250eee0ba58834..8df51dd2335922667fa4065f62f88d681bb9b4dd 100644 (file)
@@ -36,7 +36,7 @@ import org.apache.log4j.MDC;
 import org.sonar.api.config.Settings;
 import org.sonar.process.ProcessProperties;
 import org.sonar.process.Props;
-import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.queue.CeTask;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.collect.FluentIterable.from;
index 896b4b8a79bd428fbdf5608302270b52d7dfbafb..d530a51e89a981da9a3d40bfe04e0e56ce93d160 100644 (file)
@@ -25,7 +25,7 @@ import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import org.sonar.db.ce.CeActivityDto;
 import org.sonar.db.ce.CeQueueDto;
-import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.queue.CeTask;
 
 import static java.lang.String.format;
 
index a5b525d06ac62ac64a341156ef813e36f4b3fb94..f78dfb43efcc473a6edc51374eb80be580e270a7 100644 (file)
@@ -20,7 +20,7 @@
 package org.sonar.server.computation.monitoring;
 
 import java.util.LinkedHashMap;
-import org.sonar.server.computation.CeQueue;
+import org.sonar.server.computation.queue.CeQueue;
 import org.sonar.server.platform.monitoring.BaseMonitorMBean;
 
 public class ComputeEngineQueueMonitor extends BaseMonitorMBean implements ComputeEngineQueueMonitorMBean {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeProcessingScheduler.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeProcessingScheduler.java
new file mode 100644 (file)
index 0000000..fa82e55
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue;
+
+public interface CeProcessingScheduler {
+
+  void startScheduling();
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeProcessingSchedulerExecutorService.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeProcessingSchedulerExecutorService.java
new file mode 100644 (file)
index 0000000..54d0be2
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue;
+
+import org.sonar.server.util.StoppableScheduledExecutorService;
+
+/**
+ * The {@link java.util.concurrent.ExecutorService} responsible for running {@link CeWorkerRunnable}.
+ */
+public interface CeProcessingSchedulerExecutorService extends StoppableScheduledExecutorService {
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeProcessingSchedulerExecutorServiceImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeProcessingSchedulerExecutorServiceImpl.java
new file mode 100644 (file)
index 0000000..e9eb954
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue;
+
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import org.sonar.server.util.AbstractStoppableScheduledExecutorServiceImpl;
+
+public class CeProcessingSchedulerExecutorServiceImpl extends AbstractStoppableScheduledExecutorServiceImpl<ScheduledExecutorService>
+  implements CeProcessingSchedulerExecutorService {
+  private static final String THREAD_NAME_PREFIX = "ce-processor-";
+
+  public CeProcessingSchedulerExecutorServiceImpl() {
+    super(
+      Executors.newSingleThreadScheduledExecutor(
+        new ThreadFactoryBuilder()
+          .setNameFormat(THREAD_NAME_PREFIX + "%d")
+          .setPriority(Thread.MIN_PRIORITY)
+          .build()));
+  }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeProcessingSchedulerImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeProcessingSchedulerImpl.java
new file mode 100644 (file)
index 0000000..4b91824
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue;
+
+import java.util.concurrent.TimeUnit;
+import org.sonar.server.computation.queue.report.ReportTaskProcessor;
+import org.sonar.server.computation.log.CeLogging;
+
+public class CeProcessingSchedulerImpl implements CeProcessingScheduler {
+  private final CeProcessingSchedulerExecutorService executorService;
+  private final CeQueue ceQueue;
+  private final ReportTaskProcessor reportTaskProcessor;
+  private final CeLogging ceLogging;
+
+  private final long delayBetweenTasks;
+  private final long delayForFirstStart;
+  private final TimeUnit timeUnit;
+
+  public CeProcessingSchedulerImpl(CeProcessingSchedulerExecutorService processingExecutorService, CeQueue ceQueue, ReportTaskProcessor reportTaskProcessor, CeLogging ceLogging) {
+    this.executorService = processingExecutorService;
+    this.ceQueue = ceQueue;
+    this.reportTaskProcessor = reportTaskProcessor;
+    this.ceLogging = ceLogging;
+
+    this.delayBetweenTasks = 10;
+    this.delayForFirstStart = 0;
+    this.timeUnit = TimeUnit.SECONDS;
+  }
+
+  @Override
+  public void startScheduling() {
+    executorService.scheduleAtFixedRate(new CeWorkerRunnable(ceQueue, reportTaskProcessor, ceLogging), delayForFirstStart, delayBetweenTasks, timeUnit);
+  }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeQueue.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeQueue.java
new file mode 100644 (file)
index 0000000..74adfcc
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue;
+
+import com.google.common.base.Optional;
+import org.sonar.db.ce.CeActivityDto;
+
+/**
+ * Queue of pending Compute Engine tasks. Both producer and consumer actions
+ * are implemented.
+ * <p>
+ *   This class is decoupled from the regular task type {@link org.sonar.db.ce.CeTaskTypes#REPORT}.
+ * </p>
+ */
+public interface CeQueue {
+  /**
+   * Build an instance of {@link CeTaskSubmit} required for {@link #submit(CeTaskSubmit)}. It allows
+   * to enforce that task ids are generated by the queue. It's used also for having access
+   * to the id before submitting the task to the queue.
+   */
+  CeTaskSubmit.Builder prepareSubmit();
+
+  /**
+   * Submits a task to the queue. The task is processed asynchronously.
+   * If submits are paused (see {@link #isSubmitPaused()}, then an
+   * unchecked exception is thrown.
+   */
+  CeTask submit(CeTaskSubmit submission);
+
+  /**
+   * Peek the oldest task in status {@link org.sonar.db.ce.CeQueueDto.Status#PENDING}.
+   * The task status is changed to {@link org.sonar.db.ce.CeQueueDto.Status#IN_PROGRESS}.
+   * Does not return anything if the queue is paused (see {@link #isPeekPaused()}.
+   *
+   * <p>Only a single task can be peeked by project.</p>
+   *
+   * <p>An unchecked exception may be thrown on technical errors (db connection, ...).</p>
+   */
+  Optional<CeTask> peek();
+
+  /**
+   * Cancels a task in status {@link org.sonar.db.ce.CeQueueDto.Status#PENDING}. An unchecked
+   * exception is thrown if the status is not {@link org.sonar.db.ce.CeQueueDto.Status#PENDING}.
+   * The method does nothing and returns {@code false} if the task does not exist.
+   *
+   * @return true if the task exists and is successfully canceled.
+   */
+  boolean cancel(String taskUuid);
+
+  /**
+   * Removes all the tasks from the queue, whatever their status. They are marked
+   * as {@link org.sonar.db.ce.CeActivityDto.Status#CANCELED} in past activity.
+   * This method can NOT be called when  workers are being executed, as in progress
+   * tasks can't be killed.
+   *
+   * @return the number of canceled tasks
+   */
+  int clear();
+
+  /**
+   * Similar as {@link #clear()}, except that the tasks with status
+   * {@link org.sonar.db.ce.CeQueueDto.Status#IN_PROGRESS} are ignored. This method
+   * can be called at runtime, even if workers are being executed.
+   *
+   * @return the number of canceled tasks
+   */
+  int cancelAll();
+
+  /**
+   * Removes a task from the queue and registers it to past activities. This method
+   * is called by Compute Engine workers when task is processed.
+   *
+   * <p>An unchecked exception is thrown if the task does not exist in the queue.</p>
+   */
+  void remove(CeTask task, CeActivityDto.Status status);
+
+  void pauseSubmit();
+
+  void resumeSubmit();
+
+  boolean isSubmitPaused();
+
+  void pausePeek();
+
+  void resumePeek();
+
+  boolean isPeekPaused();
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeQueueCleaner.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeQueueCleaner.java
new file mode 100644 (file)
index 0000000..6ac6a89
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.sonar.api.platform.ServerUpgradeStatus;
+import org.sonar.api.server.ServerSide;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.ce.CeQueueDto;
+import org.sonar.db.ce.CeTaskTypes;
+import org.sonar.server.computation.ReportFiles;
+
+/**
+ * Cleans-up the Compute Engine queue and resets the JMX counters.
+ * CE workers must not be started before execution of this class.
+ */
+@ServerSide
+public class CeQueueCleaner {
+
+  private static final Logger LOGGER = Loggers.get(CeQueueCleaner.class);
+
+  private final DbClient dbClient;
+  private final ServerUpgradeStatus serverUpgradeStatus;
+  private final ReportFiles reportFiles;
+  private final CeQueueImpl queue;
+
+  public CeQueueCleaner(DbClient dbClient, ServerUpgradeStatus serverUpgradeStatus, ReportFiles reportFiles, CeQueueImpl queue) {
+    this.dbClient = dbClient;
+    this.serverUpgradeStatus = serverUpgradeStatus;
+    this.reportFiles = reportFiles;
+    this.queue = queue;
+  }
+
+  public void clean(DbSession dbSession) {
+    if (serverUpgradeStatus.isUpgraded()) {
+      cleanOnUpgrade();
+    } else {
+      verifyConsistency(dbSession);
+    }
+  }
+
+  private void cleanOnUpgrade() {
+    // we assume that pending tasks are not compatible with the new version
+    // and can't be processed
+    LOGGER.info("Cancel all pending tasks (due to upgrade)");
+    queue.clear();
+  }
+
+  private void verifyConsistency(DbSession dbSession) {
+    // server is not being upgraded
+    dbClient.ceQueueDao().resetAllToPendingStatus(dbSession);
+    dbSession.commit();
+
+    // verify that the report files are available for the tasks in queue
+    Set<String> uuidsInQueue = new HashSet<>();
+    for (CeQueueDto queueDto : dbClient.ceQueueDao().selectAllInAscOrder(dbSession)) {
+      uuidsInQueue.add(queueDto.getUuid());
+      if (CeTaskTypes.REPORT.equals(queueDto.getTaskType()) && !reportFiles.fileForUuid(queueDto.getUuid()).exists()) {
+        // the report is not available on file system
+        queue.cancel(dbSession, queueDto);
+      }
+    }
+
+    // clean-up filesystem
+    for (String uuid : reportFiles.listUuids()) {
+      if (!uuidsInQueue.contains(uuid)) {
+        reportFiles.deleteIfExists(uuid);
+      }
+    }
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeQueueImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeQueueImpl.java
new file mode 100644 (file)
index 0000000..f3ce365
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue;
+
+import com.google.common.base.Optional;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.sonar.api.server.ServerSide;
+import org.sonar.api.utils.System2;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.ce.CeActivityDto;
+import org.sonar.db.ce.CeQueueDto;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.server.computation.monitoring.CEQueueStatus;
+
+import static com.google.common.base.Preconditions.checkState;
+import static java.lang.String.format;
+
+@ServerSide
+public class CeQueueImpl implements CeQueue {
+
+  private final System2 system2;
+  private final DbClient dbClient;
+  private final UuidFactory uuidFactory;
+  private final CEQueueStatus queueStatus;
+  private final CeQueueListener[] listeners;
+
+  // state
+  private AtomicBoolean submitPaused = new AtomicBoolean(false);
+  private AtomicBoolean peekPaused = new AtomicBoolean(false);
+
+  public CeQueueImpl(System2 system2, DbClient dbClient, UuidFactory uuidFactory,
+    CEQueueStatus queueStatus, CeQueueListener[] listeners) {
+    this.system2 = system2;
+    this.dbClient = dbClient;
+    this.uuidFactory = uuidFactory;
+    this.queueStatus = queueStatus;
+    this.listeners = listeners;
+  }
+
+  @Override
+  public CeTaskSubmit.Builder prepareSubmit() {
+    return new CeTaskSubmit.Builder(uuidFactory.create());
+  }
+
+  @Override
+  public CeTask submit(CeTaskSubmit submission) {
+    checkState(!submitPaused.get(), "Compute Engine does not currently accept new tasks");
+
+    DbSession dbSession = dbClient.openSession(false);
+    try {
+      CeQueueDto dto = new CeQueueDto();
+      dto.setUuid(submission.getUuid());
+      dto.setTaskType(submission.getType());
+      dto.setComponentUuid(submission.getComponentUuid());
+      dto.setStatus(CeQueueDto.Status.PENDING);
+      dto.setSubmitterLogin(submission.getSubmitterLogin());
+      dto.setStartedAt(null);
+      dbClient.ceQueueDao().insert(dbSession, dto);
+      CeTask task = loadTask(dbSession, dto);
+      dbSession.commit();
+      queueStatus.addReceived();
+      return task;
+
+    } finally {
+      dbClient.closeSession(dbSession);
+    }
+  }
+
+  @Override
+  public Optional<CeTask> peek() {
+    if (peekPaused.get()) {
+      return Optional.absent();
+    }
+    DbSession dbSession = dbClient.openSession(false);
+    try {
+      Optional<CeQueueDto> dto = dbClient.ceQueueDao().peek(dbSession);
+      CeTask task = null;
+      if (dto.isPresent()) {
+        task = loadTask(dbSession, dto.get());
+        queueStatus.addInProgress();
+      }
+      return Optional.fromNullable(task);
+
+    } finally {
+      dbClient.closeSession(dbSession);
+    }
+  }
+
+  private CeTask loadTask(DbSession dbSession, CeQueueDto dto) {
+    CeTask.Builder builder = new CeTask.Builder();
+    builder.setUuid(dto.getUuid());
+    builder.setType(dto.getTaskType());
+    builder.setSubmitterLogin(dto.getSubmitterLogin());
+    String componentUuid = dto.getComponentUuid();
+    if (componentUuid != null) {
+      builder.setComponentUuid(componentUuid);
+      Optional<ComponentDto> component = dbClient.componentDao().selectByUuid(dbSession, componentUuid);
+      if (component.isPresent()) {
+        builder.setComponentKey(component.get().getKey());
+        builder.setComponentName(component.get().name());
+      }
+    }
+    return builder.build();
+  }
+
+  @Override
+  public boolean cancel(String taskUuid) {
+    DbSession dbSession = dbClient.openSession(false);
+    try {
+      Optional<CeQueueDto> queueDto = dbClient.ceQueueDao().selectByUuid(dbSession, taskUuid);
+      if (queueDto.isPresent()) {
+        checkState(CeQueueDto.Status.PENDING.equals(queueDto.get().getStatus()), "Task is in progress and can't be canceled [uuid=%s]", taskUuid);
+        cancel(dbSession, queueDto.get());
+        return true;
+      }
+      return false;
+    } finally {
+      dbClient.closeSession(dbSession);
+    }
+  }
+
+  void cancel(DbSession dbSession, CeQueueDto q) {
+    CeTask task = loadTask(dbSession, q);
+    CeActivityDto activityDto = new CeActivityDto(q);
+    activityDto.setStatus(CeActivityDto.Status.CANCELED);
+    remove(dbSession, task, q, activityDto);
+  }
+
+  @Override
+  public int clear() {
+    return cancelAll(true);
+  }
+
+  @Override
+  public int cancelAll() {
+    return cancelAll(false);
+  }
+
+  private int cancelAll(boolean includeInProgress) {
+    int count = 0;
+    DbSession dbSession = dbClient.openSession(false);
+    try {
+      for (CeQueueDto queueDto : dbClient.ceQueueDao().selectAllInAscOrder(dbSession)) {
+        if (includeInProgress || !queueDto.getStatus().equals(CeQueueDto.Status.IN_PROGRESS)) {
+          cancel(dbSession, queueDto);
+          count++;
+        }
+      }
+      return count;
+    } finally {
+      dbClient.closeSession(dbSession);
+    }
+  }
+
+  @Override
+  public void remove(CeTask task, CeActivityDto.Status status) {
+    DbSession dbSession = dbClient.openSession(false);
+    try {
+      Optional<CeQueueDto> queueDto = dbClient.ceQueueDao().selectByUuid(dbSession, task.getUuid());
+      if (!queueDto.isPresent()) {
+        throw new IllegalStateException(format("Task does not exist anymore: %s", task));
+      }
+      CeActivityDto activityDto = new CeActivityDto(queueDto.get());
+      activityDto.setStatus(status);
+      updateQueueStatus(status, activityDto);
+      remove(dbSession, task, queueDto.get(), activityDto);
+
+    } finally {
+      dbClient.closeSession(dbSession);
+    }
+  }
+
+  private void updateQueueStatus(CeActivityDto.Status status, CeActivityDto activityDto) {
+    Long startedAt = activityDto.getStartedAt();
+    if (startedAt == null) {
+      return;
+    }
+    activityDto.setFinishedAt(system2.now());
+    long executionTime = activityDto.getFinishedAt() - startedAt;
+    activityDto.setExecutionTimeMs(executionTime);
+    if (status == CeActivityDto.Status.SUCCESS) {
+      queueStatus.addSuccess(executionTime);
+    } else {
+      queueStatus.addError(executionTime);
+    }
+  }
+
+  private void remove(DbSession dbSession, CeTask task, CeQueueDto queueDto, CeActivityDto activityDto) {
+    dbClient.ceActivityDao().insert(dbSession, activityDto);
+    dbClient.ceQueueDao().deleteByUuid(dbSession, queueDto.getUuid());
+    dbSession.commit();
+    for (CeQueueListener listener : listeners) {
+      listener.onRemoved(task, activityDto.getStatus());
+    }
+  }
+
+  @Override
+  public void pauseSubmit() {
+    this.submitPaused.set(true);
+  }
+
+  @Override
+  public void resumeSubmit() {
+    this.submitPaused.set(false);
+  }
+
+  @Override
+  public boolean isSubmitPaused() {
+    return submitPaused.get();
+  }
+
+  @Override
+  public void pausePeek() {
+    this.peekPaused.set(true);
+  }
+
+  @Override
+  public void resumePeek() {
+    this.peekPaused.set(false);
+  }
+
+  @Override
+  public boolean isPeekPaused() {
+    return peekPaused.get();
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeQueueInitializer.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeQueueInitializer.java
new file mode 100644 (file)
index 0000000..526eb16
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue;
+
+import org.picocontainer.Startable;
+import org.sonar.api.server.ServerSide;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.server.computation.monitoring.CEQueueStatus;
+
+/**
+ * Cleans-up the queue, initializes JMX counters then schedule
+ * the execution of workers. That allows to not prevent workers
+ * from peeking the queue before it's ready.
+ */
+@ServerSide
+public class CeQueueInitializer implements Startable {
+
+  private final DbClient dbClient;
+  private final CEQueueStatus queueStatus;
+  private final CeQueueCleaner cleaner;
+  private final CeProcessingScheduler scheduler;
+
+  public CeQueueInitializer(DbClient dbClient, CEQueueStatus queueStatus, CeQueueCleaner cleaner, CeProcessingScheduler scheduler) {
+    this.dbClient = dbClient;
+    this.queueStatus = queueStatus;
+    this.cleaner = cleaner;
+    this.scheduler = scheduler;
+  }
+
+  @Override
+  public void start() {
+    DbSession dbSession = dbClient.openSession(false);
+    try {
+      initJmxCounters(dbSession);
+      cleaner.clean(dbSession);
+      scheduler.startScheduling();
+
+    } finally {
+      dbClient.closeSession(dbSession);
+    }
+  }
+
+  @Override
+  public void stop() {
+    // nothing to do
+  }
+
+  private void initJmxCounters(DbSession dbSession) {
+    queueStatus.initPendingCount(dbClient.ceQueueDao().countAll(dbSession));
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeQueueListener.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeQueueListener.java
new file mode 100644 (file)
index 0000000..938c4d1
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue;
+
+import org.sonar.db.ce.CeActivityDto;
+
+public interface CeQueueListener {
+
+  void onRemoved(CeTask task, CeActivityDto.Status status);
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeTask.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeTask.java
new file mode 100644 (file)
index 0000000..7867c83
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue;
+
+import com.google.common.base.Objects;
+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 type;
+  private final String uuid;
+  private final String componentUuid;
+  private final String componentKey;
+  private final String componentName;
+  private final String submitterLogin;
+
+  private CeTask(Builder builder) {
+    this.uuid = requireNonNull(emptyToNull(builder.uuid));
+    this.type = requireNonNull(emptyToNull(builder.type));
+    this.componentUuid = emptyToNull(builder.componentUuid);
+    this.componentKey = emptyToNull(builder.componentKey);
+    this.componentName = emptyToNull(builder.componentName);
+    this.submitterLogin = emptyToNull(builder.submitterLogin);
+  }
+
+  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 getSubmitterLogin() {
+    return submitterLogin;
+  }
+
+  @Override
+  public String toString() {
+    return Objects.toStringHelper(this)
+      .add("componentUuid", componentUuid)
+      .add("uuid", uuid)
+      .add("type", type)
+      .add("submitterLogin", submitterLogin)
+      .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 uuid;
+    private String type;
+    private String componentUuid;
+    private String componentKey;
+    private String componentName;
+    private String submitterLogin;
+
+    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 setSubmitterLogin(@Nullable String s) {
+      this.submitterLogin = s;
+      return this;
+    }
+
+    public CeTask build() {
+      return new CeTask(this);
+    }
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeTaskSubmit.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeTaskSubmit.java
new file mode 100644 (file)
index 0000000..affa52f
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue;
+
+import java.util.Objects;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+
+import static com.google.common.base.Strings.emptyToNull;
+
+@Immutable
+public final class CeTaskSubmit {
+
+  private final String uuid;
+  private final String type;
+  private final String componentUuid;
+  private final String submitterLogin;
+
+  private CeTaskSubmit(Builder builder) {
+    this.uuid = Objects.requireNonNull(emptyToNull(builder.uuid));
+    this.type = Objects.requireNonNull(emptyToNull(builder.type));
+    this.componentUuid = emptyToNull(builder.componentUuid);
+    this.submitterLogin = emptyToNull(builder.submitterLogin);
+  }
+
+  public String getType() {
+    return type;
+  }
+
+  public String getUuid() {
+    return uuid;
+  }
+
+  @CheckForNull
+  public String getComponentUuid() {
+    return componentUuid;
+  }
+
+  @CheckForNull
+  public String getSubmitterLogin() {
+    return submitterLogin;
+  }
+
+  public static final class Builder {
+    private final String uuid;
+    private String type;
+    private String componentUuid;
+    private String submitterLogin;
+
+    public Builder(String uuid) {
+      this.uuid = uuid;
+    }
+
+    public String getUuid() {
+      return uuid;
+    }
+
+    public Builder setType(String s) {
+      this.type = s;
+      return this;
+    }
+
+    public Builder setComponentUuid(@Nullable String s) {
+      this.componentUuid = s;
+      return this;
+    }
+
+    public Builder setSubmitterLogin(@Nullable String s) {
+      this.submitterLogin = s;
+      return this;
+    }
+
+    public CeTaskSubmit build() {
+      return new CeTaskSubmit(this);
+    }
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeWorkerRunnable.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/CeWorkerRunnable.java
new file mode 100644 (file)
index 0000000..20cebe7
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.computation.queue;
+
+import com.google.common.base.Optional;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.core.util.logs.Profiler;
+import org.sonar.db.ce.CeActivityDto;
+import org.sonar.server.computation.log.CeLogging;
+import org.sonar.server.computation.queue.report.ReportTaskProcessor;
+
+import static java.lang.String.format;
+
+class CeWorkerRunnable implements Runnable {
+
+  private static final Logger LOG = Loggers.get(CeWorkerRunnable.class);
+
+  private final CeQueue queue;
+  private final ReportTaskProcessor reportTaskProcessor;
+  private final CeLogging ceLogging;
+
+  public CeWorkerRunnable(CeQueue queue, ReportTaskProcessor reportTaskProcessor, CeLogging ceLogging) {
+    this.queue = queue;
+    this.reportTaskProcessor = reportTaskProcessor;
+    this.ceLogging = ceLogging;
+  }
+
+  @Override
+  public void run() {
+    Optional<CeTask> ceTask = tryAndFindTaskToExecute();
+    if (!ceTask.isPresent()) {
+      return;
+    }
+
+    executeTask(ceTask.get());
+  }
+
+  private Optional<CeTask> tryAndFindTaskToExecute() {
+    try {
+      return queue.peek();
+    } catch (Exception e) {
+      LOG.error("Failed to pop the queue of analysis reports", e);
+    }
+    return Optional.absent();
+  }
+
+  private void executeTask(CeTask task) {
+    ceLogging.initForTask(task);
+    Profiler profiler = Profiler.create(LOG).startInfo(format("Analysis of project %s (report %s)", task.getComponentKey(), task.getUuid()));
+    try {
+      // TODO delegate the message to the related task processor, according to task type
+      reportTaskProcessor.process(task);
+      queue.remove(task, CeActivityDto.Status.SUCCESS);
+    } catch (Throwable e) {
+      LOG.error(format("Failed to process task %s", task.getUuid()), e);
+      queue.remove(task, CeActivityDto.Status.FAILED);
+    } finally {
+      profiler.stopInfo(String.format("Total thread execution of project %s (report %s)", task.getComponentUuid(), task.getUuid()));
+      ceLogging.clearForTask();
+    }
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/package-info.java
new file mode 100644 (file)
index 0000000..e94d884
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonar.server.computation.queue;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/report/CleanReportQueueListener.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/report/CleanReportQueueListener.java
new file mode 100644 (file)
index 0000000..7a0b38c
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue.report;
+
+import org.sonar.db.ce.CeActivityDto;
+import org.sonar.server.computation.ReportFiles;
+import org.sonar.server.computation.queue.CeQueueListener;
+import org.sonar.server.computation.queue.CeTask;
+
+public class CleanReportQueueListener implements CeQueueListener {
+
+  private final ReportFiles reportFiles;
+
+  public CleanReportQueueListener(ReportFiles reportFiles) {
+    this.reportFiles = reportFiles;
+  }
+
+  @Override
+  public void onRemoved(CeTask task, CeActivityDto.Status status) {
+    reportFiles.deleteIfExists(task.getUuid());
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/report/ReportSubmitter.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/report/ReportSubmitter.java
new file mode 100644 (file)
index 0000000..f8489f6
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue.report;
+
+import java.io.InputStream;
+import javax.annotation.Nullable;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.server.ServerSide;
+import org.sonar.core.component.ComponentKeys;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.db.ce.CeTaskTypes;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.server.component.ComponentService;
+import org.sonar.server.component.NewComponent;
+import org.sonar.server.computation.ReportFiles;
+import org.sonar.server.computation.queue.CeQueue;
+import org.sonar.server.computation.queue.CeTask;
+import org.sonar.server.computation.queue.CeTaskSubmit;
+import org.sonar.server.permission.PermissionService;
+import org.sonar.server.user.UserSession;
+
+@ServerSide
+public class ReportSubmitter {
+
+  private final CeQueue queue;
+  private final UserSession userSession;
+  private final ReportFiles reportFiles;
+  private final ComponentService componentService;
+  private final PermissionService permissionService;
+
+  public ReportSubmitter(CeQueue queue, UserSession userSession, ReportFiles reportFiles,
+    ComponentService componentService, PermissionService permissionService) {
+    this.queue = queue;
+    this.userSession = userSession;
+    this.reportFiles = reportFiles;
+    this.componentService = componentService;
+    this.permissionService = permissionService;
+  }
+
+  public CeTask submit(String projectKey, @Nullable String projectBranch, @Nullable String projectName, InputStream reportInput) {
+    userSession.checkGlobalPermission(GlobalPermissions.SCAN_EXECUTION);
+
+    String effectiveProjectKey = ComponentKeys.createKey(projectKey, projectBranch);
+    ComponentDto project = componentService.getNullableByKey(effectiveProjectKey);
+    if (project == null) {
+      // the project does not exist -> requires to provision it
+      NewComponent newProject = new NewComponent(projectKey, StringUtils.defaultIfBlank(projectName, projectKey));
+      newProject.setBranch(projectBranch);
+      newProject.setQualifier(Qualifiers.PROJECT);
+      // no need to verify the permission "provisioning" as it's already handled by componentService
+      project = componentService.create(newProject);
+      permissionService.applyDefaultPermissionTemplate(project.getKey());
+    }
+
+    // the report file must be saved before submitting the task
+    CeTaskSubmit.Builder submit = queue.prepareSubmit();
+    reportFiles.save(submit.getUuid(), reportInput);
+
+    submit.setType(CeTaskTypes.REPORT);
+    submit.setComponentUuid(project.uuid());
+    submit.setSubmitterLogin(userSession.getLogin());
+    return queue.submit(submit.build());
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/report/ReportTaskProcessor.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/report/ReportTaskProcessor.java
new file mode 100644 (file)
index 0000000..21b64ed
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue.report;
+
+import org.sonar.core.platform.ComponentContainer;
+import org.sonar.server.computation.ComputationStepExecutor;
+import org.sonar.server.computation.container.ComputeEngineContainer;
+import org.sonar.server.computation.container.ContainerFactory;
+import org.sonar.server.computation.queue.CeTask;
+
+public class ReportTaskProcessor {
+
+  private final ContainerFactory containerFactory;
+  private final ComponentContainer serverContainer;
+
+  public ReportTaskProcessor(ContainerFactory containerFactory, ComponentContainer serverContainer) {
+    this.containerFactory = containerFactory;
+    this.serverContainer = serverContainer;
+  }
+
+  public void process(CeTask task) {
+    ComputeEngineContainer ceContainer = containerFactory.create(serverContainer, task);
+    try {
+      ceContainer.getComponentByType(ComputationStepExecutor.class).execute();
+    } finally {
+      ceContainer.cleanup();
+    }
+  }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/queue/report/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/computation/queue/report/package-info.java
new file mode 100644 (file)
index 0000000..bda36b5
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonar.server.computation.queue.report;
+
+import javax.annotation.ParametersAreNonnullByDefault;
index d7065e4cac74818a43a5a888b5266d65c2fee16f..878ee5aeaa53b62ebf330d54267e6be26c490b1e 100644 (file)
@@ -26,12 +26,12 @@ import org.sonar.api.utils.TempFolder;
 import org.sonar.api.utils.ZipUtils;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
-import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.queue.CeTask;
 import org.sonar.server.computation.ReportFiles;
 import org.sonar.server.computation.batch.MutableBatchReportDirectoryHolder;
 
 /**
- * Extracts the content zip file of the {@link org.sonar.server.computation.CeTask} to a temp directory and adds a {@link File}
+ * Extracts the content zip file of the {@link CeTask} to a temp directory and adds a {@link File}
  * representing that temp directory to the {@link MutableBatchReportDirectoryHolder}.
  */
 public class ExtractReportStep implements ComputationStep {
index eb2df43f1085a94d3464bd4bc6de6491ee66984c..23150d2ba0f434280e69cc383d7f06a0d65b2fb7 100644 (file)
@@ -23,7 +23,7 @@ import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.web.UserRole;
-import org.sonar.server.computation.CeQueue;
+import org.sonar.server.computation.queue.CeQueue;
 import org.sonar.server.user.UserSession;
 
 public class CancelAllWsAction implements CeWsAction {
index 22f380069fa4ecf3b0b85ba6f418c1b45846fbd6..3b39b2a7e85c7fe3529802cc1e4ba0a0857a6168 100644 (file)
@@ -24,7 +24,7 @@ import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.web.UserRole;
 import org.sonar.core.util.Uuids;
-import org.sonar.server.computation.CeQueue;
+import org.sonar.server.computation.queue.CeQueue;
 import org.sonar.server.user.UserSession;
 
 public class CancelWsAction implements CeWsAction {
index 2ea8ce25027a32cedd315a0ebe9ff1d81703f210..64c1f2daf13b52e8fe226a1dbe35b4e92ff18ad0 100644 (file)
@@ -24,8 +24,8 @@ import org.apache.commons.lang.StringUtils;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
-import org.sonar.server.computation.CeTask;
-import org.sonar.server.computation.ReportSubmitter;
+import org.sonar.server.computation.queue.CeTask;
+import org.sonar.server.computation.queue.report.ReportSubmitter;
 import org.sonar.server.ws.WsUtils;
 import org.sonarqube.ws.WsCe;
 
index 3e7c66f713f28545468358cce4fb03a7e840ba97..efacdd7b99bd917f5071feb33216f26b451f10d5 100644 (file)
@@ -62,13 +62,13 @@ import org.sonar.server.component.DefaultRubyComponentService;
 import org.sonar.server.component.ws.ComponentsWs;
 import org.sonar.server.component.ws.EventsWs;
 import org.sonar.server.component.ws.ResourcesWs;
-import org.sonar.server.computation.CeQueueCleaner;
-import org.sonar.server.computation.CeQueueImpl;
-import org.sonar.server.computation.CeQueueInitializer;
-import org.sonar.server.computation.CleanReportQueueListener;
+import org.sonar.server.computation.queue.CeQueueImpl;
+import org.sonar.server.computation.queue.CeQueueCleaner;
+import org.sonar.server.computation.queue.CeQueueInitializer;
+import org.sonar.server.computation.queue.report.CleanReportQueueListener;
 import org.sonar.server.computation.ComputeEngineProcessingModule;
 import org.sonar.server.computation.ReportFiles;
-import org.sonar.server.computation.ReportSubmitter;
+import org.sonar.server.computation.queue.report.ReportSubmitter;
 import org.sonar.server.computation.dbcleaner.IndexPurgeListener;
 import org.sonar.server.computation.dbcleaner.ProjectCleaner;
 import org.sonar.server.computation.log.CeLogging;
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/CeProcessingSchedulerImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/CeProcessingSchedulerImplTest.java
deleted file mode 100644 (file)
index 50e1763..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import java.util.concurrent.TimeUnit;
-import org.junit.Test;
-import org.sonar.server.computation.log.CeLogging;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-public class CeProcessingSchedulerImplTest {
-  private CeProcessingSchedulerExecutorService processingExecutorService = mock(CeProcessingSchedulerExecutorService.class);
-  private CeQueue ceQueue = mock(CeQueue.class);
-  private ReportTaskProcessor reportTaskProcessor = mock(ReportTaskProcessor.class);
-  private CeLogging ceLogging = mock(CeLogging.class);
-  private CeProcessingSchedulerImpl underTest = new CeProcessingSchedulerImpl(processingExecutorService, ceQueue, reportTaskProcessor, ceLogging);
-
-  @Test
-  public void startScheduling_schedules_CeWorkerRunnable_at_fixed_rate_run_head_of_queue() {
-    underTest.startScheduling();
-
-    verify(processingExecutorService).scheduleAtFixedRate(any(CeWorkerRunnable.class), eq(0L), eq(10L), eq(TimeUnit.SECONDS));
-    verifyNoMoreInteractions(processingExecutorService);
-  }
-
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/CeQueueCleanerTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/CeQueueCleanerTest.java
deleted file mode 100644 (file)
index db5786d..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import java.io.File;
-import java.io.IOException;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.mockito.Mockito;
-import org.sonar.api.platform.ServerUpgradeStatus;
-import org.sonar.api.utils.System2;
-import org.sonar.db.DbSession;
-import org.sonar.db.DbTester;
-import org.sonar.db.ce.CeQueueDto;
-import org.sonar.db.ce.CeTaskTypes;
-
-import static java.util.Arrays.asList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class CeQueueCleanerTest {
-
-  @Rule
-  public DbTester dbTester = DbTester.create(System2.INSTANCE);
-
-  @Rule
-  public TemporaryFolder tempFolder = new TemporaryFolder();
-
-  ServerUpgradeStatus serverUpgradeStatus = mock(ServerUpgradeStatus.class);
-  ReportFiles reportFiles = mock(ReportFiles.class, Mockito.RETURNS_DEEP_STUBS);
-  CeQueueImpl queue = mock(CeQueueImpl.class);
-  CeQueueCleaner underTest = new CeQueueCleaner(dbTester.getDbClient(), serverUpgradeStatus, reportFiles, queue);
-
-  @Test
-  public void reset_in_progress_tasks_to_pending() throws IOException {
-    insertInQueue("TASK_1", CeQueueDto.Status.PENDING);
-    insertInQueue("TASK_2", CeQueueDto.Status.IN_PROGRESS);
-
-    underTest.clean(dbTester.getSession());
-
-    assertThat(dbTester.getDbClient().ceQueueDao().countByStatus(dbTester.getSession(), CeQueueDto.Status.PENDING)).isEqualTo(2);
-    assertThat(dbTester.getDbClient().ceQueueDao().countByStatus(dbTester.getSession(), CeQueueDto.Status.IN_PROGRESS)).isEqualTo(0);
-  }
-
-  @Test
-  public void clear_queue_if_version_upgrade() {
-    when(serverUpgradeStatus.isUpgraded()).thenReturn(true);
-
-    underTest.clean(dbTester.getSession());
-
-    verify(queue).clear();
-  }
-
-  @Test
-  public void cancel_task_if_report_file_is_missing() throws IOException {
-    CeQueueDto task = insertInQueue("TASK_1", CeQueueDto.Status.PENDING, false);
-
-    underTest.clean(dbTester.getSession());
-
-    verify(queue).cancel(any(DbSession.class), eq(task));
-  }
-
-  @Test
-  public void delete_orphan_report_files() throws Exception {
-    // two files on disk but on task in queue
-    insertInQueue("TASK_1", CeQueueDto.Status.PENDING, true);
-    when(reportFiles.listUuids()).thenReturn(asList("TASK_1", "TASK_2"));
-
-    underTest.clean(dbTester.getSession());
-
-    verify(reportFiles).deleteIfExists("TASK_2");
-  }
-
-  private void insertInQueue(String taskUuid, CeQueueDto.Status status) throws IOException {
-    insertInQueue(taskUuid, status, true);
-  }
-
-  private CeQueueDto insertInQueue(String taskUuid, CeQueueDto.Status status, boolean createFile) throws IOException {
-    CeQueueDto queueDto = new CeQueueDto();
-    queueDto.setTaskType(CeTaskTypes.REPORT);
-    queueDto.setComponentUuid("PROJECT_1");
-    queueDto.setUuid(taskUuid);
-    queueDto.setStatus(status);
-    dbTester.getDbClient().ceQueueDao().insert(dbTester.getSession(), queueDto);
-    dbTester.getSession().commit();
-
-    File file = tempFolder.newFile();
-    when(reportFiles.fileForUuid(taskUuid)).thenReturn(file);
-    if (!createFile) {
-      file.delete();
-    }
-    return queueDto;
-  }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/CeQueueImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/CeQueueImplTest.java
deleted file mode 100644 (file)
index 212cc4d..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import com.google.common.base.Optional;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.utils.System2;
-import org.sonar.api.utils.internal.TestSystem2;
-import org.sonar.core.util.UuidFactory;
-import org.sonar.core.util.UuidFactoryImpl;
-import org.sonar.db.DbTester;
-import org.sonar.db.ce.CeActivityDto;
-import org.sonar.db.ce.CeQueueDto;
-import org.sonar.db.ce.CeTaskTypes;
-import org.sonar.server.computation.monitoring.CEQueueStatus;
-import org.sonar.server.computation.monitoring.CEQueueStatusImpl;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.hamcrest.Matchers.startsWith;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-
-public class CeQueueImplTest {
-
-  @Rule
-  public ExpectedException expectedException = ExpectedException.none();
-
-  System2 system2 = new TestSystem2().setNow(1_450_000_000_000L);
-
-  @Rule
-  public DbTester dbTester = DbTester.create(system2);
-
-  UuidFactory uuidFactory = UuidFactoryImpl.INSTANCE;
-  CEQueueStatus queueStatus = new CEQueueStatusImpl();
-  CeQueueListener listener = mock(CeQueueListener.class);
-  CeQueue underTest = new CeQueueImpl(system2, dbTester.getDbClient(), uuidFactory, queueStatus, new CeQueueListener[] {listener});
-
-  @Test
-  public void test_submit() {
-    CeTaskSubmit.Builder submission = underTest.prepareSubmit();
-    submission.setComponentUuid("PROJECT_1");
-    submission.setType(CeTaskTypes.REPORT);
-    submission.setSubmitterLogin("rob");
-
-    CeTask task = underTest.submit(submission.build());
-    assertThat(task.getUuid()).isEqualTo(submission.getUuid());
-    assertThat(task.getComponentUuid()).isEqualTo("PROJECT_1");
-    assertThat(task.getSubmitterLogin()).isEqualTo("rob");
-
-    Optional<CeQueueDto> queueDto = dbTester.getDbClient().ceQueueDao().selectByUuid(dbTester.getSession(), submission.getUuid());
-    assertThat(queueDto.isPresent()).isTrue();
-    assertThat(queueDto.get().getTaskType()).isEqualTo(CeTaskTypes.REPORT);
-    assertThat(queueDto.get().getComponentUuid()).isEqualTo("PROJECT_1");
-    assertThat(queueDto.get().getSubmitterLogin()).isEqualTo("rob");
-    assertThat(queueDto.get().getCreatedAt()).isEqualTo(1_450_000_000_000L);
-    assertThat(queueStatus.getReceivedCount()).isEqualTo(1L);
-  }
-
-  @Test
-  public void fail_to_submit_if_paused() {
-    expectedException.expect(IllegalStateException.class);
-    expectedException.expectMessage("Compute Engine does not currently accept new tasks");
-    underTest.pauseSubmit();
-
-    submit(CeTaskTypes.REPORT, "PROJECT_1");
-  }
-
-  @Test
-  public void test_remove() {
-    CeTask task = submit(CeTaskTypes.REPORT, "PROJECT_1");
-    Optional<CeTask> peek = underTest.peek();
-    underTest.remove(peek.get(), CeActivityDto.Status.SUCCESS);
-
-    // queue is empty
-    assertThat(dbTester.getDbClient().ceQueueDao().selectByUuid(dbTester.getSession(), task.getUuid()).isPresent()).isFalse();
-    assertThat(underTest.peek().isPresent()).isFalse();
-
-    // available in history
-    Optional<CeActivityDto> history = dbTester.getDbClient().ceActivityDao().selectByUuid(dbTester.getSession(), task.getUuid());
-    assertThat(history.isPresent()).isTrue();
-    assertThat(history.get().getStatus()).isEqualTo(CeActivityDto.Status.SUCCESS);
-    assertThat(history.get().getIsLast()).isTrue();
-
-    verify(listener).onRemoved(task, CeActivityDto.Status.SUCCESS);
-  }
-
-  @Test
-  public void fail_to_remove_if_not_in_queue() throws Exception {
-    expectedException.expect(IllegalStateException.class);
-    CeTask task = submit(CeTaskTypes.REPORT, "PROJECT_1");
-    underTest.remove(task, CeActivityDto.Status.SUCCESS);
-
-    // fail
-    underTest.remove(task, CeActivityDto.Status.SUCCESS);
-  }
-
-  @Test
-  public void test_peek() throws Exception {
-    CeTask task = submit(CeTaskTypes.REPORT, "PROJECT_1");
-
-    Optional<CeTask> peek = underTest.peek();
-    assertThat(peek.isPresent()).isTrue();
-    assertThat(peek.get().getUuid()).isEqualTo(task.getUuid());
-    assertThat(peek.get().getType()).isEqualTo(CeTaskTypes.REPORT);
-    assertThat(peek.get().getComponentUuid()).isEqualTo("PROJECT_1");
-
-    // no more pending tasks
-    peek = underTest.peek();
-    assertThat(peek.isPresent()).isFalse();
-
-    verify(listener, never()).onRemoved(eq(task), any(CeActivityDto.Status.class));
-  }
-
-  @Test
-  public void peek_nothing_if_paused() throws Exception {
-    submit(CeTaskTypes.REPORT, "PROJECT_1");
-    underTest.pausePeek();
-
-    Optional<CeTask> peek = underTest.peek();
-    assertThat(peek.isPresent()).isFalse();
-  }
-
-  @Test
-  public void cancel_pending() throws Exception {
-    CeTask task = submit(CeTaskTypes.REPORT, "PROJECT_1");
-
-    // ignore
-    boolean canceled = underTest.cancel("UNKNOWN");
-    assertThat(canceled).isFalse();
-    verifyZeroInteractions(listener);
-
-    canceled = underTest.cancel(task.getUuid());
-    assertThat(canceled).isTrue();
-    Optional<CeActivityDto> activity = dbTester.getDbClient().ceActivityDao().selectByUuid(dbTester.getSession(), task.getUuid());
-    assertThat(activity.isPresent()).isTrue();
-    assertThat(activity.get().getStatus()).isEqualTo(CeActivityDto.Status.CANCELED);
-    verify(listener).onRemoved(task, CeActivityDto.Status.CANCELED);
-  }
-
-  @Test
-  public void fail_to_cancel_if_in_progress() throws Exception {
-    expectedException.expect(IllegalStateException.class);
-    expectedException.expectMessage(startsWith("Task is in progress and can't be canceled"));
-
-    CeTask task = submit(CeTaskTypes.REPORT, "PROJECT_1");
-    underTest.peek();
-
-    underTest.cancel(task.getUuid());
-  }
-
-  @Test
-  public void cancelAll_pendings_but_not_in_progress() throws Exception {
-    CeTask inProgressTask = submit(CeTaskTypes.REPORT, "PROJECT_1");
-    CeTask pendingTask1 = submit(CeTaskTypes.REPORT, "PROJECT_2");
-    CeTask pendingTask2 = submit(CeTaskTypes.REPORT, "PROJECT_3");
-    underTest.peek();
-
-    int canceledCount = underTest.cancelAll();
-    assertThat(canceledCount).isEqualTo(2);
-
-    Optional<CeActivityDto> history = dbTester.getDbClient().ceActivityDao().selectByUuid(dbTester.getSession(), pendingTask1.getUuid());
-    assertThat(history.get().getStatus()).isEqualTo(CeActivityDto.Status.CANCELED);
-    history = dbTester.getDbClient().ceActivityDao().selectByUuid(dbTester.getSession(), pendingTask2.getUuid());
-    assertThat(history.get().getStatus()).isEqualTo(CeActivityDto.Status.CANCELED);
-    history = dbTester.getDbClient().ceActivityDao().selectByUuid(dbTester.getSession(), inProgressTask.getUuid());
-    assertThat(history.isPresent()).isFalse();
-
-    verify(listener).onRemoved(pendingTask1, CeActivityDto.Status.CANCELED);
-    verify(listener).onRemoved(pendingTask2, CeActivityDto.Status.CANCELED);
-  }
-
-  @Test
-  public void pause_and_resume_submits() throws Exception {
-    assertThat(underTest.isSubmitPaused()).isFalse();
-    underTest.pauseSubmit();
-    assertThat(underTest.isSubmitPaused()).isTrue();
-    underTest.resumeSubmit();
-    assertThat(underTest.isSubmitPaused()).isFalse();
-  }
-
-  @Test
-  public void pause_and_resume_peeks() throws Exception {
-    assertThat(underTest.isPeekPaused()).isFalse();
-    underTest.pausePeek();
-    assertThat(underTest.isPeekPaused()).isTrue();
-    underTest.resumePeek();
-    assertThat(underTest.isPeekPaused()).isFalse();
-  }
-
-  private CeTask submit(String reportType, String componentUuid) {
-    CeTaskSubmit.Builder submission = underTest.prepareSubmit();
-    submission.setType(reportType);
-    submission.setComponentUuid(componentUuid);
-    return underTest.submit(submission.build());
-  }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/CeQueueInitializerTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/CeQueueInitializerTest.java
deleted file mode 100644 (file)
index 37ffc3a..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import java.io.File;
-import java.io.IOException;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-import org.mockito.InOrder;
-import org.mockito.Mockito;
-import org.sonar.api.utils.System2;
-import org.sonar.db.DbSession;
-import org.sonar.db.DbTester;
-import org.sonar.db.ce.CeQueueDto;
-import org.sonar.db.ce.CeTaskTypes;
-import org.sonar.server.computation.monitoring.CEQueueStatus;
-import org.sonar.server.computation.monitoring.CEQueueStatusImpl;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class CeQueueInitializerTest {
-
-  @Rule
-  public DbTester dbTester = DbTester.create(System2.INSTANCE);
-
-  @Rule
-  public TemporaryFolder tempFolder = new TemporaryFolder();
-
-  ReportFiles reportFiles = mock(ReportFiles.class, Mockito.RETURNS_DEEP_STUBS);
-  CEQueueStatus queueStatus = new CEQueueStatusImpl();
-  CeQueueCleaner cleaner = mock(CeQueueCleaner.class);
-  CeProcessingScheduler scheduler = mock(CeProcessingScheduler.class);
-  CeQueueInitializer underTest = new CeQueueInitializer(dbTester.getDbClient(), queueStatus, cleaner, scheduler);
-
-  @Test
-  public void init_jmx_counters() throws IOException {
-    insertInQueue("TASK_1", CeQueueDto.Status.PENDING);
-    insertInQueue("TASK_2", CeQueueDto.Status.PENDING);
-    // this in-progress task is going to be moved to PENDING
-    insertInQueue("TASK_3", CeQueueDto.Status.IN_PROGRESS);
-
-    underTest.start();
-
-    assertThat(queueStatus.getPendingCount()).isEqualTo(3);
-  }
-
-  @Test
-  public void init_jmx_counters_when_queue_is_empty() {
-    underTest.start();
-
-    assertThat(queueStatus.getPendingCount()).isEqualTo(0);
-  }
-
-  @Test
-  public void clean_queue_then_start_scheduler_of_workers() throws IOException {
-    InOrder inOrder = Mockito.inOrder(cleaner, scheduler);
-
-    underTest.start();
-
-    inOrder.verify(cleaner).clean(any(DbSession.class));
-    inOrder.verify(scheduler).startScheduling();
-  }
-
-  private void insertInQueue(String taskUuid, CeQueueDto.Status status) throws IOException {
-    insertInQueue(taskUuid, status, true);
-  }
-
-  private CeQueueDto insertInQueue(String taskUuid, CeQueueDto.Status status, boolean createFile) throws IOException {
-    CeQueueDto queueDto = new CeQueueDto();
-    queueDto.setTaskType(CeTaskTypes.REPORT);
-    queueDto.setComponentUuid("PROJECT_1");
-    queueDto.setUuid(taskUuid);
-    queueDto.setStatus(status);
-    dbTester.getDbClient().ceQueueDao().insert(dbTester.getSession(), queueDto);
-    dbTester.getSession().commit();
-
-    File file = tempFolder.newFile();
-    when(reportFiles.fileForUuid(taskUuid)).thenReturn(file);
-    if (!createFile) {
-      file.delete();
-    }
-    return queueDto;
-  }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/CeTaskTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/CeTaskTest.java
deleted file mode 100644 (file)
index b950ca7..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import org.junit.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class CeTaskTest {
-
-  @Test
-  public void build() {
-    CeTask.Builder builder = new CeTask.Builder();
-    builder.setType("TYPE_1");
-    builder.setUuid("UUID_1");
-    builder.setSubmitterLogin("LOGIN_1");
-    builder.setComponentKey("COMPONENT_KEY_1");
-    builder.setComponentUuid("COMPONENT_UUID_1");
-    builder.setComponentName("The component");
-    CeTask task = builder.build();
-
-    assertThat(task.getType()).isEqualTo("TYPE_1");
-    assertThat(task.getUuid()).isEqualTo("UUID_1");
-    assertThat(task.getSubmitterLogin()).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 equals_and_hashCode_on_uuid() {
-    CeTask.Builder builder1 = new CeTask.Builder().setType("TYPE_1").setUuid("UUID_1");
-    CeTask task1 = builder1.build();
-    CeTask task1bis = builder1.build();
-    CeTask task2 = new CeTask.Builder().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());
-  }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/CeWorkerRunnableTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/CeWorkerRunnableTest.java
deleted file mode 100644 (file)
index 89dc70c..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import com.google.common.base.Optional;
-import org.junit.Test;
-import org.mockito.InOrder;
-import org.mockito.Mockito;
-import org.sonar.db.ce.CeActivityDto;
-import org.sonar.db.ce.CeTaskTypes;
-import org.sonar.server.computation.log.CeLogging;
-
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-public class CeWorkerRunnableTest {
-
-  CeQueue queue = mock(CeQueueImpl.class);
-  ReportTaskProcessor taskProcessor = mock(ReportTaskProcessor.class);
-  CeLogging ceLogging = mock(CeLogging.class);
-  CeWorkerRunnable underTest = new CeWorkerRunnable(queue, taskProcessor, ceLogging);
-
-  @Test
-  public void no_pending_tasks_in_queue() throws Exception {
-    when(queue.peek()).thenReturn(Optional.<CeTask>absent());
-
-    underTest.run();
-
-    verifyZeroInteractions(taskProcessor, ceLogging);
-  }
-
-  @Test
-  public void peek_and_process_task() throws Exception {
-    CeTask task = new CeTask.Builder().setUuid("TASK_1").setType(CeTaskTypes.REPORT).setComponentUuid("PROJECT_1").setSubmitterLogin(null).build();
-    when(queue.peek()).thenReturn(Optional.of(task));
-
-    underTest.run();
-
-    InOrder inOrder = Mockito.inOrder(ceLogging, taskProcessor, queue);
-    inOrder.verify(ceLogging).initForTask(task);
-    inOrder.verify(taskProcessor).process(task);
-    inOrder.verify(queue).remove(task, CeActivityDto.Status.SUCCESS);
-    inOrder.verify(ceLogging).clearForTask();
-  }
-
-  @Test
-  public void fail_to_process_task() throws Exception {
-    CeTask task = new CeTask.Builder().setUuid("TASK_1").setType(CeTaskTypes.REPORT).setComponentUuid("PROJECT_1").setSubmitterLogin(null).build();
-    when(queue.peek()).thenReturn(Optional.of(task));
-    doThrow(new IllegalStateException()).when(taskProcessor).process(task);
-
-    underTest.run();
-
-    InOrder inOrder = Mockito.inOrder(ceLogging, taskProcessor, queue);
-    inOrder.verify(ceLogging).initForTask(task);
-    inOrder.verify(taskProcessor).process(task);
-    inOrder.verify(queue).remove(task, CeActivityDto.Status.FAILED);
-    inOrder.verify(ceLogging).clearForTask();
-  }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/CleanReportQueueListenerTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/CleanReportQueueListenerTest.java
deleted file mode 100644 (file)
index f87f16e..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import org.junit.Test;
-import org.sonar.db.ce.CeActivityDto;
-import org.sonar.db.ce.CeTaskTypes;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-public class CleanReportQueueListenerTest {
-
-  ReportFiles reportFiles = mock(ReportFiles.class);
-  CleanReportQueueListener underTest = new CleanReportQueueListener(reportFiles);
-
-  @Test
-  public void remove_report_file_if_success() {
-    CeTask task = new CeTask.Builder().setUuid("TASK_1").setType(CeTaskTypes.REPORT).setComponentUuid("PROJECT_1").setSubmitterLogin(null).build();
-
-    underTest.onRemoved(task, CeActivityDto.Status.SUCCESS);
-    verify(reportFiles).deleteIfExists("TASK_1");
-  }
-
-  @Test
-  public void remove_report_file_if_failure() {
-    CeTask task = new CeTask.Builder().setUuid("TASK_1").setType(CeTaskTypes.REPORT).setComponentUuid("PROJECT_1").setSubmitterLogin(null).build();
-
-    underTest.onRemoved(task, CeActivityDto.Status.FAILED);
-    verify(reportFiles).deleteIfExists("TASK_1");
-  }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/ReportSubmitterTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ReportSubmitterTest.java
deleted file mode 100644 (file)
index 6abbf2a..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.computation;
-
-import org.apache.commons.io.IOUtils;
-import org.hamcrest.Description;
-import org.hamcrest.TypeSafeMatcher;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.db.ce.CeTaskTypes;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.server.component.ComponentService;
-import org.sonar.server.component.NewComponent;
-import org.sonar.server.permission.PermissionService;
-import org.sonar.server.tester.UserSessionRule;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
-
-public class ReportSubmitterTest {
-
-  @Rule
-  public UserSessionRule userSession = UserSessionRule.standalone();
-
-  CeQueue queue = mock(CeQueueImpl.class);
-  ReportFiles reportFiles = mock(ReportFiles.class);
-  ComponentService componentService = mock(ComponentService.class);
-  PermissionService permissionService = mock(PermissionService.class);
-  ReportSubmitter underTest = new ReportSubmitter(queue, userSession, reportFiles, componentService, permissionService);
-
-  @Test
-  public void submit_a_report_on_existing_project() {
-    when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder("TASK_1"));
-    userSession.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
-    when(componentService.getNullableByKey("MY_PROJECT")).thenReturn(new ComponentDto().setUuid("P1"));
-
-    underTest.submit("MY_PROJECT", null, "My Project", IOUtils.toInputStream("{binary}"));
-
-    verifyZeroInteractions(permissionService);
-    verify(queue).submit(argThat(new TypeSafeMatcher<CeTaskSubmit>() {
-      @Override
-      protected boolean matchesSafely(CeTaskSubmit submit) {
-        return submit.getType().equals(CeTaskTypes.REPORT) && submit.getComponentUuid().equals("P1") &&
-          submit.getUuid().equals("TASK_1");
-      }
-
-      @Override
-      public void describeTo(Description description) {
-
-      }
-    }));
-  }
-
-  @Test
-  public void provision_project_if_does_not_exist() throws Exception {
-    when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder("TASK_1"));
-    userSession.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.PROVISIONING);
-    when(componentService.getNullableByKey("MY_PROJECT")).thenReturn(null);
-    when(componentService.create(any(NewComponent.class))).thenReturn(new ComponentDto().setUuid("P1").setKey("MY_PROJECT"));
-
-    underTest.submit("MY_PROJECT", null, "My Project", IOUtils.toInputStream("{binary}"));
-
-    verify(permissionService).applyDefaultPermissionTemplate("MY_PROJECT");
-    verify(queue).submit(argThat(new TypeSafeMatcher<CeTaskSubmit>() {
-      @Override
-      protected boolean matchesSafely(CeTaskSubmit submit) {
-        return submit.getType().equals(CeTaskTypes.REPORT) && submit.getComponentUuid().equals("P1") &&
-          submit.getUuid().equals("TASK_1");
-      }
-
-      @Override
-      public void describeTo(Description description) {
-
-      }
-    }));
-
-  }
-}
index 3d4656b63c1cd30c2a2f77caefdcfc30d9547bfa..9ca4ace9f7c1b8c3de009e829ad08c60df075c83 100644 (file)
@@ -27,7 +27,7 @@ import java.util.List;
 import javax.annotation.Nullable;
 import org.junit.Test;
 import org.sonar.core.platform.ComponentContainer;
-import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.queue.CeTask;
 import org.sonar.server.computation.step.ComputationStep;
 
 import static com.google.common.base.Predicates.notNull;
index 9e6aeca37d1b342b2bb6814f6cc69a54f125d85e..3ef849ba27086772f0e4c0019ef5033951d4a7d0 100644 (file)
@@ -35,7 +35,7 @@ import org.junit.rules.TemporaryFolder;
 import org.slf4j.MDC;
 import org.sonar.api.config.Settings;
 import org.sonar.process.ProcessProperties;
-import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.queue.CeTask;
 
 import static java.lang.String.format;
 import static org.assertj.core.api.Assertions.assertThat;
index bbd2cc07c589ab491540c5b294b9859314e40c52..2320bfc8dc4aa675c7cfad19cf37edd54620cd73 100644 (file)
@@ -20,7 +20,7 @@
 package org.sonar.server.computation.monitoring;
 
 import org.junit.Test;
-import org.sonar.server.computation.CeQueueImpl;
+import org.sonar.server.computation.queue.CeQueueImpl;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.entry;
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/queue/CeProcessingSchedulerImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/queue/CeProcessingSchedulerImplTest.java
new file mode 100644 (file)
index 0000000..2a031bf
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue;
+
+import java.util.concurrent.TimeUnit;
+import org.junit.Test;
+import org.sonar.server.computation.queue.report.ReportTaskProcessor;
+import org.sonar.server.computation.log.CeLogging;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+public class CeProcessingSchedulerImplTest {
+  private CeProcessingSchedulerExecutorService processingExecutorService = mock(CeProcessingSchedulerExecutorService.class);
+  private CeQueue ceQueue = mock(CeQueue.class);
+  private ReportTaskProcessor reportTaskProcessor = mock(ReportTaskProcessor.class);
+  private CeLogging ceLogging = mock(CeLogging.class);
+  private CeProcessingSchedulerImpl underTest = new CeProcessingSchedulerImpl(processingExecutorService, ceQueue, reportTaskProcessor, ceLogging);
+
+  @Test
+  public void startScheduling_schedules_CeWorkerRunnable_at_fixed_rate_run_head_of_queue() {
+    underTest.startScheduling();
+
+    verify(processingExecutorService).scheduleAtFixedRate(any(CeWorkerRunnable.class), eq(0L), eq(10L), eq(TimeUnit.SECONDS));
+    verifyNoMoreInteractions(processingExecutorService);
+  }
+
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/queue/CeQueueCleanerTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/queue/CeQueueCleanerTest.java
new file mode 100644 (file)
index 0000000..2aecacb
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue;
+
+import java.io.File;
+import java.io.IOException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.mockito.Mockito;
+import org.sonar.api.platform.ServerUpgradeStatus;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+import org.sonar.db.ce.CeQueueDto;
+import org.sonar.db.ce.CeTaskTypes;
+import org.sonar.server.computation.ReportFiles;
+import org.sonar.server.computation.queue.CeQueueCleaner;
+import org.sonar.server.computation.queue.CeQueueImpl;
+
+import static java.util.Arrays.asList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class CeQueueCleanerTest {
+
+  @Rule
+  public DbTester dbTester = DbTester.create(System2.INSTANCE);
+
+  @Rule
+  public TemporaryFolder tempFolder = new TemporaryFolder();
+
+  ServerUpgradeStatus serverUpgradeStatus = mock(ServerUpgradeStatus.class);
+  ReportFiles reportFiles = mock(ReportFiles.class, Mockito.RETURNS_DEEP_STUBS);
+  CeQueueImpl queue = mock(CeQueueImpl.class);
+  CeQueueCleaner underTest = new CeQueueCleaner(dbTester.getDbClient(), serverUpgradeStatus, reportFiles, queue);
+
+  @Test
+  public void reset_in_progress_tasks_to_pending() throws IOException {
+    insertInQueue("TASK_1", CeQueueDto.Status.PENDING);
+    insertInQueue("TASK_2", CeQueueDto.Status.IN_PROGRESS);
+
+    underTest.clean(dbTester.getSession());
+
+    assertThat(dbTester.getDbClient().ceQueueDao().countByStatus(dbTester.getSession(), CeQueueDto.Status.PENDING)).isEqualTo(2);
+    assertThat(dbTester.getDbClient().ceQueueDao().countByStatus(dbTester.getSession(), CeQueueDto.Status.IN_PROGRESS)).isEqualTo(0);
+  }
+
+  @Test
+  public void clear_queue_if_version_upgrade() {
+    when(serverUpgradeStatus.isUpgraded()).thenReturn(true);
+
+    underTest.clean(dbTester.getSession());
+
+    verify(queue).clear();
+  }
+
+  @Test
+  public void cancel_task_if_report_file_is_missing() throws IOException {
+    CeQueueDto task = insertInQueue("TASK_1", CeQueueDto.Status.PENDING, false);
+
+    underTest.clean(dbTester.getSession());
+
+    verify(queue).cancel(any(DbSession.class), eq(task));
+  }
+
+  @Test
+  public void delete_orphan_report_files() throws Exception {
+    // two files on disk but on task in queue
+    insertInQueue("TASK_1", CeQueueDto.Status.PENDING, true);
+    when(reportFiles.listUuids()).thenReturn(asList("TASK_1", "TASK_2"));
+
+    underTest.clean(dbTester.getSession());
+
+    verify(reportFiles).deleteIfExists("TASK_2");
+  }
+
+  private void insertInQueue(String taskUuid, CeQueueDto.Status status) throws IOException {
+    insertInQueue(taskUuid, status, true);
+  }
+
+  private CeQueueDto insertInQueue(String taskUuid, CeQueueDto.Status status, boolean createFile) throws IOException {
+    CeQueueDto queueDto = new CeQueueDto();
+    queueDto.setTaskType(CeTaskTypes.REPORT);
+    queueDto.setComponentUuid("PROJECT_1");
+    queueDto.setUuid(taskUuid);
+    queueDto.setStatus(status);
+    dbTester.getDbClient().ceQueueDao().insert(dbTester.getSession(), queueDto);
+    dbTester.getSession().commit();
+
+    File file = tempFolder.newFile();
+    when(reportFiles.fileForUuid(taskUuid)).thenReturn(file);
+    if (!createFile) {
+      file.delete();
+    }
+    return queueDto;
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/queue/CeQueueImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/queue/CeQueueImplTest.java
new file mode 100644 (file)
index 0000000..b2d3fae
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue;
+
+import com.google.common.base.Optional;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.System2;
+import org.sonar.api.utils.internal.TestSystem2;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.core.util.UuidFactoryImpl;
+import org.sonar.db.DbTester;
+import org.sonar.db.ce.CeActivityDto;
+import org.sonar.db.ce.CeQueueDto;
+import org.sonar.db.ce.CeTaskTypes;
+import org.sonar.server.computation.monitoring.CEQueueStatus;
+import org.sonar.server.computation.monitoring.CEQueueStatusImpl;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.Matchers.startsWith;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+public class CeQueueImplTest {
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  System2 system2 = new TestSystem2().setNow(1_450_000_000_000L);
+
+  @Rule
+  public DbTester dbTester = DbTester.create(system2);
+
+  UuidFactory uuidFactory = UuidFactoryImpl.INSTANCE;
+  CEQueueStatus queueStatus = new CEQueueStatusImpl();
+  CeQueueListener listener = mock(CeQueueListener.class);
+  CeQueue underTest = new CeQueueImpl(system2, dbTester.getDbClient(), uuidFactory, queueStatus, new CeQueueListener[] {listener});
+
+  @Test
+  public void test_submit() {
+    CeTaskSubmit.Builder submission = underTest.prepareSubmit();
+    submission.setComponentUuid("PROJECT_1");
+    submission.setType(CeTaskTypes.REPORT);
+    submission.setSubmitterLogin("rob");
+
+    CeTask task = underTest.submit(submission.build());
+    assertThat(task.getUuid()).isEqualTo(submission.getUuid());
+    assertThat(task.getComponentUuid()).isEqualTo("PROJECT_1");
+    assertThat(task.getSubmitterLogin()).isEqualTo("rob");
+
+    Optional<CeQueueDto> queueDto = dbTester.getDbClient().ceQueueDao().selectByUuid(dbTester.getSession(), submission.getUuid());
+    assertThat(queueDto.isPresent()).isTrue();
+    assertThat(queueDto.get().getTaskType()).isEqualTo(CeTaskTypes.REPORT);
+    assertThat(queueDto.get().getComponentUuid()).isEqualTo("PROJECT_1");
+    assertThat(queueDto.get().getSubmitterLogin()).isEqualTo("rob");
+    assertThat(queueDto.get().getCreatedAt()).isEqualTo(1_450_000_000_000L);
+    assertThat(queueStatus.getReceivedCount()).isEqualTo(1L);
+  }
+
+  @Test
+  public void fail_to_submit_if_paused() {
+    expectedException.expect(IllegalStateException.class);
+    expectedException.expectMessage("Compute Engine does not currently accept new tasks");
+    underTest.pauseSubmit();
+
+    submit(CeTaskTypes.REPORT, "PROJECT_1");
+  }
+
+  @Test
+  public void test_remove() {
+    CeTask task = submit(CeTaskTypes.REPORT, "PROJECT_1");
+    Optional<CeTask> peek = underTest.peek();
+    underTest.remove(peek.get(), CeActivityDto.Status.SUCCESS);
+
+    // queue is empty
+    assertThat(dbTester.getDbClient().ceQueueDao().selectByUuid(dbTester.getSession(), task.getUuid()).isPresent()).isFalse();
+    assertThat(underTest.peek().isPresent()).isFalse();
+
+    // available in history
+    Optional<CeActivityDto> history = dbTester.getDbClient().ceActivityDao().selectByUuid(dbTester.getSession(), task.getUuid());
+    assertThat(history.isPresent()).isTrue();
+    assertThat(history.get().getStatus()).isEqualTo(CeActivityDto.Status.SUCCESS);
+    assertThat(history.get().getIsLast()).isTrue();
+
+    verify(listener).onRemoved(task, CeActivityDto.Status.SUCCESS);
+  }
+
+  @Test
+  public void fail_to_remove_if_not_in_queue() throws Exception {
+    expectedException.expect(IllegalStateException.class);
+    CeTask task = submit(CeTaskTypes.REPORT, "PROJECT_1");
+    underTest.remove(task, CeActivityDto.Status.SUCCESS);
+
+    // fail
+    underTest.remove(task, CeActivityDto.Status.SUCCESS);
+  }
+
+  @Test
+  public void test_peek() throws Exception {
+    CeTask task = submit(CeTaskTypes.REPORT, "PROJECT_1");
+
+    Optional<CeTask> peek = underTest.peek();
+    assertThat(peek.isPresent()).isTrue();
+    assertThat(peek.get().getUuid()).isEqualTo(task.getUuid());
+    assertThat(peek.get().getType()).isEqualTo(CeTaskTypes.REPORT);
+    assertThat(peek.get().getComponentUuid()).isEqualTo("PROJECT_1");
+
+    // no more pending tasks
+    peek = underTest.peek();
+    assertThat(peek.isPresent()).isFalse();
+
+    verify(listener, never()).onRemoved(eq(task), any(CeActivityDto.Status.class));
+  }
+
+  @Test
+  public void peek_nothing_if_paused() throws Exception {
+    submit(CeTaskTypes.REPORT, "PROJECT_1");
+    underTest.pausePeek();
+
+    Optional<CeTask> peek = underTest.peek();
+    assertThat(peek.isPresent()).isFalse();
+  }
+
+  @Test
+  public void cancel_pending() throws Exception {
+    CeTask task = submit(CeTaskTypes.REPORT, "PROJECT_1");
+
+    // ignore
+    boolean canceled = underTest.cancel("UNKNOWN");
+    assertThat(canceled).isFalse();
+    verifyZeroInteractions(listener);
+
+    canceled = underTest.cancel(task.getUuid());
+    assertThat(canceled).isTrue();
+    Optional<CeActivityDto> activity = dbTester.getDbClient().ceActivityDao().selectByUuid(dbTester.getSession(), task.getUuid());
+    assertThat(activity.isPresent()).isTrue();
+    assertThat(activity.get().getStatus()).isEqualTo(CeActivityDto.Status.CANCELED);
+    verify(listener).onRemoved(task, CeActivityDto.Status.CANCELED);
+  }
+
+  @Test
+  public void fail_to_cancel_if_in_progress() throws Exception {
+    expectedException.expect(IllegalStateException.class);
+    expectedException.expectMessage(startsWith("Task is in progress and can't be canceled"));
+
+    CeTask task = submit(CeTaskTypes.REPORT, "PROJECT_1");
+    underTest.peek();
+
+    underTest.cancel(task.getUuid());
+  }
+
+  @Test
+  public void cancelAll_pendings_but_not_in_progress() throws Exception {
+    CeTask inProgressTask = submit(CeTaskTypes.REPORT, "PROJECT_1");
+    CeTask pendingTask1 = submit(CeTaskTypes.REPORT, "PROJECT_2");
+    CeTask pendingTask2 = submit(CeTaskTypes.REPORT, "PROJECT_3");
+    underTest.peek();
+
+    int canceledCount = underTest.cancelAll();
+    assertThat(canceledCount).isEqualTo(2);
+
+    Optional<CeActivityDto> history = dbTester.getDbClient().ceActivityDao().selectByUuid(dbTester.getSession(), pendingTask1.getUuid());
+    assertThat(history.get().getStatus()).isEqualTo(CeActivityDto.Status.CANCELED);
+    history = dbTester.getDbClient().ceActivityDao().selectByUuid(dbTester.getSession(), pendingTask2.getUuid());
+    assertThat(history.get().getStatus()).isEqualTo(CeActivityDto.Status.CANCELED);
+    history = dbTester.getDbClient().ceActivityDao().selectByUuid(dbTester.getSession(), inProgressTask.getUuid());
+    assertThat(history.isPresent()).isFalse();
+
+    verify(listener).onRemoved(pendingTask1, CeActivityDto.Status.CANCELED);
+    verify(listener).onRemoved(pendingTask2, CeActivityDto.Status.CANCELED);
+  }
+
+  @Test
+  public void pause_and_resume_submits() throws Exception {
+    assertThat(underTest.isSubmitPaused()).isFalse();
+    underTest.pauseSubmit();
+    assertThat(underTest.isSubmitPaused()).isTrue();
+    underTest.resumeSubmit();
+    assertThat(underTest.isSubmitPaused()).isFalse();
+  }
+
+  @Test
+  public void pause_and_resume_peeks() throws Exception {
+    assertThat(underTest.isPeekPaused()).isFalse();
+    underTest.pausePeek();
+    assertThat(underTest.isPeekPaused()).isTrue();
+    underTest.resumePeek();
+    assertThat(underTest.isPeekPaused()).isFalse();
+  }
+
+  private CeTask submit(String reportType, String componentUuid) {
+    CeTaskSubmit.Builder submission = underTest.prepareSubmit();
+    submission.setType(reportType);
+    submission.setComponentUuid(componentUuid);
+    return underTest.submit(submission.build());
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/queue/CeQueueInitializerTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/queue/CeQueueInitializerTest.java
new file mode 100644 (file)
index 0000000..79c3070
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue;
+
+import java.io.File;
+import java.io.IOException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.mockito.InOrder;
+import org.mockito.Mockito;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+import org.sonar.db.ce.CeQueueDto;
+import org.sonar.db.ce.CeTaskTypes;
+import org.sonar.server.computation.ReportFiles;
+import org.sonar.server.computation.monitoring.CEQueueStatus;
+import org.sonar.server.computation.monitoring.CEQueueStatusImpl;
+import org.sonar.server.computation.queue.CeProcessingScheduler;
+import org.sonar.server.computation.queue.CeQueueCleaner;
+import org.sonar.server.computation.queue.CeQueueInitializer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class CeQueueInitializerTest {
+
+  @Rule
+  public DbTester dbTester = DbTester.create(System2.INSTANCE);
+
+  @Rule
+  public TemporaryFolder tempFolder = new TemporaryFolder();
+
+  ReportFiles reportFiles = mock(ReportFiles.class, Mockito.RETURNS_DEEP_STUBS);
+  CEQueueStatus queueStatus = new CEQueueStatusImpl();
+  CeQueueCleaner cleaner = mock(CeQueueCleaner.class);
+  CeProcessingScheduler scheduler = mock(CeProcessingScheduler.class);
+  CeQueueInitializer underTest = new CeQueueInitializer(dbTester.getDbClient(), queueStatus, cleaner, scheduler);
+
+  @Test
+  public void init_jmx_counters() throws IOException {
+    insertInQueue("TASK_1", CeQueueDto.Status.PENDING);
+    insertInQueue("TASK_2", CeQueueDto.Status.PENDING);
+    // this in-progress task is going to be moved to PENDING
+    insertInQueue("TASK_3", CeQueueDto.Status.IN_PROGRESS);
+
+    underTest.start();
+
+    assertThat(queueStatus.getPendingCount()).isEqualTo(3);
+  }
+
+  @Test
+  public void init_jmx_counters_when_queue_is_empty() {
+    underTest.start();
+
+    assertThat(queueStatus.getPendingCount()).isEqualTo(0);
+  }
+
+  @Test
+  public void clean_queue_then_start_scheduler_of_workers() throws IOException {
+    InOrder inOrder = Mockito.inOrder(cleaner, scheduler);
+
+    underTest.start();
+
+    inOrder.verify(cleaner).clean(any(DbSession.class));
+    inOrder.verify(scheduler).startScheduling();
+  }
+
+  private void insertInQueue(String taskUuid, CeQueueDto.Status status) throws IOException {
+    insertInQueue(taskUuid, status, true);
+  }
+
+  private CeQueueDto insertInQueue(String taskUuid, CeQueueDto.Status status, boolean createFile) throws IOException {
+    CeQueueDto queueDto = new CeQueueDto();
+    queueDto.setTaskType(CeTaskTypes.REPORT);
+    queueDto.setComponentUuid("PROJECT_1");
+    queueDto.setUuid(taskUuid);
+    queueDto.setStatus(status);
+    dbTester.getDbClient().ceQueueDao().insert(dbTester.getSession(), queueDto);
+    dbTester.getSession().commit();
+
+    File file = tempFolder.newFile();
+    when(reportFiles.fileForUuid(taskUuid)).thenReturn(file);
+    if (!createFile) {
+      file.delete();
+    }
+    return queueDto;
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/queue/CeTaskTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/queue/CeTaskTest.java
new file mode 100644 (file)
index 0000000..85fb27d
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class CeTaskTest {
+
+  @Test
+  public void build() {
+    CeTask.Builder builder = new CeTask.Builder();
+    builder.setType("TYPE_1");
+    builder.setUuid("UUID_1");
+    builder.setSubmitterLogin("LOGIN_1");
+    builder.setComponentKey("COMPONENT_KEY_1");
+    builder.setComponentUuid("COMPONENT_UUID_1");
+    builder.setComponentName("The component");
+    CeTask task = builder.build();
+
+    assertThat(task.getType()).isEqualTo("TYPE_1");
+    assertThat(task.getUuid()).isEqualTo("UUID_1");
+    assertThat(task.getSubmitterLogin()).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 equals_and_hashCode_on_uuid() {
+    CeTask.Builder builder1 = new CeTask.Builder().setType("TYPE_1").setUuid("UUID_1");
+    CeTask task1 = builder1.build();
+    CeTask task1bis = builder1.build();
+    CeTask task2 = new CeTask.Builder().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());
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/queue/CeWorkerRunnableTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/queue/CeWorkerRunnableTest.java
new file mode 100644 (file)
index 0000000..f7ed66b
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue;
+
+import com.google.common.base.Optional;
+import org.junit.Test;
+import org.mockito.InOrder;
+import org.mockito.Mockito;
+import org.sonar.db.ce.CeActivityDto;
+import org.sonar.db.ce.CeTaskTypes;
+import org.sonar.server.computation.queue.report.ReportTaskProcessor;
+import org.sonar.server.computation.log.CeLogging;
+
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+public class CeWorkerRunnableTest {
+
+  CeQueue queue = mock(CeQueueImpl.class);
+  ReportTaskProcessor taskProcessor = mock(ReportTaskProcessor.class);
+  CeLogging ceLogging = mock(CeLogging.class);
+  CeWorkerRunnable underTest = new CeWorkerRunnable(queue, taskProcessor, ceLogging);
+
+  @Test
+  public void no_pending_tasks_in_queue() throws Exception {
+    when(queue.peek()).thenReturn(Optional.<CeTask>absent());
+
+    underTest.run();
+
+    verifyZeroInteractions(taskProcessor, ceLogging);
+  }
+
+  @Test
+  public void peek_and_process_task() throws Exception {
+    CeTask task = new CeTask.Builder().setUuid("TASK_1").setType(CeTaskTypes.REPORT).setComponentUuid("PROJECT_1").setSubmitterLogin(null).build();
+    when(queue.peek()).thenReturn(Optional.of(task));
+
+    underTest.run();
+
+    InOrder inOrder = Mockito.inOrder(ceLogging, taskProcessor, queue);
+    inOrder.verify(ceLogging).initForTask(task);
+    inOrder.verify(taskProcessor).process(task);
+    inOrder.verify(queue).remove(task, CeActivityDto.Status.SUCCESS);
+    inOrder.verify(ceLogging).clearForTask();
+  }
+
+  @Test
+  public void fail_to_process_task() throws Exception {
+    CeTask task = new CeTask.Builder().setUuid("TASK_1").setType(CeTaskTypes.REPORT).setComponentUuid("PROJECT_1").setSubmitterLogin(null).build();
+    when(queue.peek()).thenReturn(Optional.of(task));
+    doThrow(new IllegalStateException()).when(taskProcessor).process(task);
+
+    underTest.run();
+
+    InOrder inOrder = Mockito.inOrder(ceLogging, taskProcessor, queue);
+    inOrder.verify(ceLogging).initForTask(task);
+    inOrder.verify(taskProcessor).process(task);
+    inOrder.verify(queue).remove(task, CeActivityDto.Status.FAILED);
+    inOrder.verify(ceLogging).clearForTask();
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/queue/report/CleanReportQueueListenerTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/queue/report/CleanReportQueueListenerTest.java
new file mode 100644 (file)
index 0000000..6bd893f
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue.report;
+
+import org.junit.Test;
+import org.sonar.db.ce.CeActivityDto;
+import org.sonar.db.ce.CeTaskTypes;
+import org.sonar.server.computation.ReportFiles;
+import org.sonar.server.computation.queue.CeTask;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class CleanReportQueueListenerTest {
+
+  ReportFiles reportFiles = mock(ReportFiles.class);
+  CleanReportQueueListener underTest = new CleanReportQueueListener(reportFiles);
+
+  @Test
+  public void remove_report_file_if_success() {
+    CeTask task = new CeTask.Builder().setUuid("TASK_1").setType(CeTaskTypes.REPORT).setComponentUuid("PROJECT_1").setSubmitterLogin(null).build();
+
+    underTest.onRemoved(task, CeActivityDto.Status.SUCCESS);
+    verify(reportFiles).deleteIfExists("TASK_1");
+  }
+
+  @Test
+  public void remove_report_file_if_failure() {
+    CeTask task = new CeTask.Builder().setUuid("TASK_1").setType(CeTaskTypes.REPORT).setComponentUuid("PROJECT_1").setSubmitterLogin(null).build();
+
+    underTest.onRemoved(task, CeActivityDto.Status.FAILED);
+    verify(reportFiles).deleteIfExists("TASK_1");
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/queue/report/ReportSubmitterTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/queue/report/ReportSubmitterTest.java
new file mode 100644 (file)
index 0000000..14a4306
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.computation.queue.report;
+
+import org.apache.commons.io.IOUtils;
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.core.permission.GlobalPermissions;
+import org.sonar.db.ce.CeTaskTypes;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.server.component.ComponentService;
+import org.sonar.server.component.NewComponent;
+import org.sonar.server.computation.ReportFiles;
+import org.sonar.server.computation.queue.CeQueue;
+import org.sonar.server.computation.queue.CeQueueImpl;
+import org.sonar.server.computation.queue.CeTaskSubmit;
+import org.sonar.server.permission.PermissionService;
+import org.sonar.server.tester.UserSessionRule;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+public class ReportSubmitterTest {
+
+  @Rule
+  public UserSessionRule userSession = UserSessionRule.standalone();
+
+  CeQueue queue = mock(CeQueueImpl.class);
+  ReportFiles reportFiles = mock(ReportFiles.class);
+  ComponentService componentService = mock(ComponentService.class);
+  PermissionService permissionService = mock(PermissionService.class);
+  ReportSubmitter underTest = new ReportSubmitter(queue, userSession, reportFiles, componentService, permissionService);
+
+  @Test
+  public void submit_a_report_on_existing_project() {
+    when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder("TASK_1"));
+    userSession.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
+    when(componentService.getNullableByKey("MY_PROJECT")).thenReturn(new ComponentDto().setUuid("P1"));
+
+    underTest.submit("MY_PROJECT", null, "My Project", IOUtils.toInputStream("{binary}"));
+
+    verifyZeroInteractions(permissionService);
+    verify(queue).submit(argThat(new TypeSafeMatcher<CeTaskSubmit>() {
+      @Override
+      protected boolean matchesSafely(CeTaskSubmit submit) {
+        return submit.getType().equals(CeTaskTypes.REPORT) && submit.getComponentUuid().equals("P1") &&
+          submit.getUuid().equals("TASK_1");
+      }
+
+      @Override
+      public void describeTo(Description description) {
+
+      }
+    }));
+  }
+
+  @Test
+  public void provision_project_if_does_not_exist() throws Exception {
+    when(queue.prepareSubmit()).thenReturn(new CeTaskSubmit.Builder("TASK_1"));
+    userSession.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.PROVISIONING);
+    when(componentService.getNullableByKey("MY_PROJECT")).thenReturn(null);
+    when(componentService.create(any(NewComponent.class))).thenReturn(new ComponentDto().setUuid("P1").setKey("MY_PROJECT"));
+
+    underTest.submit("MY_PROJECT", null, "My Project", IOUtils.toInputStream("{binary}"));
+
+    verify(permissionService).applyDefaultPermissionTemplate("MY_PROJECT");
+    verify(queue).submit(argThat(new TypeSafeMatcher<CeTaskSubmit>() {
+      @Override
+      protected boolean matchesSafely(CeTaskSubmit submit) {
+        return submit.getType().equals(CeTaskTypes.REPORT) && submit.getComponentUuid().equals("P1") &&
+          submit.getUuid().equals("TASK_1");
+      }
+
+      @Override
+      public void describeTo(Description description) {
+
+      }
+    }));
+
+  }
+}
index 65616a7bde047229dc48148a463fcf9c38a7ffdd..cb05ce578d268bf00faa74ff97e51eef060d3b25 100644 (file)
@@ -27,7 +27,7 @@ import java.util.Set;
 import org.junit.Test;
 import org.picocontainer.ComponentAdapter;
 import org.sonar.core.platform.ComponentContainer;
-import org.sonar.server.computation.CeTask;
+import org.sonar.server.computation.queue.CeTask;
 import org.sonar.server.computation.container.ComputeEngineContainerImpl;
 import org.sonar.server.computation.container.ReportComputeEngineContainerPopulator;
 import org.sonar.server.computation.container.StepsExplorer;
index f86045bfb254dfe52a6733aca58f666920136581..33cbe40211321c7a853c2989de5ca53c6228f721 100644 (file)
@@ -24,7 +24,7 @@ import org.junit.Test;
 import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
 import org.sonar.db.DbTester;
-import org.sonar.server.computation.CeQueue;
+import org.sonar.server.computation.queue.CeQueue;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.WsActionTester;
index d0fdefe6f6dde5e3b1748e90fe236b4c413ddc07..8f1cf22e2f3e1fa4cb89e168f781e64014882e21 100644 (file)
@@ -24,7 +24,7 @@ import org.junit.Test;
 import org.sonar.api.utils.System2;
 import org.sonar.api.web.UserRole;
 import org.sonar.db.DbTester;
-import org.sonar.server.computation.CeQueue;
+import org.sonar.server.computation.queue.CeQueue;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.WsActionTester;
index c88e206cff9e7d5a6b5d19978812b8ced4f9dd56..bdcd11bbf0572c70943e443f3082faa183a18575 100644 (file)
@@ -22,7 +22,7 @@ package org.sonar.server.computation.ws;
 import org.junit.Test;
 import org.mockito.Mockito;
 import org.sonar.api.server.ws.WebService;
-import org.sonar.server.computation.ReportSubmitter;
+import org.sonar.server.computation.queue.report.ReportSubmitter;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
index d9294215382b295a06913b5e974261c0c7641266..bd1d9cfc9f5d1aebb2f636c66fbf32259227b93a 100644 (file)
@@ -24,8 +24,8 @@ import org.junit.Test;
 import org.mockito.Matchers;
 import org.sonar.core.util.Protobuf;
 import org.sonar.db.ce.CeTaskTypes;
-import org.sonar.server.computation.CeTask;
-import org.sonar.server.computation.ReportSubmitter;
+import org.sonar.server.computation.queue.CeTask;
+import org.sonar.server.computation.queue.report.ReportSubmitter;
 import org.sonar.server.plugins.MimeTypes;
 import org.sonar.server.ws.TestResponse;
 import org.sonar.server.ws.WsActionTester;