/**
* This file is part of Graylog.
*
* Graylog is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Graylog 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Graylog. If not, see <http://www.gnu.org/licenses/>.
*/
package org.graylog2.migrations;
import com.google.common.collect.ImmutableList;
import org.graylog2.configuration.ElasticsearchConfiguration;
import org.graylog2.events.ClusterEventBus;
import org.graylog2.indexer.indexset.DefaultIndexSetCreated;
import org.graylog2.indexer.indexset.IndexSetConfig;
import org.graylog2.indexer.indexset.IndexSetService;
import org.graylog2.indexer.indexset.V20161216123500_Succeeded;
import org.graylog2.indexer.indexset.events.IndexSetCreatedEvent;
import org.graylog2.plugin.cluster.ClusterConfigService;
import org.graylog2.plugin.indexer.retention.RetentionStrategyConfig;
import org.graylog2.plugin.indexer.rotation.RotationStrategyConfig;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
public class V20161216123500_DefaultIndexSetMigrationTest {
@Rule
public final MockitoRule mockitoRule = MockitoJUnit.rule();
@Rule
public final ExpectedException expectedException = ExpectedException.none();
@Mock
private IndexSetService indexSetService;
@Mock
private ClusterConfigService clusterConfigService;
@Mock
private ClusterEventBus clusterEventBus;
private final ElasticsearchConfiguration elasticsearchConfiguration = new ElasticsearchConfiguration();
private Migration migration;
@Before
public void setUpService() throws Exception {
migration = new V20161216123500_DefaultIndexSetMigration(
elasticsearchConfiguration,
indexSetService,
clusterConfigService,
clusterEventBus);
}
@Test
public void upgradeCreatesDefaultIndexSet() throws Exception {
final RotationStrategyConfig rotationStrategyConfig = mock(RotationStrategyConfig.class);
final RetentionStrategyConfig retentionStrategyConfig = mock(RetentionStrategyConfig.class);
final IndexSetConfig defaultConfig = IndexSetConfig.builder()
.id("id")
.title("title")
.description("description")
.indexPrefix("prefix")
.shards(1)
.replicas(0)
.rotationStrategy(rotationStrategyConfig)
.retentionStrategy(retentionStrategyConfig)
.creationDate(ZonedDateTime.of(2016, 10, 12, 0, 0, 0, 0, ZoneOffset.UTC))
.indexAnalyzer("standard")
.indexTemplateName("prefix-template")
.indexOptimizationMaxNumSegments(1)
.indexOptimizationDisabled(false)
.build();
final IndexSetConfig additionalConfig = defaultConfig.toBuilder()
.id("foo")
.indexPrefix("foo")
.build();
final IndexSetConfig savedDefaultConfig = defaultConfig.toBuilder()
.indexAnalyzer(elasticsearchConfiguration.getAnalyzer())
.indexTemplateName(elasticsearchConfiguration.getTemplateName())
.indexOptimizationMaxNumSegments(elasticsearchConfiguration.getIndexOptimizationMaxNumSegments())
.indexOptimizationDisabled(elasticsearchConfiguration.isDisableIndexOptimization())
.build();
final IndexSetConfig savedAdditionalConfig = additionalConfig.toBuilder()
.indexAnalyzer(elasticsearchConfiguration.getAnalyzer())
.indexTemplateName("foo-template")
.indexOptimizationMaxNumSegments(elasticsearchConfiguration.getIndexOptimizationMaxNumSegments())
.indexOptimizationDisabled(elasticsearchConfiguration.isDisableIndexOptimization())
.build();
when(indexSetService.save(any(IndexSetConfig.class))).thenReturn(savedAdditionalConfig, savedDefaultConfig);
when(indexSetService.getDefault()).thenReturn(defaultConfig);
when(indexSetService.findAll()).thenReturn(ImmutableList.of(defaultConfig, additionalConfig));
when(clusterConfigService.get(DefaultIndexSetCreated.class)).thenReturn(DefaultIndexSetCreated.create());
final ArgumentCaptor<IndexSetConfig> indexSetConfigCaptor = ArgumentCaptor.forClass(IndexSetConfig.class);
migration.upgrade();
verify(indexSetService, times(2)).save(indexSetConfigCaptor.capture());
verify(clusterEventBus, times(2)).post(any(IndexSetCreatedEvent.class));
verify(clusterConfigService).write(V20161216123500_Succeeded.create());
final List<IndexSetConfig> allValues = indexSetConfigCaptor.getAllValues();
assertThat(allValues).hasSize(2);
final IndexSetConfig capturedDefaultIndexSetConfig = allValues.get(0);
assertThat(capturedDefaultIndexSetConfig.id()).isEqualTo("id");
assertThat(capturedDefaultIndexSetConfig.title()).isEqualTo("title");
assertThat(capturedDefaultIndexSetConfig.description()).isEqualTo("description");
assertThat(capturedDefaultIndexSetConfig.indexPrefix()).isEqualTo("prefix");
assertThat(capturedDefaultIndexSetConfig.shards()).isEqualTo(1);
assertThat(capturedDefaultIndexSetConfig.replicas()).isEqualTo(0);
assertThat(capturedDefaultIndexSetConfig.rotationStrategy()).isEqualTo(rotationStrategyConfig);
assertThat(capturedDefaultIndexSetConfig.retentionStrategy()).isEqualTo(retentionStrategyConfig);
assertThat(capturedDefaultIndexSetConfig.indexAnalyzer()).isEqualTo(elasticsearchConfiguration.getAnalyzer());
assertThat(capturedDefaultIndexSetConfig.indexTemplateName()).isEqualTo(elasticsearchConfiguration.getTemplateName());
assertThat(capturedDefaultIndexSetConfig.indexOptimizationMaxNumSegments()).isEqualTo(elasticsearchConfiguration.getIndexOptimizationMaxNumSegments());
assertThat(capturedDefaultIndexSetConfig.indexOptimizationDisabled()).isEqualTo(elasticsearchConfiguration.isDisableIndexOptimization());
final IndexSetConfig capturedAdditionalIndexSetConfig = allValues.get(1);
assertThat(capturedAdditionalIndexSetConfig.id()).isEqualTo("foo");
assertThat(capturedAdditionalIndexSetConfig.title()).isEqualTo("title");
assertThat(capturedAdditionalIndexSetConfig.description()).isEqualTo("description");
assertThat(capturedAdditionalIndexSetConfig.indexPrefix()).isEqualTo("foo");
assertThat(capturedAdditionalIndexSetConfig.shards()).isEqualTo(1);
assertThat(capturedAdditionalIndexSetConfig.replicas()).isEqualTo(0);
assertThat(capturedAdditionalIndexSetConfig.rotationStrategy()).isEqualTo(rotationStrategyConfig);
assertThat(capturedAdditionalIndexSetConfig.retentionStrategy()).isEqualTo(retentionStrategyConfig);
assertThat(capturedAdditionalIndexSetConfig.indexAnalyzer()).isEqualTo(elasticsearchConfiguration.getAnalyzer());
assertThat(capturedAdditionalIndexSetConfig.indexTemplateName()).isEqualTo("foo-template");
assertThat(capturedAdditionalIndexSetConfig.indexOptimizationMaxNumSegments()).isEqualTo(elasticsearchConfiguration.getIndexOptimizationMaxNumSegments());
assertThat(capturedAdditionalIndexSetConfig.indexOptimizationDisabled()).isEqualTo(elasticsearchConfiguration.isDisableIndexOptimization());
}
@Test
public void upgradeFailsIfDefaultIndexSetHasNotBeenCreated() throws Exception {
when(clusterConfigService.get(DefaultIndexSetCreated.class)).thenReturn(null);
expectedException.expect(IllegalStateException.class);
expectedException.expectMessage("The default index set hasn't been created yet. This is a bug!");
migration.upgrade();
}
@Test
public void migrationDoesNotRunAgainIfMigrationWasSuccessfulBefore() throws Exception {
when(clusterConfigService.get(V20161216123500_Succeeded.class)).thenReturn(V20161216123500_Succeeded.create());
migration.upgrade();
verify(clusterConfigService).get(V20161216123500_Succeeded.class);
verifyNoMoreInteractions(clusterConfigService);
verifyZeroInteractions(clusterEventBus);
verifyZeroInteractions(indexSetService);
}
}