@@ -89,6 +89,7 @@ import org.sonar.server.computation.sqale.SqaleRatingSettings; | |||
import org.sonar.server.computation.step.ComputationStepExecutor; | |||
import org.sonar.server.computation.step.ComputationSteps; | |||
import org.sonar.server.computation.step.ReportComputationSteps; | |||
import org.sonar.server.computation.taskprocessor.MutableTaskResultHolderImpl; | |||
import org.sonar.server.devcockpit.DevCockpitBridge; | |||
import org.sonar.server.view.index.ViewIndex; | |||
@@ -135,6 +136,7 @@ public final class ReportComputeEngineContainerPopulator implements ContainerPop | |||
SqaleRatingSettings.class, | |||
ActiveRulesHolderImpl.class, | |||
MeasureComputersHolderImpl.class, | |||
MutableTaskResultHolderImpl.class, | |||
BatchReportReaderImpl.class, | |||
@@ -0,0 +1,63 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.computation.step; | |||
import javax.annotation.concurrent.Immutable; | |||
import org.sonar.server.computation.component.DbIdsRepository; | |||
import org.sonar.server.computation.component.TreeRootHolder; | |||
import org.sonar.server.computation.queue.CeTaskResult; | |||
import org.sonar.server.computation.taskprocessor.MutableTaskResultHolder; | |||
public class PublishTaskResultStep implements ComputationStep { | |||
private final MutableTaskResultHolder taskResultHolder; | |||
private final TreeRootHolder treeRootHolder; | |||
private final DbIdsRepository dbIdsRepository; | |||
public PublishTaskResultStep(MutableTaskResultHolder taskResultHolder, TreeRootHolder treeRootHolder, DbIdsRepository dbIdsRepository) { | |||
this.taskResultHolder = taskResultHolder; | |||
this.treeRootHolder = treeRootHolder; | |||
this.dbIdsRepository = dbIdsRepository; | |||
} | |||
@Override | |||
public String getDescription() { | |||
return "Publish task results"; | |||
} | |||
@Override | |||
public void execute() { | |||
long snapshotId = dbIdsRepository.getSnapshotId(treeRootHolder.getRoot()); | |||
taskResultHolder.setResult(new CeTaskResultImpl(snapshotId)); | |||
} | |||
@Immutable | |||
private static class CeTaskResultImpl implements CeTaskResult { | |||
private final long snapshotId; | |||
public CeTaskResultImpl(long snapshotId) { | |||
this.snapshotId = snapshotId; | |||
} | |||
@Override | |||
public Long getSnapshotId() { | |||
return snapshotId; | |||
} | |||
} | |||
} |
@@ -103,7 +103,9 @@ public class ReportComputationSteps extends AbstractComputationSteps { | |||
IndexTestsStep.class, | |||
// notifications are sent at the end, so that webapp displays up-to-date information | |||
SendIssueNotificationsStep.class | |||
SendIssueNotificationsStep.class, | |||
PublishTaskResultStep.class | |||
); | |||
private final ComputeEngineContainer computeEngineContainer; |
@@ -44,7 +44,8 @@ public interface CeTaskProcessor { | |||
Set<String> getHandledCeTaskTypes(); | |||
/** | |||
* Call the processing code for a specific {@link CeTask}. | |||
* Calls the processing code for a specific {@link CeTask} which will optionally return a {@link CeTaskResult} | |||
* holding information to be persisted in the processing history of the Compute Engine (currently the {@code CE_ACTIVITY} table). | |||
* <p> | |||
* The specified is guaranteed to be non {@code null} and its {@link CeTask#getType()} to be one of the values | |||
* of {@link #getHandledCeTaskTypes()}. |
@@ -0,0 +1,30 @@ | |||
/* | |||
* 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.taskprocessor; | |||
import org.sonar.server.computation.queue.CeTaskResult; | |||
public interface MutableTaskResultHolder extends TaskResultHolder { | |||
/** | |||
* @throws NullPointerException if {@code taskResult} is {@code null} | |||
* @throws IllegalStateException if a {@link CeTaskResult} has already been set in the holder | |||
*/ | |||
void setResult(CeTaskResult taskResult); | |||
} |
@@ -0,0 +1,44 @@ | |||
/* | |||
* 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.taskprocessor; | |||
import javax.annotation.CheckForNull; | |||
import org.sonar.server.computation.queue.CeTaskResult; | |||
import static com.google.common.base.Preconditions.checkState; | |||
import static java.util.Objects.requireNonNull; | |||
public class MutableTaskResultHolderImpl implements MutableTaskResultHolder { | |||
@CheckForNull | |||
private CeTaskResult result; | |||
@Override | |||
public CeTaskResult getResult() { | |||
checkState(this.result != null, "No CeTaskResult has been set in the holder"); | |||
return this.result; | |||
} | |||
@Override | |||
public void setResult(CeTaskResult taskResult) { | |||
requireNonNull(taskResult, "taskResult can not be null"); | |||
checkState(this.result == null, "CeTaskResult has already been set in the holder"); | |||
this.result = taskResult; | |||
} | |||
} |
@@ -0,0 +1,29 @@ | |||
/* | |||
* 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.taskprocessor; | |||
import org.sonar.server.computation.queue.CeTaskResult; | |||
public interface TaskResultHolder { | |||
/** | |||
* @throws IllegalStateException if holder holds no CeTaskResult | |||
*/ | |||
CeTaskResult getResult(); | |||
} |
@@ -30,6 +30,7 @@ import org.sonar.server.computation.queue.CeTask; | |||
import org.sonar.server.computation.queue.CeTaskResult; | |||
import org.sonar.server.computation.step.ComputationStepExecutor; | |||
import org.sonar.server.computation.taskprocessor.CeTaskProcessor; | |||
import org.sonar.server.computation.taskprocessor.TaskResultHolder; | |||
import org.sonar.server.devcockpit.DevCockpitBridge; | |||
public class ReportTaskProcessor implements CeTaskProcessor { | |||
@@ -69,7 +70,7 @@ public class ReportTaskProcessor implements CeTaskProcessor { | |||
ComputeEngineContainer ceContainer = containerFactory.create(serverContainer, task, devCockpitBridge); | |||
try { | |||
ceContainer.getComponentByType(ComputationStepExecutor.class).execute(); | |||
return null; | |||
return ceContainer.getComponentByType(TaskResultHolder.class).getResult(); | |||
} finally { | |||
ceContainer.cleanup(); | |||
} |
@@ -0,0 +1,61 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.computation.step; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.sonar.server.computation.batch.TreeRootHolderRule; | |||
import org.sonar.server.computation.component.Component; | |||
import org.sonar.server.computation.component.DbIdsRepository; | |||
import org.sonar.server.computation.taskprocessor.MutableTaskResultHolder; | |||
import org.sonar.server.computation.taskprocessor.MutableTaskResultHolderImpl; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
public class PublishTaskResultStepTest { | |||
private static final Component ROOT_COMPONENT = mock(Component.class); | |||
@Rule | |||
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule() | |||
.setRoot(ROOT_COMPONENT); | |||
private DbIdsRepository dbIdsRepository = mock(DbIdsRepository.class); | |||
private MutableTaskResultHolder taskResultHolder = new MutableTaskResultHolderImpl(); | |||
private PublishTaskResultStep underTest = new PublishTaskResultStep(taskResultHolder, treeRootHolder, dbIdsRepository); | |||
@Test | |||
public void verify_getDescription() { | |||
assertThat(underTest.getDescription()).isEqualTo("Publish task results"); | |||
} | |||
@Test | |||
public void execute_populate_TaskResultHolder_with_a_TaskResult_with_snapshot_id_of_the_root_taken_from_DbIdsRepository() { | |||
long snapshotId = 1233L; | |||
when(dbIdsRepository.getSnapshotId(ROOT_COMPONENT)).thenReturn(snapshotId); | |||
underTest.execute(); | |||
assertThat(taskResultHolder.getResult().getSnapshotId()).isEqualTo(snapshotId); | |||
} | |||
} |
@@ -0,0 +1,70 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* SonarQube is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonar.server.computation.taskprocessor; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.server.computation.queue.CeTaskResult; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
public class MutableTaskResultHolderImplTest { | |||
@Rule | |||
public ExpectedException expectedException = ExpectedException.none(); | |||
private MutableTaskResultHolder underTest = new MutableTaskResultHolderImpl(); | |||
@Test | |||
public void getResult_throws_ISE_if_no_CeTaskResult_is_set() { | |||
expectedException.expect(IllegalStateException.class); | |||
expectedException.expectMessage("No CeTaskResult has been set in the holder"); | |||
underTest.getResult(); | |||
} | |||
@Test | |||
public void getResult_returns_object_set_with_setResult() { | |||
CeTaskResult taskResult = mock(CeTaskResult.class); | |||
underTest.setResult(taskResult); | |||
assertThat(underTest.getResult()).isSameAs(taskResult); | |||
} | |||
@Test | |||
public void setResult_throws_NPE_if_CeTaskResult_argument_is_null() { | |||
expectedException.expect(NullPointerException.class); | |||
expectedException.expectMessage("taskResult can not be null"); | |||
underTest.setResult(null); | |||
} | |||
@Test | |||
public void setResult_throws_ISE_if_called_twice() { | |||
underTest.setResult(mock(CeTaskResult.class)); | |||
expectedException.expect(IllegalStateException.class); | |||
expectedException.expectMessage("CeTaskResult has already been set in the holder"); | |||
underTest.setResult(mock(CeTaskResult.class)); | |||
} | |||
} |