aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>2015-04-03 15:08:33 +0200
committerJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>2015-04-09 09:44:15 +0200
commitfc06f3f4fc7f700fef817873a318b3d8378ec310 (patch)
treeaa18a6ec629c0ddd8414f41a937c257f1dbc8130 /server
parent9d5ef51098e460fe753e46dedbc109ad1be0d6d8 (diff)
downloadsonarqube-fc06f3f4fc7f700fef817873a318b3d8378ec310.tar.gz
sonarqube-fc06f3f4fc7f700fef817873a318b3d8378ec310.zip
SONAR-6305 WS to restore a quality profile
Diffstat (limited to 'server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java1
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileBackuper.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileProjectsAction.java3
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileRestoreAction.java65
-rw-r--r--server/sonar-server/src/main/resources/org/sonar/server/qualityprofile/ws/example-projects.json52
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileRestoreActionTest.java80
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java31
7 files changed, 230 insertions, 4 deletions
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 <code>null</code>, 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<RuleActivation> 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", "<polop><palap/></polop>").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", "<polop><palap/></polop>").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();