]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10592 new WS api/ce/info
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Wed, 18 Apr 2018 15:57:55 +0000 (17:57 +0200)
committerSonarTech <sonartech@sonarsource.com>
Thu, 10 May 2018 18:20:53 +0000 (20:20 +0200)
server/sonar-server/src/main/java/org/sonar/server/ce/ws/CeWsModule.java
server/sonar-server/src/main/java/org/sonar/server/ce/ws/InfoAction.java [new file with mode: 0644]
server/sonar-server/src/main/resources/org/sonar/server/ce/ws/info-example.json [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/ce/ws/CeWsModuleTest.java
server/sonar-server/src/test/java/org/sonar/server/ce/ws/InfoActionTest.java [new file with mode: 0644]
sonar-ws/src/main/java/org/sonarqube/ws/client/ce/CeService.java
sonar-ws/src/main/protobuf/ws-ce.proto

index 63fd305ae745f885bc2bd9039ca00abb7251e373..c83157dc1ddf03541cee27c712ed0ab9bc0f84e0 100644 (file)
@@ -30,6 +30,8 @@ public class CeWsModule extends Module {
       ActivityStatusAction.class,
       CancelAction.class,
       CancelAllAction.class,
+      ComponentAction.class,
+      InfoAction.class,
       IsQueueEmptyWs.class,
       ComponentAction.class,
       SubmitAction.class,
diff --git a/server/sonar-server/src/main/java/org/sonar/server/ce/ws/InfoAction.java b/server/sonar-server/src/main/java/org/sonar/server/ce/ws/InfoAction.java
new file mode 100644 (file)
index 0000000..fc30d4d
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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 java.util.Optional;
+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;
+import org.sonar.server.ws.WsUtils;
+import org.sonarqube.ws.Ce;
+
+public class InfoAction implements CeWsAction {
+
+  private final UserSession userSession;
+  private final SystemPasscode systemPasscode;
+  private final CeQueue ceQueue;
+
+  public InfoAction(UserSession userSession, SystemPasscode systemPasscode, CeQueue ceQueue) {
+    this.userSession = userSession;
+    this.systemPasscode = systemPasscode;
+    this.ceQueue = ceQueue;
+  }
+
+  @Override
+  public void define(WebService.NewController controller) {
+    controller.createAction("info")
+      .setDescription("Gets information about Compute Engine. Requires the system administration permission or " +
+        "system passcode (see " + SystemPasscodeImpl.PASSCODE_CONF_PROPERTY + " in sonar.properties).")
+      .setSince("7.2")
+      .setHandler(this)
+      .setResponseExample(getClass().getResource("info-example.json"));
+  }
+
+  @Override
+  public void handle(Request request, Response response) throws Exception {
+    if (!userSession.isSystemAdministrator() && !systemPasscode.isValid(request)) {
+      throw AbstractUserSession.insufficientPrivilegesException();
+    }
+
+    Ce.InfoWsResponse.Builder builder = Ce.InfoWsResponse.newBuilder();
+    Optional<CeQueue.WorkersPause> pause = ceQueue.getWorkersPause();
+    builder.setWorkersPaused(isPaused(pause));
+    builder.setWorkersPauseRequested(isPauseRequested(pause));
+    WsUtils.writeProtobuf(builder.build(), request, response);
+  }
+
+  private static boolean isPaused(Optional<CeQueue.WorkersPause> pause) {
+    return pause.isPresent() && pause.get() == CeQueue.WorkersPause.PAUSED;
+  }
+
+  private static boolean isPauseRequested(Optional<CeQueue.WorkersPause> pause) {
+    return pause.isPresent() && pause.get() == CeQueue.WorkersPause.PAUSING;
+  }
+}
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/ce/ws/info-example.json b/server/sonar-server/src/main/resources/org/sonar/server/ce/ws/info-example.json
new file mode 100644 (file)
index 0000000..f1c8aec
--- /dev/null
@@ -0,0 +1,4 @@
+{
+  "workersPaused": false,
+  "workersPauseRequested": true
+}
index 76caf43dc7286b24fb999b4df06bbb9013056476..e1d039f9f909be9875a8b1adc3849f3d3d5ec06d 100644 (file)
@@ -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(12 + COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER);
+    assertThat(container.size()).isEqualTo(13 + COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER);
   }
 }
