]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8798 move default index properties to NewIndex
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Wed, 19 Jul 2017 14:30:01 +0000 (16:30 +0200)
committerDaniel Schwarz <bartfastiel@users.noreply.github.com>
Wed, 9 Aug 2017 13:09:54 +0000 (15:09 +0200)
specifying them as node properties is not supported in ES 5.X and causes failure at startup

20 files changed:
server/sonar-process-monitor/src/main/java/org/sonar/application/process/EsSettings.java
server/sonar-process-monitor/src/test/java/org/sonar/application/process/EsSettingsTest.java
server/sonar-search/src/main/java/org/sonar/search/EsSettings.java
server/sonar-server/src/main/java/org/sonar/server/component/index/ComponentIndexDefinition.java
server/sonar-server/src/main/java/org/sonar/server/es/IndexDefinition.java
server/sonar-server/src/main/java/org/sonar/server/es/NewIndex.java
server/sonar-server/src/main/java/org/sonar/server/es/metadata/MetadataIndexDefinition.java
server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndexDefinition.java
server/sonar-server/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndexDefinition.java
server/sonar-server/src/main/java/org/sonar/server/rule/index/RuleIndexDefinition.java
server/sonar-server/src/main/java/org/sonar/server/test/index/TestIndexDefinition.java
server/sonar-server/src/main/java/org/sonar/server/user/index/UserIndexDefinition.java
server/sonar-server/src/main/java/org/sonar/server/view/index/ViewIndexDefinition.java
server/sonar-server/src/test/java/org/sonar/server/es/FakeIndexDefinition.java
server/sonar-server/src/test/java/org/sonar/server/es/IndexCreatorTest.java
server/sonar-server/src/test/java/org/sonar/server/es/IndexDefinitionContextTest.java
server/sonar-server/src/test/java/org/sonar/server/es/IndexDefinitionHashTest.java
server/sonar-server/src/test/java/org/sonar/server/es/NewIndexSettingsConfigurationTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/es/NewIndexTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/index/FooIndexDefinition.java

index 76b0046e2c31f1f3829c00fb16d07a517da4ad21..a93740d81d194895f47eac4986c769d9f9448096 100644 (file)
@@ -67,6 +67,7 @@ public class EsSettings {
     configureNetwork(builder);
     configureCluster(builder);
     configureMarvel(builder);
+    configureAction(builder);
     return builder;
   }
 
@@ -133,25 +134,6 @@ public class EsSettings {
     }
   }
 
-  void configureIndexDefaults(Map<String, String> builder) {
-    configureIndexDefaultsForCluster(builder);
-    builder.put("index.number_of_shards", "1");
-    builder.put("index.refresh_interval", "30s");
-    builder.put("action.auto_create_index", String.valueOf(false));
-    builder.put("index.mapper.dynamic", String.valueOf(false));
-  }
-
-  private void configureIndexDefaultsForCluster(Map<String, String> builder) {
-    builder.put("index.number_of_replicas", String.valueOf(computeReplicationFactor()));
-  }
-
-  private int computeReplicationFactor() {
-    if (clusterEnabled) {
-      return props.valueAsInt(ProcessProperties.SEARCH_REPLICAS, 1);
-    }
-    return 0;
-  }
-
   private void configureCluster(Map<String, String> builder) {
     // Default value in a standalone mode, not overridable
 
@@ -189,4 +171,7 @@ public class EsSettings {
     }
   }
 
+  private void configureAction(Map<String, String> builder) {
+    builder.put("action.auto_create_index", String.valueOf(false));
+  }
 }
