From: Jean-Baptiste Lievremont Date: Fri, 3 Apr 2015 13:08:33 +0000 (+0200) Subject: SONAR-6305 WS to restore a quality profile X-Git-Tag: 5.2-RC1~2334 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=fc06f3f4fc7f700fef817873a318b3d8378ec310;p=sonarqube.git SONAR-6305 WS to restore 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 720d51d5c6d..9710751594a 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 @@ -386,6 +386,7 @@ class ServerComponents { pico.addSingleton(QProfileRenameAction.class); pico.addSingleton(QProfileCopyAction.class); pico.addSingleton(QProfileBackupAction.class); + pico.addSingleton(QProfileRestoreAction.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/QProfileBackuper.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileBackuper.java index 1b9365c692c..5110006f25c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileBackuper.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileBackuper.java @@ -100,7 +100,7 @@ public class QProfileBackuper implements ServerComponent { * @param toProfileName the target profile. If null, then use the * lang and name declared in the backup */ - BulkChangeResult restore(Reader reader, @Nullable QProfileName toProfileName) { + public BulkChangeResult restore(Reader reader, @Nullable QProfileName toProfileName) { try { String profileLang = null, profileName = null; List ruleActivations = Lists.newArrayList(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileProjectsAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileProjectsAction.java index 9755a806fe7..6dccf049159 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileProjectsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileProjectsAction.java @@ -66,7 +66,8 @@ public class QProfileProjectsAction implements BaseQProfileWsAction { NewAction projects = controller.createAction("projects") .setSince("5.2") .setHandler(this) - .setDescription("List projects with their association status regarding a quality profile."); + .setDescription("List projects with their association status regarding a quality profile.") + .setResponseExample(getClass().getResource("example-projects.json")); projects.createParam(PARAM_KEY) .setDescription("A quality profile key.") .setRequired(true) diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileRestoreAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileRestoreAction.java new file mode 100644 index 00000000000..258508c11b0 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileRestoreAction.java @@ -0,0 +1,65 @@ +/* + * 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.Charsets; +import com.google.common.base.Preconditions; +import org.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.qualityprofile.QProfileBackuper; +import org.sonar.server.user.UserSession; + +import java.io.InputStream; +import java.io.InputStreamReader; + +public class QProfileRestoreAction implements BaseQProfileWsAction { + + private static final String PARAM_BACKUP = "backup"; + private final QProfileBackuper backuper; + + public QProfileRestoreAction(QProfileBackuper backuper) { + this.backuper = backuper; + } + + @Override + public void handle(Request request, Response response) throws Exception { + UserSession.get().checkLoggedIn().checkGlobalPermission(GlobalPermissions.QUALITY_PROFILE_ADMIN); + InputStream backup = request.paramAsInputStream(PARAM_BACKUP); + Preconditions.checkArgument(backup != null, "A backup file must be provided"); + + backuper.restore(new InputStreamReader(backup, Charsets.UTF_8), null); + response.noContent(); + } + + @Override + public void define(WebService.NewController controller) { + controller.createAction("restore") + .setSince("5.2") + .setDescription("Restore a quality profile using an XML file.") + .setPost(true) + .setHandler(this) + .createParam(PARAM_BACKUP) + .setDescription("A profile backup file in XML format, as generated by api/qualityprofiles/backup " + + "or the former api/profiles/backup."); + } + +} diff --git a/server/sonar-server/src/main/resources/org/sonar/server/qualityprofile/ws/example-projects.json b/server/sonar-server/src/main/resources/org/sonar/server/qualityprofile/ws/example-projects.json new file mode 100644 index 00000000000..9aff0b78fc0 --- /dev/null +++ b/server/sonar-server/src/main/resources/org/sonar/server/qualityprofile/ws/example-projects.json @@ -0,0 +1,52 @@ +{ + "results": + [ + { + "key": "5eab015a-1f76-4ba4-bd89-bf547132d673", + "name": "JavaScript Plugin", + "selected": true + }, + { + "key": "f1ab623e-d00d-401b-bf9e-c45e91976bf0", + "name": "Jenkins SonarQube Plugin", + "selected": false + }, + { + "key": "69e57151-be0d-4157-adff-c06741d88879", + "name": "SonarQube", + "selected": false + }, + { + "key": "c355a0fe-9b77-4d39-9837-8364a41ce10d", + "name": "SonarQube Android Plugin", + "selected": false + }, + { + "key": "1ef05695-f234-4125-8fb9-24880c9f0b20", + "name": "SonarQube C# Plugin", + "selected": false + }, + { + "key": "56afe010-f83b-4d97-b256-5443c763ba29", + "name": "SonarQube Groovy Plugin", + "selected": false + }, + { + "key": "dd7c3556-ce3f-42d0-a348-914a582dc944", + "name": "SonarQube Java", + "selected": true + }, + { + "key": "ba422ef1-794e-4a4c-be6d-9ce77b4cd5fa", + "name": "SonarQube Maven Plugin", + "selected": false + }, + { + "key": "6899e06b-4a34-4966-80f1-073a658bee03", + "name": "SonarQube Web Plugin", + "selected": false + } + ], + + "more": false +} \ No newline at end of file diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileRestoreActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileRestoreActionTest.java new file mode 100644 index 00000000000..07106e359ca --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileRestoreActionTest.java @@ -0,0 +1,80 @@ +/* + * 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.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.qualityprofile.QProfileBackuper; +import org.sonar.server.qualityprofile.QProfileName; +import org.sonar.server.user.MockUserSession; +import org.sonar.server.ws.WsTester; + +import java.io.Reader; + +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +@RunWith(MockitoJUnitRunner.class) +public class QProfileRestoreActionTest { + + // TODO Replace with proper DbTester + EsTester medium test once DaoV2 is removed + @Mock + private QProfileBackuper backuper; + + private WsTester tester; + + @Before + public void setUp() throws Exception { + tester = new WsTester(new QProfilesWs( + mock(RuleActivationActions.class), + mock(BulkRuleActivationActions.class), + mock(ProjectAssociationActions.class), + new QProfileRestoreAction(backuper))); + } + + @Test + public void restore_profile() throws Exception { + MockUserSession.set().setLogin("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + tester.newPostRequest("api/qualityprofiles", "restore").setParam("backup", "").execute(); + verify(backuper).restore(any(Reader.class), (QProfileName) eq(null)); + } + + @Test(expected = IllegalArgumentException.class) + public void fail_on_missing_backup() throws Exception { + MockUserSession.set().setLogin("obiwan").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN); + + tester.newGetRequest("api/qualityprofiles", "restore").execute(); + } + + @Test(expected = ForbiddenException.class) + public void fail_on_misssing_permission() throws Exception { + MockUserSession.set().setLogin("obiwan"); + + tester.newPostRequest("api/qualityprofiles", "restore").setParam("backup", "").execute(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java index c8900b7c00c..e7885696f70 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java @@ -54,7 +54,9 @@ public class QProfilesWsTest { new QProfileRestoreBuiltInAction(null), new QProfileSearchAction(languages, null, null), new QProfileSetDefaultAction(languages, null, null), - new QProfileBackupAction(null) + new QProfileProjectsAction(null), + new QProfileBackupAction(null), + new QProfileRestoreAction(null) )).controller(QProfilesWs.API_ENDPOINT); } @@ -63,7 +65,7 @@ public class QProfilesWsTest { assertThat(controller).isNotNull(); assertThat(controller.path()).isEqualTo(QProfilesWs.API_ENDPOINT); assertThat(controller.description()).isNotEmpty(); - assertThat(controller.actions()).hasSize(9); + assertThat(controller.actions()).hasSize(12); } @Test @@ -125,6 +127,31 @@ public class QProfilesWsTest { assertThat(setDefault.params()).hasSize(3); } + @Test + public void define_projects_action() throws Exception { + WebService.Action projects = controller.action("projects"); + assertThat(projects).isNotNull(); + assertThat(projects.isPost()).isFalse(); + assertThat(projects.params()).hasSize(5); + assertThat(projects.responseExampleAsString()).isNotEmpty(); + } + + @Test + public void define_backup_action() throws Exception { + WebService.Action backup = controller.action("backup"); + assertThat(backup).isNotNull(); + assertThat(backup.isPost()).isFalse(); + assertThat(backup.params()).hasSize(1); + } + + @Test + public void define_restore_action() throws Exception { + WebService.Action restore = controller.action("restore"); + assertThat(restore).isNotNull(); + assertThat(restore.isPost()).isTrue(); + assertThat(restore.params()).hasSize(1); + } + public void define_bulk_activate_rule_action() throws Exception { WebService.Action restoreProfiles = controller.action(BulkRuleActivationActions.BULK_ACTIVATE_ACTION); assertThat(restoreProfiles).isNotNull();