Skip to content

Commit

Permalink
SONAR-8857 clean-up opening of DbSession
Browse files Browse the repository at this point in the history
  • Loading branch information
Simon Brandhof authored and sns-seb committed Mar 23, 2017
1 parent 56a036a commit 86aa29e
Show file tree
Hide file tree
Showing 15 changed files with 145 additions and 153 deletions.
Expand Up @@ -61,17 +61,6 @@ public QProfileBackuper(QProfileReset reset, DbClient db) {
this.db = db; this.db = db;
} }


/**
* @deprecated use {@link #backup(DbSession, QualityProfileDto, Writer)} instead
*/
@Deprecated
public void backup(String key, Writer writer) {
try (DbSession dbSession = db.openSession(false)) {
QualityProfileDto profile = db.qualityProfileDao().selectOrFailByKey(dbSession, key);
backup(dbSession, profile, writer);
}
}

public void backup(DbSession dbSession, QualityProfileDto profileDto, Writer writer) { public void backup(DbSession dbSession, QualityProfileDto profileDto, Writer writer) {
List<ActiveRuleDto> activeRules = db.activeRuleDao().selectByProfileKey(dbSession, profileDto.getKey()); List<ActiveRuleDto> activeRules = db.activeRuleDao().selectByProfileKey(dbSession, profileDto.getKey());
activeRules.sort(BackupActiveRuleComparator.INSTANCE); activeRules.sort(BackupActiveRuleComparator.INSTANCE);
Expand Down Expand Up @@ -109,7 +98,7 @@ private void writeXml(DbSession dbSession, Writer writer, QualityProfileDto prof
* @param toProfileName the target profile. If <code>null</code>, then use the * @param toProfileName the target profile. If <code>null</code>, then use the
* lang and name declared in the backup * lang and name declared in the backup
*/ */
public BulkChangeResult restore(Reader reader, @Nullable QProfileName toProfileName) { public BulkChangeResult restore(DbSession dbSession, Reader reader, @Nullable QProfileName toProfileName) {
try { try {
String profileLang = null; String profileLang = null;
String profileName = null; String profileName = null;
Expand All @@ -136,7 +125,7 @@ public BulkChangeResult restore(Reader reader, @Nullable QProfileName toProfileN
} }


QProfileName target = (QProfileName) ObjectUtils.defaultIfNull(toProfileName, new QProfileName(profileLang, profileName)); QProfileName target = (QProfileName) ObjectUtils.defaultIfNull(toProfileName, new QProfileName(profileLang, profileName));
return reset.reset(target, ruleActivations); return reset.reset(dbSession, target, ruleActivations);
} catch (XMLStreamException e) { } catch (XMLStreamException e) {
throw new IllegalStateException("Fail to restore Quality profile backup", e); throw new IllegalStateException("Fail to restore Quality profile backup", e);
} }
Expand Down
Expand Up @@ -25,9 +25,7 @@
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.Reader; import java.io.Reader;
import java.io.Writer; import java.io.Writer;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.sonar.api.server.ServerSide; import org.sonar.api.server.ServerSide;
import org.sonar.api.utils.TempFolder; import org.sonar.api.utils.TempFolder;
Expand All @@ -36,6 +34,8 @@
import org.sonar.db.qualityprofile.QualityProfileDto; import org.sonar.db.qualityprofile.QualityProfileDto;
import org.sonar.server.qualityprofile.ws.QProfileWsSupport; import org.sonar.server.qualityprofile.ws.QProfileWsSupport;


import static java.nio.charset.StandardCharsets.UTF_8;

@ServerSide @ServerSide
public class QProfileCopier { public class QProfileCopier {


Expand All @@ -53,38 +53,32 @@ public QProfileCopier(DbClient db, QProfileFactory factory, QProfileBackuper bac
this.qProfileWsSupport = qProfileWsSupport; this.qProfileWsSupport = qProfileWsSupport;
} }


public QualityProfileDto copyToName(String fromProfileKey, String toName) { public QualityProfileDto copyToName(DbSession dbSession, String fromProfileKey, String toName) {
QualityProfileDto to = prepareTarget(fromProfileKey, toName); QualityProfileDto from = db.qualityProfileDao().selectOrFailByKey(dbSession, fromProfileKey);
QualityProfileDto to = prepareTarget(dbSession, from, toName);
File backupFile = temp.newFile(); File backupFile = temp.newFile();
try { try {
backup(fromProfileKey, backupFile); backup(dbSession, from, backupFile);
restore(backupFile, QProfileName.createFor(to.getLanguage(), to.getName())); restore(dbSession, backupFile, QProfileName.createFor(to.getLanguage(), to.getName()));
return to; return to;
} finally { } finally {
org.sonar.core.util.FileUtils.deleteQuietly(backupFile); org.sonar.core.util.FileUtils.deleteQuietly(backupFile);
} }
} }


private QualityProfileDto prepareTarget(String fromProfileKey, String toName) { private QualityProfileDto prepareTarget(DbSession dbSession, QualityProfileDto from, String toName) {
DbSession dbSession = db.openSession(false); QProfileName toProfileName = new QProfileName(from.getLanguage(), toName);
try { verify(from, toProfileName);
QualityProfileDto fromProfile = db.qualityProfileDao().selectOrFailByKey(dbSession, fromProfileKey); QualityProfileDto toProfile = db.qualityProfileDao().selectByNameAndLanguage(toProfileName.getName(), toProfileName.getLanguage(), dbSession);
QProfileName toProfileName = new QProfileName(fromProfile.getLanguage(), toName); if (toProfile == null) {
verify(fromProfile, toProfileName); // Do not delegate creation to QProfileBackuper because we need to keep
QualityProfileDto toProfile = db.qualityProfileDao().selectByNameAndLanguage(toProfileName.getName(), toProfileName.getLanguage(), dbSession); // the parent-child association, if exists.
if (toProfile == null) { toProfile = factory.create(dbSession, qProfileWsSupport.getDefaultOrganization(dbSession), toProfileName);
// Do not delegate creation to QProfileBackuper because we need to keep toProfile.setParentKee(from.getParentKee());
// the parent-child association, if exists. db.qualityProfileDao().update(dbSession, toProfile);
toProfile = factory.create(dbSession, qProfileWsSupport.getDefaultOrganization(dbSession), toProfileName); dbSession.commit();
toProfile.setParentKee(fromProfile.getParentKee());
db.qualityProfileDao().update(dbSession, toProfile);
dbSession.commit();
}
return toProfile;

} finally {
dbSession.close();
} }
return toProfile;
} }


private void verify(QualityProfileDto fromProfile, QProfileName toProfileName) { private void verify(QualityProfileDto fromProfile, QProfileName toProfileName) {
Expand All @@ -99,27 +93,19 @@ private void verify(QualityProfileDto fromProfile, QProfileName toProfileName) {
} }
} }


private void backup(String profileKey, File backupFile) { private void backup(DbSession dbSession, QualityProfileDto profile, File backupFile) {
Writer writer = null; try (Writer writer = new OutputStreamWriter(FileUtils.openOutputStream(backupFile), UTF_8)) {
try { backuper.backup(dbSession, profile, writer);
writer = new OutputStreamWriter(FileUtils.openOutputStream(backupFile), StandardCharsets.UTF_8);
backuper.backup(profileKey, writer);
} catch (IOException e) { } catch (IOException e) {
throw new IllegalStateException("Fail to open temporary backup file: " + backupFile, e); throw new IllegalStateException("Fail to open temporary backup file: " + backupFile, e);
} finally {
IOUtils.closeQuietly(writer);
} }
} }


private void restore(File backupFile, QProfileName profileName) { private void restore(DbSession dbSession, File backupFile, QProfileName profileName) {
Reader reader = null; try (Reader reader = new InputStreamReader(FileUtils.openInputStream(backupFile), UTF_8)) {
try { backuper.restore(dbSession, reader, profileName);
reader = new InputStreamReader(FileUtils.openInputStream(backupFile), StandardCharsets.UTF_8);
backuper.restore(reader, profileName);
} catch (IOException e) { } catch (IOException e) {
throw new IllegalStateException("Fail to create temporary backup file: " + backupFile, e); throw new IllegalStateException("Fail to create temporary backup file: " + backupFile, e);
} finally {
IOUtils.closeQuietly(reader);
} }
} }
} }
Expand Up @@ -77,48 +77,38 @@ public QProfileReset(DbClient db, RuleActivator activator, ActiveRuleIndexer act
* Reset built-in profiles for the given language. Missing profiles are created and * Reset built-in profiles for the given language. Missing profiles are created and
* existing ones are updated. * existing ones are updated.
*/ */
public void resetLanguage(String language) { public void resetLanguage(DbSession dbSession, String language) {
DbSession dbSession = db.openSession(false); ListMultimap<QProfileName, RulesProfile> profilesByName = loadDefinitionsGroupedByName(language);
try { for (Map.Entry<QProfileName, Collection<RulesProfile>> entry : profilesByName.asMap().entrySet()) {
ListMultimap<QProfileName, RulesProfile> profilesByName = loadDefinitionsGroupedByName(language); QProfileName profileName = entry.getKey();
for (Map.Entry<QProfileName, Collection<RulesProfile>> entry : profilesByName.asMap().entrySet()) { QualityProfileDto profile = factory.getOrCreate(dbSession, qProfileWsSupport.getDefaultOrganization(dbSession), profileName);
QProfileName profileName = entry.getKey(); List<RuleActivation> activations = Lists.newArrayList();
QualityProfileDto profile = factory.getOrCreate(dbSession, qProfileWsSupport.getDefaultOrganization(dbSession), profileName); for (RulesProfile def : entry.getValue()) {
List<RuleActivation> activations = Lists.newArrayList(); for (ActiveRule activeRule : def.getActiveRules()) {
for (RulesProfile def : entry.getValue()) { RuleActivation activation = new RuleActivation(RuleKey.of(activeRule.getRepositoryKey(), activeRule.getRuleKey()));
for (ActiveRule activeRule : def.getActiveRules()) { activation.setSeverity(activeRule.getSeverity().name());
RuleActivation activation = new RuleActivation(RuleKey.of(activeRule.getRepositoryKey(), activeRule.getRuleKey())); if (!activeRule.getActiveRuleParams().isEmpty()) {
activation.setSeverity(activeRule.getSeverity().name()); for (ActiveRuleParam param : activeRule.getActiveRuleParams()) {
if (!activeRule.getActiveRuleParams().isEmpty()) { activation.setParameter(param.getParamKey(), param.getValue());
for (ActiveRuleParam param : activeRule.getActiveRuleParams()) { }
activation.setParameter(param.getParamKey(), param.getValue()); } else {
} for (RuleParamDto param : db.ruleDao().selectRuleParamsByRuleKey(dbSession, activeRule.getRule().ruleKey())) {
} else { activation.setParameter(param.getName(), param.getDefaultValue());
for (RuleParamDto param : db.ruleDao().selectRuleParamsByRuleKey(dbSession, activeRule.getRule().ruleKey())) {
activation.setParameter(param.getName(), param.getDefaultValue());
}
} }
activations.add(activation);
} }
activations.add(activation);
} }
doReset(dbSession, profile, activations);
} }
} finally { doReset(dbSession, profile, activations);
dbSession.close();
} }
} }


/** /**
* Reset the profile, which is created if it does not exist * Reset the profile, which is created if it does not exist
*/ */
BulkChangeResult reset(QProfileName profileName, Collection<RuleActivation> activations) { BulkChangeResult reset(DbSession dbSession, QProfileName profileName, Collection<RuleActivation> activations) {
DbSession dbSession = db.openSession(false); QualityProfileDto profile = factory.getOrCreate(dbSession, qProfileWsSupport.getDefaultOrganization(dbSession), profileName);
try { return doReset(dbSession, profile, activations);
QualityProfileDto profile = factory.getOrCreate(dbSession, qProfileWsSupport.getDefaultOrganization(dbSession), profileName);
return doReset(dbSession, profile, activations);
} finally {
dbSession.close();
}
} }


/** /**
Expand Down
Expand Up @@ -25,6 +25,8 @@
import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService;
import org.sonar.api.server.ws.WebService.NewAction; import org.sonar.api.server.ws.WebService.NewAction;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.qualityprofile.QualityProfileDto; import org.sonar.db.qualityprofile.QualityProfileDto;
import org.sonar.server.qualityprofile.QProfileCopier; import org.sonar.server.qualityprofile.QProfileCopier;


Expand All @@ -33,11 +35,13 @@ public class CopyAction implements QProfileWsAction {
private static final String PARAM_PROFILE_NAME = "toName"; private static final String PARAM_PROFILE_NAME = "toName";
private static final String PARAM_PROFILE_KEY = "fromKey"; private static final String PARAM_PROFILE_KEY = "fromKey";


private final DbClient dbClient;
private final QProfileCopier profileCopier; private final QProfileCopier profileCopier;
private final Languages languages; private final Languages languages;
private final QProfileWsSupport qProfileWsSupport; private final QProfileWsSupport qProfileWsSupport;


public CopyAction(QProfileCopier profileCopier, Languages languages, QProfileWsSupport qProfileWsSupport) { public CopyAction(DbClient dbClient, QProfileCopier profileCopier, Languages languages, QProfileWsSupport qProfileWsSupport) {
this.dbClient = dbClient;
this.profileCopier = profileCopier; this.profileCopier = profileCopier;
this.languages = languages; this.languages = languages;
this.qProfileWsSupport = qProfileWsSupport; this.qProfileWsSupport = qProfileWsSupport;
Expand Down Expand Up @@ -69,20 +73,22 @@ public void handle(Request request, Response response) throws Exception {
String newName = request.mandatoryParam(PARAM_PROFILE_NAME); String newName = request.mandatoryParam(PARAM_PROFILE_NAME);
String profileKey = request.mandatoryParam(PARAM_PROFILE_KEY); String profileKey = request.mandatoryParam(PARAM_PROFILE_KEY);


QualityProfileDto copiedProfile = profileCopier.copyToName(profileKey, newName); try (DbSession dbSession = dbClient.openSession(false)) {
QualityProfileDto copiedProfile = profileCopier.copyToName(dbSession, profileKey, newName);


String languageKey = copiedProfile.getLanguage(); String languageKey = copiedProfile.getLanguage();
Language language = languages.get(copiedProfile.getLanguage()); Language language = languages.get(copiedProfile.getLanguage());
String parentKey = copiedProfile.getParentKee(); String parentKey = copiedProfile.getParentKee();
response.newJsonWriter() response.newJsonWriter()
.beginObject() .beginObject()
.prop("key", copiedProfile.getKey()) .prop("key", copiedProfile.getKey())
.prop("name", copiedProfile.getName()) .prop("name", copiedProfile.getName())
.prop("language", languageKey) .prop("language", languageKey)
.prop("languageName", language == null ? null : language.getName()) .prop("languageName", language == null ? null : language.getName())
.prop("isDefault", copiedProfile.isDefault()) .prop("isDefault", copiedProfile.isDefault())
.prop("isInherited", parentKey != null) .prop("isInherited", parentKey != null)
.prop("parentKey", parentKey) .prop("parentKey", parentKey)
.endObject().close(); .endObject().close();
}
} }
} }
Expand Up @@ -29,6 +29,8 @@
import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.text.JsonWriter; import org.sonar.api.utils.text.JsonWriter;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.qualityprofile.QualityProfileDto; import org.sonar.db.qualityprofile.QualityProfileDto;
import org.sonar.server.qualityprofile.BulkChangeResult; import org.sonar.server.qualityprofile.BulkChangeResult;
import org.sonar.server.qualityprofile.QProfileBackuper; import org.sonar.server.qualityprofile.QProfileBackuper;
Expand All @@ -44,11 +46,14 @@
public class OldRestoreAction implements WsAction { public class OldRestoreAction implements WsAction {


private static final String PARAM_BACKUP = "backup"; private static final String PARAM_BACKUP = "backup";

private final DbClient dbClient;
private final QProfileBackuper backuper; private final QProfileBackuper backuper;
private final Languages languages; private final Languages languages;
private final QProfileWsSupport qProfileWsSupport; private final QProfileWsSupport qProfileWsSupport;


public OldRestoreAction(QProfileBackuper backuper, Languages languages, QProfileWsSupport qProfileWsSupport) { public OldRestoreAction(DbClient dbClient, QProfileBackuper backuper, Languages languages, QProfileWsSupport qProfileWsSupport) {
this.dbClient = dbClient;
this.backuper = backuper; this.backuper = backuper;
this.languages = languages; this.languages = languages;
this.qProfileWsSupport = qProfileWsSupport; this.qProfileWsSupport = qProfileWsSupport;
Expand Down Expand Up @@ -77,10 +82,10 @@ public void handle(Request request, Response response) throws Exception {
InputStream backup = request.paramAsInputStream(PARAM_BACKUP); InputStream backup = request.paramAsInputStream(PARAM_BACKUP);
InputStreamReader reader = null; InputStreamReader reader = null;


try { try (DbSession dbSession = dbClient.openSession(false)) {
checkArgument(backup != null, "A backup file must be provided"); checkArgument(backup != null, "A backup file must be provided");
reader = new InputStreamReader(backup, StandardCharsets.UTF_8); reader = new InputStreamReader(backup, StandardCharsets.UTF_8);
BulkChangeResult result = backuper.restore(reader, null); BulkChangeResult result = backuper.restore(dbSession, reader, null);
writeResponse(response.newJsonWriter(), result); writeResponse(response.newJsonWriter(), result);
} finally { } finally {
IOUtils.closeQuietly(reader); IOUtils.closeQuietly(reader);
Expand Down
Expand Up @@ -21,26 +21,33 @@


import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets; import org.apache.commons.io.IOUtils;
import org.sonar.api.resources.Language; import org.sonar.api.resources.Language;
import org.sonar.api.resources.Languages; import org.sonar.api.resources.Languages;
import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.text.JsonWriter; import org.sonar.api.utils.text.JsonWriter;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.qualityprofile.QualityProfileDto; import org.sonar.db.qualityprofile.QualityProfileDto;
import org.sonar.server.qualityprofile.BulkChangeResult; import org.sonar.server.qualityprofile.BulkChangeResult;
import org.sonar.server.qualityprofile.QProfileBackuper; import org.sonar.server.qualityprofile.QProfileBackuper;


import static com.google.common.base.Preconditions.checkArgument;
import static java.nio.charset.StandardCharsets.UTF_8;

public class RestoreAction implements QProfileWsAction { public class RestoreAction implements QProfileWsAction {


private static final String PARAM_BACKUP = "backup"; private static final String PARAM_BACKUP = "backup";


private final DbClient dbClient;
private final QProfileBackuper backuper; private final QProfileBackuper backuper;
private final Languages languages; private final Languages languages;
private final QProfileWsSupport wsSupport; private final QProfileWsSupport wsSupport;


public RestoreAction(QProfileBackuper backuper, Languages languages, QProfileWsSupport wsSupport) { public RestoreAction(DbClient dbClient, QProfileBackuper backuper, Languages languages, QProfileWsSupport wsSupport) {
this.dbClient = dbClient;
this.backuper = backuper; this.backuper = backuper;
this.languages = languages; this.languages = languages;
this.wsSupport = wsSupport; this.wsSupport = wsSupport;
Expand All @@ -66,10 +73,17 @@ public void define(WebService.NewController controller) {
public void handle(Request request, Response response) throws Exception { public void handle(Request request, Response response) throws Exception {
wsSupport.checkQProfileAdminPermission(); wsSupport.checkQProfileAdminPermission();


try (InputStream backup = request.paramAsInputStream(PARAM_BACKUP); InputStream backup = request.paramAsInputStream(PARAM_BACKUP);
InputStreamReader reader = new InputStreamReader(backup, StandardCharsets.UTF_8)) { InputStreamReader reader = null;
BulkChangeResult result = backuper.restore(reader, null);
try (DbSession dbSession = dbClient.openSession(false)) {
checkArgument(backup != null, "A backup file must be provided");
reader = new InputStreamReader(backup, UTF_8);
BulkChangeResult result = backuper.restore(dbSession, reader, null);
writeResponse(response.newJsonWriter(), result); writeResponse(response.newJsonWriter(), result);
} finally {
IOUtils.closeQuietly(reader);
IOUtils.closeQuietly(backup);
} }
} }


Expand Down

0 comments on commit 86aa29e

Please sign in to comment.