diff --git a/server/sonar-server/src/test/java/org/sonar/server/ce/ws/InfoActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/ce/ws/InfoActionTest.java
new file mode 100644 (file)
index 0000000..1e2a4ba
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * 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 java.util.Optional;
+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 org.sonarqube.ws.Ce;
+
+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.when;
+
+public class InfoActionTest {
+
+  @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 InfoAction underTest = new InfoAction(userSession, passcode, ceQueue);
+  private WsActionTester ws = new WsActionTester(underTest);
+
+  @Test
+  public void test_definition() {
+    WebService.Action def = ws.getDef();
+    assertThat(def.key()).isEqualTo("info");
+    assertThat(def.isInternal()).isFalse();
+    assertThat(def.isPost()).isFalse();
+    assertThat(def.params()).isEmpty();
+  }
+
+  @Test
+  public void test_example_of_response() {
+    userSession.logIn().setSystemAdministrator();
+    when(ceQueue.getWorkersPause()).thenReturn(Optional.of(CeQueue.WorkersPause.PAUSING));
+
+    ws.newRequest().execute().assertJson(ws.getDef().responseExampleAsString());
+  }
+
+  @Test
+  public void test_workers_in_pausing_state() {
+    userSession.logIn().setSystemAdministrator();
+    when(ceQueue.getWorkersPause()).thenReturn(Optional.of(CeQueue.WorkersPause.PAUSING));
+
+    Ce.InfoWsResponse response = ws.newRequest().executeProtobuf(Ce.InfoWsResponse.class);
+    assertThat(response.getWorkersPaused()).isFalse();
+    assertThat(response.getWorkersPauseRequested()).isTrue();
+  }
+
+  @Test
+  public void test_workers_in_paused_state() {
+    userSession.logIn().setSystemAdministrator();
+    when(ceQueue.getWorkersPause()).thenReturn(Optional.of(CeQueue.WorkersPause.PAUSED));
+
+    Ce.InfoWsResponse response = ws.newRequest().executeProtobuf(Ce.InfoWsResponse.class);
+    assertThat(response.getWorkersPaused()).isTrue();
+    assertThat(response.getWorkersPauseRequested()).isFalse();
+  }
+
+  @Test
+  public void test_workers_in_resumed_state() {
+    userSession.logIn().setSystemAdministrator();
+    when(ceQueue.getWorkersPause()).thenReturn(Optional.empty());
+
+    Ce.InfoWsResponse response = ws.newRequest().executeProtobuf(Ce.InfoWsResponse.class);
+    assertThat(response.getWorkersPaused()).isFalse();
+    assertThat(response.getWorkersPauseRequested()).isFalse();
+  }
+
+  @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);
+    when(ceQueue.getWorkersPause()).thenReturn(Optional.empty());
+
+    Ce.InfoWsResponse response = ws.newRequest().executeProtobuf(Ce.InfoWsResponse.class);
+    assertThat(response.getWorkersPaused()).isFalse();
+    assertThat(response.getWorkersPauseRequested()).isFalse();
+  }
+}
index effd68204df41496f359b5fe6c016ae2ae68aa5b..aa49783c8cc1a620efd0f11d01ad8aca1afd7105 100644 (file)
@@ -29,6 +29,7 @@ import org.sonarqube.ws.client.WsConnector;
 import org.sonarqube.ws.Ce.ActivityResponse;
 import org.sonarqube.ws.Ce.ActivityStatusWsResponse;
 import org.sonarqube.ws.Ce.ComponentResponse;
+import org.sonarqube.ws.Ce.InfoWsResponse;
 import org.sonarqube.ws.Ce.SubmitResponse;
 import org.sonarqube.ws.Ce.TaskResponse;
 import org.sonarqube.ws.Ce.TaskTypesWsResponse;
@@ -126,6 +127,17 @@ public class CeService extends BaseService {
       ComponentResponse.parser());
   }
 
+  /**
+   * 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
+   */
+  public InfoWsResponse info() {
+    return call(
+      new GetRequest(path("info")),
+      InfoWsResponse.parser());
+  }
+
   /**
    *
    * This is part of the internal API.
index 5787a326e5e235eb843fcf7b58c6feef3269aabf..b52038250c0546c2fa8dc157ce964a891e89dd10 100644 (file)
@@ -57,6 +57,12 @@ message ComponentResponse {
   optional Task current = 2;
 }
 
+// GET api/ce/info
+message InfoWsResponse {
+  optional bool workersPaused = 1;
+  optional bool workersPauseRequested = 2;
+}
+
 // GET api/ce/task_types
 message TaskTypesWsResponse {
   repeated string taskTypes = 1;