}
/**
- * Disable characteristic and sub characteristic or only sub characteristic.
- * Will also update every rules linked to sub characteristics by setting characteristic id to -1 and remove function, coefficient and offset.
+ * Delete a characteristic or a sub characteristic.
+ * <br/>
+ * If a characteristic is selected, all its sub characteristics will also be deleted.
+ * Every rules linked to sub characteristics will have their debt definitions reset.
*/
public void delete(int characteristicId) {
debtModelOperations.delete(characteristicId);
RulesDefinition.Context context = defLoader.load();
Buffer buffer = new Buffer(system.now());
List<CharacteristicDto> characteristicDtos = characteristicDao.selectEnabledCharacteristics();
+ for (CharacteristicDto characteristicDto : characteristicDtos) {
+ buffer.add(characteristicDto);
+ }
selectRulesFromDb(buffer, sqlSession);
enableRuleDefinitions(context, buffer, characteristicDtos, sqlSession);
List<RuleDto> removedRules = processRemainingDbRules(buffer, sqlSession);
}
private void index(Buffer buffer) {
- ruleRegistry.bulkRegisterRules(buffer.rulesById.values(), buffer.paramsByRuleId, buffer.tagsByRuleId);
+ ruleRegistry.bulkRegisterRules(buffer.rulesById.values(), buffer.characteristicsById, buffer.paramsByRuleId, buffer.tagsByRuleId);
esRuleTags.putAllTags(buffer.referenceTagsByTagValue.values());
}
private Multimap<Integer, RuleParamDto> paramsByRuleId = ArrayListMultimap.create();
private Multimap<Integer, RuleRuleTagDto> tagsByRuleId = ArrayListMultimap.create();
private Map<String, RuleTagDto> referenceTagsByTagValue = Maps.newHashMap();
+ private Map<Integer, CharacteristicDto> characteristicsById = Maps.newHashMap();
Buffer(long now) {
this.now = new Date(now);
rulesByKey.put(RuleKey.of(rule.getRepositoryKey(), rule.getRuleKey()), rule);
}
+ void add(CharacteristicDto characteristicDto) {
+ characteristicsById.put(characteristicDto.getId(), characteristicDto);
+ }
+
void add(RuleTagDto tag) {
referenceTagsByTagValue.put(tag.getTag(), tag);
}
return ruleRegistry.findIds(params).toArray(new Integer[0]);
}
+ /**
+ * No more used
+ */
public void saveOrUpdate(int ruleId) {
ruleRegistry.saveOrUpdate(ruleId);
}
public final class RuleDocument {
+ public static final String FIELD_ID = "id";
+ public static final String FIELD_REPOSITORY_KEY = "repositoryKey";
+ public static final String FIELD_KEY = "key";
+ public static final String FIELD_LANGUAGE = "language";
+ public static final String FIELD_NAME = "name";
+ public static final String FIELD_SEVERITY = "severity";
+ public static final String FIELD_DESCRIPTION = "description";
+ public static final String FIELD_TEMPLATE_ID = "templateId";
+ public static final String FIELD_STATUS = "status";
public static final String FIELD_SYSTEM_TAGS = "systemTags";
public static final String FIELD_ADMIN_TAGS = "adminTags";
public static final String FIELD_PARAMS = "params";
public static final String FIELD_UPDATED_AT = "updatedAt";
public static final String FIELD_CREATED_AT = "createdAt";
- public static final String FIELD_STATUS = "status";
- public static final String FIELD_SEVERITY = "severity";
- public static final String FIELD_REPOSITORY_KEY = "repositoryKey";
- public static final String FIELD_TEMPLATE_ID = "templateId";
- public static final String FIELD_DESCRIPTION = "description";
- public static final String FIELD_NAME = "name";
- public static final String FIELD_LANGUAGE = "language";
- public static final String FIELD_KEY = "key";
- public static final String FIELD_ID = "id";
+
+ public static final String FIELD_CHARACTERISTIC_ID = "characteristicId";
+ public static final String FIELD_CHARACTERISTIC_KEY = "characteristicKey";
+ public static final String FIELD_CHARACTERISTIC_NAME = "characteristicName";
+ public static final String FIELD_SUB_CHARACTERISTIC_ID = "subCharacteristicId";
+ public static final String FIELD_SUB_CHARACTERISTIC_KEY = "subCharacteristicKey";
+ public static final String FIELD_SUB_CHARACTERISTIC_NAME = "subCharacteristicName";
+ public static final String FIELD_REMEDIATION_FUNCTION = "remediationFunction";
+ public static final String FIELD_REMEDIATION_COEFFICIENT = "remediationCoefficient";
+ public static final String FIELD_REMEDIATION_OFFSET = "remediationOffset";
public static final String FIELD_PARAM_KEY = "key";
public static final String FIELD_PARAM_TYPE = "type";
*/
package org.sonar.server.rule;
-import org.sonar.server.paging.Paging;
+import com.google.common.base.Preconditions;
+import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
/**
*/
public class RuleQuery {
+ public static final int DEFAULT_PAGE_INDEX = 1;
private static final int DEFAULT_PAGE_SIZE = 25;
private String key;
-
private String query;
-
- private Paging paging;
-
- private RuleQuery(@Nullable String key, @Nullable String query, Paging paging) {
- this.key = key;
- this.query = query;
- this.paging = paging;
+ private String characteristicKey;
+ private String subCharacteristicKey;
+
+ private int pageSize;
+ private int pageIndex;
+
+ private RuleQuery(Builder builder) {
+ this.key = builder.key;
+ this.query = builder.query;
+ this.subCharacteristicKey = builder.subCharacteristicKey;
+ this.characteristicKey = builder.characteristicKey;
+ this.pageSize = builder.pageSize;
+ this.pageIndex = builder.pageIndex;
}
+ @CheckForNull
public String key() {
- return this.key;
+ return key;
}
+ @CheckForNull
public String query() {
- return this.query;
+ return query;
}
- public Paging paging() {
- return this.paging;
+ @CheckForNull
+ public String characteristicKey() {
+ return characteristicKey;
+ }
+
+ @CheckForNull
+ public String subCharacteristicKey() {
+ return subCharacteristicKey;
+ }
+
+ public int pageSize() {
+ return pageSize;
+ }
+
+ public int pageIndex() {
+ return pageIndex;
}
public static Builder builder() {
public static class Builder {
private String key;
-
private String query;
+ private String characteristicKey;
+ private String subCharacteristicKey;
- private int pageSize;
+ private Integer pageSize;
+ private Integer pageIndex;
- private int page;
+ public Builder key(@Nullable String key) {
+ this.key = key;
+ return this;
+ }
- private Builder() {
- this.page = 0;
- this.pageSize = DEFAULT_PAGE_SIZE;
+ public Builder searchQuery(@Nullable String query) {
+ this.query = query;
+ return this;
}
- public Builder withKey(String key) {
- this.key = key;
+ public Builder characteristicKey(@Nullable String characteristicKey) {
+ this.characteristicKey = characteristicKey;
return this;
}
- public Builder withSearchQuery(String query) {
- this.query = query;
+ public Builder subCharacteristicKey(@Nullable String subCharacteristicKey) {
+ this.subCharacteristicKey = subCharacteristicKey;
return this;
}
- public Builder withPageSize(int pageSize) {
+ public Builder pageSize(@Nullable Integer pageSize) {
this.pageSize = pageSize;
return this;
}
- public Builder withPage(int page) {
- this.page = page;
+ public Builder pageIndex(@Nullable Integer page) {
+ this.pageIndex = page;
return this;
}
public RuleQuery build() {
- return new RuleQuery(key, query, Paging.create(pageSize, page));
+ initPageSize();
+ initPageIndex();
+ return new RuleQuery(this);
+ }
+
+ private void initPageSize() {
+ if (pageSize == null) {
+ pageSize = DEFAULT_PAGE_SIZE;
+ }
+ }
+
+ private void initPageIndex() {
+ if (pageIndex == null) {
+ pageIndex = DEFAULT_PAGE_INDEX;
+ }
+ Preconditions.checkArgument(pageIndex > 0, "Page index must be greater than 0 (got " + pageIndex + ")");
}
}
}
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.TimeProfiler;
import org.sonar.core.rule.*;
+import org.sonar.core.technicaldebt.db.CharacteristicDto;
import org.sonar.server.es.ESIndex;
import org.sonar.server.es.SearchQuery;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.paging.PagedResult;
+import org.sonar.server.paging.Paging;
import org.sonar.server.paging.PagingResult;
import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import static com.google.common.collect.Lists.newArrayList;
+import static org.elasticsearch.index.query.FilterBuilders.boolFilter;
+import static org.elasticsearch.index.query.FilterBuilders.termFilter;
import static org.sonar.api.rules.Rule.STATUS_REMOVED;
/**
searchIndex.addMappingFromClasspath(INDEX_RULES, TYPE_RULE, "/org/sonar/server/es/config/mappings/rule_mapping.json");
}
- public void bulkRegisterRules(Collection<RuleDto> rules, Multimap<Integer, RuleParamDto> paramsByRule, Multimap<Integer, RuleRuleTagDto> tagsByRule) {
- String[] ids = bulkIndexRules(rules, paramsByRule, tagsByRule);
+ 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);
}
}
public PagedResult<Rule> find(RuleQuery query) {
- BoolFilterBuilder mainFilter = FilterBuilders.boolFilter().mustNot(FilterBuilders.termFilter(RuleDocument.FIELD_STATUS, STATUS_REMOVED));
+ BoolFilterBuilder mainFilter = boolFilter().mustNot(termFilter(RuleDocument.FIELD_STATUS, STATUS_REMOVED));
if (StringUtils.isNotBlank(query.query())) {
mainFilter.must(FilterBuilders.queryFilter(
- QueryBuilders.multiMatchQuery(query.query(), RuleDocument.FIELD_NAME+".search", RuleDocument.FIELD_KEY).operator(Operator.AND)));
+ QueryBuilders.multiMatchQuery(query.query(), RuleDocument.FIELD_NAME + ".search", RuleDocument.FIELD_KEY).operator(Operator.AND)));
}
+ if (query.characteristicKey() != null) {
+ mainFilter.must(termFilter(RuleDocument.FIELD_CHARACTERISTIC_KEY, query.characteristicKey()));
+ }
+ if (query.subCharacteristicKey() != null) {
+ mainFilter.must(termFilter(RuleDocument.FIELD_SUB_CHARACTERISTIC_KEY, query.subCharacteristicKey()));
+ }
+ Paging paging = Paging.create(query.pageSize(), query.pageIndex());
SearchHits hits = searchIndex.executeRequest(
searchIndex.client().prepareSearch(INDEX_RULES).setTypes(TYPE_RULE)
.setPostFilter(mainFilter)
.addSort(RuleDocument.FIELD_NAME, SortOrder.ASC)
- .setSize(query.paging().pageSize())
- .setFrom(query.paging().offset()));
+ .setSize(paging.pageSize())
+ .setFrom(paging.offset())
+ );
Builder<Rule> rulesBuilder = ImmutableList.builder();
- for (SearchHit hit: hits.hits()) {
+ for (SearchHit hit : hits.hits()) {
rulesBuilder.add(RuleDocumentParser.parse(hit.sourceAsMap()));
}
- return new PagedResult<Rule>(rulesBuilder.build(), PagingResult.create(query.paging().pageSize(), query.paging().pageIndex(), hits.getTotalHits()));
+ return new PagedResult<Rule>(rulesBuilder.build(), PagingResult.create(paging.pageSize(), paging.pageIndex(), hits.getTotalHits()));
}
/**
* Create or update definition of rule identified by <code>ruleId</code>
- *
- * @param ruleId
*/
public void saveOrUpdate(int ruleId) {
RuleDto rule = ruleDao.selectById(ruleId);
public void save(RuleDto rule, Collection<RuleParamDto> params, Collection<RuleRuleTagDto> tags) {
try {
- searchIndex.putSynchronous(INDEX_RULES, TYPE_RULE, Long.toString(rule.getId()), ruleDocument(rule, params, tags));
+ searchIndex.putSynchronous(INDEX_RULES, TYPE_RULE, Long.toString(rule.getId()), ruleDocument(rule, null, null, params, tags));
} catch (IOException ioexception) {
throw new IllegalStateException("Unable to index rule with id=" + rule.getId(), ioexception);
}
@CheckForNull
public Rule findByKey(RuleKey key) {
final SearchHits hits = searchIndex.executeRequest(searchIndex.client().prepareSearch(INDEX_RULES).setTypes(TYPE_RULE)
- .setPostFilter(FilterBuilders.boolFilter()
+ .setPostFilter(boolFilter()
.must(
- FilterBuilders.termFilter(RuleDocument.FIELD_REPOSITORY_KEY, key.repository()),
- FilterBuilders.termFilter(RuleDocument.FIELD_KEY, key.rule())
- )));
+ termFilter(RuleDocument.FIELD_REPOSITORY_KEY, key.repository()),
+ termFilter(RuleDocument.FIELD_KEY, key.rule())
+ )));
if (hits.totalHits() == 0) {
return null;
} else {
}
}
- private String[] bulkIndexRules(Collection<RuleDto> rules, Multimap<Integer, RuleParamDto> paramsByRule, Multimap<Integer, RuleRuleTagDto> tagsByRule) {
+ private String[] bulkIndexRules(Collection<RuleDto> rules, Map<Integer, CharacteristicDto> characteristicsById, Multimap<Integer, RuleParamDto> paramsByRule,
+ Multimap<Integer, RuleRuleTagDto> tagsByRule) {
try {
String[] ids = new String[rules.size()];
BytesStream[] docs = new BytesStream[rules.size()];
profiler.start("Build rules documents");
for (RuleDto rule : rules) {
ids[index] = rule.getId().toString();
- docs[index] = ruleDocument(rule, paramsByRule.get(rule.getId()), tagsByRule.get(rule.getId()));
+ 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()));
index++;
}
profiler.stop();
}
}
- private XContentBuilder ruleDocument(RuleDto rule, Collection<RuleParamDto> params, Collection<RuleRuleTagDto> tags) throws IOException {
+ private XContentBuilder ruleDocument(RuleDto rule, @Nullable CharacteristicDto characteristicDto, @Nullable CharacteristicDto subCharacteristicDto,
+ Collection<RuleParamDto> params, Collection<RuleRuleTagDto> tags) throws IOException {
XContentBuilder document = XContentFactory.jsonBuilder()
.startObject()
.field(RuleDocument.FIELD_ID, rule.getId())
.field(RuleDocument.FIELD_CARDINALITY, rule.getCardinality())
.field(RuleDocument.FIELD_CREATED_AT, rule.getCreatedAt())
.field(RuleDocument.FIELD_UPDATED_AT, rule.getUpdatedAt());
+ if (characteristicDto != null && subCharacteristicDto != null) {
+ document
+ .field(RuleDocument.FIELD_CHARACTERISTIC_ID, characteristicDto.getId())
+ .field(RuleDocument.FIELD_CHARACTERISTIC_KEY, characteristicDto.getKey())
+ .field(RuleDocument.FIELD_CHARACTERISTIC_NAME, characteristicDto.getName())
+ .field(RuleDocument.FIELD_SUB_CHARACTERISTIC_ID, subCharacteristicDto.getId())
+ .field(RuleDocument.FIELD_SUB_CHARACTERISTIC_KEY, subCharacteristicDto.getKey())
+ .field(RuleDocument.FIELD_SUB_CHARACTERISTIC_NAME, subCharacteristicDto.getName())
+ .field(RuleDocument.FIELD_REMEDIATION_FUNCTION, rule.getRemediationFunction() != null ? rule.getRemediationFunction() : rule.getDefaultRemediationFunction())
+ .field(RuleDocument.FIELD_REMEDIATION_COEFFICIENT, rule.getRemediationCoefficient() != null ? rule.getRemediationCoefficient() : rule.getDefaultRemediationCoefficient())
+ .field(RuleDocument.FIELD_REMEDIATION_OFFSET, rule.getRemediationOffset() != null ? rule.getRemediationOffset() : rule.getDefaultRemediationOffset());
+ }
+
if (rule.getNoteData() != null || rule.getNoteUserLogin() != null) {
document.startObject(RuleDocument.FIELD_NOTE)
.field(RuleDocument.FIELD_NOTE_DATA, rule.getNoteData())
}
document.endArray();
}
-
List<String> systemTags = Lists.newArrayList();
List<String> adminTags = Lists.newArrayList();
- for (RuleRuleTagDto tag: tags) {
+ for (RuleRuleTagDto tag : tags) {
if (tag.getType() == RuleTagType.SYSTEM) {
systemTags.add(tag.getTag());
} else {
final int pageSize = request.paramAsInt("ps", 25);
final int pageIndex = request.paramAsInt("p", 1);
PagedResult<Rule> searchResult = rules.find(RuleQuery.builder()
- .withSearchQuery(ruleSearchParam)
- .withPageSize(pageSize)
- .withPage(pageIndex)
+ .searchQuery(ruleSearchParam)
+ .pageSize(pageSize)
+ .pageIndex(pageIndex)
.build());
foundRules = searchResult.results();
hasMore = searchResult.paging().hasNextPage();
"adminTags": {
"type": "string",
"index": "not_analyzed"
+ },
+ "characteristicId": {
+ "type": "integer",
+ "index": "not_analyzed"
+ },
+ "characteristicKey": {
+ "type": "string",
+ "index": "not_analyzed"
+ },
+ "characteristicName": {
+ "type": "string",
+ "index": "not_analyzed"
+ },
+ "subCharacteristicId": {
+ "type": "integer",
+ "index": "not_analyzed"
+ },
+ "subCharacteristicKey": {
+ "type": "string",
+ "index": "not_analyzed"
+ },
+ "subCharacteristicName": {
+ "type": "string",
+ "index": "not_analyzed"
+ },
+ "remediationFunction": {
+ "type": "string",
+ "index": "not_analyzed"
+ },
+ "remediationCoefficient": {
+ "type": "string",
+ "index": "not_analyzed"
+ },
+ "remediationOffset": {
+ "type": "string",
+ "index": "not_analyzed"
}
}
}
package org.sonar.server.rule;
import com.github.tlrx.elasticsearch.test.EsSetup;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Multimap;
+import com.google.common.collect.*;
import org.apache.commons.io.IOUtils;
import org.apache.ibatis.session.SqlSession;
import org.elasticsearch.common.collect.Lists;
import org.sonar.core.persistence.MyBatis;
import org.sonar.core.profiling.Profiling;
import org.sonar.core.rule.*;
+import org.sonar.core.technicaldebt.db.CharacteristicDto;
import org.sonar.server.es.ESIndex;
import org.sonar.server.es.ESNode;
import org.sonar.test.TestUtils;
import java.util.List;
import java.util.Map;
+import static com.google.common.collect.Maps.newHashMap;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
esSetup.execute(
EsSetup.index("rules", "rule", "1").withSource(testFileAsString("shared/rule1.json")),
EsSetup.index("rules", "rule", "2").withSource(testFileAsString("shared/rule2.json")),
+ // rule 3 is removed
EsSetup.index("rules", "rule", "3").withSource(testFileAsString("shared/rule3.json"))
);
esSetup.client().admin().cluster().prepareHealth(RuleRegistry.INDEX_RULES).setWaitForGreenStatus().execute().actionGet();
}
@Test
- public void should_register_mapping_at_startup() {
+ public void register_mapping_at_startup() {
assertThat(esSetup.exists("rules")).isTrue();
assertThat(esSetup.client().admin().indices().prepareTypesExists("rules").setTypes("rule").execute().actionGet().isExists()).isTrue();
}
@Test
- public void should_find_rule_by_key() {
+ public void find_rule_by_key() {
assertThat(registry.findByKey(RuleKey.of("unknown", "RuleWithParameters"))).isNull();
assertThat(registry.findByKey(RuleKey.of("xoo", "unknown"))).isNull();
final Rule rule = registry.findByKey(RuleKey.of("xoo", "RuleWithParameters"));
}
@Test
- public void should_filter_removed_rules() {
+ public void filter_removed_rules() {
assertThat(registry.findIds(new HashMap<String, String>())).containsOnly(1, 2);
}
@Test
- public void should_display_disabled_rule() {
+ public void display_disabled_rule() {
assertThat(registry.findIds(ImmutableMap.of("status", "BETA|REMOVED"))).containsOnly(2, 3);
}
@Test
- public void should_filter_on_name_or_key() throws Exception {
+ public void filter_on_name_or_key() throws Exception {
assertThat(registry.findIds(ImmutableMap.of("nameOrKey", "parameters"))).containsOnly(1);
assertThat(registry.findIds(ImmutableMap.of("nameOrKey", "issue"))).containsOnly(1, 2);
assertThat(registry.findIds(ImmutableMap.of("nameOrKey", "issue line"))).containsOnly(2);
}
@Test
- public void should_filter_on_key() throws Exception {
+ public void filter_on_key() throws Exception {
assertThat(registry.findIds(ImmutableMap.of("key", "OneIssuePerLine"))).containsOnly(2);
}
@Test
- public void should_filter_on_multiple_criteria() {
+ public void filter_on_multiple_criteria() {
assertThat(registry.findIds(ImmutableMap.of("nameOrKey", "parameters", "key", "OneIssuePerLine"))).isEmpty();
assertThat(registry.findIds(ImmutableMap.of("repositoryKey", "polop"))).isEmpty();
}
@Test
- public void should_filter_on_multiple_values() {
+ public void filter_on_multiple_values() {
assertThat(registry.findIds(ImmutableMap.of("key", "RuleWithParameters|OneIssuePerLine"))).hasSize(2);
}
@Test(expected = IllegalArgumentException.class)
- public void should_reject_leading_wildcard() {
+ public void reject_leading_wildcard() {
registry.findIds(ImmutableMap.of("nameOrKey", "*ssue"));
}
@Test(expected = IllegalArgumentException.class)
- public void should_wrap_parse_exceptions() {
+ public void wrap_parse_exceptions() {
registry.findIds(ImmutableMap.of("nameOrKey", "\"'"));
}
@Test
- public void should_remove_all_rules_when_ro_rule_registered() {
+ public void remove_all_rules_when_ro_rule_registered() {
List<RuleDto> rules = Lists.newArrayList();
- registry.bulkRegisterRules(rules, null, null);
+ registry.bulkRegisterRules(rules, null, null, null);
assertThat(registry.findIds(new HashMap<String, String>())).hasSize(0);
}
@Test
- public void should_index_all_rules() {
+ public void index_all_rules() {
int ruleId1 = 3;
RuleDto rule1 = new RuleDto();
rule1.setRepositoryKey("repo");
rule1.setSeverity(Severity.MINOR);
rule1.setNoteData("noteData");
rule1.setNoteUserLogin("userLogin");
+
int ruleId2 = 4;
RuleDto rule2 = new RuleDto();
rule2.setRepositoryKey("repo");
RuleParamDto paramRule2 = new RuleParamDto();
paramRule2.setName("name");
paramRule2.setRuleId(ruleId2);
+
Multimap<Integer, RuleParamDto> params = ArrayListMultimap.create();
params.put(ruleId2, paramRule2);
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, params, tags);
+ 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))
}
@Test
- public void should_index_and_reindex_single_rule() {
+ public void index_and_reindex_single_rule() {
RuleDto rule = new RuleDto();
rule.setRepositoryKey("repo");
rule.setRuleKey("key");
}
@Test
- public void should_update_existing_rules_and_forget_deleted_rules() {
+ public void update_existing_rules_and_forget_deleted_rules() {
int ruleId1 = 1;
RuleDto rule1 = new RuleDto();
rule1.setRepositoryKey("xoo");
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, params, tags);
+ registry.bulkRegisterRules(rules, Maps.<Integer, CharacteristicDto>newHashMap(), params, tags);
assertThat(registry.findIds(ImmutableMap.of("repositoryKey", "xoo")))
.hasSize(2)
}
@Test
- public void should_find_rules_by_name() {
+ public void find_rules_by_name() {
// Removed rule should not appear
- assertThat(registry.find(RuleQuery.builder().withPage(1).withPageSize(10).build()).results()).hasSize(2);
+ assertThat(registry.find(RuleQuery.builder().pageIndex(1).pageSize(10).build()).results()).hasSize(2);
// Search is case insensitive
- assertThat(registry.find(RuleQuery.builder().withPage(1).withPageSize(10).withSearchQuery("one issue per line").build()).results()).hasSize(1);
+ assertThat(registry.find(RuleQuery.builder().pageIndex(1).pageSize(10).searchQuery("one issue per line").build()).results()).hasSize(1);
// Search is ngram based
- assertThat(registry.find(RuleQuery.builder().withPage(1).withPageSize(10).withSearchQuery("with param").build()).results()).hasSize(1);
+ assertThat(registry.find(RuleQuery.builder().pageIndex(1).pageSize(10).searchQuery("with param").build()).results()).hasSize(1);
// Search works also with key
- assertThat(registry.find(RuleQuery.builder().withPage(1).withPageSize(10).withSearchQuery("OneIssuePerLine").build()).results()).hasSize(1);
+ assertThat(registry.find(RuleQuery.builder().pageIndex(1).pageSize(10).searchQuery("OneIssuePerLine").build()).results()).hasSize(1);
+ }
+
+ @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_debt_definitions_if_both_default_and_overridden_values_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 find_rules_by_characteristic_and_sub_characteristic() {
+ 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("2h"));
+
+ registry.bulkRegisterRules(rules, characteristics, ArrayListMultimap.<Integer, RuleParamDto>create(),
+ ArrayListMultimap.<Integer, RuleRuleTagDto>create());
+
+ assertThat(registry.find(RuleQuery.builder().subCharacteristicKey("MODULARITY").build()).results()).hasSize(1);
+ assertThat(registry.find(RuleQuery.builder().subCharacteristicKey("REUSABILITY").build()).results()).isEmpty();
+ assertThat(registry.find(RuleQuery.builder().subCharacteristicKey("Unknown").build()).results()).isEmpty();
+ assertThat(registry.find(RuleQuery.builder().characteristicKey("REUSABILITY").build()).results()).hasSize(1);
+ assertThat(registry.find(RuleQuery.builder().characteristicKey("MODULARITY").build()).results()).isEmpty();
+ assertThat(registry.find(RuleQuery.builder().characteristicKey("Unknown").build()).results()).isEmpty();
}
private String testFileAsString(String testFile) throws Exception {
"createdAt": "2013-10-28T13:07:26.329Z",
"updatedAt": "2013-11-08T10:52:53.473Z",
"params": [
- {
- "key": "string",
- "type": "STRING",
- "defaultValue": null,
- "description": ""
- },
- {
- "key": "text",
- "type": "TEXT",
- "defaultValue": null,
- "description": ""
- },
- {
- "key": "boolean",
- "type": "BOOLEAN",
- "defaultValue": null,
- "description": ""
- },
- {
- "key": "integer",
- "type": "INTEGER",
- "defaultValue": null,
- "description": ""
- },
- {
- "key": "float",
- "type": "FLOAT",
- "defaultValue": null,
- "description": ""
- }
- ]
- }
+ {
+ "key": "string",
+ "type": "STRING",
+ "defaultValue": null,
+ "description": ""
+ },
+ {
+ "key": "text",
+ "type": "TEXT",
+ "defaultValue": null,
+ "description": ""
+ },
+ {
+ "key": "boolean",
+ "type": "BOOLEAN",
+ "defaultValue": null,
+ "description": ""
+ },
+ {
+ "key": "integer",
+ "type": "INTEGER",
+ "defaultValue": null,
+ "description": ""
+ },
+ {
+ "key": "float",
+ "type": "FLOAT",
+ "defaultValue": null,
+ "description": ""
+ }
+ ]
}
"systemTags": [ "has-params", "integration-tests" ],
"adminTags": [ "keep-enabled" ],
"params": [
- {
- "key": "string",
- "type": "STRING",
- "defaultValue": null,
- "description": ""
- },
- {
- "key": "text",
- "type": "TEXT",
- "defaultValue": null,
- "description": ""
- },
- {
- "key": "boolean",
- "type": "BOOLEAN",
- "defaultValue": null,
- "description": ""
- },
- {
- "key": "integer",
- "type": "INTEGER",
- "defaultValue": null,
- "description": ""
- },
- {
- "key": "float",
- "type": "FLOAT",
- "defaultValue": null,
- "description": ""
- }
- ]
- }
+ {
+ "key": "string",
+ "type": "STRING",
+ "defaultValue": null,
+ "description": ""
+ },
+ {
+ "key": "text",
+ "type": "TEXT",
+ "defaultValue": null,
+ "description": ""
+ },
+ {
+ "key": "boolean",
+ "type": "BOOLEAN",
+ "defaultValue": null,
+ "description": ""
+ },
+ {
+ "key": "integer",
+ "type": "INTEGER",
+ "defaultValue": null,
+ "description": ""
+ },
+ {
+ "key": "float",
+ "type": "FLOAT",
+ "defaultValue": null,
+ "description": ""
+ }
+ ],
+ "defaultCharacteristicId": 1,
+ "characteristicId": 2,
+ "defaultRemediationFunction": "LINEAR",
+ "remediationFunction": "LINEAR_OFFSET",
+ "defaultRemediationCoefficient": "2h",
+ "remediationCoefficient": "1h",
+ "defaultRemediationOffset": null,
+ "remediationOffset": "15min"
}