From a63bb2a1d7b1b1d33928ea9360f8f76682c831ea Mon Sep 17 00:00:00 2001 From: Teryk Bellahsene Date: Mon, 17 Oct 2016 11:11:20 +0200 Subject: [PATCH] SONAR-8287 Add nested field to index type 'projectmeasures' --- .../java/org/sonar/server/es/NewIndex.java | 43 ++++++++++++++++++- .../org/sonar/server/es/NewIndexTest.java | 37 +++++++++++++++- 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/es/NewIndex.java b/server/sonar-server/src/main/java/org/sonar/server/es/NewIndex.java index 6683df588d1..0c447fe48f7 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/es/NewIndex.java +++ b/server/sonar-server/src/main/java/org/sonar/server/es/NewIndex.java @@ -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 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 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 hash = new TreeMap<>(); + hash.put("type", "nested"); + hash.put("properties", properties); + + return indexType.setProperty(fieldName, hash); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/es/NewIndexTest.java b/server/sonar-server/src/test/java/org/sonar/server/es/NewIndexTest.java index 2f105eda24d..e67740fbeea 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/es/NewIndexTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/es/NewIndexTest.java @@ -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 result = (Map) mapping.getProperty("measures"); + + assertThat(result.get("type")).isEqualTo("nested"); + Map> 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)mapping.getAttributes().get("_source")).containsExactly(MapEntry.entry("enabled", true)); + assertThat((Map) 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)mapping.getAttributes().get("_source")).containsExactly(MapEntry.entry("enabled", false)); + assertThat((Map) mapping.getAttributes().get("_source")).containsExactly(MapEntry.entry("enabled", false)); } } -- 2.39.5