From: Julien Lancelot Date: Fri, 25 Sep 2015 09:36:24 +0000 (+0200) Subject: SONAR-6547 Clear rules overloaded debt X-Git-Tag: 4.5.6~13 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=a9535853b9805a3cbedc68634a210db2f7c47f0e;p=sonarqube.git SONAR-6547 Clear rules overloaded debt --- 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 8ed0d7b5abc..028381c3c38 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 @@ -20,6 +20,9 @@ package org.sonar.server.platform; import com.google.common.collect.Lists; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; import org.apache.commons.configuration.BaseConfiguration; import org.sonar.api.config.EmailSettings; import org.sonar.api.issue.action.Actions; @@ -52,7 +55,13 @@ import org.sonar.core.measure.db.MeasureFilterDao; import org.sonar.core.metric.DefaultMetricFinder; import org.sonar.core.notification.DefaultNotificationManager; import org.sonar.core.permission.PermissionFacade; -import org.sonar.core.persistence.*; +import org.sonar.core.persistence.DaoUtils; +import org.sonar.core.persistence.DatabaseVersion; +import org.sonar.core.persistence.DefaultDatabase; +import org.sonar.core.persistence.MyBatis; +import org.sonar.core.persistence.PreviewDatabaseFactory; +import org.sonar.core.persistence.SemaphoreUpdater; +import org.sonar.core.persistence.SemaphoresImpl; import org.sonar.core.preview.PreviewCache; import org.sonar.core.profiling.Profiling; import org.sonar.core.purge.PurgeProfiler; @@ -78,24 +87,54 @@ import org.sonar.server.activity.index.ActivityNormalizer; import org.sonar.server.activity.ws.ActivitiesWebService; import org.sonar.server.activity.ws.ActivityMapping; import org.sonar.server.authentication.ws.AuthenticationWs; -import org.sonar.server.batch.*; +import org.sonar.server.batch.BatchIndex; +import org.sonar.server.batch.BatchWs; +import org.sonar.server.batch.GlobalReferentialsAction; +import org.sonar.server.batch.ProjectReferentialsAction; +import org.sonar.server.batch.ProjectReferentialsLoader; import org.sonar.server.charts.ChartFactory; import org.sonar.server.component.DefaultComponentFinder; import org.sonar.server.component.DefaultRubyComponentService; import org.sonar.server.component.persistence.ComponentDao; import org.sonar.server.component.persistence.SnapshotDao; -import org.sonar.server.component.ws.*; +import org.sonar.server.component.ws.ComponentAppAction; +import org.sonar.server.component.ws.ComponentsWs; +import org.sonar.server.component.ws.EventsWs; +import org.sonar.server.component.ws.ProjectsWs; +import org.sonar.server.component.ws.ResourcesWs; import org.sonar.server.config.ws.PropertiesWs; import org.sonar.server.db.DatabaseChecker; import org.sonar.server.db.DbClient; import org.sonar.server.db.EmbeddedDatabaseFactory; import org.sonar.server.db.migrations.DatabaseMigrations; import org.sonar.server.db.migrations.DatabaseMigrator; -import org.sonar.server.debt.*; +import org.sonar.server.debt.DebtCharacteristicsXMLImporter; +import org.sonar.server.debt.DebtModelBackup; +import org.sonar.server.debt.DebtModelLookup; +import org.sonar.server.debt.DebtModelOperations; +import org.sonar.server.debt.DebtModelPluginRepository; +import org.sonar.server.debt.DebtModelService; +import org.sonar.server.debt.DebtModelXMLExporter; +import org.sonar.server.debt.DebtRulesXMLImporter; import org.sonar.server.duplication.ws.DuplicationsJsonWriter; import org.sonar.server.duplication.ws.DuplicationsParser; import org.sonar.server.duplication.ws.DuplicationsWs; -import org.sonar.server.issue.*; +import org.sonar.server.issue.ActionService; +import org.sonar.server.issue.AssignAction; +import org.sonar.server.issue.CommentAction; +import org.sonar.server.issue.DefaultIssueFinder; +import org.sonar.server.issue.InternalRubyIssueService; +import org.sonar.server.issue.IssueBulkChangeService; +import org.sonar.server.issue.IssueChangelogFormatter; +import org.sonar.server.issue.IssueChangelogService; +import org.sonar.server.issue.IssueCommentService; +import org.sonar.server.issue.IssueService; +import org.sonar.server.issue.IssueStatsFinder; +import org.sonar.server.issue.PlanAction; +import org.sonar.server.issue.PublicRubyIssueService; +import org.sonar.server.issue.ServerIssueStorage; +import org.sonar.server.issue.SetSeverityAction; +import org.sonar.server.issue.TransitionAction; import org.sonar.server.issue.actionplan.ActionPlanService; import org.sonar.server.issue.actionplan.ActionPlanWs; import org.sonar.server.issue.db.IssueDao; @@ -124,22 +163,83 @@ import org.sonar.server.platform.ws.L10nWs; import org.sonar.server.platform.ws.RestartHandler; import org.sonar.server.platform.ws.ServerWs; import org.sonar.server.platform.ws.SystemWs; -import org.sonar.server.plugins.*; +import org.sonar.server.plugins.InstalledPluginReferentialFactory; +import org.sonar.server.plugins.PluginDownloader; +import org.sonar.server.plugins.ServerExtensionInstaller; +import org.sonar.server.plugins.ServerPluginJarInstaller; +import org.sonar.server.plugins.ServerPluginJarsInstaller; +import org.sonar.server.plugins.ServerPluginRepository; +import org.sonar.server.plugins.UpdateCenterClient; +import org.sonar.server.plugins.UpdateCenterMatrixFactory; import org.sonar.server.qualitygate.QgateProjectFinder; import org.sonar.server.qualitygate.QualityGates; import org.sonar.server.qualitygate.RegisterQualityGates; -import org.sonar.server.qualitygate.ws.*; -import org.sonar.server.qualityprofile.*; +import org.sonar.server.qualitygate.ws.QGatesAppAction; +import org.sonar.server.qualitygate.ws.QGatesCopyAction; +import org.sonar.server.qualitygate.ws.QGatesCreateAction; +import org.sonar.server.qualitygate.ws.QGatesCreateConditionAction; +import org.sonar.server.qualitygate.ws.QGatesDeleteConditionAction; +import org.sonar.server.qualitygate.ws.QGatesDeselectAction; +import org.sonar.server.qualitygate.ws.QGatesDestroyAction; +import org.sonar.server.qualitygate.ws.QGatesListAction; +import org.sonar.server.qualitygate.ws.QGatesRenameAction; +import org.sonar.server.qualitygate.ws.QGatesSearchAction; +import org.sonar.server.qualitygate.ws.QGatesSelectAction; +import org.sonar.server.qualitygate.ws.QGatesSetAsDefaultAction; +import org.sonar.server.qualitygate.ws.QGatesShowAction; +import org.sonar.server.qualitygate.ws.QGatesUnsetDefaultAction; +import org.sonar.server.qualitygate.ws.QGatesUpdateConditionAction; +import org.sonar.server.qualitygate.ws.QGatesWs; +import org.sonar.server.qualityprofile.BuiltInProfiles; +import org.sonar.server.qualityprofile.QProfileBackuper; +import org.sonar.server.qualityprofile.QProfileCopier; +import org.sonar.server.qualityprofile.QProfileExporters; +import org.sonar.server.qualityprofile.QProfileFactory; +import org.sonar.server.qualityprofile.QProfileLoader; +import org.sonar.server.qualityprofile.QProfileLookup; +import org.sonar.server.qualityprofile.QProfileProjectLookup; +import org.sonar.server.qualityprofile.QProfileProjectOperations; +import org.sonar.server.qualityprofile.QProfileReset; +import org.sonar.server.qualityprofile.QProfileService; +import org.sonar.server.qualityprofile.QProfiles; +import org.sonar.server.qualityprofile.RegisterQualityProfiles; +import org.sonar.server.qualityprofile.RuleActivator; +import org.sonar.server.qualityprofile.RuleActivatorContextFactory; import org.sonar.server.qualityprofile.db.ActiveRuleDao; import org.sonar.server.qualityprofile.index.ActiveRuleIndex; import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer; -import org.sonar.server.qualityprofile.ws.*; -import org.sonar.server.rule.*; +import org.sonar.server.qualityprofile.ws.BulkRuleActivationActions; +import org.sonar.server.qualityprofile.ws.ProfilesWs; +import org.sonar.server.qualityprofile.ws.QProfileRestoreBuiltInAction; +import org.sonar.server.qualityprofile.ws.QProfilesWs; +import org.sonar.server.qualityprofile.ws.RuleActivationActions; +import org.sonar.server.rule.DefaultRuleFinder; +import org.sonar.server.rule.DeprecatedRulesDefinitionLoader; +import org.sonar.server.rule.RegisterRules; +import org.sonar.server.rule.RubyRuleService; +import org.sonar.server.rule.RuleCreator; +import org.sonar.server.rule.RuleDefinitionsLoader; +import org.sonar.server.rule.RuleDeleter; +import org.sonar.server.rule.RuleOperations; +import org.sonar.server.rule.RuleRepositories; +import org.sonar.server.rule.RuleService; +import org.sonar.server.rule.RuleUpdater; import org.sonar.server.rule.db.RuleDao; import org.sonar.server.rule.index.RuleIndex; import org.sonar.server.rule.index.RuleNormalizer; -import org.sonar.server.rule.ws.*; -import org.sonar.server.search.*; +import org.sonar.server.rule.ws.ActiveRuleCompleter; +import org.sonar.server.rule.ws.AppAction; +import org.sonar.server.rule.ws.DeleteAction; +import org.sonar.server.rule.ws.RuleMapping; +import org.sonar.server.rule.ws.RulesWebService; +import org.sonar.server.rule.ws.SearchAction; +import org.sonar.server.rule.ws.TagsAction; +import org.sonar.server.rule.ws.UpdateAction; +import org.sonar.server.search.IndexClient; +import org.sonar.server.search.IndexQueue; +import org.sonar.server.search.IndexSynchronizer; +import org.sonar.server.search.SearchClient; +import org.sonar.server.search.SearchHealth; import org.sonar.server.source.CodeColorizers; import org.sonar.server.source.DeprecatedSourceDecorator; import org.sonar.server.source.HtmlSourceDecorator; @@ -148,9 +248,28 @@ import org.sonar.server.source.ws.ScmAction; import org.sonar.server.source.ws.ScmWriter; import org.sonar.server.source.ws.ShowAction; import org.sonar.server.source.ws.SourcesWs; -import org.sonar.server.startup.*; +import org.sonar.server.startup.CleanPreviewAnalysisCache; +import org.sonar.server.startup.ClearRulesOverloadedDebt; +import org.sonar.server.startup.CopyRequirementsFromCharacteristicsToRules; +import org.sonar.server.startup.GeneratePluginIndex; +import org.sonar.server.startup.GwtPublisher; +import org.sonar.server.startup.JdbcDriverDeployer; +import org.sonar.server.startup.LogServerId; +import org.sonar.server.startup.RegisterDashboards; +import org.sonar.server.startup.RegisterDebtModel; +import org.sonar.server.startup.RegisterMetrics; +import org.sonar.server.startup.RegisterNewMeasureFilters; +import org.sonar.server.startup.RegisterPermissionTemplates; +import org.sonar.server.startup.RegisterServletFilters; +import org.sonar.server.startup.RenameDeprecatedPropertyKeys; +import org.sonar.server.startup.ServerMetadataPersister; import org.sonar.server.test.CoverageService; -import org.sonar.server.test.ws.*; +import org.sonar.server.test.ws.CoverageShowAction; +import org.sonar.server.test.ws.CoverageWs; +import org.sonar.server.test.ws.TestsCoveredFilesAction; +import org.sonar.server.test.ws.TestsShowAction; +import org.sonar.server.test.ws.TestsTestCasesAction; +import org.sonar.server.test.ws.TestsWs; import org.sonar.server.text.MacroInterpreter; import org.sonar.server.text.RubyTextService; import org.sonar.server.ui.JRubyI18n; @@ -158,18 +277,25 @@ import org.sonar.server.ui.JRubyProfiling; import org.sonar.server.ui.PageDecorations; import org.sonar.server.ui.Views; import org.sonar.server.updatecenter.ws.UpdateCenterWs; -import org.sonar.server.user.*; +import org.sonar.server.user.DefaultUserService; +import org.sonar.server.user.DoPrivileged; +import org.sonar.server.user.GroupMembershipFinder; +import org.sonar.server.user.GroupMembershipService; +import org.sonar.server.user.NewUserNotifier; +import org.sonar.server.user.SecurityRealmFactory; import org.sonar.server.user.ws.FavoritesWs; import org.sonar.server.user.ws.UserPropertiesWs; import org.sonar.server.user.ws.UsersWs; -import org.sonar.server.util.*; +import org.sonar.server.util.BooleanTypeValidation; +import org.sonar.server.util.FloatTypeValidation; +import org.sonar.server.util.IntegerTypeValidation; +import org.sonar.server.util.StringListTypeValidation; +import org.sonar.server.util.StringTypeValidation; +import org.sonar.server.util.TextTypeValidation; +import org.sonar.server.util.TypeValidations; import org.sonar.server.ws.ListingWs; import org.sonar.server.ws.WebServiceEngine; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - class ServerComponents { private final Object[] rootComponents; @@ -582,6 +708,7 @@ class ServerComponents { startupContainer.addSingleton(RegisterServletFilters.class); startupContainer.addSingleton(CleanPreviewAnalysisCache.class); startupContainer.addSingleton(CopyRequirementsFromCharacteristicsToRules.class); + startupContainer.addSingleton(ClearRulesOverloadedDebt.class); DoPrivileged.execute(new DoPrivileged.Task() { @Override diff --git a/server/sonar-server/src/main/java/org/sonar/server/startup/ClearRulesOverloadedDebt.java b/server/sonar-server/src/main/java/org/sonar/server/startup/ClearRulesOverloadedDebt.java new file mode 100644 index 00000000000..91e1538f51b --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/startup/ClearRulesOverloadedDebt.java @@ -0,0 +1,112 @@ +/* + * 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.startup; + +import org.picocontainer.Startable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.rule.RuleDto; +import org.sonar.core.template.LoadedTemplateDto; +import org.sonar.server.db.DbClient; + +import static org.sonar.core.template.LoadedTemplateDto.ONE_SHOT_TASK_TYPE; + +/** + * Clear the overloaded technical debt of rules when SQALE plugin is not installed. + * See SONAR-6547. + * + * Should be removed after LTS 5.X + * + * @since 5.2 + */ +public class ClearRulesOverloadedDebt implements Startable { + + private static final Logger LOG = LoggerFactory.getLogger(ClearRulesOverloadedDebt.class); + + private static final String TEMPLATE_KEY = "ClearRulesOverloadedDebt"; + + private static final String SQALE_LICENSE_PROPERTY = "sonar.sqale.licenseHash.secured"; + + private final DbClient dbClient; + + public ClearRulesOverloadedDebt(DbClient dbClient) { + this.dbClient = dbClient; + } + + @Override + public void start() { + DbSession session = dbClient.openSession(false); + try { + if (hasAlreadyBeenExecuted(session)) { + return; + } + if (!isSqalePluginInstalled(session)) { + clearDebt(session); + } + markAsExecuted(session); + session.commit(); + } finally { + session.close(); + } + } + + private void clearDebt(DbSession session) { + int countClearedRules = 0; + for (RuleDto rule : dbClient.ruleDao().findAll(session)) { + if (isDebtOverridden(rule)) { + rule.setSubCharacteristicId(null); + rule.setRemediationFunction(null); + rule.setRemediationCoefficient(null); + rule.setRemediationOffset(null); + dbClient.ruleDao().update(session, rule); + countClearedRules++; + } + } + if (countClearedRules > 0) { + LOG.warn("The SQALE model has been cleaned to remove useless data left over by previous migrations. The technical debt of {} rules was reset to their default values.", + countClearedRules); + LOG.warn("=> As a consequence, the overall technical debt of your projects might slightly evolve during the next analysis."); + } + } + + private static boolean isDebtOverridden(RuleDto ruleDto) { + return ruleDto.getSubCharacteristicId() != null || ruleDto.getRemediationFunction() != null || ruleDto.getRemediationCoefficient() != null + || ruleDto.getRemediationOffset() != null; + } + + private boolean isSqalePluginInstalled(DbSession session) { + return dbClient.propertiesDao().selectGlobalProperty(session, SQALE_LICENSE_PROPERTY) != null; + } + + private boolean hasAlreadyBeenExecuted(DbSession session) { + return dbClient.loadedTemplateDao().countByTypeAndKey(ONE_SHOT_TASK_TYPE, TEMPLATE_KEY, session) > 0; + } + + private void markAsExecuted(DbSession session) { + dbClient.loadedTemplateDao().insert(new LoadedTemplateDto(TEMPLATE_KEY, ONE_SHOT_TASK_TYPE), session); + } + + @Override + public void stop() { + // Nothing to do + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/startup/ClearRulesOverloadedDebtTest.java b/server/sonar-server/src/test/java/org/sonar/server/startup/ClearRulesOverloadedDebtTest.java new file mode 100644 index 00000000000..99b6a297004 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/startup/ClearRulesOverloadedDebtTest.java @@ -0,0 +1,158 @@ +/* + * 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.startup; + +import java.util.Date; +import javax.annotation.Nullable; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.sonar.api.rule.RuleKey; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.properties.PropertyDto; +import org.sonar.core.rule.RuleDto; +import org.sonar.server.db.DbClient; +import org.sonar.server.rule.Rule; +import org.sonar.server.rule.RuleTesting; +import org.sonar.server.rule.db.RuleDao; +import org.sonar.server.rule.index.RuleIndex; +import org.sonar.server.tester.ServerTester; + +import static org.fest.assertions.Assertions.assertThat; +import static org.sonar.core.template.LoadedTemplateDto.ONE_SHOT_TASK_TYPE; +import static org.sonar.server.rule.RuleTesting.XOO_X1; +import static org.sonar.server.rule.RuleTesting.XOO_X2; +import static org.sonar.server.rule.RuleTesting.XOO_X3; + +public class ClearRulesOverloadedDebtTest { + + static final int SUB_CHARACTERISTIC_ID = 1; + + private static final RuleKey RULE_KEY_1 = XOO_X1; + private static final RuleKey RULE_KEY_2 = XOO_X2; + private static final RuleKey RULE_KEY_3 = XOO_X3; + + @ClassRule + public static ServerTester tester = new ServerTester(); + + RuleDao ruleDao = tester.get(RuleDao.class); + RuleIndex ruleIndex = tester.get(RuleIndex.class); + DbClient dbClient = tester.get(DbClient.class); + DbSession dbSession = tester.get(DbClient.class).openSession(false); + + ClearRulesOverloadedDebt underTest = new ClearRulesOverloadedDebt(dbClient); + + @Before + public void before() { + tester.clearDbAndIndexes(); + } + + @After + public void after() { + dbSession.close(); + } + + @Test + public void remove_overridden_debt() throws Exception { + // Characteristic and remediation function is overridden + insertRuleDto(RULE_KEY_1, SUB_CHARACTERISTIC_ID, "LINEAR", null, "1d"); + // Only characteristic is overridden + insertRuleDto(RULE_KEY_2, SUB_CHARACTERISTIC_ID, null, null, null); + // Only remediation function is overridden + insertRuleDto(RULE_KEY_3, null, "CONSTANT_ISSUE", "5min", null); + + underTest.start(); + + verifyRuleHasNotOverriddenDebt(RULE_KEY_1); + verifyRuleHasNotOverriddenDebt(RULE_KEY_2); + verifyRuleHasNotOverriddenDebt(RULE_KEY_3); + verifyTaskRegistered(); + } + + @Test + public void not_update_rule_debt_not_overridden() throws Exception { + RuleDto rule = insertRuleDto(RULE_KEY_1, null, null, null, null); + Date updateAt = rule.getUpdatedAt(); + + underTest.start(); + + RuleDto reloaded = ruleDao.getByKey(dbSession, RULE_KEY_1); + assertThat(reloaded.getUpdatedAt()).isEqualTo(updateAt); + verifyRuleHasNotOverriddenDebt(RULE_KEY_1); + + verifyTaskRegistered(); + } + + @Test + public void not_update_rule_debt_when_sqale_is_installed() throws Exception { + insertSqaleProperty(); + RuleDto rule = insertRuleDto(RULE_KEY_1, SUB_CHARACTERISTIC_ID, "LINEAR", null, "1d"); + Date updateAt = rule.getUpdatedAt(); + + underTest.start(); + + RuleDto reloaded = ruleDao.getByKey(dbSession, RULE_KEY_1); + assertThat(reloaded.getUpdatedAt()).isEqualTo(updateAt); + + Rule ruleEs = ruleIndex.getByKey(RULE_KEY_1); + assertThat(ruleEs.debtOverloaded()).isTrue(); + + verifyTaskRegistered(); + } + + private void verifyRuleHasNotOverriddenDebt(RuleKey ruleKey) { + // Refresh session + dbSession.commit(true); + + RuleDto ruleDto = ruleDao.getByKey(dbSession, ruleKey); + assertThat(ruleDto.getSubCharacteristicId()).isNull(); + assertThat(ruleDto.getRemediationFunction()).isNull(); + assertThat(ruleDto.getRemediationCoefficient()).isNull(); + assertThat(ruleDto.getRemediationOffset()).isNull(); + + Rule rule = ruleIndex.getByKey(ruleKey); + assertThat(rule.debtOverloaded()).isFalse(); + } + + private RuleDto insertRuleDto(RuleKey ruleKey, @Nullable Integer subCharId, @Nullable String function, @Nullable String coeff, @Nullable String offset) { + RuleDto ruleDto = RuleTesting.newDto(ruleKey) + .setSubCharacteristicId(subCharId) + .setRemediationFunction(function) + .setRemediationOffset(offset) + .setRemediationCoefficient(coeff); + ruleDao.insert(dbSession, + ruleDto + ); + dbSession.commit(); + return ruleDto; + } + + private void insertSqaleProperty() { + dbClient.propertiesDao().setProperty(new PropertyDto().setKey("sonar.sqale.licenseHash.secured").setValue("ABCD"), dbSession); + dbSession.commit(); + } + + private void verifyTaskRegistered() { + assertThat(dbClient.loadedTemplateDao().countByTypeAndKey(ONE_SHOT_TASK_TYPE, "ClearRulesOverloadedDebt")).isEqualTo(1); + } + +} diff --git a/sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java b/sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java index 11c4a80dd0f..8b592ef897b 100644 --- a/sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java +++ b/sonar-core/src/main/java/org/sonar/core/properties/PropertiesDao.java @@ -21,6 +21,9 @@ package org.sonar.core.properties; import com.google.common.base.Preconditions; import com.google.common.base.Strings; +import java.util.List; +import java.util.Map; +import javax.annotation.Nullable; import org.apache.commons.lang.StringUtils; import org.apache.ibatis.session.SqlSession; import org.sonar.api.BatchComponent; @@ -29,11 +32,6 @@ import org.sonar.core.persistence.DaoComponent; import org.sonar.core.persistence.DbSession; import org.sonar.core.persistence.MyBatis; -import javax.annotation.Nullable; - -import java.util.List; -import java.util.Map; - public class PropertiesDao implements BatchComponent, ServerComponent, DaoComponent { private static final String NOTIFICATION_PREFIX = "notification."; @@ -85,11 +83,14 @@ public class PropertiesDao implements BatchComponent, ServerComponent, DaoCompon return session.getMapper(PropertiesMapper.class).selectGlobalProperties(); } + public PropertyDto selectGlobalProperty(DbSession session, String propertyKey) { + return session.getMapper(PropertiesMapper.class).selectByKey(new PropertyDto().setKey(propertyKey)); + } + public PropertyDto selectGlobalProperty(String propertyKey) { - SqlSession session = mybatis.openSession(false); - PropertiesMapper mapper = session.getMapper(PropertiesMapper.class); + DbSession session = mybatis.openSession(false); try { - return mapper.selectByKey(new PropertyDto().setKey(propertyKey)); + return selectGlobalProperty(session, propertyKey); } finally { MyBatis.closeQuietly(session); }