aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-webserver-webapi
diff options
context:
space:
mode:
authoralain <108417558+alain-kermis-sonarsource@users.noreply.github.com>2022-10-27 14:08:20 +0200
committersonartech <sonartech@sonarsource.com>2022-10-27 20:03:02 +0000
commit83bd18d97d9d8e0b858875b253bc52efff70e810 (patch)
tree6984dfa8964d739eafa615aa9434cb933a899f3e /server/sonar-webserver-webapi
parent0806043b590e1d0f3bf08c4d88627dc9bb6cf913 (diff)
downloadsonarqube-83bd18d97d9d8e0b858875b253bc52efff70e810.tar.gz
sonarqube-83bd18d97d9d8e0b858875b253bc52efff70e810.zip
SONAR-17497 Add web service to reindex issues
Diffstat (limited to 'server/sonar-webserver-webapi')
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/IssueWsModule.java1
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/ReindexAction.java87
-rw-r--r--server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/ReindexActionTest.java113
3 files changed, 201 insertions, 0 deletions
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/IssueWsModule.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/IssueWsModule.java
index 37b3a53adbb..6bf37943b81 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/IssueWsModule.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/IssueWsModule.java
@@ -67,6 +67,7 @@ public class IssueWsModule extends Module {
SetTagsAction.class,
SetTypeAction.class,
ComponentTagsAction.class,
+ ReindexAction.class,
AuthorsAction.class,
ChangelogAction.class,
BulkChangeAction.class,
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/ReindexAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/ReindexAction.java
new file mode 100644
index 00000000000..2d2a2618528
--- /dev/null
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/ReindexAction.java
@@ -0,0 +1,87 @@
+/*
+ * 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.issue.ws;
+
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.web.UserRole;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.project.ProjectDto;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.issue.index.IssueIndexer;
+import org.sonar.server.user.UserSession;
+
+import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
+import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECT;
+
+/**
+ * Implementation of the {@code reindex} action for the Issues WebService.
+ */
+public class ReindexAction implements IssuesWsAction {
+
+ private static final String ACTION = "reindex";
+ private final DbClient dbClient;
+ private final IssueIndexer issueIndexer;
+ private final UserSession userSession;
+
+ public ReindexAction(DbClient dbClient, IssueIndexer indexer, UserSession userSession) {
+ this.dbClient = dbClient;
+ this.issueIndexer = indexer;
+ this.userSession = userSession;
+ }
+
+ @Override
+ public void define(WebService.NewController context) {
+ WebService.NewAction action = context
+ .createAction(ACTION)
+ .setPost(true)
+ .setDescription("Reindex issues for a project.<br> " +
+ "Requires one of the following permissions: " +
+ "<ul>" +
+ "<li>'Administer System'</li>" +
+ "<li>'Administer' rights on the specified project</li>" +
+ "</ul>")
+ .setSince("9.8")
+ .setHandler(this);
+
+ action
+ .createParam(PARAM_PROJECT)
+ .setDescription("Project key")
+ .setRequired(true)
+ .setExampleValue(KEY_PROJECT_EXAMPLE_001);
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ String projectKey = request.mandatoryParam(PARAM_PROJECT);
+
+ ProjectDto projectDto;
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ projectDto = dbClient.projectDao().selectProjectByKey(dbSession, projectKey).orElseThrow(() -> new NotFoundException("project not found"));
+ userSession.checkProjectPermission(UserRole.ADMIN, projectDto);
+ }
+
+ issueIndexer.indexProject(projectDto.getUuid());
+ response.noContent();
+ }
+
+}
diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/ReindexActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/ReindexActionTest.java
new file mode 100644
index 00000000000..fb18d387348
--- /dev/null
+++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/issue/ws/ReindexActionTest.java
@@ -0,0 +1,113 @@
+/*
+ * 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.issue.ws;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.web.UserRole;
+import org.sonar.db.DbTester;
+import org.sonar.db.project.ProjectDto;
+import org.sonar.server.es.EsTester;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.issue.index.AsyncIssueIndexing;
+import org.sonar.server.issue.index.IssueIndexer;
+import org.sonar.server.issue.index.IssueIteratorFactory;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.TestRequest;
+import org.sonar.server.ws.TestResponse;
+import org.sonar.server.ws.WsActionTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+public class ReindexActionTest {
+
+ @Rule
+ public EsTester es = EsTester.create();
+ @Rule
+ public DbTester db = DbTester.create();
+ @Rule
+ public UserSessionRule userSession = UserSessionRule.standalone();
+
+ private final AsyncIssueIndexing mock = mock(AsyncIssueIndexing.class);
+ private final IssueIndexer issueIndexer = new IssueIndexer(es.client(), db.getDbClient(), new IssueIteratorFactory(db.getDbClient()), mock);
+ private final ReindexAction underTest = new ReindexAction(db.getDbClient(), issueIndexer, userSession);
+ private final WsActionTester tester = new WsActionTester(underTest);
+
+ @Test
+ public void test_definition() {
+ WebService.Action action = tester.getDef();
+
+ assertThat(action.key()).isEqualTo("reindex");
+ assertThat(action.isPost()).isTrue();
+ assertThat(action.isInternal()).isFalse();
+ assertThat(action.params()).extracting(WebService.Param::key).containsExactly("project");
+ }
+
+ @Test
+ public void reindex_project() {
+ ProjectDto project = db.components().insertPrivateProjectDto();
+ userSession.logIn().setSystemAdministrator();
+ userSession.addProjectPermission(UserRole.ADMIN, project);
+
+ TestResponse response = tester.newRequest()
+ .setParam("project", project.getKey())
+ .execute();
+
+ assertThat(response.getStatus()).isEqualTo(204);
+ verify(mock, times(1)).triggerForProject(project.getUuid());
+ }
+
+ @Test
+ public void fail_if_project_does_not_exist() {
+ userSession.logIn().setSystemAdministrator();
+
+ TestRequest testRequest = tester.newRequest().setParam("project", "some-key");
+ assertThatThrownBy(testRequest::execute)
+ .isInstanceOf(NotFoundException.class)
+ .hasMessage("project not found");
+ }
+
+ @Test
+ public void fail_if_parameter_not_present() {
+ userSession.anonymous();
+ TestRequest testRequest = tester.newRequest();
+ assertThatThrownBy(testRequest::execute)
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("The 'project' parameter is missing");
+ }
+
+ @Test
+ public void fail_if_not_authorized() {
+ ProjectDto project = db.components().insertPrivateProjectDto();
+ userSession.addProjectPermission(UserRole.USER, project);
+
+ TestRequest testRequest = tester.newRequest().setParam("project", project.getKey());
+ assertThatThrownBy(testRequest::execute)
+ .isInstanceOf(ForbiddenException.class)
+ .hasMessage("Insufficient privileges");
+ }
+
+}