]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5529 - Initial materialization of Issues in ES
authorStephane Gamard <stephane.gamard@sonarsource.com>
Sun, 31 Aug 2014 15:53:17 +0000 (17:53 +0200)
committerStephane Gamard <stephane.gamard@sonarsource.com>
Sun, 31 Aug 2014 15:53:17 +0000 (17:53 +0200)
server/sonar-server/src/main/java/org/sonar/server/issue/db/IssueDao.java
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueDoc.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/test/java/org/sonar/server/issue/db/IssueBackendMediumTest.java

index 3cd0b1af7fc580866539dd32223174330632f892..390e39d49b8707b7ebe55399b93ebe263636252d 100644 (file)
@@ -27,6 +27,7 @@ import org.sonar.core.issue.db.IssueMapper;
 import org.sonar.core.persistence.DaoComponent;
 import org.sonar.core.persistence.DbSession;
 import org.sonar.server.db.BaseDao;
+import org.sonar.server.search.IndexDefinition;
 
 import java.sql.Timestamp;
 import java.util.Date;
@@ -39,7 +40,7 @@ public class IssueDao extends BaseDao<IssueMapper, IssueDto, String> implements
 
   @VisibleForTesting
   public IssueDao(System2 system) {
-    super(null, IssueMapper.class, system);
+    super(IndexDefinition.ISSUES, IssueMapper.class, system);
   }
 
   @Override
