Adds rollover step and implements RolloverAction.toSteps

This commit is contained in:
Colin Goodheart-Smithe 2018-04-09 15:55:06 +01:00
parent 54c6d280a5
commit 06e969b430
6 changed files with 381 additions and 312 deletions

View File

@ -5,19 +5,18 @@
*/
package org.elasticsearch.xpack.core.indexlifecycle;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.logging.ESLoggerFactory;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
import org.elasticsearch.common.xcontent.ObjectParser.ValueType;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
import java.io.IOException;
import java.util.Collections;
@ -34,7 +33,6 @@ public class RolloverAction implements LifecycleAction {
public static final ParseField MAX_DOCS_FIELD = new ParseField("max_docs");
public static final ParseField MAX_AGE_FIELD = new ParseField("max_age");
private static final Logger logger = ESLoggerFactory.getLogger(RolloverAction.class);
private static final ConstructingObjectParser<RolloverAction, Void> PARSER = new ConstructingObjectParser<>(NAME,
a -> new RolloverAction((String) a[0], (ByteSizeValue) a[1], (TimeValue) a[2], (Long) a[3]));
static {
@ -147,38 +145,8 @@ public class RolloverAction implements LifecycleAction {
@Override
public List<Step> toSteps(Client client, String phase, Step.StepKey nextStepKey) {
return Collections.emptyList();
// ConditionalWaitStep wait = new ConditionalWaitStep(clusterService, "wait_for_rollover",
// index.getName(), phase, action, (clusterState) -> {
// // TODO(talevy): actually, needs to RolloverRequest with dryrun to get the appropriate data; clusterState is not enough...
// // can potentially reduce down to original problem with RolloverRequest...1minute...RolloverRequest...1minute... probably ok?
// if (clusterService.state().getMetaData().index(index.getName()).getAliases().containsKey(alias)) {
// RolloverRequest rolloverRequest = new RolloverRequest(alias, null);
// if (maxAge != null) {
// rolloverRequest.addMaxIndexAgeCondition(maxAge);
// }
// if (maxSize != null) {
// rolloverRequest.addMaxIndexSizeCondition(maxSize);
// }
// if (maxDocs != null) {
// rolloverRequest.addMaxIndexDocsCondition(maxDocs);
// }
// client.admin().indices().rolloverIndex(rolloverRequest, new ActionListener<RolloverResponse>() {
// @Override
// public void onResponse(RolloverResponse rolloverResponse) {
// return rolloverResponse.isRolledOver();
// }
//
// @Override
// public void onFailure(Exception e) {
// listener.onFailure(e);
// }
// });
// } else {
// listener.onSuccess(true);
// }
// });
return Collections.singletonList(
new RolloverStep(new StepKey(phase, NAME, RolloverStep.NAME), nextStepKey, client, alias, maxSize, maxAge, maxDocs));
}
@Override

View File

@ -0,0 +1,87 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.core.indexlifecycle;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.admin.indices.rollover.RolloverRequest;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.Index;
import java.util.Objects;
public class RolloverStep extends AsyncActionStep {
public static final String NAME = "attempt_rollover";
private String alias;
private ByteSizeValue maxSize;
private TimeValue maxAge;
private Long maxDocs;
public RolloverStep(StepKey key, StepKey nextStepKey, Client client, String alias, ByteSizeValue maxSize, TimeValue maxAge,
Long maxDocs) {
super(key, nextStepKey, client);
this.alias = alias;
this.maxSize = maxSize;
this.maxAge = maxAge;
this.maxDocs = maxDocs;
}
@Override
public void performAction(Index index, Listener listener) {
RolloverRequest rolloverRequest = new RolloverRequest(alias, null);
if (maxAge != null) {
rolloverRequest.addMaxIndexAgeCondition(maxAge);
}
if (maxSize != null) {
rolloverRequest.addMaxIndexSizeCondition(maxSize);
}
if (maxDocs != null) {
rolloverRequest.addMaxIndexDocsCondition(maxDocs);
}
getClient().admin().indices().rolloverIndex(rolloverRequest,
ActionListener.wrap(response -> listener.onResponse(response.isRolledOver()), listener::onFailure));
}
String getAlias() {
return alias;
}
ByteSizeValue getMaxSize() {
return maxSize;
}
TimeValue getMaxAge() {
return maxAge;
}
Long getMaxDocs() {
return maxDocs;
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), alias, maxSize, maxAge, maxDocs);
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
RolloverStep other = (RolloverStep) obj;
return super.equals(obj) &&
Objects.equals(alias, other.alias) &&
Objects.equals(maxSize, other.maxSize) &&
Objects.equals(maxAge, other.maxAge) &&
Objects.equals(maxDocs, other.maxDocs);
}
}

View File

@ -20,11 +20,11 @@ public abstract class Step {
this.nextStepKey = nextStepKey;
}
public StepKey getKey() {
public final StepKey getKey() {
return key;
}
public StepKey getNextStepKey() {
public final StepKey getNextStepKey() {
return nextStepKey;
}
@ -51,7 +51,7 @@ public abstract class Step {
return key + " => " + nextStepKey;
}
public static class StepKey {
public static final class StepKey {
private final String phase;
private final String action;
private final String name;

View File

@ -6,8 +6,6 @@
package org.elasticsearch.xpack.core.indexlifecycle;
import com.carrotsearch.randomizedtesting.annotations.Repeat;
import org.elasticsearch.Version;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.ClusterState;
@ -27,7 +25,6 @@ import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.EqualsHashCodeTestUtils;
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
@Repeat(iterations = 1000, useConstantSeed = false)
public class EnoughShardsWaitStepTests extends ESTestCase {
public EnoughShardsWaitStep createRandomInstance() {

View File

@ -5,42 +5,16 @@
*/
package org.elasticsearch.xpack.core.indexlifecycle;
import org.apache.lucene.util.SetOnce;
import org.elasticsearch.Version;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.admin.indices.rollover.Condition;
import org.elasticsearch.action.admin.indices.rollover.MaxAgeCondition;
import org.elasticsearch.action.admin.indices.rollover.MaxDocsCondition;
import org.elasticsearch.action.admin.indices.rollover.MaxSizeCondition;
import org.elasticsearch.action.admin.indices.rollover.RolloverIndexTestHelper;
import org.elasticsearch.action.admin.indices.rollover.RolloverRequest;
import org.elasticsearch.action.admin.indices.rollover.RolloverResponse;
import org.elasticsearch.client.AdminClient;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.IndicesAdminClient;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.AliasMetaData;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.io.stream.Writeable.Reader;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.ByteSizeUnit;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.index.Index;
import org.elasticsearch.test.AbstractSerializingTestCase;
import org.elasticsearch.xpack.core.indexlifecycle.RolloverAction;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import java.util.List;
public class RolloverActionTests extends AbstractSerializingTestCase<RolloverAction> {
@ -105,247 +79,21 @@ public class RolloverActionTests extends AbstractSerializingTestCase<RolloverAct
assertEquals(RolloverAction.ALIAS_FIELD.getPreferredName() + " must be not be null", exception.getMessage());
}
// public void testExecute() throws Exception {
// Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
//
// RolloverAction action = createTestInstance();
// IndexMetaData indexMetadata = IndexMetaData.builder(index.getName())
// .settings(Settings.builder().put("index.version.created", Version.CURRENT.id))
// .putAlias(AliasMetaData.builder(action.getAlias()))
// .numberOfShards(randomIntBetween(1, 5)).numberOfReplicas(randomIntBetween(0, 5)).build();
// ImmutableOpenMap.Builder<String, IndexMetaData> indices = ImmutableOpenMap.<String, IndexMetaData> builder().fPut(index.getName(),
// indexMetadata);
// ClusterState clusterstate = ClusterState.builder(ClusterState.EMPTY_STATE).metaData(MetaData.builder().indices(indices.build()))
// .build();
//
// Client client = Mockito.mock(Client.class);
// AdminClient adminClient = Mockito.mock(AdminClient.class);
// IndicesAdminClient indicesClient = Mockito.mock(IndicesAdminClient.class);
// ClusterService clusterService = Mockito.mock(ClusterService.class);
//
// Mockito.when(client.admin()).thenReturn(adminClient);
// Mockito.when(adminClient.indices()).thenReturn(indicesClient);
// Mockito.doAnswer(new Answer<Void>() {
//
// @Override
// public Void answer(InvocationOnMock invocation) throws Throwable {
// RolloverRequest request = (RolloverRequest) invocation.getArguments()[0];
// @SuppressWarnings("unchecked")
// ActionListener<RolloverResponse> listener = (ActionListener<RolloverResponse>) invocation.getArguments()[1];
// Set<Condition<?>> expectedConditions = new HashSet<>();
// if (action.getMaxAge() != null) {
// expectedConditions.add(new MaxAgeCondition(action.getMaxAge()));
// }
// if (action.getMaxSize() != null) {
// expectedConditions.add(new MaxSizeCondition(action.getMaxSize()));
// }
// if (action.getMaxDocs() != null) {
// expectedConditions.add(new MaxDocsCondition(action.getMaxDocs()));
// }
// RolloverIndexTestHelper.assertRolloverIndexRequest(request, action.getAlias(), expectedConditions);
// listener.onResponse(RolloverIndexTestHelper.createMockResponse(request, true));
// return null;
// }
//
// }).when(indicesClient).rolloverIndex(Mockito.any(), Mockito.any());
// Mockito.when(clusterService.state()).thenReturn(clusterstate);
//
// SetOnce<Boolean> actionCompleted = new SetOnce<>();
// action.execute(index, client, clusterService, new Listener() {
//
// @Override
// public void onSuccess(boolean completed) {
// actionCompleted.set(completed);
// }
//
// @Override
// public void onFailure(Exception e) {
// throw new AssertionError("Unexpected method call", e);
// }
// });
//
// assertEquals(true, actionCompleted.get());
//
// Mockito.verify(client, Mockito.only()).admin();
// Mockito.verify(adminClient, Mockito.only()).indices();
// Mockito.verify(indicesClient, Mockito.only()).rolloverIndex(Mockito.any(), Mockito.any());
// Mockito.verify(clusterService, Mockito.only()).state();
// }
//
// public void testExecuteNotComplete() throws Exception {
// Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
//
// RolloverAction action = createTestInstance();
// IndexMetaData indexMetadata = IndexMetaData.builder(index.getName())
// .settings(Settings.builder().put("index.version.created", Version.CURRENT.id))
// .putAlias(AliasMetaData.builder(action.getAlias())).numberOfShards(randomIntBetween(1, 5))
// .numberOfReplicas(randomIntBetween(0, 5)).build();
// ImmutableOpenMap.Builder<String, IndexMetaData> indices = ImmutableOpenMap.<String, IndexMetaData> builder().fPut(index.getName(),
// indexMetadata);
// ClusterState clusterstate = ClusterState.builder(ClusterState.EMPTY_STATE).metaData(MetaData.builder().indices(indices.build()))
// .build();
//
// Client client = Mockito.mock(Client.class);
// AdminClient adminClient = Mockito.mock(AdminClient.class);
// IndicesAdminClient indicesClient = Mockito.mock(IndicesAdminClient.class);
// ClusterService clusterService = Mockito.mock(ClusterService.class);
//
// Mockito.when(client.admin()).thenReturn(adminClient);
// Mockito.when(adminClient.indices()).thenReturn(indicesClient);
// Mockito.doAnswer(new Answer<Void>() {
//
// @Override
// public Void answer(InvocationOnMock invocation) throws Throwable {
// RolloverRequest request = (RolloverRequest) invocation.getArguments()[0];
// @SuppressWarnings("unchecked")
// ActionListener<RolloverResponse> listener = (ActionListener<RolloverResponse>) invocation.getArguments()[1];
// Set<Condition<?>> expectedConditions = new HashSet<>();
// if (action.getMaxAge() != null) {
// expectedConditions.add(new MaxAgeCondition(action.getMaxAge()));
// }
// if (action.getMaxSize() != null) {
// expectedConditions.add(new MaxSizeCondition(action.getMaxSize()));
// }
// if (action.getMaxDocs() != null) {
// expectedConditions.add(new MaxDocsCondition(action.getMaxDocs()));
// }
// RolloverIndexTestHelper.assertRolloverIndexRequest(request, action.getAlias(), expectedConditions);
// listener.onResponse(RolloverIndexTestHelper.createMockResponse(request, false));
// return null;
// }
//
// }).when(indicesClient).rolloverIndex(Mockito.any(), Mockito.any());
// Mockito.when(clusterService.state()).thenReturn(clusterstate);
//
// SetOnce<Boolean> actionCompleted = new SetOnce<>();
// action.execute(index, client, clusterService, new Listener() {
//
// @Override
// public void onSuccess(boolean completed) {
// actionCompleted.set(completed);
// }
//
// @Override
// public void onFailure(Exception e) {
// throw new AssertionError("Unexpected method call", e);
// }
// });
//
// assertEquals(false, actionCompleted.get());
//
// Mockito.verify(client, Mockito.only()).admin();
// Mockito.verify(adminClient, Mockito.only()).indices();
// Mockito.verify(indicesClient, Mockito.only()).rolloverIndex(Mockito.any(), Mockito.any());
// Mockito.verify(clusterService, Mockito.only()).state();
// }
//
// public void testExecuteAlreadyCompleted() throws Exception {
// Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
//
// RolloverAction action = createTestInstance();
//
// IndexMetaData indexMetadata = IndexMetaData.builder(index.getName())
// .settings(Settings.builder().put("index.version.created", Version.CURRENT.id)).numberOfShards(randomIntBetween(1, 5))
// .numberOfReplicas(randomIntBetween(0, 5)).build();
// ImmutableOpenMap.Builder<String, IndexMetaData> indices = ImmutableOpenMap.<String, IndexMetaData> builder().fPut(index.getName(),
// indexMetadata);
// ClusterState clusterstate = ClusterState.builder(ClusterState.EMPTY_STATE).metaData(MetaData.builder().indices(indices.build()))
// .build();
//
// Client client = Mockito.mock(Client.class);
// AdminClient adminClient = Mockito.mock(AdminClient.class);
// IndicesAdminClient indicesClient = Mockito.mock(IndicesAdminClient.class);
// ClusterService clusterService = Mockito.mock(ClusterService.class);
//
// Mockito.when(clusterService.state()).thenReturn(clusterstate);
//
// SetOnce<Boolean> actionCompleted = new SetOnce<>();
// action.execute(index, client, clusterService, new Listener() {
//
// @Override
// public void onSuccess(boolean completed) {
// actionCompleted.set(completed);
// }
//
// @Override
// public void onFailure(Exception e) {
// throw new AssertionError("Unexpected method call", e);
// }
// });
//
// assertEquals(true, actionCompleted.get());
//
// Mockito.verify(clusterService, Mockito.only()).state();
// Mockito.verifyZeroInteractions(client, adminClient, indicesClient);
// }
//
// public void testExecuteFailure() throws Exception {
// Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
// Exception exception = new RuntimeException();
//
// RolloverAction action = createTestInstance();
//
// IndexMetaData indexMetadata = IndexMetaData.builder(index.getName())
// .settings(Settings.builder().put("index.version.created", Version.CURRENT.id))
// .putAlias(AliasMetaData.builder(action.getAlias())).numberOfShards(randomIntBetween(1, 5))
// .numberOfReplicas(randomIntBetween(0, 5)).build();
// ImmutableOpenMap.Builder<String, IndexMetaData> indices = ImmutableOpenMap.<String, IndexMetaData> builder().fPut(index.getName(),
// indexMetadata);
// ClusterState clusterstate = ClusterState.builder(ClusterState.EMPTY_STATE).metaData(MetaData.builder().indices(indices.build()))
// .build();
//
// Client client = Mockito.mock(Client.class);
// AdminClient adminClient = Mockito.mock(AdminClient.class);
// IndicesAdminClient indicesClient = Mockito.mock(IndicesAdminClient.class);
// ClusterService clusterService = Mockito.mock(ClusterService.class);
//
// Mockito.when(client.admin()).thenReturn(adminClient);
// Mockito.when(adminClient.indices()).thenReturn(indicesClient);
// Mockito.doAnswer(new Answer<Void>() {
//
// @Override
// public Void answer(InvocationOnMock invocation) throws Throwable {
// RolloverRequest request = (RolloverRequest) invocation.getArguments()[0];
// @SuppressWarnings("unchecked")
// ActionListener<RolloverResponse> listener = (ActionListener<RolloverResponse>) invocation.getArguments()[1];
// Set<Condition<?>> expectedConditions = new HashSet<>();
// if (action.getMaxAge() != null) {
// expectedConditions.add(new MaxAgeCondition(action.getMaxAge()));
// }
// if (action.getMaxSize() != null) {
// expectedConditions.add(new MaxSizeCondition(action.getMaxSize()));
// }
// if (action.getMaxDocs() != null) {
// expectedConditions.add(new MaxDocsCondition(action.getMaxDocs()));
// }
// RolloverIndexTestHelper.assertRolloverIndexRequest(request, action.getAlias(), expectedConditions);
// listener.onFailure(exception);
// return null;
// }
//
// }).when(indicesClient).rolloverIndex(Mockito.any(), Mockito.any());
// Mockito.when(clusterService.state()).thenReturn(clusterstate);
//
// SetOnce<Boolean> exceptionThrown = new SetOnce<>();
// action.execute(index, client, clusterService, new Listener() {
//
// @Override
// public void onSuccess(boolean completed) {
// throw new AssertionError("Unexpected method call");
// }
//
// @Override
// public void onFailure(Exception e) {
// assertEquals(exception, e);
// exceptionThrown.set(true);
// }
// });
//
// assertEquals(true, exceptionThrown.get());
//
// Mockito.verify(client, Mockito.only()).admin();
// Mockito.verify(adminClient, Mockito.only()).indices();
// Mockito.verify(indicesClient, Mockito.only()).rolloverIndex(Mockito.any(), Mockito.any());
// }
public void testToSteps() {
RolloverAction action = createTestInstance();
String phase = randomAlphaOfLengthBetween(1, 10);
StepKey nextStepKey = new StepKey(randomAlphaOfLengthBetween(1, 10), randomAlphaOfLengthBetween(1, 10),
randomAlphaOfLengthBetween(1, 10));
List<Step> steps = action.toSteps(null, phase, nextStepKey);
assertNotNull(steps);
assertEquals(1, steps.size());
StepKey expectedFirstStepKey = new StepKey(phase, RolloverAction.NAME, RolloverStep.NAME);
RolloverStep firstStep = (RolloverStep) steps.get(0);
assertEquals(expectedFirstStepKey, firstStep.getKey());
assertEquals(nextStepKey, firstStep.getNextStepKey());
assertEquals(action.getAlias(), firstStep.getAlias());
assertEquals(action.getMaxSize(), firstStep.getMaxSize());
assertEquals(action.getMaxAge(), firstStep.getMaxAge());
assertEquals(action.getMaxDocs(), firstStep.getMaxDocs());
}
}

View File

@ -0,0 +1,269 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.core.indexlifecycle;
import org.apache.lucene.util.SetOnce;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.admin.indices.rollover.Condition;
import org.elasticsearch.action.admin.indices.rollover.MaxAgeCondition;
import org.elasticsearch.action.admin.indices.rollover.MaxDocsCondition;
import org.elasticsearch.action.admin.indices.rollover.MaxSizeCondition;
import org.elasticsearch.action.admin.indices.rollover.RolloverIndexTestHelper;
import org.elasticsearch.action.admin.indices.rollover.RolloverRequest;
import org.elasticsearch.action.admin.indices.rollover.RolloverResponse;
import org.elasticsearch.client.AdminClient;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.IndicesAdminClient;
import org.elasticsearch.common.unit.ByteSizeUnit;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.Index;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.EqualsHashCodeTestUtils;
import org.elasticsearch.xpack.core.indexlifecycle.AsyncActionStep.Listener;
import org.elasticsearch.xpack.core.indexlifecycle.Step.StepKey;
import org.junit.Before;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import java.util.HashSet;
import java.util.Set;
public class RolloverStepTests extends ESTestCase {
private Client client;
@Before
public void setup() {
client = Mockito.mock(Client.class);
}
public RolloverStep createRandomInstance() {
StepKey stepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
StepKey nextStepKey = new StepKey(randomAlphaOfLength(10), randomAlphaOfLength(10), randomAlphaOfLength(10));
String alias = randomAlphaOfLengthBetween(1, 20);
ByteSizeUnit maxSizeUnit = randomFrom(ByteSizeUnit.values());
ByteSizeValue maxSize = randomBoolean() ? null : new ByteSizeValue(randomNonNegativeLong() / maxSizeUnit.toBytes(1), maxSizeUnit);
Long maxDocs = randomBoolean() ? null : randomNonNegativeLong();
TimeValue maxAge = (maxDocs == null && maxSize == null || randomBoolean())
? TimeValue.parseTimeValue(randomPositiveTimeValue(), "rollover_action_test")
: null;
return new RolloverStep(stepKey, nextStepKey, client, alias, maxSize, maxAge, maxDocs);
}
public RolloverStep mutateInstance(RolloverStep instance) {
StepKey key = instance.getKey();
StepKey nextKey = instance.getNextStepKey();
String alias = instance.getAlias();
ByteSizeValue maxSize = instance.getMaxSize();
TimeValue maxAge = instance.getMaxAge();
Long maxDocs = instance.getMaxDocs();
switch (between(0, 5)) {
case 0:
key = new StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5));
break;
case 1:
nextKey = new StepKey(key.getPhase(), key.getAction(), key.getName() + randomAlphaOfLength(5));
break;
case 2:
alias = alias + randomAlphaOfLengthBetween(1, 5);
break;
case 3:
maxSize = randomValueOtherThan(maxSize, () -> {
ByteSizeUnit maxSizeUnit = randomFrom(ByteSizeUnit.values());
return new ByteSizeValue(randomNonNegativeLong() / maxSizeUnit.toBytes(1), maxSizeUnit);
});
break;
case 4:
maxAge = TimeValue.parseTimeValue(randomPositiveTimeValue(), "rollover_action_test");
break;
case 5:
maxDocs = randomNonNegativeLong();
break;
default:
throw new AssertionError("Illegal randomisation branch");
}
return new RolloverStep(key, nextKey, instance.getClient(), alias, maxSize, maxAge, maxDocs);
}
public void testHashcodeAndEquals() {
EqualsHashCodeTestUtils
.checkEqualsAndHashCode(createRandomInstance(),
instance -> new RolloverStep(instance.getKey(), instance.getNextStepKey(), instance.getClient(),
instance.getAlias(), instance.getMaxSize(), instance.getMaxAge(), instance.getMaxDocs()),
this::mutateInstance);
}
public void testPerformAction() throws Exception {
Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
RolloverStep step = createRandomInstance();
AdminClient adminClient = Mockito.mock(AdminClient.class);
IndicesAdminClient indicesClient = Mockito.mock(IndicesAdminClient.class);
Mockito.when(client.admin()).thenReturn(adminClient);
Mockito.when(adminClient.indices()).thenReturn(indicesClient);
Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
RolloverRequest request = (RolloverRequest) invocation.getArguments()[0];
@SuppressWarnings("unchecked")
ActionListener<RolloverResponse> listener = (ActionListener<RolloverResponse>) invocation.getArguments()[1];
Set<Condition<?>> expectedConditions = new HashSet<>();
if (step.getMaxAge() != null) {
expectedConditions.add(new MaxAgeCondition(step.getMaxAge()));
}
if (step.getMaxSize() != null) {
expectedConditions.add(new MaxSizeCondition(step.getMaxSize()));
}
if (step.getMaxDocs() != null) {
expectedConditions.add(new MaxDocsCondition(step.getMaxDocs()));
}
RolloverIndexTestHelper.assertRolloverIndexRequest(request, step.getAlias(), expectedConditions);
listener.onResponse(RolloverIndexTestHelper.createMockResponse(request, true));
return null;
}
}).when(indicesClient).rolloverIndex(Mockito.any(), Mockito.any());
SetOnce<Boolean> actionCompleted = new SetOnce<>();
step.performAction(index, new Listener() {
@Override
public void onResponse(boolean complete) {
actionCompleted.set(complete);
}
@Override
public void onFailure(Exception e) {
throw new AssertionError("Unexpected method call", e);
}
});
assertEquals(true, actionCompleted.get());
Mockito.verify(client, Mockito.only()).admin();
Mockito.verify(adminClient, Mockito.only()).indices();
Mockito.verify(indicesClient, Mockito.only()).rolloverIndex(Mockito.any(), Mockito.any());
}
public void testPerformActionNotComplete() throws Exception {
Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
RolloverStep step = createRandomInstance();
AdminClient adminClient = Mockito.mock(AdminClient.class);
IndicesAdminClient indicesClient = Mockito.mock(IndicesAdminClient.class);
Mockito.when(client.admin()).thenReturn(adminClient);
Mockito.when(adminClient.indices()).thenReturn(indicesClient);
Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
RolloverRequest request = (RolloverRequest) invocation.getArguments()[0];
@SuppressWarnings("unchecked")
ActionListener<RolloverResponse> listener = (ActionListener<RolloverResponse>) invocation.getArguments()[1];
Set<Condition<?>> expectedConditions = new HashSet<>();
if (step.getMaxAge() != null) {
expectedConditions.add(new MaxAgeCondition(step.getMaxAge()));
}
if (step.getMaxSize() != null) {
expectedConditions.add(new MaxSizeCondition(step.getMaxSize()));
}
if (step.getMaxDocs() != null) {
expectedConditions.add(new MaxDocsCondition(step.getMaxDocs()));
}
RolloverIndexTestHelper.assertRolloverIndexRequest(request, step.getAlias(), expectedConditions);
listener.onResponse(RolloverIndexTestHelper.createMockResponse(request, false));
return null;
}
}).when(indicesClient).rolloverIndex(Mockito.any(), Mockito.any());
SetOnce<Boolean> actionCompleted = new SetOnce<>();
step.performAction(index, new Listener() {
@Override
public void onResponse(boolean complete) {
actionCompleted.set(complete);
}
@Override
public void onFailure(Exception e) {
throw new AssertionError("Unexpected method call", e);
}
});
assertEquals(false, actionCompleted.get());
Mockito.verify(client, Mockito.only()).admin();
Mockito.verify(adminClient, Mockito.only()).indices();
Mockito.verify(indicesClient, Mockito.only()).rolloverIndex(Mockito.any(), Mockito.any());
}
public void testPerformActionFailure() throws Exception {
Index index = new Index(randomAlphaOfLengthBetween(1, 20), randomAlphaOfLengthBetween(1, 20));
Exception exception = new RuntimeException();
RolloverStep step = createRandomInstance();
AdminClient adminClient = Mockito.mock(AdminClient.class);
IndicesAdminClient indicesClient = Mockito.mock(IndicesAdminClient.class);
Mockito.when(client.admin()).thenReturn(adminClient);
Mockito.when(adminClient.indices()).thenReturn(indicesClient);
Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
RolloverRequest request = (RolloverRequest) invocation.getArguments()[0];
@SuppressWarnings("unchecked")
ActionListener<RolloverResponse> listener = (ActionListener<RolloverResponse>) invocation.getArguments()[1];
Set<Condition<?>> expectedConditions = new HashSet<>();
if (step.getMaxAge() != null) {
expectedConditions.add(new MaxAgeCondition(step.getMaxAge()));
}
if (step.getMaxSize() != null) {
expectedConditions.add(new MaxSizeCondition(step.getMaxSize()));
}
if (step.getMaxDocs() != null) {
expectedConditions.add(new MaxDocsCondition(step.getMaxDocs()));
}
RolloverIndexTestHelper.assertRolloverIndexRequest(request, step.getAlias(), expectedConditions);
listener.onFailure(exception);
return null;
}
}).when(indicesClient).rolloverIndex(Mockito.any(), Mockito.any());
SetOnce<Boolean> exceptionThrown = new SetOnce<>();
step.performAction(index, new Listener() {
@Override
public void onResponse(boolean complete) {
throw new AssertionError("Unexpected method call");
}
@Override
public void onFailure(Exception e) {
assertSame(exception, e);
exceptionThrown.set(true);
}
});
assertEquals(true, exceptionThrown.get());
Mockito.verify(client, Mockito.only()).admin();
Mockito.verify(adminClient, Mockito.only()).indices();
Mockito.verify(indicesClient, Mockito.only()).rolloverIndex(Mockito.any(), Mockito.any());
}
}