]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4860 Remove deleted rules from index (removed rules are still kept)
authorJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Tue, 26 Nov 2013 14:08:08 +0000 (15:08 +0100)
committerJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Tue, 26 Nov 2013 14:08:08 +0000 (15:08 +0100)
sonar-server/src/main/java/org/sonar/server/rule/RuleRegistry.java
sonar-server/src/main/java/org/sonar/server/search/SearchIndex.java
sonar-server/src/test/java/org/sonar/server/rule/RuleRegistryTest.java

index 65c10b0820e78ebe2b07d8defae93ea383e4e197..66e6b3b6db47753e4ece88f4e4349d084e24dd7a 100644 (file)
@@ -38,10 +38,7 @@ import org.sonar.server.search.SearchIndex;
 import org.sonar.server.search.SearchQuery;
 
 import java.io.IOException;
-import java.util.Collection;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
+import java.util.*;
 
 /**
  * Fill search index with rules
@@ -156,6 +153,13 @@ public class RuleRegistry {
     profiler.start("Index rules");
     searchIndex.bulkIndex(INDEX_RULES, TYPE_RULE, ids, docs);
     profiler.stop();
+
+    List<String> indexIds = searchIndex.findDocumentIds(SearchQuery.create().index(INDEX_RULES).type(TYPE_RULE));
+    indexIds.removeAll(Arrays.asList(ids));
+    if (! indexIds.isEmpty()) {
+      profiler.start("Remove deleted rule documents");
+      searchIndex.bulkDelete(INDEX_RULES, TYPE_RULE, indexIds.toArray(new String[0]));
+    }
   }
 
   private XContentBuilder ruleDocument(RuleDto rule, Collection<RuleParamDto> params) throws IOException {
index 9f2774fa7e0c5f23979afb59f1d7dd8592f1c821..06f512da49952e7795f543744250a5517c015182 100644 (file)
@@ -189,10 +189,35 @@ public class SearchIndex {
     return result;
   }
 
+  public void bulkDelete(String index, String type, String[] ids) {
+    BulkRequestBuilder builder = new BulkRequestBuilder(client);
+    for (int i=0; i<ids.length; i++) {
+      builder.add(client.prepareDelete(index, type, ids[i]));
+    }
+    TimeProfiler profiler = newDebugProfiler();
+    try {
+      profiler.start(format("bulk delete of %d documents with type '%s' from index '%s'", ids.length, type, index));
+      BulkResponse bulkResponse = client.bulk(builder.setRefresh(true).request()).get();
+      if (bulkResponse.hasFailures()) {
+        for (BulkItemResponse bulkItemResponse : bulkResponse.getItems()) {
+          if(bulkItemResponse.isFailed()) {
+            int itemId = bulkItemResponse.getItemId();
+            client.prepareDelete(index, type, ids[itemId]).execute().actionGet();
+          }
+        }
+      }
+    } catch (InterruptedException e) {
+      LOG.error("Interrupted during bulk operation", e);
+    } catch (ExecutionException e) {
+      LOG.error("Execution of bulk operation failed", e);
+    } finally {
+      profiler.stop();
+    }
+  }
+
   private TimeProfiler newDebugProfiler() {
     TimeProfiler profiler = new TimeProfiler();
     profiler.setLogger(LOG);
     return profiler;
   }
-
 }
index 2b91b3e47704dd9509d0838265b168a389ec1435..1b59896c120e00da409f9571bdda731e7b245dad 100644 (file)
@@ -170,7 +170,25 @@ public class RuleRegistryTest {
   }
 
   @Test
-  public void should_throw_when_problem_on_index() {
+  public void should_update_existing_rules_and_forget_deleted_rules() {
+    long ruleId1 = 1L;
+    RuleDto rule1 = new RuleDto();
+    rule1.setRepositoryKey("xoo");
+    rule1.setRuleKey("key1");
+    rule1.setId(ruleId1);
+    long ruleId2 = 2L;
+    RuleDto rule2 = new RuleDto();
+    rule2.setRepositoryKey("xoo");
+    rule2.setRuleKey("key2");
+    rule2.setId(ruleId2);
+    rule2.setParentId(ruleId1);
+    List<RuleDto> rules = ImmutableList.of(rule1, rule2);
+
+    when(ruleDao.selectNonManual()).thenReturn(rules);
+    registry.bulkRegisterRules();
 
+    assertThat(registry.findIds(ImmutableMap.of("repositoryKey", "xoo")))
+      .hasSize(2)
+      .containsOnly((int) ruleId1, (int) ruleId2);
   }
 }