index 344a482e78d958c44fdbadc7f654831d3daf1aef..991fba0dd9eadd7c8c1b69ca816f6db4eb669011 100644 (file)
@@ -36,7 +36,7 @@ public class IssueDoc extends BaseDoc implements Issue {
 
   @Override
   public String key() {
-    return null;
+    return getField(IssueNormalizer.IssueField.KEY.field());
   }
 
   @Override
index ef8cb1639622f5d4ed9a18c05591d467a740f7a5..92fd7aef6c793a7d45edc9d3049ad440e67b7ed0 100644 (file)
  */
 package org.sonar.server.issue.index;
 
+import com.google.common.base.Preconditions;
+import org.elasticsearch.common.settings.ImmutableSettings;
 import org.elasticsearch.common.settings.Settings;
 import org.sonar.core.issue.db.IssueDto;
 import org.sonar.server.search.BaseIndex;
 import org.sonar.server.search.IndexDefinition;
+import org.sonar.server.search.IndexField;
 import org.sonar.server.search.SearchClient;
 
 import java.io.IOException;
+import java.util.HashMap;
 import java.util.Map;
 
 public class IssueIndex extends BaseIndex<IssueDoc, IssueDto, String> {
 
-  protected IssueIndex(IssueNormalizer normalizer, SearchClient client) {
+  public IssueIndex(IssueNormalizer normalizer, SearchClient client) {
     super(IndexDefinition.ISSUES, normalizer, client);
   }
 
   @Override
-  protected String getKeyValue(String s) {
-    return s;
+  protected String getKeyValue(String keyString) {
+    return keyString;
   }
 
   @Override
   protected Settings getIndexSettings() throws IOException {
-    return null;
+    return ImmutableSettings.builder()
+      .put("index.number_of_replicas", 0)
+      .put("index.number_of_shards", 1)
+      .build();
   }
 
   @Override
   protected Map mapProperties() {
-    return null;
+    Map<String, Object> mapping = new HashMap<String, Object>();
+    for (IndexField field : IssueNormalizer.IssueField.ALL_FIELDS) {
+      mapping.put(field.field(), mapField(field));
+    }
+    return mapping;
   }
 
   @Override
   protected Map mapKey() {
-    return null;
+    Map<String, Object> mapping = new HashMap<String, Object>();
+    mapping.put("path", IssueNormalizer.IssueField.KEY.field());
+    return mapping;
   }
 
   @Override
   protected IssueDoc toDoc(Map<String, Object> fields) {
-    return null;
+    Preconditions.checkNotNull(fields, "Cannot construct Issue with null response");
+    return new IssueDoc(fields);
   }
 }
index 27f7116bbda2a13c645456dbdd6908918a9e965b..6932cb9f40e519d304e1f778ddb048813bfc6619 100644 (file)
  */
 package org.sonar.server.issue.index;
 
+import com.google.common.collect.ImmutableList;
 import org.elasticsearch.action.update.UpdateRequest;
 import org.sonar.core.issue.db.IssueDto;
 import org.sonar.server.db.DbClient;
 import org.sonar.server.search.BaseNormalizer;
 import org.sonar.server.search.IndexDefinition;
+import org.sonar.server.search.IndexField;
+import org.sonar.server.search.Indexable;
 
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 public class IssueNormalizer extends BaseNormalizer<IssueDto, String> {
 
-  protected IssueNormalizer(DbClient db) {
+  public IssueNormalizer(DbClient db) {
     super(IndexDefinition.ISSUES, db);
   }
 
+  public static final class IssueField extends Indexable {
+
+    public static final IndexField KEY = addSortable(IndexField.Type.STRING, "key");
+
+    public static final Set<IndexField> ALL_FIELDS = getAllFields();
+
+    private static final Set<IndexField> getAllFields() {
+      Set<IndexField> fields = new HashSet<IndexField>();
+      for (Field classField : IssueField.class.getDeclaredFields()) {
+        if (classField.getType().isAssignableFrom(IndexField.class)) {
+          try {
+            fields.add(IndexField.class.cast(classField.get(null)));
+          } catch (IllegalAccessException e) {
+            throw new IllegalStateException("Could not access Field '" + classField.getName() + "'", e);
+          }
+        }
+      }
+      return fields;
+    }
+
+    public static final IndexField of(String fieldName) {
+      for (IndexField field : ALL_FIELDS) {
+        if (field.field().equals(fieldName)) {
+          return field;
+        }
+      }
+      throw new IllegalStateException("Could not find an IndexField for '" + fieldName + "'");
+    }
+  }
+
   @Override
   public List<UpdateRequest> normalize(IssueDto dto) {
-    return null;
+    Map<String, Object> update = new HashMap<String, Object>();
+    Map<String, Object> upsert = new HashMap<String, Object>();
+
+    update.put(IssueField.KEY.field(), dto.getKey());
+
+    return ImmutableList.of(
+      new UpdateRequest()
+        .id(dto.getKey().toString())
+        .doc(update)
+        .upsert(update));
   }
 }
index 4416feab29de9ff899cf8815dca77b7f0ca615fe..9b7e9d8829b6f4aab24ee87904fd409dd5226ec6 100644 (file)
@@ -29,6 +29,8 @@ import org.sonar.core.persistence.DbSession;
 import org.sonar.core.rule.RuleDto;
 import org.sonar.server.component.persistence.ComponentDao;
 import org.sonar.server.db.DbClient;
+import org.sonar.server.issue.index.IssueDoc;
+import org.sonar.server.issue.index.IssueIndex;
 import org.sonar.server.platform.Platform;
 import org.sonar.server.rule.RuleTesting;
 import org.sonar.server.rule.db.RuleDao;
@@ -67,7 +69,42 @@ public class IssueBackendMediumTest {
   }
 
   @Test
-  public void insert_and_find_after_date() throws Exception {
+  public void insert_and_find_by_key() throws Exception {
+    RuleDto rule = RuleTesting.newXooX1();
+    tester.get(RuleDao.class).insert(dbSession, rule);
+
+    ComponentDto project = new ComponentDto()
+      .setId(1L)
+      .setProjectId(1L);
+    tester.get(ComponentDao.class).insert(dbSession, project);
+
+    ComponentDto resource = new ComponentDto()
+      .setProjectId(1L)
+      .setId(2L);
+    tester.get(ComponentDao.class).insert(dbSession, resource);
+
+    IssueDto issue = new IssueDto().setId(1L).setRuleId(50).setComponentId(123l).setRootComponentId(100l)
+      .setRuleId(rule.getId())
+      .setRootComponentId(project.getId())
+      .setComponentId(resource.getId())
+      .setStatus("OPEN").setResolution("OPEN")
+      .setKee(UUID.randomUUID().toString());
+    dbClient.issueDao().insert(dbSession, issue);
+
+    dbSession.commit();
+    assertThat(issue.getId()).isNotNull();
+
+    // Check that Issue is in Index
+    assertThat(indexClient.get(IssueIndex.class).countAll()).isEqualTo(1);
+
+    // should find by key
+    IssueDoc issueDoc = indexClient.get(IssueIndex.class).getByKey(issue.getKey());
+    assertThat(issueDoc).isNotNull();
+    assertThat(issueDoc.key()).isEqualTo(issue.getKey());
+  }
+
+  @Test
+ public void insert_and_find_after_date() throws Exception {
 
     RuleDto rule = RuleTesting.newXooX1();
     tester.get(RuleDao.class).insert(dbSession, rule);
@@ -100,5 +137,12 @@ public class IssueBackendMediumTest {
     // Should not find any new issues
     Date t1 = new Date();
     assertThat(dbClient.issueDao().findAfterDate(dbSession, t1)).hasSize(0);
+
+    // Should synchronise
+    tester.clearIndexes();
+    assertThat(indexClient.get(IssueIndex.class).countAll()).isEqualTo(0);
+    tester.get(Platform.class).executeStartupTasks();
+    assertThat(indexClient.get(IssueIndex.class).countAll()).isEqualTo(1);
+
   }
 }