Browse Source

SONAR-12187 make ES indices read-write at startup if are read-only

tags/7.8
Sébastien Lesaint 4 years ago
parent
commit
00e91c1362

+ 30
- 0
server/sonar-server/src/main/java/org/sonar/server/es/IndexCreator.java View File

@@ -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

+ 47
- 1
server/sonar-server/src/test/java/org/sonar/server/es/IndexCreatorTest.java View File

@@ -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) {

Loading…
Cancel
Save