]> source.dussan.org Git - sonarqube.git/commitdiff
Refactor ES framework
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Wed, 29 Oct 2014 08:24:27 +0000 (09:24 +0100)
committerSimon Brandhof <simon.brandhof@sonarsource.com>
Wed, 29 Oct 2014 08:24:51 +0000 (09:24 +0100)
* do not limit facet values to integers, but use long
* distinguish integer, long and double field types
* remove unused sub-facets

13 files changed:
server/sonar-server/src/main/java/org/sonar/server/issue/InternalRubyIssueService.java
server/sonar-server/src/main/java/org/sonar/server/issue/IssueService.java
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueNormalizer.java
server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleNormalizer.java
server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleQuery.java
server/sonar-server/src/main/java/org/sonar/server/search/BaseIndex.java
server/sonar-server/src/main/java/org/sonar/server/search/FacetValue.java
server/sonar-server/src/main/java/org/sonar/server/search/IndexField.java
server/sonar-server/src/main/java/org/sonar/server/search/Indexable.java
server/sonar-server/src/main/java/org/sonar/server/search/Result.java
server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/rule/index/RuleIndexMediumTest.java

index 1513c8b2936e011d71724ba890f945bcd7234774..a686986824b5332571de69059dee50af8d8cf8a0 100644 (file)
@@ -111,7 +111,7 @@ public class InternalRubyIssueService implements ServerComponent {
     return issueService.getByKey(issueKey);
   }
 
