From 1816e7c90a602ee889a99c23977df5574062616f Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Wed, 9 Apr 2014 10:07:26 +0200 Subject: [PATCH] SONAR-5056 When resetting debt model, do not load rule definitions if no rule --- ...vedIssuesOnRemovedComponentsMigration.java | 96 +++++++++++++++++++ .../sonar/server/debt/DebtModelBackup.java | 66 +++++++------ .../server/debt/DebtModelBackupTest.java | 27 ++++++ 3 files changed, 158 insertions(+), 31 deletions(-) create mode 100644 sonar-server/src/main/java/org/sonar/server/db/migrations/v43/NotResolvedIssuesOnRemovedComponentsMigration.java diff --git a/sonar-server/src/main/java/org/sonar/server/db/migrations/v43/NotResolvedIssuesOnRemovedComponentsMigration.java b/sonar-server/src/main/java/org/sonar/server/db/migrations/v43/NotResolvedIssuesOnRemovedComponentsMigration.java new file mode 100644 index 00000000000..a851125dab7 --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/db/migrations/v43/NotResolvedIssuesOnRemovedComponentsMigration.java @@ -0,0 +1,96 @@ +/* + * 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.db.migrations.v43; + +import com.google.common.annotations.VisibleForTesting; +import org.sonar.api.config.Settings; +import org.sonar.api.utils.System2; +import org.sonar.core.persistence.Database; +import org.sonar.server.db.migrations.DatabaseMigration; +import org.sonar.server.db.migrations.MassUpdater; +import org.sonar.server.db.migrations.SqlUtil; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; + +/** + * Used in the Active Record Migration 525 + * @since 4.3 + */ +public class NotResolvedIssuesOnRemovedComponentsMigration implements DatabaseMigration { + + private final WorkDurationConvertor workDurationConvertor; + private final System2 system2; + private final Database db; + + public NotResolvedIssuesOnRemovedComponentsMigration(Database database, Settings settings) { + this(database, settings, System2.INSTANCE); + } + + @VisibleForTesting + NotResolvedIssuesOnRemovedComponentsMigration(Database database, Settings settings, System2 system2) { + this.db = database; + this.workDurationConvertor = new WorkDurationConvertor(settings); + this.system2 = system2; + } + + @Override + public void execute() { + new MassUpdater(db).execute( + new MassUpdater.InputLoader() { + @Override + public String selectSql() { + return "SELECT i.id, i.technical_debt FROM issues i WHERE i.technical_debt IS NOT NULL"; + } + + @Override + public Row load(ResultSet rs) throws SQLException { + Row row = new Row(); + row.id = SqlUtil.getLong(rs, 1); + row.debt = SqlUtil.getLong(rs, 2); + return row; + } + }, + new MassUpdater.InputConverter() { + @Override + public String updateSql() { + return "UPDATE issues SET technical_debt=?,updated_at=? WHERE id=?"; + } + + @Override + public boolean convert(Row row, PreparedStatement updateStatement) throws SQLException { + updateStatement.setLong(1, workDurationConvertor.createFromLong(row.debt)); + updateStatement.setTimestamp(2, new Timestamp(system2.now())); + updateStatement.setLong(3, row.id); + return true; + } + } + ); + } + + private static class Row { + private Long id; + private Long debt; + } + +} diff --git a/sonar-server/src/main/java/org/sonar/server/debt/DebtModelBackup.java b/sonar-server/src/main/java/org/sonar/server/debt/DebtModelBackup.java index f4a972e5f3c..978fe32a40d 100644 --- a/sonar-server/src/main/java/org/sonar/server/debt/DebtModelBackup.java +++ b/sonar-server/src/main/java/org/sonar/server/debt/DebtModelBackup.java @@ -151,40 +151,44 @@ public class DebtModelBackup implements ServerComponent { // Restore characteristics List allCharacteristicDtos = restoreCharacteristics(loadModelFromPlugin(DebtModelPluginRepository.DEFAULT_MODEL), updateDate, session); - // Load default rule definitions - RulesDefinition.Context context = defLoader.load(); - List rules = newArrayList(); - for (RulesDefinition.Repository repoDef : context.repositories()) { - rules.addAll(repoDef.rules()); - } - // Restore rules List ruleDtos = ruleDao.selectEnablesAndNonManual(session); - for (RuleDto rule : ruleDtos) { - // Restore default debt definitions - RulesDefinition.Rule ruleDef = ruleDef(rule.getRepositoryKey(), rule.getRuleKey(), rules); - // Custom rules will not be found in rules definition - if (ruleDef != null) { - String subCharacteristicKey = ruleDef.debtSubCharacteristic(); - CharacteristicDto subCharacteristicDto = characteristicByKey(subCharacteristicKey, allCharacteristicDtos, false); - DebtRemediationFunction remediationFunction = ruleDef.debtRemediationFunction(); - boolean hasDebtDefinition = subCharacteristicDto != null && remediationFunction != null; - - rule.setDefaultSubCharacteristicId(hasDebtDefinition ? subCharacteristicDto.getId() : null); - rule.setDefaultRemediationFunction(hasDebtDefinition ? remediationFunction.type().name() : null); - rule.setDefaultRemediationCoefficient(hasDebtDefinition ? remediationFunction.coefficient() : null); - rule.setDefaultRemediationOffset(hasDebtDefinition ? remediationFunction.offset() : null); + if (!ruleDtos.isEmpty()) { + + // Load default rule definitions + RulesDefinition.Context context = defLoader.load(); + List rules = newArrayList(); + for (RulesDefinition.Repository repoDef : context.repositories()) { + rules.addAll(repoDef.rules()); } - // Reset overridden debt definitions - rule.setSubCharacteristicId(null); - rule.setRemediationFunction(null); - rule.setRemediationCoefficient(null); - rule.setRemediationOffset(null); - rule.setUpdatedAt(updateDate); - ruleDao.update(rule, session); + for (RuleDto rule : ruleDtos) { + // Restore default debt definitions + RulesDefinition.Rule ruleDef = ruleDef(rule.getRepositoryKey(), rule.getRuleKey(), rules); + // Custom rules will not be found in rules definition + if (ruleDef != null) { + String subCharacteristicKey = ruleDef.debtSubCharacteristic(); + CharacteristicDto subCharacteristicDto = characteristicByKey(subCharacteristicKey, allCharacteristicDtos, false); + DebtRemediationFunction remediationFunction = ruleDef.debtRemediationFunction(); + boolean hasDebtDefinition = subCharacteristicDto != null && remediationFunction != null; + + rule.setDefaultSubCharacteristicId(hasDebtDefinition ? subCharacteristicDto.getId() : null); + rule.setDefaultRemediationFunction(hasDebtDefinition ? remediationFunction.type().name() : null); + rule.setDefaultRemediationCoefficient(hasDebtDefinition ? remediationFunction.coefficient() : null); + rule.setDefaultRemediationOffset(hasDebtDefinition ? remediationFunction.offset() : null); + } + + // Reset overridden debt definitions + rule.setSubCharacteristicId(null); + rule.setRemediationFunction(null); + rule.setRemediationCoefficient(null); + rule.setRemediationOffset(null); + rule.setUpdatedAt(updateDate); + ruleDao.update(rule, session); + } + ruleRegistry.reindex(ruleDtos, session); } - ruleRegistry.reindex(ruleDtos, session); + session.commit(); } finally { MyBatis.closeQuietly(session); @@ -233,8 +237,8 @@ public class DebtModelBackup implements ServerComponent { CharacteristicDto subCharacteristicDto = subCharacteristicKey != null ? characteristicByKey(ruleDebt.subCharacteristicKey(), allCharacteristicDtos, true) : null; ruleOperations.updateRule(rule, subCharacteristicDto, ruleDebt != null ? ruleDebt.function() : null, - ruleDebt != null ? ruleDebt.coefficient() :null, - ruleDebt != null ? ruleDebt.offset() :null, updateDate, session); + ruleDebt != null ? ruleDebt.coefficient() : null, + ruleDebt != null ? ruleDebt.offset() : null, updateDate, session); rule.setUpdatedAt(updateDate); ruleDebts.remove(ruleDebt); } diff --git a/sonar-server/src/test/java/org/sonar/server/debt/DebtModelBackupTest.java b/sonar-server/src/test/java/org/sonar/server/debt/DebtModelBackupTest.java index dbf476b1766..8f986648bfc 100644 --- a/sonar-server/src/test/java/org/sonar/server/debt/DebtModelBackupTest.java +++ b/sonar-server/src/test/java/org/sonar/server/debt/DebtModelBackupTest.java @@ -539,6 +539,33 @@ public class DebtModelBackupTest { assertThat(rule.getUpdatedAt()).isEqualTo(now); } + @Test + public void reset_model_do_not_load_rule_definitions_if_no_rule() throws Exception { + when(characteristicsXMLImporter.importXML(any(Reader.class))).thenReturn(new DebtModel() + .addRootCharacteristic(new DefaultDebtCharacteristic().setKey("PORTABILITY").setName("Portability").setOrder(1)) + .addSubCharacteristic(new DefaultDebtCharacteristic().setKey("COMPILER").setName("Compiler"), "PORTABILITY")); + + when(dao.selectEnabledCharacteristics(session)).thenReturn(newArrayList( + new CharacteristicDto().setId(1).setKey("PORTABILITY").setName("Portability updated").setOrder(2).setCreatedAt(oldDate), + new CharacteristicDto().setId(2).setKey("COMPILER").setName("Compiler updated").setParentId(1).setCreatedAt(oldDate) + )); + + when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(Collections.emptyList()); + + debtModelBackup.reset(); + + verify(dao).selectEnabledCharacteristics(session); + verify(dao, times(2)).update(any(CharacteristicDto.class), eq(session)); + verifyNoMoreInteractions(dao); + + verify(ruleDao).selectEnablesAndNonManual(session); + verify(ruleDao, never()).update(any(RuleDto.class), eq(session)); + verifyZeroInteractions(ruleRegistry); + verifyZeroInteractions(defLoader); + + verify(session).commit(); + } + @Test public void restore_from_xml() throws Exception { when(characteristicsXMLImporter.importXML(anyString())).thenReturn(new DebtModel() -- 2.39.5