aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2016-02-11 21:20:18 +0100
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2016-02-15 13:44:59 +0100
commit89a93e795af89c98f5e99de60620c21287f7889e (patch)
tree105152b4d0ac83e11cdc6749b2e37c8b3b24e338
parent8909ccd99b9bc5874f24395519d66e2bcb9bdacb (diff)
downloadsonarqube-89a93e795af89c98f5e99de60620c21287f7889e.tar.gz
sonarqube-89a93e795af89c98f5e99de60620c21287f7889e.zip
SONAR-7187 WS api/ce/activity handles queue and past CE tasks
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/ws/ActivityAction.java224
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/ws/CeWsModule.java4
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/ws/ComponentAction.java3
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/ws/ActivityActionTest.java97
-rw-r--r--sonar-db/src/main/java/org/sonar/db/ce/CeActivityDao.java5
-rw-r--r--sonar-db/src/main/java/org/sonar/db/ce/CeActivityQuery.java10
-rw-r--r--sonar-db/src/main/java/org/sonar/db/ce/CeQueueDao.java32
-rw-r--r--sonar-db/src/main/java/org/sonar/db/ce/CeQueueMapper.java5
-rw-r--r--sonar-db/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml9
-rw-r--r--sonar-db/src/main/resources/org/sonar/db/ce/CeQueueMapper.xml40
-rw-r--r--sonar-db/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java28
-rw-r--r--sonar-db/src/test/java/org/sonar/db/ce/CeQueueDaoTest.java62
-rw-r--r--sonar-db/src/test/java/org/sonar/db/ce/CeQueueTesting.java2
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/HttpWsClient.java10
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/WsClient.java3
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/ce/ActivityWsRequest.java127
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/ce/CeService.java57
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/ce/CeWsParameters.java35
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/ce/package-info.java25
-rw-r--r--sonar-ws/src/test/java/org/sonarqube/ws/client/ce/CeServiceTest.java90
-rw-r--r--sonar-ws/src/test/java/org/sonarqube/ws/client/issue/ActivityWsRequestTest.java (renamed from sonar-ws/src/test/java/org/sonarqube/ws/client/issue/SearchWsRequestTest.java)2
21 files changed, 727 insertions, 143 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/ActivityAction.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/ActivityAction.java
index 5189cae7f57..fca135da732 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/ActivityAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/ActivityAction.java
@@ -17,19 +17,23 @@
* 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.ws;
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import java.util.Date;
+import java.util.LinkedHashSet;
import java.util.List;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import org.apache.ibatis.session.RowBounds;
+import java.util.Set;
import org.sonar.api.resources.Qualifiers;
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.server.ws.WebService.Param;
import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.Paging;
import org.sonar.api.web.UserRole;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.util.Uuids;
@@ -37,124 +41,141 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.ce.CeActivityDto;
import org.sonar.db.ce.CeActivityQuery;
+import org.sonar.db.ce.CeQueueDto;
import org.sonar.db.ce.CeTaskTypes;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentDtoFunctions;
import org.sonar.db.component.ComponentQuery;
-import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.computation.taskprocessor.CeTaskProcessor;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.user.UserSession;
-import org.sonar.server.ws.WsUtils;
import org.sonarqube.ws.Common;
import org.sonarqube.ws.WsCe;
+import org.sonarqube.ws.WsCe.ActivityResponse;
+import org.sonarqube.ws.client.ce.ActivityWsRequest;
import static java.lang.String.format;
+import static org.sonar.api.utils.DateUtils.dateToLong;
+import static org.sonar.api.utils.DateUtils.parseDateTimeQuietly;
+import static org.sonar.api.utils.Paging.offset;
import static org.sonar.server.ws.WsUtils.checkRequest;
+import static org.sonar.server.ws.WsUtils.writeProtobuf;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_ID;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_QUERY;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_MAX_EXECUTED_AT;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_MIN_SUBMITTED_AT;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_ONLY_CURRENTS;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_STATUS;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_TYPE;
public class ActivityAction implements CeWsAction {
-
- private static final String PARAM_COMPONENT_UUID = "componentId";
- private static final String PARAM_COMPONENT_QUERY = "componentQuery";
- private static final String PARAM_TYPE = "type";
- private static final String PARAM_STATUS = "status";
- private static final String PARAM_ONLY_CURRENTS = "onlyCurrents";
- private static final String PARAM_MIN_SUBMITTED_AT = "minSubmittedAt";
- private static final String PARAM_MAX_EXECUTED_AT = "maxExecutedAt";
-
private final UserSession userSession;
private final DbClient dbClient;
private final TaskFormatter formatter;
+ private final Set<String> taskTypes;
- public ActivityAction(UserSession userSession, DbClient dbClient, TaskFormatter formatter) {
+ public ActivityAction(UserSession userSession, DbClient dbClient, TaskFormatter formatter, CeTaskProcessor[] taskProcessors) {
this.userSession = userSession;
this.dbClient = dbClient;
this.formatter = formatter;
+
+ this.taskTypes = new LinkedHashSet<>();
+ for (CeTaskProcessor taskProcessor : taskProcessors) {
+ taskTypes.addAll(taskProcessor.getHandledCeTaskTypes());
+ }
}
@Override
public void define(WebService.NewController controller) {
WebService.NewAction action = controller.createAction("activity")
- .setDescription(format("Search for past task executions. Requires the system administration permission, " +
- "or project administration permission if %s is set.", PARAM_COMPONENT_UUID))
+ .setDescription(format("Search for tasks.<br> " +
+ "Requires the system administration permission, " +
+ "or project administration permission if %s is set.", PARAM_COMPONENT_ID))
.setResponseExample(getClass().getResource("activity-example.json"))
.setHandler(this)
.setSince("5.2");
- action.createParam(PARAM_COMPONENT_UUID)
- .setDescription("Optional id of the component (project) to filter on")
+
+ action.createParam(PARAM_COMPONENT_ID)
+ .setDescription("Id of the component (project) to filter on")
.setExampleValue(Uuids.UUID_EXAMPLE_03);
action.createParam(PARAM_COMPONENT_QUERY)
- .setDescription(format("Optional search by component name or key. Must not be set together with %s.", PARAM_COMPONENT_UUID))
+ .setDescription(format("Limit search to: <ul>" +
+ "<li>component names that contain the supplied string</li>" +
+ "<li>component keys that are exactly the same as the supplied string</li>" +
+ "</ul>" +
+ "Must not be set together with %s", PARAM_COMPONENT_ID))
.setExampleValue("Apache");
action.createParam(PARAM_STATUS)
- .setDescription("Optional filter on task status")
- .setPossibleValues(CeActivityDto.Status.values());
+ .setDescription("Comma separated list of task statuses")
+ .setPossibleValues(ImmutableList.builder()
+ .add(CeActivityDto.Status.values())
+ .add(CeQueueDto.Status.values()).build())
+ .setExampleValue(Joiner.on(",").join(CeQueueDto.Status.IN_PROGRESS, CeActivityDto.Status.SUCCESS))
+ // activity statuses by default to be backward compatible
+ // queued tasks have been added in 5.5
+ .setDefaultValue(Joiner.on(",").join(CeActivityDto.Status.values()));
action.createParam(PARAM_ONLY_CURRENTS)
- .setDescription("Optional filter on the current activities (only the most recent task by project)")
+ .setDescription("Filter on the last tasks (only the most recent finished task by project)")
.setBooleanPossibleValues()
.setDefaultValue("false");
action.createParam(PARAM_TYPE)
- .setDescription("Optional filter on task type")
- .setExampleValue(CeTaskTypes.REPORT);
+ .setDescription("Task type")
+ .setExampleValue(CeTaskTypes.REPORT)
+ .setPossibleValues(taskTypes);
action.createParam(PARAM_MIN_SUBMITTED_AT)
- .setDescription("Optional filter on minimum date of task submission")
+ .setDescription("Minimum date of task submission")
.setExampleValue(DateUtils.formatDateTime(new Date()));
action.createParam(PARAM_MAX_EXECUTED_AT)
- .setDescription("Optional filter on the maximum date of end of task processing")
+ .setDescription("Maximum date of end of task processing")
.setExampleValue(DateUtils.formatDateTime(new Date()));
- action.addPagingParams(10);
+ action.addPagingParams(100);
}
@Override
public void handle(Request wsRequest, Response wsResponse) throws Exception {
+ ActivityResponse activityResponse = doHandle(toSearchWsRequest(wsRequest));
+ writeProtobuf(activityResponse, wsRequest, wsResponse);
+ }
+
+ private ActivityResponse doHandle(ActivityWsRequest request) {
DbSession dbSession = dbClient.openSession(false);
try {
- CeActivityQuery query = buildQuery(dbSession, wsRequest);
+ CeActivityQuery query = buildQuery(dbSession, request);
checkPermissions(query);
+ TaskResult queuedTasks = loadQueuedTasks(dbSession, request, query);
+ TaskResult pastTasks = loadPastTasks(dbSession, request, query, queuedTasks.total);
- RowBounds rowBounds = readMyBatisRowBounds(wsRequest);
- List<CeActivityDto> dtos = dbClient.ceActivityDao().selectByQuery(dbSession, query, rowBounds);
- int total = dbClient.ceActivityDao().countByQuery(dbSession, query);
-
- WsCe.ActivityResponse.Builder wsResponseBuilder = WsCe.ActivityResponse.newBuilder();
- wsResponseBuilder.addAllTasks(formatter.formatActivity(dbSession, dtos));
- wsResponseBuilder.setPaging(Common.Paging.newBuilder()
- .setPageIndex(wsRequest.mandatoryParamAsInt(WebService.Param.PAGE))
- .setPageSize(wsRequest.mandatoryParamAsInt(WebService.Param.PAGE_SIZE))
- .setTotal(total));
- WsUtils.writeProtobuf(wsResponseBuilder.build(), wsRequest, wsResponse);
+ return buildResponse(
+ queuedTasks.tasks,
+ pastTasks.tasks,
+ Paging.forPageIndex(request.getPage())
+ .withPageSize(request.getPageSize())
+ .andTotal(queuedTasks.total + pastTasks.total));
} finally {
dbClient.closeSession(dbSession);
}
}
- private CeActivityQuery buildQuery(DbSession dbSession, Request wsRequest) {
- String componentUuid = wsRequest.param(PARAM_COMPONENT_UUID);
- String componentQuery = wsRequest.param(PARAM_COMPONENT_QUERY);
- checkRequest(componentUuid == null || componentQuery == null,
- format("Only one of following parameters is accepted: %s or %s", PARAM_COMPONENT_UUID, PARAM_COMPONENT_QUERY));
-
+ private CeActivityQuery buildQuery(DbSession dbSession, ActivityWsRequest request) {
CeActivityQuery query = new CeActivityQuery();
- query.setType(wsRequest.param(PARAM_TYPE));
- query.setOnlyCurrents(wsRequest.mandatoryParamAsBoolean(PARAM_ONLY_CURRENTS));
- query.setMinSubmittedAt(toTime(wsRequest.paramAsDateTime(PARAM_MIN_SUBMITTED_AT)));
- query.setMaxExecutedAt(toTime(wsRequest.paramAsDateTime(PARAM_MAX_EXECUTED_AT)));
-
- String status = wsRequest.param(PARAM_STATUS);
- if (status != null) {
- query.setStatus(CeActivityDto.Status.valueOf(status));
+ query.setType(request.getType());
+ query.setOnlyCurrents(request.getOnlyCurrents());
+ query.setMinSubmittedAt(dateToLong(parseDateTimeQuietly(request.getMinSubmittedAt())));
+ query.setMaxExecutedAt(dateToLong(parseDateTimeQuietly(request.getMaxExecutedAt())));
+
+ List<String> statuses = request.getStatus();
+ if (statuses != null && !statuses.isEmpty()) {
+ query.setStatuses(request.getStatus());
}
- loadComponentUuids(dbSession, wsRequest, query);
+ loadComponentUuids(dbSession, request, query);
return query;
}
- private void loadComponentUuids(DbSession dbSession, Request wsRequest, CeActivityQuery query) {
- String componentUuid = wsRequest.param(PARAM_COMPONENT_UUID);
- String componentQuery = wsRequest.param(PARAM_COMPONENT_QUERY);
- if (componentUuid != null && componentQuery != null) {
- throw new BadRequestException(format("Only one of parameters must be set: %s or %s", PARAM_COMPONENT_UUID, PARAM_COMPONENT_QUERY));
- }
+ private void loadComponentUuids(DbSession dbSession, ActivityWsRequest request, CeActivityQuery query) {
+ String componentUuid = request.getComponentId();
+ String componentQuery = request.getComponentQuery();
if (componentUuid != null) {
query.setComponentUuid(componentUuid);
@@ -166,6 +187,26 @@ public class ActivityAction implements CeWsAction {
}
}
+ private TaskResult loadQueuedTasks(DbSession dbSession, ActivityWsRequest request, CeActivityQuery query) {
+ int total = dbClient.ceQueueDao().countByQuery(dbSession, query);
+ List<CeQueueDto> dtos = dbClient.ceQueueDao().selectByQueryInDescOrder(dbSession, query,
+ Paging.forPageIndex(request.getPage())
+ .withPageSize(request.getPageSize())
+ .andTotal(total));
+ Iterable<WsCe.Task> tasks = formatter.formatQueue(dbSession, dtos);
+ return new TaskResult(tasks, total);
+ }
+
+ private TaskResult loadPastTasks(DbSession dbSession, ActivityWsRequest request, CeActivityQuery query, int totalQueuedTasks) {
+ int total = dbClient.ceActivityDao().countByQuery(dbSession, query);
+ // we have to take into account the total number of queue tasks found
+ int offset = Math.max(0, offset(request.getPage(), request.getPageSize()) - totalQueuedTasks);
+ List<CeActivityDto> dtos = dbClient.ceActivityDao().selectByQuery(dbSession, query, offset, request.getPageSize());
+ Iterable<WsCe.Task> ceTasks = formatter.formatActivity(dbSession, dtos);
+
+ return new TaskResult(ceTasks, total);
+ }
+
private void checkPermissions(CeActivityQuery query) {
List<String> componentUuids = query.getComponentUuids();
if (componentUuids != null && componentUuids.size() == 1) {
@@ -177,18 +218,61 @@ public class ActivityAction implements CeWsAction {
}
}
- private static RowBounds readMyBatisRowBounds(Request wsRequest) {
- int pageIndex = wsRequest.mandatoryParamAsInt(WebService.Param.PAGE);
- int pageSize = wsRequest.mandatoryParamAsInt(WebService.Param.PAGE_SIZE);
- return new RowBounds((pageIndex - 1) * pageSize, pageSize);
+ public static boolean isAllowedOnComponentUuid(UserSession userSession, String componentUuid) {
+ return userSession.hasPermission(GlobalPermissions.SYSTEM_ADMIN) || userSession.hasComponentUuidPermission(UserRole.ADMIN, componentUuid);
}
- @CheckForNull
- private static Long toTime(@Nullable Date date) {
- return date == null ? null : date.getTime();
+ private static ActivityResponse buildResponse(Iterable<WsCe.Task> queuedTasks, Iterable<WsCe.Task> pastTasks, Paging paging) {
+ WsCe.ActivityResponse.Builder wsResponseBuilder = WsCe.ActivityResponse.newBuilder();
+
+ int nbInsertedTasks = 0;
+ for (WsCe.Task queuedTask : queuedTasks) {
+ if (nbInsertedTasks < paging.pageSize()) {
+ wsResponseBuilder.addTasks(queuedTask);
+ nbInsertedTasks++;
+ }
+ }
+
+ for (WsCe.Task pastTask : pastTasks) {
+ if (nbInsertedTasks < paging.pageSize()) {
+ wsResponseBuilder.addTasks(pastTask);
+ nbInsertedTasks++;
+ }
+ }
+
+ wsResponseBuilder.setPaging(Common.Paging.newBuilder()
+ .setPageIndex(paging.pageIndex())
+ .setPageSize(paging.pageSize())
+ .setTotal(paging.total()));
+
+ return wsResponseBuilder.build();
}
- public static boolean isAllowedOnComponentUuid(UserSession userSession, String componentUuid) {
- return userSession.hasPermission(GlobalPermissions.SYSTEM_ADMIN) || userSession.hasComponentUuidPermission(UserRole.ADMIN, componentUuid);
+ private static ActivityWsRequest toSearchWsRequest(Request request) {
+ ActivityWsRequest activityWsRequest = new ActivityWsRequest()
+ .setComponentId(request.param(PARAM_COMPONENT_ID))
+ .setComponentQuery(request.param(PARAM_COMPONENT_QUERY))
+ .setStatus(request.paramAsStrings(PARAM_STATUS))
+ .setType(request.param(PARAM_TYPE))
+ .setMaxExecutedAt(request.param(PARAM_MAX_EXECUTED_AT))
+ .setMinSubmittedAt(request.param(PARAM_MIN_SUBMITTED_AT))
+ .setOnlyCurrents(request.paramAsBoolean(PARAM_ONLY_CURRENTS))
+ .setPage(request.mandatoryParamAsInt(Param.PAGE))
+ .setPageSize(request.mandatoryParamAsInt(Param.PAGE_SIZE));
+
+ checkRequest(activityWsRequest.getComponentId() == null || activityWsRequest.getComponentQuery() == null, "%s and %s must not be set at the same time",
+ PARAM_COMPONENT_ID, PARAM_COMPONENT_QUERY);
+
+ return activityWsRequest;
+ }
+
+ private static class TaskResult {
+ private final Iterable<WsCe.Task> tasks;
+ private final int total;
+
+ private TaskResult(Iterable<WsCe.Task> tasks, int total) {
+ this.tasks = tasks;
+ this.total = total;
+ }
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/CeWsModule.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/CeWsModule.java
index dd29f1297e7..edc04a1202e 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/CeWsModule.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/CeWsModule.java
@@ -26,7 +26,6 @@ public class CeWsModule extends Module {
protected void configureModule() {
add(
CeWs.class,
- ActivityAction.class,
CancelAction.class,
CancelAllAction.class,
QueueAction.class,
@@ -35,6 +34,7 @@ public class CeWsModule extends Module {
ComponentAction.class,
SubmitAction.class,
TaskFormatter.class,
- TaskAction.class);
+ TaskAction.class,
+ ActivityAction.class);
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/ComponentAction.java b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/ComponentAction.java
index ec7a0c80f08..1a30756dc7e 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/ws/ComponentAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/ws/ComponentAction.java
@@ -20,7 +20,6 @@
package org.sonar.server.computation.ws;
import java.util.List;
-import org.apache.ibatis.session.RowBounds;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
@@ -75,7 +74,7 @@ public class ComponentAction implements CeWsAction {
CeActivityQuery activityQuery = new CeActivityQuery()
.setComponentUuid(componentUuid)
.setOnlyCurrents(true);
- List<CeActivityDto> activityDtos = dbClient.ceActivityDao().selectByQuery(dbSession, activityQuery, new RowBounds(0, 1));
+ List<CeActivityDto> activityDtos = dbClient.ceActivityDao().selectByQuery(dbSession, activityQuery, 0, 1);
ProjectResponse.Builder wsResponseBuilder = ProjectResponse.newBuilder();
wsResponseBuilder.addAllQueue(formatter.formatQueue(dbSession, queueDtos));
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/ActivityActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/ActivityActionTest.java
index d491bc46957..967c93dcb75 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/ws/ActivityActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/ws/ActivityActionTest.java
@@ -17,6 +17,7 @@
* 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.ws;
import com.google.common.base.Optional;
@@ -39,12 +40,13 @@ import org.sonar.db.ce.CeTaskTypes;
import org.sonar.db.component.ComponentDbTester;
import org.sonar.server.computation.log.CeLogging;
import org.sonar.server.computation.log.LogFileRef;
+import org.sonar.server.computation.taskprocessor.CeTaskProcessor;
import org.sonar.server.exceptions.BadRequestException;
-import org.sonarqube.ws.MediaTypes;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestResponse;
import org.sonar.server.ws.WsActionTester;
import org.sonar.test.JsonAssert;
+import org.sonarqube.ws.MediaTypes;
import org.sonarqube.ws.WsCe;
import static java.util.Arrays.asList;
@@ -53,6 +55,7 @@ import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.db.component.ComponentTesting.newProjectDto;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_STATUS;
public class ActivityActionTest {
@@ -69,8 +72,8 @@ public class ActivityActionTest {
CeLogging ceLogging = mock(CeLogging.class);
TaskFormatter formatter = new TaskFormatter(dbTester.getDbClient(), ceLogging, System2.INSTANCE);
- ActivityAction underTest = new ActivityAction(userSession, dbTester.getDbClient(), formatter);
- WsActionTester tester = new WsActionTester(underTest);
+ ActivityAction underTest = new ActivityAction(userSession, dbTester.getDbClient(), formatter, new CeTaskProcessor[] {mock(CeTaskProcessor.class)});
+ WsActionTester ws = new WsActionTester(underTest);
@Before
public void setUp() {
@@ -80,15 +83,15 @@ public class ActivityActionTest {
@Test
public void get_all_past_activity() {
userSession.setGlobalPermissions(UserRole.ADMIN);
- insert("T1", "PROJECT_1", CeActivityDto.Status.SUCCESS);
- insert("T2", "PROJECT_2", CeActivityDto.Status.FAILED);
+ insertActivity("T1", "PROJECT_1", CeActivityDto.Status.SUCCESS);
+ insertActivity("T2", "PROJECT_2", CeActivityDto.Status.FAILED);
- TestResponse wsResponse = tester.newRequest()
+ TestResponse wsResponse = ws.newRequest()
.setMediaType(MediaTypes.PROTOBUF)
.execute();
// verify the protobuf response
- WsCe.ActivityResponse activityResponse = Protobuf.read(wsResponse.getInputStream(), WsCe.ActivityResponse.PARSER);
+ WsCe.ActivityResponse activityResponse = Protobuf.read(wsResponse.getInputStream(), WsCe.ActivityResponse.parser());
assertThat(activityResponse.getTasksCount()).isEqualTo(2);
// chronological order, from newest to oldest
@@ -107,32 +110,35 @@ public class ActivityActionTest {
@Test
public void filter_by_status() {
userSession.setGlobalPermissions(UserRole.ADMIN);
- insert("T1", "PROJECT_1", CeActivityDto.Status.SUCCESS);
- insert("T2", "PROJECT_2", CeActivityDto.Status.FAILED);
+ insertActivity("T1", "PROJECT_1", CeActivityDto.Status.SUCCESS);
+ insertActivity("T2", "PROJECT_2", CeActivityDto.Status.FAILED);
+ insertQueue("T3", "PROJECT_1", CeQueueDto.Status.IN_PROGRESS);
- TestResponse wsResponse = tester.newRequest()
- .setParam("status", "FAILED")
+ TestResponse wsResponse = ws.newRequest()
+ .setParam("status", "FAILED,IN_PROGRESS")
.setMediaType(MediaTypes.PROTOBUF)
.execute();
- WsCe.ActivityResponse activityResponse = Protobuf.read(wsResponse.getInputStream(), WsCe.ActivityResponse.PARSER);
- assertThat(activityResponse.getTasksCount()).isEqualTo(1);
- assertThat(activityResponse.getTasks(0).getId()).isEqualTo("T2");
+ WsCe.ActivityResponse activityResponse = Protobuf.read(wsResponse.getInputStream(), WsCe.ActivityResponse.parser());
+ assertThat(activityResponse.getTasksCount()).isEqualTo(2);
+ assertThat(activityResponse.getTasks(0).getId()).isEqualTo("T3");
+ assertThat(activityResponse.getTasks(1).getId()).isEqualTo("T2");
}
@Test
public void filter_on_current_activities() {
userSession.setGlobalPermissions(UserRole.ADMIN);
// T2 is the current activity (the most recent one)
- insert("T1", "PROJECT_1", CeActivityDto.Status.SUCCESS);
- insert("T2", "PROJECT_1", CeActivityDto.Status.FAILED);
+ insertActivity("T1", "PROJECT_1", CeActivityDto.Status.SUCCESS);
+ insertActivity("T2", "PROJECT_1", CeActivityDto.Status.FAILED);
+ insertQueue("T3", "PROJECT_1", CeQueueDto.Status.PENDING);
- TestResponse wsResponse = tester.newRequest()
+ TestResponse wsResponse = ws.newRequest()
.setParam("onlyCurrents", "true")
.setMediaType(MediaTypes.PROTOBUF)
.execute();
- WsCe.ActivityResponse activityResponse = Protobuf.read(wsResponse.getInputStream(), WsCe.ActivityResponse.PARSER);
+ WsCe.ActivityResponse activityResponse = Protobuf.read(wsResponse.getInputStream(), WsCe.ActivityResponse.parser());
assertThat(activityResponse.getTasksCount()).isEqualTo(1);
assertThat(activityResponse.getTasks(0).getId()).isEqualTo("T2");
}
@@ -140,23 +146,25 @@ public class ActivityActionTest {
@Test
public void paginate_results() {
userSession.setGlobalPermissions(UserRole.ADMIN);
- insert("T1", "PROJECT_1", CeActivityDto.Status.SUCCESS);
- insert("T2", "PROJECT_2", CeActivityDto.Status.FAILED);
-
- assertPage(1, 1, 2, asList("T2"));
- assertPage(2, 1, 2, asList("T1"));
- assertPage(1, 10, 2, asList("T2", "T1"));
- assertPage(2, 10, 2, Collections.<String>emptyList());
+ insertActivity("T1", "PROJECT_1", CeActivityDto.Status.SUCCESS);
+ insertActivity("T2", "PROJECT_2", CeActivityDto.Status.FAILED);
+ insertQueue("T3", "PROJECT_1", CeQueueDto.Status.IN_PROGRESS);
+
+ assertPage(1, 1, 3, asList("T3"));
+ assertPage(2, 1, 3, asList("T2"));
+ assertPage(1, 10, 3, asList("T3", "T2", "T1"));
+ assertPage(2, 10, 3, Collections.<String>emptyList());
}
private void assertPage(int pageIndex, int pageSize, int expectedTotal, List<String> expectedOrderedTaskIds) {
- TestResponse wsResponse = tester.newRequest()
+ TestResponse wsResponse = ws.newRequest()
.setMediaType(MediaTypes.PROTOBUF)
.setParam(WebService.Param.PAGE, Integer.toString(pageIndex))
.setParam(WebService.Param.PAGE_SIZE, Integer.toString(pageSize))
+ .setParam(PARAM_STATUS, "SUCCESS,FAILED,CANCELED,IN_PROGRESS,PENDING")
.execute();
- WsCe.ActivityResponse activityResponse = Protobuf.read(wsResponse.getInputStream(), WsCe.ActivityResponse.PARSER);
+ WsCe.ActivityResponse activityResponse = Protobuf.read(wsResponse.getInputStream(), WsCe.ActivityResponse.parser());
assertThat(activityResponse.getPaging().getPageIndex()).isEqualTo(pageIndex);
assertThat(activityResponse.getPaging().getPageSize()).isEqualTo(pageSize);
assertThat(activityResponse.getPaging().getTotal()).isEqualTo(expectedTotal);
@@ -172,15 +180,15 @@ public class ActivityActionTest {
public void project_administrator_can_access_his_project_activity() {
// no need to be a system admin
userSession.addComponentUuidPermission(UserRole.ADMIN, "PROJECT_1", "PROJECT_1");
- insert("T1", "PROJECT_1", CeActivityDto.Status.SUCCESS);
- insert("T2", "PROJECT_2", CeActivityDto.Status.FAILED);
+ insertActivity("T1", "PROJECT_1", CeActivityDto.Status.SUCCESS);
+ insertActivity("T2", "PROJECT_2", CeActivityDto.Status.FAILED);
- TestResponse wsResponse = tester.newRequest()
+ TestResponse wsResponse = ws.newRequest()
.setParam("componentId", "PROJECT_1")
.setMediaType(MediaTypes.PROTOBUF)
.execute();
- WsCe.ActivityResponse activityResponse = Protobuf.read(wsResponse.getInputStream(), WsCe.ActivityResponse.PARSER);
+ WsCe.ActivityResponse activityResponse = Protobuf.read(wsResponse.getInputStream(), WsCe.ActivityResponse.parser());
assertThat(activityResponse.getTasksCount()).isEqualTo(1);
assertThat(activityResponse.getTasks(0).getId()).isEqualTo("T1");
assertThat(activityResponse.getTasks(0).getStatus()).isEqualTo(WsCe.TaskStatus.SUCCESS);
@@ -195,11 +203,11 @@ public class ActivityActionTest {
dbTester.commit();
componentDb.indexProjects();
userSession.setGlobalPermissions(UserRole.ADMIN);
- insert("T1", "P1", CeActivityDto.Status.SUCCESS);
- insert("T2", "P2", CeActivityDto.Status.SUCCESS);
- insert("T3", "P3", CeActivityDto.Status.SUCCESS);
+ insertActivity("T1", "P1", CeActivityDto.Status.SUCCESS);
+ insertActivity("T2", "P2", CeActivityDto.Status.SUCCESS);
+ insertActivity("T3", "P3", CeActivityDto.Status.SUCCESS);
- TestResponse wsResponse = tester.newRequest()
+ TestResponse wsResponse = ws.newRequest()
.setParam("componentQuery", "apac")
.setMediaType(MediaTypes.PROTOBUF)
.execute();
@@ -211,9 +219,9 @@ public class ActivityActionTest {
@Test
public void fail_if_both_filters_on_component_id_and_name() {
expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("Only one of following parameters is accepted: componentId or componentQuery");
+ expectedException.expectMessage("componentId and componentQuery must not be set at the same time");
- tester.newRequest()
+ ws.newRequest()
.setParam("componentId", "ID1")
.setParam("componentQuery", "apache")
.setMediaType(MediaTypes.PROTOBUF)
@@ -223,14 +231,25 @@ public class ActivityActionTest {
@Test
public void support_json_response() {
userSession.setGlobalPermissions(UserRole.ADMIN);
- TestResponse wsResponse = tester.newRequest()
+ TestResponse wsResponse = ws.newRequest()
.setMediaType(MediaTypes.JSON)
.execute();
JsonAssert.assertJson(wsResponse.getInput()).isSimilarTo("{\"tasks\":[]}");
}
- private CeActivityDto insert(String taskUuid, String componentUuid, CeActivityDto.Status status) {
+ private CeQueueDto insertQueue(String taskUuid, String componentUuid, CeQueueDto.Status status) {
+ CeQueueDto queueDto = new CeQueueDto();
+ queueDto.setTaskType(CeTaskTypes.REPORT);
+ queueDto.setComponentUuid(componentUuid);
+ queueDto.setUuid(taskUuid);
+ queueDto.setStatus(status);
+ dbTester.getDbClient().ceQueueDao().insert(dbTester.getSession(), queueDto);
+ dbTester.commit();
+ return queueDto;
+ }
+
+ private CeActivityDto insertActivity(String taskUuid, String componentUuid, CeActivityDto.Status status) {
CeQueueDto queueDto = new CeQueueDto();
queueDto.setTaskType(CeTaskTypes.REPORT);
queueDto.setComponentUuid(componentUuid);
diff --git a/sonar-db/src/main/java/org/sonar/db/ce/CeActivityDao.java b/sonar-db/src/main/java/org/sonar/db/ce/CeActivityDao.java
index d4922d8c7c6..97bf1f41c4f 100644
--- a/sonar-db/src/main/java/org/sonar/db/ce/CeActivityDao.java
+++ b/sonar-db/src/main/java/org/sonar/db/ce/CeActivityDao.java
@@ -64,11 +64,12 @@ public class CeActivityDao implements Dao {
/**
* Ordered by id desc -> newest to oldest
*/
- public List<CeActivityDto> selectByQuery(DbSession dbSession, CeActivityQuery query, RowBounds rowBounds) {
+ public List<CeActivityDto> selectByQuery(DbSession dbSession, CeActivityQuery query, int offset, int pageSize) {
if (query.isShortCircuitedByComponentUuids()) {
return Collections.emptyList();
}
- return mapper(dbSession).selectByQuery(query, rowBounds);
+
+ return mapper(dbSession).selectByQuery(query, new RowBounds(offset, pageSize));
}
public int countByQuery(DbSession dbSession, CeActivityQuery query) {
diff --git a/sonar-db/src/main/java/org/sonar/db/ce/CeActivityQuery.java b/sonar-db/src/main/java/org/sonar/db/ce/CeActivityQuery.java
index 8813a996436..2681554dcab 100644
--- a/sonar-db/src/main/java/org/sonar/db/ce/CeActivityQuery.java
+++ b/sonar-db/src/main/java/org/sonar/db/ce/CeActivityQuery.java
@@ -32,7 +32,7 @@ public class CeActivityQuery {
private boolean onlyCurrents = false;
private List<String> componentUuids;
- private CeActivityDto.Status status;
+ private List<String> statuses;
private String type;
private Long minSubmittedAt;
private Long maxExecutedAt;
@@ -70,12 +70,12 @@ public class CeActivityQuery {
}
@CheckForNull
- public CeActivityDto.Status getStatus() {
- return status;
+ public List<String> getStatuses() {
+ return statuses;
}
- public CeActivityQuery setStatus(@Nullable CeActivityDto.Status status) {
- this.status = status;
+ public CeActivityQuery setStatuses(@Nullable List<String> statuses) {
+ this.statuses = statuses;
return this;
}
diff --git a/sonar-db/src/main/java/org/sonar/db/ce/CeQueueDao.java b/sonar-db/src/main/java/org/sonar/db/ce/CeQueueDao.java
index 1b58a57ccf9..09f0b964ea6 100644
--- a/sonar-db/src/main/java/org/sonar/db/ce/CeQueueDao.java
+++ b/sonar-db/src/main/java/org/sonar/db/ce/CeQueueDao.java
@@ -21,12 +21,15 @@ package org.sonar.db.ce;
import com.google.common.base.Optional;
import java.util.List;
+import org.apache.ibatis.session.RowBounds;
+import org.sonar.api.utils.Paging;
import org.sonar.api.utils.System2;
import org.sonar.db.Dao;
import org.sonar.db.DbSession;
-import static org.sonar.db.ce.CeQueueDto.Status.PENDING;
+import static java.util.Collections.emptyList;
import static org.sonar.db.ce.CeQueueDto.Status.IN_PROGRESS;
+import static org.sonar.db.ce.CeQueueDto.Status.PENDING;
public class CeQueueDao implements Dao {
@@ -43,6 +46,26 @@ public class CeQueueDao implements Dao {
return mapper(session).selectAllInAscOrder();
}
+ public List<CeQueueDto> selectByQueryInDescOrder(DbSession dbSession, CeActivityQuery query, Paging paging) {
+ if (query.isShortCircuitedByComponentUuids()
+ || query.isOnlyCurrents()
+ || query.getMaxExecutedAt() != null) {
+ return emptyList();
+ }
+
+ return mapper(dbSession).selectByQueryInDescOrder(query, new RowBounds(paging.offset(), paging.pageSize()));
+ }
+
+ public int countByQuery(DbSession dbSession, CeActivityQuery query) {
+ if (query.isShortCircuitedByComponentUuids()
+ || query.isOnlyCurrents()
+ || query.getMaxExecutedAt() != null) {
+ return 0;
+ }
+
+ return mapper(dbSession).countByQuery(query);
+ }
+
/**
* Ordered by ascending id: oldest to newest
*/
@@ -55,8 +78,11 @@ public class CeQueueDao implements Dao {
}
public CeQueueDto insert(DbSession session, CeQueueDto dto) {
- dto.setCreatedAt(system2.now());
- dto.setUpdatedAt(system2.now());
+ if (dto.getCreatedAt() == 0L || dto.getUpdatedAt() == 0L) {
+ dto.setCreatedAt(system2.now());
+ dto.setUpdatedAt(system2.now());
+ }
+
mapper(session).insert(dto);
return dto;
}
diff --git a/sonar-db/src/main/java/org/sonar/db/ce/CeQueueMapper.java b/sonar-db/src/main/java/org/sonar/db/ce/CeQueueMapper.java
index 464007b9752..fb803a73fa8 100644
--- a/sonar-db/src/main/java/org/sonar/db/ce/CeQueueMapper.java
+++ b/sonar-db/src/main/java/org/sonar/db/ce/CeQueueMapper.java
@@ -23,6 +23,7 @@ import java.util.List;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.session.RowBounds;
public interface CeQueueMapper {
@@ -30,6 +31,10 @@ public interface CeQueueMapper {
List<CeQueueDto> selectAllInAscOrder();
+ List<CeQueueDto> selectByQueryInDescOrder(@Param("query") CeActivityQuery query, RowBounds rowBounds);
+
+ int countByQuery(@Param("query") CeActivityQuery query);
+
List<String> selectEligibleForPeek();
@CheckForNull
diff --git a/sonar-db/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml b/sonar-db/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml
index c19c97a0800..d86c8f73212 100644
--- a/sonar-db/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml
+++ b/sonar-db/src/main/resources/org/sonar/db/ce/CeActivityMapper.xml
@@ -47,7 +47,7 @@
select
<include refid="columns"/>
<include refid="sqlSelectByQuery" />
- order by ca.id desc
+ order by ca.submitted_at desc, ca.id desc
</select>
<select id="countByQuery" parameterType="map" resultType="int">
@@ -67,8 +67,11 @@
#{cUuid}
</foreach>
</if>
- <if test="query.status != null">
- and ca.status=#{query.status}
+ <if test="query.statuses != null and !query.statuses.isEmpty()">
+ and ca.status in
+ <foreach collection="query.statuses" open="(" close=")" item="status" separator=",">
+ #{status}
+ </foreach>
</if>
<if test="query.type != null">
and ca.task_type=#{query.type}
diff --git a/sonar-db/src/main/resources/org/sonar/db/ce/CeQueueMapper.xml b/sonar-db/src/main/resources/org/sonar/db/ce/CeQueueMapper.xml
index f43a9e9b30c..b00fadad36a 100644
--- a/sonar-db/src/main/resources/org/sonar/db/ce/CeQueueMapper.xml
+++ b/sonar-db/src/main/resources/org/sonar/db/ce/CeQueueMapper.xml
@@ -18,6 +18,10 @@
order by cq.created_at asc, cq.id asc
</sql>
+ <sql id="orderByDescDateAndId">
+ order by cq.created_at desc, cq.id asc
+ </sql>
+
<select id="selectByUuid" parameterType="String" resultType="org.sonar.db.ce.CeQueueDto">
select
<include refid="columns"/>
@@ -48,6 +52,42 @@
<include refid="orderByDateAndId"/>
</select>
+ <select id="selectByQueryInDescOrder" resultType="org.sonar.db.ce.CeQueueDto">
+ select
+ <include refid="columns"/>
+ <include refid="sqlSelectByQuery"/>
+ <include refid="orderByDescDateAndId"/>
+ </select>
+
+ <select id="countByQuery" resultType="int">
+ select count(id)
+ <include refid="sqlSelectByQuery"/>
+ </select>
+
+ <sql id="sqlSelectByQuery">
+ from ce_queue cq
+ <where>
+ <if test="query.componentUuids != null and query.componentUuids.size()>0">
+ and cq.component_uuid in
+ <foreach collection="query.componentUuids" open="(" close=")" item="cUuid" separator=",">
+ #{cUuid}
+ </foreach>
+ </if>
+ <if test="query.statuses != null">
+ and cq.status in
+ <foreach collection="query.statuses" open="(" close=")" item="status" separator=",">
+ #{status}
+ </foreach>
+ </if>
+ <if test="query.type != null">
+ and cq.task_type=#{query.type}
+ </if>
+ <if test="query.minSubmittedAt != null">
+ and cq.created_at &gt;= #{query.minSubmittedAt}
+ </if>
+ </where>
+ </sql>
+
<select id="selectEligibleForPeek" resultType="String">
select cq.uuid
from ce_queue cq
diff --git a/sonar-db/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java b/sonar-db/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java
index c1a15756f9b..cf726322310 100644
--- a/sonar-db/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java
+++ b/sonar-db/src/test/java/org/sonar/db/ce/CeActivityDaoTest.java
@@ -22,7 +22,6 @@ package org.sonar.db.ce;
import com.google.common.base.Optional;
import java.util.Collections;
import java.util.List;
-import org.apache.ibatis.session.RowBounds;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
@@ -30,6 +29,7 @@ import org.sonar.api.utils.internal.TestSystem2;
import org.sonar.db.DbTester;
import org.sonar.test.DbTests;
+import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.db.ce.CeTaskTypes.REPORT;
@@ -96,31 +96,31 @@ public class CeActivityDaoTest {
insert("TASK_4", "views", null, CeActivityDto.Status.SUCCESS);
// no filters
- CeActivityQuery query = new CeActivityQuery();
- List<CeActivityDto> dtos = underTest.selectByQuery(db.getSession(), query, new RowBounds(0, 10));
+ CeActivityQuery query = new CeActivityQuery().setStatuses(Collections.<String>emptyList());
+ List<CeActivityDto> dtos = underTest.selectByQuery(db.getSession(), query, 0, 10);
assertThat(dtos).extracting("uuid").containsExactly("TASK_4", "TASK_3", "TASK_2", "TASK_1");
// select by component uuid
query = new CeActivityQuery().setComponentUuid("PROJECT_1");
- dtos = underTest.selectByQuery(db.getSession(), query, new RowBounds(0, 10));
+ dtos = underTest.selectByQuery(db.getSession(), query, 0, 100);
assertThat(dtos).extracting("uuid").containsExactly("TASK_2", "TASK_1");
// select by status
- query = new CeActivityQuery().setStatus(CeActivityDto.Status.SUCCESS);
- dtos = underTest.selectByQuery(db.getSession(), query, new RowBounds(0, 10));
+ query = new CeActivityQuery().setStatuses(singletonList(CeActivityDto.Status.SUCCESS.name()));
+ dtos = underTest.selectByQuery(db.getSession(), query, 0, 100);
assertThat(dtos).extracting("uuid").containsExactly("TASK_4", "TASK_3", "TASK_1");
// select by type
query = new CeActivityQuery().setType(REPORT);
- dtos = underTest.selectByQuery(db.getSession(), query, new RowBounds(0, 10));
+ dtos = underTest.selectByQuery(db.getSession(), query, 0, 100);
assertThat(dtos).extracting("uuid").containsExactly("TASK_3", "TASK_2", "TASK_1");
query = new CeActivityQuery().setType("views");
- dtos = underTest.selectByQuery(db.getSession(), query, new RowBounds(0, 10));
+ dtos = underTest.selectByQuery(db.getSession(), query, 0, 100);
assertThat(dtos).extracting("uuid").containsExactly("TASK_4");
// select by multiple conditions
query = new CeActivityQuery().setType(REPORT).setOnlyCurrents(true).setComponentUuid("PROJECT_1");
- dtos = underTest.selectByQuery(db.getSession(), query, new RowBounds(0, 10));
+ dtos = underTest.selectByQuery(db.getSession(), query, 0, 100);
assertThat(dtos).extracting("uuid").containsExactly("TASK_2");
}
@@ -140,7 +140,7 @@ public class CeActivityDaoTest {
assertThat(underTest.countByQuery(db.getSession(), query)).isEqualTo(2);
// select by status
- query = new CeActivityQuery().setStatus(CeActivityDto.Status.SUCCESS);
+ query = new CeActivityQuery().setStatuses(singletonList(CeActivityDto.Status.SUCCESS.name()));
assertThat(underTest.countByQuery(db.getSession(), query)).isEqualTo(3);
// select by type
@@ -160,7 +160,7 @@ public class CeActivityDaoTest {
CeActivityQuery query = new CeActivityQuery();
query.setComponentUuids(Collections.<String>emptyList());
- assertThat(underTest.selectByQuery(db.getSession(), query, new RowBounds(0, 10))).isEmpty();
+ assertThat(underTest.selectByQuery(db.getSession(), query, 0, 0)).isEmpty();
}
@Test
@@ -179,19 +179,19 @@ public class CeActivityDaoTest {
// search by min submitted date
CeActivityQuery query = new CeActivityQuery().setMinSubmittedAt(1_455_000_000_000L);
- assertThat(underTest.selectByQuery(db.getSession(), query, new RowBounds(0, 10))).extracting("uuid").containsOnly("UUID2");
+ assertThat(underTest.selectByQuery(db.getSession(), query, 0, 5)).extracting("uuid").containsOnly("UUID2");
assertThat(underTest.countByQuery(db.getSession(), query)).isEqualTo(1);
// search by max executed date
query = new CeActivityQuery().setMaxExecutedAt(1_475_000_000_000L);
- assertThat(underTest.selectByQuery(db.getSession(), query, new RowBounds(0, 10))).extracting("uuid").containsOnly("UUID1");
+ assertThat(underTest.selectByQuery(db.getSession(), query, 0, 5)).extracting("uuid").containsOnly("UUID1");
assertThat(underTest.countByQuery(db.getSession(), query)).isEqualTo(1);
// search by both dates
query = new CeActivityQuery()
.setMinSubmittedAt(1_400_000_000_000L)
.setMaxExecutedAt(1_475_000_000_000L);
- assertThat(underTest.selectByQuery(db.getSession(), query, new RowBounds(0, 10))).extracting("uuid").containsOnly("UUID1");
+ assertThat(underTest.selectByQuery(db.getSession(), query, 0, 5)).extracting("uuid").containsOnly("UUID1");
assertThat(underTest.countByQuery(db.getSession(), query)).isEqualTo(1);
}
diff --git a/sonar-db/src/test/java/org/sonar/db/ce/CeQueueDaoTest.java b/sonar-db/src/test/java/org/sonar/db/ce/CeQueueDaoTest.java
index 247f735430e..943fbc14e52 100644
--- a/sonar-db/src/test/java/org/sonar/db/ce/CeQueueDaoTest.java
+++ b/sonar-db/src/test/java/org/sonar/db/ce/CeQueueDaoTest.java
@@ -20,15 +20,20 @@
package org.sonar.db.ce;
import com.google.common.base.Optional;
+import java.util.List;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
+import org.sonar.api.utils.Paging;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.internal.TestSystem2;
import org.sonar.db.DbTester;
import org.sonar.test.DbTests;
+import static com.google.common.collect.Lists.newArrayList;
+import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.db.ce.CeQueueTesting.newCeQueueDto;
@Category(DbTests.class)
public class CeQueueDaoTest {
@@ -169,6 +174,61 @@ public class CeQueueDaoTest {
assertThat(peek.get().getUuid()).isEqualTo("TASK_2");
}
+ @Test
+ public void select_by_query() {
+ // task status not in query
+ insert(newCeQueueDto("TASK_1")
+ .setComponentUuid("PROJECT_1")
+ .setStatus(CeQueueDto.Status.IN_PROGRESS)
+ .setTaskType(CeTaskTypes.REPORT)
+ .setCreatedAt(100_000L));
+
+ // too early
+ insert(newCeQueueDto("TASK_3")
+ .setComponentUuid("PROJECT_1")
+ .setStatus(CeQueueDto.Status.PENDING)
+ .setTaskType(CeTaskTypes.REPORT)
+ .setCreatedAt(90_000L));
+
+ // task type not in query
+ insert(newCeQueueDto("TASK_4")
+ .setComponentUuid("PROJECT_2")
+ .setStatus(CeQueueDto.Status.PENDING)
+ .setTaskType("ANOTHER_TYPE")
+ .setCreatedAt(100_000L));
+
+ // correct
+ insert(newCeQueueDto("TASK_2")
+ .setComponentUuid("PROJECT_1")
+ .setStatus(CeQueueDto.Status.PENDING)
+ .setTaskType(CeTaskTypes.REPORT)
+ .setCreatedAt(100_000L));
+
+ // correct submitted later
+ insert(newCeQueueDto("TASK_5")
+ .setComponentUuid("PROJECT_1")
+ .setStatus(CeQueueDto.Status.PENDING)
+ .setTaskType(CeTaskTypes.REPORT)
+ .setCreatedAt(120_000L));
+
+ CeActivityQuery query = new CeActivityQuery()
+ .setComponentUuids(newArrayList("PROJECT_1", "PROJECT_2"))
+ .setStatuses(singletonList(CeQueueDto.Status.PENDING.name()))
+ .setType(CeTaskTypes.REPORT)
+ .setMinSubmittedAt(100_000L);
+
+ List<CeQueueDto> result = underTest.selectByQueryInDescOrder(db.getSession(), query, Paging.forPageIndex(1).withPageSize(1_000).andTotal(1_000));
+ int total = underTest.countByQuery(db.getSession(), query);
+
+ assertThat(result).extracting("uuid").containsExactly("TASK_5", "TASK_2");
+ assertThat(total).isEqualTo(2);
+ }
+
+ private void insert(CeQueueDto dto) {
+ underTest.insert(db.getSession(), dto);
+ db.commit();
+ }
+
private void insert(String uuid, String componentUuid, CeQueueDto.Status status) {
CeQueueDto dto = new CeQueueDto();
dto.setUuid(uuid);
@@ -177,6 +237,6 @@ public class CeQueueDaoTest {
dto.setStatus(status);
dto.setSubmitterLogin("henri");
underTest.insert(db.getSession(), dto);
- db.getSession().commit();
+ db.commit();
}
}
diff --git a/sonar-db/src/test/java/org/sonar/db/ce/CeQueueTesting.java b/sonar-db/src/test/java/org/sonar/db/ce/CeQueueTesting.java
index 7e8974421ba..0f0a7564018 100644
--- a/sonar-db/src/test/java/org/sonar/db/ce/CeQueueTesting.java
+++ b/sonar-db/src/test/java/org/sonar/db/ce/CeQueueTesting.java
@@ -38,4 +38,6 @@ public class CeQueueTesting {
.setUpdatedAt(nextLong())
.setStartedAt(nextLong());
}
+
+
}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/HttpWsClient.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/HttpWsClient.java
index 664960aec8d..abec779c8c5 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/HttpWsClient.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/HttpWsClient.java
@@ -19,6 +19,7 @@
*/
package org.sonarqube.ws.client;
+import org.sonarqube.ws.client.ce.CeService;
import org.sonarqube.ws.client.component.ComponentsService;
import org.sonarqube.ws.client.issue.IssuesService;
import org.sonarqube.ws.client.measure.MeasuresService;
@@ -35,6 +36,7 @@ import org.sonarqube.ws.client.usertoken.UserTokensService;
*/
public class HttpWsClient implements WsClient {
+ private final WsConnector wsConnector;
private final PermissionsService permissionsService;
private final ComponentsService componentsService;
private final QualityProfilesService qualityProfilesService;
@@ -43,7 +45,7 @@ public class HttpWsClient implements WsClient {
private final QualityGatesService qualityGatesService;
private final MeasuresService measuresService;
private final SystemService systemService;
- private final WsConnector wsConnector;
+ private final CeService ceService;
public HttpWsClient(WsConnector wsConnector) {
this.wsConnector = wsConnector;
@@ -55,6 +57,7 @@ public class HttpWsClient implements WsClient {
this.qualityGatesService = new QualityGatesService(wsConnector);
this.measuresService = new MeasuresService(wsConnector);
this.systemService = new SystemService(wsConnector);
+ this.ceService = new CeService(wsConnector);
}
@Override
@@ -101,4 +104,9 @@ public class HttpWsClient implements WsClient {
public SystemService system() {
return systemService;
}
+
+ @Override
+ public CeService ce() {
+ return ceService;
+ }
}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/WsClient.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/WsClient.java
index db7ab7ba245..7f865292fc7 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/WsClient.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/WsClient.java
@@ -19,6 +19,7 @@
*/
package org.sonarqube.ws.client;
+import org.sonarqube.ws.client.ce.CeService;
import org.sonarqube.ws.client.component.ComponentsService;
import org.sonarqube.ws.client.issue.IssuesService;
import org.sonarqube.ws.client.measure.MeasuresService;
@@ -48,5 +49,7 @@ public interface WsClient {
SystemService system();
+ CeService ce();
+
WsConnector wsConnector();
}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/ce/ActivityWsRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/ce/ActivityWsRequest.java
new file mode 100644
index 00000000000..a0e53ace029
--- /dev/null
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/ce/ActivityWsRequest.java
@@ -0,0 +1,127 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.sonarqube.ws.client.ce;
+
+import java.util.List;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+public class ActivityWsRequest {
+ private String componentId;
+ private String componentQuery;
+ private List<String> status;
+ private String type;
+ private Boolean onlyCurrents;
+ private String minSubmittedAt;
+ private String maxExecutedAt;
+ private Integer page;
+ private Integer pageSize;
+
+ @CheckForNull
+ public String getComponentId() {
+ return componentId;
+ }
+
+ public ActivityWsRequest setComponentId(@Nullable String componentId) {
+ this.componentId = componentId;
+ return this;
+ }
+
+ @CheckForNull
+ public String getComponentQuery() {
+ return componentQuery;
+ }
+
+ public ActivityWsRequest setComponentQuery(@Nullable String componentQuery) {
+ this.componentQuery = componentQuery;
+ return this;
+ }
+
+ @CheckForNull
+ public List<String> getStatus() {
+ return status;
+ }
+
+ public ActivityWsRequest setStatus(@Nullable List<String> status) {
+ this.status = status;
+ return this;
+ }
+
+ @CheckForNull
+ public String getType() {
+ return type;
+ }
+
+ public ActivityWsRequest setType(@Nullable String type) {
+ this.type = type;
+ return this;
+ }
+
+ @CheckForNull
+ public Boolean getOnlyCurrents() {
+ return onlyCurrents;
+ }
+
+ public ActivityWsRequest setOnlyCurrents(@Nullable Boolean onlyCurrents) {
+ this.onlyCurrents = onlyCurrents;
+ return this;
+ }
+
+ @CheckForNull
+ public String getMinSubmittedAt() {
+ return minSubmittedAt;
+ }
+
+ public ActivityWsRequest setMinSubmittedAt(@Nullable String minSubmittedAt) {
+ this.minSubmittedAt = minSubmittedAt;
+ return this;
+ }
+
+ @CheckForNull
+ public String getMaxExecutedAt() {
+ return maxExecutedAt;
+ }
+
+ public ActivityWsRequest setMaxExecutedAt(@Nullable String maxExecutedAt) {
+ this.maxExecutedAt = maxExecutedAt;
+ return this;
+ }
+
+ @CheckForNull
+ public Integer getPage() {
+ return page;
+ }
+
+ public ActivityWsRequest setPage(@Nullable Integer page) {
+ this.page = page;
+ return this;
+ }
+
+ @CheckForNull
+ public Integer getPageSize() {
+ return pageSize;
+ }
+
+ public ActivityWsRequest setPageSize(@Nullable Integer pageSize) {
+ this.pageSize = pageSize;
+ return this;
+ }
+}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/ce/CeService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/ce/CeService.java
new file mode 100644
index 00000000000..b11cfdfb60e
--- /dev/null
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/ce/CeService.java
@@ -0,0 +1,57 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.sonarqube.ws.client.ce;
+
+import org.sonarqube.ws.WsCe.ActivityResponse;
+import org.sonarqube.ws.client.BaseService;
+import org.sonarqube.ws.client.GetRequest;
+import org.sonarqube.ws.client.WsConnector;
+
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_ID;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_QUERY;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_MAX_EXECUTED_AT;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_MIN_SUBMITTED_AT;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_ONLY_CURRENTS;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_STATUS;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_TYPE;
+
+public class CeService extends BaseService {
+
+ public CeService(WsConnector wsConnector) {
+ super(wsConnector, "api/ce");
+ }
+
+ public ActivityResponse activity(ActivityWsRequest request) {
+ return call(
+ new GetRequest(path("activity"))
+ .setParam(PARAM_COMPONENT_ID, request.getComponentId())
+ .setParam(PARAM_COMPONENT_QUERY, request.getComponentQuery())
+ .setParam(PARAM_STATUS, inlineMultipleParamValue(request.getStatus()))
+ .setParam(PARAM_TYPE, request.getType())
+ .setParam(PARAM_MAX_EXECUTED_AT, request.getMaxExecutedAt())
+ .setParam(PARAM_MIN_SUBMITTED_AT, request.getMinSubmittedAt())
+ .setParam(PARAM_ONLY_CURRENTS, request.getOnlyCurrents())
+ .setParam("p", request.getPage())
+ .setParam("ps", request.getPageSize()),
+ ActivityResponse.parser());
+ }
+
+}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/ce/CeWsParameters.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/ce/CeWsParameters.java
new file mode 100644
index 00000000000..3b4fc97e4f1
--- /dev/null
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/ce/CeWsParameters.java
@@ -0,0 +1,35 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.sonarqube.ws.client.ce;
+
+public class CeWsParameters {
+ public static final String PARAM_COMPONENT_ID = "componentId";
+ public static final String PARAM_COMPONENT_QUERY = "componentQuery";
+ public static final String PARAM_TYPE = "type";
+ public static final String PARAM_STATUS = "status";
+ public static final String PARAM_ONLY_CURRENTS = "onlyCurrents";
+ public static final String PARAM_MIN_SUBMITTED_AT = "minSubmittedAt";
+ public static final String PARAM_MAX_EXECUTED_AT = "maxExecutedAt";
+
+ private CeWsParameters() {
+ // prevent instantiation
+ }
+}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/ce/package-info.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/ce/package-info.java
new file mode 100644
index 00000000000..46846e51219
--- /dev/null
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/ce/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+@ParametersAreNonnullByDefault
+package org.sonarqube.ws.client.ce;
+
+import javax.annotation.ParametersAreNonnullByDefault;
+
diff --git a/sonar-ws/src/test/java/org/sonarqube/ws/client/ce/CeServiceTest.java b/sonar-ws/src/test/java/org/sonarqube/ws/client/ce/CeServiceTest.java
new file mode 100644
index 00000000000..d7094f75495
--- /dev/null
+++ b/sonar-ws/src/test/java/org/sonarqube/ws/client/ce/CeServiceTest.java
@@ -0,0 +1,90 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.sonarqube.ws.client.ce;
+
+import com.google.common.collect.ImmutableList;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonarqube.ws.WsCe.ActivityResponse;
+import org.sonarqube.ws.client.GetRequest;
+import org.sonarqube.ws.client.ServiceTester;
+import org.sonarqube.ws.client.WsConnector;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_ID;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_QUERY;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_MAX_EXECUTED_AT;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_MIN_SUBMITTED_AT;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_ONLY_CURRENTS;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_STATUS;
+import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_TYPE;
+
+public class CeServiceTest {
+ private static final String VALUE_COMPONENT_ID = "component-uuid";
+ private static final String VALUE_COMPONENT_QUERY = "component-query";
+ private static final String VALUE_TASK_STATUS_1 = "task-status";
+ private static final String VALUE_TASK_STATUS_2 = "task-status-2";
+ private static final String VALUE_TASK_TYPE = "task-type";
+ private static final int VALUE_PAGE = 1;
+ private static final int VALUE_PAGE_SIZE = 10;
+ private static final String VALUE_MAX_EXECUTED_AT = "2015-09-17T23:34:59+0200";
+ private static final String VALUE_MIN_SUBMITTED_AT = "2015-09-17T23:34:59+0200";
+ private static final boolean VALUE_ONLY_CURRENTS = true;
+
+ @Rule
+ public ServiceTester<CeService> serviceTester = new ServiceTester<>(new CeService(mock(WsConnector.class)));
+
+ CeService underTest = serviceTester.getInstanceUnderTest();
+
+ @Test
+ public void search() {
+ ActivityWsRequest request = new ActivityWsRequest()
+ .setComponentId(VALUE_COMPONENT_ID)
+ .setComponentQuery(VALUE_COMPONENT_QUERY)
+ .setStatus(ImmutableList.of(VALUE_TASK_STATUS_1, VALUE_TASK_STATUS_2))
+ .setType(VALUE_TASK_TYPE)
+ .setPage(VALUE_PAGE)
+ .setPageSize(VALUE_PAGE_SIZE)
+ .setMaxExecutedAt(VALUE_MAX_EXECUTED_AT)
+ .setMinSubmittedAt(VALUE_MIN_SUBMITTED_AT)
+ .setOnlyCurrents(VALUE_ONLY_CURRENTS)
+ .setPage(1)
+ .setPageSize(1);
+
+ underTest.activity(request);
+ GetRequest result = serviceTester.getGetRequest();
+
+ assertThat(serviceTester.getGetParser()).isSameAs(ActivityResponse.parser());
+ serviceTester.assertThat(result)
+ .hasPath("activity")
+ .hasParam(PARAM_COMPONENT_ID, VALUE_COMPONENT_ID)
+ .hasParam(PARAM_COMPONENT_QUERY, VALUE_COMPONENT_QUERY)
+ .hasParam(PARAM_STATUS, VALUE_TASK_STATUS_1 + "," + VALUE_TASK_STATUS_2)
+ .hasParam(PARAM_TYPE, VALUE_TASK_TYPE)
+ .hasParam(PARAM_MAX_EXECUTED_AT, VALUE_MAX_EXECUTED_AT)
+ .hasParam(PARAM_MIN_SUBMITTED_AT, VALUE_MIN_SUBMITTED_AT)
+ .hasParam(PARAM_ONLY_CURRENTS, VALUE_ONLY_CURRENTS)
+ .hasParam("p", 1)
+ .hasParam("ps", 1)
+ .andNoOtherParam();
+ }
+}
diff --git a/sonar-ws/src/test/java/org/sonarqube/ws/client/issue/SearchWsRequestTest.java b/sonar-ws/src/test/java/org/sonarqube/ws/client/issue/ActivityWsRequestTest.java
index 9fc4bac7ccd..c8115e322d0 100644
--- a/sonar-ws/src/test/java/org/sonarqube/ws/client/issue/SearchWsRequestTest.java
+++ b/sonar-ws/src/test/java/org/sonarqube/ws/client/issue/ActivityWsRequestTest.java
@@ -24,7 +24,7 @@ import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
-public class SearchWsRequestTest {
+public class ActivityWsRequestTest {
private static final ImmutableList<String> LIST_OF_STRINGS = ImmutableList.of("A", "B");
private static final String SOME_STRING = "some string";
public static final int SOME_INT = 894352;