*/
package org.sonar.server.rule;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
private RuleStatus status;
private final Map<String, String> parameters = Maps.newHashMap();
- public String ruleKey() {
- return ruleKey;
+ private boolean isCustomRule = false;
+
+ private NewRule() {
+ // No direct call to constructor
}
- public NewRule setRuleKey(String ruleKey) {
- this.ruleKey = ruleKey;
- return this;
+ public String ruleKey() {
+ return ruleKey;
}
@CheckForNull
return templateKey;
}
- /**
- * For the creation a custom rule
- */
- public NewRule setTemplateKey(@Nullable RuleKey templateKey) {
- this.templateKey = templateKey;
- return this;
- }
-
@CheckForNull
public String name() {
return name;
}
public NewRule setStatus(@Nullable RuleStatus status) {
+ checkCustomRule();
this.status = status;
return this;
}
}
public NewRule setParameters(Map<String, String> params) {
+ checkCustomRule();
this.parameters.clear();
this.parameters.putAll(params);
return this;
}
+
+ private void checkCustomRule(){
+ if (!isCustomRule) {
+ throw new IllegalStateException("Not a custom rule");
+ }
+ }
+
+ public static NewRule createForCustomRule(String customKey, RuleKey templateKey) {
+ Preconditions.checkArgument(!Strings.isNullOrEmpty(customKey), "Custom key should be set");
+ Preconditions.checkArgument(templateKey != null, "Template key should be set");
+ NewRule newRule = new NewRule();
+ newRule.ruleKey = customKey;
+ newRule.templateKey = templateKey;
+ newRule.isCustomRule = true;
+ return newRule;
+ }
+
+ public static NewRule createForManualRule(String manualKey) {
+ Preconditions.checkArgument(!Strings.isNullOrEmpty(manualKey), "Manual key should be set");
+ NewRule newRule = new NewRule();
+ newRule.ruleKey = manualKey;
+ return newRule;
+ }
+
}
// sqale
public void updateRule(Map<String, Object> params) {
- RuleUpdate update = new RuleUpdate(RuleKey.parse((String) params.get("ruleKey")));
+ RuleUpdate update = RuleUpdate.createForPluginRule(RuleKey.parse((String) params.get("ruleKey")));
update.setDebtSubCharacteristic(Strings.emptyToNull((String) params.get("debtCharacteristicKey")));
String fn = (String) params.get("debtRemediationFunction");
if (fn == null) {
@CheckForNull
Date noteUpdatedAt();
+
+ boolean isManual();
}
import com.google.common.base.Strings;
import org.sonar.api.ServerComponent;
import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rule.Severity;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.rule.RuleDto;
import org.sonar.core.rule.RuleParamDto;
import org.sonar.server.db.DbClient;
+import org.sonar.server.rule.index.RuleDoc;
public class RuleCreator implements ServerComponent {
DbSession dbSession = dbClient.openSession(false);
try {
RuleKey templateKey = newRule.templateKey();
+ // Creation of a custom rule
if (templateKey != null) {
RuleDto templateRule = dbClient.ruleDao().getByKey(dbSession, templateKey);
if (!templateRule.isTemplate()) {
throw new IllegalArgumentException("This rule is not a template rule: " + templateKey.toString());
}
- validateRule(newRule);
+ validateCustomRule(newRule);
RuleKey customRuleKey = RuleKey.of(templateRule.getRepositoryKey(), newRule.ruleKey());
checkRuleKeyUnicity(customRuleKey, dbSession);
createCustomRule(customRuleKey, newRule, templateRule, dbSession);
+
+ dbSession.commit();
+ return customRuleKey;
+ } else {
+ // Creation of a manual rule
+ validateManualRule(newRule);
+
+ RuleKey customRuleKey = RuleKey.of(RuleDoc.MANUAL_REPOSITORY, newRule.ruleKey());
+ checkRuleKeyUnicity(customRuleKey, dbSession);
+ createManualRule(customRuleKey, newRule, dbSession);
+
dbSession.commit();
return customRuleKey;
}
- throw new IllegalArgumentException("Not supported");
} finally {
dbSession.close();
}
}
- private static void validateRule(NewRule newRule) {
+ private static void validateCustomRule(NewRule newRule) {
validateRuleKey(newRule.ruleKey());
- if (Strings.isNullOrEmpty(newRule.name())) {
- throw new IllegalArgumentException("The name is missing");
- }
- if (Strings.isNullOrEmpty(newRule.htmlDescription())) {
- throw new IllegalArgumentException("The description is missing");
- }
+ validateName(newRule);
+ validateDescription(newRule);
+
String severity = newRule.severity();
if (Strings.isNullOrEmpty(severity)) {
throw new IllegalArgumentException("The severity is missing");
}
}
+ private static void validateManualRule(NewRule newRule) {
+ validateRuleKey(newRule.ruleKey());
+ validateName(newRule);
+ validateDescription(newRule);
+
+ if (!newRule.parameters().isEmpty()) {
+ throw new IllegalArgumentException("No parameter can be set on a manual rule");
+ }
+ }
+
+ private static void validateName(NewRule newRule){
+ if (Strings.isNullOrEmpty(newRule.name())) {
+ throw new IllegalArgumentException("The name is missing");
+ }
+ }
+
+ private static void validateDescription(NewRule newRule){
+ if (Strings.isNullOrEmpty(newRule.htmlDescription())) {
+ throw new IllegalArgumentException("The description is missing");
+ }
+ }
+
private static void validateRuleKey(String ruleKey) {
- if (Strings.isNullOrEmpty(ruleKey)) {
- throw new IllegalArgumentException("The rule key is missing");
- } else {
- if (!ruleKey.matches("^[\\w]+$")) {
- throw new IllegalArgumentException(String.format("The rule key '%s' is invalid, it should only contains : a-z, 0-9, '_'", ruleKey));
- }
+ if (!ruleKey.matches("^[\\w]+$")) {
+ throw new IllegalArgumentException(String.format("The rule key '%s' is invalid, it should only contains : a-z, 0-9, '_'", ruleKey));
}
}
dbClient.ruleDao().addRuleParam(dbSession, ruleDto, ruleParamDto);
}
+ private RuleKey createManualRule(RuleKey ruleKey, NewRule newRule, DbSession dbSession){
+ RuleDto ruleDto = RuleDto.createFor(ruleKey)
+ .setName(newRule.name())
+ .setDescription(newRule.htmlDescription())
+ .setSeverity(newRule.severity())
+ .setStatus(RuleStatus.READY);
+ dbClient.ruleDao().insert(dbSession, ruleDto);
+ return ruleKey;
+ }
+
}
private boolean changeTags = false, changeMarkdownNote = false, changeDebtSubCharacteristic = false, changeDebtRemediationFunction = false,
changeName = false, changeDescription = false, changeSeverity = false, changeStatus = false, changeParameters = false;
- private boolean isCustomRule = false;
+ private boolean isCustomRule, isManual;
private Set<String> tags;
private String markdownNote;
private String debtSubCharacteristicKey;
private RuleStatus status;
private final Map<String, String> parameters = Maps.newHashMap();
- public RuleUpdate(RuleKey ruleKey) {
+ private RuleUpdate(RuleKey ruleKey) {
this.ruleKey = ruleKey;
}
}
public RuleUpdate setName(@Nullable String name) {
- checkCustomRule();
+ checkCustomOrManualRule();
this.name = name;
this.changeName = true;
return this;
}
public RuleUpdate setHtmlDescription(@Nullable String htmlDescription) {
- checkCustomRule();
+ checkCustomOrManualRule();
this.htmlDescription = htmlDescription;
this.changeDescription = true;
return this;
}
public RuleUpdate setSeverity(@Nullable String severity) {
- checkCustomRule();
+ checkCustomOrManualRule();
this.severity = severity;
this.changeSeverity = true;
return this;
}
}
- public static RuleUpdate createForRule(RuleKey ruleKey) {
- return new RuleUpdate(ruleKey);
+ private void checkCustomOrManualRule(){
+ if (!isCustomRule && !isManual) {
+ throw new IllegalStateException("Not a custom or a manual rule");
+ }
+ }
+
+ /**
+ * Use to update a rule provided by a plugin (name, description, severity, status and parameters cannot by changed)
+ */
+ public static RuleUpdate createForPluginRule(RuleKey ruleKey) {
+ RuleUpdate ruleUpdate = new RuleUpdate(ruleKey);
+ ruleUpdate.isCustomRule = false;
+ ruleUpdate.isManual = false;
+ return ruleUpdate;
}
+ /**
+ * Use to update a custom rule
+ */
public static RuleUpdate createForCustomRule(RuleKey ruleKey) {
RuleUpdate ruleUpdate = new RuleUpdate(ruleKey);
ruleUpdate.isCustomRule = true;
+ ruleUpdate.isManual = false;
+ return ruleUpdate;
+ }
+
+ /**
+ * Use to update a manual rule (status and parameters cannot by changed)
+ */
+ public static RuleUpdate createForManualRule(RuleKey ruleKey) {
+ RuleUpdate ruleUpdate = new RuleUpdate(ruleKey);
+ ruleUpdate.isManual = true;
+ ruleUpdate.isCustomRule = false;
return ruleUpdate;
}
*/
public class RuleDoc extends BaseDoc implements Rule {
+ public final static String MANUAL_REPOSITORY = "manual";
+
RuleDoc(@Nullable Map<String, Object> fields) {
super(fields);
}
}
@Override
+ @CheckForNull
public String internalKey() {
return getNullableField(RuleNormalizer.RuleField.INTERNAL_KEY.field());
}
@Override
+ @CheckForNull
public String language() {
- return getField(RuleNormalizer.RuleField.LANGUAGE.field());
+ return getNullableField(RuleNormalizer.RuleField.LANGUAGE.field());
}
@Override
}
@Override
+ @CheckForNull
public String severity() {
- return (String) getField(RuleNormalizer.RuleField.SEVERITY.field());
+ return (String) getNullableField(RuleNormalizer.RuleField.SEVERITY.field());
}
@Override
+ @CheckForNull
public RuleStatus status() {
return RuleStatus.valueOf((String) getField(RuleNormalizer.RuleField.STATUS.field()));
}
}
@Override
+ @CheckForNull
public RuleKey templateKey() {
String templateKey = getNullableField(RuleNormalizer.RuleField.TEMPLATE_KEY.field());
return templateKey != null ? RuleKey.parse(templateKey) : null;
}
@Override
+ @CheckForNull
public String debtCharacteristicKey() {
return (String) getNullableField(RuleNormalizer.RuleField.CHARACTERISTIC.field());
}
@Override
+ @CheckForNull
public String debtSubCharacteristicKey() {
return (String) getNullableField(RuleNormalizer.RuleField.SUB_CHARACTERISTIC.field());
}
@Override
+ @CheckForNull
public DebtRemediationFunction debtRemediationFunction() {
final String function = getNullableField(RuleNormalizer.RuleField.DEBT_FUNCTION_TYPE.field());
if (function == null || function.isEmpty()) {
}
@Override
+ @CheckForNull
public String markdownNote() {
return getNullableField(RuleNormalizer.RuleField.NOTE.field());
}
@Override
+ @CheckForNull
public String noteLogin() {
return (String) getNullableField(RuleNormalizer.RuleField.NOTE_LOGIN.field());
}
@Override
+ @CheckForNull
public Date noteCreatedAt() {
return IndexUtils.parseDateTime((String) getNullableField(RuleNormalizer.RuleField.NOTE_CREATED_AT.field()));
}
@Override
+ @CheckForNull
public Date noteUpdatedAt() {
return IndexUtils.parseDateTime((String) getNullableField(RuleNormalizer.RuleField.NOTE_UPDATED_AT.field()));
}
return IndexUtils.parseDateTime((String) getNullableField(RuleNormalizer.RuleField.UPDATED_AT.field()));
}
+ @Override
+ public boolean isManual() {
+ return getField(RuleNormalizer.RuleField.REPOSITORY.field()).equals(MANUAL_REPOSITORY);
+ }
+
@Override
public String toString() {
return ReflectionToStringBuilder.toString(this);
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.rule.NewRule;
import org.sonar.server.rule.Rule;
import org.sonar.server.rule.RuleService;
*/
public class CreateAction implements RequestHandler {
- public static final String PARAM_KEY = "key";
+ public static final String PARAM_CUSTOM_KEY = "custom_key";
+ public static final String PARAM_MANUAL_KEY = "manual_key";
public static final String PARAM_NAME = "name";
public static final String PARAM_DESCRIPTION = "html_description";
public static final String PARAM_SEVERITY = "severity";
.setHandler(this);
action
- .createParam(PARAM_KEY)
- .setDescription("Key of the rule")
+ .createParam(PARAM_CUSTOM_KEY)
+ .setDescription("Key of the custom rule")
.setExampleValue("Todo_should_not_be_used");
+ action
+ .createParam(PARAM_MANUAL_KEY)
+ .setDescription("Key of the manual rule")
+ .setExampleValue("Error_handling");
+
action
.createParam(PARAM_TEMPLATE_KEY)
- .setDescription("Key of the template rule in order to create a custom rule")
+ .setDescription("Key of the template rule in order to create a custom rule (mandatory for custom rule)")
.setExampleValue("java:XPath");
action
action
.createParam(PARAM_SEVERITY)
- .setDescription("Rule severity")
- .setRequired(true)
+ .setDescription("Rule severity (Only for custom rule)")
.setPossibleValues(Severity.ALL);
action
.createParam(PARAM_STATUS)
- .setDescription("Rule status")
- .setRequired(true)
+ .setDescription("Rule status (Only for custom rule)")
.setDefaultValue(RuleStatus.READY)
.setPossibleValues(RuleStatus.values());
action.createParam(PARAMS)
- .setDescription("Parameters as semi-colon list of <key>=<value>, for example 'params=key1=v1;key2=v2'");
+ .setDescription("Parameters as semi-colon list of <key>=<value>, for example 'params=key1=v1;key2=v2' (Only for custom rule)");
}
@Override
public void handle(Request request, Response response) {
- String templateRuleKey = request.param(PARAM_TEMPLATE_KEY);
- NewRule newRule = new NewRule()
- .setRuleKey(request.mandatoryParam(PARAM_KEY))
- .setTemplateKey(templateRuleKey != null ? RuleKey.parse(templateRuleKey) : null)
- .setName(request.mandatoryParam(PARAM_NAME))
- .setHtmlDescription(request.mandatoryParam(PARAM_DESCRIPTION))
- .setSeverity(request.mandatoryParam(PARAM_SEVERITY))
- .setStatus(RuleStatus.valueOf(request.mandatoryParam(PARAM_STATUS)));
- String params = request.param(PARAMS);
- if (!Strings.isNullOrEmpty(params)) {
- newRule.setParameters(KeyValueFormat.parse(params));
+ String customKey = request.param(PARAM_CUSTOM_KEY);
+ String manualKey = request.param(PARAM_MANUAL_KEY);
+ if (Strings.isNullOrEmpty(customKey) && Strings.isNullOrEmpty(manualKey)) {
+ throw new BadRequestException(String.format("Either '%s' or '%s' parameters should be set", PARAM_CUSTOM_KEY, PARAM_MANUAL_KEY));
+ }
+
+ if (!Strings.isNullOrEmpty(customKey)) {
+ NewRule newRule = NewRule.createForCustomRule(customKey, RuleKey.parse(request.mandatoryParam(PARAM_TEMPLATE_KEY)))
+ .setName(request.mandatoryParam(PARAM_NAME))
+ .setHtmlDescription(request.mandatoryParam(PARAM_DESCRIPTION))
+ .setSeverity(request.mandatoryParam(PARAM_SEVERITY))
+ .setStatus(RuleStatus.valueOf(request.mandatoryParam(PARAM_STATUS)));
+ String params = request.param(PARAMS);
+ if (!Strings.isNullOrEmpty(params)) {
+ newRule.setParameters(KeyValueFormat.parse(params));
+ }
+ writeResponse(response, service.create(newRule));
+ }
+
+ if (!Strings.isNullOrEmpty(manualKey)) {
+ NewRule newRule = NewRule.createForManualRule(manualKey)
+ .setName(request.mandatoryParam(PARAM_NAME))
+ .setHtmlDescription(request.mandatoryParam(PARAM_DESCRIPTION))
+ .setSeverity(request.param(PARAM_SEVERITY));
+ writeResponse(response, service.create(newRule));
}
- writeResponse(response, service.create(newRule));
}
private void writeResponse(Response response, RuleKey ruleKey) {
}
if (rule.templateKey() != null) {
return RuleUpdate.createForCustomRule(key);
+ } else if (rule.isManual()) {
+ return RuleUpdate.createForManualRule(key);
} else {
- return RuleUpdate.createForRule(key);
+ return RuleUpdate.createForPluginRule(key);
}
}
Rule templateRule = index.getByKey(RuleKey.of("xoo", "template1"));
// Create custom rule
- RuleKey customRuleKey = tester.get(RuleCreator.class).create(new NewRule()
- .setRuleKey("CUSTOM_RULE")
- .setTemplateKey(templateRule.key())
+ RuleKey customRuleKey = tester.get(RuleCreator.class).create(NewRule.createForCustomRule("CUSTOM_RULE", templateRule.key())
.setName("My custom")
.setHtmlDescription("Some description")
.setSeverity(Severity.MAJOR)
Rule templateRule = index.getByKey(RuleKey.of("xoo", "template1"));
// Create custom rule
- RuleKey customRuleKey = tester.get(RuleCreator.class).create(new NewRule()
- .setRuleKey("CUSTOM_RULE")
- .setTemplateKey(templateRule.key())
+ RuleKey customRuleKey = tester.get(RuleCreator.class).create(NewRule.createForCustomRule("CUSTOM_RULE", templateRule.key())
.setName("My custom")
.setHtmlDescription("Some description")
.setSeverity(Severity.MAJOR)
Rule templateRule = index.getByKey(RuleKey.of("xoo", "template1"));
// Create custom rule
- RuleKey customRuleKey = tester.get(RuleCreator.class).create(new NewRule()
- .setRuleKey("CUSTOM_RULE")
- .setTemplateKey(templateRule.key())
+ RuleKey customRuleKey = tester.get(RuleCreator.class).create(NewRule.createForCustomRule("CUSTOM_RULE", templateRule.key())
.setName("My custom")
.setHtmlDescription("Some description")
.setSeverity(Severity.MAJOR)
import org.sonar.core.rule.RuleParamDto;
import org.sonar.server.db.DbClient;
import org.sonar.server.rule.db.RuleDao;
+import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.tester.ServerTester;
import java.util.List;
DbClient db = tester.get(DbClient.class);
RuleDao dao = tester.get(RuleDao.class);
RuleCreator creator = tester.get(RuleCreator.class);
+ RuleIndex ruleIndex = tester.get(RuleIndex.class);
@Before
public void before() {
RuleDto templateRule = createTemplateRule();
// Create custom rule
- NewRule newRule = new NewRule()
- .setRuleKey("CUSTOM_RULE")
- .setTemplateKey(templateRule.getKey())
+ NewRule newRule = NewRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey())
.setName("My custom")
.setHtmlDescription("Some description")
.setSeverity(Severity.MAJOR)
// insert template rule
RuleDto templateRule = createTemplateRule();
- NewRule newRule = new NewRule()
- .setRuleKey("CUSTOM_RULE")
- .setTemplateKey(templateRule.getKey())
+ NewRule newRule = NewRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey())
.setName("My custom")
.setHtmlDescription("Some description")
.setSeverity(Severity.MAJOR)
// insert template rule
RuleDto templateRule = createTemplateRule();
- NewRule newRule = new NewRule()
- .setName("My custom")
- .setTemplateKey(templateRule.getKey())
- .setHtmlDescription("Some description")
- .setSeverity(Severity.MAJOR)
- .setStatus(RuleStatus.READY)
- .setParameters(ImmutableMap.of("regex", "a.*"));
-
try {
- creator.create(newRule);
+ NewRule newRule = NewRule.createForCustomRule("", templateRule.getKey())
+ .setName("My custom")
+ .setHtmlDescription("Some description")
+ .setSeverity(Severity.MAJOR)
+ .setStatus(RuleStatus.READY)
+ .setParameters(ImmutableMap.of("regex", "a.*"));
fail();
} catch (Exception e) {
- assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("The rule key is missing");
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Custom key should be set");
}
}
// insert template rule
RuleDto templateRule = createTemplateRule();
- NewRule newRule = new NewRule()
- .setRuleKey("*INVALID*")
+ NewRule newRule = NewRule.createForCustomRule("*INVALID*", templateRule.getKey())
.setName("My custom")
- .setTemplateKey(templateRule.getKey())
.setHtmlDescription("Some description")
.setSeverity(Severity.MAJOR)
.setStatus(RuleStatus.READY)
RuleDto templateRule = createTemplateRule();
// Create a custom rule
- NewRule newRule = new NewRule()
- .setRuleKey("CUSTOM_RULE")
+ NewRule newRule = NewRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey())
.setName("My custom")
- .setTemplateKey(templateRule.getKey())
.setHtmlDescription("Some description")
.setSeverity(Severity.MAJOR)
.setStatus(RuleStatus.READY)
try {
// Create another custom rule having same key
- newRule = new NewRule()
- .setRuleKey("CUSTOM_RULE")
+ newRule = NewRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey())
.setName("My another custom")
- .setTemplateKey(templateRule.getKey())
.setHtmlDescription("Some description")
.setSeverity(Severity.MAJOR)
.setStatus(RuleStatus.READY)
// insert template rule
RuleDto templateRule = createTemplateRule();
- NewRule newRule = new NewRule()
- .setRuleKey("CUSTOM_RULE")
- .setTemplateKey(templateRule.getKey())
+ NewRule newRule = NewRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey())
.setHtmlDescription("Some description")
.setSeverity(Severity.MAJOR)
.setStatus(RuleStatus.READY)
// insert template rule
RuleDto templateRule = createTemplateRule();
- NewRule newRule = new NewRule()
- .setRuleKey("CUSTOM_RULE")
- .setTemplateKey(templateRule.getKey())
+ NewRule newRule = NewRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey())
.setName("My custom")
.setSeverity(Severity.MAJOR)
.setStatus(RuleStatus.READY)
// insert template rule
RuleDto templateRule = createTemplateRule();
- NewRule newRule = new NewRule()
- .setRuleKey("CUSTOM_RULE")
- .setTemplateKey(templateRule.getKey())
+ NewRule newRule = NewRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey())
.setName("My custom")
.setHtmlDescription("Some description")
.setStatus(RuleStatus.READY)
// insert template rule
RuleDto templateRule = createTemplateRule();
- NewRule newRule = new NewRule()
- .setRuleKey("CUSTOM_RULE")
- .setTemplateKey(templateRule.getKey())
+ NewRule newRule = NewRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey())
.setName("My custom")
.setHtmlDescription("Some description")
.setSeverity("INVALID")
// insert template rule
RuleDto templateRule = createTemplateRule();
- NewRule newRule = new NewRule()
- .setRuleKey("CUSTOM_RULE")
- .setTemplateKey(templateRule.getKey())
+ NewRule newRule = NewRule.createForCustomRule("CUSTOM_RULE", templateRule.getKey())
.setName("My custom")
.setHtmlDescription("Some description")
.setSeverity(Severity.MAJOR)
dbSession.commit();
// Create custom rule with unknown template rule
- NewRule newRule = new NewRule()
- .setRuleKey("CUSTOM_RULE")
- .setTemplateKey(rule.getKey())
+ NewRule newRule = NewRule.createForCustomRule("CUSTOM_RULE", rule.getKey())
.setName("My custom")
.setHtmlDescription("Some description")
.setSeverity(Severity.MAJOR)
}
}
+ @Test
+ public void create_manual_rule() throws Exception {
+ NewRule newRule = NewRule.createForManualRule("MANUAL_RULE")
+ .setName("My manual")
+ .setHtmlDescription("Some description");
+ RuleKey ruleKey = creator.create(newRule);
+
+ dbSession.clearCache();
+
+ Rule rule = ruleIndex.getByKey(ruleKey);
+ assertThat(rule).isNotNull();
+ assertThat(rule.key()).isEqualTo(RuleKey.of("manual", "MANUAL_RULE"));
+ assertThat(rule.name()).isEqualTo("My manual");
+ assertThat(rule.htmlDescription()).isEqualTo("Some description");
+ assertThat(rule.severity()).isNull();
+ assertThat(rule.status()).isEqualTo(RuleStatus.READY);
+ assertThat(rule.language()).isNull();
+ assertThat(rule.internalKey()).isNull();
+ assertThat(rule.debtSubCharacteristicKey()).isNull();
+ assertThat(rule.debtRemediationFunction()).isNull();
+ assertThat(rule.tags()).isEmpty();
+ assertThat(rule.systemTags()).isEmpty();
+ assertThat(rule.params()).isEmpty();
+ }
+
+ @Test
+ public void create_manual_rule_with_severity() throws Exception {
+ NewRule newRule = NewRule.createForManualRule("MANUAL_RULE")
+ .setName("My manual")
+ .setHtmlDescription("Some description")
+ .setSeverity(Severity.BLOCKER);
+ RuleKey ruleKey = creator.create(newRule);
+
+ dbSession.clearCache();
+
+ Rule rule = ruleIndex.getByKey(ruleKey);
+ assertThat(rule).isNotNull();
+ assertThat(rule.key()).isEqualTo(RuleKey.of("manual", "MANUAL_RULE"));
+ assertThat(rule.name()).isEqualTo("My manual");
+ assertThat(rule.htmlDescription()).isEqualTo("Some description");
+ assertThat(rule.severity()).isEqualTo(Severity.BLOCKER);
+ assertThat(rule.status()).isEqualTo(RuleStatus.READY);
+ assertThat(rule.language()).isNull();
+ assertThat(rule.internalKey()).isNull();
+ assertThat(rule.debtSubCharacteristicKey()).isNull();
+ assertThat(rule.debtRemediationFunction()).isNull();
+ assertThat(rule.tags()).isEmpty();
+ assertThat(rule.systemTags()).isEmpty();
+ assertThat(rule.params()).isEmpty();
+ }
+
+ @Test
+ public void fail_to_create_manual_rule_when_missing_key() throws Exception {
+ try {
+ NewRule.createForManualRule("")
+ .setName("My manual")
+ .setHtmlDescription("Some description");
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("Manual key should be set");
+ }
+ }
+
+ @Test
+ public void fail_to_create_manual_rule_when_invalid_key() throws Exception {
+ NewRule newRule = NewRule.createForManualRule("*INVALID*")
+ .setName("My custom")
+ .setHtmlDescription("Some description");
+
+ try {
+ creator.create(newRule);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("The rule key '*INVALID*' is invalid, it should only contains : a-z, 0-9, '_'");
+ }
+ }
+
+ @Test
+ public void fail_to_create_manual_rule_when_rule_key_already_exits() throws Exception {
+ NewRule newRule = NewRule.createForManualRule("MANUAL_RULE")
+ .setName("My manual")
+ .setHtmlDescription("Some description");
+ creator.create(newRule);
+
+ try {
+ // Create another rule having same key
+ newRule = NewRule.createForManualRule("MANUAL_RULE")
+ .setName("My other manual")
+ .setHtmlDescription("Some description");
+ creator.create(newRule);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("A rule with the key 'MANUAL_RULE' already exits");
+ }
+ }
+
+ @Test
+ public void fail_to_create_manual_rule_when_missing_name() throws Exception {
+ NewRule newRule = NewRule.createForManualRule("MANUAL_RULE")
+ .setHtmlDescription("Some description");
+
+ try {
+ creator.create(newRule);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("The name is missing");
+ }
+ }
+
+ @Test
+ public void fail_to_create_manual_rule_when_missing_description() throws Exception {
+ NewRule newRule = NewRule.createForManualRule("MANUAL_RULE")
+ .setName("My manual");
+
+ try {
+ creator.create(newRule);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("The description is missing");
+ }
+ }
+
+ @Test
+ public void fail_to_create_manual_rule_with_status() throws Exception {
+ try {
+ NewRule.createForManualRule("MANUAL_RULE")
+ .setName("My manual")
+ .setHtmlDescription("Some description")
+ .setStatus(RuleStatus.BETA);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("Not a custom rule");
+ }
+ }
+
+ @Test
+ public void fail_to_create_manual_rule_with_parameters() throws Exception {
+ try {
+ NewRule.createForManualRule("MANUAL_RULE")
+ .setName("My manual")
+ .setHtmlDescription("Some description")
+ .setParameters(ImmutableMap.of("regex", "a.*"));
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("Not a custom rule");
+ }
+ }
+
private RuleDto createTemplateRule() {
RuleDto templateRule = dao.insert(dbSession,
RuleTesting.newDto(RuleKey.of("java", "S001"))
dao.insert(dbSession, RuleTesting.newDto(key));
dbSession.commit();
- RuleUpdate update = new RuleUpdate(key);
+ RuleUpdate update = RuleUpdate.createForCustomRule(key);
update.setMarkdownNote("my *note*");
service.update(update);
.setSystemTags(Sets.newHashSet("java8", "javadoc")));
dbSession.commit();
- RuleUpdate update = new RuleUpdate(key).setMarkdownNote("my *note*");
+ RuleUpdate update = RuleUpdate.createForPluginRule(key).setMarkdownNote("my *note*");
service.update(update);
}
@Test
- public void create_custom_rule() throws Exception {
+ public void create_rule() throws Exception {
MockUserSession.set()
.setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN)
.setLogin("me");
dbSession.commit();
// Create custom rule
- NewRule newRule = new NewRule()
- .setRuleKey("MY_CUSTOM")
- .setTemplateKey(templateRuleKey)
+ NewRule newRule = NewRule.createForCustomRule("MY_CUSTOM", templateRuleKey)
.setName("My custom")
.setHtmlDescription("Some description")
.setSeverity(Severity.MAJOR)
public void do_not_create_if_not_granted() throws Exception {
MockUserSession.set().setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
- service.create(new NewRule());
+ service.create(NewRule.createForCustomRule("MY_CUSTOM", RuleKey.of("java", "S001")));
}
@Test
- public void delete_custom_rule() throws Exception {
+ public void delete_rule() throws Exception {
MockUserSession.set()
.setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN)
.setLogin("me");
dbSession.commit();
// Create custom rule
- NewRule newRule = new NewRule()
- .setRuleKey("MY_CUSTOM")
- .setTemplateKey(templateRuleKey)
+ NewRule newRule = NewRule.createForCustomRule("MY_CUSTOM", templateRuleKey)
.setName("My custom")
.setHtmlDescription("Some description")
.setSeverity(Severity.MAJOR)
.setTemplateId(templateRule.getId());
}
+ public static RuleDto newManualRule(String manualKey){
+ return new RuleDto().setRuleKey(manualKey)
+ .setRepositoryKey("manual")
+ .setDescription("Description " + manualKey)
+ .setStatus(RuleStatus.READY);
+ }
+
}
ruleDao.insert(dbSession, RuleTesting.newDto(RULE_KEY).setStatus(RuleStatus.REMOVED));
dbSession.commit();
- RuleUpdate update = new RuleUpdate(RULE_KEY).setTags(Sets.newHashSet("java9"));
+ RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY).setTags(Sets.newHashSet("java9"));
try {
updater.update(update, UserSession.get());
fail();
.setRemediationOffset("5min"));
dbSession.commit();
- RuleUpdate update = new RuleUpdate(RULE_KEY);
+ RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY);
assertThat(update.isEmpty()).isTrue();
updater.update(update, UserSession.get());
.setRemediationOffset("5min"));
dbSession.commit();
- RuleUpdate update = new RuleUpdate(RULE_KEY);
+ RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY);
update.setMarkdownNote("my *note*");
updater.update(update, UserSession.get());
.setNoteUserLogin("me"));
dbSession.commit();
- RuleUpdate update = new RuleUpdate(RULE_KEY).setMarkdownNote(null);
+ RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY).setMarkdownNote(null);
updater.update(update, UserSession.get());
dbSession.clearCache();
dbSession.commit();
// java8 is a system tag -> ignore
- RuleUpdate update = new RuleUpdate(RULE_KEY).setTags(Sets.newHashSet("bug", "java8"));
+ RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY).setTags(Sets.newHashSet("bug", "java8"));
updater.update(update, UserSession.get());
dbSession.clearCache();
.setSystemTags(Sets.newHashSet("java8", "javadoc")));
dbSession.commit();
- RuleUpdate update = new RuleUpdate(RULE_KEY).setTags(null);
+ RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY).setTags(null);
updater.update(update, UserSession.get());
dbSession.clearCache();
dbSession.commit();
DefaultDebtRemediationFunction fn = new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.CONSTANT_ISSUE, null, "1min");
- RuleUpdate update = new RuleUpdate(RULE_KEY)
+ RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY)
.setDebtSubCharacteristic("SOFT_RELIABILITY")
.setDebtRemediationFunction(fn);
updater.update(update, UserSession.get());
.setRemediationOffset("1min"));
dbSession.commit();
- RuleUpdate update = new RuleUpdate(RULE_KEY)
+ RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY)
.setDebtSubCharacteristic(RuleUpdate.DEFAULT_DEBT_CHARACTERISTIC);
updater.update(update, UserSession.get());
.setRemediationOffset("1min"));
dbSession.commit();
- RuleUpdate update = new RuleUpdate(RULE_KEY)
+ RuleUpdate update = RuleUpdate.createForPluginRule(RULE_KEY)
.setDebtSubCharacteristic(null);
updater.update(update, UserSession.get());
assertThat(activeRule.severity()).isEqualTo(Severity.BLOCKER);
}
+ @Test
+ public void update_manual_rule() throws Exception {
+ // Create manual rule
+ RuleDto manualRule = RuleTesting.newManualRule("My manual")
+ .setName("Old name")
+ .setDescription("Old description")
+ .setSeverity(Severity.INFO);
+ ruleDao.insert(dbSession, manualRule);
+
+ dbSession.commit();
+
+ // Update manual rule
+ RuleUpdate update = RuleUpdate.createForManualRule(manualRule.getKey())
+ .setName("New name")
+ .setHtmlDescription("New description")
+ .setSeverity(Severity.CRITICAL);
+ updater.update(update, UserSession.get());
+
+ dbSession.clearCache();
+
+ // Verify manual rule is updated
+ Rule manualRuleReloaded = ruleIndex.getByKey(manualRule.getKey());
+ assertThat(manualRuleReloaded).isNotNull();
+ assertThat(manualRuleReloaded.name()).isEqualTo("New name");
+ assertThat(manualRuleReloaded.htmlDescription()).isEqualTo("New description");
+ assertThat(manualRuleReloaded.severity()).isEqualTo(Severity.CRITICAL);
+ }
+
+ @Test
+ public void fail_to_update_manual_rule_if_status_is_set() throws Exception {
+ // Create manual rule
+ RuleDto manualRule = RuleTesting.newManualRule("My manual");
+ ruleDao.insert(dbSession, manualRule);
+
+ dbSession.commit();
+
+ try {
+ // Update manual rule
+ RuleUpdate.createForManualRule(manualRule.getKey())
+ .setStatus(RuleStatus.BETA);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("Not a custom rule");
+ }
+ }
+
+ @Test
+ public void fail_to_update_manual_rule_if_parameters_are_set() throws Exception {
+ // Create manual rule
+ RuleDto manualRule = RuleTesting.newManualRule("My manual");
+ ruleDao.insert(dbSession, manualRule);
+
+ dbSession.commit();
+
+ try {
+ // Update manual rule
+ RuleUpdate.createForManualRule(manualRule.getKey())
+ .setStatus(RuleStatus.BETA)
+ .setParameters(ImmutableMap.of("regex", "b.*", "message", "a message"));
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("Not a custom rule");
+ }
+ }
+
+ @Test
+ public void fail_to_update_plugin_rule_if_name_is_set() throws Exception {
+ // Create rule rule
+ RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("squid", "S01"));
+ ruleDao.insert(dbSession, ruleDto);
+
+ dbSession.commit();
+
+ try {
+ // Update rule
+ RuleUpdate.createForPluginRule(ruleDto.getKey())
+ .setName("New name");
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("Not a custom or a manual rule");
+ }
+ }
+
+ @Test
+ public void fail_to_update_plugin_rule_if_description_is_set() throws Exception {
+ // Create rule rule
+ RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("squid", "S01"));
+ ruleDao.insert(dbSession, ruleDto);
+
+ dbSession.commit();
+
+ try {
+ // Update rule
+ RuleUpdate.createForPluginRule(ruleDto.getKey())
+ .setHtmlDescription("New description");
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("Not a custom or a manual rule");
+ }
+ }
+
+ @Test
+ public void fail_to_update_plugin_rule_if_severity_is_set() throws Exception {
+ // Create rule rule
+ RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("squid", "S01"));
+ ruleDao.insert(dbSession, ruleDto);
+
+ dbSession.commit();
+
+ try {
+ // Update rule
+ RuleUpdate.createForPluginRule(ruleDto.getKey())
+ .setSeverity(Severity.CRITICAL);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(IllegalStateException.class).hasMessage("Not a custom or a manual rule");
+ }
+ }
+
private void insertDebtCharacteristics(DbSession dbSession) {
CharacteristicDto reliability = DebtTesting.newCharacteristicDto("RELIABILITY");
db.debtCharacteristicDao().insert(reliability, dbSession);
import org.sonar.core.rule.RuleDto;
import org.sonar.core.rule.RuleParamDto;
import org.sonar.server.db.DbClient;
+import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.rule.RuleService;
import org.sonar.server.rule.RuleTesting;
import org.sonar.server.rule.db.RuleDao;
import org.sonar.server.user.MockUserSession;
import org.sonar.server.ws.WsTester;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
+
@RunWith(MockitoJUnitRunner.class)
public class CreateActionMediumTest {
session.commit();
WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "create")
- .setParam("key", "MY_CUSTOM")
+ .setParam("custom_key", "MY_CUSTOM")
.setParam("template_key", templateRule.getKey().toString())
.setParam("name", "My custom rule")
.setParam("html_description", "Description")
request.execute().assertJson(getClass(), "create_custom_rule.json", false);
}
+ @Test
+ public void create_manual_rule() throws Exception {
+ MockUserSession.set()
+ .setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN)
+ .setLogin("me");
+
+ WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "create")
+ .setParam("manual_key", "MY_MANUAL")
+ .setParam("name", "My manual rule")
+ .setParam("html_description", "Description")
+ .setParam("severity", "MAJOR");
+ request.execute().assertJson(getClass(), "create_manual_rule.json", false);
+ }
+
+ @Test
+ public void create_manual_rule_without_severity() throws Exception {
+ MockUserSession.set()
+ .setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN)
+ .setLogin("me");
+
+ WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "create")
+ .setParam("manual_key", "MY_MANUAL")
+ .setParam("name", "My manual rule")
+ .setParam("html_description", "Description");
+ request.execute().assertJson(getClass(), "create_manual_rule_without_severity.json", false);
+ }
+
+ @Test
+ public void fail_if_custom_key_and_manual_key_parameters_are_not_set() throws Exception {
+ MockUserSession.set()
+ .setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN)
+ .setLogin("me");
+
+ WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "create")
+ .setParam("key", "MY_MANUAL")
+ .setParam("name", "My manual rule")
+ .setParam("html_description", "Description")
+ .setParam("severity", "MAJOR");
+
+ try {
+ request.execute();
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(BadRequestException.class).hasMessage("Either 'custom_key' or 'manual_key' parameters should be set");
+ }
+ }
+
}
session.commit();
// Custom rule
- NewRule newRule = new NewRule()
- .setRuleKey("MY_CUSTOM")
- .setTemplateKey(templateRule.getKey())
+ NewRule newRule = NewRule.createForCustomRule("MY_CUSTOM", templateRule.getKey())
.setName("Old custom")
.setHtmlDescription("Old description")
.setSeverity(Severity.MINOR)
--- /dev/null
+{
+ "rule": {
+ "key": "manual:MY_MANUAL",
+ "repo": "manual",
+ "name": "My manual rule",
+ "htmlDesc": "Description",
+ "severity": "MAJOR",
+ "status": "READY",
+ "isTemplate": false,
+ "tags": [],
+ "sysTags": [],
+ "params": []
+ }
+}
--- /dev/null
+{
+ "rule": {
+ "key": "manual:MY_MANUAL",
+ "repo": "manual",
+ "name": "My manual rule",
+ "htmlDesc": "Description",
+ "status": "READY",
+ "isTemplate": false,
+ "tags": [],
+ "sysTags": [],
+ "params": []
+ }
+}