]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6540 Ignore active rules linked on removed rules / profiles
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Fri, 18 Sep 2015 15:22:51 +0000 (17:22 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Mon, 21 Sep 2015 08:31:02 +0000 (10:31 +0200)
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ActiveRuleBackendMediumTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ActiveRuleTest.java [new file with mode: 0644]
sonar-db/src/main/resources/org/sonar/db/qualityprofile/ActiveRuleMapper.xml

diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ActiveRuleBackendMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ActiveRuleBackendMediumTest.java
deleted file mode 100644 (file)
index b7e8c0f..0000000
+++ /dev/null
@@ -1,410 +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.
- */
-package org.sonar.server.qualityprofile;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Multimap;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.RuleStatus;
-import org.sonar.api.rule.Severity;
-import org.sonar.api.server.debt.DebtRemediationFunction;
-import org.sonar.db.DbSession;
-import org.sonar.db.qualityprofile.ActiveRuleDto;
-import org.sonar.db.qualityprofile.ActiveRuleParamDto;
-import org.sonar.db.qualityprofile.QualityProfileDto;
-import org.sonar.db.rule.RuleDto;
-import org.sonar.db.rule.RuleParamDto;
-import org.sonar.db.rule.RuleTesting;
-import org.sonar.server.db.DbClient;
-import org.sonar.server.platform.Platform;
-import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
-import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer;
-import org.sonar.server.rule.db.RuleDao;
-import org.sonar.server.search.FacetValue;
-import org.sonar.server.search.IndexClient;
-import org.sonar.server.tester.ServerTester;
-import org.sonar.server.tester.UserSessionRule;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class ActiveRuleBackendMediumTest {
-
-  @ClassRule
-  public static ServerTester tester = new ServerTester();
-  @Rule
-  public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester);
-
-  DbClient db;
-  RuleDao dao;
-  IndexClient index;
-  DbSession dbSession;
-
-  @Before
-  public void before() {
-    dao = tester.get(RuleDao.class);
-    tester.clearDbAndIndexes();
-    db = tester.get(DbClient.class);
-    index = tester.get(IndexClient.class);
-    dbSession = tester.get(DbClient.class).openSession(false);
-
-  }
-
-  @After
-  public void after() {
-    if (dbSession != null) {
-      dbSession.close();
-    }
-  }
-
-  @Test
-  public void synchronize_index() {
-
-    Date beginning = new Date();
-
-    QualityProfileDto profile1 = QProfileTesting.newXooP1();
-    db.qualityProfileDao().insert(dbSession, profile1);
-
-    RuleDto rule1 = RuleDto.createFor(RuleTesting.XOO_X1).setSeverity(Severity.MAJOR);
-    db.deprecatedRuleDao().insert(dbSession, rule1);
-
-    ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile1, rule1).setSeverity("BLOCKER");
-    db.activeRuleDao().insert(dbSession, activeRule);
-    dbSession.commit();
-
-    // 1. Synchronize since 0
-    tester.clearIndexes();
-    assertThat(index.get(ActiveRuleIndex.class).getNullableByKey(activeRule.getKey())).isNull();
-    db.activeRuleDao().synchronizeAfter(dbSession, new Date(0L));
-    dbSession.commit();
-    assertThat(index.get(ActiveRuleIndex.class).getNullableByKey(activeRule.getKey())).isNotNull();
-
-    // 2. Synchronize since beginning
-    tester.clearIndexes();
-    assertThat(index.get(ActiveRuleIndex.class).getNullableByKey(activeRule.getKey())).isNull();
-    db.activeRuleDao().synchronizeAfter(dbSession, beginning);
-    dbSession.commit();
-    assertThat(index.get(ActiveRuleIndex.class).getNullableByKey(activeRule.getKey())).isNotNull();
-
-    // 3. Assert startup picks it up
-    tester.clearIndexes();
-    assertThat(index.get(ActiveRuleIndex.class).getLastSynchronization()).isNull();
-    tester.get(Platform.class).executeStartupTasks();
-    assertThat(index.get(ActiveRuleIndex.class).getNullableByKey(activeRule.getKey())).isNotNull();
-    assertThat(index.get(ActiveRuleIndex.class).getLastSynchronization()).isNotNull();
-  }
-
-  @Test
-  public void insert_and_index_active_rule() {
-    QualityProfileDto profileDto = QProfileTesting.newXooP1();
-    db.qualityProfileDao().insert(dbSession, profileDto);
-    RuleKey ruleKey = RuleTesting.XOO_X1;
-    RuleDto ruleDto = newRuleDto(ruleKey);
-    db.deprecatedRuleDao().insert(dbSession, ruleDto);
-
-    ActiveRuleDto activeRule = ActiveRuleDto.createFor(profileDto, ruleDto)
-      .setInheritance(ActiveRule.Inheritance.INHERITED.name())
-      .setSeverity(Severity.BLOCKER);
-    db.activeRuleDao().insert(dbSession, activeRule);
-    dbSession.commit();
-
-    // verify db
-    assertThat(db.activeRuleDao().getByKey(dbSession, activeRule.getKey())).isNotNull();
-    List<ActiveRuleDto> persistedDtos = db.activeRuleDao().selectByRule(dbSession, ruleDto);
-    assertThat(persistedDtos).hasSize(1);
-
-    // verify es
-    ActiveRule hit = index.get(ActiveRuleIndex.class).getByKey(activeRule.getKey());
-    assertThat(hit).isNotNull();
-    assertThat(hit.key()).isEqualTo(activeRule.getKey());
-    assertThat(hit.inheritance().name()).isEqualTo(activeRule.getInheritance());
-    assertThat(hit.parentKey()).isNull();
-    assertThat(hit.severity()).isEqualTo(activeRule.getSeverityString());
-  }
-
-  @Test
-  public void insert_and_index_active_rule_param() {
-    // insert and index
-    QualityProfileDto profileDto = QProfileTesting.newXooP1();
-    db.qualityProfileDao().insert(dbSession, profileDto);
-    RuleKey ruleKey = RuleTesting.XOO_X1;
-    RuleDto ruleDto = newRuleDto(ruleKey);
-    db.deprecatedRuleDao().insert(dbSession, ruleDto);
-
-    RuleParamDto minParam = new RuleParamDto()
-      .setName("min")
-      .setType("STRING");
-    db.deprecatedRuleDao().insertRuleParam(dbSession, ruleDto, minParam);
-
-    RuleParamDto maxParam = new RuleParamDto()
-      .setName("max")
-      .setType("STRING");
-    db.deprecatedRuleDao().insertRuleParam(dbSession, ruleDto, maxParam);
-
-    ActiveRuleDto activeRule = ActiveRuleDto.createFor(profileDto, ruleDto)
-      .setInheritance(ActiveRule.Inheritance.INHERITED.name())
-      .setSeverity(Severity.BLOCKER);
-    db.activeRuleDao().insert(dbSession, activeRule);
-
-    ActiveRuleParamDto activeRuleMinParam = ActiveRuleParamDto.createFor(minParam)
-      .setValue("minimum");
-    db.activeRuleDao().insertParam(dbSession, activeRule, activeRuleMinParam);
-
-    ActiveRuleParamDto activeRuleMaxParam = ActiveRuleParamDto.createFor(maxParam)
-      .setValue("maximum");
-    db.activeRuleDao().insertParam(dbSession, activeRule, activeRuleMaxParam);
-
-    dbSession.commit();
-
-    // verify db
-    List<ActiveRuleParamDto> persistedDtos = db.activeRuleDao().selectParamsByActiveRuleKey(dbSession, activeRule.getKey());
-    assertThat(persistedDtos).hasSize(2);
-
-    // verify es
-    ActiveRule rule = index.get(ActiveRuleIndex.class).getByKey(activeRule.getKey());
-    assertThat(rule).isNotNull();
-    assertThat(rule.params()).hasSize(2);
-    assertThat(rule.params().keySet()).containsOnly("min", "max");
-    assertThat(rule.params().values()).containsOnly("minimum", "maximum");
-    assertThat(rule.params().get("min")).isEqualTo("minimum");
-  }
-
-  @Test
-  public void find_active_rules() {
-    QualityProfileDto profile1 = QProfileTesting.newXooP1();
-    QualityProfileDto profile2 = QProfileTesting.newXooP2();
-    db.qualityProfileDao().insert(dbSession, profile1, profile2);
-
-    RuleDto rule1 = RuleTesting.newXooX1().setSeverity(Severity.MAJOR);
-    RuleDto rule2 = RuleTesting.newXooX2().setSeverity(Severity.MAJOR);
-    RuleDto removedRule = RuleTesting.newDto(RuleKey.of("xoo", "removed")).setSeverity(Severity.MAJOR).setStatus(RuleStatus.REMOVED);
-    db.deprecatedRuleDao().insert(dbSession, rule1, rule2, removedRule);
-
-    db.activeRuleDao().insert(dbSession, ActiveRuleDto.createFor(profile1, rule1).setSeverity(Severity.MINOR));
-    db.activeRuleDao().insert(dbSession, ActiveRuleDto.createFor(profile1, rule2).setSeverity(Severity.BLOCKER));
-    db.activeRuleDao().insert(dbSession, ActiveRuleDto.createFor(profile2, rule2).setSeverity(Severity.CRITICAL));
-    // Removed rule can still be activated for instance when removing the checkstyle plugin, active rules related on checkstyle are not
-    // removed
-    // because if the plugin is re-install, quality profiles using these rule are not changed.
-    db.activeRuleDao().insert(dbSession, ActiveRuleDto.createFor(profile2, removedRule).setSeverity(Severity.MAJOR));
-    dbSession.commit();
-
-    // 1. find by rule key
-
-    // in db
-    dbSession.clearCache();
-    assertThat(db.activeRuleDao().selectByRule(dbSession, rule1)).hasSize(1);
-    assertThat(db.activeRuleDao().selectByRule(dbSession, rule2)).hasSize(2);
-
-    // in es
-    List<ActiveRule> activeRules = index.get(ActiveRuleIndex.class).findByRule(RuleTesting.XOO_X1);
-    assertThat(activeRules).hasSize(1);
-    assertThat(activeRules.get(0).key().ruleKey()).isEqualTo(RuleTesting.XOO_X1);
-
-    activeRules = index.get(ActiveRuleIndex.class).findByRule(RuleTesting.XOO_X2);
-    assertThat(activeRules).hasSize(2);
-    assertThat(activeRules.get(0).key().ruleKey()).isEqualTo(RuleTesting.XOO_X2);
-
-    activeRules = index.get(ActiveRuleIndex.class).findByRule(RuleTesting.XOO_X3);
-    assertThat(activeRules).isEmpty();
-
-    // 2. find by profile
-    activeRules = Lists.newArrayList(index.get(ActiveRuleIndex.class).findByProfile(profile1.getKey()));
-    assertThat(activeRules).hasSize(2);
-    assertThat(activeRules.get(0).key().qProfile()).isEqualTo(profile1.getKey());
-    assertThat(activeRules.get(1).key().qProfile()).isEqualTo(profile1.getKey());
-
-    activeRules = Lists.newArrayList(index.get(ActiveRuleIndex.class).findByProfile(profile2.getKey()));
-    assertThat(activeRules).hasSize(1);
-    assertThat(activeRules.get(0).key().qProfile()).isEqualTo(profile2.getKey());
-
-    activeRules = Lists.newArrayList(index.get(ActiveRuleIndex.class).findByProfile("unknown"));
-    assertThat(activeRules).isEmpty();
-  }
-
-  @Test
-  public void find_many_active_rules_by_profile() {
-    // insert and index
-    QualityProfileDto profileDto = QProfileTesting.newXooP1();
-    db.qualityProfileDao().insert(dbSession, profileDto);
-    int nb = 100;
-    for (int i = 0; i < nb; i++) {
-      RuleDto rule = newRuleDto(RuleKey.of("xoo", "S00" + i));
-      db.deprecatedRuleDao().insert(dbSession, rule);
-
-      ActiveRuleDto activeRule = ActiveRuleDto.createFor(profileDto, rule).setSeverity(Severity.MAJOR);
-      db.activeRuleDao().insert(dbSession, activeRule);
-    }
-    dbSession.commit();
-    dbSession.clearCache();
-
-    // verify index
-    Collection<ActiveRule> activeRules = Lists.newArrayList(index.get(ActiveRuleIndex.class).findByProfile(profileDto.getKey()));
-    assertThat(activeRules).hasSize(nb);
-  }
-
-  @Test
-  public void count_by_profile() {
-    QualityProfileDto profileDto1 = QProfileTesting.newXooP1();
-    QualityProfileDto profileDto2 = QProfileTesting.newXooP2();
-    db.qualityProfileDao().insert(dbSession, profileDto1, profileDto2);
-
-    RuleKey ruleKey = RuleTesting.XOO_X1;
-    RuleDto ruleDto = newRuleDto(ruleKey);
-    db.deprecatedRuleDao().insert(dbSession, ruleDto);
-
-    ActiveRuleDto activeRule1 = ActiveRuleDto.createFor(profileDto1, ruleDto).setSeverity(Severity.MAJOR);
-    ActiveRuleDto activeRule2 = ActiveRuleDto.createFor(profileDto2, ruleDto).setSeverity(Severity.MAJOR);
-    db.activeRuleDao().insert(dbSession, activeRule1, activeRule2);
-    dbSession.commit();
-
-    // 0. Test base case
-    assertThat(index.get(ActiveRuleIndex.class).countAll()).isEqualTo(2);
-
-    // 1. Assert by profileKey
-    assertThat(index.get(ActiveRuleIndex.class).countByQualityProfileKey(profileDto1.getKey())).isEqualTo(1);
-
-    // 2. Assert by term aggregation;
-    Map<String, Long> counts = index.get(ActiveRuleIndex.class).countByField(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY);
-    assertThat(counts).hasSize(2);
-    assertThat(counts.values()).containsOnly(1L, 1L);
-    assertThat(counts.keySet()).containsOnly(profileDto1.getKey().toString(), profileDto2.getKey().toString());
-  }
-
-  @Test
-  public void count_all_by_index_field() {
-    QualityProfileDto profileDto1 = QProfileTesting.newXooP1();
-    QualityProfileDto profileDto2 = QProfileTesting.newXooP2();
-    db.qualityProfileDao().insert(dbSession, profileDto1, profileDto2);
-
-    RuleKey ruleKey = RuleTesting.XOO_X1;
-    RuleDto ruleDto = newRuleDto(ruleKey);
-    db.deprecatedRuleDao().insert(dbSession, ruleDto);
-
-    ActiveRuleDto activeRule1 = ActiveRuleDto.createFor(profileDto1, ruleDto).setSeverity(Severity.MAJOR);
-    ActiveRuleDto activeRule2 = ActiveRuleDto.createFor(profileDto2, ruleDto).setSeverity(Severity.MAJOR);
-    db.activeRuleDao().insert(dbSession, activeRule1, activeRule2);
-    dbSession.commit();
-
-    // 0. Test base case
-    assertThat(index.get(ActiveRuleIndex.class).countAll()).isEqualTo(2);
-
-    // 1. Assert by term aggregation;
-    Map<String, Long> counts = index.get(ActiveRuleIndex.class).countByField(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY);
-    assertThat(counts).hasSize(2);
-    assertThat(counts.values()).containsOnly(1L, 1L);
-    assertThat(counts.keySet()).containsOnly(profileDto1.getKey(), profileDto2.getKey());
-  }
-
-  @Test
-  public void stats_for_all() {
-    QualityProfileDto profileDto1 = QProfileTesting.newXooP1();
-    QualityProfileDto profileDto2 = QProfileTesting.newXooP2();
-    db.qualityProfileDao().insert(dbSession, profileDto1, profileDto2);
-
-    RuleDto ruleDto1 = newRuleDto(RuleTesting.XOO_X1);
-    RuleDto ruleDto2 = newRuleDto(RuleTesting.XOO_X2);
-    db.deprecatedRuleDao().insert(dbSession, ruleDto1, ruleDto2);
-
-    db.activeRuleDao().insert(dbSession,
-      ActiveRuleDto.createFor(profileDto1, ruleDto1)
-        .setInheritance(ActiveRule.Inheritance.INHERITED.name())
-        .setSeverity(Severity.BLOCKER),
-      ActiveRuleDto.createFor(profileDto2, ruleDto1)
-        .setInheritance(ActiveRule.Inheritance.INHERITED.name())
-        .setSeverity(Severity.MINOR),
-      ActiveRuleDto.createFor(profileDto1, ruleDto2)
-        .setInheritance(ActiveRule.Inheritance.OVERRIDES.name())
-        .setSeverity(Severity.MAJOR),
-      ActiveRuleDto.createFor(profileDto2, ruleDto2)
-        .setInheritance(ActiveRule.Inheritance.INHERITED.name())
-        .setSeverity(Severity.BLOCKER));
-    dbSession.commit();
-    dbSession.clearCache();
-
-    // 0. Test base case
-    assertThat(index.get(ActiveRuleIndex.class).countAll()).isEqualTo(4);
-
-    // 1. Assert by term aggregation;
-    Map<String, Multimap<String, FacetValue>> stats = index.get(ActiveRuleIndex.class).getStatsByProfileKeys(
-      ImmutableList.of(profileDto1.getKey(),
-        profileDto2.getKey()));
-
-    assertThat(stats).hasSize(2);
-  }
-
-  /**
-   * SONAR-5844
-   */
-  @Test
-  public void stats_for_all_with_lof_of_profiles() {
-    RuleDto ruleDto1 = newRuleDto(RuleTesting.XOO_X1);
-    RuleDto ruleDto2 = newRuleDto(RuleTesting.XOO_X2);
-    db.deprecatedRuleDao().insert(dbSession, ruleDto1, ruleDto2);
-
-    List<String> profileKeys = newArrayList();
-    for (int i = 0; i < 30; i++) {
-      QualityProfileDto profileDto = QProfileTesting.newQProfileDto(QProfileName.createFor("xoo", "profile-" + i), "profile-" + i);
-      profileKeys.add(profileDto.getKey());
-      db.qualityProfileDao().insert(dbSession, profileDto);
-
-      db.activeRuleDao().insert(dbSession,
-        ActiveRuleDto.createFor(profileDto, ruleDto1)
-          .setSeverity(Severity.BLOCKER),
-        ActiveRuleDto.createFor(profileDto, ruleDto2)
-          .setSeverity(Severity.MAJOR));
-    }
-    dbSession.commit();
-    dbSession.clearCache();
-
-    Map<String, Multimap<String, FacetValue>> stats = index.get(ActiveRuleIndex.class).getStatsByProfileKeys(profileKeys);
-    assertThat(stats).hasSize(30);
-  }
-
-  private RuleDto newRuleDto(RuleKey ruleKey) {
-    return new RuleDto()
-      .setRuleKey(ruleKey.rule())
-      .setRepositoryKey(ruleKey.repository())
-      .setName("Rule " + ruleKey.rule())
-      .setDescription("Description " + ruleKey.rule())
-      .setStatus(RuleStatus.READY)
-      .setConfigKey("InternalKey" + ruleKey.rule())
-      .setSeverity(Severity.INFO)
-      .setIsTemplate(false)
-      .setLanguage("js")
-      .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString())
-      .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString())
-      .setRemediationCoefficient("1h")
-      .setDefaultRemediationCoefficient("5d")
-      .setRemediationOffset("5min")
-      .setDefaultRemediationOffset("10h")
-      .setEffortToFixDescription(ruleKey.repository() + "." + ruleKey.rule() + ".effortToFix");
-  }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ActiveRuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ActiveRuleTest.java
new file mode 100644 (file)
index 0000000..b7932c1
--- /dev/null
@@ -0,0 +1,526 @@
+/*
+ * 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;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.RuleStatus;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.server.debt.DebtRemediationFunction;
+import org.sonar.db.DbSession;
+import org.sonar.db.qualityprofile.ActiveRuleDto;
+import org.sonar.db.qualityprofile.ActiveRuleParamDto;
+import org.sonar.db.qualityprofile.QualityProfileDto;
+import org.sonar.db.rule.RuleDto;
+import org.sonar.db.rule.RuleParamDto;
+import org.sonar.db.rule.RuleTesting;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.platform.Platform;
+import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
+import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer;
+import org.sonar.server.rule.db.RuleDao;
+import org.sonar.server.search.FacetValue;
+import org.sonar.server.search.IndexClient;
+import org.sonar.server.tester.ServerTester;
+import org.sonar.server.tester.UserSessionRule;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ActiveRuleTest {
+
+  @ClassRule
+  public static ServerTester tester = new ServerTester();
+
+  @Rule
+  public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester);
+
+  DbClient db;
+  RuleDao dao;
+  IndexClient index;
+  DbSession dbSession;
+
+  @Before
+  public void before() {
+    dao = tester.get(RuleDao.class);
+    tester.clearDbAndIndexes();
+    db = tester.get(DbClient.class);
+    index = tester.get(IndexClient.class);
+    dbSession = tester.get(DbClient.class).openSession(false);
+  }
+
+  @After
+  public void after() {
+    if (dbSession != null) {
+      dbSession.close();
+    }
+  }
+
+  @Test
+  public void synchronize_index() {
+    Date beginning = new Date();
+
+    QualityProfileDto profile1 = QProfileTesting.newXooP1();
+    db.qualityProfileDao().insert(dbSession, profile1);
+
+    RuleDto rule1 = RuleDto.createFor(RuleTesting.XOO_X1).setSeverity(Severity.MAJOR);
+    db.deprecatedRuleDao().insert(dbSession, rule1);
+
+    ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile1, rule1).setSeverity("BLOCKER");
+    db.activeRuleDao().insert(dbSession, activeRule);
+    dbSession.commit();
+
+    // 1. Synchronize since 0
+    tester.clearIndexes();
+    assertThat(index.get(ActiveRuleIndex.class).getNullableByKey(activeRule.getKey())).isNull();
+    db.activeRuleDao().synchronizeAfter(dbSession, new Date(0L));
+    dbSession.commit();
+    assertThat(index.get(ActiveRuleIndex.class).getNullableByKey(activeRule.getKey())).isNotNull();
+
+    // 2. Synchronize since beginning
+    tester.clearIndexes();
+    assertThat(index.get(ActiveRuleIndex.class).getNullableByKey(activeRule.getKey())).isNull();
+    db.activeRuleDao().synchronizeAfter(dbSession, beginning);
+    dbSession.commit();
+    assertThat(index.get(ActiveRuleIndex.class).getNullableByKey(activeRule.getKey())).isNotNull();
+
+    // 3. Assert startup picks it up
+    tester.clearIndexes();
+    assertThat(index.get(ActiveRuleIndex.class).getLastSynchronization()).isNull();
+    tester.get(Platform.class).executeStartupTasks();
+    assertThat(index.get(ActiveRuleIndex.class).getNullableByKey(activeRule.getKey())).isNotNull();
+    assertThat(index.get(ActiveRuleIndex.class).getLastSynchronization()).isNotNull();
+  }
+
+  /**
+   * SONAR-6540
+   */
+  @Test
+  public void active_rule_linked_to_not_existing_rule_should_be_ignored() throws SQLException {
+    QualityProfileDto profile = QProfileTesting.newXooP1();
+    db.qualityProfileDao().insert(dbSession, profile);
+
+    RuleDto rule = RuleDto.createFor(RuleTesting.XOO_X1).setSeverity(Severity.MAJOR);
+    db.deprecatedRuleDao().insert(dbSession, rule);
+
+    ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule).setSeverity("BLOCKER");
+    db.activeRuleDao().insert(dbSession, activeRule);
+    dbSession.commit();
+
+    // Remove rule -> Active rule is now linked to a not existing rule
+    executeSql(String.format("DELETE FROM rules WHERE id=%s", rule.getId()));
+    dbSession.commit();
+
+    // Synchronize index from start
+    tester.clearIndexes();
+    db.activeRuleDao().synchronizeAfter(dbSession, new Date(0L));
+    dbSession.commit();
+
+    // Active does not exist in the index
+    assertThat(index.get(ActiveRuleIndex.class).getNullableByKey(activeRule.getKey())).isNull();
+  }
+
+  /**
+   * SONAR-6540
+   */
+  @Test
+  public void active_rule_linked_to_not_existing_profile_should_be_ignored() throws SQLException {
+    QualityProfileDto profile = QProfileTesting.newXooP1();
+    db.qualityProfileDao().insert(dbSession, profile);
+
+    RuleDto rule = RuleDto.createFor(RuleTesting.XOO_X1).setSeverity(Severity.MAJOR);
+    db.deprecatedRuleDao().insert(dbSession, rule);
+
+    ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule).setSeverity("BLOCKER");
+    db.activeRuleDao().insert(dbSession, activeRule);
+    dbSession.commit();
+
+    // Remove quality profile -> active rule is now linked to a not existing quality profile
+    executeSql(String.format("DELETE FROM rules_profiles WHERE id=%s", profile.getId()));
+    dbSession.commit();
+
+    // Synchronize index from start
+    tester.clearIndexes();
+    db.activeRuleDao().synchronizeAfter(dbSession, new Date(0L));
+    dbSession.commit();
+
+    // Active does not exist in the index
+    assertThat(index.get(ActiveRuleIndex.class).getNullableByKey(activeRule.getKey())).isNull();
+  }
+
+  @Test
+  public void insert_and_index_active_rule() {
+    QualityProfileDto profileDto = QProfileTesting.newXooP1();
+    db.qualityProfileDao().insert(dbSession, profileDto);
+    RuleKey ruleKey = RuleTesting.XOO_X1;
+    RuleDto ruleDto = newRuleDto(ruleKey);
+    db.deprecatedRuleDao().insert(dbSession, ruleDto);
+
+    ActiveRuleDto activeRule = ActiveRuleDto.createFor(profileDto, ruleDto)
+      .setInheritance(ActiveRule.Inheritance.INHERITED.name())
+      .setSeverity(Severity.BLOCKER);
+    db.activeRuleDao().insert(dbSession, activeRule);
+    dbSession.commit();
+
+    // verify db
+    assertThat(db.activeRuleDao().getByKey(dbSession, activeRule.getKey())).isNotNull();
+    List<ActiveRuleDto> persistedDtos = db.activeRuleDao().selectByRule(dbSession, ruleDto);
+    assertThat(persistedDtos).hasSize(1);
+
+    // verify es
+    ActiveRule hit = index.get(ActiveRuleIndex.class).getByKey(activeRule.getKey());
+    assertThat(hit).isNotNull();
+    assertThat(hit.key()).isEqualTo(activeRule.getKey());
+    assertThat(hit.inheritance().name()).isEqualTo(activeRule.getInheritance());
+    assertThat(hit.parentKey()).isNull();
+    assertThat(hit.severity()).isEqualTo(activeRule.getSeverityString());
+  }
+
+  @Test
+  public void insert_and_index_active_rule_param() {
+    // insert and index
+    QualityProfileDto profileDto = QProfileTesting.newXooP1();
+    db.qualityProfileDao().insert(dbSession, profileDto);
+    RuleKey ruleKey = RuleTesting.XOO_X1;
+    RuleDto ruleDto = newRuleDto(ruleKey);
+    db.deprecatedRuleDao().insert(dbSession, ruleDto);
+
+    RuleParamDto minParam = new RuleParamDto()
+      .setName("min")
+      .setType("STRING");
+    db.deprecatedRuleDao().insertRuleParam(dbSession, ruleDto, minParam);
+
+    RuleParamDto maxParam = new RuleParamDto()
+      .setName("max")
+      .setType("STRING");
+    db.deprecatedRuleDao().insertRuleParam(dbSession, ruleDto, maxParam);
+
+    ActiveRuleDto activeRule = ActiveRuleDto.createFor(profileDto, ruleDto)
+      .setInheritance(ActiveRule.Inheritance.INHERITED.name())
+      .setSeverity(Severity.BLOCKER);
+    db.activeRuleDao().insert(dbSession, activeRule);
+
+    ActiveRuleParamDto activeRuleMinParam = ActiveRuleParamDto.createFor(minParam)
+      .setValue("minimum");
+    db.activeRuleDao().insertParam(dbSession, activeRule, activeRuleMinParam);
+
+    ActiveRuleParamDto activeRuleMaxParam = ActiveRuleParamDto.createFor(maxParam)
+      .setValue("maximum");
+    db.activeRuleDao().insertParam(dbSession, activeRule, activeRuleMaxParam);
+
+    dbSession.commit();
+
+    // verify db
+    List<ActiveRuleParamDto> persistedDtos = db.activeRuleDao().selectParamsByActiveRuleKey(dbSession, activeRule.getKey());
+    assertThat(persistedDtos).hasSize(2);
+
+    // verify es
+    ActiveRule rule = index.get(ActiveRuleIndex.class).getByKey(activeRule.getKey());
+    assertThat(rule).isNotNull();
+    assertThat(rule.params()).hasSize(2);
+    assertThat(rule.params().keySet()).containsOnly("min", "max");
+    assertThat(rule.params().values()).containsOnly("minimum", "maximum");
+    assertThat(rule.params().get("min")).isEqualTo("minimum");
+  }
+
+  @Test
+  public void find_active_rules() {
+    QualityProfileDto profile1 = QProfileTesting.newXooP1();
+    QualityProfileDto profile2 = QProfileTesting.newXooP2();
+    db.qualityProfileDao().insert(dbSession, profile1, profile2);
+
+    RuleDto rule1 = RuleTesting.newXooX1().setSeverity(Severity.MAJOR);
+    RuleDto rule2 = RuleTesting.newXooX2().setSeverity(Severity.MAJOR);
+    RuleDto removedRule = RuleTesting.newDto(RuleKey.of("xoo", "removed")).setSeverity(Severity.MAJOR).setStatus(RuleStatus.REMOVED);
+    db.deprecatedRuleDao().insert(dbSession, rule1, rule2, removedRule);
+
+    db.activeRuleDao().insert(dbSession, ActiveRuleDto.createFor(profile1, rule1).setSeverity(Severity.MINOR));
+    db.activeRuleDao().insert(dbSession, ActiveRuleDto.createFor(profile1, rule2).setSeverity(Severity.BLOCKER));
+    db.activeRuleDao().insert(dbSession, ActiveRuleDto.createFor(profile2, rule2).setSeverity(Severity.CRITICAL));
+    // Removed rule can still be activated for instance when removing the checkstyle plugin, active rules related on checkstyle are not
+    // removed
+    // because if the plugin is re-install, quality profiles using these rule are not changed.
+    db.activeRuleDao().insert(dbSession, ActiveRuleDto.createFor(profile2, removedRule).setSeverity(Severity.MAJOR));
+    dbSession.commit();
+
+    // 1. find by rule key
+
+    // in db
+    dbSession.clearCache();
+    assertThat(db.activeRuleDao().selectByRule(dbSession, rule1)).hasSize(1);
+    assertThat(db.activeRuleDao().selectByRule(dbSession, rule2)).hasSize(2);
+
+    // in es
+    List<ActiveRule> activeRules = index.get(ActiveRuleIndex.class).findByRule(RuleTesting.XOO_X1);
+    assertThat(activeRules).hasSize(1);
+    assertThat(activeRules.get(0).key().ruleKey()).isEqualTo(RuleTesting.XOO_X1);
+
+    activeRules = index.get(ActiveRuleIndex.class).findByRule(RuleTesting.XOO_X2);
+    assertThat(activeRules).hasSize(2);
+    assertThat(activeRules.get(0).key().ruleKey()).isEqualTo(RuleTesting.XOO_X2);
+
+    activeRules = index.get(ActiveRuleIndex.class).findByRule(RuleTesting.XOO_X3);
+    assertThat(activeRules).isEmpty();
+
+    // 2. find by profile
+    activeRules = Lists.newArrayList(index.get(ActiveRuleIndex.class).findByProfile(profile1.getKey()));
+    assertThat(activeRules).hasSize(2);
+    assertThat(activeRules.get(0).key().qProfile()).isEqualTo(profile1.getKey());
+    assertThat(activeRules.get(1).key().qProfile()).isEqualTo(profile1.getKey());
+
+    activeRules = Lists.newArrayList(index.get(ActiveRuleIndex.class).findByProfile(profile2.getKey()));
+    assertThat(activeRules).hasSize(1);
+    assertThat(activeRules.get(0).key().qProfile()).isEqualTo(profile2.getKey());
+
+    activeRules = Lists.newArrayList(index.get(ActiveRuleIndex.class).findByProfile("unknown"));
+    assertThat(activeRules).isEmpty();
+  }
+
+  @Test
+  public void find_many_active_rules_by_profile() {
+    // insert and index
+    QualityProfileDto profileDto = QProfileTesting.newXooP1();
+    db.qualityProfileDao().insert(dbSession, profileDto);
+    int nb = 100;
+    for (int i = 0; i < nb; i++) {
+      RuleDto rule = newRuleDto(RuleKey.of("xoo", "S00" + i));
+      db.deprecatedRuleDao().insert(dbSession, rule);
+
+      ActiveRuleDto activeRule = ActiveRuleDto.createFor(profileDto, rule).setSeverity(Severity.MAJOR);
+      db.activeRuleDao().insert(dbSession, activeRule);
+    }
+    dbSession.commit();
+    dbSession.clearCache();
+
+    // verify index
+    Collection<ActiveRule> activeRules = Lists.newArrayList(index.get(ActiveRuleIndex.class).findByProfile(profileDto.getKey()));
+    assertThat(activeRules).hasSize(nb);
+  }
+
+  @Test
+  public void count_by_profile() {
+    QualityProfileDto profileDto1 = QProfileTesting.newXooP1();
+    QualityProfileDto profileDto2 = QProfileTesting.newXooP2();
+    db.qualityProfileDao().insert(dbSession, profileDto1, profileDto2);
+
+    RuleKey ruleKey = RuleTesting.XOO_X1;
+    RuleDto ruleDto = newRuleDto(ruleKey);
+    db.deprecatedRuleDao().insert(dbSession, ruleDto);
+
+    ActiveRuleDto activeRule1 = ActiveRuleDto.createFor(profileDto1, ruleDto).setSeverity(Severity.MAJOR);
+    ActiveRuleDto activeRule2 = ActiveRuleDto.createFor(profileDto2, ruleDto).setSeverity(Severity.MAJOR);
+    db.activeRuleDao().insert(dbSession, activeRule1, activeRule2);
+    dbSession.commit();
+
+    // 0. Test base case
+    assertThat(index.get(ActiveRuleIndex.class).countAll()).isEqualTo(2);
+
+    // 1. Assert by profileKey
+    assertThat(index.get(ActiveRuleIndex.class).countByQualityProfileKey(profileDto1.getKey())).isEqualTo(1);
+
+    // 2. Assert by term aggregation;
+    Map<String, Long> counts = index.get(ActiveRuleIndex.class).countByField(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY);
+    assertThat(counts).hasSize(2);
+    assertThat(counts.values()).containsOnly(1L, 1L);
+    assertThat(counts.keySet()).containsOnly(profileDto1.getKey().toString(), profileDto2.getKey().toString());
+  }
+
+  @Test
+  public void count_all_by_index_field() {
+    QualityProfileDto profileDto1 = QProfileTesting.newXooP1();
+    QualityProfileDto profileDto2 = QProfileTesting.newXooP2();
+    db.qualityProfileDao().insert(dbSession, profileDto1, profileDto2);
+
+    RuleKey ruleKey = RuleTesting.XOO_X1;
+    RuleDto ruleDto = newRuleDto(ruleKey);
+    db.deprecatedRuleDao().insert(dbSession, ruleDto);
+
+    ActiveRuleDto activeRule1 = ActiveRuleDto.createFor(profileDto1, ruleDto).setSeverity(Severity.MAJOR);
+    ActiveRuleDto activeRule2 = ActiveRuleDto.createFor(profileDto2, ruleDto).setSeverity(Severity.MAJOR);
+    db.activeRuleDao().insert(dbSession, activeRule1, activeRule2);
+    dbSession.commit();
+
+    // 0. Test base case
+    assertThat(index.get(ActiveRuleIndex.class).countAll()).isEqualTo(2);
+
+    // 1. Assert by term aggregation;
+    Map<String, Long> counts = index.get(ActiveRuleIndex.class).countByField(ActiveRuleNormalizer.ActiveRuleField.PROFILE_KEY);
+    assertThat(counts).hasSize(2);
+    assertThat(counts.values()).containsOnly(1L, 1L);
+    assertThat(counts.keySet()).containsOnly(profileDto1.getKey(), profileDto2.getKey());
+  }
+
+  @Test
+  public void stats_for_all() {
+    QualityProfileDto profileDto1 = QProfileTesting.newXooP1();
+    QualityProfileDto profileDto2 = QProfileTesting.newXooP2();
+    db.qualityProfileDao().insert(dbSession, profileDto1, profileDto2);
+
+    RuleDto ruleDto1 = newRuleDto(RuleTesting.XOO_X1);
+    RuleDto ruleDto2 = newRuleDto(RuleTesting.XOO_X2);
+    db.deprecatedRuleDao().insert(dbSession, ruleDto1, ruleDto2);
+
+    db.activeRuleDao().insert(dbSession,
+      ActiveRuleDto.createFor(profileDto1, ruleDto1)
+        .setInheritance(ActiveRule.Inheritance.INHERITED.name())
+        .setSeverity(Severity.BLOCKER),
+      ActiveRuleDto.createFor(profileDto2, ruleDto1)
+        .setInheritance(ActiveRule.Inheritance.INHERITED.name())
+        .setSeverity(Severity.MINOR),
+      ActiveRuleDto.createFor(profileDto1, ruleDto2)
+        .setInheritance(ActiveRule.Inheritance.OVERRIDES.name())
+        .setSeverity(Severity.MAJOR),
+      ActiveRuleDto.createFor(profileDto2, ruleDto2)
+        .setInheritance(ActiveRule.Inheritance.INHERITED.name())
+        .setSeverity(Severity.BLOCKER));
+    dbSession.commit();
+    dbSession.clearCache();
+
+    // 0. Test base case
+    assertThat(index.get(ActiveRuleIndex.class).countAll()).isEqualTo(4);
+
+    // 1. Assert by term aggregation;
+    Map<String, Multimap<String, FacetValue>> stats = index.get(ActiveRuleIndex.class).getStatsByProfileKeys(
+      ImmutableList.of(profileDto1.getKey(),
+        profileDto2.getKey()));
+
+    assertThat(stats).hasSize(2);
+  }
+
+  /**
+   * SONAR-5844
+   */
+  @Test
+  public void stats_for_all_with_lof_of_profiles() {
+    RuleDto ruleDto1 = newRuleDto(RuleTesting.XOO_X1);
+    RuleDto ruleDto2 = newRuleDto(RuleTesting.XOO_X2);
+    db.deprecatedRuleDao().insert(dbSession, ruleDto1, ruleDto2);
+
+    List<String> profileKeys = newArrayList();
+    for (int i = 0; i < 30; i++) {
+      QualityProfileDto profileDto = QProfileTesting.newQProfileDto(QProfileName.createFor("xoo", "profile-" + i), "profile-" + i);
+      profileKeys.add(profileDto.getKey());
+      db.qualityProfileDao().insert(dbSession, profileDto);
+
+      db.activeRuleDao().insert(dbSession,
+        ActiveRuleDto.createFor(profileDto, ruleDto1)
+          .setSeverity(Severity.BLOCKER),
+        ActiveRuleDto.createFor(profileDto, ruleDto2)
+          .setSeverity(Severity.MAJOR));
+    }
+    dbSession.commit();
+    dbSession.clearCache();
+
+    Map<String, Multimap<String, FacetValue>> stats = index.get(ActiveRuleIndex.class).getStatsByProfileKeys(profileKeys);
+    assertThat(stats).hasSize(30);
+  }
+
+  @Test
+  public void select_by_id() throws Exception {
+    QualityProfileDto profile = QProfileTesting.newXooP1();
+    db.qualityProfileDao().insert(dbSession, profile);
+
+    RuleDto rule = RuleDto.createFor(RuleTesting.XOO_X1).setSeverity(Severity.MAJOR);
+    db.deprecatedRuleDao().insert(dbSession, rule);
+
+    ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule).setSeverity("BLOCKER");
+    db.activeRuleDao().insert(dbSession, activeRule);
+    dbSession.commit();
+
+    assertThat(db.activeRuleDao().selectById(dbSession, activeRule.getId()).getId()).isEqualTo(activeRule.getId());
+  }
+
+  @Test
+  public void select_by_id_return_nothing_when_rule_does_not_exist() throws Exception {
+    QualityProfileDto profile = QProfileTesting.newXooP1();
+    db.qualityProfileDao().insert(dbSession, profile);
+
+    RuleDto rule = RuleDto.createFor(RuleTesting.XOO_X1).setSeverity(Severity.MAJOR);
+    db.deprecatedRuleDao().insert(dbSession, rule);
+
+    ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule).setSeverity("BLOCKER");
+    db.activeRuleDao().insert(dbSession, activeRule);
+    dbSession.commit();
+
+    // Remove rule -> Active rule is now linked to a not existing rule
+    executeSql(String.format("DELETE FROM rules WHERE id=%s", rule.getId()));
+    dbSession.commit();
+
+    assertThat(db.activeRuleDao().selectById(dbSession, activeRule.getId())).isNull();
+  }
+
+  @Test
+  public void select_by_id_return_nothing_when_profile_does_not_exist() throws Exception {
+    QualityProfileDto profile = QProfileTesting.newXooP1();
+    db.qualityProfileDao().insert(dbSession, profile);
+
+    RuleDto rule = RuleDto.createFor(RuleTesting.XOO_X1).setSeverity(Severity.MAJOR);
+    db.deprecatedRuleDao().insert(dbSession, rule);
+
+    ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule).setSeverity("BLOCKER");
+    db.activeRuleDao().insert(dbSession, activeRule);
+    dbSession.commit();
+
+    // Remove quality profile -> active rule is now linked to a not existing quality profile
+    executeSql(String.format("DELETE FROM rules_profiles WHERE id=%s", profile.getId()));
+    dbSession.commit();
+
+    assertThat(db.activeRuleDao().selectById(dbSession, activeRule.getId())).isNull();
+  }
+
+  private RuleDto newRuleDto(RuleKey ruleKey) {
+    return new RuleDto()
+      .setRuleKey(ruleKey.rule())
+      .setRepositoryKey(ruleKey.repository())
+      .setName("Rule " + ruleKey.rule())
+      .setDescription("Description " + ruleKey.rule())
+      .setStatus(RuleStatus.READY)
+      .setConfigKey("InternalKey" + ruleKey.rule())
+      .setSeverity(Severity.INFO)
+      .setIsTemplate(false)
+      .setLanguage("js")
+      .setRemediationFunction(DebtRemediationFunction.Type.LINEAR.toString())
+      .setDefaultRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET.toString())
+      .setRemediationCoefficient("1h")
+      .setDefaultRemediationCoefficient("5d")
+      .setRemediationOffset("5min")
+      .setDefaultRemediationOffset("10h")
+      .setEffortToFixDescription(ruleKey.repository() + "." + ruleKey.rule() + ".effortToFix");
+  }
+
+  private void executeSql(String sql) throws SQLException {
+    PreparedStatement stmt = db.getDatabase().getDataSource().getConnection().prepareStatement(sql);
+    stmt.executeUpdate();
+  }
+
+}
index 23ac091ce8ac2ff9d4c1c9355db24663b740568d..f9bf9b9c8f146e72716f351dd8a806cb942dde4b 100644 (file)
   </sql>
 
   <sql id="activeRuleKeyJoin">
