-
Notifications
You must be signed in to change notification settings - Fork 25.7k
Refactor ILMs UpdateSettingsStep to be more generic
#133329
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
0978063
883ce28
3905671
23fde79
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,22 +12,45 @@ | |
| import org.elasticsearch.cluster.ClusterStateObserver; | ||
| import org.elasticsearch.cluster.ProjectState; | ||
| import org.elasticsearch.cluster.metadata.IndexMetadata; | ||
| import org.elasticsearch.cluster.metadata.LifecycleExecutionState; | ||
| import org.elasticsearch.common.settings.Settings; | ||
| import org.elasticsearch.core.TimeValue; | ||
|
|
||
| import java.util.Objects; | ||
| import java.util.function.BiFunction; | ||
| import java.util.function.Function; | ||
|
|
||
| /** | ||
| * Updates the settings for an index. | ||
| */ | ||
| public class UpdateSettingsStep extends AsyncActionStep { | ||
| public static final String NAME = "update-settings"; | ||
|
|
||
| private final Settings settings; | ||
| private static final BiFunction<String, LifecycleExecutionState, String> DEFAULT_TARGET_INDEX_NAME_SUPPLIER = (index, state) -> index; | ||
|
|
||
| private final BiFunction<String, LifecycleExecutionState, String> targetIndexNameSupplier; | ||
| private final Function<IndexMetadata, Settings> settingsSupplier; | ||
|
|
||
| /** | ||
| * Use this constructor when you want to update the index that ILM runs on with <i>constant</i> settings. | ||
| */ | ||
| public UpdateSettingsStep(StepKey key, StepKey nextStepKey, Client client, Settings settings) { | ||
| this(key, nextStepKey, client, DEFAULT_TARGET_INDEX_NAME_SUPPLIER, indexMetadata -> settings); | ||
| } | ||
|
|
||
| /** | ||
| * Use this constructor when you want to update an index other than the one ILM runs on, and/or when you have non-constant settings | ||
| * (i.e., settings that depend on the index metadata). | ||
| */ | ||
| public UpdateSettingsStep( | ||
| StepKey key, | ||
| StepKey nextStepKey, | ||
| Client client, | ||
| BiFunction<String, LifecycleExecutionState, String> targetIndexNameSupplier, | ||
| Function<IndexMetadata, Settings> settingsSupplier | ||
| ) { | ||
| super(key, nextStepKey, client); | ||
| this.settings = settings; | ||
| this.targetIndexNameSupplier = targetIndexNameSupplier; | ||
| this.settingsSupplier = settingsSupplier; | ||
| } | ||
|
|
||
| @Override | ||
|
|
@@ -42,32 +65,16 @@ public void performAction( | |
| ClusterStateObserver observer, | ||
| ActionListener<Void> listener | ||
| ) { | ||
| UpdateSettingsRequest updateSettingsRequest = new UpdateSettingsRequest(indexMetadata.getIndex().getName()).masterNodeTimeout( | ||
| TimeValue.MAX_VALUE | ||
| ).settings(settings); | ||
| String indexName = targetIndexNameSupplier.apply(indexMetadata.getIndex().getName(), indexMetadata.getLifecycleExecutionState()); | ||
| Settings settings = settingsSupplier.apply(indexMetadata); | ||
| UpdateSettingsRequest updateSettingsRequest = new UpdateSettingsRequest(indexName).masterNodeTimeout(TimeValue.MAX_VALUE) | ||
| .settings(settings); | ||
| getClient(currentState.projectId()).admin() | ||
| .indices() | ||
| .updateSettings(updateSettingsRequest, listener.delegateFailureAndWrap((l, r) -> l.onResponse(null))); | ||
| } | ||
|
|
||
| public Settings getSettings() { | ||
| return settings; | ||
| } | ||
|
|
||
| @Override | ||
| public int hashCode() { | ||
| return Objects.hash(super.hashCode(), settings); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean equals(Object obj) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's not much value in overriding |
||
| if (obj == null) { | ||
| return false; | ||
| } | ||
| if (getClass() != obj.getClass()) { | ||
| return false; | ||
| } | ||
| UpdateSettingsStep other = (UpdateSettingsStep) obj; | ||
| return super.equals(obj) && Objects.equals(settings, other.settings); | ||
| public Function<IndexMetadata, Settings> getSettingsSupplier() { | ||
| return settingsSupplier; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -186,7 +186,7 @@ public void testToSteps() { | |
| expectedSettings.put(ShardsLimitAllocationDecider.INDEX_TOTAL_SHARDS_PER_NODE_SETTING.getKey(), action.getTotalShardsPerNode()); | ||
| } | ||
|
|
||
| assertThat(firstStep.getSettings(), equalTo(expectedSettings.build())); | ||
| assertThat(firstStep.getSettingsSupplier().apply(null), equalTo(expectedSettings.build())); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I considered adding a getter like so in // visibility for testing
Settings getSettings() {
return settingsApplier(null);
}to avoid having to do this in several tests, but I didn't feel like that was a good place for such test-only code, and I couldn't think of a sensible other place, so decided to update the few tests that required updating. |
||
| AllocationRoutedStep secondStep = (AllocationRoutedStep) steps.get(1); | ||
| assertEquals(expectedSecondStepKey, secondStep.getKey()); | ||
| assertEquals(nextStepKey, secondStep.getNextStepKey()); | ||
|
|
@@ -204,13 +204,15 @@ public void testTotalNumberOfShards() throws Exception { | |
| ); | ||
| List<Step> steps = action.toSteps(null, phase, nextStepKey); | ||
| UpdateSettingsStep firstStep = (UpdateSettingsStep) steps.get(0); | ||
| assertEquals(totalShardsPerNode, firstStep.getSettings().getAsInt(INDEX_TOTAL_SHARDS_PER_NODE_SETTING.getKey(), null)); | ||
| Settings actualSettings = firstStep.getSettingsSupplier().apply(null); | ||
| assertEquals(totalShardsPerNode, actualSettings.getAsInt(INDEX_TOTAL_SHARDS_PER_NODE_SETTING.getKey(), null)); | ||
|
|
||
| totalShardsPerNode = null; | ||
| action = new AllocateAction(numberOfReplicas, totalShardsPerNode, null, null, null); | ||
| steps = action.toSteps(null, phase, nextStepKey); | ||
| firstStep = (UpdateSettingsStep) steps.get(0); | ||
| assertEquals(null, firstStep.getSettings().get(INDEX_TOTAL_SHARDS_PER_NODE_SETTING.getKey())); | ||
| actualSettings = firstStep.getSettingsSupplier().apply(null); | ||
| assertNull(actualSettings.get(INDEX_TOTAL_SHARDS_PER_NODE_SETTING.getKey())); | ||
|
|
||
| // allow an allocate action that only specifies total shards per node (don't expect any exceptions in this case) | ||
| action = new AllocateAction(null, 5, null, null, null); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed the signature of the field to match the signature of similar fields in other steps, such as:
elasticsearch/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ilm/CopyExecutionStateStep.java
Line 38 in cb2e4db
While I would prefer using
Function<IndexMetadata, String>which still gives access to the name and state, and is more compact, having only oneShrinkIndexNameSupplier#getShrinkIndexNameis more worth it IMO. We can always refactor all usages if one go if we change our mind.