]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-14372 move alm GetBinding endpoint to CE
authorZipeng WU <zipeng.wu@sonarsource.com>
Tue, 2 Feb 2021 10:31:16 +0000 (11:31 +0100)
committersonartech <sonartech@sonarsource.com>
Thu, 4 Feb 2021 20:07:08 +0000 (20:07 +0000)
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/AlmSettingsWsModule.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GetBindingAction.java [new file with mode: 0644]
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/AlmSettingsWsModuleTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/GetBindingActionTest.java [new file with mode: 0644]
server/sonar-webserver-webapi/src/test/resources/org/sonar/server/almsettings/ws/get_binding-example.json [new file with mode: 0644]

index e1ed3e3fa247b7b545ff3b8326c02c69471fff01..dc5335abd801dc2e708fa1224700ac896c44226a 100644 (file)
@@ -31,6 +31,7 @@ public class AlmSettingsWsModule extends Module {
       ListAction.class,
       ListDefinitionsAction.class,
       ValidateAction.class,
+      GetBindingAction.class,
       //Azure alm settings,
       CreateAzureAction.class,
       UpdateAzureAction.class,
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GetBindingAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GetBindingAction.java
new file mode 100644 (file)
index 0000000..a6a9ba1
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.almsettings.ws;
+
+import org.sonar.api.server.ws.Change;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.alm.setting.AlmSettingDto;
+import org.sonar.db.alm.setting.ProjectAlmSettingDto;
+import org.sonar.db.project.ProjectDto;
+import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.user.UserSession;
+import org.sonarqube.ws.AlmSettings.GetBindingWsResponse;
+
+import static java.lang.String.format;
+import static java.util.Optional.ofNullable;
+import static org.sonar.api.web.UserRole.ADMIN;
+import static org.sonar.server.almsettings.ws.AlmSettingsSupport.toAlmWs;
+import static org.sonar.server.ws.WsUtils.writeProtobuf;
+
+public class GetBindingAction implements AlmSettingsWsAction {
+
+  private static final String PARAM_PROJECT = "project";
+
+  private final DbClient dbClient;
+  private final UserSession userSession;
+  private final ComponentFinder componentFinder;
+
+  public GetBindingAction(DbClient dbClient, UserSession userSession, ComponentFinder componentFinder) {
+    this.dbClient = dbClient;
+    this.userSession = userSession;
+    this.componentFinder = componentFinder;
+  }
+
+  @Override
+  public void define(WebService.NewController context) {
+    WebService.NewAction action = context.createAction("get_binding")
+      .setDescription("Get ALM binding of a given project.<br/>" +
+        "Requires the 'Administer' permission on the project")
+      .setSince("8.1")
+      .setResponseExample(getClass().getResource("get_binding-example.json"))
+      .setChangelog(new Change("8.6", "Azure binding now contains the project and repository names"))
+      .setChangelog(new Change("8.7", "Azure binding now contains a monorepo flag for monorepo feature in Enterprise Edition and above"))
+      .setHandler(this);
+
+    action
+      .createParam(PARAM_PROJECT)
+      .setDescription("Project key")
+      .setRequired(true);
+  }
+
+  @Override
+  public void handle(Request request, Response response) {
+    GetBindingWsResponse wsResponse = doHandle(request);
+    writeProtobuf(wsResponse, request, response);
+  }
+
+  private GetBindingWsResponse doHandle(Request request) {
+    String projectKey = request.mandatoryParam(PARAM_PROJECT);
+    try (DbSession dbSession = dbClient.openSession(false)) {
+      ProjectDto project = componentFinder.getProjectByKey(dbSession, projectKey);
+      userSession.checkProjectPermission(ADMIN, project);
+      ProjectAlmSettingDto projectAlmSetting = dbClient.projectAlmSettingDao().selectByProject(dbSession, project)
+        .orElseThrow(() -> new NotFoundException(format("Project '%s' is not bound to any ALM", project.getKey())));
+      AlmSettingDto almSetting = dbClient.almSettingDao().selectByUuid(dbSession, projectAlmSetting.getAlmSettingUuid())
+        .orElseThrow(() -> new IllegalStateException(format("ALM setting with uuid '%s' cannot be found", projectAlmSetting.getAlmSettingUuid())));
+
+      GetBindingWsResponse.Builder builder = GetBindingWsResponse.newBuilder()
+        .setAlm(toAlmWs(almSetting.getAlm()))
+        .setKey(almSetting.getKey());
+      ofNullable(projectAlmSetting.getAlmRepo()).ifPresent(builder::setRepository);
+      ofNullable(almSetting.getUrl()).ifPresent(builder::setUrl);
+      ofNullable(projectAlmSetting.getAlmSlug()).ifPresent(builder::setSlug);
+      ofNullable(projectAlmSetting.getSummaryCommentEnabled()).ifPresent(builder::setSummaryCommentEnabled);
+      ofNullable(projectAlmSetting.getMonorepo()).ifPresent(builder::setMonorepo);
+      return builder.build();
+    }
+  }
+}
index bf28d5d87229107ae4ea6d7e822ea1f11e2e8d69..d1b9d32d877c4a853c6ee7120c62290c56157421 100644 (file)
@@ -31,7 +31,7 @@ public class AlmSettingsWsModuleTest {
   public void verify_count_of_added_components() {
     ComponentContainer container = new ComponentContainer();
     new AlmSettingsWsModule().configure(container);
-    assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 14);
+    assertThat(container.size()).isEqualTo(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 15);
   }
 
 }