-    LEFT JOIN rules_profiles qp ON qp.id=a.profile_id
-    LEFT JOIN rules r ON r.id = a.rule_id
+    INNER JOIN rules_profiles qp ON qp.id=a.profile_id
+    INNER JOIN rules r ON r.id = a.rule_id
   </sql>
 
-
   <sql id="activeRuleColumns">
     a.id,
     a.profile_id as profileId,
   </sql>
 
   <sql id="activeRuleJoin">
-    LEFT JOIN rules_profiles qp ON qp.id=a.profile_id
+    INNER JOIN rules_profiles qp ON qp.id=a.profile_id
     LEFT JOIN rules_profiles profile_parent ON profile_parent.kee=qp.parent_kee
-    LEFT JOIN active_rules active_rule_parent ON active_rule_parent.profile_id=profile_parent.id AND
-    a.rule_id=active_rule_parent.rule_id
+    LEFT JOIN active_rules active_rule_parent ON active_rule_parent.profile_id=profile_parent.id AND a.rule_id=active_rule_parent.rule_id
   </sql>
 
   <select id="selectAfterDate" parameterType="Date" resultType="ActiveRule"
@@ -92,7 +90,6 @@
     WHERE a.id=#{id}
   </select>
 
-
   <select id="selectByKey" parameterType="map" resultType="ActiveRule">
     SELECT
     <include refid="activeRuleKeyColumns"/>