]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10010 Add WS api/edition/form_data
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Thu, 19 Oct 2017 06:45:26 +0000 (08:45 +0200)
committerGrégoire Aubert <gregoire.aubert@sonarsource.com>
Mon, 23 Oct 2017 15:01:13 +0000 (08:01 -0700)
server/sonar-server/src/main/java/org/sonar/server/edition/EditionsWsModule.java
server/sonar-server/src/main/java/org/sonar/server/edition/ws/FormDataAction.java [new file with mode: 0644]
server/sonar-server/src/main/resources/org/sonar/server/edition/ws/example-edition-form_data.json [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/edition/EditionsWsModuleTest.java
server/sonar-server/src/test/java/org/sonar/server/edition/ws/FormDataActionTest.java [new file with mode: 0644]
sonar-ws/src/main/protobuf/ws-editions.proto

index e62724d7d5151f7bd69995e21e5575ccc6ff0387..958250388d5b37e26847784966a24178f41fd15c 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.server.edition;
 import org.sonar.core.platform.Module;
 import org.sonar.server.edition.ws.ApplyLicenseAction;
 import org.sonar.server.edition.ws.EditionsWs;
+import org.sonar.server.edition.ws.FormDataAction;
 import org.sonar.server.edition.ws.PreviewAction;
 import org.sonar.server.edition.ws.StatusAction;
 
@@ -32,6 +33,7 @@ public class EditionsWsModule extends Module {
       StatusAction.class,
       ApplyLicenseAction.class,
       PreviewAction.class,
+      FormDataAction.class,
       EditionsWs.class);
   }
 }
diff --git a/server/sonar-server/src/main/java/org/sonar/server/edition/ws/FormDataAction.java b/server/sonar-server/src/main/java/org/sonar/server/edition/ws/FormDataAction.java
new file mode 100644 (file)
index 0000000..1cfb9aa
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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.edition.ws;
+
+import org.sonar.api.platform.Server;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.server.measure.index.ProjectMeasuresIndex;
+import org.sonar.server.user.UserSession;
+import org.sonar.server.ws.WsUtils;
+import org.sonarqube.ws.WsEditions.FormDataResponse;
+
+public class FormDataAction implements EditionsWsAction {
+  private final UserSession userSession;
+  private final Server server;
+  private final ProjectMeasuresIndex measuresIndex;
+
+  public FormDataAction(UserSession userSession, Server server, ProjectMeasuresIndex measuresIndex) {
+    this.userSession = userSession;
+    this.server = server;
+    this.measuresIndex = measuresIndex;
+  }
+
+  @Override
+  public void define(WebService.NewController controller) {
+    controller.createAction("form_data")
+      .setSince("6.7")
+      .setPost(false)
+      .setDescription("Provide data to prefill license request forms: the server ID and the total number of lines of code.")
+      .setResponseExample(getClass().getResource("example-edition-form_data.json"))
+      .setInternal(true)
+      .setHandler(this);
+  }
+
+  @Override
+  public void handle(Request request, Response response) throws Exception {
+    userSession
+      .checkLoggedIn()
+      .checkIsSystemAdministrator();
+
+    String serverId = server.getId();
+    long nloc = measuresIndex.searchTelemetryStatistics().getNcloc();
+
+    FormDataResponse responsePayload = FormDataResponse.newBuilder()
+      .setNcloc(nloc)
+      .setServerId(serverId)
+      .build();
+    WsUtils.writeProtobuf(responsePayload, request, response);
+  }
+}
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/edition/ws/example-edition-form_data.json b/server/sonar-server/src/main/resources/org/sonar/server/edition/ws/example-edition-form_data.json
new file mode 100644 (file)
index 0000000..3a36112
--- /dev/null
@@ -0,0 +1,4 @@
+{
+  "serverId": "uuid",
+  "ncloc": 12345
+}
index 116a4f4f2cdec3ba8707a05edeb1f77563721aba..a499e10eeef839fbc53165720a6cc42e52a136a9 100644 (file)
@@ -34,6 +34,6 @@ public class EditionsWsModuleTest {
     underTest.configure(container);
 
     assertThat(container.getPicoContainer().getComponentAdapters())
-      .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 4);
+      .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 5);
   }
 }
