aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2017-08-28 14:58:12 +0200
committerJanos Gyerik <janos.gyerik@sonarsource.com>2017-09-12 11:34:54 +0200
commit8767617b9d142cd617a22933089947796c97090c (patch)
tree379b9266940869d73d234cac5fecbb32acbe82ab /server
parentb135ed4ad8922c03bc882d64ad7d5d9e0e89c22c (diff)
downloadsonarqube-8767617b9d142cd617a22933089947796c97090c.tar.gz
sonarqube-8767617b9d142cd617a22933089947796c97090c.zip
SONAR-9616 Use ES to get issues in api/project_branches/list
Diffstat (limited to 'server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/projectbranch/ws/BranchDtoToWsBranch.java79
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/projectbranch/ws/ListAction.java92
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/projectbranch/ws/ListActionTest.java44
3 files changed, 98 insertions, 117 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/projectbranch/ws/BranchDtoToWsBranch.java b/server/sonar-server/src/main/java/org/sonar/server/projectbranch/ws/BranchDtoToWsBranch.java
deleted file mode 100644
index 06ff510630e..00000000000
--- a/server/sonar-server/src/main/java/org/sonar/server/projectbranch/ws/BranchDtoToWsBranch.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.projectbranch.ws;
-
-import java.util.Map;
-import java.util.Optional;
-import org.sonar.db.component.BranchDto;
-import org.sonar.db.measure.MeasureDto;
-import org.sonarqube.ws.Common;
-import org.sonarqube.ws.WsBranches;
-
-import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY;
-import static org.sonar.api.measures.CoreMetrics.BUGS_KEY;
-import static org.sonar.api.measures.CoreMetrics.CODE_SMELLS_KEY;
-import static org.sonar.api.measures.CoreMetrics.VULNERABILITIES_KEY;
-import static org.sonar.core.util.Protobuf.setNullable;
-import static org.sonar.db.component.BranchType.LONG;
-import static org.sonar.db.component.BranchType.SHORT;
-
-public class BranchDtoToWsBranch {
-
- private BranchDtoToWsBranch() {
- // static methods only
- }
-
- static WsBranches.Branch.Builder toBranchBuilder(BranchDto branch, Optional<BranchDto> mergeBranch, Map<String, MeasureDto> measuresByMetricKey) {
- WsBranches.Branch.Builder builder = WsBranches.Branch.newBuilder();
- String branchKey = branch.getKey();
- setNullable(branchKey, builder::setName);
- builder.setIsMain(branch.isMain());
- builder.setType(Common.BranchType.valueOf(branch.getBranchType().name()));
- if (branch.getBranchType().equals(SHORT)) {
- if (mergeBranch.isPresent()) {
- String mergeBranchKey = mergeBranch.get().getKey();
- builder.setMergeBranch(mergeBranchKey);
- } else {
- builder.setIsOrphan(true);
- }
- }
-
- if (branch.getBranchType().equals(LONG)) {
- WsBranches.Branch.Status.Builder statusBuilder = WsBranches.Branch.Status.newBuilder();
- MeasureDto measure = measuresByMetricKey.get(ALERT_STATUS_KEY);
- setNullable(measure, m -> builder.setStatus(statusBuilder.setQualityGateStatus(m.getData())));
- }
-
- if (branch.getBranchType().equals(SHORT)) {
- WsBranches.Branch.Status.Builder statusBuilder = WsBranches.Branch.Status.newBuilder();
- MeasureDto bugs = measuresByMetricKey.get(BUGS_KEY);
- setNullable(bugs, m -> builder.setStatus(statusBuilder.setBugs(m.getValue().intValue())));
-
- MeasureDto vulnerabilities = measuresByMetricKey.get(VULNERABILITIES_KEY);
- setNullable(vulnerabilities, m -> builder.setStatus(statusBuilder.setVulnerabilities(m.getValue().intValue())));
-
- MeasureDto codeSmells = measuresByMetricKey.get(CODE_SMELLS_KEY);
- setNullable(codeSmells, m -> builder.setStatus(statusBuilder.setCodeSmells(m.getValue().intValue())));
- builder.setStatus(statusBuilder);
- }
- return builder;
- }
-}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/projectbranch/ws/ListAction.java b/server/sonar-server/src/main/java/org/sonar/server/projectbranch/ws/ListAction.java
index 3237961ea26..05595f72c00 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/projectbranch/ws/ListAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/projectbranch/ws/ListAction.java
@@ -19,14 +19,13 @@
*/
package org.sonar.server.projectbranch.ws;
-import com.google.common.collect.Multimap;
import com.google.common.io.Resources;
import java.util.Collection;
-import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
-import java.util.function.Function;
+import javax.annotation.Nullable;
+import org.elasticsearch.action.search.SearchResponse;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
@@ -35,26 +34,34 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.BranchDto;
import org.sonar.db.component.BranchKeyType;
+import org.sonar.db.component.BranchType;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.measure.MeasureDto;
import org.sonar.db.metric.MetricDto;
import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.es.Facets;
+import org.sonar.server.es.SearchOptions;
+import org.sonar.server.issue.IssueQuery;
+import org.sonar.server.issue.index.IssueIndex;
import org.sonar.server.user.UserSession;
import org.sonar.server.ws.WsUtils;
+import org.sonarqube.ws.Common;
import org.sonarqube.ws.WsBranches;
import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY;
-import static org.sonar.api.measures.CoreMetrics.BUGS_KEY;
-import static org.sonar.api.measures.CoreMetrics.CODE_SMELLS_KEY;
-import static org.sonar.api.measures.CoreMetrics.VULNERABILITIES_KEY;
import static org.sonar.api.resources.Qualifiers.PROJECT;
-import static org.sonar.core.util.stream.MoreCollectors.index;
+import static org.sonar.core.util.Protobuf.setNullable;
import static org.sonar.core.util.stream.MoreCollectors.toList;
import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex;
-import static org.sonar.server.projectbranch.ws.BranchDtoToWsBranch.toBranchBuilder;
+import static org.sonar.db.component.BranchType.LONG;
+import static org.sonar.db.component.BranchType.SHORT;
+import static org.sonar.server.rule.index.RuleIndex.FACET_TYPES;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
+import static org.sonarqube.ws.Common.RuleType.BUG;
+import static org.sonarqube.ws.Common.RuleType.CODE_SMELL;
+import static org.sonarqube.ws.Common.RuleType.VULNERABILITY;
import static org.sonarqube.ws.client.projectbranches.ProjectBranchesParameters.ACTION_LIST;
import static org.sonarqube.ws.client.projectbranches.ProjectBranchesParameters.PARAM_PROJECT;
@@ -63,11 +70,13 @@ public class ListAction implements BranchWsAction {
private final DbClient dbClient;
private final UserSession userSession;
private final ComponentFinder componentFinder;
+ private final IssueIndex issueIndex;
- public ListAction(DbClient dbClient, UserSession userSession, ComponentFinder componentFinder) {
+ public ListAction(DbClient dbClient, UserSession userSession, ComponentFinder componentFinder, IssueIndex issueIndex) {
this.dbClient = dbClient;
this.userSession = userSession;
this.componentFinder = componentFinder;
+ this.issueIndex = issueIndex;
}
@Override
@@ -95,30 +104,69 @@ public class ListAction implements BranchWsAction {
userSession.checkComponentPermission(UserRole.USER, project);
checkArgument(project.isEnabled() && PROJECT.equals(project.qualifier()), "Invalid project key");
- List<MetricDto> metrics = dbClient.metricDao().selectByKeys(dbSession, asList(ALERT_STATUS_KEY, BUGS_KEY, VULNERABILITIES_KEY, CODE_SMELLS_KEY));
- Map<Integer, MetricDto> metricsById = metrics.stream().collect(uniqueIndex(MetricDto::getId));
-
Collection<BranchDto> branches = dbClient.branchDao().selectByComponent(dbSession, project);
+ MetricDto qualityGateMetric = dbClient.metricDao().selectOrFailByKey(dbSession, ALERT_STATUS_KEY);
Map<String, BranchDto> mergeBranchesByUuid = dbClient.branchDao()
.selectByUuids(dbSession, branches.stream().map(BranchDto::getMergeBranchUuid).filter(Objects::nonNull).collect(toList()))
.stream().collect(uniqueIndex(BranchDto::getUuid));
- Multimap<String, MeasureDto> measuresByComponentUuids = dbClient.measureDao()
- .selectByComponentsAndMetrics(dbSession, branches.stream().map(BranchDto::getUuid).collect(toList()), metricsById.keySet())
- .stream().collect(index(MeasureDto::getComponentUuid));
+ Map<String, MeasureDto> qualityGateMeasuresByComponentUuids = dbClient.measureDao()
+ .selectByComponentsAndMetrics(dbSession, branches.stream().map(BranchDto::getUuid).collect(toList()), singletonList(qualityGateMetric.getId()))
+ .stream().collect(uniqueIndex(MeasureDto::getComponentUuid));
WsBranches.ListWsResponse.Builder protobufResponse = WsBranches.ListWsResponse.newBuilder();
branches.stream()
.filter(b -> b.getKeeType().equals(BranchKeyType.BRANCH))
- .forEach(b -> addBranch(protobufResponse, b, mergeBranchesByUuid, metricsById, measuresByComponentUuids.get(b.getUuid())));
+ .forEach(b -> addBranch(protobufResponse, b, mergeBranchesByUuid, qualityGateMeasuresByComponentUuids.get(b.getUuid())));
WsUtils.writeProtobuf(protobufResponse.build(), request, response);
}
}
- private static void addBranch(WsBranches.ListWsResponse.Builder response, BranchDto branch, Map<String, BranchDto> mergeBranchesByUuid,
- Map<Integer, MetricDto> metricsById, Collection<MeasureDto> measures) {
- response.addBranches(
- toBranchBuilder(branch, Optional.ofNullable(mergeBranchesByUuid.get(branch.getMergeBranchUuid())),
- measures.stream().collect(uniqueIndex(m -> metricsById.get(m.getMetricId()).getKey(), Function.identity()))));
+ private void addBranch(WsBranches.ListWsResponse.Builder response, BranchDto branch, Map<String, BranchDto> mergeBranchesByUuid, @Nullable MeasureDto qualityGateMeasure) {
+ WsBranches.Branch.Builder builder = toBranchBuilder(branch, Optional.ofNullable(mergeBranchesByUuid.get(branch.getMergeBranchUuid())));
+ setLongLivingBranchStatus(builder, branch, qualityGateMeasure);
+ setShortLivingBranchStatus(builder, branch);
+ response.addBranches(builder);
+ }
+
+ private static WsBranches.Branch.Builder toBranchBuilder(BranchDto branch, Optional<BranchDto> mergeBranch) {
+ WsBranches.Branch.Builder builder = WsBranches.Branch.newBuilder();
+ String branchKey = branch.getKey();
+ setNullable(branchKey, builder::setName);
+ builder.setIsMain(branch.isMain());
+ builder.setType(Common.BranchType.valueOf(branch.getBranchType().name()));
+ if (branch.getBranchType().equals(SHORT)) {
+ if (mergeBranch.isPresent()) {
+ String mergeBranchKey = mergeBranch.get().getKey();
+ builder.setMergeBranch(mergeBranchKey);
+ } else {
+ builder.setIsOrphan(true);
+ }
+ }
+ return builder;
+ }
+
+ private static void setLongLivingBranchStatus(WsBranches.Branch.Builder builder, BranchDto branch, @Nullable MeasureDto qualityGateMeasure) {
+ if (branch.getBranchType().equals(LONG) && qualityGateMeasure != null) {
+ WsBranches.Branch.Status.Builder statusBuilder = WsBranches.Branch.Status.newBuilder();
+ statusBuilder.setQualityGateStatus(qualityGateMeasure.getData());
+ builder.setStatus(statusBuilder);
+ }
+ }
+
+ private void setShortLivingBranchStatus(WsBranches.Branch.Builder builder, BranchDto branch) {
+ if (!branch.getBranchType().equals(BranchType.SHORT)) {
+ return;
+ }
+ SearchResponse searchResponse = issueIndex.search(IssueQuery.builder().branchUuid(branch.getUuid()).build(), new SearchOptions()
+ .setLimit(0)
+ .addFacets(FACET_TYPES));
+ Facets facets = new Facets(searchResponse);
+ Map<String, Long> typesFacet = Objects.requireNonNull(facets.get(FACET_TYPES), "Facet types does not exists");
+ WsBranches.Branch.Status.Builder statusBuilder = WsBranches.Branch.Status.newBuilder();
+ setNullable(typesFacet.get(BUG.name()), v -> statusBuilder.setBugs(v.intValue()));
+ setNullable(typesFacet.get(VULNERABILITY.name()), v -> statusBuilder.setVulnerabilities(v.intValue()));
+ setNullable(typesFacet.get(CODE_SMELL.name()), v -> statusBuilder.setCodeSmells(v.intValue()));
+ builder.setStatus(statusBuilder);
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/projectbranch/ws/ListActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/projectbranch/ws/ListActionTest.java
index 15ddf4440b6..ba6722e6247 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/projectbranch/ws/ListActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/projectbranch/ws/ListActionTest.java
@@ -23,6 +23,7 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.resources.ResourceTypes;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.System2;
@@ -35,8 +36,16 @@ import org.sonar.db.component.ResourceTypesRule;
import org.sonar.db.component.SnapshotDto;
import org.sonar.db.metric.MetricDto;
import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.es.EsTester;
import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.issue.index.IssueIndex;
+import org.sonar.server.issue.index.IssueIndexDefinition;
+import org.sonar.server.issue.index.IssueIndexer;
+import org.sonar.server.issue.index.IssueIteratorFactory;
+import org.sonar.server.permission.index.AuthorizationTypeSupport;
+import org.sonar.server.permission.index.PermissionIndexerTester;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsActionTester;
import org.sonarqube.ws.Common;
@@ -46,13 +55,14 @@ import org.sonarqube.ws.WsBranches.Branch;
import org.sonarqube.ws.WsBranches.ListWsResponse;
import static java.lang.String.format;
+import static java.util.Collections.emptySet;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY;
-import static org.sonar.api.measures.CoreMetrics.BUGS_KEY;
-import static org.sonar.api.measures.CoreMetrics.CODE_SMELLS_KEY;
-import static org.sonar.api.measures.CoreMetrics.VULNERABILITIES_KEY;
import static org.sonar.api.resources.Qualifiers.PROJECT;
+import static org.sonar.api.rules.RuleType.BUG;
+import static org.sonar.api.rules.RuleType.CODE_SMELL;
+import static org.sonar.api.rules.RuleType.VULNERABILITY;
import static org.sonar.test.JsonAssert.assertJson;
import static org.sonarqube.ws.WsBranches.Branch.Status;
@@ -60,28 +70,25 @@ public class ListActionTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();
-
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
-
+ @Rule
+ public EsTester es = new EsTester(new IssueIndexDefinition(new MapSettings().asConfig()));
@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
private ResourceTypes resourceTypes = new ResourceTypesRule().setRootQualifiers(PROJECT);
+ private IssueIndexer issueIndexer = new IssueIndexer(es.client(), db.getDbClient(), new IssueIteratorFactory(db.getDbClient()));
+ private IssueIndex issueIndex = new IssueIndex(es.client(), System2.INSTANCE, userSession, new AuthorizationTypeSupport(userSession));
+ private PermissionIndexerTester permissionIndexerTester = new PermissionIndexerTester(es, issueIndexer);
private MetricDto qualityGateStatus;
- private MetricDto bugs;
- private MetricDto vulnerabilities;
- private MetricDto codeSmells;
- public WsActionTester ws = new WsActionTester(new ListAction(db.getDbClient(), userSession, new ComponentFinder(db.getDbClient(), resourceTypes)));
+ public WsActionTester ws = new WsActionTester(new ListAction(db.getDbClient(), userSession, new ComponentFinder(db.getDbClient(), resourceTypes), issueIndex));
@Before
public void setUp() throws Exception {
qualityGateStatus = db.measures().insertMetric(m -> m.setKey(ALERT_STATUS_KEY));
- bugs = db.measures().insertMetric(m -> m.setKey(BUGS_KEY));
- vulnerabilities = db.measures().insertMetric(m -> m.setKey(VULNERABILITIES_KEY));
- codeSmells = db.measures().insertMetric(m -> m.setKey(CODE_SMELLS_KEY));
}
@Test
@@ -252,10 +259,15 @@ public class ListActionTest {
ComponentDto longLivingBranch = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.LONG));
ComponentDto shortLivingBranch = db.components().insertProjectBranch(project,
b -> b.setBranchType(BranchType.SHORT).setMergeBranchUuid(longLivingBranch.uuid()));
- SnapshotDto branchAnalysis = db.components().insertSnapshot(shortLivingBranch);
- db.measures().insertMeasure(shortLivingBranch, branchAnalysis, bugs, m -> m.setValue(1d));
- db.measures().insertMeasure(shortLivingBranch, branchAnalysis, vulnerabilities, m -> m.setValue(2d));
- db.measures().insertMeasure(shortLivingBranch, branchAnalysis, codeSmells, m -> m.setValue(3d));
+ RuleDefinitionDto rule = db.rules().insert();
+ db.issues().insert(rule, shortLivingBranch, shortLivingBranch, i -> i.setType(BUG));
+ db.issues().insert(rule, shortLivingBranch, shortLivingBranch, i -> i.setType(VULNERABILITY));
+ db.issues().insert(rule, shortLivingBranch, shortLivingBranch, i -> i.setType(VULNERABILITY));
+ db.issues().insert(rule, shortLivingBranch, shortLivingBranch, i -> i.setType(CODE_SMELL));
+ db.issues().insert(rule, shortLivingBranch, shortLivingBranch, i -> i.setType(CODE_SMELL));
+ db.issues().insert(rule, shortLivingBranch, shortLivingBranch, i -> i.setType(CODE_SMELL));
+ issueIndexer.indexOnStartup(emptySet());
+ permissionIndexerTester.allowOnlyAnyone(project);
ListWsResponse response = ws.newRequest()
.setParam("project", project.getKey())