From: Jean-Baptiste Lievremont Date: Wed, 8 Apr 2015 08:46:05 +0000 (+0200) Subject: SONAR-6306 WS to show ancestors and children of a quality profile X-Git-Tag: 5.2-RC1~2318 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=0aaeb8c595e64a43aa1590d1bb6a4fbafe5e8826;p=sonarqube.git SONAR-6306 WS to show ancestors and children of a quality profile --- diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java index eb874b84664..23a95ec3bd2 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java @@ -389,6 +389,7 @@ class ServerComponents { pico.addSingleton(QProfileRestoreAction.class); pico.addSingleton(QProfileCreateAction.class); pico.addSingleton(QProfileImportersAction.class); + pico.addSingleton(QProfileInheritanceAction.class); pico.addSingleton(QProfilesWs.class); pico.addSingleton(ProfilesWs.class); pico.addSingleton(RuleActivationActions.class); diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileLookup.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileLookup.java index 4830b4e3d57..bd6c88cda30 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileLookup.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileLookup.java @@ -116,6 +116,12 @@ public class QProfileLookup implements ServerComponent { return toQProfiles(db.qualityProfileDao().findChildren(session, profile.key())); } + public List ancestors(QualityProfileDto profile, DbSession session) { + List ancestors = newArrayList(); + incrementAncestors(QProfile.from(profile), ancestors, session); + return ancestors; + } + public List ancestors(QProfile profile) { List ancestors = newArrayList(); DbSession session = db.openSession(false); diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileInheritanceAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileInheritanceAction.java new file mode 100644 index 00000000000..131215733b5 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileInheritanceAction.java @@ -0,0 +1,114 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.qualityprofile.ws; + +import org.sonar.api.resources.Languages; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService.NewAction; +import org.sonar.api.server.ws.WebService.NewController; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.qualityprofile.db.QualityProfileDto; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.qualityprofile.QProfile; +import org.sonar.server.qualityprofile.QProfileFactory; +import org.sonar.server.qualityprofile.QProfileLookup; + +import java.util.List; + +public class QProfileInheritanceAction implements BaseQProfileWsAction { + + private final DbClient dbClient; + + private final QProfileLookup profileLookup; + + private final QProfileFactory profileFactory; + + private final Languages languages; + + public QProfileInheritanceAction(DbClient dbClient, QProfileLookup profileLookup, QProfileFactory profileFactory, Languages languages) { + this.dbClient = dbClient; + this.profileLookup = profileLookup; + this.profileFactory = profileFactory; + this.languages = languages; + } + + @Override + public void define(NewController context) { + NewAction inheritance = context.createAction("inheritance") + .setSince("5.2") + .setDescription("Show a quality profile's ancestors and children.") + .setHandler(this) + .setResponseExample(getClass().getResource("example-inheritance.json")); + + QProfileIdentificationParamUtils.defineProfileParams(inheritance, languages); + } + + @Override + public void handle(Request request, Response response) throws Exception { + DbSession session = dbClient.openSession(false); + try { + String profileKey = QProfileIdentificationParamUtils.getProfileKeyFromParameters(request, profileFactory, session); + QualityProfileDto profile = dbClient.qualityProfileDao().getByKey(session, profileKey); + if (profile == null) { + throw new NotFoundException(String.format("Could not find a quality profile with key %s", profileKey)); + } + + List ancestors = profileLookup.ancestors(profile, session); + List children = dbClient.qualityProfileDao().findChildren(session, profileKey); + + writeResponse(response.newJsonWriter(), ancestors, children); + } finally { + session.close(); + } + } + + private void writeResponse(JsonWriter json, List ancestors, List children) { + json.beginObject(); + writeAncestors(json, ancestors); + writeChildren(json, children); + json.endObject().close(); + } + + private void writeAncestors(JsonWriter json, List ancestors) { + json.name("ancestors").beginArray(); + for (QProfile ancestor : ancestors) { + json.beginObject() + .prop("key", ancestor.key()) + .prop("name", ancestor.name()) + .prop("parent", ancestor.parent()) + .endObject(); + } + json.endArray(); + } + + private void writeChildren(JsonWriter json, List children) { + json.name("children").beginArray(); + for (QualityProfileDto child : children) { + json.beginObject() + .prop("key", child.getKey()) + .prop("name", child.getName()) + .endObject(); + } + json.endArray(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileInheritanceActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileInheritanceActionTest.java new file mode 100644 index 00000000000..4231d26966b --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileInheritanceActionTest.java @@ -0,0 +1,96 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.qualityprofile.ws; + +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.sonar.api.utils.System2; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.DbTester; +import org.sonar.core.qualityprofile.db.QualityProfileDao; +import org.sonar.core.qualityprofile.db.QualityProfileDto; +import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.language.LanguageTesting; +import org.sonar.server.qualityprofile.QProfileFactory; +import org.sonar.server.qualityprofile.QProfileLookup; +import org.sonar.server.qualityprofile.QProfileName; +import org.sonar.server.qualityprofile.QProfileTesting; +import org.sonar.server.ws.WsTester; +import org.sonar.test.DbTests; + +import static org.mockito.Mockito.mock; + +@Category(DbTests.class) +public class QProfileInheritanceActionTest { + + @ClassRule + public static final DbTester dbTester = new DbTester(); + + private WsTester wsTester; + + private DbClient dbClient; + + private DbSession session; + + @Before + public void setUp() throws Exception { + dbTester.truncateTables(); + dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), + new QualityProfileDao(dbTester.myBatis(), mock(System2.class))); + session = dbClient.openSession(false); + + wsTester = new WsTester(new QProfilesWs( + mock(RuleActivationActions.class), + mock(BulkRuleActivationActions.class), + mock(ProjectAssociationActions.class), + new QProfileInheritanceAction(dbClient, new QProfileLookup(dbClient), new QProfileFactory(dbClient), LanguageTesting.newLanguages("xoo")))); + } + + @After + public void tearDown() { + session.close(); + } + + @Test + public void inheritance_nominal() throws Exception { + /* + * groupWide <- companyWide <- buWide <- (forProject1, forProject2) + */ + QualityProfileDto groupWide = QProfileTesting.newDto(QProfileName.createFor("xoo", "My Group Profile"), "xoo-my-group-profile-01234"); + QualityProfileDto companyWide = QProfileTesting.newDto(QProfileName.createFor("xoo", "My Company Profile"), "xoo-my-company-profile-12345").setParentKee(groupWide.getKee()); + QualityProfileDto buWide = QProfileTesting.newDto(QProfileName.createFor("xoo", "My BU Profile"), "xoo-my-by-profile-23456").setParentKee(companyWide.getKee()); + QualityProfileDto forProject1 = QProfileTesting.newDto(QProfileName.createFor("xoo", "For Project One"), "xoo-for-project-one-34567").setParentKee(buWide.getKee()); + QualityProfileDto forProject2 = QProfileTesting.newDto(QProfileName.createFor("xoo", "For Project Two"), "xoo-for-project-two-45678").setParentKee(buWide.getKee()); + + dbClient.qualityProfileDao().insert(session, groupWide, companyWide, buWide, forProject1, forProject2); + session.commit(); + + wsTester.newGetRequest("api/qualityprofiles", "inheritance").setParam("profileKey", buWide.getKee()).execute().assertJson(getClass(), "inheritance-buWide.json"); + } + + @Test(expected = NotFoundException.class) + public void fail_if_not_found() throws Exception { + wsTester.newGetRequest("api/qualityprofiles", "inheritance").setParam("profileKey", "polop").execute(); + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileInheritanceActionTest/inheritance-buWide.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileInheritanceActionTest/inheritance-buWide.json new file mode 100644 index 00000000000..154c25e3f13 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileInheritanceActionTest/inheritance-buWide.json @@ -0,0 +1,10 @@ +{ + "ancestors": [ + {"key": "xoo-my-company-profile-12345", "name": "My Company Profile", "parent": "xoo-my-group-profile-01234"}, + {"key": "xoo-my-group-profile-01234", "name": "My Group Profile"} + ], + "children": [ + {"key": "xoo-for-project-one-34567", "name": "For Project One"}, + {"key": "xoo-for-project-two-45678", "name": "For Project Two"} + ] +} \ No newline at end of file