Browse Source

SONAR-6299 WS to delete a quality profile

tags/5.2-RC1
Jean-Baptiste Lievremont 9 years ago
parent
commit
8ec086fd99

+ 1
- 0
server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java View File

@@ -382,6 +382,7 @@ class ServerComponents {
pico.addSingleton(QProfileSearchAction.class);
pico.addSingleton(QProfileSetDefaultAction.class);
pico.addSingleton(QProfileProjectsAction.class);
pico.addSingleton(QProfileDeleteAction.class);
pico.addSingleton(QProfilesWs.class);
pico.addSingleton(ProfilesWs.class);
pico.addSingleton(RuleActivationActions.class);

+ 2
- 1
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileFactory.java View File

@@ -100,7 +100,7 @@ public class QProfileFactory implements ServerComponent {
* Session is NOT committed. Profiles marked as "default" for a language can't be deleted,
* except if the parameter <code>force</code> is true.
*/
void delete(DbSession session, String key, boolean force) {
public void delete(DbSession session, String key, boolean force) {
QualityProfileDto profile = db.qualityProfileDao().getNonNullByKey(session, key);
List<QualityProfileDto> descendants = db.qualityProfileDao().findDescendants(session, key);
if (!force) {
@@ -117,6 +117,7 @@ public class QProfileFactory implements ServerComponent {
}

private void doDelete(DbSession session, QualityProfileDto profile) {
db.qualityProfileDao().deleteAllProjectProfileAssociation(profile.getKey(), session);
db.activeRuleDao().deleteByProfileKey(session, profile.getKey());
db.qualityProfileDao().delete(session, profile);
}

+ 75
- 0
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileDeleteAction.java View File

@@ -0,0 +1,75 @@
/*
* 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.core.permission.GlobalPermissions;
import org.sonar.core.persistence.DbSession;
import org.sonar.server.db.DbClient;
import org.sonar.server.qualityprofile.QProfileFactory;
import org.sonar.server.user.UserSession;

public class QProfileDeleteAction implements BaseQProfileWsAction {

private final Languages languages;
private final QProfileFactory profileFactory;
private final DbClient dbClient;

public QProfileDeleteAction(Languages languages, QProfileFactory profileFactory, DbClient dbClient) {
this.languages = languages;
this.profileFactory = profileFactory;
this.dbClient = dbClient;
}

@Override
public void define(NewController controller) {
NewAction action = controller.createAction("delete")
.setDescription("Delete a quality profile and all its descendants. The default quality profile cannot be deleted.")
.setSince("5.2")
.setPost(true)
.setHandler(this);

QProfileParamUtils.defineProfileParams(action, languages);
}


@Override
public void handle(Request request, Response response) throws Exception {
UserSession.get().checkLoggedIn();
UserSession.get().checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN);


DbSession session = dbClient.openSession(false);
try {
String profileKey = QProfileParamUtils.getProfileKey(request, profileFactory, session);
profileFactory.delete(session, profileKey, false);

session.commit();
} finally {
session.close();
}

response.noContent();
}
}

+ 78
- 0
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileParamUtils.java View File

@@ -0,0 +1,78 @@
/*
* 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 com.google.common.base.Preconditions;
import org.sonar.api.resources.Languages;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.WebService.NewAction;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.qualityprofile.db.QualityProfileDto;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.qualityprofile.QProfileFactory;

import static org.apache.commons.lang.StringUtils.isEmpty;

public class QProfileParamUtils {

private static final String PARAM_LANGUAGE = "language";
private static final String PARAM_PROFILE_NAME = "profileName";
private static final String PARAM_PROFILE_KEY = "profileKey";

private QProfileParamUtils() {
// Utility class
}

public static void defineProfileParams(NewAction action, Languages languages) {
action.createParam(PARAM_PROFILE_KEY)
.setDescription("A quality profile key. Either this parameter, or a combination of profileName + language must be set.")
.setExampleValue("sonar-way-java-12345");
action.createParam(PARAM_PROFILE_NAME)
.setDescription("A quality profile name. If this parameter is set, profileKey must not be set and language must be set to disambiguate.")
.setExampleValue("Sonar way");
action.createParam(PARAM_LANGUAGE)
.setDescription("A quality profile language. If this parameter is set, profileKey must not be set and profileName must be set to disambiguate.")
.setPossibleValues(LanguageParamUtils.getLanguageKeys(languages))
.setExampleValue("js");
}

public static String getProfileKey(Request request, QProfileFactory profileFactory, DbSession session) {
String language = request.param(PARAM_LANGUAGE);
String profileName = request.param(PARAM_PROFILE_NAME);
String profileKey = request.param(PARAM_PROFILE_KEY);

Preconditions.checkArgument(
(!isEmpty(language) && !isEmpty(profileName)) ^ !isEmpty(profileKey), "Either profileKey or profileName + language must be set");

if (profileKey == null) {
profileKey = getProfileKeyFromLanguageAndName(language, profileName, profileFactory, session);
}
return profileKey;
}

private static String getProfileKeyFromLanguageAndName(String language, String profileName, QProfileFactory profileFactory, DbSession session) {
QualityProfileDto profile = profileFactory.getByNameAndLanguage(session, profileName, language);
if (profile == null) {
throw new NotFoundException(String.format("Unable to find a profile for language '%s' with name '%s'", language, profileName));
}
return profile.getKey();
}

}

+ 162
- 0
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileDeleteActionTest.java View File

@@ -0,0 +1,162 @@
/*
* 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.sonar.api.resources.Language;
import org.sonar.api.resources.Languages;
import org.sonar.api.utils.System2;
import org.sonar.core.component.ComponentDto;
import org.sonar.core.permission.GlobalPermissions;
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.component.ComponentTesting;
import org.sonar.server.component.db.ComponentDao;
import org.sonar.server.db.DbClient;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.language.LanguageTesting;
import org.sonar.server.qualityprofile.QProfileFactory;
import org.sonar.server.qualityprofile.db.ActiveRuleDao;
import org.sonar.server.rule.db.RuleDao;
import org.sonar.server.user.MockUserSession;
import org.sonar.server.ws.WsTester;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

public class QProfileDeleteActionTest {

@ClassRule
public static DbTester dbTester = new DbTester();

private DbClient dbClient;

private QualityProfileDao qualityProfileDao;

private ComponentDao componentDao;

private Language xoo1, xoo2;

private WsTester tester;

private DbSession session;

@Before
public void setUp() throws Exception {
dbTester.truncateTables();
qualityProfileDao = new QualityProfileDao(dbTester.myBatis(), mock(System2.class));
componentDao = new ComponentDao();

dbClient = new DbClient(dbTester.database(), dbTester.myBatis(), qualityProfileDao, new ActiveRuleDao(qualityProfileDao, new RuleDao()));
session = dbClient.openSession(false);

xoo1 = LanguageTesting.newLanguage("xoo1");
xoo2 = LanguageTesting.newLanguage("xoo2");

tester = new WsTester(new QProfilesWs(
mock(RuleActivationActions.class),
mock(BulkRuleActivationActions.class),
mock(ProjectAssociationActions.class),
new QProfileDeleteAction(new Languages(xoo1, xoo2), new QProfileFactory(dbClient), dbClient)));
}

@After
public void teadDown() {
session.close();
}

@Test
public void delete_nominal_with_key() throws Exception {
String profileKey = "sonar-way-xoo1-12345";

ComponentDto project = ComponentTesting.newProjectDto("polop");
componentDao.insert(session, project);
qualityProfileDao.insert(session, QualityProfileDto.createFor(profileKey).setLanguage(xoo1.getKey()).setName("Sonar way"));
qualityProfileDao.insertProjectProfileAssociation(project.uuid(), profileKey, session);
session.commit();

MockUserSession.set().setLogin("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN);

tester.newPostRequest("api/qualityprofiles", "delete").setParam("profileKey", "sonar-way-xoo1-12345").execute().assertNoContent();

assertThat(qualityProfileDao.getByKey(session, "sonar-way-xoo1-12345")).isNull();
assertThat(qualityProfileDao.selectProjects("Sonar way", xoo1.getName())).isEmpty();
}

@Test
public void delete_nominal_with_language_and_name() throws Exception {
String profileKey = "sonar-way-xoo1-12345";

ComponentDto project = ComponentTesting.newProjectDto("polop");
componentDao.insert(session, project);
qualityProfileDao.insert(session, QualityProfileDto.createFor(profileKey).setLanguage(xoo1.getKey()).setName("Sonar way"));
qualityProfileDao.insertProjectProfileAssociation(project.uuid(), profileKey, session);
session.commit();

MockUserSession.set().setLogin("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN);

tester.newPostRequest("api/qualityprofiles", "delete").setParam("profileName", "Sonar way").setParam("language", xoo1.getKey()).execute().assertNoContent();

assertThat(qualityProfileDao.getByKey(session, "sonar-way-xoo1-12345")).isNull();
assertThat(qualityProfileDao.selectProjects("Sonar way", xoo1.getName())).isEmpty();
}

@Test(expected = ForbiddenException.class)
public void fail_on_missing_permission() throws Exception {
MockUserSession.set().setLogin("obiwan");
tester.newPostRequest("api/qualityprofiles", "delete").execute();
}

@Test(expected = IllegalArgumentException.class)
public void fail_on_missing_arguments() throws Exception {
MockUserSession.set().setLogin("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN);
tester.newPostRequest("api/qualityprofiles", "delete").execute();
}

@Test(expected = IllegalArgumentException.class)
public void fail_on_missing_language() throws Exception {
MockUserSession.set().setLogin("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN);
tester.newPostRequest("api/qualityprofiles", "delete").setParam("profileName", "Polop").execute();
}

@Test(expected = IllegalArgumentException.class)
public void fail_on_missing_name() throws Exception {
MockUserSession.set().setLogin("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN);
tester.newPostRequest("api/qualityprofiles", "delete").setParam("language", xoo1.getKey()).execute();
}

@Test(expected = IllegalArgumentException.class)
public void fail_on_too_many_arguments() throws Exception {
MockUserSession.set().setLogin("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN);
tester.newPostRequest("api/qualityprofiles", "delete").setParam("profileName", "Polop").setParam("language", xoo1.getKey()).setParam("profileKey", "polop").execute();
}

@Test(expected = NotFoundException.class)
public void fail_on_unexisting_profile() throws Exception {
MockUserSession.set().setLogin("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN);
tester.newPostRequest("api/qualityprofiles", "delete").setParam("profileName", "Polop").setParam("language", xoo1.getKey()).execute();
}
}

Loading…
Cancel
Save