* ProjectAlmBindingDto#getAlm does not need to return Optional, as column is not nullable * Add warning on Bitbucket PR analysis when organization is not bound * Extract GitHub API call in dedicated class * Add warning on GitHub PR analysis when organization is not boundtags/7.5
@@ -43,7 +43,11 @@ public class OrganizationAlmBindingDao implements Dao { | |||
} | |||
public Optional<OrganizationAlmBindingDto> selectByOrganization(DbSession dbSession, OrganizationDto organization) { | |||
return ofNullable(getMapper(dbSession).selectByOrganizationUuid(organization.getUuid())); | |||
return selectByOrganizationUuid(dbSession, organization.getUuid()); | |||
} | |||
public Optional<OrganizationAlmBindingDto> selectByOrganizationUuid(DbSession dbSession, String organizationUuid) { | |||
return ofNullable(getMapper(dbSession).selectByOrganizationUuid(organizationUuid)); | |||
} | |||
public List<OrganizationAlmBindingDto> selectByOrganizations(DbSession dbSession, Collection<OrganizationDto> organizations) { |
@@ -20,7 +20,6 @@ | |||
package org.sonar.db.alm; | |||
import java.util.Arrays; | |||
import java.util.Optional; | |||
/** | |||
* DTO is used only for select, hence no setters (MyBatis populates field by reflection). | |||
@@ -33,14 +32,11 @@ public class ProjectAlmBindingDto { | |||
private String githubSlug; | |||
private String url; | |||
public Optional<ALM> getAlm() { | |||
if (rawAlmId == null) { | |||
return Optional.empty(); | |||
} | |||
public ALM getAlm() { | |||
return Arrays.stream(ALM.values()) | |||
.filter(a -> a.getId().equals(rawAlmId)) | |||
.findAny(); | |||
.findAny() | |||
.orElseThrow(() -> new IllegalStateException("ALM id " + rawAlmId + " is invalid")); | |||
} | |||
public String getRepoId() { |
@@ -81,6 +81,23 @@ public class OrganizationAlmBindingDaoTest { | |||
assertThat(result).isEmpty(); | |||
} | |||
@Test | |||
public void selectByOrganizationUuid() { | |||
OrganizationDto organization = db.organizations().insert(); | |||
AlmAppInstallDto almAppInstall = db.alm().insertAlmAppInstall(); | |||
OrganizationAlmBindingDto dto = db.alm().insertOrganizationAlmBinding(organization, almAppInstall); | |||
assertThat(underTest.selectByOrganizationUuid(db.getSession(), organization.getUuid()).get()) | |||
.extracting(OrganizationAlmBindingDto::getUuid, OrganizationAlmBindingDto::getOrganizationUuid, OrganizationAlmBindingDto::getAlmAppInstallUuid, | |||
OrganizationAlmBindingDto::getUrl, OrganizationAlmBindingDto::getAlm, | |||
OrganizationAlmBindingDto::getUserUuid, OrganizationAlmBindingDto::getCreatedAt) | |||
.containsExactlyInAnyOrder(dto.getUuid(), organization.getUuid(), dto.getAlmAppInstallUuid(), | |||
dto.getUrl(), ALM.GITHUB, | |||
dto.getUserUuid(), NOW); | |||
assertThat(underTest.selectByOrganizationUuid(db.getSession(), "unknown")).isNotPresent(); | |||
} | |||
@Test | |||
public void selectByOrganizations() { | |||
OrganizationDto organization1 = db.organizations().insert(); |
@@ -193,7 +193,7 @@ public class ProjectAlmBindingDaoTest { | |||
Optional<ProjectAlmBindingDto> dto = underTest.selectByRepoId(dbSession, GITHUB, A_REPO); | |||
assertThat(dto).isPresent(); | |||
assertThat(dto.get().getUuid()).isEqualTo("uuid1"); | |||
assertThat(dto.get().getAlm()).contains(GITHUB); | |||
assertThat(dto.get().getAlm()).isEqualTo(GITHUB); | |||
assertThat(dto.get().getRepoId()).isEqualTo(A_REPO); | |||
assertThat(dto.get().getProjectUuid()).isEqualTo(A_UUID); | |||
assertThat(dto.get().getUrl()).isEqualTo(A_URL); | |||
@@ -216,7 +216,7 @@ public class ProjectAlmBindingDaoTest { | |||
Optional<ProjectAlmBindingDto> dto = underTest.selectByProjectUuid(dbSession, A_UUID); | |||
assertThat(dto).isPresent(); | |||
assertThat(dto.get().getUuid()).isEqualTo("uuid1"); | |||
assertThat(dto.get().getAlm()).contains(BITBUCKETCLOUD); | |||
assertThat(dto.get().getAlm()).isEqualTo(BITBUCKETCLOUD); | |||
assertThat(dto.get().getRepoId()).isEqualTo(A_REPO); | |||
assertThat(dto.get().getProjectUuid()).isEqualTo(A_UUID); | |||
assertThat(dto.get().getUrl()).isEqualTo(A_URL); | |||
@@ -236,7 +236,7 @@ public class ProjectAlmBindingDaoTest { | |||
underTest.insertOrUpdate(dbSession, BITBUCKETCLOUD, ANOTHER_REPO, "foo", null, "http://foo"); | |||
assertThat(underTest.selectByRepoIds(dbSession, GITHUB, Arrays.asList(A_REPO, ANOTHER_REPO, "foo"))) | |||
.extracting(ProjectAlmBindingDto::getUuid, t -> t.getAlm().get(), ProjectAlmBindingDto::getRepoId, ProjectAlmBindingDto::getProjectUuid, | |||
.extracting(ProjectAlmBindingDto::getUuid, t -> t.getAlm(), ProjectAlmBindingDto::getRepoId, ProjectAlmBindingDto::getProjectUuid, | |||
ProjectAlmBindingDto::getUrl, ProjectAlmBindingDto::getGithubSlug) | |||
.containsExactlyInAnyOrder( | |||
tuple("uuid1", GITHUB, A_REPO, A_UUID, A_URL, A_GITHUB_SLUG), |
@@ -42,7 +42,6 @@ import org.sonar.api.web.UserRole; | |||
import org.sonar.api.web.page.Page; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.alm.ALM; | |||
import org.sonar.db.alm.ProjectAlmBindingDto; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.component.SnapshotDto; | |||
@@ -188,10 +187,7 @@ public class ComponentAction implements NavigationWsAction { | |||
private void writeAlmDetails(JsonWriter json, DbSession session, ComponentDto component) { | |||
Optional<ProjectAlmBindingDto> bindingOpt = dbClient.projectAlmBindingsDao().selectByProjectUuid(session, component.uuid()); | |||
bindingOpt.ifPresent(b -> { | |||
String almId = b.getAlm() | |||
.map(ALM::getId) | |||
.map(String::valueOf) | |||
.orElseThrow(() -> new IllegalStateException("Alm binding id DB has no ALM id")); | |||
String almId = String.valueOf(b.getAlm().getId()); | |||
json.name("alm").beginObject() | |||
.prop("key", almId) | |||
.prop("url", b.getUrl()) |
@@ -0,0 +1,75 @@ | |||
/* | |||
* 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.sonarqube.ws.client.ce; | |||
import javax.annotation.Generated; | |||
/** | |||
* This is part of the internal API. | |||
* This is a POST request. | |||
* @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/ce/analysis_status">Further information about this action online (including a response example)</a> | |||
* @since 7.4 | |||
*/ | |||
@Generated("sonar-ws-generator") | |||
public class AnalysisStatusRequest { | |||
private String branch; | |||
private String component; | |||
private String pullRequest; | |||
/** | |||
* This is part of the internal API. | |||
* Example value: "feature/my_branch" | |||
*/ | |||
public AnalysisStatusRequest setBranch(String branch) { | |||
this.branch = branch; | |||
return this; | |||
} | |||
public String getBranch() { | |||
return branch; | |||
} | |||
/** | |||
* This is a mandatory parameter. | |||
* Example value: "my_project" | |||
*/ | |||
public AnalysisStatusRequest setComponent(String component) { | |||
this.component = component; | |||
return this; | |||
} | |||
public String getComponent() { | |||
return component; | |||
} | |||
/** | |||
* This is part of the internal API. | |||
* Example value: "5461" | |||
*/ | |||
public AnalysisStatusRequest setPullRequest(String pullRequest) { | |||
this.pullRequest = pullRequest; | |||
return this; | |||
} | |||
public String getPullRequest() { | |||
return pullRequest; | |||
} | |||
} |
@@ -21,19 +21,20 @@ package org.sonarqube.ws.client.ce; | |||
import java.util.stream.Collectors; | |||
import javax.annotation.Generated; | |||
import org.sonarqube.ws.MediaTypes; | |||
import org.sonarqube.ws.client.BaseService; | |||
import org.sonarqube.ws.client.GetRequest; | |||
import org.sonarqube.ws.client.PostRequest; | |||
import org.sonarqube.ws.client.WsConnector; | |||
import org.sonarqube.ws.Ce.ActivityResponse; | |||
import org.sonarqube.ws.Ce.ActivityStatusWsResponse; | |||
import org.sonarqube.ws.Ce.AnalysisStatusWsResponse; | |||
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; | |||
import org.sonarqube.ws.Ce.WorkerCountResponse; | |||
import org.sonarqube.ws.MediaTypes; | |||
import org.sonarqube.ws.client.BaseService; | |||
import org.sonarqube.ws.client.GetRequest; | |||
import org.sonarqube.ws.client.PostRequest; | |||
import org.sonarqube.ws.client.WsConnector; | |||
/** | |||
* @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/ce">Further information about this web service online</a> | |||
@@ -83,6 +84,22 @@ public class CeService extends BaseService { | |||
ActivityStatusWsResponse.parser()); | |||
} | |||
/** | |||
* | |||
* This is part of the internal API. | |||
* This is a GET request. | |||
* @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/ce/analysis_status">Further information about this action online (including a response example)</a> | |||
* @since 7.4 | |||
*/ | |||
public AnalysisStatusWsResponse analysisStatus(AnalysisStatusRequest request) { | |||
return call( | |||
new GetRequest(path("analysis_status")) | |||
.setParam("branch", request.getBranch()) | |||
.setParam("component", request.getComponent()) | |||
.setParam("pullRequest", request.getPullRequest()), | |||
AnalysisStatusWsResponse.parser()); | |||
} | |||
/** | |||
* | |||
* This is part of the internal API. | |||
@@ -129,6 +146,7 @@ public class CeService extends BaseService { | |||
/** | |||
* | |||
* This is part of the internal API. | |||
* 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 | |||
@@ -140,6 +158,8 @@ public class CeService extends BaseService { | |||
} | |||
/** | |||
* | |||
* This is part of the internal API. | |||
* 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 | |||
@@ -152,6 +172,8 @@ public class CeService extends BaseService { | |||
} | |||
/** | |||
* | |||
* This is part of the internal API. | |||
* 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 |
@@ -39,6 +39,7 @@ public class TaskRequest { | |||
* <ul> | |||
* <li>"stacktrace"</li> | |||
* <li>"scannerContext"</li> | |||
* <li>"warnings"</li> | |||
* </ul> | |||
*/ | |||
public TaskRequest setAdditionalFields(List<String> additionalFields) { |