-  public Map<String, Integer> findIssueAssignees(Map<String, Object> params) {
+  public Map<String, Long> findIssueAssignees(Map<String, Object> params) {
     return issueService.findIssueAssignees(issueQueryService.createFromMap(params));
   }
 
index e2100f8a6add15094d7e87af35777f1fc8d4a02c..efa6867f785ab473262dce7e104ec58bdaa8c378 100644 (file)
@@ -292,8 +292,8 @@ public class IssueService implements ServerComponent {
     return aggregation;
   }
 
-  public Map<String, Integer> findIssueAssignees(IssueQuery query) {
-    Map<String, Integer> result = newLinkedHashMap();
+  public Map<String, Long> findIssueAssignees(IssueQuery query) {
+    Map<String, Long> result = newLinkedHashMap();
     List<FacetValue> facetValues = indexClient.get(IssueIndex.class).listAssignees(query);
     for (FacetValue facetValue : facetValues) {
       if ("_notAssigned_".equals(facetValue.getKey())) {
index 86ef7d40b5cd9949d3cfde8d42b07fe14b7acbb3..0f96719f3b8cf172928d8968681e5539ade48cd3 100644 (file)
@@ -165,9 +165,9 @@ public class IssueIndex extends BaseIndex<Issue, IssueDto, String> {
     Terms aggregation = (Terms) response.getAggregations().getAsMap().get(IssueNormalizer.IssueField.ASSIGNEE.field());
     List<FacetValue> facetValues = newArrayList();
     for (Terms.Bucket value : aggregation.getBuckets()) {
-      facetValues.add(new FacetValue(value.getKey(), (int) value.getDocCount()));
+      facetValues.add(new FacetValue(value.getKey(), value.getDocCount()));
     }
-    facetValues.add(new FacetValue("_notAssigned_", (int) ((InternalMissing) response.getAggregations().get("notAssigned")).getDocCount()));
+    facetValues.add(new FacetValue("_notAssigned_", ((InternalMissing) response.getAggregations().get("notAssigned")).getDocCount()));
 
     return facetValues;
   }
@@ -390,19 +390,18 @@ public class IssueIndex extends BaseIndex<Issue, IssueDto, String> {
   }
 
   private void setSorting(IssueQuery query, SearchRequestBuilder esSearch) {
-    /* integrate Query Sort */
     String sortField = query.sort();
-    Boolean asc = query.asc();
     if (sortField != null) {
+      Boolean asc = query.asc();
       List<IndexField> fields = toIndexFields(sortField);
       for (IndexField field : fields) {
-        FieldSortBuilder sort = SortBuilders.fieldSort(field.sortField());
+        FieldSortBuilder sortBuilder = SortBuilders.fieldSort(field.sortField());
         if (asc != null && asc) {
-          sort.order(SortOrder.ASC);
+          sortBuilder.order(SortOrder.ASC);
         } else {
-          sort.order(SortOrder.DESC);
+          sortBuilder.order(SortOrder.DESC);
         }
-        esSearch.addSort(sort);
+        esSearch.addSort(sortBuilder);
       }
     } else {
       esSearch.addSort(IssueNormalizer.IssueField.ISSUE_UPDATED_AT.sortField(), SortOrder.DESC);
index 94407f6de5426a30a6af05dc6834a547a48d43db..777ba466f288682a2c8564acb215dc7bd3446e35 100644 (file)
@@ -58,18 +58,18 @@ public class IssueNormalizer extends BaseNormalizer<IssueDto, String> {
     public static final IndexField ASSIGNEE = addSortable(IndexField.Type.STRING, "assignee");
     public static final IndexField ATTRIBUTES = add(IndexField.Type.STRING, "attributes");
     public static final IndexField AUTHOR_LOGIN = add(IndexField.Type.STRING, "authorLogin");
-    public static final IndexField DEBT = add(IndexField.Type.NUMERIC, "debt");
-    public static final IndexField EFFORT = add(IndexField.Type.NUMERIC, "effort");
+    public static final IndexField DEBT = add(IndexField.Type.DOUBLE, "debt");
+    public static final IndexField EFFORT = add(IndexField.Type.DOUBLE, "effort");
     public static final IndexField ISSUE_CREATED_AT = addSortable(IndexField.Type.DATE, "issueCreatedAt");
     public static final IndexField ISSUE_UPDATED_AT = addSortable(IndexField.Type.DATE, "issueUpdatedAt");
     public static final IndexField ISSUE_CLOSE_DATE = addSortable(IndexField.Type.DATE, "issueClosedAt");
-    public static final IndexField LINE = addSortable(IndexField.Type.NUMERIC, "line");
+    public static final IndexField LINE = addSortable(IndexField.Type.INTEGER, "line");
     public static final IndexField MESSAGE = add(IndexField.Type.STRING, "message");
     public static final IndexField RESOLUTION = add(IndexField.Type.STRING, "resolution");
     public static final IndexField REPORTER = add(IndexField.Type.STRING, "reporter");
     public static final IndexField STATUS = addSortable(IndexField.Type.STRING, "status");
     public static final IndexField SEVERITY = add(IndexField.Type.STRING, "severity");
-    public static final IndexField SEVERITY_VALUE = addSortable(IndexField.Type.NUMERIC, "severityValue");
+    public static final IndexField SEVERITY_VALUE = addSortable(IndexField.Type.INTEGER, "severityValue");
     public static final IndexField LANGUAGE = add(IndexField.Type.STRING, "language");
     public static final IndexField RULE_KEY = add(IndexField.Type.STRING, "ruleKey");
     public static final IndexField FILE_PATH = addSortable(IndexField.Type.STRING, "filePath");
index 086a75fda7367407ab4f76ae20d1279cceaae331..54eae4488f725023c88eeddcb56607a348312b9f 100644 (file)
@@ -78,7 +78,7 @@ public class RuleNormalizer extends BaseNormalizer<RuleDto, RuleKey> {
      * SQALE console.
      */
     @Deprecated
-    public static final IndexField ID = addSortable(IndexField.Type.NUMERIC, "id");
+    public static final IndexField ID = addSortable(IndexField.Type.DOUBLE, "id");
 
     public static final IndexField KEY = addSortable(IndexField.Type.STRING, "key");
     public static final IndexField _KEY = add(IndexField.Type.STRING, "_key");
index ca8a14e6fe3055ecc3b7c6d25ed4962806175261..d7edab19ed645d2a33f0331064516ca9411f1092 100644 (file)
@@ -230,8 +230,8 @@ public class RuleQuery {
   }
 
   public RuleQuery setSortField(@Nullable IndexField sf) {
-    if (sf != null && !sf.sortable()) {
-      throw new IllegalStateException("Field '" + sf.field() + "' is not sortable!");
+    if (sf != null && !sf.isSortable()) {
+      throw new IllegalStateException(String.format("Field '%s' is not sortable", sf.field()));
     }
     this.sortField = sf;
     return this;
index 2cf2f6af745fa2cdc166d4f51422ce09be8688fc..a4dae1a5819e712d7cd62ba4ee83903b79030aba 100644 (file)
@@ -268,8 +268,12 @@ public abstract class BaseIndex<DOMAIN, DTO extends Dto<KEY>, KEY extends Serial
       return mapNestedField(field);
     } else if (field.type() == IndexField.Type.DATE) {
       return mapDateField(field);
-    } else if (field.type() == IndexField.Type.NUMERIC) {
-      return mapNumericField(field);
+    } else if (field.type() == IndexField.Type.DOUBLE) {
+      return mapDoubleField(field);
+    } else if (field.type() == IndexField.Type.INTEGER) {
+      return mapIntegerField(field);
+    } else if (field.type() == IndexField.Type.LONG) {
+      return mapLongField(field);
     } else if (field.type() == IndexField.Type.UUID_PATH) {
       return mapUuidPathField(field);
     } else {
@@ -284,10 +288,18 @@ public abstract class BaseIndex<DOMAIN, DTO extends Dto<KEY>, KEY extends Serial
       "analyzer", "uuid_analyzer");
   }
 
-  protected Map mapNumericField(IndexField field) {
+  protected Map mapDoubleField(IndexField field) {
     return ImmutableMap.of("type", "double");
   }
 
+  protected Map mapIntegerField(IndexField field) {
+    return ImmutableMap.of("type", "integer");
+  }
+
+  protected Map mapLongField(IndexField field) {
+    return ImmutableMap.of("type", "long");
+  }
+
   protected Map mapBooleanField(IndexField field) {
     return ImmutableMap.of("type", "boolean");
   }
@@ -315,14 +327,7 @@ public abstract class BaseIndex<DOMAIN, DTO extends Dto<KEY>, KEY extends Serial
   protected boolean needMultiField(IndexField field) {
     return (field.type() == IndexField.Type.TEXT
       || field.type() == IndexField.Type.STRING)
-      && (field.sortable() || field.searchable());
-  }
-
-  protected Map mapSortField(IndexField field) {
-    return ImmutableMap.of(
-      "type", "string",
-      "index", "analyzed",
-      "analyzer", "sortable");
+      && (field.isSortable() || field.isSearchable());
   }
 
   protected Map mapGramsField(IndexField field) {
@@ -343,10 +348,13 @@ public abstract class BaseIndex<DOMAIN, DTO extends Dto<KEY>, KEY extends Serial
 
   protected Map mapMultiField(IndexField field) {
     Map<String, Object> mapping = new HashMap<String, Object>();
-    if (field.sortable()) {
-      mapping.put(IndexField.SORT_SUFFIX, mapSortField(field));
+    if (field.isSortable()) {
+      mapping.put(IndexField.SORT_SUFFIX, ImmutableMap.of(
+        "type", "string",
+        "index", "analyzed",
+        "analyzer", "sortable"));
     }
-    if (field.searchable()) {
+    if (field.isSearchable()) {
       if (field.type() != IndexField.Type.TEXT) {
         mapping.put(IndexField.SEARCH_PARTIAL_SUFFIX, mapGramsField(field));
       }
@@ -509,16 +517,14 @@ public abstract class BaseIndex<DOMAIN, DTO extends Dto<KEY>, KEY extends Serial
     Multimap<String, FacetValue> stats = ArrayListMultimap.create();
     if (aggregations != null) {
       for (Aggregation aggregation : aggregations.asList()) {
-        if (aggregation.getClass().isAssignableFrom(StringTerms.class)) {
+        if (aggregation instanceof StringTerms) {
           for (Terms.Bucket value : ((Terms) aggregation).getBuckets()) {
-
-            FacetValue facetValue = new FacetValue(value.getKey(), (int) value.getDocCount());
-            facetValue.setSubFacets(processAggregations(value.getAggregations()));
+            FacetValue facetValue = new FacetValue(value.getKey(), value.getDocCount());
             stats.put(aggregation.getName(), facetValue);
           }
-        } else if (aggregation.getClass().isAssignableFrom(InternalValueCount.class)) {
+        } else if (aggregation instanceof InternalValueCount) {
           InternalValueCount count = (InternalValueCount) aggregation;
-          FacetValue facetValue = new FacetValue(count.getName(), (int) count.getValue());
+          FacetValue facetValue = new FacetValue(count.getName(), count.getValue());
           stats.put(count.getName(), facetValue);
         }
       }
index 57dbe6f3a8265675f36e1029fffe828d038edb03..8ff062563e0547e395ec722a29ff9ca75b2c5e72 100644 (file)
  */
 package org.sonar.server.search;
 
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Multimap;
-import org.apache.commons.lang.builder.EqualsBuilder;
-import org.apache.commons.lang.builder.HashCodeBuilder;
-
 public class FacetValue {
 
-  private String key;
-  private Integer value;
-  private Multimap<String, FacetValue> subFacets;
+  private final String key;
+  private final long value;
 
-  public FacetValue(String key, Integer value){
+  public FacetValue(String key, long value) {
     this.key = key;
     this.value = value;
-    this.subFacets = ArrayListMultimap.create();
   }
 
   public String getKey() {
     return key;
   }
 
-  public FacetValue setKey(String key) {
-    this.key = key;
-    return this;
-  }
-
-  public Integer getValue() {
+  public long getValue() {
     return value;
   }
 
-  public FacetValue setValue(Integer value) {
-    this.value = value;
-    return this;
-  }
-
-  public Multimap<String, FacetValue> getSubFacets() {
-    return subFacets;
-  }
-
-  public FacetValue setSubFacets(Multimap<String, FacetValue> subFacets) {
-    this.subFacets = subFacets;
-    return this;
-  }
-
   @Override
-  public boolean equals(Object other) {
-    return EqualsBuilder.reflectionEquals(this, other);
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (o == null || getClass() != o.getClass()) {
+      return false;
+    }
+
+    FacetValue that = (FacetValue) o;
+    if (key != null ? !key.equals(that.key) : that.key != null) {
+      return false;
+    }
+    return true;
   }
 
   @Override
   public int hashCode() {
-    return HashCodeBuilder.reflectionHashCode(this);
+    return key != null ? key.hashCode() : 0;
   }
 }
index 5a271bfa061722157f34fc29f9c069e03847a19a..ef171748b3a1bbd163e178f578767e9ecbac9a76 100644 (file)
@@ -28,7 +28,7 @@ import java.util.Collections;
 public class IndexField {
 
   public static enum Type {
-    STRING, TEXT, DATE, BOOLEAN, NUMERIC, OBJECT, UUID_PATH
+    STRING, TEXT, DATE, BOOLEAN, INTEGER, LONG, DOUBLE, OBJECT, UUID_PATH
   }
 
   public static final String SORT_SUFFIX = "sort";
@@ -52,20 +52,20 @@ public class IndexField {
     this.nestedFields = nestedFields;
   }
 
-  public boolean sortable() {
+  public boolean isSortable() {
     return sortable;
   }
 
-  public IndexField sortable(boolean b) {
+  public IndexField setSortable(boolean b) {
     this.sortable = b;
     return this;
   }
 
-  public boolean searchable() {
+  public boolean isSearchable() {
     return searchable;
   }
 
-  public IndexField searchable(boolean b) {
+  public IndexField setSearchable(boolean b) {
     this.searchable = b;
     return this;
   }
@@ -79,15 +79,15 @@ public class IndexField {
   }
 
   public Collection<IndexField> nestedFields() {
-    return this.nestedFields;
+    return nestedFields;
   }
 
   public String sortField() {
-    if (this.sortable()) {
+    if (isSortable()) {
       return this.field + ((type == IndexField.Type.TEXT
         || type == IndexField.Type.STRING) ? "." + IndexField.SORT_SUFFIX : "");
     } else {
-      throw new IllegalStateException("Cannot sort on field (Field is not sortable)");
+      throw new IllegalStateException("Field is not sortable: " + field);
     }
   }
 
index 46846a6d51e491b7e996678131c0acd3a00c5149..eb993d1feb39834e69f6605393c50a7c946262de 100644 (file)
@@ -26,9 +26,6 @@ import java.util.Collection;
 import java.util.HashSet;
 import java.util.Set;
 
-/**
- * @since 4.4
- */
 public class Indexable {
 
   private static final Set<IndexField> ALL_FIELDS = new HashSet<IndexField>();
@@ -48,7 +45,7 @@ public class Indexable {
 
   public static IndexField addSearchable(IndexField.Type type, String field){
     IndexField indexField = new IndexField(type, field)
-      .searchable(true);
+      .setSearchable(true);
     ALL_FIELDS.add(indexField);
     return indexField;
   }
@@ -56,15 +53,15 @@ public class Indexable {
 
   public static IndexField addSortableAndSearchable(IndexField.Type type, String field) {
     IndexField indexField = new IndexField(type, field)
-      .searchable(true)
-      .sortable(true);
+      .setSearchable(true)
+      .setSortable(true);
     ALL_FIELDS.add(indexField);
     return indexField;
   }
 
   public static IndexField addSortable(IndexField.Type type, String field){
     IndexField indexField = new IndexField(type, field)
-      .sortable(true);
+      .setSortable(true);
     ALL_FIELDS.add(indexField);
     return indexField;
   }
index d7861e0cd859a895b8562a3fe0c2b9280524918b..844f31211fc30a75e61aab3691971301ea212729 100644 (file)
@@ -72,14 +72,14 @@ public class Result<K> {
   private void processAggregation(Aggregation aggregation) {
     if (Missing.class.isAssignableFrom(aggregation.getClass())) {
       Missing missing = (Missing) aggregation;
-      int docCount = (int) missing.getDocCount();
-      if (docCount > 0) {
+      long docCount = missing.getDocCount();
+      if (docCount > 0L) {
         this.facets.put(aggregation.getName().replace("_missing",""), new FacetValue("", docCount));
       }
     } else if (Terms.class.isAssignableFrom(aggregation.getClass())) {
       Terms termAggregation = (Terms) aggregation;
       for (Terms.Bucket value : termAggregation.getBuckets()) {
-        this.facets.put(aggregation.getName().replace("_selected",""), new FacetValue(value.getKey(), (int) value.getDocCount()));
+        this.facets.put(aggregation.getName().replace("_selected",""), new FacetValue(value.getKey(), value.getDocCount()));
       }
     } else if (HasAggregations.class.isAssignableFrom(aggregation.getClass())) {
       HasAggregations hasAggregations = (HasAggregations) aggregation;
index ee6d3fa63e840d16aea314c5fcb282feb4621cd4..93104c738eed2e14543b2a18c55670fd75a8f279 100644 (file)
@@ -400,12 +400,12 @@ public class IssueServiceMediumTest {
       IssueTesting.newDto(rule, file, project).setAssignee("steph"));
     session.commit();
 
-    Map<String, Integer> results = service.findIssueAssignees(IssueQuery.builder().build());
+    Map<String, Long> results = service.findIssueAssignees(IssueQuery.builder().build());
 
     assertThat(results).hasSize(3);
-    assertThat(results.get("steph")).isEqualTo(2);
-    assertThat(results.get("simon")).isEqualTo(1);
-    assertThat(results.get(null)).isEqualTo(1);
+    assertThat(results.get("steph")).isEqualTo(2L);
+    assertThat(results.get("simon")).isEqualTo(1L);
+    assertThat(results.get(null)).isEqualTo(1L);
 
     assertThat(results.keySet().toArray()[0]).isEqualTo("steph");
     assertThat(results.keySet().toArray()[1]).isEqualTo("simon");
index 627314159fdb2a8b2e2cee745c59b4f8030cb8f1..dc0dd4c16f9b96873b6b1df6cf6e29af5d35fc98 100644 (file)
@@ -55,11 +55,9 @@ import static org.fest.assertions.Fail.fail;
 
 public class RuleIndexMediumTest extends SearchMediumTest {
 
-
   RuleDao dao = tester.get(RuleDao.class);
   RuleIndex index = tester.get(RuleIndex.class);
 
-
   @Test
   public void getByKey() throws InterruptedException {
     RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("javascript", "S001"));
@@ -71,9 +69,6 @@ public class RuleIndexMediumTest extends SearchMediumTest {
     assertThat(rule.htmlDescription()).isEqualTo(ruleDto.getDescription());
     assertThat(rule.key()).isEqualTo(ruleDto.getKey());
 
-    // TODO
-    // assertThat(rule.debtSubCharacteristicKey())
-    // .isEqualTo(ruleDto.getDefaultSubCharacteristicId().toString());
     assertThat(rule.debtRemediationFunction().type().name())
       .isEqualTo(ruleDto.getRemediationFunction());
 
@@ -551,7 +546,7 @@ public class RuleIndexMediumTest extends SearchMediumTest {
       new RuleQuery().setSortField(RuleNormalizer.RuleField.LANGUAGE);
       fail();
     } catch (IllegalStateException e) {
-      assertThat(e.getMessage()).isEqualTo("Field 'lang' is not sortable!");
+      assertThat(e).hasMessage("Field 'lang' is not sortable");
     }
   }