\ No newline at end of file
diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/GetBindingActionTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/almsettings/ws/GetBindingActionTest.java
new file mode 100644 (file)
index 0000000..1413738
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.almsettings.ws;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.db.DbTester;
+import org.sonar.db.alm.setting.AlmSettingDto;
+import org.sonar.db.alm.setting.ProjectAlmSettingDto;
+import org.sonar.db.project.ProjectDto;
+import org.sonar.db.user.UserDto;
+import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.WsActionTester;
+import org.sonarqube.ws.AlmSettings;
+import org.sonarqube.ws.AlmSettings.GetBindingWsResponse;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.groups.Tuple.tuple;
+import static org.sonar.api.web.UserRole.ADMIN;
+import static org.sonar.api.web.UserRole.USER;
+import static org.sonar.test.JsonAssert.assertJson;
+
+public class GetBindingActionTest {
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+  @Rule
+  public UserSessionRule userSession = UserSessionRule.standalone();
+  @Rule
+  public DbTester db = DbTester.create();
+
+  private WsActionTester ws = new WsActionTester(new GetBindingAction(db.getDbClient(), userSession, new ComponentFinder(db.getDbClient(), null)));
+
+  private UserDto user;
+  private ProjectDto project;
+
+  @Before
+  public void before() {
+    user = db.users().insertUser();
+    project = db.components().insertPrivateProjectDto();
+  }
+
+  @Test
+  public void get_github_project_binding() {
+    userSession.logIn(user).addProjectPermission(ADMIN, project);
+    AlmSettingDto githubAlmSetting = db.almSettings().insertGitHubAlmSetting();
+    ProjectAlmSettingDto githubProjectAlmSetting = db.almSettings().insertGitHubProjectAlmSetting(githubAlmSetting, project);
+
+    GetBindingWsResponse response = ws.newRequest()
+      .setParam("project", project.getKey())
+      .executeProtobuf(GetBindingWsResponse.class);
+
+    assertThat(response.getAlm()).isEqualTo(AlmSettings.Alm.github);
+    assertThat(response.getKey()).isEqualTo(githubAlmSetting.getKey());
+    assertThat(response.getRepository()).isEqualTo(githubProjectAlmSetting.getAlmRepo());
+    assertThat(response.getUrl()).isEqualTo(githubAlmSetting.getUrl());
+    assertThat(response.getSummaryCommentEnabled()).isTrue();
+  }
+
+  @Test
+  public void get_azure_project_binding() {
+    userSession.logIn(user).addProjectPermission(ADMIN, project);
+    AlmSettingDto almSetting = db.almSettings().insertAzureAlmSetting();
+    ProjectAlmSettingDto projectAlmSettingDto = db.almSettings().insertAzureMonoRepoProjectAlmSetting(almSetting, project);
+
+    GetBindingWsResponse response = ws.newRequest()
+      .setParam("project", project.getKey())
+      .executeProtobuf(GetBindingWsResponse.class);
+
+    assertThat(response.getAlm()).isEqualTo(AlmSettings.Alm.azure);
+    assertThat(response.getKey()).isEqualTo(almSetting.getKey());
+    assertThat(response.getUrl()).isEqualTo(almSetting.getUrl());
+    assertThat(response.getRepository()).isEqualTo(projectAlmSettingDto.getAlmRepo());
+    assertThat(response.getSlug()).isEqualTo(projectAlmSettingDto.getAlmSlug());
+    assertThat(response.hasSummaryCommentEnabled()).isFalse();
+    assertThat(response.getMonorepo()).isTrue();
+  }
+
+  @Test
+  public void get_gitlab_project_binding() {
+    UserDto user = db.users().insertUser();
+    ProjectDto project = db.components().insertPrivateProjectDto();
+    userSession.logIn(user).addProjectPermission(ADMIN, project);
+    AlmSettingDto almSetting = db.almSettings().insertGitlabAlmSetting();
+    db.almSettings().insertGitlabProjectAlmSetting(almSetting, project);
+
+    GetBindingWsResponse response = ws.newRequest()
+      .setParam("project", project.getKey())
+      .executeProtobuf(GetBindingWsResponse.class);
+
+    assertThat(response.getAlm()).isEqualTo(AlmSettings.Alm.gitlab);
+    assertThat(response.getKey()).isEqualTo(almSetting.getKey());
+    assertThat(response.hasRepository()).isFalse();
+    assertThat(response.getUrl()).isEqualTo(almSetting.getUrl());
+    assertThat(response.hasUrl()).isTrue();
+    assertThat(response.hasSummaryCommentEnabled()).isFalse();
+  }
+
+  @Test
+  public void get_bitbucket_project_binding() {
+    userSession.logIn(user).addProjectPermission(ADMIN, project);
+    AlmSettingDto almSetting = db.almSettings().insertBitbucketAlmSetting();
+    ProjectAlmSettingDto projectAlmSettingDto = db.almSettings().insertBitbucketProjectAlmSetting(almSetting, project);
+
+    GetBindingWsResponse response = ws.newRequest()
+      .setParam("project", project.getKey())
+      .executeProtobuf(GetBindingWsResponse.class);
+
+    assertThat(response.getAlm()).isEqualTo(AlmSettings.Alm.bitbucket);
+    assertThat(response.getKey()).isEqualTo(almSetting.getKey());
+    assertThat(response.getRepository()).isEqualTo(projectAlmSettingDto.getAlmRepo());
+    assertThat(response.getUrl()).isEqualTo(almSetting.getUrl());
+    assertThat(response.getSlug()).isEqualTo(projectAlmSettingDto.getAlmSlug());
+    assertThat(response.hasSummaryCommentEnabled()).isFalse();
+  }
+
+  @Test
+  public void fail_when_project_does_not_exist() {
+    userSession.logIn(user).addProjectPermission(ADMIN, project);
+    AlmSettingDto githubAlmSetting = db.almSettings().insertGitHubAlmSetting();
+    db.almSettings().insertGitHubProjectAlmSetting(githubAlmSetting, project);
+
+    expectedException.expect(NotFoundException.class);
+
+    ws.newRequest()
+      .setParam("project", "unknown")
+      .execute();
+  }
+
+  @Test
+  public void fail_when_missing_administer_permission_on_project() {
+    userSession.logIn(user).addProjectPermission(USER, project);
+    AlmSettingDto githubAlmSetting = db.almSettings().insertGitHubAlmSetting();
+    db.almSettings().insertGitHubProjectAlmSetting(githubAlmSetting, project);
+
+    expectedException.expect(ForbiddenException.class);
+
+    ws.newRequest()
+      .setParam("project", project.getKey())
+      .execute();
+  }
+
+  @Test
+  public void json_example() {
+    userSession.logIn(user).addProjectPermission(ADMIN, project);
+    AlmSettingDto githubAlmSetting = db.almSettings().insertGitHubAlmSetting(
+      almSettingDto -> almSettingDto
+        .setKey("GitHub Server - Dev Team")
+        .setUrl("https://github.enterprise.com")
+        .setAppId("12345")
+        .setPrivateKey("54684654"));
+    db.almSettings().insertGitHubProjectAlmSetting(githubAlmSetting, project, projectAlmSetting -> projectAlmSetting.setAlmRepo("team/project"));
+
+    String response = ws.newRequest()
+      .setParam("project", project.getKey())
+      .execute().getInput();
+
+    assertJson(response).isSimilarTo(getClass().getResource("get_binding-example.json"));
+  }
+
+  @Test
+  public void definition() {
+    WebService.Action def = ws.getDef();
+
+    assertThat(def.since()).isEqualTo("8.1");
+    assertThat(def.isPost()).isFalse();
+    assertThat(def.responseExampleAsString()).isNotEmpty();
+    assertThat(def.params())
+      .extracting(WebService.Param::key, WebService.Param::isRequired)
+      .containsExactlyInAnyOrder(tuple("project", true));
+  }
+
+}
diff --git a/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/almsettings/ws/get_binding-example.json b/server/sonar-webserver-webapi/src/test/resources/org/sonar/server/almsettings/ws/get_binding-example.json
new file mode 100644 (file)
index 0000000..146dff3
--- /dev/null
@@ -0,0 +1,6 @@
+{
+  "key": "GitHub Server - Dev Team",
+  "alm": "github",
+  "repository": "team/project",
+  "url": "https://github.enterprise.com"
+}