index eb0f6a90e22d84d644613df548a714179a7c70c8..93dcbdb4966c6b5d1ef3b1cce56d0e7bbb4e8fa2 100644 (file)
@@ -34,6 +34,9 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 public class EsSettingsTest {
 
+  private static final boolean CLUSTER_ENABLED = true;
+  private static final boolean CLUSTER_DISABLED = false;
+  
   @Rule
   public TemporaryFolder temp = new TemporaryFolder();
 
@@ -66,10 +69,11 @@ public class EsSettingsTest {
     // http is disabled for security reasons
     assertThat(generated.get("http.enabled")).isEqualTo("false");
 
-    assertThat(generated.get("index.number_of_replicas")).isEqualTo("0");
     assertThat(generated.get("discovery.zen.ping.unicast.hosts")).isNull();
     assertThat(generated.get("discovery.zen.minimum_master_nodes")).isEqualTo("1");
     assertThat(generated.get("discovery.initial_state_timeout")).isEqualTo("30s");
+
+    assertThat(generated.get("action.auto_create_index")).isEqualTo("false");
   }
 
   @Test
@@ -77,7 +81,7 @@ public class EsSettingsTest {
     File dataDir = temp.newFolder();
     File logDir = temp.newFolder();
     File tempDir = temp.newFolder();
-    Props props = minProps(false);
+    Props props = minProps(CLUSTER_DISABLED);
     props.set(ProcessProperties.PATH_DATA, dataDir.getAbsolutePath());
     props.set(ProcessProperties.PATH_LOGS, logDir.getAbsolutePath());
     props.set(ProcessProperties.PATH_TEMP, tempDir.getAbsolutePath());
@@ -90,12 +94,11 @@ public class EsSettingsTest {
   }
 
   @Test
-  public void cluster_is_enabled() throws Exception {
-    Props props = minProps(true);
+  public void set_discovery_settings_if_cluster_is_enabled() throws Exception {
+    Props props = minProps(CLUSTER_ENABLED);
     props.set(ProcessProperties.CLUSTER_SEARCH_HOSTS, "1.2.3.4:9000,1.2.3.5:8080");
     Map<String, String> settings = new EsSettings(props).build();
 
-    assertThat(settings.get("index.number_of_replicas")).isEqualTo("1");
     assertThat(settings.get("discovery.zen.ping.unicast.hosts")).isEqualTo("1.2.3.4:9000,1.2.3.5:8080");
     assertThat(settings.get("discovery.zen.minimum_master_nodes")).isEqualTo("2");
     assertThat(settings.get("discovery.initial_state_timeout")).isEqualTo("120s");
@@ -103,7 +106,7 @@ public class EsSettingsTest {
 
   @Test
   public void incorrect_values_of_minimum_master_nodes() throws Exception {
-    Props props = minProps(true);
+    Props props = minProps(CLUSTER_ENABLED);
     props.set(ProcessProperties.SEARCH_MINIMUM_MASTER_NODES, "ꝱꝲꝳପ");
 
     EsSettings underTest = new EsSettings(props);
@@ -115,7 +118,7 @@ public class EsSettingsTest {
 
   @Test
   public void cluster_is_enabled_with_defined_minimum_master_nodes() throws Exception {
-    Props props = minProps(true);
+    Props props = minProps(CLUSTER_ENABLED);
     props.set(ProcessProperties.SEARCH_MINIMUM_MASTER_NODES, "5");
     Map<String, String> settings = new EsSettings(props).build();
 
@@ -124,7 +127,7 @@ public class EsSettingsTest {
 
   @Test
   public void cluster_is_enabled_with_defined_initialTimeout() throws Exception {
-    Props props = minProps(true);
+    Props props = minProps(CLUSTER_ENABLED);
     props.set(ProcessProperties.SEARCH_INITIAL_STATE_TIMEOUT, "10s");
     Map<String, String> settings = new EsSettings(props).build();
 
@@ -133,7 +136,7 @@ public class EsSettingsTest {
 
   @Test
   public void in_standalone_initialTimeout_is_not_overridable() throws Exception {
-    Props props = minProps(false);
+    Props props = minProps(CLUSTER_DISABLED);
     props.set(ProcessProperties.SEARCH_INITIAL_STATE_TIMEOUT, "10s");
     Map<String, String> settings = new EsSettings(props).build();
 
@@ -142,7 +145,7 @@ public class EsSettingsTest {
 
   @Test
   public void in_standalone_minimumMasterNodes_is_not_overridable() throws Exception {
-    Props props = minProps(false);
+    Props props = minProps(CLUSTER_DISABLED);
     props.set(ProcessProperties.SEARCH_MINIMUM_MASTER_NODES, "5");
     Map<String, String> settings = new EsSettings(props).build();
 
@@ -150,40 +153,10 @@ public class EsSettingsTest {
   }
 
 
-  @Test
-  public void in_standalone_searchReplicas_is_not_overridable() throws Exception {
-    Props props = minProps(false);
-    props.set(ProcessProperties.SEARCH_REPLICAS, "5");
-    Map<String, String> settings = new EsSettings(props).build();
-
-    assertThat(settings.get("index.number_of_replicas")).isEqualTo("0");
-  }
-
-  @Test
-  public void cluster_is_enabled_with_defined_replicas() throws Exception {
-    Props props = minProps(true);
-    props.set(ProcessProperties.SEARCH_REPLICAS, "5");
-    Map<String, String> settings = new EsSettings(props).build();
-
-    assertThat(settings.get("index.number_of_replicas")).isEqualTo("5");
-  }
-
-  @Test
-  public void incorrect_values_of_replicas() throws Exception {
-    Props props = minProps(true);
-
-    props.set(ProcessProperties.SEARCH_REPLICAS, "ꝱꝲꝳପ");
-
-    EsSettings underTest = new EsSettings(props);
-
-    expectedException.expect(IllegalStateException.class);
-    expectedException.expectMessage("Value of property sonar.search.replicas is not an integer:");
-    underTest.build();
-  }
 
   @Test
   public void enable_marvel() throws Exception {
-    Props props = minProps(false);
+    Props props = minProps(CLUSTER_DISABLED);
     props.set("sonar.search.marvelHosts", "127.0.0.2,127.0.0.3");
     Map<String, String> settings = new EsSettings(props).build();
 
@@ -192,7 +165,7 @@ public class EsSettingsTest {
 
   @Test
   public void enable_http_connector() throws Exception {
-    Props props = minProps(false);
+    Props props = minProps(CLUSTER_DISABLED);
     props.set(ProcessProperties.SEARCH_HTTP_PORT, "9010");
     Map<String, String> settings = new EsSettings(props).build();
 
@@ -203,7 +176,7 @@ public class EsSettingsTest {
 
   @Test
   public void enable_http_connector_different_host() throws Exception {
-    Props props = minProps(false);
+    Props props = minProps(CLUSTER_DISABLED);
     props.set(ProcessProperties.SEARCH_HTTP_PORT, "9010");
     props.set(ProcessProperties.SEARCH_HOST, "127.0.0.2");
     Map<String, String> settings = new EsSettings(props).build();
index 4998c6007f10900b26229a921d8dae7c89e59495..549809ef13a27cab576ddb79646c6ba2d210fce7 100644 (file)
@@ -29,8 +29,6 @@ import java.util.Set;
 import java.util.TreeSet;
 import java.util.UUID;
 import org.apache.commons.lang.StringUtils;
-import org.elasticsearch.cluster.metadata.IndexMetaData;
-import org.elasticsearch.common.settings.Settings;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.process.ProcessProperties;
@@ -79,7 +77,6 @@ public class EsSettings implements EsSettingsMBean {
   Map<String, String> build() {
     Map<String, String> builder = new HashMap<>();
     configureFileSystem(builder);
-    configureIndexDefaults(builder);
     configureNetwork(builder);
     configureCluster(builder);
     configureMarvel(builder);
@@ -148,15 +145,6 @@ public class EsSettings implements EsSettingsMBean {
     }
   }
 
-  private static void configureIndexDefaults(Settings.Builder builder) {
-    builder
-      .put("index.number_of_shards", "1")
-      .put("index.refresh_interval", "30s")
-      .put("action.auto_create_index", false)
-      .put("index.mapper.dynamic", false)
-      .put("action.auto_create_index", false);
-  }
-
   private void configureCluster(Map<String, String> builder) {
     // Default value in a standalone mode, not overridable
     int replicationFactor = 0;
index 8cf458879bbc45f8d9e14df48c2ba2ab3fa1371a..d0b60c84ec32c52f12417018f95c118e0f9e95ee 100644 (file)
@@ -29,6 +29,8 @@ import static org.sonar.server.es.DefaultIndexSettingsElement.SEARCH_GRAMS_ANALY
 import static org.sonar.server.es.DefaultIndexSettingsElement.SEARCH_PREFIX_ANALYZER;
 import static org.sonar.server.es.DefaultIndexSettingsElement.SEARCH_PREFIX_CASE_INSENSITIVE_ANALYZER;
 import static org.sonar.server.es.DefaultIndexSettingsElement.SORTABLE_ANALYZER;
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.MANUAL_REFRESH_INTERVAL;
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.newBuilder;
 
 public class ComponentIndexDefinition implements IndexDefinition {
 
@@ -51,9 +53,12 @@ public class ComponentIndexDefinition implements IndexDefinition {
 
   @Override
   public void define(IndexDefinitionContext context) {
-    NewIndex index = context.create(INDEX_TYPE_COMPONENT.getIndex());
-    index.refreshHandledByIndexer();
-    index.configureShards(config, DEFAULT_NUMBER_OF_SHARDS);
+    NewIndex index = context.create(
+      INDEX_TYPE_COMPONENT.getIndex(),
+      newBuilder(config)
+        .setRefreshInterval(MANUAL_REFRESH_INTERVAL)
+        .setDefaultNbOfShards(DEFAULT_NUMBER_OF_SHARDS)
+        .build());
 
     NewIndex.NewIndexType mapping = index.createType(INDEX_TYPE_COMPONENT.getType())
       .requireProjectAuthorization();
index b751640cdea4f6c17a0ce6161a8df4c30bd2c703..bd12a4aff1906ffee082a39f2889336ea37ec14c 100644 (file)
@@ -31,9 +31,9 @@ public interface IndexDefinition {
   class IndexDefinitionContext {
     private final Map<String, NewIndex> byKey = Maps.newHashMap();
 
-    public NewIndex create(String key) {
+    public NewIndex create(String key, NewIndex.SettingsConfiguration settingsConfiguration) {
       Preconditions.checkArgument(!byKey.containsKey(key), String.format("Index already exists: %s", key));
-      NewIndex index = new NewIndex(key);
+      NewIndex index = new NewIndex(key, settingsConfiguration);
       byKey.put(key, index);
       return index;
     }
index 8ac99bc3bb238153300acc9b0a467a32579ed7ff..5cea7f3a1c7778521cca7125fb2dd4ee5fc21af5 100644 (file)
@@ -19,7 +19,6 @@
  */
 package org.sonar.server.es;
 
-import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSortedMap;
 import com.google.common.collect.Maps;
@@ -38,6 +37,8 @@ import org.sonar.server.permission.index.AuthorizationTypeSupport;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static java.lang.String.format;
+import static java.lang.String.valueOf;
+import static java.util.Objects.requireNonNull;
 import static org.sonar.server.es.DefaultIndexSettings.ANALYZER;
 import static org.sonar.server.es.DefaultIndexSettings.FIELDDATA_ENABLED;
 import static org.sonar.server.es.DefaultIndexSettings.FIELD_FIELDDATA;
@@ -56,13 +57,90 @@ public class NewIndex {
   private final Settings.Builder settings = DefaultIndexSettings.defaults();
   private final Map<String, NewIndexType> types = new LinkedHashMap<>();
 
-  NewIndex(String indexName) {
-    Preconditions.checkArgument(StringUtils.isAllLowerCase(indexName), "Index name must be lower-case: " + indexName);
+  NewIndex(String indexName, SettingsConfiguration settingsConfiguration) {
+    checkArgument(StringUtils.isAllLowerCase(indexName), "Index name must be lower-case: " + indexName);
     this.indexName = indexName;
+    applySettingsConfiguration(settingsConfiguration);
   }
 
-  public void refreshHandledByIndexer() {
-    getSettings().put("index.refresh_interval", "-1");
+  private void applySettingsConfiguration(SettingsConfiguration settingsConfiguration) {
+    settings.put("index.mapper.dynamic", valueOf(false));
+    settings.put("index.refresh_interval", refreshInterval(settingsConfiguration));
+
+    Configuration config = settingsConfiguration.getConfiguration();
+    boolean clusterMode = config.getBoolean(ProcessProperties.CLUSTER_ENABLED).orElse(false);
+    int shards = config.getInt(format("sonar.search.%s.shards", indexName))
+      .orElse(settingsConfiguration.getDefaultNbOfShards());
+    int replicas = clusterMode ? config.getInt(ProcessProperties.SEARCH_REPLICAS).orElse(1) : 0;
+
+    settings.put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, shards);
+    settings.put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, replicas);
+  }
+
+  private static String refreshInterval(SettingsConfiguration settingsConfiguration) {
+    int refreshInterval = settingsConfiguration.getRefreshInterval();
+    if (refreshInterval == -1) {
+      return "-1";
+    }
+    return refreshInterval + "s";
+  }
+
+  public static class SettingsConfiguration {
+    public static final int MANUAL_REFRESH_INTERVAL = -1;
+
+    private final Configuration configuration;
+    private final int defaultNbOfShards;
+    private final int refreshInterval;
+
+    private SettingsConfiguration(Builder builder) {
+      this.configuration = builder.configuration;
+      this.defaultNbOfShards = builder.defaultNbOfShards;
+      this.refreshInterval = builder.refreshInterval;
+    }
+
+    public static Builder newBuilder(Configuration configuration) {
+      return new Builder(configuration);
+    }
+
+    public Configuration getConfiguration() {
+      return configuration;
+    }
+
+    public int getDefaultNbOfShards() {
+      return defaultNbOfShards;
+    }
+
+    public int getRefreshInterval() {
+      return refreshInterval;
+    }
+
+    public static class Builder {
+      private final Configuration configuration;
+      private int defaultNbOfShards = 1;
+      private int refreshInterval = 30;
+
+      public Builder(Configuration configuration) {
+        this.configuration = requireNonNull(configuration, "configuration can't be null");
+      }
+
+      public Builder setDefaultNbOfShards(int defaultNbOfShards) {
+        checkArgument(defaultNbOfShards >= 1, "defaultNbOfShards must be >= 1");
+        this.defaultNbOfShards = defaultNbOfShards;
+        return this;
+      }
+
+      public Builder setRefreshInterval(int refreshInterval) {
+        checkArgument(refreshInterval == -1 || refreshInterval > 0,
+          "refreshInterval must be either -1 or strictly positive");
+        this.refreshInterval = refreshInterval;
+        return this;
+      }
+
+      public SettingsConfiguration build() {
+        return new SettingsConfiguration(this);
+      }
+    }
+
   }
 
   public String getName() {
@@ -83,16 +161,6 @@ public class NewIndex {
     return types;
   }
 
-  public void configureShards(Configuration config, int defaultNbOfShards) {
-    boolean clusterMode = config.getBoolean(ProcessProperties.CLUSTER_ENABLED).orElse(false);
-    int shards = config.getInt(format("sonar.search.%s.shards", indexName)).orElse(defaultNbOfShards);
-
-    int replicas = config.getInt(ProcessProperties.SEARCH_REPLICAS).orElse(clusterMode ? 1 : 0);
-
-    getSettings().put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, shards);
-    getSettings().put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, replicas);
-  }
-
   public static class NewIndexType {
     private final NewIndex index;
     private final String name;
@@ -275,8 +343,8 @@ public class NewIndex {
         hash.putAll(ImmutableMap.of(
           "type", getFieldType(),
           "index", disableSearch ? INDEX_NOT_SEARCHABLE : INDEX_SEARCHABLE,
-          "norms", String.valueOf(!disableNorms),
-          "store", String.valueOf(store)));
+          "norms", valueOf(!disableNorms),
+          "store", valueOf(store)));
         if (getFieldData()) {
           hash.put(FIELD_FIELDDATA, FIELDDATA_ENABLED);
         }
@@ -314,7 +382,7 @@ public class NewIndex {
           "type", getFieldType(),
           "index", INDEX_SEARCHABLE,
           "norms", "false",
-          "store", String.valueOf(store)));
+          "store", valueOf(store)));
 
         hash.put("fields", multiFields);
       }
index 4eb744e5b5924407fe97aad02d3cdc0add6fe569..bb680208f2d4c755e42b6d44bd0d97fec70fbf20 100644 (file)
@@ -24,6 +24,9 @@ import org.sonar.server.es.IndexDefinition.IndexDefinitionContext;
 import org.sonar.server.es.IndexType;
 import org.sonar.server.es.NewIndex;
 
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.MANUAL_REFRESH_INTERVAL;
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.newBuilder;
+
 public class MetadataIndexDefinition {
 
   public static final IndexType INDEX_TYPE_METADATA = new IndexType("metadatas", "metadata");
@@ -38,9 +41,12 @@ public class MetadataIndexDefinition {
   }
 
   public void define(IndexDefinitionContext context) {
-    NewIndex index = context.create(INDEX_TYPE_METADATA.getIndex());
-    index.refreshHandledByIndexer();
-    index.configureShards(configuration, DEFAULT_NUMBER_OF_SHARDS);
+    NewIndex index = context.create(
+      INDEX_TYPE_METADATA.getIndex(),
+      newBuilder(configuration)
+        .setRefreshInterval(MANUAL_REFRESH_INTERVAL)
+        .setDefaultNbOfShards(DEFAULT_NUMBER_OF_SHARDS)
+        .build());
 
     NewIndex.NewIndexType mapping = index.createType(INDEX_TYPE_METADATA.getType());
 
index 908767016614f4e24243257f59891be8eb09e464..0eabde4223ceb5e51e66b1a309506b522859cab9 100644 (file)
@@ -26,6 +26,8 @@ import org.sonar.server.es.IndexType;
 import org.sonar.server.es.NewIndex;
 
 import static org.sonar.server.es.DefaultIndexSettingsElement.SORTABLE_ANALYZER;
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.MANUAL_REFRESH_INTERVAL;
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.newBuilder;
 
 /**
  * Definition of ES index "issues", including settings and fields.
@@ -89,10 +91,12 @@ public class IssueIndexDefinition implements IndexDefinition {
 
   @Override
   public void define(IndexDefinitionContext context) {
-    NewIndex index = context.create(INDEX_TYPE_ISSUE.getIndex());
-
-    index.refreshHandledByIndexer();
-    index.configureShards(config, 5);
+    NewIndex index = context.create(
+      INDEX_TYPE_ISSUE.getIndex(),
+      newBuilder(config)
+        .setRefreshInterval(MANUAL_REFRESH_INTERVAL)
+        .setDefaultNbOfShards(5)
+        .build());
 
     NewIndex.NewIndexType type = index.createType(INDEX_TYPE_ISSUE.getType());
     type.requireProjectAuthorization();
index d6865ac1aa6bfcd814fe1c24ff72fc0b35e38551..5f0f7f73c84b8a332ad05c589d42de2c13a8794a 100644 (file)
@@ -26,6 +26,8 @@ import org.sonar.server.es.NewIndex;
 
 import static org.sonar.server.es.DefaultIndexSettingsElement.SEARCH_GRAMS_ANALYZER;
 import static org.sonar.server.es.DefaultIndexSettingsElement.SORTABLE_ANALYZER;
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.MANUAL_REFRESH_INTERVAL;
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.newBuilder;
 
 public class ProjectMeasuresIndexDefinition implements IndexDefinition {
 
@@ -50,9 +52,12 @@ public class ProjectMeasuresIndexDefinition implements IndexDefinition {
 
   @Override
   public void define(IndexDefinitionContext context) {
-    NewIndex index = context.create(INDEX_TYPE_PROJECT_MEASURES.getIndex());
-    index.refreshHandledByIndexer();
-    index.configureShards(config, 5);
+    NewIndex index = context.create(
+      INDEX_TYPE_PROJECT_MEASURES.getIndex(),
+      newBuilder(config)
+        .setRefreshInterval(MANUAL_REFRESH_INTERVAL)
+        .setDefaultNbOfShards(5)
+        .build());
 
     NewIndex.NewIndexType mapping = index.createType(INDEX_TYPE_PROJECT_MEASURES.getType())
       .requireProjectAuthorization();
index bf563459590ee4cce4d320e8a9402bbb27d7c41f..f7d6a4e06ec921b2b97b2d8985d887417cdf85e8 100644 (file)
@@ -33,6 +33,8 @@ import org.sonar.server.es.NewIndex;
 import static org.sonar.server.es.DefaultIndexSettingsElement.ENGLISH_HTML_ANALYZER;
 import static org.sonar.server.es.DefaultIndexSettingsElement.SEARCH_WORDS_ANALYZER;
 import static org.sonar.server.es.DefaultIndexSettingsElement.SORTABLE_ANALYZER;
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.MANUAL_REFRESH_INTERVAL;
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.newBuilder;
 
 /**
  * Definition of ES index "rules", including settings and fields.
@@ -102,13 +104,15 @@ public class RuleIndexDefinition implements IndexDefinition {
 
   @Override
   public void define(IndexDefinitionContext context) {
-    NewIndex index = context.create(INDEX_TYPE_RULE.getIndex());
-
-    index.refreshHandledByIndexer();
-    // Default nb of shards should be greater than 1 in order to
-    // easily detect routing misconfiguration.
-    // See https://jira.sonarsource.com/browse/SONAR-9489
-    index.configureShards(config, 2);
+    NewIndex index = context.create(
+      INDEX_TYPE_RULE.getIndex(),
+      newBuilder(config)
+        .setRefreshInterval(MANUAL_REFRESH_INTERVAL)
+        // Default nb of shards should be greater than 1 in order to
+        // easily detect routing misconfiguration.
+        // See https://jira.sonarsource.com/browse/SONAR-9489
+        .setDefaultNbOfShards(2)
+        .build());
 
     // Active rule type
     NewIndex.NewIndexType activeRuleMapping = index.createType(INDEX_TYPE_ACTIVE_RULE.getType());
index 478b2702d4acba5e928eb5686234e4cbccd6d0c9..123246a58b76d4dcf6f32d7c60f2d67373c80630 100644 (file)
@@ -27,6 +27,8 @@ import org.sonar.server.es.NewIndex;
 
 import static org.sonar.server.es.DefaultIndexSettings.FIELD_TYPE_KEYWORD;
 import static org.sonar.server.es.DefaultIndexSettings.INDEX_SEARCHABLE;
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.MANUAL_REFRESH_INTERVAL;
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.newBuilder;
 
 public class TestIndexDefinition implements IndexDefinition {
 
@@ -52,10 +54,12 @@ public class TestIndexDefinition implements IndexDefinition {
 
   @Override
   public void define(IndexDefinitionContext context) {
-    NewIndex index = context.create(INDEX_TYPE_TEST.getIndex());
-
-    index.refreshHandledByIndexer();
-    index.configureShards(config, 5);
+    NewIndex index = context.create(
+      INDEX_TYPE_TEST.getIndex(),
+      newBuilder(config)
+        .setRefreshInterval(MANUAL_REFRESH_INTERVAL)
+        .setDefaultNbOfShards(5)
+        .build());
 
     NewIndex.NewIndexType mapping = index.createType(INDEX_TYPE_TEST.getType());
     mapping.setAttribute("_routing", ImmutableMap.of("required", true));
index 13830f63ba8eb6bd796f5cc6bf929324fc131bc2..69dec57e66b43b8ca5c3099b46dd9835242013e0 100644 (file)
@@ -26,6 +26,7 @@ import org.sonar.server.es.NewIndex;
 
 import static org.sonar.server.es.DefaultIndexSettingsElement.SORTABLE_ANALYZER;
 import static org.sonar.server.es.DefaultIndexSettingsElement.USER_SEARCH_GRAMS_ANALYZER;
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.newBuilder;
 
 /**
  * Definition of ES index "users", including settings and fields.
@@ -48,9 +49,10 @@ public class UserIndexDefinition implements IndexDefinition {
 
   @Override
   public void define(IndexDefinitionContext context) {
-    NewIndex index = context.create(INDEX_TYPE_USER.getIndex());
-
-    index.configureShards(config, 1);
+    NewIndex index = context.create(INDEX_TYPE_USER.getIndex(),
+      newBuilder(config)
+        .setDefaultNbOfShards(1)
+        .build());
 
     // type "user"
     NewIndex.NewIndexType mapping = index.createType(INDEX_TYPE_USER.getType());
index 79523f94a804ae406bbbc380f02bb538695b122f..0cbef7a16adf3c6c42115b565d59c978b77f5771 100644 (file)
@@ -24,6 +24,8 @@ import org.sonar.server.es.IndexDefinition;
 import org.sonar.server.es.IndexType;
 import org.sonar.server.es.NewIndex;
 
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.newBuilder;
+
 /**
  * Definition of ES index "views", including settings and fields.
  */
@@ -41,9 +43,11 @@ public class ViewIndexDefinition implements IndexDefinition {
 
   @Override
   public void define(IndexDefinitionContext context) {
-    NewIndex index = context.create(INDEX_TYPE_VIEW.getIndex());
-
-    index.configureShards(config, 5);
+    NewIndex index = context.create(
+      INDEX_TYPE_VIEW.getIndex(),
+      newBuilder(config)
+        .setDefaultNbOfShards(5)
+        .build());
 
     // type "view"
     NewIndex.NewIndexType mapping = index.createType(INDEX_TYPE_VIEW.getType());
index b3124bc1aaf2b9a35390f8511bea8b606e38b53d..86149653373617ec550e20427c6f7f3dad651feb 100644 (file)
@@ -20,6 +20,9 @@
 package org.sonar.server.es;
 
 import org.elasticsearch.cluster.metadata.IndexMetaData;
+import org.sonar.api.config.internal.MapSettings;
+
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.newBuilder;
 
 public class FakeIndexDefinition implements IndexDefinition {
 
@@ -37,7 +40,7 @@ public class FakeIndexDefinition implements IndexDefinition {
 
   @Override
   public void define(IndexDefinitionContext context) {
-    NewIndex index = context.create(INDEX);
+    NewIndex index = context.create(INDEX, newBuilder(new MapSettings().asConfig()).build());
     index.getSettings().put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, replicas);
     index.getSettings().put("index.refresh_interval", "-1");
     NewIndex.NewIndexType type = index.createType(INDEX_TYPE_FAKE.getType());
index 80da6dd045780ffa514a5f3ca047de40ffe5b0ac..b96d86437e85417635d59f940e8c5758c1731355 100644 (file)
@@ -38,11 +38,15 @@ import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.newBuilder;
 
 public class IndexCreatorTest {
 
+  private static final NewIndex.SettingsConfiguration settingsConfiguration = newBuilder(new MapSettings().asConfig()).build();
+
   @Rule
   public EsTester es = new EsTester();
+
   private MetadataIndexDefinition metadataIndexDefinition = new MetadataIndexDefinition(new MapSettings().asConfig());
   private MetadataIndex metadataIndex = new MetadataIndex(es.client());
 
@@ -72,7 +76,8 @@ public class IndexCreatorTest {
   public void mark_all_non_existing_index_types_as_uninitialized() throws Exception {
     MetadataIndex metadataIndexMock = mock(MetadataIndex.class);
     IndexDefinitions registry = new IndexDefinitions(new IndexDefinition[] {context -> {
-      NewIndex i = context.create("i");
+
+      NewIndex i = context.create("i", settingsConfiguration);
       i.createType("t1");
       i.createType("t2");
     }}, new MapSettings().asConfig());
@@ -160,7 +165,7 @@ public class IndexCreatorTest {
   public static class FakeIndexDefinition implements IndexDefinition {
     @Override
     public void define(IndexDefinitionContext context) {
-      NewIndex index = context.create("fakes");
+      NewIndex index = context.create("fakes", settingsConfiguration);
       NewIndex.NewIndexType mapping = index.createType("fake");
       mapping.keywordFieldBuilder("key").build();
       mapping.createDateTimeField("updatedAt");
@@ -170,7 +175,7 @@ public class IndexCreatorTest {
   public static class FakeIndexDefinitionV2 implements IndexDefinition {
     @Override
     public void define(IndexDefinitionContext context) {
-      NewIndex index = context.create("fakes");
+      NewIndex index = context.create("fakes", settingsConfiguration);
       NewIndex.NewIndexType mapping = index.createType("fake");
       mapping.keywordFieldBuilder("key").build();
       mapping.createDateTimeField("updatedAt");
index 0397075eb39fa92c75d07ec1b5b596b04904bbda..875fc9626fd095a4fd34c52b01dcbd8da9c08d07 100644 (file)
 package org.sonar.server.es;
 
 import org.junit.Test;
+import org.sonar.api.config.internal.MapSettings;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.fail;
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.newBuilder;
 
 public class IndexDefinitionContextTest {
+  private NewIndex.SettingsConfiguration emptySettingsConfiguration = newBuilder(new MapSettings().asConfig()).build();
 
   @Test
   public void create_indices() {
     IndexDefinition.IndexDefinitionContext context = new IndexDefinition.IndexDefinitionContext();
 
-    context.create("issues");
-    context.create("measures");
+    context.create("issues", emptySettingsConfiguration);
+    context.create("measures", emptySettingsConfiguration);
     assertThat(context.getIndices().keySet()).containsOnly("issues", "measures");
   }
 
@@ -39,9 +42,9 @@ public class IndexDefinitionContextTest {
   public void fail_to_create_twice_the_same_index() {
     IndexDefinition.IndexDefinitionContext context = new IndexDefinition.IndexDefinitionContext();
 
-    context.create("issues");
+    context.create("issues", emptySettingsConfiguration);
     try {
-      context.create("issues");
+      context.create("issues", emptySettingsConfiguration);
       fail();
     } catch (IllegalArgumentException ok) {
       assertThat(ok).hasMessage("Index already exists: issues");
index 1c3c30d710e7b6af9a368336879ce762059986b6..8433146a49dbf67c538bb1422c7650e359e7db2f 100644 (file)
@@ -22,8 +22,10 @@ package org.sonar.server.es;
 import org.junit.Test;
 
 import java.util.Arrays;
+import org.sonar.api.config.internal.MapSettings;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.newBuilder;
 
 public class IndexDefinitionHashTest {
 
@@ -42,7 +44,7 @@ public class IndexDefinitionHashTest {
   }
 
   private NewIndex createIndex() {
-    NewIndex newIndex = new NewIndex("fakes");
+    NewIndex newIndex = new NewIndex("fakes", newBuilder(new MapSettings().asConfig()).build());
     NewIndex.NewIndexType mapping = newIndex.createType("fake");
     mapping.setAttribute("list_attr", Arrays.asList("foo", "bar"));
     mapping.keywordFieldBuilder("key").build();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/es/NewIndexSettingsConfigurationTest.java b/server/sonar-server/src/test/java/org/sonar/server/es/NewIndexSettingsConfigurationTest.java
new file mode 100644 (file)
index 0000000..d2929dc
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.es;
+
+import java.util.Random;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.config.Configuration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.newBuilder;
+
+public class NewIndexSettingsConfigurationTest {
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  private Configuration mockConfiguration = mock(Configuration.class);
+
+  @Test
+  public void newBuilder_fails_with_NPE_when_Configuration_is_null() {
+    expectedException.expect(NullPointerException.class);
+    expectedException.expectMessage("configuration can't be null");
+
+    newBuilder(null);
+  }
+
+  @Test
+  public void setDefaultNbOfShards_fails_with_IAE_if_argument_is_zero() {
+    NewIndex.SettingsConfiguration.Builder underTest = newBuilder(mockConfiguration);
+
+    expectedException.expect(IllegalArgumentException.class);
+    expectedException.expectMessage("defaultNbOfShards must be >= 1");
+
+    underTest.setDefaultNbOfShards(0);
+  }
+
+  @Test
+  public void setDefaultNbOfShards_fails_with_IAE_if_argument_is_less_than_zero() {
+    NewIndex.SettingsConfiguration.Builder underTest = newBuilder(mockConfiguration);
+
+    expectedException.expect(IllegalArgumentException.class);
+    expectedException.expectMessage("defaultNbOfShards must be >= 1");
+
+    underTest.setDefaultNbOfShards(-1 - new Random().nextInt(10));
+  }
+
+  @Test
+  public void setDefaultNbOfShards_accepts_1() {
+    NewIndex.SettingsConfiguration.Builder underTest = newBuilder(mockConfiguration);
+
+    assertThat(underTest.setDefaultNbOfShards(1).build().getDefaultNbOfShards()).isEqualTo(1);
+  }
+
+  @Test
+  public void setDefaultNbOfShards_accepts_any_int_greater_than_1() {
+    NewIndex.SettingsConfiguration.Builder underTest = newBuilder(mockConfiguration);
+
+    int value = 1 + new Random().nextInt(200);
+
+    assertThat(underTest.setDefaultNbOfShards(value).build().getDefaultNbOfShards()).isEqualTo(value);
+  }
+
+  @Test
+  public void getDefaultNbOfShards_returns_1_when_not_explicitly_set() {
+    assertThat(newBuilder(mockConfiguration).build().getDefaultNbOfShards()).isEqualTo(1);
+  }
+
+  @Test
+  public void setRefreshInterval_fails_with_IAE_if_argument_is_zero() {
+    NewIndex.SettingsConfiguration.Builder underTest = newBuilder(mockConfiguration);
+
+    expectedException.expect(IllegalArgumentException.class);
+    expectedException.expectMessage("refreshInterval must be either -1 or strictly positive");
+
+    underTest.setRefreshInterval(0);
+  }
+
+  @Test
+  public void setRefreshInterval_fails_with_IAE_if_argument_is_less_than_minus_1() {
+    NewIndex.SettingsConfiguration.Builder underTest = newBuilder(mockConfiguration);
+
+    expectedException.expect(IllegalArgumentException.class);
+    expectedException.expectMessage("refreshInterval must be either -1 or strictly positive");
+
+    underTest.setRefreshInterval(-2 - new Random().nextInt(10));
+  }
+
+  @Test
+  public void setRefreshInterval_accepts_minus_1() {
+    NewIndex.SettingsConfiguration.Builder underTest = newBuilder(mockConfiguration);
+
+    assertThat(underTest.setRefreshInterval(-1).build().getRefreshInterval()).isEqualTo(-1);
+  }
+
+  @Test
+  public void setRefreshInterval_accepts_any_int_greater_than_1() {
+    NewIndex.SettingsConfiguration.Builder underTest = newBuilder(mockConfiguration);
+
+    int value = 1 + new Random().nextInt(200);
+
+    assertThat(underTest.setRefreshInterval(value).build().getRefreshInterval()).isEqualTo(value);
+  }
+
+  @Test
+  public void getRefreshInterval_returns_30_when_not_explicitly_set() {
+    assertThat(newBuilder(mockConfiguration).build().getRefreshInterval()).isEqualTo(30);
+  }
+}
index 16dba3566b97a0367944e0d362105beaad9aff62..a3dcf87c1dfa1abd2e555271b5afd401d9ec1b0b 100644 (file)
@@ -32,26 +32,54 @@ import org.sonar.process.ProcessProperties;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.data.MapEntry.entry;
 import static org.junit.Assert.fail;
+import static org.sonar.process.ProcessProperties.CLUSTER_ENABLED;
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.newBuilder;
 
 public class NewIndexTest {
 
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
 
+  private MapSettings settings = new MapSettings();
+  private NewIndex.SettingsConfiguration defaultSettingsConfiguration = newBuilder(settings.asConfig()).build();
+
+  @Test
+  public void getName_returns_constructor_argument() {
+    assertThat(new NewIndex("foo", defaultSettingsConfiguration).getName()).isEqualTo("foo");
+  }
+
+  @Test
+  public void no_types_of_none_are_specified() {
+    assertThat(new NewIndex("foo", defaultSettingsConfiguration).getTypes()).isEmpty();
+  }
+
   @Test
-  public void most_basic_index() {
-    NewIndex index = new NewIndex("issues");
-    assertThat(index.getName()).isEqualTo("issues");
-    assertThat(index.getTypes()).isEmpty();
-    Settings settings = index.getSettings().build();
-    // test some basic settings
-    assertThat(settings.get("index.number_of_shards")).isNotEmpty();
+  public void verify_default_index_settings_in_standalone() {
+    Settings underTest = new NewIndex("issues", defaultSettingsConfiguration).getSettings().build();
+
+    assertThat(underTest.get("index.number_of_shards")).isNotEmpty();
+    assertThat(underTest.get("index.mapper.dynamic")).isEqualTo("false");
+    assertThat(underTest.get("index.refresh_interval")).isEqualTo("30s");
+    assertThat(underTest.get("index.number_of_shards")).isEqualTo("1");
+    assertThat(underTest.get("index.number_of_replicas")).isEqualTo("0");
+  }
+
+  @Test
+  public void verify_default_index_settings_in_cluster() {
+    settings.setProperty(CLUSTER_ENABLED, "true");
+    Settings underTest = new NewIndex("issues", defaultSettingsConfiguration).getSettings().build();
+
+    assertThat(underTest.get("index.number_of_shards")).isNotEmpty();
+    assertThat(underTest.get("index.mapper.dynamic")).isEqualTo("false");
+    assertThat(underTest.get("index.refresh_interval")).isEqualTo("30s");
+    assertThat(underTest.get("index.number_of_shards")).isEqualTo("1");
+    assertThat(underTest.get("index.number_of_replicas")).isEqualTo("1");
   }
 
   @Test
   public void index_name_is_lower_case() {
     try {
-      new NewIndex("Issues");
+      new NewIndex("Issues", defaultSettingsConfiguration);
       fail();
     } catch (IllegalArgumentException e) {
       assertThat(e).hasMessage("Index name must be lower-case: Issues");
@@ -60,7 +88,7 @@ public class NewIndexTest {
 
   @Test
   public void define_fields() {
-    NewIndex index = new NewIndex("issues");
+    NewIndex index = new NewIndex("issues", defaultSettingsConfiguration);
     NewIndex.NewIndexType mapping = index.createType("issue");
     mapping.setAttribute("dynamic", "true");
     mapping.setProperty("foo_field", ImmutableMap.of("type", "keyword"));
@@ -90,7 +118,7 @@ public class NewIndexTest {
 
   @Test
   public void define_string_field() {
-    NewIndex index = new NewIndex("issues");
+    NewIndex index = new NewIndex("issues", defaultSettingsConfiguration);
     NewIndex.NewIndexType mapping = index.createType("issue");
     mapping.keywordFieldBuilder("basic_field").build();
     mapping.keywordFieldBuilder("not_searchable_field").disableSearch().build();
@@ -119,7 +147,7 @@ public class NewIndexTest {
 
   @Test
   public void define_nested_field() {
-    NewIndex index = new NewIndex("projectmeasures");
+    NewIndex index = new NewIndex("projectmeasures", defaultSettingsConfiguration);
     NewIndex.NewIndexType mapping = index.createType("projectmeasures");
 
     mapping.nestedFieldBuilder("measures")
@@ -139,7 +167,7 @@ public class NewIndexTest {
     expectedException.expect(IllegalArgumentException.class);
     expectedException.expectMessage("At least one sub-field must be declared in nested property 'measures'");
 
-    NewIndex index = new NewIndex("projectmeasures");
+    NewIndex index = new NewIndex("projectmeasures", defaultSettingsConfiguration);
     NewIndex.NewIndexType mapping = index.createType("project_measures");
 
     mapping.nestedFieldBuilder("measures").build();
@@ -147,7 +175,7 @@ public class NewIndexTest {
 
   @Test
   public void use_default_doc_values() {
-    NewIndex index = new NewIndex("issues");
+    NewIndex index = new NewIndex("issues", defaultSettingsConfiguration);
     NewIndex.NewIndexType mapping = index.createType("issue");
     mapping.keywordFieldBuilder("the_doc_value").build();
 
@@ -158,28 +186,26 @@ public class NewIndexTest {
 
   @Test
   public void default_shards_and_replicas() {
-    NewIndex index = new NewIndex("issues");
-    index.configureShards(new MapSettings().asConfig(), 5);
+    NewIndex index = new NewIndex("issues", newBuilder(settings.asConfig()).setDefaultNbOfShards(5).build());
+
     assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_SHARDS)).isEqualTo("5");
     assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_REPLICAS)).isEqualTo("0");
   }
 
   @Test
   public void five_shards_and_one_replica_by_default_on_cluster() {
-    NewIndex index = new NewIndex("issues");
-    MapSettings settings = new MapSettings();
-    settings.setProperty(ProcessProperties.CLUSTER_ENABLED, "true");
-    index.configureShards(settings.asConfig(), 5);
+    settings.setProperty(CLUSTER_ENABLED, "true");
+    NewIndex index = new NewIndex("issues", newBuilder(settings.asConfig()).setDefaultNbOfShards(5).build());
+
     assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_SHARDS)).isEqualTo("5");
     assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_REPLICAS)).isEqualTo("1");
   }
 
   @Test
   public void customize_number_of_shards() {
-    NewIndex index = new NewIndex("issues");
-    MapSettings settings = new MapSettings();
     settings.setProperty("sonar.search.issues.shards", "3");
-    index.configureShards(settings.asConfig(), 5);
+    NewIndex index = new NewIndex("issues", newBuilder(settings.asConfig()).setDefaultNbOfShards(5).build());
+
     assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_SHARDS)).isEqualTo("3");
     // keep default value
     assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_REPLICAS)).isEqualTo("0");
@@ -187,52 +213,68 @@ public class NewIndexTest {
 
   @Test
   public void default_number_of_replicas_on_standalone_instance_must_be_0() {
-    NewIndex index = new NewIndex("issues");
-    MapSettings settings = new MapSettings();
-    index.configureShards(settings.asConfig(), 5);
+    NewIndex index = new NewIndex("issues", newBuilder(settings.asConfig()).setDefaultNbOfShards(5).build());
+
     assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_REPLICAS)).isEqualTo("0");
   }
 
   @Test
   public void default_number_of_replicas_on_non_enabled_cluster_must_be_0() {
-    NewIndex index = new NewIndex("issues");
-    MapSettings settings = new MapSettings();
-    settings.setProperty(ProcessProperties.CLUSTER_ENABLED, "false");
-    index.configureShards(settings.asConfig(), 5);
+    settings.setProperty(CLUSTER_ENABLED, "false");
+    NewIndex index = new NewIndex("issues", newBuilder(settings.asConfig()).setDefaultNbOfShards(5).build());
+
     assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_REPLICAS)).isEqualTo("0");
   }
 
   @Test
   public void default_number_of_replicas_on_cluster_instance_must_be_1() {
-    NewIndex index = new NewIndex("issues");
-    MapSettings settings = new MapSettings();
-    settings.setProperty(ProcessProperties.CLUSTER_ENABLED, "true");
-    index.configureShards(settings.asConfig(), 5);
+    settings.setProperty(CLUSTER_ENABLED, "true");
+    NewIndex index = new NewIndex("issues", newBuilder(settings.asConfig()).setDefaultNbOfShards(5).build());
+
     assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_REPLICAS)).isEqualTo("1");
   }
 
   @Test
   public void when_number_of_replicas_on_cluster_is_specified_to_zero_default_value_must_not_be_used() {
-    NewIndex index = new NewIndex("issues");
-    MapSettings settings = new MapSettings();
-    settings.setProperty(ProcessProperties.CLUSTER_ENABLED, "true");
+    settings.setProperty(CLUSTER_ENABLED, "true");
     settings.setProperty(ProcessProperties.SEARCH_REPLICAS, "0");
-    index.configureShards(settings.asConfig(), 5);
+    NewIndex index = new NewIndex("issues", newBuilder(settings.asConfig()).setDefaultNbOfShards(5).build());
+
     assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_REPLICAS)).isEqualTo("0");
   }
 
   @Test
-  public void customize_number_of_replicas() {
-    NewIndex index = new NewIndex("issues");
-    MapSettings settings = new MapSettings();
+  public void index_defined_with_specified_number_of_replicas_when_cluster_enabled() {
+    settings.setProperty(CLUSTER_ENABLED, "true");
     settings.setProperty(ProcessProperties.SEARCH_REPLICAS, "3");
-    index.configureShards(settings.asConfig(), 5);
+    NewIndex index = new NewIndex("issues", newBuilder(settings.asConfig()).setDefaultNbOfShards(5).build());
+
     assertThat(index.getSettings().get(IndexMetaData.SETTING_NUMBER_OF_REPLICAS)).isEqualTo("3");
   }
 
+  @Test
+  public void fail_when_replica_customization_cant_be_parsed() throws Exception {
+    settings.setProperty(CLUSTER_ENABLED, "true");
+    settings.setProperty(ProcessProperties.SEARCH_REPLICAS, "ꝱꝲꝳପ");
+    NewIndex.SettingsConfiguration settingsConfiguration = newBuilder(settings.asConfig()).setDefaultNbOfShards(5).build();
+
+    expectedException.expect(IllegalStateException.class);
+    expectedException.expectMessage("The property 'sonar.search.replicas' is not an int value: For input string: \"ꝱꝲꝳପ\"");
+
+    new NewIndex("issues", settingsConfiguration);
+  }
+
+  @Test
+  public void in_standalone_searchReplicas_is_not_overridable() throws Exception {
+    settings.setProperty(ProcessProperties.SEARCH_REPLICAS, "5");
+    NewIndex index = new NewIndex("issues", defaultSettingsConfiguration);
+
+    assertThat(index.getSettings().get("index.number_of_replicas")).isEqualTo("0");
+  }
+
   @Test
   public void index_with_source() {
-    NewIndex index = new NewIndex("issues");
+    NewIndex index = new NewIndex("issues", defaultSettingsConfiguration);
     NewIndex.NewIndexType mapping = index.createType("issue");
     mapping.setEnableSource(true);
 
@@ -243,7 +285,7 @@ public class NewIndexTest {
 
   @Test
   public void index_without_source() {
-    NewIndex index = new NewIndex("issues");
+    NewIndex index = new NewIndex("issues", defaultSettingsConfiguration);
     NewIndex.NewIndexType mapping = index.createType("issue");
     mapping.setEnableSource(false);
 
@@ -254,7 +296,7 @@ public class NewIndexTest {
 
   @Test
   public void index_requires_project_authorization() {
-    NewIndex index = new NewIndex("issues");
+    NewIndex index = new NewIndex("issues", defaultSettingsConfiguration);
     index.createType("issue")
       // creates a second type "authorization" and configures _parent and _routing fields
       .requireProjectAuthorization();
index 8d416609aec780344a24639b7b51a08c8565d965..18b1b3c8fe9c72b86b0381793839f0c6b79c74c5 100644 (file)
  */
 package org.sonar.server.permission.index;
 
+import org.sonar.api.config.internal.MapSettings;
 import org.sonar.server.es.IndexDefinition;
 import org.sonar.server.es.IndexType;
 import org.sonar.server.es.NewIndex;
 
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.MANUAL_REFRESH_INTERVAL;
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.newBuilder;
+
 public class FooIndexDefinition implements IndexDefinition {
 
   public static final String FOO_INDEX = "foos";
@@ -33,8 +37,7 @@ public class FooIndexDefinition implements IndexDefinition {
 
   @Override
   public void define(IndexDefinitionContext context) {
-    NewIndex index = context.create(FOO_INDEX);
-    index.refreshHandledByIndexer();
+    NewIndex index = context.create(FOO_INDEX, newBuilder(new MapSettings().asConfig()).setRefreshInterval(MANUAL_REFRESH_INTERVAL).build());
 
     NewIndex.NewIndexType type = index.createType(FOO_TYPE)
       .requireProjectAuthorization();