aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/sonar-ce-common/build.gradle1
-rw-r--r--server/sonar-ce-common/src/main/java/org/sonar/ce/queue/CeQueueImpl.java9
-rw-r--r--server/sonar-ce-common/src/test/java/org/sonar/ce/queue/CeQueueImplTest.java64
-rw-r--r--server/sonar-ce/src/main/java/org/sonar/ce/queue/InternalCeQueueImpl.java7
-rw-r--r--server/sonar-ce/src/test/java/org/sonar/ce/queue/InternalCeQueueImplTest.java43
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityDto.java18
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml3
-rw-r--r--server/sonar-db-dao/src/schema/schema-sq.ddl3
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java3
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDtoTest.java17
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java2
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v99/AddNodeNameColumnToCeActivityTable.java51
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v99/DbVersion99.java31
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v99/AddNodeNameColumnToCeActivityTableTest.java53
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v99/DbVersion99Test.java40
-rw-r--r--server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v99/AddNodeNameColumnToCeActivityTableTest/schema.sql25
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/platform/WebServer.java5
-rw-r--r--server/sonar-server-common/src/main/java/org/sonar/server/platform/WebServerImpl.java10
-rw-r--r--server/sonar-server-common/src/test/java/org/sonar/server/platform/WebServerImplTest.java36
-rw-r--r--server/sonar-webserver-core/src/main/java/org/sonar/server/platform/serverid/ServerIdManager.java3
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java1
-rw-r--r--server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/projectdump/ExportSubmitterImplTest.java4
-rw-r--r--server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/ActivityActionTest.java4
-rw-r--r--server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/CancelActionTest.java4
-rw-r--r--server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java3
25 files changed, 417 insertions, 23 deletions
diff --git a/server/sonar-ce-common/build.gradle b/server/sonar-ce-common/build.gradle
index 20e6562ad0b..124c2af585c 100644
--- a/server/sonar-ce-common/build.gradle
+++ b/server/sonar-ce-common/build.gradle
@@ -50,6 +50,7 @@ dependencies {
testImplementation 'org.assertj:assertj-core'
testImplementation 'org.assertj:assertj-guava'
testImplementation 'org.hamcrest:hamcrest-all'
+ testImplementation 'org.mockito:mockito-core'
testImplementation project(':sonar-plugin-api-impl')
testImplementation testFixtures(project(':server:sonar-server-common'))
}
diff --git a/server/sonar-ce-common/src/main/java/org/sonar/ce/queue/CeQueueImpl.java b/server/sonar-ce-common/src/main/java/org/sonar/ce/queue/CeQueueImpl.java
index b207dd7e410..b8dc9456d7a 100644
--- a/server/sonar-ce-common/src/main/java/org/sonar/ce/queue/CeQueueImpl.java
+++ b/server/sonar-ce-common/src/main/java/org/sonar/ce/queue/CeQueueImpl.java
@@ -49,6 +49,7 @@ import org.sonar.db.ce.CeTaskCharacteristicDto;
import org.sonar.db.ce.DeleteIf;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.user.UserDto;
+import org.sonar.server.platform.WebServer;
import org.sonar.server.property.InternalProperties;
import static com.google.common.base.Preconditions.checkState;
@@ -68,11 +69,13 @@ public class CeQueueImpl implements CeQueue {
private final System2 system2;
private final DbClient dbClient;
private final UuidFactory uuidFactory;
+ protected final WebServer webServer;
- public CeQueueImpl(System2 system2, DbClient dbClient, UuidFactory uuidFactory) {
+ public CeQueueImpl(System2 system2, DbClient dbClient, UuidFactory uuidFactory, WebServer webServer) {
this.system2 = system2;
this.dbClient = dbClient;
this.uuidFactory = uuidFactory;
+ this.webServer = webServer;
}
@Override
@@ -243,6 +246,7 @@ public class CeQueueImpl implements CeQueue {
private void cancelImpl(DbSession dbSession, CeQueueDto q) {
CeActivityDto activityDto = new CeActivityDto(q);
+ activityDto.setNodeName(webServer.getNodeName().orElse(null));
activityDto.setStatus(CeActivityDto.Status.CANCELED);
remove(dbSession, q, activityDto);
}
@@ -251,13 +255,14 @@ public class CeQueueImpl implements CeQueue {
public void fail(DbSession dbSession, CeQueueDto task, @Nullable String errorType, @Nullable String errorMessage) {
checkState(IN_PROGRESS.equals(task.getStatus()), "Task is not in-progress and can't be marked as failed [uuid=%s]", task.getUuid());
CeActivityDto activityDto = new CeActivityDto(task);
+ activityDto.setNodeName(webServer.getNodeName().orElse(null));
activityDto.setStatus(CeActivityDto.Status.FAILED);
activityDto.setErrorType(errorType);
activityDto.setErrorMessage(errorMessage);
updateExecutionFields(activityDto);
remove(dbSession, task, activityDto);
}
-
+
protected long updateExecutionFields(CeActivityDto activityDto) {
Long startedAt = activityDto.getStartedAt();
if (startedAt == null) {
diff --git a/server/sonar-ce-common/src/test/java/org/sonar/ce/queue/CeQueueImplTest.java b/server/sonar-ce-common/src/test/java/org/sonar/ce/queue/CeQueueImplTest.java
index 3aa74acca40..548bf5da50b 100644
--- a/server/sonar-ce-common/src/test/java/org/sonar/ce/queue/CeQueueImplTest.java
+++ b/server/sonar-ce-common/src/test/java/org/sonar/ce/queue/CeQueueImplTest.java
@@ -43,6 +43,7 @@ import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.user.UserDto;
import org.sonar.db.user.UserTesting;
+import org.sonar.server.platform.WebServer;
import static com.google.common.collect.ImmutableList.of;
import static java.util.Arrays.asList;
@@ -52,12 +53,15 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.assertj.core.api.Assertions.tuple;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import static org.sonar.ce.queue.CeQueue.SubmitOption.UNIQUE_QUEUE_PER_MAIN_COMPONENT;
public class CeQueueImplTest {
private static final String WORKER_UUID = "workerUuid";
private static final long NOW = 1_450_000_000_000L;
+ private static final String NODE_NAME = "nodeName1";
private System2 system2 = new TestSystem2().setNow(NOW);
@@ -68,7 +72,9 @@ public class CeQueueImplTest {
private UuidFactory uuidFactory = new SequenceUuidFactory();
- private CeQueue underTest = new CeQueueImpl(system2, db.getDbClient(), uuidFactory);
+ private WebServer nodeInformationProvider = mock(WebServer.class);
+
+ private CeQueue underTest = new CeQueueImpl(system2, db.getDbClient(), uuidFactory, nodeInformationProvider);
@Test
public void submit_returns_task_populated_from_CeTaskSubmit_and_creates_CeQueue_row() {
@@ -382,12 +388,38 @@ public class CeQueueImplTest {
underTest.cancel(db.getSession(), queueDto);
- Optional<CeActivityDto> activity = db.getDbClient().ceActivityDao().selectByUuid(db.getSession(), task.getUuid());
+ Optional<CeActivityDto> activity = findCeActivityDtoInDb(task);
assertThat(activity).isPresent();
assertThat(activity.get().getStatus()).isEqualTo(CeActivityDto.Status.CANCELED);
}
@Test
+ public void cancel_pending_whenNodeNameProvided_setItInCeActivity() {
+ when(nodeInformationProvider.getNodeName()).thenReturn(Optional.of(NODE_NAME));
+ CeTask task = submit(CeTaskTypes.REPORT, newComponent(randomAlphabetic(12)));
+ CeQueueDto queueDto = db.getDbClient().ceQueueDao().selectByUuid(db.getSession(), task.getUuid()).get();
+
+ underTest.cancel(db.getSession(), queueDto);
+
+ Optional<CeActivityDto> activity = findCeActivityDtoInDb(task);
+ assertThat(activity).isPresent();
+ assertThat(activity.get().getNodeName()).isEqualTo(NODE_NAME);
+ }
+
+ @Test
+ public void cancel_pending_whenNodeNameNOtProvided_setNulInCeActivity() {
+ when(nodeInformationProvider.getNodeName()).thenReturn(Optional.empty());
+ CeTask task = submit(CeTaskTypes.REPORT, newComponent(randomAlphabetic(12)));
+ CeQueueDto queueDto = db.getDbClient().ceQueueDao().selectByUuid(db.getSession(), task.getUuid()).get();
+
+ underTest.cancel(db.getSession(), queueDto);
+
+ Optional<CeActivityDto> activity = findCeActivityDtoInDb(task);
+ assertThat(activity).isPresent();
+ assertThat(activity.get().getNodeName()).isNull();
+ }
+
+ @Test
public void fail_to_cancel_if_in_progress() {
CeTask task = submit(CeTaskTypes.REPORT, newComponent(randomAlphabetic(11)));
CeQueueDto ceQueueDto = db.getDbClient().ceQueueDao().tryToPeek(session, task.getUuid(), WORKER_UUID).get();
@@ -408,11 +440,11 @@ public class CeQueueImplTest {
int canceledCount = underTest.cancelAll();
assertThat(canceledCount).isEqualTo(2);
- Optional<CeActivityDto> ceActivityInProgress = db.getDbClient().ceActivityDao().selectByUuid(db.getSession(), pendingTask1.getUuid());
+ Optional<CeActivityDto> ceActivityInProgress = findCeActivityDtoInDb(pendingTask1);
assertThat(ceActivityInProgress.get().getStatus()).isEqualTo(CeActivityDto.Status.CANCELED);
- Optional<CeActivityDto> ceActivityPending1 = db.getDbClient().ceActivityDao().selectByUuid(db.getSession(), pendingTask2.getUuid());
+ Optional<CeActivityDto> ceActivityPending1 = findCeActivityDtoInDb(pendingTask2);
assertThat(ceActivityPending1.get().getStatus()).isEqualTo(CeActivityDto.Status.CANCELED);
- Optional<CeActivityDto> ceActivityPending2 = db.getDbClient().ceActivityDao().selectByUuid(db.getSession(), inProgressTask.getUuid());
+ Optional<CeActivityDto> ceActivityPending2 = findCeActivityDtoInDb(inProgressTask);
assertThat(ceActivityPending2).isNotPresent();
}
@@ -430,7 +462,7 @@ public class CeQueueImplTest {
@Test
public void pauseWorkers_marks_workers_as_pausing_if_some_tasks_in_progress() {
CeTask task = submit(CeTaskTypes.REPORT, newComponent(randomAlphabetic(12)));
- db.getDbClient().ceQueueDao().tryToPeek(session, task.getUuid(), WORKER_UUID);
+ db.getDbClient().ceQueueDao().tryToPeek(session, task.getUuid(), WORKER_UUID);
// task is in-progress
assertThat(underTest.getWorkersPauseStatus()).isEqualTo(CeQueue.WorkersPauseStatus.RESUMED);
@@ -477,13 +509,31 @@ public class CeQueueImplTest {
underTest.fail(db.getSession(), queueDto, "TIMEOUT", "Failed on timeout");
- Optional<CeActivityDto> activity = db.getDbClient().ceActivityDao().selectByUuid(db.getSession(), task.getUuid());
+ Optional<CeActivityDto> activity = findCeActivityDtoInDb(task);
assertThat(activity).isPresent();
assertThat(activity.get().getStatus()).isEqualTo(CeActivityDto.Status.FAILED);
assertThat(activity.get().getErrorType()).isEqualTo("TIMEOUT");
assertThat(activity.get().getErrorMessage()).isEqualTo("Failed on timeout");
assertThat(activity.get().getExecutedAt()).isEqualTo(NOW);
assertThat(activity.get().getWorkerUuid()).isEqualTo(WORKER_UUID);
+ assertThat(activity.get().getNodeName()).isNull();
+ }
+
+ @Test
+ public void fail_in_progress_task_whenNodeNameProvided_setsItInCeActivityDto() {
+ when(nodeInformationProvider.getNodeName()).thenReturn(Optional.of(NODE_NAME));
+ CeTask task = submit(CeTaskTypes.REPORT, newComponent(randomAlphabetic(12)));
+ CeQueueDto queueDto = db.getDbClient().ceQueueDao().tryToPeek(db.getSession(), task.getUuid(), WORKER_UUID).get();
+
+ underTest.fail(db.getSession(), queueDto, "TIMEOUT", "Failed on timeout");
+
+ Optional<CeActivityDto> activity = findCeActivityDtoInDb(task);
+ assertThat(activity).isPresent();
+ assertThat(activity.get().getNodeName()).isEqualTo(NODE_NAME);
+ }
+
+ private Optional<CeActivityDto> findCeActivityDtoInDb(CeTask task) {
+ return db.getDbClient().ceActivityDao().selectByUuid(db.getSession(), task.getUuid());
}
@Test
diff --git a/server/sonar-ce/src/main/java/org/sonar/ce/queue/InternalCeQueueImpl.java b/server/sonar-ce/src/main/java/org/sonar/ce/queue/InternalCeQueueImpl.java
index 92a076aff6f..a95a102f4a5 100644
--- a/server/sonar-ce/src/main/java/org/sonar/ce/queue/InternalCeQueueImpl.java
+++ b/server/sonar-ce/src/main/java/org/sonar/ce/queue/InternalCeQueueImpl.java
@@ -47,6 +47,7 @@ import org.sonar.db.ce.CeQueueDao;
import org.sonar.db.ce.CeQueueDto;
import org.sonar.db.ce.CeTaskCharacteristicDto;
import org.sonar.db.component.ComponentDto;
+import org.sonar.server.platform.WebServer;
import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format;
@@ -65,8 +66,8 @@ public class InternalCeQueueImpl extends CeQueueImpl implements InternalCeQueue
private final NextPendingTaskPicker nextPendingTaskPicker;
public InternalCeQueueImpl(System2 system2, DbClient dbClient, UuidFactory uuidFactory, CEQueueStatus queueStatus,
- ComputeEngineStatus computeEngineStatus, NextPendingTaskPicker nextPendingTaskPicker) {
- super(system2, dbClient, uuidFactory);
+ ComputeEngineStatus computeEngineStatus, NextPendingTaskPicker nextPendingTaskPicker, WebServer webServer) {
+ super(system2, dbClient, uuidFactory, webServer);
this.dbClient = dbClient;
this.queueStatus = queueStatus;
this.computeEngineStatus = computeEngineStatus;
@@ -113,6 +114,7 @@ public class InternalCeQueueImpl extends CeQueueImpl implements InternalCeQueue
CeQueueDto queueDto = dbClient.ceQueueDao().selectByUuid(dbSession, task.getUuid())
.orElseThrow(() -> new IllegalStateException("Task does not exist anymore: " + task));
CeActivityDto activityDto = new CeActivityDto(queueDto);
+ activityDto.setNodeName(webServer.getNodeName().orElse(null));
activityDto.setStatus(status);
executionTimeInMs = updateExecutionFields(activityDto);
updateTaskResult(activityDto, taskResult);
@@ -176,6 +178,7 @@ public class InternalCeQueueImpl extends CeQueueImpl implements InternalCeQueue
List<CeQueueDto> wornOutTasks = dbClient.ceQueueDao().selectWornout(dbSession);
wornOutTasks.forEach(queueDto -> {
CeActivityDto activityDto = new CeActivityDto(queueDto);
+ activityDto.setNodeName(webServer.getNodeName().orElse(null));
activityDto.setStatus(CeActivityDto.Status.CANCELED);
updateExecutionFields(activityDto);
remove(dbSession, queueDto, activityDto);
diff --git a/server/sonar-ce/src/test/java/org/sonar/ce/queue/InternalCeQueueImplTest.java b/server/sonar-ce/src/test/java/org/sonar/ce/queue/InternalCeQueueImplTest.java
index c488e4db934..445b29ec849 100644
--- a/server/sonar-ce/src/test/java/org/sonar/ce/queue/InternalCeQueueImplTest.java
+++ b/server/sonar-ce/src/test/java/org/sonar/ce/queue/InternalCeQueueImplTest.java
@@ -48,6 +48,7 @@ import org.sonar.db.ce.CeTaskTypes;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.user.UserDto;
+import org.sonar.server.platform.WebServer;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyMap;
@@ -68,6 +69,7 @@ public class InternalCeQueueImplTest {
private static final String AN_ANALYSIS_UUID = "U1";
private static final String WORKER_UUID_1 = "worker uuid 1";
private static final String WORKER_UUID_2 = "worker uuid 2";
+ private static final String NODE_NAME = "nodeName1";
private System2 system2 = new AlwaysIncreasingSystem2();
@@ -81,13 +83,15 @@ public class InternalCeQueueImplTest {
private ComputeEngineStatus computeEngineStatus = mock(ComputeEngineStatus.class);
private Configuration config = mock(Configuration.class);
private NextPendingTaskPicker nextPendingTaskPicker = new NextPendingTaskPicker(config, db.getDbClient());
+ private WebServer nodeInformationProvider = mock(WebServer.class);
private InternalCeQueue underTest = new InternalCeQueueImpl(system2, db.getDbClient(), uuidFactory, queueStatus,
- computeEngineStatus, nextPendingTaskPicker);
+ computeEngineStatus, nextPendingTaskPicker, nodeInformationProvider);
@Before
public void setUp() {
when(config.getBoolean(any())).thenReturn(Optional.of(false));
when(computeEngineStatus.getStatus()).thenReturn(STARTED);
+ when(nodeInformationProvider.getNodeName()).thenReturn(Optional.of(NODE_NAME));
}
@Test
@@ -211,6 +215,32 @@ public class InternalCeQueueImplTest {
}
@Test
+ public void remove_sets_nodeName_in_CeActivity_when_nodeInformationProvider_defines_node_name() {
+ when(nodeInformationProvider.getNodeName()).thenReturn(Optional.of(NODE_NAME));
+ CeTask task = submit(CeTaskTypes.REPORT, newProjectDto("PROJECT_1"));
+
+ Optional<CeTask> peek = underTest.peek(WORKER_UUID_2, true);
+ underTest.remove(peek.get(), CeActivityDto.Status.SUCCESS, newTaskResult(AN_ANALYSIS_UUID), null);
+
+ Optional<CeActivityDto> history = db.getDbClient().ceActivityDao().selectByUuid(db.getSession(), task.getUuid());
+ assertThat(history).isPresent();
+ assertThat(history.get().getNodeName()).isEqualTo(NODE_NAME);
+ }
+
+ @Test
+ public void remove_do_not_set_nodeName_in_CeActivity_when_nodeInformationProvider_does_not_define_node_name() {
+ when(nodeInformationProvider.getNodeName()).thenReturn(Optional.empty());
+ CeTask task = submit(CeTaskTypes.REPORT, newProjectDto("PROJECT_1"));
+
+ Optional<CeTask> peek = underTest.peek(WORKER_UUID_2, true);
+ underTest.remove(peek.get(), CeActivityDto.Status.SUCCESS, newTaskResult(AN_ANALYSIS_UUID), null);
+
+ Optional<CeActivityDto> history = db.getDbClient().ceActivityDao().selectByUuid(db.getSession(), task.getUuid());
+ assertThat(history).isPresent();
+ assertThat(history.get().getNodeName()).isNull();
+ }
+
+ @Test
public void remove_saves_error_message_and_stacktrace_when_exception_is_provided() {
Throwable error = new NullPointerException("Fake NPE to test persistence to DB");
@@ -248,7 +278,7 @@ public class InternalCeQueueImplTest {
db.getDbClient().ceQueueDao().deleteByUuid(db.getSession(), task.getUuid());
db.commit();
- InternalCeQueueImpl underTest = new InternalCeQueueImpl(system2, db.getDbClient(), null, queueStatus, null, null);
+ InternalCeQueueImpl underTest = new InternalCeQueueImpl(system2, db.getDbClient(), null, queueStatus, null, null, nodeInformationProvider);
try {
underTest.remove(task, CeActivityDto.Status.SUCCESS, null, null);
@@ -265,7 +295,7 @@ public class InternalCeQueueImplTest {
CeTask task = submit(CeTaskTypes.REPORT, newProjectDto("PROJECT_1"));
db.getDbClient().ceQueueDao().deleteByUuid(db.getSession(), task.getUuid());
db.commit();
- InternalCeQueueImpl underTest = new InternalCeQueueImpl(system2, db.getDbClient(), null, queueStatusMock, null, null);
+ InternalCeQueueImpl underTest = new InternalCeQueueImpl(system2, db.getDbClient(), null, queueStatusMock, null, null, nodeInformationProvider);
try {
underTest.remove(task, CeActivityDto.Status.FAILED, null, null);
@@ -277,16 +307,19 @@ public class InternalCeQueueImplTest {
@Test
public void cancelWornOuts_does_not_update_queueStatus() {
+
CEQueueStatus queueStatusMock = mock(CEQueueStatus.class);
CeTask task = submit(CeTaskTypes.REPORT, newProjectDto("PROJECT_1"));
db.executeUpdateSql("update ce_queue set status = 'PENDING', started_at = 123 where uuid = '" + task.getUuid() + "'");
db.commit();
- InternalCeQueueImpl underTest = new InternalCeQueueImpl(system2, db.getDbClient(), null, queueStatusMock, null, null);
+ InternalCeQueueImpl underTest = new InternalCeQueueImpl(system2, db.getDbClient(), null, queueStatusMock, null, null, nodeInformationProvider);
underTest.cancelWornOuts();
- assertThat(db.getDbClient().ceActivityDao().selectByUuid(db.getSession(), task.getUuid())).isPresent();
+ Optional<CeActivityDto> ceActivityDto = db.getDbClient().ceActivityDao().selectByUuid(db.getSession(), task.getUuid());
+ assertThat(ceActivityDto).isPresent();
+ assertThat(ceActivityDto.get().getNodeName()).isEqualTo(NODE_NAME);
verifyNoInteractions(queueStatusMock);
}
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityDto.java
index 32114fbbfe3..f107fdb45eb 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityDto.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/ce/CeActivityDto.java
@@ -30,7 +30,8 @@ import static java.lang.String.format;
public class CeActivityDto {
- private static final int MAX_SIZE_ERROR_MESSAGE = 1000;
+ private static final int ERROR_MESSAGE_MAX_SIZE = 1000;
+ private static final int NODE_NAME_MAX_SIZE = 100;
public enum Status {
SUCCESS, FAILED, CANCELED
@@ -105,6 +106,8 @@ public class CeActivityDto {
*/
private int warningCount = 0;
+ private String nodeName;
+
CeActivityDto() {
// required for MyBatis
}
@@ -287,7 +290,7 @@ public class CeActivityDto {
}
public CeActivityDto setErrorMessage(@Nullable String errorMessage) {
- this.errorMessage = ensureNotTooBig(removeCharZeros(errorMessage), MAX_SIZE_ERROR_MESSAGE);
+ this.errorMessage = ensureNotTooBig(removeCharZeros(errorMessage), ERROR_MESSAGE_MAX_SIZE);
return this;
}
@@ -331,10 +334,21 @@ public class CeActivityDto {
return this;
}
+ @CheckForNull
+ public String getNodeName() {
+ return nodeName;
+ }
+
+ public CeActivityDto setNodeName(@Nullable String nodeName) {
+ this.nodeName = ensureNotTooBig(nodeName, NODE_NAME_MAX_SIZE);
+ return this;
+ }
+
@Override
public String toString() {
return "CeActivityDto{" +
"uuid='" + uuid + '\'' +
+ ", nodeName='" + nodeName + '\'' +
", componentUuid='" + componentUuid + '\'' +
", mainComponentUuid='" + mainComponentUuid + '\'' +
", analysisUuid='" + analysisUuid + '\'' +
diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml
index 261f886da0a..0ad2f5d286b 100644
--- a/server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml
+++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml
@@ -21,6 +21,7 @@
<sql id="ceActivityColumns">
ca.uuid,
+ ca.node_name as nodeName,
ca.task_type as taskType,
ca.component_uuid as componentUuid,
ca.main_component_uuid as mainComponentUuid,
@@ -175,6 +176,7 @@
<insert id="insert" parameterType="org.sonar.db.ce.CeActivityDto" useGeneratedKeys="false">
insert into ce_activity (
uuid,
+ node_name,
component_uuid,
main_component_uuid,
analysis_uuid,
@@ -199,6 +201,7 @@
)
values (
#{uuid,jdbcType=VARCHAR},
+ #{nodeName,jdbcType=VARCHAR},
#{componentUuid,jdbcType=VARCHAR},
#{mainComponentUuid,jdbcType=VARCHAR},
#{analysisUuid,jdbcType=VARCHAR},
diff --git a/server/sonar-db-dao/src/schema/schema-sq.ddl b/server/sonar-db-dao/src/schema/schema-sq.ddl
index eb1660e6ef6..0cc0c1c8c34 100644
--- a/server/sonar-db-dao/src/schema/schema-sq.ddl
+++ b/server/sonar-db-dao/src/schema/schema-sq.ddl
@@ -136,7 +136,8 @@ CREATE TABLE "CE_ACTIVITY"(
"ERROR_TYPE" CHARACTER VARYING(20),
"WORKER_UUID" CHARACTER VARYING(40),
"CREATED_AT" BIGINT NOT NULL,
- "UPDATED_AT" BIGINT NOT NULL
+ "UPDATED_AT" BIGINT NOT NULL,
+ "NODE_NAME" CHARACTER VARYING(100)
);
ALTER TABLE "CE_ACTIVITY" ADD CONSTRAINT "PK_CE_ACTIVITY" PRIMARY KEY("UUID");
CREATE INDEX "CE_ACTIVITY_COMPONENT" ON "CE_ACTIVITY"("COMPONENT_UUID" NULLS FIRST);
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java
index f6d28d0b87a..d6f59435edd 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java
@@ -71,6 +71,7 @@ public class CeActivityDaoTest {
private static final String COMPONENT_1 = randomAlphabetic(14);
private static final long INITIAL_TIME = 1_450_000_000_000L;
+ private static final String NODE_NAME = "node1";
private final TestSystem2 system2 = new TestSystem2().setNow(INITIAL_TIME);
@@ -93,6 +94,7 @@ public class CeActivityDaoTest {
assertThat(saved).isPresent();
CeActivityDto dto = saved.get();
assertThat(dto.getUuid()).isEqualTo("TASK_1");
+ assertThat(dto.getNodeName()).isEqualTo(NODE_NAME);
assertThat(dto.getMainComponentUuid()).isEqualTo(MAINCOMPONENT_1);
assertThat(dto.getComponentUuid()).isEqualTo(COMPONENT_1);
assertThat(dto.getStatus()).isEqualTo(SUCCESS);
@@ -858,6 +860,7 @@ public class CeActivityDaoTest {
CeQueueDto ceQueueDto = db.getDbClient().ceQueueDao().selectByUuid(dbSession, uuid).get();
CeActivityDto dto = new CeActivityDto(ceQueueDto);
+ dto.setNodeName(NODE_NAME);
dto.setStatus(status);
dto.setStartedAt(1_500_000_000_000L);
dto.setExecutedAt(1_500_000_000_500L);
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDtoTest.java
index b57f5825ac8..f9215e29076 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDtoTest.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/ce/CeActivityDtoTest.java
@@ -26,6 +26,7 @@ import java.util.Random;
import org.junit.Test;
import org.junit.runner.RunWith;
+import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -33,6 +34,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
@RunWith(DataProviderRunner.class)
public class CeActivityDtoTest {
private static final String STR_40_CHARS = "0123456789012345678901234567890123456789";
+ private static final String STR_100_CHARS = randomAlphabetic(100);
private CeActivityDto underTest = new CeActivityDto();
@Test
@@ -100,6 +102,21 @@ public class CeActivityDtoTest {
}
@Test
+ public void setNodeName_accepts_null_empty_and_string_100_chars_or_less() {
+ underTest.setNodeName(null);
+ underTest.setNodeName("");
+ underTest.setNodeName("bar");
+ underTest.setNodeName(STR_100_CHARS);
+ assertThat(underTest.getNodeName()).isEqualTo(STR_100_CHARS);
+ }
+
+ @Test
+ public void setNodeName_ifMoreThan100chars_truncates() {
+ underTest.setNodeName(STR_100_CHARS + "This should be truncated");
+ assertThat(underTest.getNodeName()).isEqualTo(STR_100_CHARS);
+ }
+
+ @Test
@UseDataProvider("stringsWithChar0")
public void setStacktrace_filters_out_char_zero(String withChar0, String expected) {
underTest.setErrorStacktrace(withChar0);
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java
index 1208b855f29..cf8c29ce3bc 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/MigrationConfigurationModule.java
@@ -37,6 +37,7 @@ import org.sonar.server.platform.db.migration.version.v95.DbVersion95;
import org.sonar.server.platform.db.migration.version.v96.DbVersion96;
import org.sonar.server.platform.db.migration.version.v97.DbVersion97;
import org.sonar.server.platform.db.migration.version.v98.DbVersion98;
+import org.sonar.server.platform.db.migration.version.v99.DbVersion99;
public class MigrationConfigurationModule extends Module {
@Override
@@ -54,6 +55,7 @@ public class MigrationConfigurationModule extends Module {
DbVersion96.class,
DbVersion97.class,
DbVersion98.class,
+ DbVersion99.class,
// migration steps
MigrationStepRegistryImpl.class,
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v99/AddNodeNameColumnToCeActivityTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v99/AddNodeNameColumnToCeActivityTable.java
new file mode 100644
index 00000000000..042605d88fc
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v99/AddNodeNameColumnToCeActivityTable.java
@@ -0,0 +1,51 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.version.v99;
+
+import com.google.common.annotations.VisibleForTesting;
+import java.sql.Connection;
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.db.DatabaseUtils;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+class AddNodeNameColumnToCeActivityTable extends DdlChange {
+ @VisibleForTesting
+ static final String TABLE_NAME = "ce_activity";
+ @VisibleForTesting
+ static final String COLUMN_NAME = "node_name";
+
+ public AddNodeNameColumnToCeActivityTable(Database db) {
+ super(db);
+ }
+
+ @Override
+ public void execute(Context context) throws SQLException {
+ try (Connection c = getDatabase().getDataSource().getConnection()) {
+ if (!DatabaseUtils.tableColumnExists(c, TABLE_NAME, COLUMN_NAME)) {
+ context.execute(new AddColumnsBuilder(getDialect(), TABLE_NAME)
+ .addColumn(VarcharColumnDef.newVarcharColumnDefBuilder(COLUMN_NAME).setLimit(100).setIsNullable(true).build())
+ .build());
+ }
+ }
+ }
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v99/DbVersion99.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v99/DbVersion99.java
new file mode 100644
index 00000000000..1d345f5b118
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v99/DbVersion99.java
@@ -0,0 +1,31 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.version.v99;
+
+import org.sonar.server.platform.db.migration.step.MigrationStepRegistry;
+import org.sonar.server.platform.db.migration.version.DbVersion;
+
+public class DbVersion99 implements DbVersion {
+ @Override
+ public void addSteps(MigrationStepRegistry registry) {
+ registry
+ .add(6800, "Add node_name column to ce_activity table", AddNodeNameColumnToCeActivityTable.class);
+ }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v99/AddNodeNameColumnToCeActivityTableTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v99/AddNodeNameColumnToCeActivityTableTest.java
new file mode 100644
index 00000000000..927e9d57666
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v99/AddNodeNameColumnToCeActivityTableTest.java
@@ -0,0 +1,53 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.version.v99;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+
+import static org.sonar.server.platform.db.migration.version.v99.AddNodeNameColumnToCeActivityTable.COLUMN_NAME;
+import static org.sonar.server.platform.db.migration.version.v99.AddNodeNameColumnToCeActivityTable.TABLE_NAME;
+
+public class AddNodeNameColumnToCeActivityTableTest {
+
+ @Rule
+ public final CoreDbTester db = CoreDbTester.createForSchema(AddNodeNameColumnToCeActivityTableTest.class, "schema.sql");
+
+ private final AddNodeNameColumnToCeActivityTable underTest = new AddNodeNameColumnToCeActivityTable(db.database());
+
+ @Test
+ public void migration_should_add_column() throws SQLException {
+ db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME);
+ underTest.execute();
+ db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, null, true);
+ }
+
+ @Test
+ public void migration_should_be_reentrant() throws SQLException {
+ db.assertColumnDoesNotExist(TABLE_NAME, COLUMN_NAME);
+ underTest.execute();
+ // re-entrant
+ underTest.execute();
+ db.assertColumnDefinition(TABLE_NAME, COLUMN_NAME, Types.VARCHAR, null, true);
+ }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v99/DbVersion99Test.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v99/DbVersion99Test.java
new file mode 100644
index 00000000000..ce39f82e710
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v99/DbVersion99Test.java
@@ -0,0 +1,40 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.platform.db.migration.version.v99;
+
+import org.junit.Test;
+
+import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMigrationNotEmpty;
+import static org.sonar.server.platform.db.migration.version.DbVersionTestUtils.verifyMinimumMigrationNumber;
+
+public class DbVersion99Test {
+ private final DbVersion99 underTest = new DbVersion99();
+
+ @Test
+ public void migrationNumber_starts_at_6800() {
+ verifyMinimumMigrationNumber(underTest, 6800);
+ }
+
+ @Test
+ public void verify_migration_is_not_empty() {
+ verifyMigrationNotEmpty(underTest);
+ }
+
+}
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v99/AddNodeNameColumnToCeActivityTableTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v99/AddNodeNameColumnToCeActivityTableTest/schema.sql
new file mode 100644
index 00000000000..578f6db77d0
--- /dev/null
+++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v99/AddNodeNameColumnToCeActivityTableTest/schema.sql
@@ -0,0 +1,25 @@
+
+CREATE TABLE "CE_ACTIVITY"(
+ "UUID" CHARACTER VARYING(40) NOT NULL,
+ "TASK_TYPE" CHARACTER VARYING(15) NOT NULL,
+ "MAIN_COMPONENT_UUID" CHARACTER VARYING(40),
+ "COMPONENT_UUID" CHARACTER VARYING(40),
+ "STATUS" CHARACTER VARYING(15) NOT NULL,
+ "MAIN_IS_LAST" BOOLEAN NOT NULL,
+ "MAIN_IS_LAST_KEY" CHARACTER VARYING(55) NOT NULL,
+ "IS_LAST" BOOLEAN NOT NULL,
+ "IS_LAST_KEY" CHARACTER VARYING(55) NOT NULL,
+ "SUBMITTER_UUID" CHARACTER VARYING(255),
+ "SUBMITTED_AT" BIGINT NOT NULL,
+ "STARTED_AT" BIGINT,
+ "EXECUTED_AT" BIGINT,
+ "EXECUTION_COUNT" INTEGER NOT NULL,
+ "EXECUTION_TIME_MS" BIGINT,
+ "ANALYSIS_UUID" CHARACTER VARYING(50),
+ "ERROR_MESSAGE" CHARACTER VARYING(1000),
+ "ERROR_STACKTRACE" CHARACTER LARGE OBJECT,
+ "ERROR_TYPE" CHARACTER VARYING(20),
+ "WORKER_UUID" CHARACTER VARYING(40),
+ "CREATED_AT" BIGINT NOT NULL,
+ "UPDATED_AT" BIGINT NOT NULL
+);
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/platform/WebServer.java b/server/sonar-server-common/src/main/java/org/sonar/server/platform/WebServer.java
index e82e99fac26..97b7ffee737 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/platform/WebServer.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/platform/WebServer.java
@@ -19,6 +19,7 @@
*/
package org.sonar.server.platform;
+import java.util.Optional;
import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.server.ServerSide;
@@ -27,7 +28,7 @@ import org.sonar.api.server.ServerSide;
public interface WebServer {
/**
- * WebServer is standalone when property {@link org.sonar.process.ProcessProperties.Property#CLUSTER_ENABLED} is {@code false} or
+ * Node is standalone when property {@link org.sonar.process.ProcessProperties.Property#CLUSTER_ENABLED} is {@code false} or
* undefined.
*/
boolean isStandalone();
@@ -40,4 +41,6 @@ public interface WebServer {
*/
boolean isStartupLeader();
+ Optional<String> getNodeName();
+
}
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/platform/WebServerImpl.java b/server/sonar-server-common/src/main/java/org/sonar/server/platform/WebServerImpl.java
index e1a8ac107b0..07f37975002 100644
--- a/server/sonar-server-common/src/main/java/org/sonar/server/platform/WebServerImpl.java
+++ b/server/sonar-server-common/src/main/java/org/sonar/server/platform/WebServerImpl.java
@@ -19,24 +19,29 @@
*/
package org.sonar.server.platform;
+import java.util.Optional;
import org.sonar.api.config.Configuration;
import org.sonar.api.utils.log.Loggers;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_ENABLED;
+import static org.sonar.process.ProcessProperties.Property.CLUSTER_NODE_NAME;
import static org.sonar.process.ProcessProperties.Property.CLUSTER_WEB_STARTUP_LEADER;
public class WebServerImpl implements WebServer {
private final boolean clusterEnabled;
private final boolean startupLeader;
+ private final String nodeName;
public WebServerImpl(Configuration config) {
this.clusterEnabled = config.getBoolean(CLUSTER_ENABLED.getKey()).orElse(false);
if (this.clusterEnabled) {
this.startupLeader = config.getBoolean(CLUSTER_WEB_STARTUP_LEADER.getKey()).orElse(false);
+ this.nodeName = config.get(CLUSTER_NODE_NAME.getKey()).orElse(CLUSTER_NODE_NAME.getDefaultValue());
Loggers.get(WebServerImpl.class).info("Cluster enabled (startup {})", startupLeader ? "leader" : "follower");
} else {
this.startupLeader = true;
+ this.nodeName = null;
}
}
@@ -49,4 +54,9 @@ public class WebServerImpl implements WebServer {
public boolean isStartupLeader() {
return startupLeader;
}
+
+ @Override
+ public Optional<String> getNodeName() {
+ return Optional.ofNullable(nodeName);
+ }
}
diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/platform/WebServerImplTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/platform/WebServerImplTest.java
index 168ed9bd234..9b1998a1236 100644
--- a/server/sonar-server-common/src/test/java/org/sonar/server/platform/WebServerImplTest.java
+++ b/server/sonar-server-common/src/test/java/org/sonar/server/platform/WebServerImplTest.java
@@ -69,4 +69,40 @@ public class WebServerImplTest {
assertThat(underTest.isStartupLeader()).isFalse();
}
+ @Test
+ public void getNodeName_whenNotACluster_isEmpty() {
+ settings.setProperty("sonar.cluster.enabled", "false");
+ settings.setProperty("sonar.cluster.node.name", "nameIgnored");
+
+ WebServerImpl underTest = new WebServerImpl(settings.asConfig());
+
+ assertThat(underTest.getNodeName()).isEmpty();
+ }
+
+ @Test
+ public void getNodeName_whenClusterAndNameNotDefined_fallbacksToDefaultName() {
+ settings.setProperty("sonar.cluster.enabled", "true");
+ settings.removeProperty("sonar.cluster.node.name");
+
+ WebServerImpl underTest = new WebServerImpl(settings.asConfig());
+
+ assertThat(underTest.getNodeName()).isNotEmpty();
+ String nodeNameFirstCallToGetNodeName = underTest.getNodeName().get();
+ assertThat(nodeNameFirstCallToGetNodeName).startsWith("sonarqube-");
+ String nodeNameSecondCallToGetNodeName = underTest.getNodeName().get();
+ assertThat(nodeNameFirstCallToGetNodeName).isEqualTo(nodeNameSecondCallToGetNodeName);
+ }
+
+ @Test
+ public void getNodeName_whenClusterAndNameDefined_returnName() {
+ String nodeName = "nodeName1";
+ settings.setProperty("sonar.cluster.enabled", "true");
+ settings.setProperty("sonar.cluster.node.name", nodeName);
+
+ WebServerImpl underTest = new WebServerImpl(settings.asConfig());
+
+ assertThat(underTest.getNodeName()).isNotEmpty();
+ assertThat(underTest.getNodeName().get()).startsWith(nodeName);
+ }
+
}
diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/serverid/ServerIdManager.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/serverid/ServerIdManager.java
index 33afdd866c4..3f017c59115 100644
--- a/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/serverid/ServerIdManager.java
+++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/serverid/ServerIdManager.java
@@ -47,7 +47,8 @@ public class ServerIdManager implements Startable {
private final SonarRuntime runtime;
private final WebServer webServer;
- public ServerIdManager(ServerIdChecksum serverIdChecksum, ServerIdFactory serverIdFactory, DbClient dbClient, SonarRuntime runtime, WebServer webServer) {
+ public ServerIdManager(ServerIdChecksum serverIdChecksum, ServerIdFactory serverIdFactory,
+ DbClient dbClient, SonarRuntime runtime, WebServer webServer) {
this.serverIdChecksum = serverIdChecksum;
this.serverIdFactory = serverIdFactory;
this.dbClient = dbClient;
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java
index f91adf41bf3..94640a00cde 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/ws/TaskFormatter.java
@@ -107,6 +107,7 @@ public class TaskFormatter {
builder.setId(dto.getUuid());
builder.setStatus(Ce.TaskStatus.valueOf(dto.getStatus().name()));
builder.setType(dto.getTaskType());
+ ofNullable(dto.getNodeName()).ifPresent(builder::setNodeName);
ofNullable(dto.getComponentUuid()).ifPresent(uuid -> setComponent(builder, uuid, cache).setComponentId(uuid));
String analysisUuid = dto.getAnalysisUuid();
ofNullable(analysisUuid).ifPresent(builder::setAnalysisId);
diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/projectdump/ExportSubmitterImplTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/projectdump/ExportSubmitterImplTest.java
index af26afe7ec8..5255dd6d7f7 100644
--- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/projectdump/ExportSubmitterImplTest.java
+++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/projectdump/ExportSubmitterImplTest.java
@@ -29,10 +29,12 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.db.ce.CeQueueDto;
import org.sonar.db.component.ComponentDto;
+import org.sonar.server.platform.WebServer;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.tuple;
+import static org.mockito.Mockito.mock;
public class ExportSubmitterImplTest {
@@ -43,7 +45,7 @@ public class ExportSubmitterImplTest {
public DbTester db = DbTester.create(system2);
private final DbClient dbClient = db.getDbClient();
- private final CeQueue ceQueue = new CeQueueImpl(system2, db.getDbClient(), UuidFactoryFast.getInstance());
+ private final CeQueue ceQueue = new CeQueueImpl(system2, db.getDbClient(), UuidFactoryFast.getInstance(), mock(WebServer.class));
private final ExportSubmitterImpl underTest = new ExportSubmitterImpl(ceQueue, dbClient);
diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/ActivityActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/ActivityActionTest.java
index 19d6da98d65..bbaf0f2a348 100644
--- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/ActivityActionTest.java
+++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/ActivityActionTest.java
@@ -84,6 +84,7 @@ import static org.sonar.server.ce.ws.CeWsParameters.PARAM_TYPE;
public class ActivityActionTest {
private static final long EXECUTED_AT = System2.INSTANCE.now();
+ private static final String NODE_NAME = "nodeName1";
@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
@@ -111,6 +112,7 @@ public class ActivityActionTest {
Task task = activityResponse.getTasks(0);
assertThat(task.getId()).isEqualTo("T2");
assertThat(task.getStatus()).isEqualTo(Ce.TaskStatus.FAILED);
+ assertThat(task.getNodeName()).isEqualTo(NODE_NAME);
assertThat(task.getComponentId()).isEqualTo(project2.uuid());
assertThat(task.hasAnalysisId()).isFalse();
assertThat(task.getExecutionTimeMs()).isEqualTo(500L);
@@ -118,6 +120,7 @@ public class ActivityActionTest {
task = activityResponse.getTasks(1);
assertThat(task.getId()).isEqualTo("T1");
+ assertThat(task.getNodeName()).isEqualTo(NODE_NAME);
assertThat(task.getStatus()).isEqualTo(Ce.TaskStatus.SUCCESS);
assertThat(task.getComponentId()).isEqualTo(project1.uuid());
assertThat(task.getWarningCount()).isZero();
@@ -678,6 +681,7 @@ public class ActivityActionTest {
activityDto.setStatus(status);
activityDto.setExecutionTimeMs(500L);
activityDto.setExecutedAt(EXECUTED_AT);
+ activityDto.setNodeName(NODE_NAME);
activityDto.setAnalysisUuid(analysis == null ? null : analysis.getUuid());
db.getDbClient().ceActivityDao().insert(db.getSession(), activityDto);
db.commit();
diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/CancelActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/CancelActionTest.java
index 057c44514bf..6086a1219b6 100644
--- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/CancelActionTest.java
+++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/CancelActionTest.java
@@ -36,12 +36,14 @@ import org.sonar.db.ce.CeQueueDto;
import org.sonar.db.ce.CeTaskTypes;
import org.sonar.db.component.ComponentDto;
import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.platform.WebServer;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsActionTester;
import static java.util.Collections.emptyMap;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Mockito.mock;
public class CancelActionTest {
@@ -51,7 +53,7 @@ public class CancelActionTest {
public DbTester db = DbTester.create();
private System2 system2 = new TestSystem2();
- private CeQueue queue = new CeQueueImpl(system2, db.getDbClient(), UuidFactoryFast.getInstance());
+ private CeQueue queue = new CeQueueImpl(system2, db.getDbClient(), UuidFactoryFast.getInstance(), mock(WebServer.class));
private CancelAction underTest = new CancelAction(userSession, db.getDbClient(), queue);
private WsActionTester tester = new WsActionTester(underTest);
diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java
index e59f4b394bc..be88d5fdea8 100644
--- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java
+++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/ws/TaskFormatterTest.java
@@ -49,6 +49,7 @@ import static org.sonar.db.ce.CeQueueTesting.makeInProgress;
public class TaskFormatterTest {
+ private static final String NODE_NAME = "nodeName1";
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
@@ -187,6 +188,7 @@ public class TaskFormatterTest {
assertThat(wsTask.getType()).isEqualTo(CeTaskTypes.REPORT);
assertThat(wsTask.getId()).isEqualTo("UUID");
+ assertThat(wsTask.getNodeName()).isEqualTo(NODE_NAME);
assertThat(wsTask.getStatus()).isEqualTo(Ce.TaskStatus.FAILED);
assertThat(wsTask.getSubmittedAt()).isEqualTo(DateUtils.formatDateTime(new Date(1_450_000_000_000L)));
assertThat(wsTask.getSubmitterLogin()).isEqualTo(user.getLogin());
@@ -282,6 +284,7 @@ public class TaskFormatterTest {
testActivityDto.setWarningCount(warningCount);
return testActivityDto
.setStatus(status)
+ .setNodeName(NODE_NAME)
.setExecutionTimeMs(500L)
.setAnalysisUuid("U1");
}