From 96935f9109dad1b724a3ced77e7263e6fec0631b Mon Sep 17 00:00:00 2001 From: Colin Goodheart-Smithe Date: Tue, 4 Sep 2018 13:32:17 +0100 Subject: [PATCH 1/6] Adds usage data for ILM --- .../IndexLifecycleFeatureSetUsage.java | 78 +++++++++++++++++++ .../IndexLifecycleFeatureSet.java | 25 +++++- 2 files changed, 101 insertions(+), 2 deletions(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsage.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsage.java index 052db7337edff..b13c1de9eef7e 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsage.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsage.java @@ -6,18 +6,96 @@ package org.elasticsearch.xpack.core.indexlifecycle; import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.common.xcontent.ToXContentObject; +import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.xpack.core.XPackFeatureSet; import org.elasticsearch.xpack.core.XPackField; import java.io.IOException; +import java.util.List; +import java.util.Map; public class IndexLifecycleFeatureSetUsage extends XPackFeatureSet.Usage { + private List policyStats; + public IndexLifecycleFeatureSetUsage(StreamInput input) throws IOException { super(input); + policyStats = input.readList(PolicyStats::new); } public IndexLifecycleFeatureSetUsage(boolean available, boolean enabled) { + this(available, enabled, null); + } + + public IndexLifecycleFeatureSetUsage(boolean available, boolean enabled, List policyStats) { super(XPackField.INDEX_LIFECYCLE, available, enabled); + this.policyStats = policyStats; + } + + @Override + protected void innerXContent(XContentBuilder builder, Params params) throws IOException { + if (policyStats != null) { + builder.field("policy_count", policyStats.size()); + builder.field("policy_stats", policyStats); + } + } + + public static final class PolicyStats implements ToXContentObject, Writeable { + private final Map phaseStats; + + public PolicyStats(Map phaseStats) { + this.phaseStats = phaseStats; + } + + public PolicyStats(StreamInput in) throws IOException { + this.phaseStats = in.readMap(StreamInput::readString, PhaseStats::new); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeMap(phaseStats, StreamOutput::writeString, (o, p) -> p.writeTo(o)); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field(LifecyclePolicy.PHASES_FIELD.getPreferredName(), phaseStats); + builder.endObject(); + return builder; + } + } + + public static final class PhaseStats implements ToXContentObject, Writeable { + private final String[] actionNames; + private final TimeValue after; + + public PhaseStats(TimeValue after, String[] actionNames) { + this.actionNames = actionNames; + this.after = after; + } + + public PhaseStats(StreamInput in) throws IOException { + actionNames = in.readStringArray(); + after = in.readTimeValue(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeStringArray(actionNames); + out.writeTimeValue(after); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.field(Phase.AFTER_FIELD.getPreferredName(), after.getStringRep()); + builder.field(Phase.ACTIONS_FIELD.getPreferredName(), actionNames); + builder.endObject(); + return builder; + } } } diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSet.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSet.java index e3214f61ed80d..5b6641fc8161f 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSet.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSet.java @@ -6,7 +6,9 @@ package org.elasticsearch.xpack.indexlifecycle; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.Nullable; +import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.license.XPackLicenseState; @@ -14,16 +16,23 @@ import org.elasticsearch.xpack.core.XPackField; import org.elasticsearch.xpack.core.XPackSettings; import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleFeatureSetUsage; +import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleFeatureSetUsage.PhaseStats; +import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleFeatureSetUsage.PolicyStats; +import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleMetadata; +import java.util.List; import java.util.Map; +import java.util.stream.Collectors; public class IndexLifecycleFeatureSet implements XPackFeatureSet { private final boolean enabled; private final XPackLicenseState licenseState; + private ClusterService clusterService; @Inject - public IndexLifecycleFeatureSet(Settings settings, @Nullable XPackLicenseState licenseState) { + public IndexLifecycleFeatureSet(Settings settings, @Nullable XPackLicenseState licenseState, ClusterService clusterService) { + this.clusterService = clusterService; this.enabled = XPackSettings.INDEX_LIFECYCLE_ENABLED.get(settings); this.licenseState = licenseState; } @@ -55,7 +64,19 @@ public Map nativeCodeInfo() { @Override public void usage(ActionListener listener) { - listener.onResponse(new IndexLifecycleFeatureSetUsage(available(), enabled())); + IndexLifecycleMetadata lifecycleMetadata = clusterService.state().metaData().custom(IndexLifecycleMetadata.TYPE); + if (enabled() && lifecycleMetadata != null) { + List policyStats = lifecycleMetadata.getPolicies().values().stream().map(policy -> { + Map phaseStats = policy.getPhases().values().stream().map(phase -> { + String[] actionNames = phase.getActions().keySet().toArray(new String[phase.getActions().size()]); + return new Tuple(phase.getName(), new PhaseStats(phase.getAfter(), actionNames)); + }).collect(Collectors.toMap(Tuple::v1, Tuple::v2)); + return new PolicyStats(phaseStats); + }).collect(Collectors.toList()); + listener.onResponse(new IndexLifecycleFeatureSetUsage(enabled(), available(), policyStats)); + } else { + listener.onResponse(new IndexLifecycleFeatureSetUsage(enabled(), available())); + } } } From 7d76b42c81541ab19988327924e50c3690b90236 Mon Sep 17 00:00:00 2001 From: Colin Goodheart-Smithe Date: Wed, 5 Sep 2018 13:52:09 +0100 Subject: [PATCH 2/6] Adds tests for IndexLifecycleFeatureSetUsage and friends --- .../IndexLifecycleFeatureSetUsage.java | 86 ++++++++++++++++++- .../IndexLifecycleFeatureSetUsageTests.java | 68 +++++++++++++++ .../core/indexlifecycle/PhaseStatsTests.java | 53 ++++++++++++ .../core/indexlifecycle/PolicyStatsTests.java | 46 ++++++++++ 4 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsageTests.java create mode 100644 x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/PhaseStatsTests.java create mode 100644 x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/PolicyStatsTests.java diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsage.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsage.java index b13c1de9eef7e..a1c0a4f585242 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsage.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsage.java @@ -15,8 +15,10 @@ import org.elasticsearch.xpack.core.XPackField; import java.io.IOException; +import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Objects; public class IndexLifecycleFeatureSetUsage extends XPackFeatureSet.Usage { @@ -24,7 +26,19 @@ public class IndexLifecycleFeatureSetUsage extends XPackFeatureSet.Usage { public IndexLifecycleFeatureSetUsage(StreamInput input) throws IOException { super(input); - policyStats = input.readList(PolicyStats::new); + if (input.readBoolean()) { + policyStats = input.readList(PolicyStats::new); + } + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + super.writeTo(out); + boolean hasPolicyStats = policyStats != null; + out.writeBoolean(hasPolicyStats); + if (hasPolicyStats) { + out.writeList(policyStats); + } } public IndexLifecycleFeatureSetUsage(boolean available, boolean enabled) { @@ -43,6 +57,29 @@ protected void innerXContent(XContentBuilder builder, Params params) throws IOEx builder.field("policy_stats", policyStats); } } + + public List getPolicyStats() { + return policyStats; + } + + @Override + public int hashCode() { + return Objects.hash(available, enabled, policyStats); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + IndexLifecycleFeatureSetUsage other = (IndexLifecycleFeatureSetUsage) obj; + return Objects.equals(available, other.available) && + Objects.equals(enabled, other.enabled) && + Objects.equals(policyStats, other.policyStats); + } public static final class PolicyStats implements ToXContentObject, Writeable { private final Map phaseStats; @@ -67,6 +104,27 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.endObject(); return builder; } + + public Map getPhaseStats() { + return phaseStats; + } + + @Override + public int hashCode() { + return Objects.hash(phaseStats); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + PolicyStats other = (PolicyStats) obj; + return Objects.equals(phaseStats, other.phaseStats); + } } public static final class PhaseStats implements ToXContentObject, Writeable { @@ -97,5 +155,31 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.endObject(); return builder; } + + public String[] getActionNames() { + return actionNames; + } + + public TimeValue getAfter() { + return after; + } + + @Override + public int hashCode() { + return Objects.hash(Arrays.hashCode(actionNames), after); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + PhaseStats other = (PhaseStats) obj; + return Objects.equals(after, other.after) && + Objects.deepEquals(actionNames, other.actionNames); + } } } diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsageTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsageTests.java new file mode 100644 index 0000000000000..1035eb7a7462c --- /dev/null +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsageTests.java @@ -0,0 +1,68 @@ +/* + * 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.common.io.stream.Writeable.Reader; +import org.elasticsearch.test.AbstractWireSerializingTestCase; +import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleFeatureSetUsage.PolicyStats; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class IndexLifecycleFeatureSetUsageTests extends AbstractWireSerializingTestCase { + + @Override + protected IndexLifecycleFeatureSetUsage createTestInstance() { + boolean enabled = randomBoolean(); + boolean available = randomBoolean(); + List policyStats = null; + if (enabled) { + int size = randomIntBetween(0, 10); + policyStats = new ArrayList<>(size); + for (int i = 0; i < size; i++) { + policyStats.add(PolicyStatsTests.createRandomInstance()); + } + } + return new IndexLifecycleFeatureSetUsage(available, enabled, policyStats); + } + + @Override + protected IndexLifecycleFeatureSetUsage mutateInstance(IndexLifecycleFeatureSetUsage instance) throws IOException { + boolean available = instance.available(); + boolean enabled = instance.enabled(); + List policyStats = instance.getPolicyStats(); + switch (between(0, 2)) { + case 0: + available = available == false; + break; + case 1: + enabled = enabled == false; + break; + case 2: + if (policyStats == null) { + policyStats = new ArrayList<>(); + policyStats.add(PolicyStatsTests.createRandomInstance()); + } else if (randomBoolean()) { + policyStats = null; + } else { + policyStats = new ArrayList<>(policyStats); + policyStats.add(PolicyStatsTests.createRandomInstance()); + } + break; + default: + throw new AssertionError("Illegal randomisation branch"); + } + return new IndexLifecycleFeatureSetUsage(available, enabled, policyStats); + } + + @Override + protected Reader instanceReader() { + return IndexLifecycleFeatureSetUsage::new; + } + +} diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/PhaseStatsTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/PhaseStatsTests.java new file mode 100644 index 0000000000000..ae4325abe5d87 --- /dev/null +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/PhaseStatsTests.java @@ -0,0 +1,53 @@ +/* + * 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.common.io.stream.Writeable.Reader; +import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.test.AbstractWireSerializingTestCase; +import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleFeatureSetUsage.PhaseStats; + +import java.io.IOException; +import java.util.Arrays; + +public class PhaseStatsTests extends AbstractWireSerializingTestCase { + + @Override + protected PhaseStats createTestInstance() { + return createRandomInstance(); + } + + public static PhaseStats createRandomInstance() { + TimeValue after = TimeValue.parseTimeValue(randomTimeValue(), "phase_stats_tests"); + String[] actionNames = randomArray(0, 20, size -> new String[size], () -> randomAlphaOfLengthBetween(1, 20)); + return new PhaseStats(after, actionNames); + } + + @Override + protected PhaseStats mutateInstance(PhaseStats instance) throws IOException { + TimeValue after = instance.getAfter(); + String[] actionNames = instance.getActionNames(); + switch (between(0, 1)) { + case 0: + after = randomValueOtherThan(after, () -> TimeValue.parseTimeValue(randomPositiveTimeValue(), "rollover_action_test")); + break; + case 1: + actionNames = randomValueOtherThanMany(a -> Arrays.equals(a, instance.getActionNames()), + () -> randomArray(0, 20, size -> new String[size], () -> randomAlphaOfLengthBetween(1, 20))); + break; + default: + throw new AssertionError("Illegal randomisation branch"); + } + return new PhaseStats(after, actionNames); + } + + @Override + protected Reader instanceReader() { + return PhaseStats::new; + } + +} diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/PolicyStatsTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/PolicyStatsTests.java new file mode 100644 index 0000000000000..12f1a13fc941a --- /dev/null +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/PolicyStatsTests.java @@ -0,0 +1,46 @@ +/* + * 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.common.io.stream.Writeable.Reader; +import org.elasticsearch.test.AbstractWireSerializingTestCase; +import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleFeatureSetUsage.PhaseStats; +import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleFeatureSetUsage.PolicyStats; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class PolicyStatsTests extends AbstractWireSerializingTestCase { + + @Override + protected PolicyStats createTestInstance() { + return createRandomInstance(); + } + + public static PolicyStats createRandomInstance() { + int size = randomIntBetween(0, 10); + Map phaseStats = new HashMap<>(size); + for (int i = 0; i < size; i++) { + phaseStats.put(randomAlphaOfLengthBetween(1, 20), PhaseStatsTests.createRandomInstance()); + } + return new PolicyStats(phaseStats); + } + + @Override + protected PolicyStats mutateInstance(PolicyStats instance) throws IOException { + Map phaseStats = new HashMap<>(instance.getPhaseStats()); + phaseStats.put(randomAlphaOfLengthBetween(1, 20), PhaseStatsTests.createRandomInstance()); + return new PolicyStats(phaseStats); + } + + @Override + protected Reader instanceReader() { + return PolicyStats::new; + } + +} From 01373850dade8e9139352bdf4bda7507d4b22e08 Mon Sep 17 00:00:00 2001 From: Colin Goodheart-Smithe Date: Thu, 6 Sep 2018 08:13:30 +0100 Subject: [PATCH 3/6] Adds tests for IndexLifecycleFeatureSet --- .../IndexLifecycleFeatureSet.java | 4 +- .../IndexLifecycleFeatureSetTests.java | 125 ++++++++++++++++++ 2 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSetTests.java diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSet.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSet.java index 5b6641fc8161f..ddd4881188e2d 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSet.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSet.java @@ -73,9 +73,9 @@ public void usage(ActionListener listener) { }).collect(Collectors.toMap(Tuple::v1, Tuple::v2)); return new PolicyStats(phaseStats); }).collect(Collectors.toList()); - listener.onResponse(new IndexLifecycleFeatureSetUsage(enabled(), available(), policyStats)); + listener.onResponse(new IndexLifecycleFeatureSetUsage(available(), enabled(), policyStats)); } else { - listener.onResponse(new IndexLifecycleFeatureSetUsage(enabled(), available())); + listener.onResponse(new IndexLifecycleFeatureSetUsage(available(), enabled())); } } diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSetTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSetTests.java new file mode 100644 index 0000000000000..b54fed59b37b4 --- /dev/null +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSetTests.java @@ -0,0 +1,125 @@ +/* + * 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.indexlifecycle; + +import org.elasticsearch.action.support.PlainActionFuture; +import org.elasticsearch.cluster.ClusterName; +import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.metadata.MetaData; +import org.elasticsearch.cluster.service.ClusterService; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.license.XPackLicenseState; +import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleFeatureSetUsage; +import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleFeatureSetUsage.PolicyStats; +import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleMetadata; +import org.elasticsearch.xpack.core.indexlifecycle.LifecyclePolicy; +import org.elasticsearch.xpack.core.indexlifecycle.LifecyclePolicyMetadata; +import org.elasticsearch.xpack.core.indexlifecycle.OperationMode; +import org.elasticsearch.xpack.core.indexlifecycle.Phase; +import org.junit.Before; +import org.mockito.Mockito; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.equalTo; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class IndexLifecycleFeatureSetTests extends ESTestCase { + + private XPackLicenseState licenseState; + private ClusterService clusterService; + + @Before + public void init() throws Exception { + licenseState = mock(XPackLicenseState.class); + clusterService = mock(ClusterService.class); + } + + public void testAvailable() { + IndexLifecycleFeatureSet featureSet = new IndexLifecycleFeatureSet(Settings.EMPTY, licenseState, clusterService); + + when(licenseState.isIndexLifecycleAllowed()).thenReturn(false); + assertThat(featureSet.available(), equalTo(false)); + + when(licenseState.isIndexLifecycleAllowed()).thenReturn(true); + assertThat(featureSet.available(), equalTo(true)); + + featureSet = new IndexLifecycleFeatureSet(Settings.EMPTY, null, clusterService); + assertThat(featureSet.available(), equalTo(false)); + } + + public void testEnabled() { + Settings.Builder settings = Settings.builder().put("xpack.ilm.enabled", false); + IndexLifecycleFeatureSet featureSet = new IndexLifecycleFeatureSet(settings.build(), licenseState, clusterService); + assertThat(featureSet.enabled(), equalTo(false)); + + settings = Settings.builder().put("xpack.ilm.enabled", true); + featureSet = new IndexLifecycleFeatureSet(settings.build(), licenseState, clusterService); + assertThat(featureSet.enabled(), equalTo(true)); + } + + public void testName() { + IndexLifecycleFeatureSet featureSet = new IndexLifecycleFeatureSet(Settings.EMPTY, licenseState, clusterService); + assertThat(featureSet.name(), equalTo("ilm")); + } + + public void testNativeCodeInfo() { + IndexLifecycleFeatureSet featureSet = new IndexLifecycleFeatureSet(Settings.EMPTY, licenseState, clusterService); + assertNull(featureSet.nativeCodeInfo()); + } + + @SuppressWarnings("unchecked") + public void testUsageStats() throws Exception { + List policies = new ArrayList<>(); + LifecyclePolicy policy1 = new LifecyclePolicy(randomAlphaOfLength(10), Collections.emptyMap()); + policies.add(policy1); + PolicyStats policy1Stats = new PolicyStats(Collections.emptyMap()); + + Map phases1 = new HashMap<>(); + LifecyclePolicy policy2 = new LifecyclePolicy(randomAlphaOfLength(10), phases1); + policies.add(policy2); + PolicyStats policy2Stats = new PolicyStats(Collections.emptyMap()); + + LifecyclePolicy policy3 = new LifecyclePolicy(randomAlphaOfLength(10), Collections.emptyMap()); + policies.add(policy3); + PolicyStats policy3Stats = new PolicyStats(Collections.emptyMap()); + + ClusterState clusterState = buildClusterState(policies); + Mockito.when(clusterService.state()).thenReturn(clusterState); + + PlainActionFuture future = new PlainActionFuture<>(); + IndexLifecycleFeatureSet ilmFeatureSet = new IndexLifecycleFeatureSet(Settings.EMPTY, licenseState, clusterService); + ilmFeatureSet.usage(future); + IndexLifecycleFeatureSetUsage ilmUsage = (IndexLifecycleFeatureSetUsage) future.get(); + assertThat(ilmUsage.enabled(), equalTo(ilmFeatureSet.enabled())); + assertThat(ilmUsage.available(), equalTo(ilmFeatureSet.available())); + + List policyStatsList = ilmUsage.getPolicyStats(); + assertThat(policyStatsList.size(), equalTo(policies.size())); + assertThat(policyStatsList, contains(equalTo(policy1Stats), equalTo(policy2Stats), equalTo(policy3Stats))); + + } + + private ClusterState buildClusterState(List lifecyclePolicies) { + Map lifecyclePolicyMetadatasMap = lifecyclePolicies.stream() + .map(p -> new LifecyclePolicyMetadata(p, Collections.emptyMap())) + .collect(Collectors.toMap(LifecyclePolicyMetadata::getName, Function.identity())); + IndexLifecycleMetadata indexLifecycleMetadata = new IndexLifecycleMetadata(lifecyclePolicyMetadatasMap, OperationMode.RUNNING); + + MetaData metadata = MetaData.builder().putCustom(IndexLifecycleMetadata.TYPE, indexLifecycleMetadata).build(); + return ClusterState.builder(new ClusterName("my_cluster")).metaData(metadata).build(); + } +} From 2d093d887e37c89e3ce334dbeb10738d9069230c Mon Sep 17 00:00:00 2001 From: Colin Goodheart-Smithe Date: Thu, 13 Sep 2018 12:59:17 +0100 Subject: [PATCH 4/6] Fixes merge errors --- .../core/indexlifecycle/IndexLifecycleFeatureSetUsage.java | 2 +- .../xpack/indexlifecycle/IndexLifecycleFeatureSet.java | 2 +- .../xpack/indexlifecycle/IndexLifecycleFeatureSetTests.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsage.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsage.java index a1c0a4f585242..ebb8116c6a2b3 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsage.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsage.java @@ -150,7 +150,7 @@ public void writeTo(StreamOutput out) throws IOException { @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); - builder.field(Phase.AFTER_FIELD.getPreferredName(), after.getStringRep()); + builder.field(Phase.MINIMUM_AGE.getPreferredName(), after.getStringRep()); builder.field(Phase.ACTIONS_FIELD.getPreferredName(), actionNames); builder.endObject(); return builder; diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSet.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSet.java index ddd4881188e2d..165a5bb62d109 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSet.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSet.java @@ -69,7 +69,7 @@ public void usage(ActionListener listener) { List policyStats = lifecycleMetadata.getPolicies().values().stream().map(policy -> { Map phaseStats = policy.getPhases().values().stream().map(phase -> { String[] actionNames = phase.getActions().keySet().toArray(new String[phase.getActions().size()]); - return new Tuple(phase.getName(), new PhaseStats(phase.getAfter(), actionNames)); + return new Tuple(phase.getName(), new PhaseStats(phase.getMinimumAge(), actionNames)); }).collect(Collectors.toMap(Tuple::v1, Tuple::v2)); return new PolicyStats(phaseStats); }).collect(Collectors.toList()); diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSetTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSetTests.java index b54fed59b37b4..c0db75b8b45ec 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSetTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSetTests.java @@ -115,7 +115,7 @@ public void testUsageStats() throws Exception { private ClusterState buildClusterState(List lifecyclePolicies) { Map lifecyclePolicyMetadatasMap = lifecyclePolicies.stream() - .map(p -> new LifecyclePolicyMetadata(p, Collections.emptyMap())) + .map(p -> new LifecyclePolicyMetadata(p, Collections.emptyMap(), 1, 0L)) .collect(Collectors.toMap(LifecyclePolicyMetadata::getName, Function.identity())); IndexLifecycleMetadata indexLifecycleMetadata = new IndexLifecycleMetadata(lifecyclePolicyMetadatasMap, OperationMode.RUNNING); From 368c0b47a984c06905e2c9c131f2dd15cbfe81e6 Mon Sep 17 00:00:00 2001 From: Colin Goodheart-Smithe Date: Wed, 24 Oct 2018 09:00:14 +0100 Subject: [PATCH 5/6] Add number of indices managed to usage stats Also adds more tests --- .../IndexLifecycleFeatureSetUsage.java | 26 +++++++- .../core/indexlifecycle/PolicyStatsTests.java | 19 ++++-- .../IndexLifecycleFeatureSet.java | 19 +++++- .../IndexLifecycleFeatureSetTests.java | 45 ++++++++++---- .../IndexLifecycleFeatureSetUsageTests.java | 59 +++++++++++++++++++ .../xpack/indexlifecycle/PhaseStatsTests.java | 54 +++++++++++++++++ .../indexlifecycle/PolicyStatsTests.java | 58 ++++++++++++++++++ 7 files changed, 259 insertions(+), 21 deletions(-) create mode 100644 x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSetUsageTests.java create mode 100644 x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/PhaseStatsTests.java create mode 100644 x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/PolicyStatsTests.java diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsage.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsage.java index ebb8116c6a2b3..0c41ff2f7ca2b 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsage.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsage.java @@ -5,6 +5,8 @@ */ package org.elasticsearch.xpack.core.indexlifecycle; +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.io.stream.Writeable; @@ -82,25 +84,33 @@ public boolean equals(Object obj) { } public static final class PolicyStats implements ToXContentObject, Writeable { + + public static final ParseField INDICES_MANAGED_FIELD = new ParseField("indices_managed"); + private final Map phaseStats; + private final int indicesManaged; - public PolicyStats(Map phaseStats) { + public PolicyStats(Map phaseStats, int numberIndicesManaged) { this.phaseStats = phaseStats; + this.indicesManaged = numberIndicesManaged; } public PolicyStats(StreamInput in) throws IOException { this.phaseStats = in.readMap(StreamInput::readString, PhaseStats::new); + this.indicesManaged = in.readVInt(); } @Override public void writeTo(StreamOutput out) throws IOException { out.writeMap(phaseStats, StreamOutput::writeString, (o, p) -> p.writeTo(o)); + out.writeVInt(indicesManaged); } @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); builder.field(LifecyclePolicy.PHASES_FIELD.getPreferredName(), phaseStats); + builder.field(INDICES_MANAGED_FIELD.getPreferredName(), indicesManaged); builder.endObject(); return builder; } @@ -109,9 +119,13 @@ public Map getPhaseStats() { return phaseStats; } + public int getIndicesManaged() { + return indicesManaged; + } + @Override public int hashCode() { - return Objects.hash(phaseStats); + return Objects.hash(phaseStats, indicesManaged); } @Override @@ -123,7 +137,13 @@ public boolean equals(Object obj) { return false; } PolicyStats other = (PolicyStats) obj; - return Objects.equals(phaseStats, other.phaseStats); + return Objects.equals(phaseStats, other.phaseStats) && + Objects.equals(indicesManaged, other.indicesManaged); + } + + @Override + public String toString() { + return Strings.toString(this); } } diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/PolicyStatsTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/PolicyStatsTests.java index 12f1a13fc941a..0a9ac853c89fe 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/PolicyStatsTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/indexlifecycle/PolicyStatsTests.java @@ -28,14 +28,25 @@ public static PolicyStats createRandomInstance() { for (int i = 0; i < size; i++) { phaseStats.put(randomAlphaOfLengthBetween(1, 20), PhaseStatsTests.createRandomInstance()); } - return new PolicyStats(phaseStats); + return new PolicyStats(phaseStats, randomIntBetween(0, 100)); } @Override protected PolicyStats mutateInstance(PolicyStats instance) throws IOException { - Map phaseStats = new HashMap<>(instance.getPhaseStats()); - phaseStats.put(randomAlphaOfLengthBetween(1, 20), PhaseStatsTests.createRandomInstance()); - return new PolicyStats(phaseStats); + Map phaseStats = instance.getPhaseStats(); + int indicesManaged = instance.getIndicesManaged(); + switch (between(0, 1)) { + case 0: + phaseStats = new HashMap<>(instance.getPhaseStats()); + phaseStats.put(randomAlphaOfLengthBetween(1, 20), PhaseStatsTests.createRandomInstance()); + break; + case 1: + indicesManaged = randomIntBetween(1, 50); + break; + default: + throw new AssertionError("Illegal randomisation branch"); + } + return new PolicyStats(phaseStats, indicesManaged); } @Override diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSet.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSet.java index 165a5bb62d109..2469621316889 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSet.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSet.java @@ -6,6 +6,7 @@ package org.elasticsearch.xpack.indexlifecycle; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.collect.Tuple; @@ -19,7 +20,9 @@ import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleFeatureSetUsage.PhaseStats; import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleFeatureSetUsage.PolicyStats; import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleMetadata; +import org.elasticsearch.xpack.core.indexlifecycle.LifecycleSettings; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -64,14 +67,26 @@ public Map nativeCodeInfo() { @Override public void usage(ActionListener listener) { - IndexLifecycleMetadata lifecycleMetadata = clusterService.state().metaData().custom(IndexLifecycleMetadata.TYPE); + MetaData metaData = clusterService.state().metaData(); + IndexLifecycleMetadata lifecycleMetadata = metaData.custom(IndexLifecycleMetadata.TYPE); if (enabled() && lifecycleMetadata != null) { + Map policyUsage = new HashMap<>(); + metaData.indices().forEach(entry -> { + String policyName = LifecycleSettings.LIFECYCLE_NAME_SETTING.get(entry.value.getSettings()); + Integer indicesManaged = policyUsage.get(policyName); + if (indicesManaged == null) { + indicesManaged = 1; + } else { + indicesManaged = indicesManaged + 1; + } + policyUsage.put(policyName, indicesManaged); + }); List policyStats = lifecycleMetadata.getPolicies().values().stream().map(policy -> { Map phaseStats = policy.getPhases().values().stream().map(phase -> { String[] actionNames = phase.getActions().keySet().toArray(new String[phase.getActions().size()]); return new Tuple(phase.getName(), new PhaseStats(phase.getMinimumAge(), actionNames)); }).collect(Collectors.toMap(Tuple::v1, Tuple::v2)); - return new PolicyStats(phaseStats); + return new PolicyStats(phaseStats, policyUsage.getOrDefault(policy.getName(), 0)); }).collect(Collectors.toList()); listener.onResponse(new IndexLifecycleFeatureSetUsage(available(), enabled(), policyStats)); } else { diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSetTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSetTests.java index c0db75b8b45ec..d83a41b4e60bc 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSetTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSetTests.java @@ -6,9 +6,11 @@ package org.elasticsearch.xpack.indexlifecycle; +import org.elasticsearch.Version; import org.elasticsearch.action.support.PlainActionFuture; import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.ClusterState; +import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.service.ClusterService; import org.elasticsearch.common.settings.Settings; @@ -19,6 +21,7 @@ import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleMetadata; import org.elasticsearch.xpack.core.indexlifecycle.LifecyclePolicy; import org.elasticsearch.xpack.core.indexlifecycle.LifecyclePolicyMetadata; +import org.elasticsearch.xpack.core.indexlifecycle.LifecycleSettings; import org.elasticsearch.xpack.core.indexlifecycle.OperationMode; import org.elasticsearch.xpack.core.indexlifecycle.Phase; import org.junit.Before; @@ -32,7 +35,6 @@ import java.util.function.Function; import java.util.stream.Collectors; -import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.equalTo; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -81,23 +83,31 @@ public void testNativeCodeInfo() { assertNull(featureSet.nativeCodeInfo()); } - @SuppressWarnings("unchecked") public void testUsageStats() throws Exception { + Map indexPolicies = new HashMap<>(); List policies = new ArrayList<>(); - LifecyclePolicy policy1 = new LifecyclePolicy(randomAlphaOfLength(10), Collections.emptyMap()); + String policy1Name = randomAlphaOfLength(10); + String policy2Name = randomAlphaOfLength(10); + String policy3Name = randomAlphaOfLength(10); + indexPolicies.put("index_1", policy1Name); + indexPolicies.put("index_2", policy1Name); + indexPolicies.put("index_3", policy1Name); + indexPolicies.put("index_4", policy1Name); + indexPolicies.put("index_5", policy3Name); + LifecyclePolicy policy1 = new LifecyclePolicy(policy1Name, Collections.emptyMap()); policies.add(policy1); - PolicyStats policy1Stats = new PolicyStats(Collections.emptyMap()); + PolicyStats policy1Stats = new PolicyStats(Collections.emptyMap(), 4); Map phases1 = new HashMap<>(); - LifecyclePolicy policy2 = new LifecyclePolicy(randomAlphaOfLength(10), phases1); + LifecyclePolicy policy2 = new LifecyclePolicy(policy2Name, phases1); policies.add(policy2); - PolicyStats policy2Stats = new PolicyStats(Collections.emptyMap()); + PolicyStats policy2Stats = new PolicyStats(Collections.emptyMap(), 0); - LifecyclePolicy policy3 = new LifecyclePolicy(randomAlphaOfLength(10), Collections.emptyMap()); + LifecyclePolicy policy3 = new LifecyclePolicy(policy3Name, Collections.emptyMap()); policies.add(policy3); - PolicyStats policy3Stats = new PolicyStats(Collections.emptyMap()); + PolicyStats policy3Stats = new PolicyStats(Collections.emptyMap(), 1); - ClusterState clusterState = buildClusterState(policies); + ClusterState clusterState = buildClusterState(policies, indexPolicies); Mockito.when(clusterService.state()).thenReturn(clusterState); PlainActionFuture future = new PlainActionFuture<>(); @@ -109,17 +119,28 @@ public void testUsageStats() throws Exception { List policyStatsList = ilmUsage.getPolicyStats(); assertThat(policyStatsList.size(), equalTo(policies.size())); - assertThat(policyStatsList, contains(equalTo(policy1Stats), equalTo(policy2Stats), equalTo(policy3Stats))); + assertTrue(policyStatsList.contains(policy1Stats)); + assertTrue(policyStatsList.contains(policy2Stats)); + assertTrue(policyStatsList.contains(policy3Stats)); } - private ClusterState buildClusterState(List lifecyclePolicies) { + private ClusterState buildClusterState(List lifecyclePolicies, Map indexPolicies) { Map lifecyclePolicyMetadatasMap = lifecyclePolicies.stream() .map(p -> new LifecyclePolicyMetadata(p, Collections.emptyMap(), 1, 0L)) .collect(Collectors.toMap(LifecyclePolicyMetadata::getName, Function.identity())); IndexLifecycleMetadata indexLifecycleMetadata = new IndexLifecycleMetadata(lifecyclePolicyMetadatasMap, OperationMode.RUNNING); - MetaData metadata = MetaData.builder().putCustom(IndexLifecycleMetadata.TYPE, indexLifecycleMetadata).build(); + MetaData.Builder metadata = MetaData.builder().putCustom(IndexLifecycleMetadata.TYPE, indexLifecycleMetadata); + indexPolicies.forEach((indexName, policyName) -> { + Settings indexSettings = Settings.builder().put(LifecycleSettings.LIFECYCLE_NAME, policyName) + .put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1) + .put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0) + .put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT).build(); + IndexMetaData.Builder indexMetadata = IndexMetaData.builder(indexName).settings(indexSettings); + metadata.put(indexMetadata); + }); + return ClusterState.builder(new ClusterName("my_cluster")).metaData(metadata).build(); } } diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSetUsageTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSetUsageTests.java new file mode 100644 index 0000000000000..7bd974d31c176 --- /dev/null +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/IndexLifecycleFeatureSetUsageTests.java @@ -0,0 +1,59 @@ +/* + * 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.indexlifecycle; + +import org.elasticsearch.common.io.stream.Writeable.Reader; +import org.elasticsearch.test.AbstractWireSerializingTestCase; +import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleFeatureSetUsage; +import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleFeatureSetUsage.PolicyStats; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class IndexLifecycleFeatureSetUsageTests extends AbstractWireSerializingTestCase { + + @Override + protected IndexLifecycleFeatureSetUsage createTestInstance() { + boolean available = randomBoolean(); + boolean enabled = randomBoolean(); + List policyStats = new ArrayList<>(); + int size = randomIntBetween(0, 10); + for (int i = 0; i < size; i++) { + policyStats.add(PolicyStatsTests.randomPolicyStats()); + } + return new IndexLifecycleFeatureSetUsage(available, enabled, policyStats); + } + + @Override + protected IndexLifecycleFeatureSetUsage mutateInstance(IndexLifecycleFeatureSetUsage instance) throws IOException { + boolean available = instance.available(); + boolean enabled = instance.enabled(); + List policyStats = instance.getPolicyStats(); + switch (between(0, 2)) { + case 0: + available = available == false; + break; + case 1: + enabled = enabled == false; + break; + case 2: + policyStats = new ArrayList<>(policyStats); + policyStats.add(PolicyStatsTests.randomPolicyStats()); + break; + default: + throw new AssertionError("Illegal randomisation branch"); + } + return new IndexLifecycleFeatureSetUsage(available, enabled, policyStats); + } + + @Override + protected Reader instanceReader() { + return IndexLifecycleFeatureSetUsage::new; + } + +} diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/PhaseStatsTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/PhaseStatsTests.java new file mode 100644 index 0000000000000..d148ee2ce0cfe --- /dev/null +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/PhaseStatsTests.java @@ -0,0 +1,54 @@ +/* + * 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.indexlifecycle; + +import org.elasticsearch.common.io.stream.Writeable.Reader; +import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.test.AbstractWireSerializingTestCase; +import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleFeatureSetUsage.PhaseStats; + +import java.io.IOException; +import java.util.Arrays; + +public class PhaseStatsTests extends AbstractWireSerializingTestCase { + + @Override + protected PhaseStats createTestInstance() { + return randomPhaseStats(); + } + + static PhaseStats randomPhaseStats() { + TimeValue after = TimeValue.parseTimeValue(randomTimeValue(0, 1000000000, "s", "m", "h", "d"), "test_after"); + String[] actionNames = generateRandomStringArray(10, 20, false); + return new PhaseStats(after, actionNames); + } + + @Override + protected PhaseStats mutateInstance(PhaseStats instance) throws IOException { + TimeValue after = instance.getAfter(); + String[] actionNames = instance.getActionNames(); + switch (between(0, 1)) { + case 0: + after = randomValueOtherThan(after, + () -> TimeValue.parseTimeValue(randomTimeValue(0, 1000000000, "s", "m", "h", "d"), "test_after")); + break; + case 1: + actionNames = Arrays.copyOf(actionNames, actionNames.length + 1); + actionNames[actionNames.length - 1] = randomAlphaOfLengthBetween(10, 20); + break; + default: + throw new AssertionError("Illegal randomisation branch"); + } + return new PhaseStats(after, actionNames); + } + + @Override + protected Reader instanceReader() { + return PhaseStats::new; + } + +} diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/PolicyStatsTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/PolicyStatsTests.java new file mode 100644 index 0000000000000..f2a77ee9e246c --- /dev/null +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/PolicyStatsTests.java @@ -0,0 +1,58 @@ +/* + * 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.indexlifecycle; + +import org.elasticsearch.common.io.stream.Writeable.Reader; +import org.elasticsearch.test.AbstractWireSerializingTestCase; +import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleFeatureSetUsage.PhaseStats; +import org.elasticsearch.xpack.core.indexlifecycle.IndexLifecycleFeatureSetUsage.PolicyStats; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class PolicyStatsTests extends AbstractWireSerializingTestCase { + + @Override + protected PolicyStats createTestInstance() { + return randomPolicyStats(); + } + + static PolicyStats randomPolicyStats() { + Map phaseStats = new HashMap<>(); + int size = randomIntBetween(0, 10); + for (int i = 0; i < size; i++) { + phaseStats.put(randomAlphaOfLength(10), PhaseStatsTests.randomPhaseStats()); + } + int numberIndicesManaged = randomIntBetween(0, 1000); + return new PolicyStats(phaseStats, numberIndicesManaged); + } + + @Override + protected PolicyStats mutateInstance(PolicyStats instance) throws IOException { + Map phaseStats = instance.getPhaseStats(); + int numberIndicesManaged = instance.getIndicesManaged(); + switch (between(0, 1)) { + case 0: + phaseStats = new HashMap<>(phaseStats); + phaseStats.put(randomAlphaOfLength(10), PhaseStatsTests.randomPhaseStats()); + break; + case 1: + numberIndicesManaged += randomIntBetween(1, 10); + break; + default: + throw new AssertionError("Illegal randomisation branch"); + } + return new PolicyStats(phaseStats, numberIndicesManaged); + } + + @Override + protected Reader instanceReader() { + return PolicyStats::new; + } + +} From 25e66ed4d7bf85c2387a19c5eefa4165064b8654 Mon Sep 17 00:00:00 2001 From: Colin Goodheart-Smithe Date: Wed, 24 Oct 2018 10:56:17 +0100 Subject: [PATCH 6/6] Addresses Review comments --- .../IndexLifecycleFeatureSetUsage.java | 16 ++++++++-------- .../xpack/indexlifecycle/PhaseStatsTests.java | 10 +++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsage.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsage.java index 0c41ff2f7ca2b..a738ad3e34cfa 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsage.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/indexlifecycle/IndexLifecycleFeatureSetUsage.java @@ -149,28 +149,28 @@ public String toString() { public static final class PhaseStats implements ToXContentObject, Writeable { private final String[] actionNames; - private final TimeValue after; + private final TimeValue minimumAge; public PhaseStats(TimeValue after, String[] actionNames) { this.actionNames = actionNames; - this.after = after; + this.minimumAge = after; } public PhaseStats(StreamInput in) throws IOException { actionNames = in.readStringArray(); - after = in.readTimeValue(); + minimumAge = in.readTimeValue(); } @Override public void writeTo(StreamOutput out) throws IOException { out.writeStringArray(actionNames); - out.writeTimeValue(after); + out.writeTimeValue(minimumAge); } @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); - builder.field(Phase.MINIMUM_AGE.getPreferredName(), after.getStringRep()); + builder.field(Phase.MINIMUM_AGE.getPreferredName(), minimumAge.getMillis()); builder.field(Phase.ACTIONS_FIELD.getPreferredName(), actionNames); builder.endObject(); return builder; @@ -181,12 +181,12 @@ public String[] getActionNames() { } public TimeValue getAfter() { - return after; + return minimumAge; } @Override public int hashCode() { - return Objects.hash(Arrays.hashCode(actionNames), after); + return Objects.hash(Arrays.hashCode(actionNames), minimumAge); } @Override @@ -198,7 +198,7 @@ public boolean equals(Object obj) { return false; } PhaseStats other = (PhaseStats) obj; - return Objects.equals(after, other.after) && + return Objects.equals(minimumAge, other.minimumAge) && Objects.deepEquals(actionNames, other.actionNames); } } diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/PhaseStatsTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/PhaseStatsTests.java index d148ee2ce0cfe..fe7fd1fca05d3 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/PhaseStatsTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/indexlifecycle/PhaseStatsTests.java @@ -22,18 +22,18 @@ protected PhaseStats createTestInstance() { } static PhaseStats randomPhaseStats() { - TimeValue after = TimeValue.parseTimeValue(randomTimeValue(0, 1000000000, "s", "m", "h", "d"), "test_after"); + TimeValue minimumAge = TimeValue.parseTimeValue(randomTimeValue(0, 1000000000, "s", "m", "h", "d"), "test_after"); String[] actionNames = generateRandomStringArray(10, 20, false); - return new PhaseStats(after, actionNames); + return new PhaseStats(minimumAge, actionNames); } @Override protected PhaseStats mutateInstance(PhaseStats instance) throws IOException { - TimeValue after = instance.getAfter(); + TimeValue minimumAge = instance.getAfter(); String[] actionNames = instance.getActionNames(); switch (between(0, 1)) { case 0: - after = randomValueOtherThan(after, + minimumAge = randomValueOtherThan(minimumAge, () -> TimeValue.parseTimeValue(randomTimeValue(0, 1000000000, "s", "m", "h", "d"), "test_after")); break; case 1: @@ -43,7 +43,7 @@ protected PhaseStats mutateInstance(PhaseStats instance) throws IOException { default: throw new AssertionError("Illegal randomisation branch"); } - return new PhaseStats(after, actionNames); + return new PhaseStats(minimumAge, actionNames); } @Override