import org.sonar.api.server.ServerSide;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
+import org.sonar.process.ProcessProperties;
import org.sonar.server.es.IndexDefinitions.Index;
import org.sonar.server.es.metadata.EsDbCompatibility;
import org.sonar.server.es.metadata.MetadataIndex;
for (Index index : definitions.getIndices().values()) {
boolean exists = client.prepareIndicesExist(index.getName()).get().isExists();
if (exists && !index.getName().equals(MetadataIndexDefinition.INDEX_TYPE_METADATA.getIndex()) && hasDefinitionChange(index)) {
+ verifyNotBlueGreenDeployment(index.getName());
LOGGER.info("Delete Elasticsearch index {} (structure changed)", index.getName());
deleteIndex(index.getName());
exists = false;
}
}
+ private void verifyNotBlueGreenDeployment(String indexToBeDeleted) {
+ if (configuration.getBoolean(ProcessProperties.Property.BLUE_GREEN_ENABLED.getKey()).orElse(false)) {
+ throw new IllegalStateException("Blue/green deployment is not supported. Elasticsearch index [" + indexToBeDeleted + "] changed and needs to be dropped.");
+ }
+ }
+
@Override
public void stop() {
// nothing to do
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
@Rule
public LogTester logTester = new LogTester();
-
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
@Rule
public EsTester es = EsTester.createCustom();
IndexCreator underTest = startNewCreator(new FakeIndexDefinition());
// check that index is created with related mapping
- ImmutableOpenMap<String, ImmutableOpenMap<String, MappingMetaData>> mappings = mappings();
- MappingMetaData mapping = mappings.get("fakes").get("fake");
- assertThat(mapping.type()).isEqualTo("fake");
- assertThat(mapping.getSourceAsMap()).isNotEmpty();
- assertThat(countMappingFields(mapping)).isEqualTo(2);
- assertThat(field(mapping, "updatedAt").get("type")).isEqualTo("date");
+ verifyFakeIndex();
// of course do not delete indices on stop
underTest.stop();
assertThat(mappings()).isNotEmpty();
}
+ @Test
+ public void creation_of_new_index_is_supported_in_blue_green_deployment() {
+ enableBlueGreenDeployment();
+
+ startNewCreator(new FakeIndexDefinition());
+
+ verifyFakeIndex();
+ }
+
@Test
public void mark_all_non_existing_index_types_as_uninitialized() {
startNewCreator(context -> {
assertThat(es.client().prepareGet(fakeIndexType, id).get().isExists()).isFalse();
}
+ @Test
+ public void fail_to_recreate_index_on_definition_changes_if_blue_green_deployment() {
+ enableBlueGreenDeployment();
+
+ // v1
+ startNewCreator(new FakeIndexDefinition());
+
+ // v2
+ expectedException.expect(IllegalStateException.class);
+ expectedException.expectMessage("Blue/green deployment is not supported. Elasticsearch index [fakes] changed and needs to be dropped.");
+
+ startNewCreator(new FakeIndexDefinitionV2());
+ }
+
+ private void enableBlueGreenDeployment() {
+ settings.setProperty("sonar.blueGreenEnabled", "true");
+ }
+
@Test
public void do_not_recreate_index_on_unchanged_definition() {
// v1
es.putDocuments(FakeIndexDefinition.INDEX_TYPE, ImmutableMap.of("key", "foo"));
}
+ private void verifyFakeIndex() {
+ ImmutableOpenMap<String, ImmutableOpenMap<String, MappingMetaData>> mappings = mappings();
+ MappingMetaData mapping = mappings.get("fakes").get("fake");
+ assertThat(mapping.type()).isEqualTo("fake");
+ assertThat(mapping.getSourceAsMap()).isNotEmpty();
+ assertThat(countMappingFields(mapping)).isEqualTo(2);
+ assertThat(field(mapping, "updatedAt").get("type")).isEqualTo("date");
+ }
+
private static class FakeIndexDefinition implements IndexDefinition {
+
private static final IndexType INDEX_TYPE = new IndexType("fakes", "fake");
@Override
mapping.createDateTimeField("updatedAt");
}
}
-
private static class FakeIndexDefinitionV2 implements IndexDefinition {
+
@Override
public void define(IndexDefinitionContext context) {
NewIndex index = context.create("fakes", SETTINGS_CONFIGURATION);