]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5007 continue to refactor rule services
authorSimon Brandhof <simon.brandhof@gmail.com>
Wed, 14 May 2014 14:26:30 +0000 (16:26 +0200)
committerSimon Brandhof <simon.brandhof@gmail.com>
Wed, 14 May 2014 14:26:30 +0000 (16:26 +0200)
19 files changed:
sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleKey.java
sonar-plugin-api/src/test/java/org/sonar/api/rule/RuleKeyTest.java
sonar-server/src/main/java/org/sonar/server/db/BaseDao.java
sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
sonar-server/src/main/java/org/sonar/server/qualityprofile/persistence/ActiveRuleDao.java
sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BulkRuleActivationActions.java [new file with mode: 0644]
sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfilesWs.java
sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RuleActivationActions.java
sonar-server/src/main/java/org/sonar/server/rule2/RegisterRules.java
sonar-server/src/main/java/org/sonar/server/rule2/RuleService.java
sonar-server/src/main/java/org/sonar/server/rule2/persistence/RuleDao.java
sonar-server/src/main/java/org/sonar/server/rule2/ws/SearchAction.java
sonar-server/src/main/java/org/sonar/server/rule2/ws/SetTagsAction.java
sonar-server/src/main/java/org/sonar/server/rule2/ws/ShowAction.java
sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileRecreateBuiltInActionTest.java
sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java
sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java [deleted file]
sonar-server/src/test/java/org/sonar/server/rule2/RegisterRulesTest.java
sonar-server/src/test/java/org/sonar/server/tester/ServerTester.java

index 73a41ce1f0680fbb694f1f8beccbfaa71a9618fa..32ad3329656f9c9191d1d90abe625b265caa9879 100644 (file)
@@ -52,7 +52,7 @@ public class RuleKey implements Serializable {
    */
   public static RuleKey parse(String s) {
     String[] split = s.split(":");
-    Preconditions.checkArgument(split.length == 2, "Bad format of rule key: " + s);
+    Preconditions.checkArgument(split.length == 2, "Invalid rule key: " + s);
     return RuleKey.of(split[0], split[1]);
   }
 
index d2cd2328893326f2a56b042781978a7486004ab8..150ed5efac96928c88ce1bbed6fb37afb29a3f4d 100644 (file)
@@ -89,7 +89,7 @@ public class RuleKeyTest {
       RuleKey.parse("foo");
       fail();
     } catch (IllegalArgumentException e) {
-      assertThat(e).hasMessage("Bad format of rule key: foo");
+      assertThat(e).hasMessage("Invalid rule key: foo");
     }
   }
 
index 741bdf7db7424c64125fe41acb51c45b80f4c692..ba83f6fc1bee41fc4d8c4fdbe13d3db9dea0df11 100644 (file)
@@ -110,10 +110,6 @@ public abstract class BaseDao<M, E extends Dto<K>, K extends Serializable> imple
   private Class<M> mapperClass;
   private System2 system2;
 
