]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8287 Add nested field to index type 'projectmeasures'
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Mon, 17 Oct 2016 09:11:20 +0000 (11:11 +0200)
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Tue, 18 Oct 2016 15:01:19 +0000 (17:01 +0200)
server/sonar-server/src/main/java/org/sonar/server/es/NewIndex.java
server/sonar-server/src/test/java/org/sonar/server/es/NewIndexTest.java

index 6683df588d16f0291329e38a4feca8a766eadb44..0c447fe48f762c894034a6fd825ec05aaf606078 100644 (file)
@@ -33,6 +33,7 @@ import org.elasticsearch.cluster.metadata.IndexMetaData;
 import org.elasticsearch.common.settings.Settings;
 import org.sonar.process.ProcessProperties;
 
+import static com.google.common.base.Preconditions.checkArgument;
 import static java.lang.String.format;
 import static org.sonar.server.es.BaseIndex.SEARCH_PARTIAL_SUFFIX;
 import static org.sonar.server.es.BaseIndex.SEARCH_WORDS_SUFFIX;
@@ -128,6 +129,10 @@ public class NewIndex {
       return new StringFieldBuilder(this, fieldName);
     }
 
+    public NestedFieldBuilder nestedFieldBuilder(String fieldName) {
+      return new NestedFieldBuilder(this, fieldName);
+    }
+
     public NewIndexType createBooleanField(String fieldName) {
       return setProperty(fieldName, ImmutableMap.of("type", "boolean"));
     }
@@ -253,7 +258,7 @@ public class NewIndex {
       return this;
     }
 
-    public void build() {
+    public NewIndexType build() {
       Map<String, Object> hash = new TreeMap<>();
       if (subFields.isEmpty()) {
         hash.putAll(ImmutableMap.of(
@@ -270,7 +275,41 @@ public class NewIndex {
         hash.put("fields", multiFields);
       }
 
-      indexType.setProperty(fieldName, hash);
+      return indexType.setProperty(fieldName, hash);
+    }
+  }
+
+  public static class NestedFieldBuilder {
+    private final NewIndexType indexType;
+    private final String fieldName;
+    private final Map<String, Object> properties = new TreeMap<>();
+
+    private NestedFieldBuilder(NewIndexType indexType, String fieldName) {
+      this.indexType = indexType;
+      this.fieldName = fieldName;
+    }
+
+    private NestedFieldBuilder setProperty(String fieldName, Object value) {
+      properties.put(fieldName, value);
+
+      return this;
+    }
+
+    public NestedFieldBuilder addStringFied(String fieldName) {
+      return setProperty(fieldName, ImmutableMap.of("type", "string"));
+    }
+
+    public NestedFieldBuilder addDoubleField(String fieldName) {
+      return setProperty(fieldName, ImmutableMap.of("type", "double"));
+    }
+
+    public NewIndexType build() {
+      checkArgument(!properties.isEmpty(), "At least one sub-field must be declared in nested property '%s'", fieldName);
+      Map<String, Object> hash = new TreeMap<>();
+      hash.put("type", "nested");
+      hash.put("properties", properties);
+
+      return indexType.setProperty(fieldName, hash);
     }
   }
 
index 2f105eda24d49227bdb5677360fda57c2c7db02d..e67740fbeea6287cbcf8c801d589fcf760f3b265 100644 (file)
@@ -24,7 +24,9 @@ import java.util.Map;
 import org.assertj.core.data.MapEntry;
 import org.elasticsearch.cluster.metadata.IndexMetaData;
 import org.elasticsearch.common.settings.Settings;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
 import org.sonar.api.config.MapSettings;
 import org.sonar.process.ProcessProperties;
 
@@ -33,6 +35,9 @@ import static org.junit.Assert.fail;
 
 public class NewIndexTest {
 
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
   @Test
   public void most_basic_index() {
     NewIndex index = new NewIndex("issues");
@@ -111,6 +116,34 @@ public class NewIndexTest {
     assertThat((Map) props.get("fields")).isNotEmpty();
   }
 
+  @Test
+  public void define_nested_field() {
+    NewIndex index = new NewIndex("projectmeasures");
+    NewIndex.NewIndexType mapping = index.createType("projectmeasures");
+
+    mapping.nestedFieldBuilder("measures")
+      .addStringFied("key")
+      .addDoubleField("value")
+      .build();
+    Map<String, Object> result = (Map) mapping.getProperty("measures");
+
+    assertThat(result.get("type")).isEqualTo("nested");
+    Map<String, Map<String, Object>> subProperties = (Map) result.get("properties");
+    assertThat(subProperties.get("key").get("type")).isEqualTo("string");
+    assertThat(subProperties.get("value").get("type")).isEqualTo("double");
+  }
+
+  @Test
+  public void fail_when_nested_with_no_field() {
+    expectedException.expect(IllegalArgumentException.class);
+    expectedException.expectMessage("At least one sub-field must be declared in nested property 'measures'");
+
+    NewIndex index = new NewIndex("projectmeasures");
+    NewIndex.NewIndexType mapping = index.createType("project_measures");
+
+    mapping.nestedFieldBuilder("measures").build();
+  }
+
   @Test
   public void use_default_doc_values() {
     NewIndex index = new NewIndex("issues");
@@ -170,7 +203,7 @@ public class NewIndexTest {
 
     mapping = index.getTypes().get("issue");
     assertThat(mapping).isNotNull();
-    assertThat((Map<String, Object>)mapping.getAttributes().get("_source")).containsExactly(MapEntry.entry("enabled", true));
+    assertThat((Map<String, Object>) mapping.getAttributes().get("_source")).containsExactly(MapEntry.entry("enabled", true));
   }
 
   @Test
@@ -181,6 +214,6 @@ public class NewIndexTest {
 
     mapping = index.getTypes().get("issue");
     assertThat(mapping).isNotNull();
-    assertThat((Map<String, Object>)mapping.getAttributes().get("_source")).containsExactly(MapEntry.entry("enabled", false));
+    assertThat((Map<String, Object>) mapping.getAttributes().get("_source")).containsExactly(MapEntry.entry("enabled", false));
   }
 }