aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-server
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2019-06-13 09:19:48 +0200
committerSonarTech <sonartech@sonarsource.com>2019-06-14 20:21:10 +0200
commit00e91c1362a5c02384ba9145ad02d9289ba5e686 (patch)
tree0da19620437aae29cf2922727ba1251d6f2b5165 /server/sonar-server
parent94b72ea61ba5dd9a16c90f5674df234f1131baf4 (diff)
downloadsonarqube-00e91c1362a5c02384ba9145ad02d9289ba5e686.tar.gz
sonarqube-00e91c1362a5c02384ba9145ad02d9289ba5e686.zip
SONAR-12187 make ES indices read-write at startup if are read-only
Diffstat (limited to 'server/sonar-server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/es/IndexCreator.java30
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/es/IndexCreatorTest.java48
2 files changed, 77 insertions, 1 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/es/IndexCreator.java b/server/sonar-server/src/main/java/org/sonar/server/es/IndexCreator.java
index 4bee944bbfa..0a45e823dbe 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/es/IndexCreator.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/es/IndexCreator.java
@@ -26,6 +26,8 @@ import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
+import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
+import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.cluster.health.ClusterHealthStatus;
import org.elasticsearch.common.settings.Settings;
@@ -81,6 +83,8 @@ public class IndexCreator implements Startable {
metadataIndexDefinition.define(context);
NewIndex index = context.getIndices().values().iterator().next();
createIndex(index.build(), false);
+ } else {
+ ensureWritable(metadataMainType);
}
checkDbCompatibility(definitions.getIndices().values());
@@ -94,10 +98,36 @@ public class IndexCreator implements Startable {
createIndex(index, true);
} else if (hasDefinitionChange(index)) {
updateIndex(index);
+ } else {
+ ensureWritable(index.getMainType());
}
});
}
+ private void ensureWritable(IndexType.IndexMainType mainType) {
+ if (isReadOnly(mainType)) {
+ removeReadOnly(mainType);
+ }
+ }
+
+ private boolean isReadOnly(IndexType.IndexMainType mainType) {
+ String indexName = mainType.getIndex().getName();
+ String readOnly = client.nativeClient().admin().indices().getSettings(new GetSettingsRequest().indices(indexName)).actionGet()
+ .getSetting(indexName, "index.blocks.read_only_allow_delete");
+ return readOnly != null && "true".equalsIgnoreCase(readOnly);
+ }
+
+ private void removeReadOnly(IndexType.IndexMainType mainType) {
+ LOGGER.info("Index [{}] is read-only. Making it writable...", mainType.getIndex().getName());
+
+ String indexName = mainType.getIndex().getName();
+ Settings.Builder builder = Settings.builder();
+ builder.putNull("index.blocks.read_only_allow_delete");
+ client.nativeClient().admin().indices()
+ .updateSettings(new UpdateSettingsRequest().indices(indexName).settings(builder.build()))
+ .actionGet();
+ }
+
@Override
public void stop() {
// nothing to do
diff --git a/server/sonar-server/src/test/java/org/sonar/server/es/IndexCreatorTest.java b/server/sonar-server/src/test/java/org/sonar/server/es/IndexCreatorTest.java
index d3d6797a4d3..b2b26d951a7 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/es/IndexCreatorTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/es/IndexCreatorTest.java
@@ -24,9 +24,12 @@ import com.google.common.collect.Sets;
import java.util.Map;
import java.util.function.Consumer;
import javax.annotation.CheckForNull;
+import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest;
+import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.common.collect.ImmutableOpenMap;
+import org.elasticsearch.common.settings.Settings;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -174,6 +177,49 @@ public class IndexCreatorTest {
.contains("Create type metadatas/metadata");
}
+ @Test
+ public void start_makes_metadata_index_read_write_if_read_only() {
+ run(new FakeIndexDefinition());
+
+ IndexMainType mainType = MetadataIndexDefinition.TYPE_METADATA;
+ makeReadOnly(mainType);
+
+ run(new FakeIndexDefinition());
+
+ assertThat(isNotReadOnly(mainType)).isTrue();
+ }
+
+ @Test
+ public void start_makes_index_read_write_if_read_only() {
+ FakeIndexDefinition fakeIndexDefinition = new FakeIndexDefinition();
+ IndexMainType fakeIndexMainType= FakeIndexDefinition.INDEX_TYPE.getMainType();
+ run(fakeIndexDefinition);
+
+ IndexMainType mainType = MetadataIndexDefinition.TYPE_METADATA;
+ makeReadOnly(mainType);
+ makeReadOnly(fakeIndexMainType);
+
+ run(fakeIndexDefinition);
+
+ assertThat(isNotReadOnly(mainType)).isTrue();
+ assertThat(isNotReadOnly(fakeIndexMainType)).isTrue();
+ }
+
+ private boolean isNotReadOnly(IndexMainType mainType) {
+ String indexName = mainType.getIndex().getName();
+ String readOnly = es.client().nativeClient().admin().indices().getSettings(new GetSettingsRequest().indices(indexName)).actionGet()
+ .getSetting(indexName, "index.blocks.read_only_allow_delete");
+ return readOnly == null;
+ }
+
+ private void makeReadOnly(IndexMainType mainType) {
+ Settings.Builder builder = Settings.builder();
+ builder.put("index.blocks.read_only_allow_delete", "true");
+ es.client().nativeClient().admin().indices()
+ .updateSettings(new UpdateSettingsRequest().indices(mainType.getIndex().getName()).settings(builder.build()))
+ .actionGet();
+ }
+
private void enableBlueGreenDeployment() {
settings.setProperty("sonar.blueGreenEnabled", "true");
}
@@ -237,7 +283,7 @@ public class IndexCreatorTest {
}
private static class FakeIndexDefinition implements IndexDefinition {
- private static final IndexMainType INDEX_TYPE = main(Index.simple("fakes"), "fake");
+ static final IndexMainType INDEX_TYPE = main(Index.simple("fakes"), "fake");
@Override
public void define(IndexDefinitionContext context) {