-  protected BaseDao(IndexDefinition indexDefinition, Class<M> mapperClass) {
-    this(indexDefinition, mapperClass, System2.INSTANCE);
-  }
-
   protected BaseDao(IndexDefinition indexDefinition, Class<M> mapperClass, System2 system2) {
     this.mapperClass = mapperClass;
     this.indexDefinition = indexDefinition;
index 50341dc206a4e1f566b68efd4883a276149d7a3b..4d6d34a8e76d46fb9b96e937a66efa66f31f0c8b 100644 (file)
@@ -120,6 +120,7 @@ import org.sonar.server.qualityprofile.RegisterQualityProfiles;
 import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
 import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer;
 import org.sonar.server.qualityprofile.persistence.ActiveRuleDao;
+import org.sonar.server.qualityprofile.ws.BulkRuleActivationActions;
 import org.sonar.server.qualityprofile.ws.ProfilesWs;
 import org.sonar.server.qualityprofile.ws.QProfileRecreateBuiltInAction;
 import org.sonar.server.qualityprofile.ws.QProfilesWs;
@@ -309,6 +310,7 @@ class ServerComponents {
     pico.addSingleton(QProfilesWs.class);
     pico.addSingleton(ProfilesWs.class);
     pico.addSingleton(RuleActivationActions.class);
+    pico.addSingleton(BulkRuleActivationActions.class);
     pico.addSingleton(ActiveRuleService.class);
     pico.addSingleton(RuleActivationContextFactory.class);
 
index 449387e73c771c34928ebd2468f490976a7c4b3a..034b73985953f16d45677013b8982ea8780f4b0b 100644 (file)
@@ -45,13 +45,11 @@ public class ActiveRuleDao extends BaseDao<ActiveRuleMapper, ActiveRuleDto, Acti
   private final QualityProfileDao profileDao;
 
   public ActiveRuleDao(QualityProfileDao profileDao, RuleDao ruleDao) {
-    super(new ActiveRuleIndexDefinition(), ActiveRuleMapper.class);
-    this.ruleDao = ruleDao;
-    this.profileDao = profileDao;
+    this(profileDao, ruleDao, System2.INSTANCE);
   }
 
   @VisibleForTesting
-  ActiveRuleDao(QualityProfileDao profileDao, RuleDao ruleDao, System2 system) {
+  public ActiveRuleDao(QualityProfileDao profileDao, RuleDao ruleDao, System2 system) {
     super(new ActiveRuleIndexDefinition(), ActiveRuleMapper.class, system);
     this.ruleDao = ruleDao;
     this.profileDao = profileDao;
@@ -78,7 +76,7 @@ public class ActiveRuleDao extends BaseDao<ActiveRuleMapper, ActiveRuleDto, Acti
     QualityProfileDto qDto = profileDao.selectByNameAndLanguage(key.qProfile().name(), key.qProfile().lang(), session);
     RuleDto ruleDto = ruleDao.getByKey(key.ruleKey(), session);
     ActiveRuleDto activeRule = mapper(session).selectByProfileAndRule(qDto.getId(), ruleDto.getId());
-    if(activeRule.getKey() == null){
+    if (activeRule.getKey() == null) {
       activeRule.setKey(key);
     }
     return activeRule;
@@ -104,7 +102,7 @@ public class ActiveRuleDao extends BaseDao<ActiveRuleMapper, ActiveRuleDto, Acti
 
   @Override
   protected void doDeleteByKey(ActiveRuleKey key, DbSession session) {
-    ActiveRuleDto rule = this.getByKey(key,session);
+    ActiveRuleDto rule = this.getByKey(key, session);
     mapper(session).delete(rule.getId());
   }
 
@@ -113,7 +111,7 @@ public class ActiveRuleDao extends BaseDao<ActiveRuleMapper, ActiveRuleDto, Acti
    */
 
   public List<ActiveRuleDto> findByRule(RuleDto rule, DbSession dbSession) {
-    Preconditions.checkArgument(rule.getId()!=null, "Rule is not persisted");
+    Preconditions.checkArgument(rule.getId() != null, "Rule is not persisted");
     return mapper(dbSession).selectByRuleId(rule.getId());
   }
 
@@ -133,31 +131,31 @@ public class ActiveRuleDao extends BaseDao<ActiveRuleMapper, ActiveRuleDto, Acti
   }
 
   public void removeAllParam(ActiveRuleDto activeRule, DbSession session) {
-    Preconditions.checkArgument(activeRule.getId()!=null, "ActiveRule is not persisted");
+    Preconditions.checkArgument(activeRule.getId() != null, "ActiveRule is not persisted");
     //TODO Optimize this
-    for(ActiveRuleParamDto activeRuleParam:this.findParamsByActiveRule(activeRule,session)){
+    for (ActiveRuleParamDto activeRuleParam : this.findParamsByActiveRule(activeRule, session)) {
       this.enqueueDelete(activeRuleParam, activeRule.getKey(), session);
     }
     mapper(session).deleteParameters(activeRule.getId());
   }
 
   public void removeParam(ActiveRuleDto activeRule, ActiveRuleParamDto activeRuleParam, DbSession session) {
-    Preconditions.checkArgument(activeRule.getId()!=null, "ActiveRule is not persisted");
-    Preconditions.checkArgument(activeRuleParam.getId()!=null, "ActiveRuleParam is not persisted");
+    Preconditions.checkArgument(activeRule.getId() != null, "ActiveRule is not persisted");
+    Preconditions.checkArgument(activeRuleParam.getId() != null, "ActiveRuleParam is not persisted");
     mapper(session).deleteParameter(activeRuleParam.getId());
     this.enqueueDelete(activeRuleParam, activeRule.getKey(), session);
   }
 
   public void updateParam(ActiveRuleDto activeRule, ActiveRuleParamDto activeRuleParam, DbSession session) {
-    Preconditions.checkArgument(activeRule.getId()!=null, "ActiveRule is not persisted");
-    Preconditions.checkArgument(activeRuleParam.getId()!=null, "ActiveRuleParam is not persisted");
+    Preconditions.checkArgument(activeRule.getId() != null, "ActiveRule is not persisted");
+    Preconditions.checkArgument(activeRuleParam.getId() != null, "ActiveRuleParam is not persisted");
     mapper(session).updateParameter(activeRuleParam);
     this.enqueueUpdate(activeRuleParam, activeRule.getKey(), session);
   }
 
   public ActiveRuleParamDto getParamsByActiveRuleAndKey(ActiveRuleDto activeRule, String key, DbSession session) {
-    Preconditions.checkArgument(activeRule.getId()!=null, "ActiveRule is not persisted");
-    Preconditions.checkArgument(key!=null, "Param key cannot be null");
+    Preconditions.checkArgument(activeRule.getId() != null, "ActiveRule is not persisted");
+    Preconditions.checkArgument(key != null, "Param key cannot be null");
     return mapper(session).selectParamByActiveRuleAndKey(activeRule.getId(), key);
   }
 
diff --git a/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BulkRuleActivationActions.java b/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/BulkRuleActivationActions.java
new file mode 100644 (file)
index 0000000..95abdbc
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.qualityprofile.ws;
+
+import org.sonar.api.ServerComponent;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.RequestHandler;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.server.qualityprofile.ActiveRuleService;
+import org.sonar.server.qualityprofile.BulkRuleActivation;
+import org.sonar.server.rule2.ws.SearchAction;
+
+public class BulkRuleActivationActions implements ServerComponent {
+
+  private final ActiveRuleService service;
+
+  public BulkRuleActivationActions(ActiveRuleService service) {
+    this.service = service;
+  }
+
+  void define(WebService.NewController controller) {
+    defineActivateAction(controller);
+    defineDeactivateAction(controller);
+  }
+
+  private void defineActivateAction(WebService.NewController controller) {
+    WebService.NewAction activate = controller
+      .createAction("activate_rules")
+      .setDescription("Bulk-activate rules on one or several Quality profiles")
+      .setPost(true)
+      .setSince("4.4")
+      .setHandler(new RequestHandler() {
+        @Override
+        public void handle(Request request, Response response) throws Exception {
+          bulkActivate(request, response);
+        }
+      });
+
+    SearchAction.defineSearchParameters(activate);
+    defineProfileKeyParameters(activate);
+
+    activate.createParam("activation_severity")
+      .setDescription("Severity")
+      .setPossibleValues(Severity.ALL);
+  }
+
+  private void defineDeactivateAction(WebService.NewController controller) {
+    WebService.NewAction deactivate = controller
+      .createAction("deactivate_rules")
+      .setDescription("Bulk deactivate rules on Quality profiles")
+      .setPost(true)
+      .setSince("4.4")
+      .setHandler(new RequestHandler() {
+        @Override
+        public void handle(Request request, Response response) throws Exception {
+          bulkDeactivate(request, response);
+        }
+      });
+
+    defineProfileKeyParameters(deactivate);
+  }
+
+  private void defineProfileKeyParameters(WebService.NewAction action) {
+    action.createParam("target_profile_lang")
+      .setDescription("Profile language")
+      .setRequired(true)
+      .setExampleValue("java");
+
+    action.createParam("target_profile_name")
+      .setDescription("Profile name")
+      .setRequired(true)
+      .setExampleValue("My profile");
+  }
+
+  private void bulkActivate(Request request, Response response) throws Exception {
+    BulkRuleActivation activation = new BulkRuleActivation();
+    // TODO
+    service.bulkActivate(activation);
+  }
+
+  private void bulkDeactivate(Request request, Response response) throws Exception {
+    // TODO
+  }
+}
index f15d3ef584facaa40349b4d00c92c4b96e3bb0fa..ec1e1d058b6c7c8d76de6ea3c1f211621ef4e805 100644 (file)
@@ -25,10 +25,13 @@ public class QProfilesWs implements WebService {
 
   private final QProfileRecreateBuiltInAction recreateBuiltInAction;
   private final RuleActivationActions ruleActivationActions;
+  private final BulkRuleActivationActions bulkRuleActivationActions;
 
-  public QProfilesWs(QProfileRecreateBuiltInAction recreateBuiltInAction, RuleActivationActions ruleActivationActions) {
+  public QProfilesWs(QProfileRecreateBuiltInAction recreateBuiltInAction, RuleActivationActions ruleActivationActions,
+                     BulkRuleActivationActions bulkRuleActivationActions) {
     this.recreateBuiltInAction = recreateBuiltInAction;
     this.ruleActivationActions = ruleActivationActions;
+    this.bulkRuleActivationActions = bulkRuleActivationActions;
   }
 
   @Override
@@ -39,6 +42,7 @@ public class QProfilesWs implements WebService {
 
     recreateBuiltInAction.define(controller);
     ruleActivationActions.define(controller);
+    bulkRuleActivationActions.define(controller);
 
     controller.done();
   }
index 9d80914d37e27bb90ff5cd3c322a19e260831b8f..daeebfddad183e0ec7139f734732fcebb1621471 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.server.qualityprofile.ws;
 
+import org.sonar.api.ServerComponent;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rule.Severity;
 import org.sonar.api.server.ws.Request;
@@ -31,7 +32,7 @@ import org.sonar.core.qualityprofile.db.QualityProfileKey;
 import org.sonar.server.qualityprofile.ActiveRuleService;
 import org.sonar.server.qualityprofile.RuleActivation;
 
-public class RuleActivationActions {
+public class RuleActivationActions implements ServerComponent {
 
   private final ActiveRuleService service;
 
index afe1111ceacb8c7e7f36a7c828e8888b6819d2da..9b6c1121d1967afcd7be2da5eba1ecce3227fe98 100644 (file)
@@ -29,6 +29,7 @@ import org.picocontainer.Startable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.rules.Rule;
 import org.sonar.api.server.debt.DebtRemediationFunction;
 import org.sonar.api.server.rule.RulesDefinition;
@@ -56,8 +57,6 @@ import static com.google.common.collect.Lists.newArrayList;
 
 /**
  * Register rules at server startup
- *
- * @since 4.2
  */
 public class RegisterRules implements Startable {
 
@@ -173,6 +172,7 @@ public class RegisterRules implements Startable {
       .setName(ruleDef.name())
       .setSeverity(ruleDef.severity())
       .setStatus(ruleDef.status().name())
+      .setEffortToFixDescription(ruleDef.effortToFixDescription())
       .setSystemTags(ruleDef.tags());
 
     return dbClient.ruleDao().insert(ruleDto, session);
@@ -215,6 +215,10 @@ public class RegisterRules implements Startable {
       dto.setLanguage(def.repository().language());
       changed = true;
     }
+    if (!StringUtils.equals(dto.getEffortToFixDescription(), def.effortToFixDescription())) {
+      dto.setEffortToFixDescription(def.effortToFixDescription());
+      changed = true;
+    }
     return changed;
   }
 
@@ -340,21 +344,22 @@ public class RegisterRules implements Startable {
           toBeRemoved = false;
         }
       }
-      if (toBeRemoved && !Rule.STATUS_REMOVED.equals(ruleDto.getStatus())) {
+      if (toBeRemoved && !RuleStatus.REMOVED.toString().equals(ruleDto.getStatus())) {
         LOG.info(String.format("Disable rule %s", ruleDto.getKey()));
         ruleDto.setStatus(Rule.STATUS_REMOVED);
         ruleDto.setSystemTags(Collections.EMPTY_SET);
         ruleDto.setTags(Collections.EMPTY_SET);
-      }
-
-      dbClient.ruleDao().update(ruleDto, session);
-      removedRules.add(ruleDto);
-      if (removedRules.size() % 100 == 0) {
-        session.commit();
+        dbClient.ruleDao().update(ruleDto, session);
+        removedRules.add(ruleDto);
+        if (removedRules.size() % 100 == 0) {
+          session.commit();
+        }
       }
     }
 
-    session.commit();
+    if (!removedRules.isEmpty()) {
+      session.commit();
+    }
     return removedRules;
   }
 
index fdd471e035a31c1235f481c39c06b3a5e847a5d3..9e4735c4e26bf0e6ccf3f6a75adb0abd23c4d4eb 100644 (file)
@@ -69,8 +69,7 @@ public class RuleService implements ServerComponent {
    * List all tags
    */
   public Set<String> listTags() {
-    return index.terms(RuleNormalizer.RuleField.TAGS.key(),
-      RuleNormalizer.RuleField.SYSTEM_TAGS.key());
+    return index.terms(RuleNormalizer.RuleField.TAGS.key(), RuleNormalizer.RuleField.SYSTEM_TAGS.key());
   }
 
   public void setTags(RuleKey ruleKey, Set<String> tags) {
index 0f9fea1a8c3aa44c40b6e1772278a9c85de633e5..27b809d283e0549c22f7705a967d1e05eb4235c6 100644 (file)
@@ -43,11 +43,11 @@ import java.util.Map;
 public class RuleDao extends BaseDao<RuleMapper, RuleDto, RuleKey> {
 
   public RuleDao() {
-    super(new RuleIndexDefinition(), RuleMapper.class);
+    this(System2.INSTANCE);
   }
 
   @VisibleForTesting
-  RuleDao(System2 system) {
+  public RuleDao(System2 system) {
     super(new RuleIndexDefinition(), RuleMapper.class, system);
   }
 
index 5974374eab3d9a7cca2dcc7d15e27d984e2af4c4..03e72a143485c7f27c270c4bf2d466a3368df2f2 100644 (file)
@@ -81,6 +81,40 @@ public class SearchAction implements RequestHandler {
       .setSince("4.4")
       .setHandler(this);
 
+    defineSearchParameters(action);
+
+    action
+      .createParam(PARAM_FIELDS)
+      .setDescription("Comma-separated list of the fields to be returned in response. All the fields are returned by default.")
+      .setPossibleValues(RuleIndex.PUBLIC_FIELDS)
+      .setExampleValue(String.format("%s,%s,%s", RuleNormalizer.RuleField.KEY, RuleNormalizer.RuleField.REPOSITORY, RuleNormalizer.RuleField.LANGUAGE));
+
+    action
+      .createParam(PARAM_PAGE)
+      .setDescription("1-based page number")
+      .setExampleValue("42")
+      .setDefaultValue("1");
+
+    action
+      .createParam(PARAM_PAGE_SIZE)
+      .setDescription("Page size. Must be greater than 0.")
+      .setExampleValue("10")
+      .setDefaultValue("25");
+
+    // TODO limit the fields to sort on + document possible values + default value ?
+    action
+      .createParam(PARAM_SORT)
+      .setDescription("Sort field")
+      .setExampleValue(RuleNormalizer.RuleField.LANGUAGE.key());
+
+    action
+      .createParam(PARAM_ASCENDING)
+      .setDescription("Ascending sort")
+      .setBooleanPossibleValues()
+      .setDefaultValue("true");
+  }
+
+  public static void defineSearchParameters(WebService.NewAction action) {
     action
       .createParam(PARAM_TEXT_QUERY)
       .setDescription("UTF-8 search query")
@@ -138,36 +172,6 @@ public class SearchAction implements RequestHandler {
       .setDescription("Used only if 'qprofile' is set")
       .setExampleValue("java:Sonar way")
       .setPossibleValues("false", "true", "all");
-
-    action
-      .createParam(PARAM_FIELDS)
-      .setDescription("Comma-separated list of the fields to be returned in response. All the fields are returned by default.")
-      .setPossibleValues(RuleIndex.PUBLIC_FIELDS)
-      .setExampleValue(String.format("%s,%s,%s", RuleNormalizer.RuleField.KEY, RuleNormalizer.RuleField.REPOSITORY, RuleNormalizer.RuleField.LANGUAGE));
-
-    action
-      .createParam(PARAM_PAGE)
-      .setDescription("1-based page number")
-      .setExampleValue("42")
-      .setDefaultValue("1");
-
-    action
-      .createParam(PARAM_PAGE_SIZE)
-      .setDescription("Page size. Must be greater than 0.")
-      .setExampleValue("10")
-      .setDefaultValue("25");
-
-    // TODO limit the fields to sort on + document possible values + default value ?
-    action
-      .createParam(PARAM_SORT)
-      .setDescription("Sort field")
-      .setExampleValue(RuleNormalizer.RuleField.LANGUAGE.key());
-
-    action
-      .createParam(PARAM_ASCENDING)
-      .setDescription("Ascending sort")
-      .setBooleanPossibleValues()
-      .setDefaultValue("true");
   }
 
   @Override
@@ -215,15 +219,15 @@ public class SearchAction implements RequestHandler {
     for (Rule rule : result.getHits()) {
       json.beginObject();
       json
-        .prop("key", rule.key().toString())
         .prop("repo", rule.key().repository())
+        .prop("key", rule.key().toString())
         .prop("lang", rule.language())
         .prop("name", rule.name())
         .prop("htmlDesc", rule.htmlDescription())
         .prop("status", rule.status().toString())
         .prop("template", rule.template())
         .prop("internalKey", rule.internalKey())
-        .prop("severity", rule.severity().toString())
+        .prop("severity", rule.severity())
         .name("tags").beginArray().values(rule.tags()).endArray()
         .name("sysTags").beginArray().values(rule.systemTags()).endArray();
       json.name("params").beginArray();
index 170f1b179c78fda0402e63dae334ac9a531d57d3..c0b01cc1139552b1dc3ee0cdf0a5022b43470b42 100644 (file)
@@ -44,16 +44,11 @@ public class SetTagsAction implements RequestHandler {
       .setSince("4.4")
       .setPost(true)
       .setHandler(this);
-    setTags
-      .createParam("repo")
-      .setRequired(true)
-      .setDescription("Repository key")
-      .setExampleValue("javascript");
     setTags
       .createParam("key")
       .setRequired(true)
       .setDescription("Rule key")
-      .setExampleValue("EmptyBlock");
+      .setExampleValue("javascript:EmptyBlock");
     setTags
       .createParam("tags")
       .setDescription("Comma-separated list of tags. Blank value is used to remove all tags.")
@@ -63,7 +58,7 @@ public class SetTagsAction implements RequestHandler {
 
   @Override
   public void handle(Request request, Response response) {
-    RuleKey key = RuleKey.of(request.mandatoryParam("repo"), request.mandatoryParam("key"));
+    RuleKey key = RuleKey.parse(request.mandatoryParam("key"));
     Set<String> tags = Sets.newHashSet(request.paramAsStrings("tags"));
     service.setTags(key, tags);
   }
index 8b304fee28996d3b60e62bc0320b3e266ce6bf24..1a41da1d485af7e12a9905218fcb79909d15ac5d 100644 (file)
@@ -20,7 +20,6 @@
 package org.sonar.server.rule2.ws;
 
 import com.google.common.io.Resources;
-import org.apache.commons.lang.StringUtils;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.RequestHandler;
@@ -51,27 +50,16 @@ public class ShowAction implements RequestHandler {
       .setResponseExample(Resources.getResource(getClass(), "example-show.json"))
       .setHandler(this);
 
-    action
-      .createParam("repo")
-      .setDescription("Repository key. It's not marked as required for backward-compatibility reasons.")
-      .setExampleValue("javascript");
-
     action
       .createParam("key")
-      .setDescription("Rule key. The format including the repository key is deprecated " +
-        "but still supported, for example 'javascript:EmptyBlock'.")
+      .setDescription("Rule key")
       .setRequired(true)
-      .setExampleValue("EmptyBlock");
+      .setExampleValue("javascript:EmptyBlock");
   }
 
   @Override
   public void handle(Request request, Response response) {
-    String ruleKey = request.mandatoryParam("key");
-    String repoKey = request.param("repo");
-    if (repoKey == null && ruleKey.contains(":")) {
-      repoKey = StringUtils.substringBefore(ruleKey, ":");
-    }
-    Rule rule = service.getByKey(RuleKey.of(repoKey, ruleKey));
+    Rule rule = service.getByKey(RuleKey.parse(request.mandatoryParam("key")));
     if (rule == null) {
       throw new NotFoundException("Rule not found");
     }
@@ -82,8 +70,8 @@ public class ShowAction implements RequestHandler {
 
   private void writeRule(Rule rule, JsonWriter json) {
     json
+      .prop("key", rule.key().toString())
       .prop("repo", rule.key().repository())
-      .prop("key", rule.key().rule())
       .prop("lang", rule.language())
       .prop("name", rule.name())
       .prop("htmlDesc", rule.htmlDescription())
index e6de1bc70ddc46d8c79a10e18c2ffe0ea4d8e5d9..d973d5a023dc41ade534d1848b3f5376862cf98a 100644 (file)
@@ -44,9 +44,11 @@ public class QProfileRecreateBuiltInActionTest {
 
   @Before
   public void setUp() throws Exception {
+    ActiveRuleService activeRuleService = mock(ActiveRuleService.class);
     tester = new WsTester(new QProfilesWs(
       new QProfileRecreateBuiltInAction(qProfileBackup),
-      new RuleActivationActions(mock(ActiveRuleService.class))));
+      new RuleActivationActions(activeRuleService),
+      new BulkRuleActivationActions(activeRuleService)));
   }
 
   @Test
index 0e982e50a1f9cafba9dbbd73038a91fe79136c85..125f40fafb32dc0b08d5b6c7d45cc39b84b33136 100644 (file)
@@ -36,8 +36,12 @@ public class QProfilesWsTest {
 
   @Before
   public void setUp() {
-    controller = new WsTester(new QProfilesWs(new QProfileRecreateBuiltInAction(mock(QProfileBackup.class)), new RuleActivationActions(mock(ActiveRuleService.class))))
-      .controller("api/qualityprofiles");
+    ActiveRuleService activeRuleService = mock(ActiveRuleService.class);
+    controller = new WsTester(new QProfilesWs(new QProfileRecreateBuiltInAction(
+      mock(QProfileBackup.class)),
+      new RuleActivationActions(activeRuleService),
+      new BulkRuleActivationActions(activeRuleService)
+    )).controller("api/qualityprofiles");
   }
 
   @Test
@@ -45,7 +49,7 @@ public class QProfilesWsTest {
     assertThat(controller).isNotNull();
     assertThat(controller.path()).isEqualTo("api/qualityprofiles");
     assertThat(controller.description()).isNotEmpty();
-    assertThat(controller.actions()).hasSize(3);
+    assertThat(controller.actions()).hasSize(5);
   }
 
   @Test
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
deleted file mode 100644 (file)
index dc734a6..0000000
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-/*
-* SonarQube, open source software quality management tool.
-* Copyright (C) 2008-2014 SonarSource
-* mailto:contact AT sonarsource DOT com
-*
-* SonarQube is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or (at your option) any later version.
-*
-* SonarQube is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public License
-* along with this program; if not, write to the Free Software Foundation,
-* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-*/
-//
-//package org.sonar.server.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;
-//import org.sonar.api.utils.DateUtils;
-//import org.sonar.api.utils.MessageException;
-//import org.sonar.api.utils.System2;
-//import org.sonar.core.cluster.WorkQueue;
-//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.rule2.RegisterRules;
-//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.Matchers.any;
-//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"};
-//  private static final String[] EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT = {"created_at", "updated_at", "note_data", "note_user_login", "note_created_at", "note_updated_at",
-//    "characteristic_id", "default_characteristic_id",
-//    "remediation_function", "default_remediation_function", "remediation_coeff", "default_remediation_coeff", "remediation_offset", "default_remediation_offset",
-//    "effort_to_fix_description"};
-//
-//  RegisterRules task;
-//
-//  @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;
-//  RuleTagDao ruleTagDao;
-//  ActiveRuleDao activeRuleDao;
-//  CharacteristicDao characteristicDao;
-//  System2 system;
-//  WorkQueue queue;
-//  Date date = DateUtils.parseDateTime("2014-03-17T19:10:03+0100");
-//
-//  @Before
-//  public void before() {
-//    system = mock(System2.class);
-//    when(system.now()).thenReturn(date.getTime());
-//    myBatis = getMyBatis();
-//    ruleDao = new RuleDao(myBatis);
-//    ruleTagDao = new RuleTagDao(myBatis);
-//    activeRuleDao = new ActiveRuleDao(myBatis);
-//    ruleTagOperations = new RuleTagOperations(ruleTagDao, esRuleTags);
-//    characteristicDao = new CharacteristicDao(myBatis);
-//    task = new RegisterRules(new RuleDefinitionsLoader(mock(RuleRepositories.class), new RulesDefinition[]{new FakeRepository()}),
-//      profilesManager, myBatis, ruleDao, ruleTagDao, activeRuleDao, characteristicDao, system);
-//  }
-//
-//  @Test
-//  public void insert_new_rules() {
-//    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");
-//  }
-//
-//  @Test
-//  public void update_template_rule_language() {
-//    setupData("update_template_rule_language");
-//    task.start();
-//
-//    checkTables("update_template_rule_language", EXCLUDED_COLUMN_NAMES, "rules");
-//  }
-//
-//  /**
-//   * SONAR-4642
-//   */
-//  @Test
-//  public void notify_for_removed_rules_when_repository_is_still_existing() {
-//    setupData("notify_for_removed_rules_when_repository_is_still_existing");
-//    task.start();
-//
-//    verify(profilesManager).removeActivatedRules(1);
-//  }
-//
-//  /**
-//   * SONAR-4642
-//   */
-//  @Test
-//  public void not_notify_for_removed_rules_when_repository_do_not_exists_anymore() {
-//    setupData("shared");
-//    task.start();
-//
-//    verifyZeroInteractions(profilesManager);
-//  }
-//
-//  @Test
-//  public void reactivate_disabled_rules() {
-//    setupData("reactivate_disabled_rules");
-//    task.start();
-//
-//    checkTables("reactivate_disabled_rules", EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT, "rules");
-//
-//    assertThat(ruleDao.selectById(1).getUpdatedAt()).isNotNull();
-//  }
-//
-//  @Test
-//  public void reactivate_disabled_template_rules() {
-//    setupData("reactivate_disabled_template_rules");
-//    task.start();
-//
-//    checkTables("reactivate_disabled_template_rules", EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT, "rules");
-//  }
-//
-//  @Test
-//  public void disable_deprecated_active_rules() {
-//    setupData("disable_deprecated_active_rules");
-//    task.start();
-//
-//    checkTables("disable_deprecated_active_rules", EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT, "rules");
-//  }
-//
-//  @Test
-//  public void disable_deprecated_active_rule_params() {
-//    setupData("disable_deprecated_active_rule_params");
-//    task.start();
-//
-//    checkTables("disable_deprecated_active_rule_params", EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT, "rules", "rules_parameters", "active_rules", "active_rule_parameters");
-//  }
-//
-//  @Test
-//  public void disable_deprecated_rules() {
-//    setupData("disable_deprecated_rules");
-//    task.start();
-//
-//    checkTables("disable_deprecated_rules", EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT, "rules", "rules_parameters", "rules_rule_tags", "rule_tags");
-//  }
-//
-//  @Test
-//  public void not_disable_already_disabled_rules() {
-//    setupData("not_disable_already_disabled_rules");
-//    task.start();
-//
-//    checkTables("not_disable_already_disabled_rules", new String[]{"created_at", "note_data", "note_user_login", "note_created_at", "note_updated_at"}, "rules");
-//  }
-//
-//  @Test
-//  public void update_rule_fields() {
-//    setupData("update_rule_fields");
-//    task.start();
-//
-//    checkTables("update_rule_fields", EXCLUDED_COLUMN_NAMES, "rules", "rules_parameters", "rule_tags", "rules_rule_tags");
-//  }
-//
-//  @Test
-//  public void update_rule_parameters() {
-//    setupData("update_rule_parameters");
-//    task.start();
-//
-//    checkTables("update_rule_parameters", EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT, "rules", "rules_parameters");
-//  }
-//
-//  @Test
-//  public void set_no_default_characteristic_when_characteristic_not_found() {
-//    setupData("set_no_characteristic_when_characteristic_not_found");
-//
-//    task.start();
-//    // Warning log should be displayed
-//
-//    checkTables("set_no_characteristic_when_characteristic_not_found", EXCLUDED_COLUMN_NAMES, "rules");
-//  }
-//
-//  @Test
-//  public void set_no_default_characteristic_when_default_characteristic_not_found_and_overriding_characteristic_disabled() {
-//    setupData("set_no_characteristic_when_default_characteristic_not_found_and_overriding_characteristic_disabled");
-//
-//    task.start();
-//    // No log should be displayed
-//
-//    checkTables("set_no_characteristic_when_default_characteristic_not_found_and_overriding_characteristic_disabled", EXCLUDED_COLUMN_NAMES, "rules");
-//  }
-//
-//  @Test
-//  public void set_no_default_characteristic_when_default_characteristic_not_found_but_characteristic_has_been_overridden() {
-//    setupData("set_no_default_characteristic_when_default_characteristic_not_found_but_characteristic_has_been_overridden");
-//
-//    task.start();
-//    // No log should be displayed
-//
-//    checkTables("set_no_default_characteristic_when_default_characteristic_not_found_but_characteristic_has_been_overridden", EXCLUDED_COLUMN_NAMES, "rules");
-//  }
-//
-//  @Test
-//  public void fail_when_rule_is_linked_on_root_characteristic() {
-//    setupData("ignore_rule_debt_definitions_if_rule_is_linked_on_root_characteristic");
-//
-//    try {
-//      task.start();
-//      fail();
-//    } catch (Exception e) {
-//      assertThat(e).isInstanceOf(MessageException.class).hasMessage("Rule 'fake:rule1' cannot be linked on the root characteristic 'MEMORY_EFFICIENCY'");
-//    }
-//  }
-//
-//  @Test
-//  public void not_disable_template_rules_if_parent_is_enabled() {
-//    setupData("not_disable_template_rules_if_parent_is_enabled");
-//    task.start();
-//
-//    checkTables("not_disable_template_rules_if_parent_is_enabled", EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT, "rules");
-//  }
-//
-//  @Test
-//  public void disable_template_rules_if_parent_is_disabled() {
-//    setupData("disable_template_rules_if_parent_is_disabled");
-//    task.start();
-//
-//    checkTables("disable_template_rules_if_parent_is_disabled", EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT, "rules");
-//  }
-//
-//  @Test
-//  public void not_disable_manual_rules() {
-//    // the hardcoded repository "manual" is used for manual violations
-//    setupData("not_disable_manual_rules");
-//    task.start();
-//
-//    checkTables("not_disable_manual_rules", EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT, "rules");
-//  }
-//
-//  @Test
-//  public void test_high_number_of_rules() {
-//    task = new RegisterRules(new RuleDefinitionsLoader(mock(RuleRepositories.class), new RulesDefinition[]{new BigRepository()}),
-//      profilesManager, ruleRegistry, esRuleTags, ruleTagOperations, myBatis, ruleDao, ruleTagDao, activeRuleDao, characteristicDao, mock(RegisterDebtModel.class));
-//
-//    setupData("shared");
-//    task.start();
-//
-//    // There is already one rule in DB
-//    assertThat(ruleDao.selectAll()).hasSize(BigRepository.SIZE + 1);
-//    assertThat(ruleDao.selectParameters()).hasSize(BigRepository.SIZE * 20);
-//    assertThat(ruleDao.selectTags(getMyBatis().openSession(false))).hasSize(BigRepository.SIZE * 3);
-//  }
-//
-//  @Test
-//  public void insert_extended_repositories() {
-//    task = new RegisterRules(new RuleDefinitionsLoader(mock(RuleRepositories.class), new RulesDefinition[]{
-//      new FindbugsRepository(), new FbContribRepository()}),
-//      profilesManager, ruleRegistry, esRuleTags, ruleTagOperations, myBatis, ruleDao, ruleTagDao, activeRuleDao, characteristicDao, mock(RegisterDebtModel.class)
-//    );
-//
-//    setupData("empty");
-//    task.start();
-//
-//    checkTables("insert_extended_repositories", EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT, "rules");
-//  }
-//
-//  static class FakeRepository implements RulesDefinition {
-//    @Override
-//    public void define(Context context) {
-//      NewRepository repo = context.createRepository("fake", "java");
-//
-//      NewRule rule1 = repo.createRule("rule1")
-//        .setName("One")
-//        .setHtmlDescription("Description of One")
-//        .setSeverity(Severity.BLOCKER)
-//        .setInternalKey("config1")
-//        .setTags("tag1", "tag3", "tag5");
-//
-//      rule1.setDebtSubCharacteristic("MEMORY_EFFICIENCY")
-//        .setDebtRemediationFunction(rule1.debtRemediationFunctions().linearWithOffset("5d", "10h"))
-//        .setEffortToFixDescription("squid.S115.effortToFix");
-//
-//      rule1.createParam("param1").setDescription("parameter one").setDefaultValue("default value one");
-//      rule1.createParam("param2").setDescription("parameter two").setDefaultValue("default value two");
-//
-//      repo.createRule("rule2")
-//        .setName("Two")
-//        .setHtmlDescription("Description of Two")
-//        .setSeverity(Severity.INFO)
-//        .setStatus(RuleStatus.DEPRECATED);
-//      repo.done();
-//    }
-//  }
-//
-//  static class BigRepository implements RulesDefinition {
-//    static final int SIZE = 500;
-//
-//    @Override
-//    public void define(Context context) {
-//      NewRepository repo = context.createRepository("big", "java");
-//      for (int i = 0; i < SIZE; i++) {
-//        NewRule rule = repo.createRule("rule" + i)
-//          .setName("name of " + i)
-//          .setHtmlDescription("description of " + i)
-//          .setSeverity(Severity.BLOCKER)
-//          .setInternalKey("config1")
-//          .setTags("tag1", "tag3", "tag5");
-//        for (int j = 0; j < 20; j++) {
-//          rule.createParam("param" + j);
-//        }
-//
-//      }
-//      repo.done();
-//    }
-//  }
-//
-//  static class FindbugsRepository implements RulesDefinition {
-//    @Override
-//    public void define(Context context) {
-//      NewRepository repo = context.createRepository("findbugs", "java");
-//      repo.createRule("rule1")
-//        .setName("Rule One")
-//        .setHtmlDescription("Description of Rule One");
-//      repo.done();
-//    }
-//  }
-//
-//  static class FbContribRepository implements RulesDefinition {
-//    @Override
-//    public void define(Context context) {
-//      NewExtendedRepository repo = context.extendRepository("findbugs", "java");
-//      repo.createRule("rule2")
-//        .setName("Rule Two")
-//        .setHtmlDescription("Description of Rule Two");
-//      repo.done();
-//    }
-//  }
-//}
-//
index 48346239f8e22e876ada223ab46aafc3695ccf8a..2c7e8890be179df4237a9b1f6fe5a766ae84d3f3 100644 (file)
@@ -21,20 +21,18 @@ package org.sonar.server.rule2;
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.runners.MockitoJUnitRunner;
+import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.rule.Severity;
 import org.sonar.api.server.rule.RulesDefinition;
 import org.sonar.api.utils.DateUtils;
-import org.sonar.api.utils.MessageException;
 import org.sonar.api.utils.System2;
 import org.sonar.core.persistence.AbstractDaoTestCase;
 import org.sonar.core.persistence.DbSession;
-import org.sonar.core.persistence.MyBatis;
 import org.sonar.core.qualityprofile.db.QualityProfileDao;
+import org.sonar.core.rule.RuleDto;
+import org.sonar.core.rule.RuleParamDto;
 import org.sonar.core.technicaldebt.db.CharacteristicDao;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.qualityprofile.ProfilesManager;
@@ -44,277 +42,219 @@ import org.sonar.server.rule.RuleRepositories;
 import org.sonar.server.rule2.persistence.RuleDao;
 
 import java.util.Date;
+import java.util.List;
 
 import static org.fest.assertions.Assertions.assertThat;
-import static org.fest.assertions.Fail.fail;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
-@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"};
-  private static final String[] EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT = {"created_at", "updated_at", "note_data", "note_user_login", "note_created_at", "note_updated_at",
-    "characteristic_id", "default_characteristic_id",
-    "remediation_function", "default_remediation_function", "remediation_coeff", "default_remediation_coeff", "remediation_offset", "default_remediation_offset",
-    "effort_to_fix_description"};
+  static final Date DATE1 = DateUtils.parseDateTime("2014-01-01T19:10:03+0100");
+  static final Date DATE2 = DateUtils.parseDateTime("2014-02-01T12:10:03+0100");
+  static final Date DATE3 = DateUtils.parseDateTime("2014-03-01T12:10:03+0100");
 
-  RegisterRules task;
   ProfilesManager profilesManager = mock(ProfilesManager.class);
-  MyBatis myBatis;
-  RuleDao ruleDao;
-  ActiveRuleDao activeRuleDao;
   CharacteristicDao characteristicDao;
   System2 system;
-  Date date = DateUtils.parseDateTime("2014-03-17T19:10:03+0100");
-  DbSession session;
   DbClient dbClient;
+  DbSession dbSession;
 
   @Before
   public void before() {
     system = mock(System2.class);
-    when(system.now()).thenReturn(date.getTime());
-    myBatis = getMyBatis();
-    ruleDao = new RuleDao();
-    activeRuleDao = new ActiveRuleDao(new QualityProfileDao(myBatis), ruleDao);
+    when(system.now()).thenReturn(DATE1.getTime());
+    RuleDao ruleDao = new RuleDao(system);
+    ActiveRuleDao activeRuleDao = new ActiveRuleDao(new QualityProfileDao(getMyBatis()), ruleDao, system);
     dbClient = new DbClient(getDatabase(), getMyBatis(), ruleDao, activeRuleDao, new QualityProfileDao(getMyBatis()));
-    characteristicDao = new CharacteristicDao(myBatis);
-    task = new RegisterRules(new RuleDefinitionsLoader(mock(RuleRepositories.class),
-      new RulesDefinition[]{new FakeRepository()}),
-      profilesManager, dbClient, characteristicDao, system
-    );
-    session = myBatis.openSession(false);
+    characteristicDao = new CharacteristicDao(getMyBatis());
+    dbSession = dbClient.openSession(false);
   }
 
   @After
-  public void after() {
-    session.close();
+  public void after() throws Exception {
+    dbSession.close();
   }
 
   @Test
-  public void update_template_rule_language() {
-    setupData("update_template_rule_language");
-    task.start();
-
-    checkTables("update_template_rule_language", EXCLUDED_COLUMN_NAMES, "rules");
-  }
-
-  /**
-   * SONAR-4642
-   */
-  @Test
-  public void notify_for_removed_rules_when_repository_is_still_existing() {
-    setupData("notify_for_removed_rules_when_repository_is_still_existing");
-    task.start();
-
-    verify(profilesManager).removeActivatedRules(1);
-  }
-
-  /**
-   * SONAR-4642
-   */
-  @Test
-  public void not_notify_for_removed_rules_when_repository_do_not_exists_anymore() {
-    setupData("shared");
-    task.start();
-
-    verifyZeroInteractions(profilesManager);
-  }
-
-  @Test
-  @Ignore //TODO Check if created and updated should be at DTO/BaseDao level.
-  public void reactivate_disabled_rules() {
-    setupData("reactivate_disabled_rules");
-    task.start();
-
-    checkTables("reactivate_disabled_rules", EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT, "rules");
-
-    assertThat(ruleDao.getById(1, session).getUpdatedAt()).isNotNull();
-  }
-
-  @Test
-  public void reactivate_disabled_template_rules() {
-    setupData("reactivate_disabled_template_rules");
-    task.start();
-
-    checkTables("reactivate_disabled_template_rules", EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT, "rules");
-  }
-
-  @Test
-  public void disable_deprecated_active_rules() {
-    setupData("disable_deprecated_active_rules");
-    task.start();
-
-    checkTables("disable_deprecated_active_rules", EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT, "rules");
+  public void insert_new_rules() {
+    execute(new FakeRepositoryV1());
+
+    assertThat(dbClient.ruleDao().findAll(dbSession)).hasSize(2);
+    RuleKey ruleKey1 = RuleKey.of("fake", "rule1");
+    RuleDto rule1 = dbClient.ruleDao().getByKey(ruleKey1, dbSession);
+    assertThat(rule1.getName()).isEqualTo("One");
+    assertThat(rule1.getDescription()).isEqualTo("Description of One");
+    assertThat(rule1.getSeverityString()).isEqualTo(Severity.BLOCKER);
+    assertThat(rule1.getTags()).isEmpty();
+    assertThat(rule1.getSystemTags()).containsOnly("tag1", "tag2", "tag3");
+    assertThat(rule1.getConfigKey()).isEqualTo("config1");
+    assertThat(rule1.getStatus()).isEqualTo(RuleStatus.BETA.toString());
+    assertThat(rule1.getCreatedAt()).isEqualTo(DATE1);
+    assertThat(rule1.getUpdatedAt()).isEqualTo(DATE1);
+    assertThat(rule1.getEffortToFixDescription()).isEqualTo("squid.S115.effortToFix");
+    // TODO check characteristic and remediation function
+
+    List<RuleParamDto> params = dbClient.ruleDao().findRuleParamsByRuleKey(ruleKey1, dbSession);
+    assertThat(params).hasSize(2);
+    RuleParamDto param = getParam(params, "param1");
+    assertThat(param.getDescription()).isEqualTo("parameter one");
+    assertThat(param.getDefaultValue()).isEqualTo("default1");
   }
 
   @Test
-  @Ignore //TODO to fix with new RegisterRule
-  public void disable_deprecated_active_rule_params() {
-    setupData("disable_deprecated_active_rule_params");
-    task.start();
-
-    checkTables("disable_deprecated_active_rule_params", EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT, "rules", "rules_parameters", "active_rules", "active_rule_parameters");
-  }
-
-  @Test
-  //TODO check with mergeTag what happens on removal.
-  public void disable_deprecated_rules() {
-    setupData("disable_deprecated_rules");
-    task.start();
-
-    checkTables("disable_deprecated_rules", EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT, "rules", "rules_parameters");
-  }
-
-  @Test
-  @Ignore //TODO to fix with new RegisterRule
-  public void not_disable_already_disabled_rules() {
-    setupData("not_disable_already_disabled_rules");
-    task.start();
-
-    checkTables("not_disable_already_disabled_rules", new String[]{"created_at", "note_data", "note_user_login", "note_created_at", "note_updated_at"}, "rules");
-  }
-
-  @Test
-  @Ignore //TODO fix in RuleRegister DAOv.2
-  public void update_rule_fields() {
-    setupData("update_rule_fields");
-    task.start();
-
-    checkTables("update_rule_fields", EXCLUDED_COLUMN_NAMES, "rules", "rules_parameters");
-  }
+  public void do_not_update_rules_when_no_changes() {
+    execute(new FakeRepositoryV1());
+    assertThat(dbClient.ruleDao().findAll(dbSession)).hasSize(2);
 
-  @Test
-  public void update_rule_parameters() {
-    setupData("update_rule_parameters");
-    task.start();
+    when(system.now()).thenReturn(DATE2.getTime());
+    execute(new FakeRepositoryV1());
 
-    checkTables("update_rule_parameters", EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT, "rules", "rules_parameters");
+    RuleKey ruleKey1 = RuleKey.of("fake", "rule1");
+    RuleDto rule1 = dbClient.ruleDao().getByKey(ruleKey1, dbSession);
+    assertThat(rule1.getCreatedAt()).isEqualTo(DATE1);
+    assertThat(rule1.getUpdatedAt()).isEqualTo(DATE1);
   }
 
   @Test
-  @Ignore //TODO characteristics not yet in DAOv.2
-  public void set_no_default_characteristic_when_characteristic_not_found() {
-    setupData("set_no_characteristic_when_characteristic_not_found");
-
-    task.start();
-    // Warning log should be displayed
-
-    checkTables("set_no_characteristic_when_characteristic_not_found", EXCLUDED_COLUMN_NAMES, "rules");
+  public void update_rules_on_changes() {
+    execute(new FakeRepositoryV1());
+    assertThat(dbClient.ruleDao().findAll(dbSession)).hasSize(2);
+
+    when(system.now()).thenReturn(DATE2.getTime());
+    execute(new FakeRepositoryV2());
+
+    // rule1 has been updated
+    RuleKey ruleKey1 = RuleKey.of("fake", "rule1");
+    RuleDto rule1 = dbClient.ruleDao().getByKey(ruleKey1, dbSession);
+    assertThat(rule1.getName()).isEqualTo("One v2");
+    assertThat(rule1.getDescription()).isEqualTo("Description of One v2");
+    assertThat(rule1.getSeverityString()).isEqualTo(Severity.INFO);
+    assertThat(rule1.getTags()).isEmpty();
+    assertThat(rule1.getSystemTags()).containsOnly("tag1", "tag4");
+    assertThat(rule1.getConfigKey()).isEqualTo("config1 v2");
+    assertThat(rule1.getStatus()).isEqualTo(RuleStatus.READY.toString());
+    assertThat(rule1.getCreatedAt()).isEqualTo(DATE1);
+    assertThat(rule1.getUpdatedAt()).isEqualTo(DATE2);
+    assertThat(rule1.getEffortToFixDescription()).isEqualTo("squid.S115.effortToFix.v2");
+    // TODO check characteristic and remediation function
+    List<RuleParamDto> params = dbClient.ruleDao().findRuleParamsByRuleKey(ruleKey1, dbSession);
+    assertThat(params).hasSize(2);
+    RuleParamDto param = getParam(params, "param1");
+    assertThat(param.getDescription()).isEqualTo("parameter one v2");
+    assertThat(param.getDefaultValue()).isEqualTo("default1 v2");
+
+    // rule2 has been removed
+    RuleDto rule2 = dbClient.ruleDao().getByKey(RuleKey.of("fake", "rule2"), dbSession);
+    assertThat(rule2.getStatus()).isEqualTo(RuleStatus.REMOVED.toString());
+    assertThat(rule2.getUpdatedAt()).isEqualTo(DATE2);
+
+    // rule3 has been created
+    RuleDto rule3 = dbClient.ruleDao().getByKey(RuleKey.of("fake", "rule3"), dbSession);
+    assertThat(rule3).isNotNull();
   }
 
   @Test
-  public void set_no_default_characteristic_when_default_characteristic_not_found_and_overriding_characteristic_disabled() {
-    setupData("set_no_characteristic_when_default_characteristic_not_found_and_overriding_characteristic_disabled");
-
-    task.start();
-    // No log should be displayed
-
-    checkTables("set_no_characteristic_when_default_characteristic_not_found_and_overriding_characteristic_disabled", EXCLUDED_COLUMN_NAMES, "rules");
+  public void do_not_update_already_removed_rules() {
+    execute(new FakeRepositoryV1());
+    assertThat(dbClient.ruleDao().findAll(dbSession)).hasSize(2);
+
+    when(system.now()).thenReturn(DATE2.getTime());
+    execute(new FakeRepositoryV2());
+    // rule2 is removed
+
+    when(system.now()).thenReturn(DATE3.getTime());
+    execute(new FakeRepositoryV2());
+    // -> rule2 is still removed, but not update at DATE3
+    RuleDto rule2 = dbClient.ruleDao().getByKey(RuleKey.of("fake", "rule2"), dbSession);
+    assertThat(rule2.getStatus()).isEqualTo(RuleStatus.REMOVED.toString());
+    assertThat(rule2.getUpdatedAt()).isEqualTo(DATE2);
   }
 
   @Test
-  @Ignore //TODO characteristics not yet in DAOv.2
-  public void set_no_default_characteristic_when_default_characteristic_not_found_but_characteristic_has_been_overridden() {
-    setupData("set_no_default_characteristic_when_default_characteristic_not_found_but_characteristic_has_been_overridden");
-
-    task.start();
-    // No log should be displayed
-
-    checkTables("set_no_default_characteristic_when_default_characteristic_not_found_but_characteristic_has_been_overridden", EXCLUDED_COLUMN_NAMES, "rules");
+  public void mass_insert() {
+    execute(new BigRepository());
+    assertThat(dbClient.ruleDao().findAll(dbSession)).hasSize(BigRepository.SIZE);
+    assertThat(dbClient.ruleDao().findAllRuleParams(dbSession)).hasSize(BigRepository.SIZE * 20);
   }
 
   @Test
-  @Ignore //TODO to fix with new RegisterRule
-  public void fail_when_rule_is_linked_on_root_characteristic() {
-    setupData("ignore_rule_debt_definitions_if_rule_is_linked_on_root_characteristic");
-
-    try {
-      task.start();
-      fail();
-    } catch (Exception e) {
-      assertThat(e).isInstanceOf(MessageException.class).hasMessage("Rule 'fake:rule1' cannot be linked on the root characteristic 'MEMORY_EFFICIENCY'");
+  public void manage_repository_extensions() {
+    execute(new FindbugsRepository(), new FbContribRepository());
+    List<RuleDto> rules = dbClient.ruleDao().findAll(dbSession);
+    assertThat(rules).hasSize(2);
+    for (RuleDto rule : rules) {
+      assertThat(rule.getRepositoryKey()).isEqualTo("findbugs");
     }
   }
 
-  @Test
-  public void not_disable_template_rules_if_parent_is_enabled() {
-    setupData("not_disable_template_rules_if_parent_is_enabled");
-    task.start();
-
-    checkTables("not_disable_template_rules_if_parent_is_enabled", EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT, "rules");
-  }
-
-  @Test
-  @Ignore //TODO to fix with new RegisterRule
-  public void disable_template_rules_if_parent_is_disabled() {
-    setupData("disable_template_rules_if_parent_is_disabled");
-    task.start();
-
-    checkTables("disable_template_rules_if_parent_is_disabled", EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT, "rules");
-  }
-
-  @Test
-  public void not_disable_manual_rules() {
-    // the hardcoded repository "manual" is used for manual violations
-    setupData("not_disable_manual_rules");
-    task.start();
-
-    checkTables("not_disable_manual_rules", EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT, "rules");
-  }
-
-  @Test
-  public void test_high_number_of_rules() {
-    task = new RegisterRules(new RuleDefinitionsLoader(mock(RuleRepositories.class), new RulesDefinition[]{new BigRepository()}),
-      profilesManager, dbClient, characteristicDao);
-
-    setupData("shared");
+  private void execute(RulesDefinition... defs) {
+    RuleDefinitionsLoader loader = new RuleDefinitionsLoader(mock(RuleRepositories.class), defs);
+    RegisterRules task = new RegisterRules(loader, profilesManager, dbClient, characteristicDao, system);
     task.start();
-
-
-    // There is already one rule in DB
-    assertThat(ruleDao.findAll(session)).hasSize(BigRepository.SIZE + 1);
-    assertThat(ruleDao.findAllRuleParams(session)).hasSize(BigRepository.SIZE * 20);
-//    assertThat(ruleDao.selectTags(getMyBatis().openSession(false))).hasSize(BigRepository.SIZE * 3);
   }
 
-  @Test
-  public void insert_extended_repositories() {
-    task = new RegisterRules(new RuleDefinitionsLoader(mock(RuleRepositories.class), new RulesDefinition[]{
-      new FindbugsRepository(), new FbContribRepository()}),
-      profilesManager, dbClient, characteristicDao
-    );
-
-
-    setupData("empty");
-    task.start();
-
-    checkTables("insert_extended_repositories", EXCLUDED_COLUMN_NAMES_INCLUDING_DEBT, "rules");
+  private RuleParamDto getParam(List<RuleParamDto> params, String key) {
+    for (RuleParamDto param : params) {
+      if (param.getName().equals(key)) {
+        return param;
+      }
+    }
+    return null;
   }
 
-  static class FakeRepository implements RulesDefinition {
+  static class FakeRepositoryV1 implements RulesDefinition {
     @Override
     public void define(Context context) {
       NewRepository repo = context.createRepository("fake", "java");
-
       NewRule rule1 = repo.createRule("rule1")
         .setName("One")
         .setHtmlDescription("Description of One")
         .setSeverity(Severity.BLOCKER)
         .setInternalKey("config1")
-        .setTags("tag1", "tag3", "tag5");
-
-      rule1.setDebtSubCharacteristic("MEMORY_EFFICIENCY")
-        .setDebtRemediationFunction(rule1.debtRemediationFunctions().linearWithOffset("5d", "10h"))
+        .setTags("tag1", "tag2", "tag3")
+        .setStatus(RuleStatus.BETA)
+        .setDebtSubCharacteristic("MEMORY_EFFICIENCY")
         .setEffortToFixDescription("squid.S115.effortToFix");
+      rule1.setDebtRemediationFunction(rule1.debtRemediationFunctions().linearWithOffset("5d", "10h"));
 
-      rule1.createParam("param1").setDescription("parameter one").setDefaultValue("default value one");
-      rule1.createParam("param2").setDescription("parameter two").setDefaultValue("default value two");
+      rule1.createParam("param1").setDescription("parameter one").setDefaultValue("default1");
+      rule1.createParam("param2").setDescription("parameter two").setDefaultValue("default2");
 
       repo.createRule("rule2")
         .setName("Two")
-        .setHtmlDescription("Description of Two")
+        .setHtmlDescription("Minimal rule");
+      repo.done();
+    }
+  }
+
+  /**
+   * FakeRepositoryV1 with some changes
+   */
+  static class FakeRepositoryV2 implements RulesDefinition {
+    @Override
+    public void define(Context context) {
+      NewRepository repo = context.createRepository("fake", "java");
+
+      // almost all the attributes of rule1 are changed
+      NewRule rule1 = repo.createRule("rule1")
+        .setName("One v2")
+        .setHtmlDescription("Description of One v2")
         .setSeverity(Severity.INFO)
-        .setStatus(RuleStatus.DEPRECATED);
+        .setInternalKey("config1 v2")
+          // tag2 and tag3 removed, tag4 added
+        .setTags("tag1", "tag4")
+        .setStatus(RuleStatus.READY)
+        .setDebtSubCharacteristic("MEMORY_EFFICIENCY")
+        .setEffortToFixDescription("squid.S115.effortToFix.v2");
+      rule1.setDebtRemediationFunction(rule1.debtRemediationFunctions().linearWithOffset("6d", "2h"));
+      rule1.createParam("param1").setDescription("parameter one v2").setDefaultValue("default1 v2");
+      rule1.createParam("param2").setDescription("parameter two v2").setDefaultValue("default2 v2");
+
+      // rule2 is dropped, rule3 is new
+      repo.createRule("rule3")
+        .setName("Three")
+        .setHtmlDescription("Rule Three");
       repo.done();
     }
   }
@@ -328,10 +268,7 @@ public class RegisterRulesTest extends AbstractDaoTestCase {
       for (int i = 0; i < SIZE; i++) {
         NewRule rule = repo.createRule("rule" + i)
           .setName("name of " + i)
-          .setHtmlDescription("description of " + i)
-          .setSeverity(Severity.BLOCKER)
-          .setInternalKey("config1")
-          .setTags("tag1", "tag3", "tag5");
+          .setHtmlDescription("description of " + i);
         for (int j = 0; j < 20; j++) {
           rule.createParam("param" + j);
         }
index 6f17a18d6cef19b0ef9b54ac4ad02f47521a5904..783cff96a7c48520a693c0e4d4d80f32c9623f1f 100644 (file)
@@ -85,6 +85,10 @@ public class ServerTester extends ExternalResource {
     platform.init(properties);
     platform.addComponents(components);
     platform.doStart();
+    if (!platform.isStarted()) {
+      throw new IllegalStateException("Server not started. You should check that db migrations " +
+        "are correctly declared, for example in schema-h2.sql or DatabaseVersion");
+    }
   }
 
   private File createTempDir() {