From 32687065aa3c0e95b30e3758f1e70d78e0ba65eb Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Lievremont Date: Fri, 13 Dec 2013 19:02:14 +0100 Subject: [PATCH] Parse rule and active rule results, with parameters --- .../server/qualityprofile/QProfileRule.java | 112 +++++++++++++++++- .../qualityprofile/QProfileRuleResult.java | 3 +- .../org/sonar/server/rule/ProfileRules.java | 7 +- .../sonar/server/rule/ProfileRulesTest.java | 21 +++- .../active_rule25.json | 2 +- .../active_rule2702.json | 1 + .../should_find_active_rules/rule1482.json | 1 + 7 files changed, 136 insertions(+), 11 deletions(-) create mode 100644 sonar-server/src/test/resources/org/sonar/server/rule/ProfileRulesTest/should_find_active_rules/active_rule2702.json create mode 100644 sonar-server/src/test/resources/org/sonar/server/rule/ProfileRulesTest/should_find_active_rules/rule1482.json diff --git a/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileRule.java b/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileRule.java index 5cfca0afd51..72c430e0433 100644 --- a/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileRule.java +++ b/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileRule.java @@ -19,14 +19,120 @@ */ package org.sonar.server.qualityprofile; +import org.elasticsearch.common.collect.Lists; +import org.elasticsearch.common.collect.Maps; +import org.sonar.api.rules.RulePriority; + +import java.util.List; +import java.util.Map; + public class QProfileRule { - private final String ruleSource; - private final String activeRuleSource; + private final Map ruleSource; + private final Map activeRuleSource; + + private final String key; + private final String name; + private final String description; + private final String status; - public QProfileRule(String ruleSource, String activeRuleSource) { + private final RulePriority severity; + private final List params; + + public QProfileRule(Map ruleSource, Map activeRuleSource) { this.ruleSource = ruleSource; this.activeRuleSource = activeRuleSource; + + key = (String) ruleSource.get("key"); + name = (String) ruleSource.get("name"); + description = (String) ruleSource.get("description"); + status = (String) ruleSource.get("status"); + + severity = RulePriority.valueOf((String) activeRuleSource.get("severity")); + params = Lists.newArrayList(); + if (ruleSource.containsKey("params")) { + Map> ruleParams = Maps.newHashMap(); + for (Map ruleParam: (List>) ruleSource.get("params")) { + ruleParams.put((String) ruleParam.get("key"), ruleParam); + } + Map> activeRuleParams = Maps.newHashMap(); + for (Map activeRuleParam: (List>) activeRuleSource.get("params")) { + activeRuleParams.put((String) activeRuleParam.get("key"), activeRuleParam); + } + for(Map.Entry> ruleParam: ruleParams.entrySet()) { + params.add(new Param( + (String) ruleParam.getValue().get("key"), + activeRuleParams.containsKey(ruleParam.getKey()) ? (String) activeRuleParams.get(ruleParam.getKey()) + .get("value") : null, + (String) ruleParam.getValue().get("description"), + (String) ruleParam.getValue().get("defaultValue"), + (String) ruleParam.getValue().get("type") + )); + } + } + } + + public Map ruleSource() { + return ruleSource; + } + + public Map activeRuleSource() { + return activeRuleSource; + } + + public String key() { + return key; + } + + public String name() { + return name; + } + + public String description() { + return description; + } + + public String status() { + return status; + } + + public RulePriority severity() { + return severity; + } + + public List params() { + return params; + } + + class Param { + private final String key; + private final String value; + private final String description; + private final String defaultValue; + private final String type; + public Param(String key, String value, String description, String defaultValue, String type) { + super(); + this.key = key; + this.value = value; + this.description = description; + this.defaultValue = defaultValue; + this.type = type; + } + public String key() { + return key; + } + public String value() { + return value; + } + public String description() { + return description; + } + public String defaultValue() { + return defaultValue; + } + public String type() { + return type; + } } @Override diff --git a/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileRuleResult.java b/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileRuleResult.java index f964944868e..e3796c6bb4e 100644 --- a/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileRuleResult.java +++ b/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileRuleResult.java @@ -19,7 +19,6 @@ */ package org.sonar.server.qualityprofile; -import java.util.Collection; import java.util.List; public class QProfileRuleResult { @@ -32,7 +31,7 @@ public class QProfileRuleResult { this.paging = paging; } - public Collection rules() { + public List rules() { return rules; } diff --git a/sonar-server/src/main/java/org/sonar/server/rule/ProfileRules.java b/sonar-server/src/main/java/org/sonar/server/rule/ProfileRules.java index e5215173be3..e412ddb0ce5 100644 --- a/sonar-server/src/main/java/org/sonar/server/rule/ProfileRules.java +++ b/sonar-server/src/main/java/org/sonar/server/rule/ProfileRules.java @@ -37,6 +37,7 @@ import org.sonar.server.search.SearchIndex; import java.util.Collection; import java.util.List; +import java.util.Map; import static org.elasticsearch.index.query.FilterBuilders.*; import static org.elasticsearch.index.query.QueryBuilders.multiMatchQuery; @@ -63,13 +64,13 @@ public class ProfileRules { .setFrom(paging.offset()); SearchHits hits = index.executeRequest(builder); - String[] activeRuleSources = new String[hits.getHits().length]; + List> activeRuleSources = Lists.newArrayList(); String[] parentIds = new String[hits.getHits().length]; int hitCounter = 0; List result = Lists.newArrayList(); for (SearchHit hit: hits.getHits()) { - activeRuleSources[hitCounter] = hit.sourceAsString(); + activeRuleSources.add(hit.sourceAsMap()); parentIds[hitCounter] = hit.field("_parent").value(); hitCounter ++; } @@ -79,7 +80,7 @@ public class ProfileRules { .execute().actionGet().getResponses(); for (int i = 0; i < hitCounter; i ++) { - result.add(new QProfileRule(responses[i].getResponse().getSourceAsString(), activeRuleSources[i])); + result.add(new QProfileRule(responses[i].getResponse().getSourceAsMap(), activeRuleSources.get(i))); } } diff --git a/sonar-server/src/test/java/org/sonar/server/rule/ProfileRulesTest.java b/sonar-server/src/test/java/org/sonar/server/rule/ProfileRulesTest.java index 56d16e980ac..8a13f0169fb 100644 --- a/sonar-server/src/test/java/org/sonar/server/rule/ProfileRulesTest.java +++ b/sonar-server/src/test/java/org/sonar/server/rule/ProfileRulesTest.java @@ -26,12 +26,16 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.sonar.api.config.Settings; +import org.sonar.api.rules.RulePriority; import org.sonar.core.profiling.Profiling; import org.sonar.server.qualityprofile.Paging; +import org.sonar.server.qualityprofile.QProfileRule; import org.sonar.server.search.SearchIndex; import org.sonar.server.search.SearchNode; import org.sonar.test.TestUtils; +import java.util.List; + import static org.fest.assertions.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -68,18 +72,26 @@ public class ProfileRulesTest { esSetup.client().prepareBulk() .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("should_find_active_rules/rule25.json"))) .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("should_find_active_rules/rule759.json"))) + .add(Requests.indexRequest().index("rules").type("rule").source(testFileAsString("should_find_active_rules/rule1482.json"))) .add(Requests.indexRequest().index("rules").type("active_rule").parent("25").source(testFileAsString("should_find_active_rules/active_rule25.json"))) .add(Requests.indexRequest().index("rules").type("active_rule").parent("759").source(testFileAsString("should_find_active_rules/active_rule391.json"))) .add(Requests.indexRequest().index("rules").type("active_rule").parent("759").source(testFileAsString("should_find_active_rules/active_rule523.json"))) + .add(Requests.indexRequest().index("rules").type("active_rule").parent("1482").source(testFileAsString("should_find_active_rules/active_rule2702.json"))) .setRefresh(true).execute().actionGet(); Paging paging = Paging.create(10, 1); // All rules for profile 1 - assertThat(profileRules.searchActiveRules(ProfileRuleQuery.create(1), paging).rules()).hasSize(2); + List rules1 = profileRules.searchActiveRules(ProfileRuleQuery.create(1), paging).rules(); + assertThat(rules1).hasSize(3); + assertThat(rules1.get(0).key()).isEqualTo("DM_CONVERT_CASE"); + assertThat(rules1.get(0).severity()).isEqualTo(RulePriority.MINOR); // All rules for profile 2 - assertThat(profileRules.searchActiveRules(ProfileRuleQuery.create(2), paging).rules()).hasSize(1); + List rules2 = profileRules.searchActiveRules(ProfileRuleQuery.create(2), paging).rules(); + assertThat(rules2).hasSize(1); + assertThat(rules2.get(0).ruleSource().get("id")).isEqualTo(759); + assertThat(rules2.get(0).activeRuleSource().get("id")).isEqualTo(523); // Inexistent profile assertThat(profileRules.searchActiveRules(ProfileRuleQuery.create(3), paging).rules()).hasSize(0); @@ -95,6 +107,11 @@ public class ProfileRulesTest { // Match on repositoryKey assertThat(profileRules.searchActiveRules(ProfileRuleQuery.create(1).addRepositoryKeys("findbugs"), paging).rules()).hasSize(1); + + // Match on key, rule has parameters + List rulesWParam = profileRules.searchActiveRules(ProfileRuleQuery.create(1).setNameOrKey("ArchitecturalConstraint"), paging).rules(); + assertThat(rulesWParam).hasSize(1); + assertThat(rulesWParam.get(0).params()).hasSize(2); } private String testFileAsString(String testFile) throws Exception { diff --git a/sonar-server/src/test/resources/org/sonar/server/rule/ProfileRulesTest/should_find_active_rules/active_rule25.json b/sonar-server/src/test/resources/org/sonar/server/rule/ProfileRulesTest/should_find_active_rules/active_rule25.json index 7f929d28844..717f25ab7df 100644 --- a/sonar-server/src/test/resources/org/sonar/server/rule/ProfileRulesTest/should_find_active_rules/active_rule25.json +++ b/sonar-server/src/test/resources/org/sonar/server/rule/ProfileRulesTest/should_find_active_rules/active_rule25.json @@ -1 +1 @@ -{"id": 25, "severity": "INFO", "profileId": 1, "inheritance": null} \ No newline at end of file +{"id": 25, "severity": "MINOR", "profileId": 1, "inheritance": null} diff --git a/sonar-server/src/test/resources/org/sonar/server/rule/ProfileRulesTest/should_find_active_rules/active_rule2702.json b/sonar-server/src/test/resources/org/sonar/server/rule/ProfileRulesTest/should_find_active_rules/active_rule2702.json new file mode 100644 index 00000000000..2c5c79d187f --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/rule/ProfileRulesTest/should_find_active_rules/active_rule2702.json @@ -0,0 +1 @@ +{"id":2702,"severity":"CRITICAL","profileId":1,"inheritance":null,"params":[{"key":"fromClasses","value":"**.core.**"},{"key":"toClasses","value":"**.server.**"}]} diff --git a/sonar-server/src/test/resources/org/sonar/server/rule/ProfileRulesTest/should_find_active_rules/rule1482.json b/sonar-server/src/test/resources/org/sonar/server/rule/ProfileRulesTest/should_find_active_rules/rule1482.json new file mode 100644 index 00000000000..4d3cc9bac62 --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/rule/ProfileRulesTest/should_find_active_rules/rule1482.json @@ -0,0 +1 @@ +{"id":1482,"key":"ArchitecturalConstraint","language":"java","name":"Architectural constraint","description":"

A source code comply to an architectural model when it fully\n\tadheres to a set of architectural constraints. A constraint allows to\n\tdeny references between classes by pattern.

\n

You can for instance use this rule to :

\n
    \n\t
  • forbid access to **.web.** from **.dao.** classes
  • \n\t
  • forbid access to java.util.Vector, java.util.Hashtable and\n\t\tjava.util.Enumeration from any classes
  • \n\t
  • forbid access to java.sql.** from **.ui.** and **.web.**\n\t\tclasses
  • \n
","parentKey":null,"repositoryKey":"squid","severity":"MAJOR","status":"READY","createdAt":"2013-12-11T13:48:00.799Z","updatedAt":"2013-12-13T17:26:35.767Z","params":[{"key":"toClasses","type":"STRING","defaultValue":"","description":"Mandatory. Ex : java.util.Vector, java.util.Hashtable, java.util.Enumeration"},{"key":"fromClasses","type":"STRING","defaultValue":"","description":"Optional. If this property is not defined, all classes should adhere to this constraint. Ex : **.web.**"}]} -- 2.39.5