diff --git a/server/sonar-server/src/test/java/org/sonar/server/edition/ws/FormDataActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/edition/ws/FormDataActionTest.java
new file mode 100644 (file)
index 0000000..e2ce1b6
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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.edition.ws;
+
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import java.io.IOException;
+import java.util.Arrays;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.sonar.api.platform.Server;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.server.edition.EditionManagementState;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.exceptions.UnauthorizedException;
+import org.sonar.server.measure.index.ProjectMeasuresIndex;
+import org.sonar.server.measure.index.ProjectMeasuresStatistics;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.TestRequest;
+import org.sonar.server.ws.WsActionTester;
+import org.sonar.test.JsonAssert;
+import org.sonarqube.ws.MediaTypes;
+import org.sonarqube.ws.WsEditions.FormDataResponse;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.sonar.server.edition.EditionManagementState.PendingStatus.NONE;
+
+@RunWith(DataProviderRunner.class)
+public class FormDataActionTest {
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+  @Rule
+  public UserSessionRule userSessionRule = UserSessionRule.standalone();
+
+  private Server server = mock(Server.class);
+  private ProjectMeasuresStatistics stats = mock(ProjectMeasuresStatistics.class);
+  private ProjectMeasuresIndex measuresIndex = mock(ProjectMeasuresIndex.class);
+  private FormDataAction underTest = new FormDataAction(userSessionRule, server, measuresIndex);
+  private WsActionTester actionTester = new WsActionTester(underTest);
+
+  @Before
+  public void setUp() {
+    when(measuresIndex.searchTelemetryStatistics()).thenReturn(stats);
+  }
+
+  @Test
+  public void verify_definition() {
+    WebService.Action def = actionTester.getDef();
+
+    assertThat(def.key()).isEqualTo("form_data");
+    assertThat(def.since()).isEqualTo("6.7");
+    assertThat(def.isPost()).isFalse();
+    assertThat(def.isInternal()).isTrue();
+    assertThat(def.description()).isNotEmpty();
+    assertThat(def.params()).isEmpty();
+  }
+
+  @Test
+  public void request_fails_if_user_not_logged_in() {
+    userSessionRule.anonymous();
+    TestRequest request = actionTester.newRequest();
+
+    expectedException.expect(UnauthorizedException.class);
+    expectedException.expectMessage("Authentication is required");
+
+    request.execute();
+  }
+
+  @Test
+  public void request_fails_if_user_is_not_system_administer() {
+    userSessionRule.logIn();
+    TestRequest request = actionTester.newRequest();
+
+    expectedException.expect(ForbiddenException.class);
+    expectedException.expectMessage("Insufficient privileges");
+
+    request.execute();
+  }
+
+  @Test
+  public void verify_example() throws IOException {
+    userSessionRule.logIn().setSystemAdministrator();
+    when(server.getId()).thenReturn("uuid");
+    when(stats.getNcloc()).thenReturn(12345L);
+
+    TestRequest request = actionTester.newRequest();
+
+    JsonAssert.assertJson(request.execute().getInput()).isSimilarTo(actionTester.getDef().responseExampleAsString());
+  }
+
+  @Test
+  public void returns_server_id_and_nloc() throws IOException {
+    userSessionRule.logIn().setSystemAdministrator();
+    when(server.getId()).thenReturn("myserver");
+    when(stats.getNcloc()).thenReturn(1000L);
+
+    FormDataResponse expectedResponse = FormDataResponse.newBuilder()
+      .setServerId("myserver")
+      .setNcloc(1000L)
+      .build();
+
+    TestRequest request = actionTester.newRequest().setMediaType(MediaTypes.PROTOBUF);
+
+    assertThat(FormDataResponse.parseFrom(request.execute().getInputStream())).isEqualTo(expectedResponse);
+  }
+
+  @DataProvider
+  public static Object[][] notNonePendingInstallationStatuses() {
+    return Arrays.stream(EditionManagementState.PendingStatus.values())
+      .filter(s -> s != NONE)
+      .map(s -> new Object[] {s})
+      .toArray(Object[][]::new);
+  }
+}
index 791ad47215f3dc6772a9720a66e3980f26764158..c8dc31ee29d302a391940319dae308bec2b150f3 100644 (file)
@@ -51,3 +51,9 @@ enum PreviewStatus {
   AUTOMATIC_INSTALL = 1;
   MANUAL_INSTALL = 2;
 }
+
+// POST api/editions/form_data
+message FormDataResponse {
+  optional string serverId = 1;
+  optional int64  ncloc = 2;
+}