@@ -20,17 +20,35 @@ | |||
package org.sonar.server.qualityprofile; | |||
import com.google.common.collect.Lists; | |||
import org.sonar.core.qualityprofile.db.QualityProfileDto; | |||
import org.sonar.server.exceptions.Errors; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import java.util.Collection; | |||
import java.util.List; | |||
public class BulkChangeResult { | |||
private final QualityProfileDto profile; | |||
private final Errors errors = new Errors(); | |||
private int succeeded = 0, failed = 0; | |||
private final List<ActiveRuleChange> changes = Lists.newArrayList(); | |||
public BulkChangeResult() { | |||
this(null); | |||
} | |||
public BulkChangeResult(@Nullable QualityProfileDto profile) { | |||
this.profile = profile; | |||
} | |||
@CheckForNull | |||
public QualityProfileDto profile() { | |||
return profile; | |||
} | |||
public Errors getErrors() { | |||
return errors; | |||
} |
@@ -125,7 +125,7 @@ public class QProfileReset implements ServerComponent { | |||
*/ | |||
private BulkChangeResult doReset(DbSession dbSession, QualityProfileDto profile, Collection<RuleActivation> activations) { | |||
Preconditions.checkNotNull(profile.getId(), "Quality profile must be persisted"); | |||
BulkChangeResult result = new BulkChangeResult(); | |||
BulkChangeResult result = new BulkChangeResult(profile); | |||
Set<RuleKey> ruleToBeDeactivated = Sets.newHashSet(); | |||
// Keep reference to all the activated rules before backup restore | |||
for (ActiveRuleDto activeRuleDto : db.activeRuleDao().findByProfileKey(dbSession, profile.getKee())) { |
@@ -22,10 +22,14 @@ package org.sonar.server.qualityprofile.ws; | |||
import com.google.common.base.Charsets; | |||
import com.google.common.base.Preconditions; | |||
import org.apache.commons.io.IOUtils; | |||
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; | |||
import org.sonar.api.utils.text.JsonWriter; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.core.qualityprofile.db.QualityProfileDto; | |||
import org.sonar.server.qualityprofile.BulkChangeResult; | |||
import org.sonar.server.qualityprofile.QProfileBackuper; | |||
import org.sonar.server.user.UserSession; | |||
@@ -36,9 +40,11 @@ public class QProfileRestoreAction implements BaseQProfileWsAction { | |||
private static final String PARAM_BACKUP = "backup"; | |||
private final QProfileBackuper backuper; | |||
private final Languages languages; | |||
public QProfileRestoreAction(QProfileBackuper backuper) { | |||
public QProfileRestoreAction(QProfileBackuper backuper, Languages languages) { | |||
this.backuper = backuper; | |||
this.languages = languages; | |||
} | |||
@Override | |||
@@ -64,11 +70,29 @@ public class QProfileRestoreAction implements BaseQProfileWsAction { | |||
try { | |||
Preconditions.checkArgument(backup != null, "A backup file must be provided"); | |||
reader = new InputStreamReader(backup, Charsets.UTF_8); | |||
backuper.restore(reader, null); | |||
response.noContent(); | |||
BulkChangeResult result = backuper.restore(reader, null); | |||
writeResponse(response.newJsonWriter(), result); | |||
} finally { | |||
IOUtils.closeQuietly(reader); | |||
IOUtils.closeQuietly(backup); | |||
} | |||
} | |||
private void writeResponse(JsonWriter json, BulkChangeResult result) { | |||
QualityProfileDto profile = result.profile(); | |||
if (profile != null) { | |||
String language = profile.getLanguage(); | |||
json.beginObject().name("profile").beginObject() | |||
.prop("key", profile.getKey()) | |||
.prop("name", profile.getName()) | |||
.prop("language", language) | |||
.prop("languageName", languages.get(profile.getLanguage()).getName()) | |||
.prop("isDefault", false) | |||
.prop("isInherited", false) | |||
.endObject(); | |||
} | |||
json.prop("ruleSuccesses", result.countSucceeded()); | |||
json.prop("ruleFailures", result.countFailed()); | |||
json.endObject().close(); | |||
} | |||
} |
@@ -25,7 +25,10 @@ import org.junit.runner.RunWith; | |||
import org.mockito.Mock; | |||
import org.mockito.runners.MockitoJUnitRunner; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.core.qualityprofile.db.QualityProfileDto; | |||
import org.sonar.server.exceptions.ForbiddenException; | |||
import org.sonar.server.language.LanguageTesting; | |||
import org.sonar.server.qualityprofile.BulkChangeResult; | |||
import org.sonar.server.qualityprofile.QProfileBackuper; | |||
import org.sonar.server.qualityprofile.QProfileName; | |||
import org.sonar.server.user.MockUserSession; | |||
@@ -37,6 +40,7 @@ import static org.mockito.Matchers.any; | |||
import static org.mockito.Matchers.eq; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.verify; | |||
import static org.mockito.Mockito.when; | |||
@RunWith(MockitoJUnitRunner.class) | |||
public class QProfileRestoreActionTest { | |||
@@ -53,14 +57,20 @@ public class QProfileRestoreActionTest { | |||
mock(RuleActivationActions.class), | |||
mock(BulkRuleActivationActions.class), | |||
mock(ProjectAssociationActions.class), | |||
new QProfileRestoreAction(backuper))); | |||
new QProfileRestoreAction(backuper, LanguageTesting.newLanguages("xoo")))); | |||
} | |||
@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(); | |||
QualityProfileDto profile = QualityProfileDto.createFor("xoo-sonar-way-12345") | |||
.setDefault(false).setLanguage("xoo").setName("Sonar way"); | |||
BulkChangeResult restoreResult = new BulkChangeResult(profile); | |||
when(backuper.restore(any(Reader.class), (QProfileName) eq(null))).thenReturn(restoreResult); | |||
tester.newPostRequest("api/qualityprofiles", "restore").setParam("backup", "<polop><palap/></polop>").execute() | |||
.assertJson(getClass(), "restore_profile.json"); | |||
verify(backuper).restore(any(Reader.class), (QProfileName) eq(null)); | |||
} | |||
@@ -66,7 +66,7 @@ public class QProfilesWsTest { | |||
new QProfileSetDefaultAction(languages, null, null), | |||
new QProfileProjectsAction(null), | |||
new QProfileBackupAction(null, null, null, languages), | |||
new QProfileRestoreAction(null) | |||
new QProfileRestoreAction(null, languages) | |||
)).controller(QProfilesWs.API_ENDPOINT); | |||
} | |||
@@ -0,0 +1,11 @@ | |||
{ | |||
"profile": { | |||
"name": "Sonar way", | |||
"language": "xoo", | |||
"languageName": "Xoo", | |||
"isDefault": false, | |||
"isInherited": false | |||
}, | |||
"ruleSuccesses": 0, | |||
"ruleFailures": 0 | |||
} |