aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2018-04-18 18:26:08 +0200
committerSonarTech <sonartech@sonarsource.com>2018-05-10 20:20:53 +0200
commitbaa5c72513957ca1600d10f2508378239c52bf29 (patch)
tree3a1e9e9fc5b893684b5ba2d026bc960b708de564
parentaf37124fb9fc67d55fe76bb648dbb435227aacf6 (diff)
downloadsonarqube-baa5c72513957ca1600d10f2508378239c52bf29.tar.gz
sonarqube-baa5c72513957ca1600d10f2508378239c52bf29.zip
SONAR-10592 add WS api/ce/pause and api/ce/resume
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/ce/ws/CeWsModule.java3
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/ce/ws/PauseAction.java61
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/ce/ws/ResumeAction.java61
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/ce/ws/CeWsModuleTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/ce/ws/PauseActionTest.java99
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/ce/ws/ResumeActionTest.java99
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/ce/CeService.java25
7 files changed, 348 insertions, 2 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/CeWsModule.java b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/CeWsModule.java
index c83157dc1dd..ac415b72a75 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/CeWsModule.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/CeWsModule.java
@@ -33,7 +33,8 @@ public class CeWsModule extends Module {
ComponentAction.class,
InfoAction.class,
IsQueueEmptyWs.class,
- ComponentAction.class,
+ PauseAction.class,
+ ResumeAction.class,
SubmitAction.class,
TaskFormatter.class,
TaskAction.class,
diff --git a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/PauseAction.java b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/PauseAction.java
new file mode 100644
index 00000000000..e725b817715
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/PauseAction.java
@@ -0,0 +1,61 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.ce.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.ce.queue.CeQueue;
+import org.sonar.server.user.AbstractUserSession;
+import org.sonar.server.user.SystemPasscode;
+import org.sonar.server.user.SystemPasscodeImpl;
+import org.sonar.server.user.UserSession;
+
+public class PauseAction implements CeWsAction {
+
+ private final UserSession userSession;
+ private final SystemPasscode systemPasscode;
+ private final CeQueue ceQueue;
+
+ public PauseAction(UserSession userSession, SystemPasscode systemPasscode, CeQueue ceQueue) {
+ this.userSession = userSession;
+ this.systemPasscode = systemPasscode;
+ this.ceQueue = ceQueue;
+ }
+
+ @Override
+ public void define(WebService.NewController controller) {
+ controller.createAction("pause")
+ .setDescription("Requests pause of Compute Engine workers. Requires the system administration permission or " +
+ "system passcode (see " + SystemPasscodeImpl.PASSCODE_CONF_PROPERTY + " in sonar.properties).")
+ .setSince("7.2")
+ .setHandler(this)
+ .setPost(true);
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ if (!userSession.isSystemAdministrator() && !systemPasscode.isValid(request)) {
+ throw AbstractUserSession.insufficientPrivilegesException();
+ }
+
+ ceQueue.pauseWorkers();
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ResumeAction.java b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ResumeAction.java
new file mode 100644
index 00000000000..3be2b45e512
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/ResumeAction.java
@@ -0,0 +1,61 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.ce.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.ce.queue.CeQueue;
+import org.sonar.server.user.AbstractUserSession;
+import org.sonar.server.user.SystemPasscode;
+import org.sonar.server.user.SystemPasscodeImpl;
+import org.sonar.server.user.UserSession;
+
+public class ResumeAction implements CeWsAction {
+
+ private final UserSession userSession;
+ private final SystemPasscode systemPasscode;
+ private final CeQueue ceQueue;
+
+ public ResumeAction(UserSession userSession, SystemPasscode systemPasscode, CeQueue ceQueue) {
+ this.userSession = userSession;
+ this.systemPasscode = systemPasscode;
+ this.ceQueue = ceQueue;
+ }
+
+ @Override
+ public void define(WebService.NewController controller) {
+ controller.createAction("resume")
+ .setDescription("Resumes pause of Compute Engine workers. Requires the system administration permission or " +
+ "system passcode (see " + SystemPasscodeImpl.PASSCODE_CONF_PROPERTY + " in sonar.properties).")
+ .setSince("7.2")
+ .setHandler(this)
+ .setPost(true);
+ }
+
+ @Override
+ public void handle(Request request, Response response) throws Exception {
+ if (!userSession.isSystemAdministrator() && !systemPasscode.isValid(request)) {
+ throw AbstractUserSession.insufficientPrivilegesException();
+ }
+
+ ceQueue.resumeWorkers();
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/CeWsModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/CeWsModuleTest.java
index e1d039f9f90..a16e0b554fa 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/CeWsModuleTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/CeWsModuleTest.java
@@ -31,6 +31,6 @@ public class CeWsModuleTest {
public void verify_count_of_added_components() {
ComponentContainer container = new ComponentContainer();
new CeWsModule().configure(container);
- assertThat(container.size()).isEqualTo(13 + COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER);
+ assertThat(container.size()).isEqualTo(15 + COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER);
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/PauseActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/PauseActionTest.java
new file mode 100644
index 00000000000..f7405267870
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/PauseActionTest.java
@@ -0,0 +1,99 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.ce.ws;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.ce.queue.CeQueue;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.user.SystemPasscode;
+import org.sonar.server.ws.WsActionTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class PauseActionTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+ @Rule
+ public UserSessionRule userSession = UserSessionRule.standalone();
+
+ private SystemPasscode passcode = mock(SystemPasscode.class);
+ private CeQueue ceQueue = mock(CeQueue.class);
+ private PauseAction underTest = new PauseAction(userSession, passcode, ceQueue);
+ private WsActionTester ws = new WsActionTester(underTest);
+
+ @Test
+ public void test_definition() {
+ WebService.Action def = ws.getDef();
+ assertThat(def.key()).isEqualTo("pause");
+ assertThat(def.isInternal()).isFalse();
+ assertThat(def.isPost()).isTrue();
+ assertThat(def.params()).isEmpty();
+ assertThat(def.responseExampleAsString()).isNull();
+ }
+
+ @Test
+ public void pause_workers() {
+ userSession.logIn().setSystemAdministrator();
+
+ ws.newRequest().execute();
+
+ verify(ceQueue).pauseWorkers();
+ }
+
+ @Test
+ public void throw_ForbiddenException_if_not_system_administrator() {
+ userSession.logIn().setNonSystemAdministrator();
+
+ expectedException.expect(ForbiddenException.class);
+ expectedException.expectMessage("Insufficient privileges");
+
+ ws.newRequest().execute();
+ }
+
+ @Test
+ public void throw_ForbiddenException_if_invalid_passcode() {
+ userSession.anonymous();
+ when(passcode.isValid(any())).thenReturn(false);
+
+ expectedException.expect(ForbiddenException.class);
+ expectedException.expectMessage("Insufficient privileges");
+
+ ws.newRequest().execute();
+ }
+
+ @Test
+ public void authenticate_with_passcode() {
+ userSession.anonymous();
+ when(passcode.isValid(any())).thenReturn(true);
+
+ ws.newRequest().execute();
+
+ verify(ceQueue).pauseWorkers();
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/ResumeActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/ResumeActionTest.java
new file mode 100644
index 00000000000..733b28c043c
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/ResumeActionTest.java
@@ -0,0 +1,99 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.ce.ws;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.ce.queue.CeQueue;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.user.SystemPasscode;
+import org.sonar.server.ws.WsActionTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class ResumeActionTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+ @Rule
+ public UserSessionRule userSession = UserSessionRule.standalone();
+
+ private SystemPasscode passcode = mock(SystemPasscode.class);
+ private CeQueue ceQueue = mock(CeQueue.class);
+ private ResumeAction underTest = new ResumeAction(userSession, passcode, ceQueue);
+ private WsActionTester ws = new WsActionTester(underTest);
+
+ @Test
+ public void test_definition() {
+ WebService.Action def = ws.getDef();
+ assertThat(def.key()).isEqualTo("resume");
+ assertThat(def.isInternal()).isFalse();
+ assertThat(def.isPost()).isTrue();
+ assertThat(def.params()).isEmpty();
+ assertThat(def.responseExampleAsString()).isNull();
+ }
+
+ @Test
+ public void resume_workers() {
+ userSession.logIn().setSystemAdministrator();
+
+ ws.newRequest().execute();
+
+ verify(ceQueue).resumeWorkers();
+ }
+
+ @Test
+ public void throw_ForbiddenException_if_not_system_administrator() {
+ userSession.logIn().setNonSystemAdministrator();
+
+ expectedException.expect(ForbiddenException.class);
+ expectedException.expectMessage("Insufficient privileges");
+
+ ws.newRequest().execute();
+ }
+
+ @Test
+ public void throw_ForbiddenException_if_invalid_passcode() {
+ userSession.anonymous();
+ when(passcode.isValid(any())).thenReturn(false);
+
+ expectedException.expect(ForbiddenException.class);
+ expectedException.expectMessage("Insufficient privileges");
+
+ ws.newRequest().execute();
+ }
+
+ @Test
+ public void authenticate_with_passcode() {
+ userSession.anonymous();
+ when(passcode.isValid(any())).thenReturn(true);
+
+ ws.newRequest().execute();
+
+ verify(ceQueue).resumeWorkers();
+ }
+}
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
index aa49783c8cc..c02981e25f0 100644
--- 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
@@ -128,6 +128,7 @@ public class CeService extends BaseService {
}
/**
+ *
* This is a GET request.
* @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/ce/info">Further information about this action online (including a response example)</a>
* @since 7.2
@@ -139,6 +140,30 @@ public class CeService extends BaseService {
}
/**
+ * This is a POST request.
+ * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/ce/pause">Further information about this action online (including a response example)</a>
+ * @since 7.2
+ */
+ public void pause() {
+ call(
+ new PostRequest(path("pause"))
+ .setMediaType(MediaTypes.JSON)
+ ).content();
+ }
+
+ /**
+ * This is a POST request.
+ * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/ce/resume">Further information about this action online (including a response example)</a>
+ * @since 7.2
+ */
+ public void resume() {
+ call(
+ new PostRequest(path("resume"))
+ .setMediaType(MediaTypes.JSON)
+ ).content();
+ }
+
+ /**
*
* This is part of the internal API.
* This is a POST request.