diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2014-04-01 19:46:53 +0200 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@sonarsource.com> | 2014-04-01 19:47:03 +0200 |
commit | 854efb2f842b3021ecb9f1a058bc9297379689b0 (patch) | |
tree | b1c82bbcec4dee400652529bcaff2524078dbccf | |
parent | ca8fc0634e839662d24312c3bbeb49ad64756349 (diff) | |
download | sonarqube-854efb2f842b3021ecb9f1a058bc9297379689b0.tar.gz sonarqube-854efb2f842b3021ecb9f1a058bc9297379689b0.zip |
SONAR-5174 Create a reindex rules method
26 files changed, 518 insertions, 323 deletions
diff --git a/sonar-core/src/main/java/org/sonar/core/rule/RuleDao.java b/sonar-core/src/main/java/org/sonar/core/rule/RuleDao.java index f35f189322b..fe04585aa3a 100644 --- a/sonar-core/src/main/java/org/sonar/core/rule/RuleDao.java +++ b/sonar-core/src/main/java/org/sonar/core/rule/RuleDao.java @@ -19,6 +19,7 @@ */ package org.sonar.core.rule; +import com.google.common.collect.Lists; import org.apache.ibatis.session.SqlSession; import org.sonar.api.BatchComponent; import org.sonar.api.ServerComponent; @@ -30,6 +31,8 @@ import javax.annotation.CheckForNull; import java.util.Collection; import java.util.List; +import static com.google.common.collect.Lists.newArrayList; + public class RuleDao implements BatchComponent, ServerComponent { private MyBatis mybatis; @@ -161,6 +164,10 @@ public class RuleDao implements BatchComponent, ServerComponent { } } + //****************************** + // Methods for Rule Parameters + //****************************** + public List<RuleParamDto> selectParameters() { SqlSession session = mybatis.openSession(); try { @@ -174,17 +181,35 @@ public class RuleDao implements BatchComponent, ServerComponent { return getMapper(session).selectAllParams(); } - public List<RuleParamDto> selectParameters(Integer id) { + public List<RuleParamDto> selectParametersByRuleId(Integer ruleId) { SqlSession session = mybatis.openSession(); try { - return selectParameters(id, session); + return selectParametersByRuleId(ruleId, session); } finally { MyBatis.closeQuietly(session); } } - public List<RuleParamDto> selectParameters(Integer ruleId, SqlSession session) { - return getMapper(session).selectParamsForRule(ruleId); + public List<RuleParamDto> selectParametersByRuleId(Integer ruleId, SqlSession session) { + return selectParametersByRuleIds(newArrayList(ruleId)); + } + + public List<RuleParamDto> selectParametersByRuleIds(List<Integer> ruleIds) { + SqlSession session = mybatis.openSession(); + try { + return selectParametersByRuleIds(ruleIds, session); + } finally { + MyBatis.closeQuietly(session); + } + } + + public List<RuleParamDto> selectParametersByRuleIds(List<Integer> ruleIds, SqlSession session) { + List<RuleParamDto> dtos = newArrayList(); + List<List<Integer>> partitionList = Lists.partition(newArrayList(ruleIds), 1000); + for (List<Integer> partition : partitionList) { + dtos.addAll(getMapper(session).selectParamsByRuleIds(partition)); + } + return dtos; } public void insert(RuleParamDto param, SqlSession session) { @@ -224,9 +249,10 @@ public class RuleDao implements BatchComponent, ServerComponent { return session.getMapper(RuleMapper.class); } - public List<RuleRuleTagDto> selectTags(SqlSession session) { - return getMapper(session).selectAllTags(); - } + //*************************** + // Methods for Rule Tags + //*************************** + public void insert(RuleRuleTagDto newTag, SqlSession session) { getMapper(session).insertTag(newTag); @@ -244,16 +270,38 @@ public class RuleDao implements BatchComponent, ServerComponent { getMapper(session).updateTag(existingTag); } - public List<RuleRuleTagDto> selectTags(Integer id) { + public List<RuleRuleTagDto> selectTags(SqlSession session) { + return getMapper(session).selectAllTags(); + } + + public List<RuleRuleTagDto> selectTagsByRuleId(Integer ruleId) { SqlSession session = mybatis.openSession(); try { - return selectTags(id, session); + return selectTagsByRuleIds(ruleId, session); } finally { MyBatis.closeQuietly(session); } } - public List<RuleRuleTagDto> selectTags(Integer id, SqlSession session) { - return getMapper(session).selectTagsForRule(id); + public List<RuleRuleTagDto> selectTagsByRuleIds(Integer ruleId, SqlSession session) { + return selectTagsByRuleIds(newArrayList(ruleId), session); + } + + public List<RuleRuleTagDto> selectTagsByRuleIds(List<Integer> ruleIds) { + SqlSession session = mybatis.openSession(); + try { + return selectTagsByRuleIds(ruleIds, session); + } finally { + MyBatis.closeQuietly(session); + } + } + + public List<RuleRuleTagDto> selectTagsByRuleIds(List<Integer> ruleIds, SqlSession session) { + List<RuleRuleTagDto> dtos = newArrayList(); + List<List<Integer>> partitionList = Lists.partition(newArrayList(ruleIds), 1000); + for (List<Integer> partition : partitionList) { + dtos.addAll(getMapper(session).selectTagsByRuleIds(partition)); + } + return dtos; } } diff --git a/sonar-core/src/main/java/org/sonar/core/rule/RuleDto.java b/sonar-core/src/main/java/org/sonar/core/rule/RuleDto.java index b7965d3bdb1..7ce85241430 100644 --- a/sonar-core/src/main/java/org/sonar/core/rule/RuleDto.java +++ b/sonar-core/src/main/java/org/sonar/core/rule/RuleDto.java @@ -161,11 +161,12 @@ public final class RuleDto { return this; } + @CheckForNull public Integer getParentId() { return parentId; } - public RuleDto setParentId(Integer parentId) { + public RuleDto setParentId(@Nullable Integer parentId) { this.parentId = parentId; return this; } diff --git a/sonar-core/src/main/java/org/sonar/core/rule/RuleMapper.java b/sonar-core/src/main/java/org/sonar/core/rule/RuleMapper.java index 6939314fd5f..e31b14e04aa 100644 --- a/sonar-core/src/main/java/org/sonar/core/rule/RuleMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/rule/RuleMapper.java @@ -47,7 +47,7 @@ public interface RuleMapper { List<RuleParamDto> selectAllParams(); - List<RuleParamDto> selectParamsForRule(Integer id); + List<RuleParamDto> selectParamsByRuleIds(@Param("ruleIds") List<Integer> ruleIds); RuleParamDto selectParamByRuleAndKey(@Param("ruleId") Integer ruleId, @Param("key") String key); @@ -65,5 +65,5 @@ public interface RuleMapper { void updateTag(RuleRuleTagDto existingTag); - List<RuleRuleTagDto> selectTagsForRule(Integer ruleId); + List<RuleRuleTagDto> selectTagsByRuleIds(@Param("ruleIds") List<Integer> ruleIds); } diff --git a/sonar-core/src/main/java/org/sonar/core/technicaldebt/db/CharacteristicDao.java b/sonar-core/src/main/java/org/sonar/core/technicaldebt/db/CharacteristicDao.java index 59a84d38c03..b82c74f4c3a 100644 --- a/sonar-core/src/main/java/org/sonar/core/technicaldebt/db/CharacteristicDao.java +++ b/sonar-core/src/main/java/org/sonar/core/technicaldebt/db/CharacteristicDao.java @@ -20,6 +20,7 @@ package org.sonar.core.technicaldebt.db; +import com.google.common.collect.Lists; import org.apache.ibatis.session.SqlSession; import org.sonar.api.BatchComponent; import org.sonar.api.ServerComponent; @@ -27,8 +28,11 @@ import org.sonar.core.persistence.MyBatis; import javax.annotation.CheckForNull; +import java.util.Collection; import java.util.List; +import static com.google.common.collect.Lists.newArrayList; + public class CharacteristicDao implements BatchComponent, ServerComponent { private final MyBatis mybatis; @@ -101,6 +105,24 @@ public class CharacteristicDao implements BatchComponent, ServerComponent { return session.getMapper(CharacteristicMapper.class).selectCharacteristicsByParentId(parentId); } + public List<CharacteristicDto> selectCharacteristicsByIds(Collection<Integer> ids) { + SqlSession session = mybatis.openSession(); + try { + return selectCharacteristicsByIds(ids, session); + } finally { + MyBatis.closeQuietly(session); + } + } + + public List<CharacteristicDto> selectCharacteristicsByIds(Collection<Integer> ids, SqlSession session) { + List<CharacteristicDto> dtos = newArrayList(); + List<List<Integer>> partitionList = Lists.partition(newArrayList(ids), 1000); + for (List<Integer> partition : partitionList) { + dtos.addAll(session.getMapper(CharacteristicMapper.class).selectCharacteristicsByIds(partition)); + } + return dtos; + } + @CheckForNull public CharacteristicDto selectByKey(String key) { SqlSession session = mybatis.openSession(); diff --git a/sonar-core/src/main/java/org/sonar/core/technicaldebt/db/CharacteristicMapper.java b/sonar-core/src/main/java/org/sonar/core/technicaldebt/db/CharacteristicMapper.java index 910f2df84b0..10b02b8faed 100644 --- a/sonar-core/src/main/java/org/sonar/core/technicaldebt/db/CharacteristicMapper.java +++ b/sonar-core/src/main/java/org/sonar/core/technicaldebt/db/CharacteristicMapper.java @@ -20,6 +20,8 @@ package org.sonar.core.technicaldebt.db; +import org.apache.ibatis.annotations.Param; + import java.util.List; public interface CharacteristicMapper { @@ -32,6 +34,8 @@ public interface CharacteristicMapper { List<CharacteristicDto> selectCharacteristicsByParentId(int parentId); + List<CharacteristicDto> selectCharacteristicsByIds(@Param("ids") List<Integer> ids); + CharacteristicDto selectByKey(String key); CharacteristicDto selectById(int id); diff --git a/sonar-core/src/main/resources/org/sonar/core/rule/RuleMapper.xml b/sonar-core/src/main/resources/org/sonar/core/rule/RuleMapper.xml index 1c10390a436..ce88ab8bdd5 100644 --- a/sonar-core/src/main/resources/org/sonar/core/rule/RuleMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/rule/RuleMapper.xml @@ -138,10 +138,12 @@ from rules_parameters </select> - <select id="selectParamsForRule" resultType="RuleParam"> - select <include refid="paramColumns"/> - from rules_parameters - where rule_id=#{id} + <select id="selectParamsByRuleIds" resultType="RuleParam"> + SELECT <include refid="paramColumns"/> + FROM rules_parameters + <where> + AND (<foreach item="id" index="index" collection="ruleIds" open="(" separator=" or " close=")">rule_id=#{id}</foreach>) + </where> </select> <select id="selectParamByRuleAndKey" resultType="RuleParam"> @@ -181,11 +183,13 @@ JOIN rule_tags rt ON rrt.rule_tag_id = rt.id </select> - <select id="selectTagsForRule" resultType="RuleRuleTag"> - select <include refid="tagColumns"/> + <select id="selectTagsByRuleIds" resultType="RuleRuleTag"> + SELECT <include refid="tagColumns"/> FROM rules_rule_tags rrt JOIN rule_tags rt ON rrt.rule_tag_id = rt.id - WHERE rrt.rule_id=#{id} + <where> + AND (<foreach item="id" index="index" collection="ruleIds" open="(" separator=" or " close=")">rrt.rule_id=#{id}</foreach>) + </where> </select> <insert id="insertTag" parameterType="RuleRuleTag" keyColumn="id" useGeneratedKeys="true" keyProperty="id"> diff --git a/sonar-core/src/main/resources/org/sonar/core/technicaldebt/db/CharacteristicMapper.xml b/sonar-core/src/main/resources/org/sonar/core/technicaldebt/db/CharacteristicMapper.xml index 0bae9e151fd..91d7cb70021 100644 --- a/sonar-core/src/main/resources/org/sonar/core/technicaldebt/db/CharacteristicMapper.xml +++ b/sonar-core/src/main/resources/org/sonar/core/technicaldebt/db/CharacteristicMapper.xml @@ -47,6 +47,15 @@ </where> </select> + <select id="selectCharacteristicsByIds" parameterType="map" resultType="Characteristic"> + select <include refid="characteristicColumns"/> + from characteristics c + <where> + and c.enabled=${_true} + AND (<foreach item="id" index="index" collection="ids" open="(" separator=" or " close=")">c.id=#{id}</foreach>) + </where> + </select> + <select id="selectByKey" parameterType="String" resultType="Characteristic"> select <include refid="characteristicColumns"/> from characteristics c diff --git a/sonar-core/src/test/java/org/sonar/core/rule/RuleDaoTest.java b/sonar-core/src/test/java/org/sonar/core/rule/RuleDaoTest.java index cfd6262feca..0a51195d85c 100644 --- a/sonar-core/src/test/java/org/sonar/core/rule/RuleDaoTest.java +++ b/sonar-core/src/test/java/org/sonar/core/rule/RuleDaoTest.java @@ -303,10 +303,10 @@ public class RuleDaoTest extends AbstractDaoTestCase { } @Test - public void select_params_for_rule() throws Exception { - setupData("selectParamsForRule"); + public void select_parameters_by_rule_id() throws Exception { + setupData("select_parameters_by_rule_id"); int ruleId = 1; - List<RuleParamDto> ruleDtos = dao.selectParameters(ruleId); + List<RuleParamDto> ruleDtos = dao.selectParametersByRuleId(ruleId); assertThat(ruleDtos.size()).isEqualTo(1); RuleParamDto ruleDto = ruleDtos.get(0); @@ -318,6 +318,14 @@ public class RuleDaoTest extends AbstractDaoTestCase { } @Test + public void select_parameters_by_rule_ids() throws Exception { + setupData("select_parameters_by_rule_ids"); + + assertThat(dao.selectParametersByRuleIds(newArrayList(1, 2))).hasSize(2); + assertThat(dao.selectParametersByRuleIds(newArrayList(1))).hasSize(1); + } + + @Test public void insert_parameter() { setupData("insert_parameter"); @@ -349,6 +357,20 @@ public class RuleDaoTest extends AbstractDaoTestCase { checkTables("update_parameter", "rules_parameters"); } + @Test + public void select_tags_by_rule_id() throws Exception { + setupData("select_tags_by_rule_id"); + + assertThat(dao.selectTagsByRuleId(3)).hasSize(2); + } + + @Test + public void select_tags_by_rule_ids() throws Exception { + setupData("select_tags_by_rule_ids"); + + assertThat(dao.selectTagsByRuleIds(newArrayList(3, 4))).hasSize(3); + } + private List<Integer> idsFromRuleDtos(List<RuleDto> ruleDtos){ return newArrayList(Iterables.transform(ruleDtos, new Function<RuleDto, Integer>() { @Override diff --git a/sonar-core/src/test/java/org/sonar/core/technicaldebt/db/CharacteristicDaoTest.java b/sonar-core/src/test/java/org/sonar/core/technicaldebt/db/CharacteristicDaoTest.java index d4647c2b403..0379af02c46 100644 --- a/sonar-core/src/test/java/org/sonar/core/technicaldebt/db/CharacteristicDaoTest.java +++ b/sonar-core/src/test/java/org/sonar/core/technicaldebt/db/CharacteristicDaoTest.java @@ -27,6 +27,7 @@ import org.sonar.core.persistence.AbstractDaoTestCase; import java.util.List; +import static com.google.common.collect.Lists.newArrayList; import static org.fest.assertions.Assertions.assertThat; public class CharacteristicDaoTest extends AbstractDaoTestCase { @@ -110,6 +111,17 @@ public class CharacteristicDaoTest extends AbstractDaoTestCase { } @Test + public void select_characteristics_by_ids() { + setupData("shared"); + + assertThat(dao.selectCharacteristicsByIds(newArrayList(1, 2))).hasSize(2); + assertThat(dao.selectCharacteristicsByIds(newArrayList(1))).hasSize(1); + + // Disabled characteristics are not returned + assertThat(dao.selectCharacteristicsByIds(newArrayList(4, 5))).isEmpty(); + } + + @Test public void select_characteristic_by_key() { setupData("shared"); diff --git a/sonar-core/src/test/resources/org/sonar/core/rule/RuleDaoTest/selectParamsForRule.xml b/sonar-core/src/test/resources/org/sonar/core/rule/RuleDaoTest/select_parameters_by_rule_id.xml index 3b21b8a8ae9..3b21b8a8ae9 100644 --- a/sonar-core/src/test/resources/org/sonar/core/rule/RuleDaoTest/selectParamsForRule.xml +++ b/sonar-core/src/test/resources/org/sonar/core/rule/RuleDaoTest/select_parameters_by_rule_id.xml diff --git a/sonar-core/src/test/resources/org/sonar/core/rule/RuleDaoTest/select_parameters_by_rule_ids.xml b/sonar-core/src/test/resources/org/sonar/core/rule/RuleDaoTest/select_parameters_by_rule_ids.xml new file mode 100644 index 00000000000..5d840d5998d --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/rule/RuleDaoTest/select_parameters_by_rule_ids.xml @@ -0,0 +1,7 @@ +<dataset> + + <rules_parameters id="1" rule_id="1" name="myParameter" param_type="plop" default_value="plouf" description="My Parameter"/> + + <rules_parameters id="2" rule_id="2" name="otherParam" param_type="plop" default_value="plouf" description="Other Parameter"/> + +</dataset> diff --git a/sonar-core/src/test/resources/org/sonar/core/rule/RuleDaoTest/select_tags_by_rule_id.xml b/sonar-core/src/test/resources/org/sonar/core/rule/RuleDaoTest/select_tags_by_rule_id.xml new file mode 100644 index 00000000000..8d252e540b4 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/rule/RuleDaoTest/select_tags_by_rule_id.xml @@ -0,0 +1,11 @@ +<dataset> + + <rule_tags id="3" tag="tag1"/> + <rule_tags id="4" tag="tag3"/> + <rule_tags id="5" tag="tag5"/> + + <rules_rule_tags id="3" rule_id="3" rule_tag_id="3" tag_type="SYSTEM"/> + <rules_rule_tags id="4" rule_id="3" rule_tag_id="4" tag_type="SYSTEM"/> + <rules_rule_tags id="5" rule_id="4" rule_tag_id="5" tag_type="SYSTEM"/> + +</dataset> diff --git a/sonar-core/src/test/resources/org/sonar/core/rule/RuleDaoTest/select_tags_by_rule_ids.xml b/sonar-core/src/test/resources/org/sonar/core/rule/RuleDaoTest/select_tags_by_rule_ids.xml new file mode 100644 index 00000000000..8d252e540b4 --- /dev/null +++ b/sonar-core/src/test/resources/org/sonar/core/rule/RuleDaoTest/select_tags_by_rule_ids.xml @@ -0,0 +1,11 @@ +<dataset> + + <rule_tags id="3" tag="tag1"/> + <rule_tags id="4" tag="tag3"/> + <rule_tags id="5" tag="tag5"/> + + <rules_rule_tags id="3" rule_id="3" rule_tag_id="3" tag_type="SYSTEM"/> + <rules_rule_tags id="4" rule_id="3" rule_tag_id="4" tag_type="SYSTEM"/> + <rules_rule_tags id="5" rule_id="4" rule_tag_id="5" tag_type="SYSTEM"/> + +</dataset> 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 377417e97a1..c61142d4c67 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 @@ -148,8 +148,11 @@ public class DebtModelBackup implements ServerComponent { try { restoreCharacteristics(loadModelFromPlugin(DebtModelPluginRepository.DEFAULT_MODEL), languageKey == null, updateDate, session); for (RuleDto rule : rules(languageKey, session)) { - disabledRuleDebt(rule, updateDate, session); + disabledOverriddenRuleDebt(rule); + rule.setUpdatedAt(updateDate); + ruleDao.update(rule, session); } + // TODO index rules in E/S session.commit(); } finally { MyBatis.closeQuietly(session); @@ -192,11 +195,11 @@ public class DebtModelBackup implements ServerComponent { for (RuleDto rule : rules) { RuleDebt ruleDebt = ruleDebtByRule(rule, ruleDebts); if (ruleDebt == null) { - disabledRuleDebt(rule, updateDate, session); + disabledOverriddenRuleDebt(rule); } else { CharacteristicDto subCharacteristicDto = characteristicByKey(ruleDebt.subCharacteristicKey(), allCharacteristicDtos); if (subCharacteristicDto == null) { - disabledRuleDebt(rule, updateDate, session); + disabledOverriddenRuleDebt(rule); } else { boolean isSameCharacteristicAsDefault = subCharacteristicDto.getId().equals(rule.getDefaultSubCharacteristicId()); boolean isSameFunctionAsDefault = isSameRemediationFunction(ruleDebt, rule); @@ -207,14 +210,14 @@ public class DebtModelBackup implements ServerComponent { rule.setRemediationFunction(!isSameFunctionAsDefault ? ruleDebt.function().name() : null); rule.setRemediationCoefficient(!isSameFunctionAsDefault ? ruleDebt.coefficient() : null); rule.setRemediationOffset(!isSameFunctionAsDefault ? ruleDebt.offset() : null); - - rule.setUpdatedAt(updateDate); - ruleDao.update(rule, session); - // TODO index rules in E/S } } + rule.setUpdatedAt(updateDate); + ruleDao.update(rule, session); + ruleDebts.remove(ruleDebt); } + // TODO index rules in E/S for (RuleDebt ruleDebt : ruleDebts) { validationMessages.addWarningText(String.format("The rule '%s' does not exist.", ruleDebt.ruleKey())); @@ -274,13 +277,11 @@ public class DebtModelBackup implements ServerComponent { .isEquals(); } - private void disabledRuleDebt(RuleDto rule, Date updateDate, SqlSession session) { + private void disabledOverriddenRuleDebt(RuleDto rule) { rule.setSubCharacteristicId(rule.getDefaultSubCharacteristicId() != null ? RuleDto.DISABLED_CHARACTERISTIC_ID : null); rule.setRemediationFunction(null); rule.setRemediationCoefficient(null); rule.setRemediationOffset(null); - rule.setUpdatedAt(updateDate); - ruleDao.update(rule, session); } private DebtModel loadModelFromPlugin(String pluginKey) { diff --git a/sonar-server/src/main/java/org/sonar/server/debt/DebtModelOperations.java b/sonar-server/src/main/java/org/sonar/server/debt/DebtModelOperations.java index f7fc54e35e7..46066deb3c8 100644 --- a/sonar-server/src/main/java/org/sonar/server/debt/DebtModelOperations.java +++ b/sonar-server/src/main/java/org/sonar/server/debt/DebtModelOperations.java @@ -36,6 +36,7 @@ import org.sonar.core.technicaldebt.db.CharacteristicDao; import org.sonar.core.technicaldebt.db.CharacteristicDto; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.rule.RuleRegistry; import org.sonar.server.user.UserSession; import org.sonar.server.util.Validation; @@ -51,16 +52,18 @@ public class DebtModelOperations implements ServerComponent { private final CharacteristicDao dao; private final RuleDao ruleDao; private final System2 system2; + private final RuleRegistry ruleRegistry; - public DebtModelOperations(MyBatis mybatis, CharacteristicDao dao, RuleDao ruleDao) { - this(mybatis, dao, ruleDao, System2.INSTANCE); + public DebtModelOperations(MyBatis mybatis, CharacteristicDao dao, RuleDao ruleDao, RuleRegistry ruleRegistry) { + this(mybatis, dao, ruleDao, ruleRegistry, System2.INSTANCE); } @VisibleForTesting - DebtModelOperations(MyBatis mybatis, CharacteristicDao dao, RuleDao ruleDao, System2 system2) { + DebtModelOperations(MyBatis mybatis, CharacteristicDao dao, RuleDao ruleDao, RuleRegistry ruleRegistry, System2 system2) { this.mybatis = mybatis; this.dao = dao; this.ruleDao = ruleDao; + this.ruleRegistry = ruleRegistry; this.system2 = system2; } @@ -189,6 +192,7 @@ public class DebtModelOperations implements ServerComponent { Date updateDate = new Date(system2.now()); SqlSession session = mybatis.openBatchSession(); try { + CharacteristicDto characteristicOrSubCharacteristic = findCharacteristic(characteristicId, session); // When root characteristic, browse sub characteristics and disable rule debt on each sub characteristic then disable it if (characteristicOrSubCharacteristic.getParentId() == null) { @@ -207,27 +211,36 @@ public class DebtModelOperations implements ServerComponent { } } + public void disableCharacteristic(CharacteristicDto characteristic, Date updateDate, SqlSession session) { + characteristic.setEnabled(false); + characteristic.setUpdatedAt(updateDate); + dao.update(characteristic, session); + } + private void disableSubCharacteristic(CharacteristicDto subCharacteristic, Date updateDate, SqlSession session) { - disableDebtRules(ruleDao.selectBySubCharacteristicId(subCharacteristic.getId(), session), updateDate, session); + disableRulesDebt(ruleDao.selectBySubCharacteristicId(subCharacteristic.getId(), session), subCharacteristic.getId(), updateDate, session); disableCharacteristic(subCharacteristic, updateDate, session); } - public void disableDebtRules(List<RuleDto> ruleDtos, Date updateDate, SqlSession session) { + public void disableRulesDebt(List<RuleDto> ruleDtos, Integer subCharacteristicId, Date updateDate, SqlSession session) { for (RuleDto ruleDto : ruleDtos) { - ruleDto.setSubCharacteristicId(RuleDto.DISABLED_CHARACTERISTIC_ID); - ruleDto.setRemediationFunction(null); - ruleDto.setRemediationCoefficient(null); - ruleDto.setRemediationOffset(null); + if (subCharacteristicId.equals(ruleDto.getSubCharacteristicId())) { + ruleDto.setSubCharacteristicId(null); + ruleDto.setRemediationFunction(null); + ruleDto.setRemediationCoefficient(null); + ruleDto.setRemediationOffset(null); + ruleDto.setUpdatedAt(updateDate); + } + if (subCharacteristicId.equals(ruleDto.getDefaultSubCharacteristicId())) { + ruleDto.setDefaultSubCharacteristicId(null); + ruleDto.setDefaultRemediationFunction(null); + ruleDto.setDefaultRemediationCoefficient(null); + ruleDto.setDefaultRemediationOffset(null); + } ruleDto.setUpdatedAt(updateDate); ruleDao.update(ruleDto, session); - // TODO update rules from E/S } - } - - public void disableCharacteristic(CharacteristicDto characteristic, Date updateDate, SqlSession session) { - characteristic.setEnabled(false); - characteristic.setUpdatedAt(updateDate); - dao.update(characteristic, session); + ruleRegistry.reindex(ruleDtos, session); } private CharacteristicDto findCharacteristic(Integer id, SqlSession session) { diff --git a/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileActiveRuleOperations.java b/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileActiveRuleOperations.java index 8b2979c79eb..70e344d77e8 100644 --- a/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileActiveRuleOperations.java +++ b/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileActiveRuleOperations.java @@ -107,7 +107,7 @@ public class QProfileActiveRuleOperations implements ServerComponent { .setSeverity(severity); activeRuleDao.insert(activeRule, session); - List<RuleParamDto> ruleParams = ruleDao.selectParameters(ruleId, session); + List<RuleParamDto> ruleParams = ruleDao.selectParametersByRuleId(ruleId, session); List<ActiveRuleParamDto> activeRuleParams = newArrayList(); for (RuleParamDto ruleParam : ruleParams) { ActiveRuleParamDto activeRuleParam = new ActiveRuleParamDto() diff --git a/sonar-server/src/main/java/org/sonar/server/rule/RegisterRules.java b/sonar-server/src/main/java/org/sonar/server/rule/RegisterRules.java index 41dfcd72a99..104bca48da0 100644 --- a/sonar-server/src/main/java/org/sonar/server/rule/RegisterRules.java +++ b/sonar-server/src/main/java/org/sonar/server/rule/RegisterRules.java @@ -111,7 +111,7 @@ public class RegisterRules implements Startable { enableRuleDefinitions(context, buffer, sqlSession); List<RuleDto> removedRules = processRemainingDbRules(buffer, sqlSession); removeActiveRulesOnStillExistingRepositories(removedRules, context); - index(buffer); + index(buffer, sqlSession); ruleTagOperations.deleteUnusedTags(sqlSession); sqlSession.commit(); @@ -272,8 +272,8 @@ public class RegisterRules implements Startable { // Debt definitions are set to null if the characteristic is null or unknown boolean hasCharacteristic = characteristic != null; - DebtRemediationFunction debtRemediationFunction = characteristic != null ? def.debtRemediationFunction() : null; - Integer characteristicId = characteristic != null ? characteristic.getId() : null; + DebtRemediationFunction debtRemediationFunction = hasCharacteristic ? def.debtRemediationFunction() : null; + Integer characteristicId = hasCharacteristic ? characteristic.getId() : null; String remediationFactor = hasCharacteristic ? debtRemediationFunction.coefficient() : null; String remediationOffset = hasCharacteristic ? debtRemediationFunction.offset() : null; String effortToFixDescription = hasCharacteristic ? def.effortToFixDescription() : null; @@ -476,8 +476,9 @@ public class RegisterRules implements Startable { } } - private void index(Buffer buffer) { - ruleRegistry.bulkRegisterRules(buffer.rulesById.values(), buffer.characteristicsById, buffer.paramsByRuleId, buffer.tagsByRuleId); + private void index(Buffer buffer, SqlSession sqlSession) { + String[] ids = ruleRegistry.reindex(buffer.rulesById.values(), sqlSession); + ruleRegistry.removeDeletedRules(ids); esRuleTags.putAllTags(buffer.referenceTagsByTagValue.values()); } diff --git a/sonar-server/src/main/java/org/sonar/server/rule/RuleOperations.java b/sonar-server/src/main/java/org/sonar/server/rule/RuleOperations.java index e0289f8f01f..d318fefa8d8 100644 --- a/sonar-server/src/main/java/org/sonar/server/rule/RuleOperations.java +++ b/sonar-server/src/main/java/org/sonar/server/rule/RuleOperations.java @@ -149,7 +149,7 @@ public class RuleOperations implements ServerComponent { .setUpdatedAt(new Date(system.now())); ruleDao.insert(rule, session); - List<RuleParamDto> templateRuleParams = ruleDao.selectParameters(templateRule.getId(), session); + List<RuleParamDto> templateRuleParams = ruleDao.selectParametersByRuleId(templateRule.getId(), session); for (RuleParamDto templateRuleParam : templateRuleParams) { String key = templateRuleParam.getName(); String value = paramsByKey.get(key); @@ -163,7 +163,7 @@ public class RuleOperations implements ServerComponent { ruleDao.insert(param, session); } - List<RuleRuleTagDto> templateRuleTags = ruleDao.selectTags(templateRule.getId(), session); + List<RuleRuleTagDto> templateRuleTags = ruleDao.selectTagsByRuleIds(templateRule.getId(), session); for (RuleRuleTagDto tag : templateRuleTags) { RuleRuleTagDto newTag = new RuleRuleTagDto() .setRuleId(rule.getId()) @@ -192,7 +192,7 @@ public class RuleOperations implements ServerComponent { .setUpdatedAt(new Date(system.now())); ruleDao.update(rule, session); - List<RuleParamDto> ruleParams = ruleDao.selectParameters(rule.getId(), session); + List<RuleParamDto> ruleParams = ruleDao.selectParametersByRuleId(rule.getId(), session); for (RuleParamDto ruleParam : ruleParams) { String value = paramsByKey.get(ruleParam.getName()); ruleParam.setDefaultValue(Strings.emptyToNull(value)); @@ -340,7 +340,7 @@ public class RuleOperations implements ServerComponent { boolean ruleChanged = false; Set<String> tagsToKeep = Sets.newHashSet(); - List<RuleRuleTagDto> currentTags = ruleDao.selectTags(ruleId, session); + List<RuleRuleTagDto> currentTags = ruleDao.selectTagsByRuleIds(ruleId, session); for (RuleRuleTagDto existingTag : currentTags) { if (existingTag.getType() == RuleTagType.ADMIN && !newTags.contains(existingTag.getTag())) { ruleDao.deleteTag(existingTag, session); @@ -366,7 +366,7 @@ public class RuleOperations implements ServerComponent { Integer subCharacteristicId = rule.getSubCharacteristicId(); CharacteristicDto subCharacteristic = subCharacteristicId != null ? characteristicDao.selectById(subCharacteristicId, session) : null; CharacteristicDto characteristic = subCharacteristic != null ? characteristicDao.selectById(subCharacteristic.getParentId(), session) : null; - ruleRegistry.save(rule, characteristic, subCharacteristic, ruleDao.selectParameters(rule.getId(), session), ruleDao.selectTags(rule.getId(), session)); + ruleRegistry.save(rule, characteristic, subCharacteristic, ruleDao.selectParametersByRuleId(rule.getId(), session), ruleDao.selectTagsByRuleIds(rule.getId(), session)); } private void checkPermission(UserSession userSession) { diff --git a/sonar-server/src/main/java/org/sonar/server/rule/RuleRegistry.java b/sonar-server/src/main/java/org/sonar/server/rule/RuleRegistry.java index 6f44491e7cd..b41c5dd49e9 100644 --- a/sonar-server/src/main/java/org/sonar/server/rule/RuleRegistry.java +++ b/sonar-server/src/main/java/org/sonar/server/rule/RuleRegistry.java @@ -67,6 +67,7 @@ import java.util.Map; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Maps.newHashMap; +import static com.google.common.collect.Sets.newHashSet; import static org.elasticsearch.index.query.FilterBuilders.*; import static org.sonar.api.rules.Rule.STATUS_REMOVED; @@ -98,37 +99,56 @@ public class RuleRegistry { searchIndex.addMappingFromClasspath(INDEX_RULES, TYPE_RULE, "/org/sonar/server/es/config/mappings/rule_mapping.json"); } - public void reindexRules() { + /** + * Reindex all enabled and non manual rules + */ + public String[] reindex() { SqlSession sqlSession = myBatis.openSession(); try { - Multimap<Integer, RuleParamDto> paramsByRuleId = ArrayListMultimap.create(); - Multimap<Integer, RuleRuleTagDto> tagsByRuleId = ArrayListMultimap.create(); - Map<Integer, CharacteristicDto> characteristicsById = newHashMap(); + return reindex(sqlSession); + } finally { + sqlSession.close(); + } + } - for (RuleParamDto paramDto : ruleDao.selectParameters(sqlSession)) { - paramsByRuleId.put(paramDto.getRuleId(), paramDto); - } - for (RuleRuleTagDto tagDto : ruleDao.selectTags(sqlSession)) { - tagsByRuleId.put(tagDto.getRuleId(), tagDto); + public String[] reindex(SqlSession session) { + return reindex(ruleDao.selectEnablesAndNonManual(session), session); + } + + public String[] reindex(Collection<RuleDto> rules, SqlSession session) { + Multimap<Integer, RuleParamDto> paramsByRuleId = ArrayListMultimap.create(); + Multimap<Integer, RuleRuleTagDto> tagsByRuleId = ArrayListMultimap.create(); + Map<Integer, CharacteristicDto> characteristicsById = newHashMap(); + + List<Integer> ruleIds = newArrayList(); + Collection<Integer> subCharacteristicIds = newHashSet(); + for (RuleDto ruleDto : rules) { + ruleIds.add(ruleDto.getId()); + if (ruleDto.getDefaultSubCharacteristicId() != null) { + subCharacteristicIds.add(ruleDto.getDefaultSubCharacteristicId()); } - for (CharacteristicDto characteristicDto : characteristicDao.selectEnabledCharacteristics(sqlSession)) { - characteristicsById.put(characteristicDto.getId(), characteristicDto); + if (ruleDto.getSubCharacteristicId() != null) { + subCharacteristicIds.add(ruleDto.getSubCharacteristicId()); } + } - bulkIndexRules( - ruleDao.selectEnablesAndNonManual(sqlSession), - characteristicsById, - paramsByRuleId, - tagsByRuleId); - } finally { - sqlSession.close(); + List<CharacteristicDto> allCharacteristicDtos = characteristicDao.selectCharacteristicsByIds(subCharacteristicIds, session); + Collection<Integer> characteristicIds = newHashSet(); + for (CharacteristicDto subCharacteristicDto : allCharacteristicDtos) { + characteristicIds.add(subCharacteristicDto.getParentId()); } - } + allCharacteristicDtos.addAll(characteristicDao.selectCharacteristicsByIds(characteristicIds, session)); - public void bulkRegisterRules(Collection<RuleDto> rules, Map<Integer, CharacteristicDto> characteristicByRule, Multimap<Integer, RuleParamDto> paramsByRule, - Multimap<Integer, RuleRuleTagDto> tagsByRule) { - String[] ids = bulkIndexRules(rules, characteristicByRule, paramsByRule, tagsByRule); - removeDeletedRules(ids); + for (RuleParamDto paramDto : ruleDao.selectParametersByRuleIds(ruleIds, session)) { + paramsByRuleId.put(paramDto.getRuleId(), paramDto); + } + for (RuleRuleTagDto tagDto : ruleDao.selectTagsByRuleIds(ruleIds, session)) { + tagsByRuleId.put(tagDto.getRuleId(), tagDto); + } + for (CharacteristicDto characteristicDto : allCharacteristicDtos) { + characteristicsById.put(characteristicDto.getId(), characteristicDto); + } + return bulkIndexRules(rules, characteristicsById, paramsByRuleId, tagsByRuleId); } /** @@ -202,8 +222,8 @@ public class RuleRegistry { Builder<Rule> rulesBuilder = ImmutableList.builder(); SearchRequestBuilder searchRequestBuilder = searchIndex.client().prepareSearch(INDEX_RULES).setTypes(TYPE_RULE) - .setPostFilter(mainFilter) - .addSort(RuleDocument.FIELD_NAME, SortOrder.ASC); + .setPostFilter(mainFilter) + .addSort(RuleDocument.FIELD_NAME, SortOrder.ASC); if (RuleQuery.NO_PAGINATION == query.pageSize()) { final int scrollTime = 100; @@ -292,10 +312,10 @@ public class RuleRegistry { profiler.start("Build rules documents"); for (RuleDto rule : rules) { ids[index] = rule.getId().toString(); - CharacteristicDto subCharacteristic = characteristicsById.get(rule.getSubCharacteristicId() != null ? rule.getSubCharacteristicId() : rule.getDefaultSubCharacteristicId()); - CharacteristicDto characteristic = subCharacteristic != null ? characteristicsById.get(subCharacteristic.getParentId()) : null; - characteristicsById.get(rule.getSubCharacteristicId() != null ? rule.getSubCharacteristicId() : rule.getDefaultSubCharacteristicId()); - docs[index] = ruleDocument(rule, characteristic, subCharacteristic, paramsByRule.get(rule.getId()), tagsByRule.get(rule.getId())); + CharacteristicDto effectiveSubCharacteristic = + characteristicsById.get(rule.getSubCharacteristicId() != null ? rule.getSubCharacteristicId() : rule.getDefaultSubCharacteristicId()); + CharacteristicDto effectiveCharacteristic = effectiveSubCharacteristic != null ? characteristicsById.get(effectiveSubCharacteristic.getParentId()) : null; + docs[index] = ruleDocument(rule, effectiveCharacteristic, effectiveSubCharacteristic, paramsByRule.get(rule.getId()), tagsByRule.get(rule.getId())); index++; } profiler.stop(); @@ -311,7 +331,7 @@ public class RuleRegistry { } } - private void removeDeletedRules(String[] ids) { + public void removeDeletedRules(String[] ids) { List<String> indexIds = searchIndex.findDocumentIds(SearchQuery.create().index(INDEX_RULES).type(TYPE_RULE)); indexIds.removeAll(Arrays.asList(ids)); TimeProfiler profiler = new TimeProfiler(); @@ -331,7 +351,7 @@ public class RuleRegistry { .field(RuleDocument.FIELD_LANGUAGE, rule.getLanguage()) .field(RuleDocument.FIELD_NAME, rule.getName()) .field(RuleDocument.FIELD_DESCRIPTION, rule.getDescription()) - .field(RuleDocument.FIELD_TEMPLATE_ID, rule.getParentId() == null ? null : rule.getParentId()) + .field(RuleDocument.FIELD_TEMPLATE_ID, rule.getParentId()) .field(RuleDocument.FIELD_REPOSITORY_KEY, rule.getRepositoryKey()) .field(RuleDocument.FIELD_SEVERITY, rule.getSeverityString()) .field(RuleDocument.FIELD_STATUS, rule.getStatus()) diff --git a/sonar-server/src/main/java/org/sonar/server/startup/CopyRequirementsFromCharacteristicsToRules.java b/sonar-server/src/main/java/org/sonar/server/startup/CopyRequirementsFromCharacteristicsToRules.java index 195d873bd63..e20ed4bb7a9 100644 --- a/sonar-server/src/main/java/org/sonar/server/startup/CopyRequirementsFromCharacteristicsToRules.java +++ b/sonar-server/src/main/java/org/sonar/server/startup/CopyRequirementsFromCharacteristicsToRules.java @@ -106,7 +106,7 @@ public class CopyRequirementsFromCharacteristicsToRules { removeRequirementsDataFromCharacteristics(); LOGGER.info("Reindex rules in E/S"); - ruleRegistry.reindexRules(); + ruleRegistry.reindex(); } private void copyRequirementsFromCharacteristicsToRules() { diff --git a/sonar-server/src/test/java/org/sonar/server/debt/DebtModelOperationsTest.java b/sonar-server/src/test/java/org/sonar/server/debt/DebtModelOperationsTest.java index c6ff57b1e1e..1e68d712c0b 100644 --- a/sonar-server/src/test/java/org/sonar/server/debt/DebtModelOperationsTest.java +++ b/sonar-server/src/test/java/org/sonar/server/debt/DebtModelOperationsTest.java @@ -42,6 +42,7 @@ import org.sonar.core.technicaldebt.db.CharacteristicDto; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.rule.RuleRegistry; import org.sonar.server.user.MockUserSession; import java.util.Date; @@ -68,6 +69,9 @@ public class DebtModelOperationsTest { SqlSession session; @Mock + RuleRegistry ruleRegistry; + + @Mock System2 system2; Date now = DateUtils.parseDate("2014-03-19"); @@ -108,7 +112,7 @@ public class DebtModelOperationsTest { }).when(dao).insert(any(CharacteristicDto.class), any(SqlSession.class)); when(mybatis.openSession()).thenReturn(session); - service = new DebtModelOperations(mybatis, dao, ruleDao, system2); + service = new DebtModelOperations(mybatis, dao, ruleDao, ruleRegistry, system2); } @Test @@ -351,13 +355,13 @@ public class DebtModelOperationsTest { ArgumentCaptor<RuleDto> ruleArgument = ArgumentCaptor.forClass(RuleDto.class); verify(ruleDao).update(ruleArgument.capture(), eq(batchSession)); RuleDto ruleDto = ruleArgument.getValue(); + assertThat(ruleDto.getUpdatedAt()).isEqualTo(now); // Overridden debt data are disabled - assertThat(ruleDto.getSubCharacteristicId()).isEqualTo(-1); + assertThat(ruleDto.getSubCharacteristicId()).isNull(); assertThat(ruleDto.getRemediationFunction()).isNull(); assertThat(ruleDto.getRemediationCoefficient()).isNull(); assertThat(ruleDto.getRemediationOffset()).isNull(); - assertThat(ruleDto.getUpdatedAt()).isEqualTo(now); // Default debt data should not be touched assertThat(ruleDto.getDefaultSubCharacteristicId()).isEqualTo(10); @@ -376,6 +380,47 @@ public class DebtModelOperationsTest { } @Test + public void delete_sub_characteristic_disable_default_rules_debt_if_default_characteristic_is_deleted() { + BatchSession batchSession = mock(BatchSession.class); + when(mybatis.openBatchSession()).thenReturn(batchSession); + + when(ruleDao.selectBySubCharacteristicId(2, batchSession)).thenReturn(newArrayList( + new RuleDto() + .setSubCharacteristicId(10).setRemediationFunction("LINEAR_OFFSET").setRemediationCoefficient("2h").setRemediationOffset("5min") + .setDefaultSubCharacteristicId(2).setDefaultRemediationFunction("LINEAR_OFFSET").setDefaultRemediationCoefficient("4h").setDefaultRemediationOffset("15min") + )); + when(dao.selectById(2, batchSession)).thenReturn(subCharacteristicDto); + + service.delete(2); + + ArgumentCaptor<RuleDto> ruleArgument = ArgumentCaptor.forClass(RuleDto.class); + verify(ruleDao).update(ruleArgument.capture(), eq(batchSession)); + RuleDto ruleDto = ruleArgument.getValue(); + assertThat(ruleDto.getUpdatedAt()).isEqualTo(now); + + // Default debt data are disabled + assertThat(ruleDto.getDefaultSubCharacteristicId()).isNull(); + assertThat(ruleDto.getDefaultRemediationFunction()).isNull(); + assertThat(ruleDto.getDefaultRemediationCoefficient()).isNull(); + assertThat(ruleDto.getDefaultRemediationOffset()).isNull(); + + // Overridden debt data should not be touched + assertThat(ruleDto.getSubCharacteristicId()).isEqualTo(10); + assertThat(ruleDto.getRemediationFunction()).isEqualTo("LINEAR_OFFSET"); + assertThat(ruleDto.getRemediationCoefficient()).isEqualTo("2h"); + assertThat(ruleDto.getRemediationOffset()).isEqualTo("5min"); + + ArgumentCaptor<CharacteristicDto> characteristicArgument = ArgumentCaptor.forClass(CharacteristicDto.class); + verify(dao).update(characteristicArgument.capture(), eq(batchSession)); + CharacteristicDto characteristicDto = characteristicArgument.getValue(); + + // Sub characteristic is disable + assertThat(characteristicDto.getId()).isEqualTo(2); + assertThat(characteristicDto.isEnabled()).isFalse(); + assertThat(characteristicDto.getUpdatedAt()).isEqualTo(now); + } + + @Test public void delete_characteristic() { BatchSession batchSession = mock(BatchSession.class); when(mybatis.openBatchSession()).thenReturn(batchSession); diff --git a/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileActiveRuleOperationsTest.java b/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileActiveRuleOperationsTest.java index 724c7dd0d91..e917baa9c55 100644 --- a/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileActiveRuleOperationsTest.java +++ b/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileActiveRuleOperationsTest.java @@ -135,7 +135,7 @@ public class QProfileActiveRuleOperationsTest { when(profileDao.selectById(1, session)).thenReturn(new QualityProfileDto().setId(1).setName("Default").setLanguage("java")); when(ruleDao.selectById(10, session)).thenReturn(new RuleDto().setId(10)); - when(ruleDao.selectParameters(eq(10), eq(session))).thenReturn(newArrayList(new RuleParamDto().setId(20).setName("max").setDefaultValue("10"))); + when(ruleDao.selectParametersByRuleId(eq(10), eq(session))).thenReturn(newArrayList(new RuleParamDto().setId(20).setName("max").setDefaultValue("10"))); final int idActiveRuleToUpdate = 42; final int idActiveRuleToDelete = 24; ProfilesManager.RuleInheritanceActions inheritanceActions = new ProfilesManager.RuleInheritanceActions() @@ -203,7 +203,7 @@ public class QProfileActiveRuleOperationsTest { ProfileRuleQuery query = ProfileRuleQuery.create(1); when(rules.searchInactiveProfileRuleIds(query)).thenReturn(newArrayList(10)); - when(ruleDao.selectParameters(eq(10), eq(session))).thenReturn(newArrayList(new RuleParamDto().setId(20).setName("max").setDefaultValue("10"))); + when(ruleDao.selectParametersByRuleId(eq(10), eq(session))).thenReturn(newArrayList(new RuleParamDto().setId(20).setName("max").setDefaultValue("10"))); final int idActiveRuleToUpdate = 42; final int idActiveRuleToDelete = 24; ProfilesManager.RuleInheritanceActions inheritanceActions = new ProfilesManager.RuleInheritanceActions() diff --git a/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java b/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java index a0fd69ff7f9..01c35e4d405 100644 --- a/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java +++ b/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java @@ -20,8 +20,14 @@ package org.sonar.server.rule; +import org.apache.ibatis.session.SqlSession; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; import org.sonar.api.rule.RuleStatus; import org.sonar.api.rule.Severity; import org.sonar.api.server.rule.RulesDefinition; @@ -32,17 +38,21 @@ import org.sonar.core.persistence.AbstractDaoTestCase; import org.sonar.core.persistence.MyBatis; import org.sonar.core.qualityprofile.db.ActiveRuleDao; import org.sonar.core.rule.RuleDao; +import org.sonar.core.rule.RuleDto; import org.sonar.core.rule.RuleTagDao; +import org.sonar.core.rule.RuleTagDto; import org.sonar.core.technicaldebt.db.CharacteristicDao; import org.sonar.server.qualityprofile.ProfilesManager; import org.sonar.server.startup.RegisterDebtModel; +import java.util.Collection; import java.util.Date; import static org.fest.assertions.Assertions.assertThat; import static org.fest.assertions.Fail.fail; import static org.mockito.Mockito.*; +@RunWith(MockitoJUnitRunner.class) public class RegisterRulesTest extends AbstractDaoTestCase { private static final String[] EXCLUDED_COLUMN_NAMES = {"created_at", "updated_at", "note_data", "note_user_login", "note_created_at", "note_updated_at"}; @@ -52,9 +62,22 @@ public class RegisterRulesTest extends AbstractDaoTestCase { "effort_to_fix_description"}; RegisterRules task; - ProfilesManager profilesManager = mock(ProfilesManager.class); - RuleRegistry ruleRegistry = mock(RuleRegistry.class); - ESRuleTags esRuleTags = mock(ESRuleTags.class); + + @Mock + ProfilesManager profilesManager; + + @Mock + RuleRegistry ruleRegistry; + + @Mock + ESRuleTags esRuleTags; + + @Captor + ArgumentCaptor<Collection<RuleDto>> rulesCaptor; + + @Captor + ArgumentCaptor<Collection<RuleTagDto>> ruleTagsCaptor; + RuleTagOperations ruleTagOperations; MyBatis myBatis; RuleDao ruleDao; @@ -83,6 +106,13 @@ public class RegisterRulesTest extends AbstractDaoTestCase { setupData("shared"); task.start(); + verify(ruleRegistry).reindex(rulesCaptor.capture(), any(SqlSession.class)); + assertThat(rulesCaptor.getValue()).hasSize(3); + verify(ruleRegistry).removeDeletedRules(any(String[].class)); + + verify(esRuleTags).putAllTags(ruleTagsCaptor.capture()); + assertThat(ruleTagsCaptor.getValue()).hasSize(3); + checkTables("insert_new_rules", EXCLUDED_COLUMN_NAMES, "rules", "rules_parameters", "rules_rule_tags", "rule_tags"); } diff --git a/sonar-server/src/test/java/org/sonar/server/rule/RuleOperationsTest.java b/sonar-server/src/test/java/org/sonar/server/rule/RuleOperationsTest.java index 0ff30e70952..249a1d8abe4 100644 --- a/sonar-server/src/test/java/org/sonar/server/rule/RuleOperationsTest.java +++ b/sonar-server/src/test/java/org/sonar/server/rule/RuleOperationsTest.java @@ -134,9 +134,9 @@ public class RuleOperationsTest { RuleDto rule = new RuleDto().setId(10).setNoteCreatedAt(null).setNoteData(null); List<RuleParamDto> ruleParams = newArrayList(new RuleParamDto().setId(20).setName("max").setDefaultValue("10")); - when(ruleDao.selectParameters(eq(10), eq(session))).thenReturn(ruleParams); + when(ruleDao.selectParametersByRuleId(eq(10), eq(session))).thenReturn(ruleParams); List<RuleRuleTagDto> ruleTags = newArrayList(new RuleRuleTagDto().setId(30L).setTag("style").setType(RuleTagType.SYSTEM)); - when(ruleDao.selectTags(eq(10), eq(session))).thenReturn(ruleTags); + when(ruleDao.selectTagsByRuleIds(eq(10), eq(session))).thenReturn(ruleTags); operations.updateRuleNote(rule, "My note", authorizedUserSession); @@ -171,9 +171,9 @@ public class RuleOperationsTest { RuleDto rule = new RuleDto().setId(10).setNoteCreatedAt(createdAt).setNoteData("My previous note").setNoteUserLogin("nicolas"); List<RuleParamDto> ruleParams = newArrayList(new RuleParamDto().setId(20).setName("max").setDefaultValue("10")); - when(ruleDao.selectParameters(eq(10), eq(session))).thenReturn(ruleParams); + when(ruleDao.selectParametersByRuleId(eq(10), eq(session))).thenReturn(ruleParams); List<RuleRuleTagDto> ruleTags = newArrayList(new RuleRuleTagDto().setId(30L).setTag("style").setType(RuleTagType.SYSTEM)); - when(ruleDao.selectTags(eq(10), eq(session))).thenReturn(ruleTags); + when(ruleDao.selectTagsByRuleIds(eq(10), eq(session))).thenReturn(ruleTags); operations.updateRuleNote(rule, "My new note", MockUserSession.create().setLogin("guy").setName("Guy").setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN)); @@ -194,9 +194,9 @@ public class RuleOperationsTest { RuleDto rule = new RuleDto().setId(10).setNoteData("My note").setNoteUserLogin("nicolas").setNoteCreatedAt(createdAt).setNoteUpdatedAt(createdAt); List<RuleParamDto> ruleParams = newArrayList(new RuleParamDto().setId(20).setName("max").setDefaultValue("10")); - when(ruleDao.selectParameters(eq(10), eq(session))).thenReturn(ruleParams); + when(ruleDao.selectParametersByRuleId(eq(10), eq(session))).thenReturn(ruleParams); List<RuleRuleTagDto> ruleTags = newArrayList(new RuleRuleTagDto().setId(30L).setTag("style").setType(RuleTagType.SYSTEM)); - when(ruleDao.selectTags(eq(10), eq(session))).thenReturn(ruleTags); + when(ruleDao.selectTagsByRuleIds(eq(10), eq(session))).thenReturn(ruleTags); long now = System.currentTimeMillis(); doReturn(now).when(system).now(); @@ -217,8 +217,8 @@ public class RuleOperationsTest { @Test public void create_custom_rule() throws Exception { RuleDto templateRule = new RuleDto().setId(10).setRepositoryKey("squid").setRuleKey("AvoidCycle").setConfigKey("Xpath"); - when(ruleDao.selectParameters(eq(10), eq(session))).thenReturn(newArrayList(new RuleParamDto().setId(20).setName("max").setDefaultValue("10"))); - when(ruleDao.selectTags(eq(10), eq(session))).thenReturn(newArrayList(new RuleRuleTagDto().setId(30L).setTag("style").setType(RuleTagType.SYSTEM))); + when(ruleDao.selectParametersByRuleId(eq(10), eq(session))).thenReturn(newArrayList(new RuleParamDto().setId(20).setName("max").setDefaultValue("10"))); + when(ruleDao.selectTagsByRuleIds(eq(10), eq(session))).thenReturn(newArrayList(new RuleRuleTagDto().setId(30L).setTag("style").setType(RuleTagType.SYSTEM))); Map<String, String> paramsByKey = ImmutableMap.of("max", "20"); RuleDto result = operations.createCustomRule(templateRule, "My New Rule", Severity.BLOCKER, "Rule Description", paramsByKey, authorizedUserSession); @@ -254,9 +254,9 @@ public class RuleOperationsTest { @Test public void update_custom_rule() throws Exception { RuleDto rule = new RuleDto().setId(11).setRepositoryKey("squid").setRuleKey("XPath_1387869254").setConfigKey("Xpath"); - when(ruleDao.selectParameters(eq(11), eq(session))).thenReturn(newArrayList(new RuleParamDto().setId(21).setName("max").setDefaultValue("20"))); + when(ruleDao.selectParametersByRuleId(eq(11), eq(session))).thenReturn(newArrayList(new RuleParamDto().setId(21).setName("max").setDefaultValue("20"))); ArrayList<RuleRuleTagDto> ruleTags = newArrayList(new RuleRuleTagDto().setId(30L).setTag("style").setType(RuleTagType.SYSTEM)); - when(ruleDao.selectTags(eq(11), eq(session))).thenReturn(ruleTags); + when(ruleDao.selectTagsByRuleIds(eq(11), eq(session))).thenReturn(ruleTags); Map<String, String> paramsByKey = ImmutableMap.of("max", "21"); operations.updateCustomRule(rule, "Updated Rule", Severity.MAJOR, "Updated Description", paramsByKey, authorizedUserSession); @@ -281,9 +281,9 @@ public class RuleOperationsTest { final int ruleId = 11; RuleDto rule = new RuleDto().setId(ruleId).setRepositoryKey("squid").setRuleKey("XPath_1387869254").setConfigKey("Xpath").setUpdatedAt(DateUtils.parseDate("2013-12-23")); RuleParamDto param = new RuleParamDto().setId(21).setName("max").setDefaultValue("20"); - when(ruleDao.selectParameters(eq(ruleId), eq(session))).thenReturn(newArrayList(param)); + when(ruleDao.selectParametersByRuleId(eq(ruleId), eq(session))).thenReturn(newArrayList(param)); ArrayList<RuleRuleTagDto> ruleTags = newArrayList(new RuleRuleTagDto().setId(30L).setTag("style").setType(RuleTagType.SYSTEM)); - when(ruleDao.selectTags(eq(ruleId), eq(session))).thenReturn(ruleTags); + when(ruleDao.selectTagsByRuleIds(eq(ruleId), eq(session))).thenReturn(ruleTags); final int activeRuleId = 5; ActiveRuleDto activeRule = new ActiveRuleDto().setId(activeRuleId).setProfileId(1).setRuleId(ruleId).setSeverity(Severity.MINOR); @@ -341,11 +341,11 @@ public class RuleOperationsTest { final RuleDto rule = new RuleDto().setId(ruleId); final String tag = "polop"; RuleRuleTagDto existingTag = new RuleRuleTagDto().setTag(tag).setType(RuleTagType.ADMIN); - when(ruleDao.selectTags(ruleId, session)).thenReturn(ImmutableList.of(existingTag)); + when(ruleDao.selectTagsByRuleIds(ruleId, session)).thenReturn(ImmutableList.of(existingTag)); operations.updateRuleTags(rule, ImmutableList.<String>of(), authorizedUserSession); - verify(ruleDao, atLeast(1)).selectTags(ruleId, session); + verify(ruleDao, atLeast(1)).selectTagsByRuleIds(ruleId, session); verify(ruleDao).deleteTag(existingTag, session); verify(ruleDao).update(rule, session); verify(ruleTagOperations).deleteUnusedTags(session); @@ -360,12 +360,12 @@ public class RuleOperationsTest { final long tagId = 42L; when(ruleTagDao.selectId(tag, session)).thenReturn(tagId); RuleRuleTagDto existingTag = new RuleRuleTagDto().setTag(tag).setType(RuleTagType.ADMIN); - when(ruleDao.selectTags(ruleId, session)).thenReturn(ImmutableList.of(existingTag)); + when(ruleDao.selectTagsByRuleIds(ruleId, session)).thenReturn(ImmutableList.of(existingTag)); operations.updateRuleTags(rule, ImmutableList.of(tag), authorizedUserSession); verify(ruleTagDao).selectId(tag, session); - verify(ruleDao).selectTags(ruleId, session); + verify(ruleDao).selectTagsByRuleIds(ruleId, session); verify(ruleTagOperations).deleteUnusedTags(session); verify(ruleDao, never()).update(rule); } diff --git a/sonar-server/src/test/java/org/sonar/server/rule/RuleRegistryTest.java b/sonar-server/src/test/java/org/sonar/server/rule/RuleRegistryTest.java index 374ae0f04cb..9e664fc628f 100644 --- a/sonar-server/src/test/java/org/sonar/server/rule/RuleRegistryTest.java +++ b/sonar-server/src/test/java/org/sonar/server/rule/RuleRegistryTest.java @@ -21,10 +21,9 @@ package org.sonar.server.rule; import com.github.tlrx.elasticsearch.test.EsSetup; -import com.google.common.collect.*; +import com.google.common.collect.ImmutableMap; import org.apache.commons.io.IOUtils; import org.apache.ibatis.session.SqlSession; -import org.elasticsearch.common.collect.Lists; import org.elasticsearch.common.settings.ImmutableSettings; import org.junit.After; import org.junit.Before; @@ -49,10 +48,10 @@ import java.util.List; import java.util.Map; import static com.google.common.collect.Lists.newArrayList; -import static com.google.common.collect.Maps.newHashMap; +import static com.google.common.collect.Sets.newHashSet; import static org.fest.assertions.Assertions.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class RuleRegistryTest { @@ -117,6 +116,140 @@ public class RuleRegistryTest { } @Test + public void index_rules() { + when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(newArrayList( + new RuleDto().setId(3).setRepositoryKey("repo").setRuleKey("key").setSeverity(Severity.MINOR).setNoteData("noteData").setNoteUserLogin("userLogin") + .setDefaultSubCharacteristicId(11).setDefaultRemediationFunction("LINEAR_OFFSET").setDefaultRemediationCoefficient("1h").setDefaultRemediationOffset("15min") + )); + + when(ruleDao.selectParametersByRuleIds(newArrayList(3), session)).thenReturn(newArrayList( + new RuleParamDto().setRuleId(3).setName("name") + )); + + when(ruleDao.selectTagsByRuleIds(newArrayList(3), session)).thenReturn(newArrayList( + new RuleRuleTagDto().setRuleId(3).setTag("tag1").setType(RuleTagType.SYSTEM), + new RuleRuleTagDto().setRuleId(3).setTag("tag2").setType(RuleTagType.SYSTEM), + new RuleRuleTagDto().setRuleId(3).setTag("tag").setType(RuleTagType.ADMIN))); + + when(characteristicDao.selectCharacteristicsByIds(newHashSet(11), session)).thenReturn(newArrayList( + new CharacteristicDto().setId(11).setKey("MODULARITY").setName("Modularity").setParentId(10))); + when(characteristicDao.selectCharacteristicsByIds(newHashSet(10), session)).thenReturn(newArrayList( + new CharacteristicDto().setId(10).setKey("REUSABILITY").setName("Reusability"))); + + registry.reindex(); + + Map<String, Object> ruleDocument = esSetup.client().prepareGet("rules", "rule", Integer.toString(3)).execute().actionGet().getSourceAsMap(); + assertThat(ruleDocument.get(RuleDocument.FIELD_ID)).isEqualTo(3); + assertThat(ruleDocument.get(RuleDocument.FIELD_REPOSITORY_KEY)).isEqualTo("repo"); + assertThat(ruleDocument.get(RuleDocument.FIELD_KEY)).isEqualTo("key"); + assertThat(ruleDocument.get(RuleDocument.FIELD_SEVERITY)).isEqualTo("MINOR"); + assertThat(ruleDocument.get(RuleDocument.FIELD_NOTE)).isNotNull(); + + assertThat((List<String>) ruleDocument.get(RuleDocument.FIELD_PARAMS)).hasSize(1); + assertThat((List<String>) ruleDocument.get(RuleDocument.FIELD_SYSTEM_TAGS)).hasSize(2); + assertThat((List<String>) ruleDocument.get(RuleDocument.FIELD_ADMIN_TAGS)).hasSize(1); + + assertThat(ruleDocument.get(RuleDocument.FIELD_CHARACTERISTIC_ID)).isEqualTo(10); + assertThat(ruleDocument.get(RuleDocument.FIELD_CHARACTERISTIC_KEY)).isEqualTo("REUSABILITY"); + assertThat(ruleDocument.get(RuleDocument.FIELD_CHARACTERISTIC_NAME)).isEqualTo("Reusability"); + assertThat(ruleDocument.get(RuleDocument.FIELD_SUB_CHARACTERISTIC_ID)).isEqualTo(11); + assertThat(ruleDocument.get(RuleDocument.FIELD_SUB_CHARACTERISTIC_KEY)).isEqualTo("MODULARITY"); + assertThat(ruleDocument.get(RuleDocument.FIELD_SUB_CHARACTERISTIC_NAME)).isEqualTo("Modularity"); + assertThat(ruleDocument.get(RuleDocument.FIELD_REMEDIATION_FUNCTION)).isEqualTo("LINEAR_OFFSET"); + assertThat(ruleDocument.get(RuleDocument.FIELD_REMEDIATION_COEFFICIENT)).isEqualTo("1h"); + assertThat(ruleDocument.get(RuleDocument.FIELD_REMEDIATION_OFFSET)).isEqualTo("15min"); + } + + @Test + public void index_overridden_characteristic_if_both_default_and_overridden_characteristics_exists() { + when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(newArrayList( + new RuleDto().setId(10).setRepositoryKey("repo").setRuleKey("key1").setSeverity(Severity.MINOR) + // default and overridden debt values are set + .setDefaultSubCharacteristicId(11).setDefaultRemediationFunction("LINEAR").setDefaultRemediationCoefficient("2h") + .setSubCharacteristicId(13).setRemediationFunction("LINEAR_OFFSET").setRemediationCoefficient("1h").setRemediationOffset("15min") + )); + + when(characteristicDao.selectCharacteristicsByIds(newHashSet(11, 13), session)).thenReturn(newArrayList( + new CharacteristicDto().setId(11).setKey("MODULARITY").setName("Modularity").setParentId(10), + new CharacteristicDto().setId(13).setKey("COMPILER").setName("Compiler").setParentId(12) + )); + when(characteristicDao.selectCharacteristicsByIds(newHashSet(10, 12), session)).thenReturn(newArrayList( + new CharacteristicDto().setId(10).setKey("REUSABILITY").setName("Reusability"), + new CharacteristicDto().setId(12).setKey("PORTABILITY").setName("Portability") + )); + + registry.reindex(); + + Map<String, Object> ruleDocument = esSetup.client().prepareGet("rules", "rule", Integer.toString(10)).execute().actionGet().getSourceAsMap(); + assertThat(ruleDocument.get(RuleDocument.FIELD_CHARACTERISTIC_ID)).isEqualTo(12); + assertThat(ruleDocument.get(RuleDocument.FIELD_CHARACTERISTIC_KEY)).isEqualTo("PORTABILITY"); + assertThat(ruleDocument.get(RuleDocument.FIELD_CHARACTERISTIC_NAME)).isEqualTo("Portability"); + assertThat(ruleDocument.get(RuleDocument.FIELD_SUB_CHARACTERISTIC_ID)).isEqualTo(13); + assertThat(ruleDocument.get(RuleDocument.FIELD_SUB_CHARACTERISTIC_KEY)).isEqualTo("COMPILER"); + assertThat(ruleDocument.get(RuleDocument.FIELD_SUB_CHARACTERISTIC_NAME)).isEqualTo("Compiler"); + + assertThat(ruleDocument.get(RuleDocument.FIELD_REMEDIATION_FUNCTION)).isEqualTo("LINEAR_OFFSET"); + assertThat(ruleDocument.get(RuleDocument.FIELD_REMEDIATION_COEFFICIENT)).isEqualTo("1h"); + assertThat(ruleDocument.get(RuleDocument.FIELD_REMEDIATION_OFFSET)).isEqualTo("15min"); + } + + @Test + public void index_overridden_function_if_both_default_and_overridden_functions_exists() { + when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(newArrayList( + new RuleDto().setId(10).setRepositoryKey("repo").setRuleKey("key1").setSeverity(Severity.MINOR) + // default and overridden debt values are set + .setDefaultSubCharacteristicId(11).setDefaultRemediationFunction("CONSTANT_ISSUE").setDefaultRemediationOffset("15min") + .setSubCharacteristicId(11).setRemediationFunction("LINEAR").setRemediationCoefficient("1h") + )); + + when(characteristicDao.selectCharacteristicsByIds(newHashSet(11), session)).thenReturn(newArrayList( + new CharacteristicDto().setId(11).setKey("MODULARITY").setName("Modularity").setParentId(10) + )); + when(characteristicDao.selectCharacteristicsByIds(newHashSet(10), session)).thenReturn(newArrayList( + new CharacteristicDto().setId(10).setKey("REUSABILITY").setName("Reusability") + )); + + registry.reindex(); + + Map<String, Object> ruleDocument = esSetup.client().prepareGet("rules", "rule", Integer.toString(10)).execute().actionGet().getSourceAsMap(); + assertThat(ruleDocument.get(RuleDocument.FIELD_CHARACTERISTIC_ID)).isEqualTo(10); + assertThat(ruleDocument.get(RuleDocument.FIELD_CHARACTERISTIC_KEY)).isEqualTo("REUSABILITY"); + assertThat(ruleDocument.get(RuleDocument.FIELD_CHARACTERISTIC_NAME)).isEqualTo("Reusability"); + assertThat(ruleDocument.get(RuleDocument.FIELD_SUB_CHARACTERISTIC_ID)).isEqualTo(11); + assertThat(ruleDocument.get(RuleDocument.FIELD_SUB_CHARACTERISTIC_KEY)).isEqualTo("MODULARITY"); + assertThat(ruleDocument.get(RuleDocument.FIELD_SUB_CHARACTERISTIC_NAME)).isEqualTo("Modularity"); + + assertThat(ruleDocument.get(RuleDocument.FIELD_REMEDIATION_FUNCTION)).isEqualTo("LINEAR"); + assertThat(ruleDocument.get(RuleDocument.FIELD_REMEDIATION_COEFFICIENT)).isEqualTo("1h"); + assertThat(ruleDocument.get(RuleDocument.FIELD_REMEDIATION_OFFSET)).isNull(); + } + + + @Test + public void remove_all_rules_when_ro_rule_registered() { + String[] ids = registry.reindex(session); + registry.removeDeletedRules(ids); + assertThat(registry.findIds(new HashMap<String, String>())).hasSize(0); + } + + @Test + public void update_existing_rules_and_forget_deleted_rules() { + when(ruleDao.selectEnablesAndNonManual(session)).thenReturn(newArrayList( + new RuleDto().setId(1).setRepositoryKey("xoo").setRuleKey("key1").setSeverity(Severity.MINOR), + new RuleDto().setId(2).setRepositoryKey("xoo").setRuleKey("key2").setSeverity(Severity.MINOR) + )); + assertThat(esSetup.exists("rules", "rule", "3")).isTrue(); + + String[] ids = registry.reindex(session); + registry.removeDeletedRules(ids); + + assertThat(registry.findIds(ImmutableMap.of("repositoryKey", "xoo"))) + .hasSize(2) + .containsOnly(1, 2); + assertThat(esSetup.exists("rules", "rule", "3")).isFalse(); + } + + @Test public void find_rule_by_key() { assertThat(registry.findByKey(RuleKey.of("unknown", "RuleWithParameters"))).isNull(); assertThat(registry.findByKey(RuleKey.of("xoo", "unknown"))).isNull(); @@ -175,185 +308,6 @@ public class RuleRegistryTest { } @Test - public void remove_all_rules_when_ro_rule_registered() { - List<RuleDto> rules = Lists.newArrayList(); - registry.bulkRegisterRules(rules, null, null, null); - assertThat(registry.findIds(new HashMap<String, String>())).hasSize(0); - } - - @Test - public void index_all_rules() { - int ruleId1 = 3; - RuleDto rule1 = new RuleDto(); - rule1.setRepositoryKey("repo"); - rule1.setRuleKey("key1"); - rule1.setId(ruleId1); - rule1.setSeverity(Severity.MINOR); - rule1.setNoteData("noteData"); - rule1.setNoteUserLogin("userLogin"); - - int ruleId2 = 4; - RuleDto rule2 = new RuleDto(); - rule2.setRepositoryKey("repo"); - rule2.setRuleKey("key2"); - rule2.setId(ruleId2); - rule2.setSeverity(Severity.MAJOR); - rule2.setParentId(ruleId1); - List<RuleDto> rules = ImmutableList.of(rule1, rule2); - - RuleParamDto paramRule2 = new RuleParamDto(); - paramRule2.setName("name"); - paramRule2.setRuleId(ruleId2); - - Multimap<Integer, RuleParamDto> params = ArrayListMultimap.create(); - params.put(ruleId2, paramRule2); - - RuleRuleTagDto systemTag1Rule2 = new RuleRuleTagDto(); - systemTag1Rule2.setRuleId(ruleId2); - systemTag1Rule2.setTag("tag1"); - systemTag1Rule2.setType(RuleTagType.SYSTEM); - RuleRuleTagDto systemTag2Rule2 = new RuleRuleTagDto(); - systemTag2Rule2.setRuleId(ruleId2); - systemTag2Rule2.setTag("tag2"); - systemTag2Rule2.setType(RuleTagType.SYSTEM); - RuleRuleTagDto adminTagRule2 = new RuleRuleTagDto(); - adminTagRule2.setRuleId(ruleId2); - adminTagRule2.setTag("tag"); - adminTagRule2.setType(RuleTagType.ADMIN); - - Multimap<Integer, RuleRuleTagDto> tags = ArrayListMultimap.create(); - tags.put(ruleId2, systemTag1Rule2); - tags.put(ruleId2, systemTag2Rule2); - tags.put(ruleId2, adminTagRule2); - - registry.bulkRegisterRules(rules, Maps.<Integer, CharacteristicDto>newHashMap(), params, tags); - assertThat(registry.findIds(ImmutableMap.of("repositoryKey", "repo"))).hasSize(2); - - Map<String, Object> rule2Document = esSetup.client().prepareGet("rules", "rule", Integer.toString(ruleId2)).execute().actionGet().getSourceAsMap(); - assertThat((List<String>) rule2Document.get(RuleDocument.FIELD_SYSTEM_TAGS)).hasSize(2); - assertThat((List<String>) rule2Document.get(RuleDocument.FIELD_ADMIN_TAGS)).hasSize(1); - } - - @Test - public void reindex_all_rules() { - SqlSession session = mock(SqlSession.class); - when(myBatis.openSession()).thenReturn(session); - - registry.reindexRules(); - - verify(ruleDao).selectEnablesAndNonManual(session); - verify(ruleDao).selectParameters(session); - verify(ruleDao).selectTags(session); - verify(characteristicDao).selectEnabledCharacteristics(session); - } - - @Test - public void update_existing_rules_and_forget_deleted_rules() { - int ruleId1 = 1; - RuleDto rule1 = new RuleDto(); - rule1.setRepositoryKey("xoo"); - rule1.setRuleKey("key1"); - rule1.setId(ruleId1); - rule1.setSeverity(Severity.MINOR); - int ruleId2 = 2; - RuleDto rule2 = new RuleDto(); - rule2.setRepositoryKey("xoo"); - rule2.setRuleKey("key2"); - rule2.setId(ruleId2); - rule2.setParentId(ruleId1); - rule2.setSeverity(Severity.MINOR); - List<RuleDto> rules = ImmutableList.of(rule1, rule2); - - assertThat(esSetup.exists("rules", "rule", "3")).isTrue(); - when(ruleDao.selectNonManual(any(SqlSession.class))).thenReturn(rules); - final Multimap<Integer, RuleParamDto> params = ArrayListMultimap.create(); - final Multimap<Integer, RuleRuleTagDto> tags = ArrayListMultimap.create(); - registry.bulkRegisterRules(rules, Maps.<Integer, CharacteristicDto>newHashMap(), params, tags); - - assertThat(registry.findIds(ImmutableMap.of("repositoryKey", "xoo"))) - .hasSize(2) - .containsOnly(ruleId1, ruleId2); - assertThat(esSetup.exists("rules", "rule", "3")).isFalse(); - } - - @Test - public void index_debt_definitions() { - Map<Integer, CharacteristicDto> characteristics = newHashMap(); - characteristics.put(10, new CharacteristicDto().setId(10).setKey("REUSABILITY").setName("Reusability")); - characteristics.put(11, new CharacteristicDto().setId(11).setKey("MODULARITY").setName("Modularity").setParentId(10)); - - List<RuleDto> rules = ImmutableList.of(new RuleDto().setId(10).setRepositoryKey("repo").setRuleKey("key1").setSeverity(Severity.MINOR) - .setDefaultSubCharacteristicId(11).setDefaultRemediationFunction("LINEAR_OFFSET").setDefaultRemediationCoefficient("1h").setDefaultRemediationOffset("15min")); - - registry.bulkRegisterRules(rules, characteristics, ArrayListMultimap.<Integer, RuleParamDto>create(), ArrayListMultimap.<Integer, RuleRuleTagDto>create()); - - Map<String, Object> ruleDocument = esSetup.client().prepareGet("rules", "rule", Integer.toString(10)).execute().actionGet().getSourceAsMap(); - assertThat(ruleDocument.get(RuleDocument.FIELD_CHARACTERISTIC_ID)).isEqualTo(10); - assertThat(ruleDocument.get(RuleDocument.FIELD_CHARACTERISTIC_KEY)).isEqualTo("REUSABILITY"); - assertThat(ruleDocument.get(RuleDocument.FIELD_CHARACTERISTIC_NAME)).isEqualTo("Reusability"); - assertThat(ruleDocument.get(RuleDocument.FIELD_SUB_CHARACTERISTIC_ID)).isEqualTo(11); - assertThat(ruleDocument.get(RuleDocument.FIELD_SUB_CHARACTERISTIC_KEY)).isEqualTo("MODULARITY"); - assertThat(ruleDocument.get(RuleDocument.FIELD_SUB_CHARACTERISTIC_NAME)).isEqualTo("Modularity"); - assertThat(ruleDocument.get(RuleDocument.FIELD_REMEDIATION_FUNCTION)).isEqualTo("LINEAR_OFFSET"); - assertThat(ruleDocument.get(RuleDocument.FIELD_REMEDIATION_COEFFICIENT)).isEqualTo("1h"); - assertThat(ruleDocument.get(RuleDocument.FIELD_REMEDIATION_OFFSET)).isEqualTo("15min"); - } - - @Test - public void index_overridden_characteristic_if_both_default_and_overridden_characteristics_exists() { - Map<Integer, CharacteristicDto> characteristics = newHashMap(); - characteristics.put(10, new CharacteristicDto().setId(10).setKey("REUSABILITY").setName("Reusability")); - characteristics.put(11, new CharacteristicDto().setId(11).setKey("MODULARITY").setName("Modularity").setParentId(10)); - characteristics.put(12, new CharacteristicDto().setId(12).setKey("PORTABILITY").setName("Portability")); - characteristics.put(13, new CharacteristicDto().setId(13).setKey("COMPILER").setName("Compiler").setParentId(12)); - - List<RuleDto> rules = ImmutableList.of(new RuleDto().setId(10).setRepositoryKey("repo").setRuleKey("key1").setSeverity(Severity.MINOR) - // default and overridden debt values are set - .setDefaultSubCharacteristicId(11).setDefaultRemediationFunction("LINEAR").setDefaultRemediationCoefficient("2h") - .setSubCharacteristicId(13).setRemediationFunction("LINEAR_OFFSET").setRemediationCoefficient("1h").setRemediationOffset("15min")); - - registry.bulkRegisterRules(rules, characteristics, ArrayListMultimap.<Integer, RuleParamDto>create(), ArrayListMultimap.<Integer, RuleRuleTagDto>create()); - - Map<String, Object> ruleDocument = esSetup.client().prepareGet("rules", "rule", Integer.toString(10)).execute().actionGet().getSourceAsMap(); - assertThat(ruleDocument.get(RuleDocument.FIELD_CHARACTERISTIC_ID)).isEqualTo(12); - assertThat(ruleDocument.get(RuleDocument.FIELD_CHARACTERISTIC_KEY)).isEqualTo("PORTABILITY"); - assertThat(ruleDocument.get(RuleDocument.FIELD_CHARACTERISTIC_NAME)).isEqualTo("Portability"); - assertThat(ruleDocument.get(RuleDocument.FIELD_SUB_CHARACTERISTIC_ID)).isEqualTo(13); - assertThat(ruleDocument.get(RuleDocument.FIELD_SUB_CHARACTERISTIC_KEY)).isEqualTo("COMPILER"); - assertThat(ruleDocument.get(RuleDocument.FIELD_SUB_CHARACTERISTIC_NAME)).isEqualTo("Compiler"); - - assertThat(ruleDocument.get(RuleDocument.FIELD_REMEDIATION_FUNCTION)).isEqualTo("LINEAR_OFFSET"); - assertThat(ruleDocument.get(RuleDocument.FIELD_REMEDIATION_COEFFICIENT)).isEqualTo("1h"); - assertThat(ruleDocument.get(RuleDocument.FIELD_REMEDIATION_OFFSET)).isEqualTo("15min"); - } - - @Test - public void index_overridden_function_if_both_default_and_overridden_functions_exists() { - Map<Integer, CharacteristicDto> characteristics = newHashMap(); - characteristics.put(10, new CharacteristicDto().setId(10).setKey("REUSABILITY").setName("Reusability")); - characteristics.put(11, new CharacteristicDto().setId(11).setKey("MODULARITY").setName("Modularity").setParentId(10)); - - List<RuleDto> rules = ImmutableList.of(new RuleDto().setId(10).setRepositoryKey("repo").setRuleKey("key1").setSeverity(Severity.MINOR) - // default and overridden debt values are set - .setDefaultSubCharacteristicId(11).setDefaultRemediationFunction("CONSTANT_ISSUE").setDefaultRemediationOffset("15min") - .setSubCharacteristicId(11).setRemediationFunction("LINEAR").setRemediationCoefficient("1h")); - - registry.bulkRegisterRules(rules, characteristics, ArrayListMultimap.<Integer, RuleParamDto>create(), ArrayListMultimap.<Integer, RuleRuleTagDto>create()); - - Map<String, Object> ruleDocument = esSetup.client().prepareGet("rules", "rule", Integer.toString(10)).execute().actionGet().getSourceAsMap(); - assertThat(ruleDocument.get(RuleDocument.FIELD_CHARACTERISTIC_ID)).isEqualTo(10); - assertThat(ruleDocument.get(RuleDocument.FIELD_CHARACTERISTIC_KEY)).isEqualTo("REUSABILITY"); - assertThat(ruleDocument.get(RuleDocument.FIELD_CHARACTERISTIC_NAME)).isEqualTo("Reusability"); - assertThat(ruleDocument.get(RuleDocument.FIELD_SUB_CHARACTERISTIC_ID)).isEqualTo(11); - assertThat(ruleDocument.get(RuleDocument.FIELD_SUB_CHARACTERISTIC_KEY)).isEqualTo("MODULARITY"); - assertThat(ruleDocument.get(RuleDocument.FIELD_SUB_CHARACTERISTIC_NAME)).isEqualTo("Modularity"); - - assertThat(ruleDocument.get(RuleDocument.FIELD_REMEDIATION_FUNCTION)).isEqualTo("LINEAR"); - assertThat(ruleDocument.get(RuleDocument.FIELD_REMEDIATION_COEFFICIENT)).isEqualTo("1h"); - assertThat(ruleDocument.get(RuleDocument.FIELD_REMEDIATION_OFFSET)).isNull(); - } - - @Test public void find_rules_by_name() { // Removed rule should not appear assertThat(registry.find(RuleQuery.builder().searchQuery("Removed rule").build()).results()).isEmpty(); @@ -419,26 +373,6 @@ public class RuleRegistryTest { } @Test - public void find_rules_with_all_remediation_function_types() { - Map<Integer, CharacteristicDto> characteristics = newHashMap(); - characteristics.put(10, new CharacteristicDto().setId(10).setKey("REUSABILITY").setName("Reusability")); - characteristics.put(11, new CharacteristicDto().setId(11).setKey("MODULARITY").setName("Modularity").setParentId(10)); - - List<RuleDto> rules = ImmutableList.of( - new RuleDto().setId(10).setRepositoryKey("repo").setRuleKey("key1").setSeverity(Severity.MINOR) - .setDefaultSubCharacteristicId(11).setDefaultRemediationFunction("LINEAR").setDefaultRemediationCoefficient("1h"), - new RuleDto().setId(11).setRepositoryKey("repo").setRuleKey("key2").setSeverity(Severity.MINOR) - .setDefaultSubCharacteristicId(11).setDefaultRemediationFunction("CONSTANT_ISSUE").setDefaultRemediationOffset("15min"), - new RuleDto().setId(12).setRepositoryKey("repo").setRuleKey("key3").setSeverity(Severity.MINOR) - .setDefaultSubCharacteristicId(11).setDefaultRemediationFunction("LINEAR_OFFSET").setDefaultRemediationCoefficient("1h").setDefaultRemediationOffset("15min") - ); - - registry.bulkRegisterRules(rules, characteristics, ArrayListMultimap.<Integer, RuleParamDto>create(), ArrayListMultimap.<Integer, RuleRuleTagDto>create()); - - assertThat(registry.find(RuleQuery.builder().build()).results()).hasSize(3); - } - - @Test public void find_with_no_pagination() { assertThat(registry.find(RuleQuery.builder().pageSize(-1).build()).results()).hasSize(2); } diff --git a/sonar-server/src/test/java/org/sonar/server/startup/CopyRequirementsFromCharacteristicsToRulesTest.java b/sonar-server/src/test/java/org/sonar/server/startup/CopyRequirementsFromCharacteristicsToRulesTest.java index 2fda3e16e20..f13544ddb5d 100644 --- a/sonar-server/src/test/java/org/sonar/server/startup/CopyRequirementsFromCharacteristicsToRulesTest.java +++ b/sonar-server/src/test/java/org/sonar/server/startup/CopyRequirementsFromCharacteristicsToRulesTest.java @@ -71,7 +71,7 @@ public class CopyRequirementsFromCharacteristicsToRulesTest extends AbstractDaoT service.start(); db.assertDbUnit(getClass(), "copy_requirements_from_characteristics_to_rules_result.xml", "rules"); - verify(ruleRegistry).reindexRules(); + verify(ruleRegistry).reindex(); } @Test @@ -84,7 +84,7 @@ public class CopyRequirementsFromCharacteristicsToRulesTest extends AbstractDaoT service.start(); db.assertDbUnit(getClass(), "remove_requirements_data_from_characteristics_result.xml", "characteristics"); - verify(ruleRegistry).reindexRules(); + verify(ruleRegistry).reindex(); } @Test |