package com.inin.analytics;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.io.IOException;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.test.TestingServer;
import org.joda.time.DateTime;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import com.inin.analytics.elasticsearch.index.rotation.ExampleElasticsearchIndexRotationStrategyZookeeper;
import com.inin.analytics.elasticsearch.index.rotation.RebuildPipelineState;
import com.inin.analytics.elasticsearch.index.rotation.ElasticSearchIndexMetadata;
import com.inin.analytics.elasticsearch.index.routing.ElasticsearchRoutingStrategyV1;
import com.inin.analytics.elasticsearch.index.selector.RealtimeIndexSelectionStrategyLagged;
@RunWith(MockitoJUnitRunner.class)
public class IndexRotationStrategyZookeeperTest {
private static final Integer ZOOKEEPER_EMBEDED_PORT = 2181;
private TestingServer zk = null;
private ExampleElasticsearchIndexRotationStrategyZookeeper rotation;
@Before
public void setup() throws Exception {
zk = new TestingServer(ZOOKEEPER_EMBEDED_PORT);
rotation = new ExampleElasticsearchIndexRotationStrategyZookeeper();
rotation.setCurator(getCurator());
rotation.init();
}
public CuratorFramework getCurator() throws InterruptedException {
ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework curator = CuratorFrameworkFactory.newClient("localhost", 10000, 10000, retryPolicy);
curator.start();
curator.getZookeeperClient().blockUntilConnectedOrTimedOut();
return curator;
}
@After
public void close() throws IOException {
zk.close();
}
@Test
public final void testRegisterAndGet() throws Exception {
DateTime now = new DateTime();
ElasticSearchIndexMetadata metaData = new ElasticSearchIndexMetadata();
metaData.setIndexNameAtBirth("a");
metaData.setNumShardsPerOrg(2);
metaData.setRebuiltIndexAlias("b");
metaData.setRebuiltIndexName("b");
metaData.setRoutingStrategyClassName(ElasticsearchRoutingStrategyV1.class.getName());
rotation.registerIndexAvailableOnRotation(metaData);
// NodeCache curator recipe is async so we loop for up to 1sec waiting for the watcher to react. Polling sucks, but it beats Thread.sleep(1000) and generally happens in a few ms.
long timer = System.currentTimeMillis();
while(true) {
ElasticSearchIndexMetadata readMetaData = rotation.getElasticSearchIndexMetadata(metaData.getIndexNameAtBirth());
assertEquals(readMetaData.getIndexNameAtBirth(), metaData.getIndexNameAtBirth());
if(readMetaData.getRebuiltIndexName() != null) {
// Assert that rotation lag is accounted for
assertEquals(readMetaData.getRebuiltIndexName(), metaData.getRebuiltIndexName());
break;
}
if(System.currentTimeMillis() - timer > 1000) {
fail("NodeCache failed to update with latest value in a reasonable amount of time");
}
}
}
@Test
public void testRealtimeIndexSelectionStrategyLagged() {
DateTime now = new DateTime();
ElasticSearchIndexMetadata metaData = new ElasticSearchIndexMetadata();
metaData.setIndexNameAtBirth("a");
metaData.setNumShardsPerOrg(2);
metaData.setRebuiltIndexAlias("b");
metaData.setRebuiltIndexName("bb");
metaData.setRoutingStrategyClassName(ElasticsearchRoutingStrategyV1.class.getName());
RealtimeIndexSelectionStrategyLagged strategy = new RealtimeIndexSelectionStrategyLagged(2);
metaData.setDate(now.toLocalDate());
assertEquals(strategy.getIndexReadable(metaData), "a");
assertEquals(strategy.getIndexWritable(metaData), "a");
metaData.setDate(now.minusDays(1).toLocalDate());
assertEquals(strategy.getIndexReadable(metaData), "a");
assertEquals(strategy.getIndexWritable(metaData), "a");
metaData.setDate(now.minusDays(2).toLocalDate());
assertEquals(strategy.getIndexReadable(metaData), "b");
assertEquals(strategy.getIndexWritable(metaData), "bb");
metaData.setDate(now.minusDays(3).toLocalDate());
assertEquals(strategy.getIndexReadable(metaData), "b");
assertEquals(strategy.getIndexWritable(metaData), "bb");
metaData.setRebuiltIndexName(null);
metaData.setRebuiltIndexAlias(null);
assertEquals(strategy.getIndexWritable(metaData), "a");
}
@Test
public void testRealtimeIndexSelectionStrategyLagged_BackwardsCompatibility() {
DateTime now = new DateTime();
ElasticSearchIndexMetadata metaData = new ElasticSearchIndexMetadata();
metaData.setIndexNameAtBirth("a");
metaData.setNumShardsPerOrg(2);
metaData.setRebuiltIndexAlias("b");
metaData.setRoutingStrategyClassName(ElasticsearchRoutingStrategyV1.class.getName());
RealtimeIndexSelectionStrategyLagged strategy = new RealtimeIndexSelectionStrategyLagged(2);
metaData.setDate(now.minusDays(2).toLocalDate());
assertEquals(strategy.getIndexReadable(metaData), "b");
assertEquals(strategy.getIndexWritable(metaData), "b");
}
@Test
public void testRebuildPipelineStateRunning() {
rotation.updateRebuildPipelineState(RebuildPipelineState.RUNNING);
assertEquals(rotation.getRebuildPipelineState(), RebuildPipelineState.RUNNING);
}
@Test
public void testRebuildPipelineStateComplete() {
rotation.updateRebuildPipelineState(RebuildPipelineState.COMPLETE);
assertEquals(rotation.getRebuildPipelineState(), RebuildPipelineState.COMPLETE);
}
}