Skip to content

Implement framework for migrating system indices #78951

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

Merged
merged 37 commits into from
Oct 20, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
03fdac2
Implement framework for migrating system indices
gwbrown Oct 12, 2021
1371cd2
Remove extra `onResponse`
gwbrown Oct 12, 2021
d528882
Address Todos/cleanup
gwbrown Oct 13, 2021
5f8b65e
Return the correct list when starting migration
gwbrown Oct 13, 2021
dabad50
Tweak docs
gwbrown Oct 13, 2021
5cdff06
Merge branch 'master' into si/upgrade-framework
gwbrown Oct 13, 2021
4c4d4b7
Merge branch 'master' into si/upgrade-framework
gwbrown Oct 13, 2021
acdcd34
Fix compilation after merge
gwbrown Oct 13, 2021
4fe3373
Merge branch 'master' into si/upgrade-framework
gwbrown Oct 14, 2021
1961c71
Fix test failures that expected fake responses
gwbrown Oct 14, 2021
83415e4
Extract constant for upgrade version per review
gwbrown Oct 14, 2021
932c0d0
Javadoc + cleanup per review
gwbrown Oct 14, 2021
08f22f1
Rename results classes to clarify their relationship
gwbrown Oct 14, 2021
7afd137
Merge branch 'master' into si/upgrade-framework
gwbrown Oct 14, 2021
95356d9
Tests + always run on master node
gwbrown Oct 15, 2021
4b2bbbf
Fix index name & doc count type
gwbrown Oct 15, 2021
fae67c0
Javadoc
gwbrown Oct 15, 2021
4552e75
Plumb in callback metadata + test it
gwbrown Oct 15, 2021
9cec136
Merge branch 'master' into si/upgrade-framework
gwbrown Oct 15, 2021
a84e781
Line length
gwbrown Oct 15, 2021
bad48b2
Verify that the pre/post migration hooks are called
gwbrown Oct 18, 2021
998ca25
Set the origin before calling reindex
gwbrown Oct 18, 2021
a4fae04
Check results in upgrade callback + fix bug where results were update…
gwbrown Oct 18, 2021
69986f2
Add multi-feature integration test
gwbrown Oct 18, 2021
ce074cf
Assert both feature names
gwbrown Oct 18, 2021
cd11bce
Cleanup
gwbrown Oct 18, 2021
6c9c9da
Merge branch 'master' into si/upgrade-framework
gwbrown Oct 18, 2021
1ac86ad
Fix unit tests for new logic
gwbrown Oct 18, 2021
c753724
Javadoc + missed renames per review
gwbrown Oct 19, 2021
cf61671
Copy aliases + alias assertions
gwbrown Oct 19, 2021
9bddfbb
Merge branch 'master' into si/upgrade-framework
gwbrown Oct 19, 2021
76e8aed
Add necessary system privileges
gwbrown Oct 19, 2021
53da87f
Merge branch 'master' into si/upgrade-framework
gwbrown Oct 19, 2021
427389e
Logging tweaks
gwbrown Oct 19, 2021
59b70a0
Fix test for real version math
gwbrown Oct 19, 2021
124c6d8
Adjust test for new system permissions
gwbrown Oct 19, 2021
34fb47d
Merge branch 'master' into si/upgrade-framework
gwbrown Oct 19, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,14 @@ protected org.elasticsearch.action.admin.cluster.migration.GetFeatureUpgradeStat
randomAlphaOfLengthBetween(3, 20),
randomFrom(Version.CURRENT, Version.CURRENT.minimumCompatibilityVersion()),
randomFrom(org.elasticsearch.action.admin.cluster.migration.GetFeatureUpgradeStatusResponse.UpgradeStatus.values()),
randomList(4,
() -> new org.elasticsearch.action.admin.cluster.migration.GetFeatureUpgradeStatusResponse.IndexVersion(
randomList(
4,
() -> new org.elasticsearch.action.admin.cluster.migration.GetFeatureUpgradeStatusResponse.IndexInfo(
randomAlphaOfLengthBetween(3, 20),
randomFrom(Version.CURRENT, Version.CURRENT.minimumCompatibilityVersion())))
randomFrom(Version.CURRENT, Version.CURRENT.minimumCompatibilityVersion()),
null
)
)
)),
randomFrom(org.elasticsearch.action.admin.cluster.migration.GetFeatureUpgradeStatusResponse.UpgradeStatus.values())
);
Expand Down Expand Up @@ -78,12 +82,12 @@ protected void assertInstances(
assertThat(clientStatus.getIndexVersions(), hasSize(serverTestStatus.getIndexVersions().size()));

for (int j = 0; i < clientStatus.getIndexVersions().size(); i++) {
org.elasticsearch.action.admin.cluster.migration.GetFeatureUpgradeStatusResponse.IndexVersion serverIndexVersion
org.elasticsearch.action.admin.cluster.migration.GetFeatureUpgradeStatusResponse.IndexInfo serverIndexInfo
= serverTestStatus.getIndexVersions().get(j);
GetFeatureUpgradeStatusResponse.IndexVersion clientIndexVersion = clientStatus.getIndexVersions().get(j);

assertThat(clientIndexVersion.getIndexName(), equalTo(serverIndexVersion.getIndexName()));
assertThat(clientIndexVersion.getVersion(), equalTo(serverIndexVersion.getVersion().toString()));
assertThat(clientIndexVersion.getIndexName(), equalTo(serverIndexInfo.getIndexName()));
assertThat(clientIndexVersion.getVersion(), equalTo(serverIndexInfo.getVersion().toString()));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,20 @@

package org.elasticsearch.action.admin.cluster.migration;

import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.Version;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.core.Nullable;
import org.elasticsearch.xcontent.ToXContentObject;
import org.elasticsearch.xcontent.XContentBuilder;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
Expand Down Expand Up @@ -98,9 +101,18 @@ public String toString() {
}

public enum UpgradeStatus {
UPGRADE_NEEDED,
NO_UPGRADE_NEEDED,
IN_PROGRESS
UPGRADE_NEEDED,
IN_PROGRESS,
ERROR;

public static UpgradeStatus combine(UpgradeStatus... statuses) {
int statusOrd = 0;
for (UpgradeStatus status : statuses) {
statusOrd = Math.max(status.ordinal(), statusOrd);
}
return UpgradeStatus.values()[statusOrd];
}
}

/**
Expand All @@ -111,20 +123,20 @@ public static class FeatureUpgradeStatus implements Writeable, ToXContentObject
private final String featureName;
private final Version minimumIndexVersion;
private final UpgradeStatus upgradeStatus;
private final List<IndexVersion> indexVersions;
private final List<IndexInfo> indexInfos;

/**
* @param featureName Name of the feature
* @param minimumIndexVersion Earliest Elasticsearch version used to create a system index for this feature
* @param upgradeStatus Whether the feature needs to be upgraded
* @param indexVersions A list of this feature's concrete indices and the Elasticsearch version that created them
* @param indexInfos A list of this feature's concrete indices and the Elasticsearch version that created them
*/
public FeatureUpgradeStatus(String featureName, Version minimumIndexVersion,
UpgradeStatus upgradeStatus, List<IndexVersion> indexVersions) {
UpgradeStatus upgradeStatus, List<IndexInfo> indexInfos) {
this.featureName = featureName;
this.minimumIndexVersion = minimumIndexVersion;
this.upgradeStatus = upgradeStatus;
this.indexVersions = indexVersions;
this.indexInfos = indexInfos;
}

/**
Expand All @@ -135,7 +147,7 @@ public FeatureUpgradeStatus(StreamInput in) throws IOException {
this.featureName = in.readString();
this.minimumIndexVersion = Version.readVersion(in);
this.upgradeStatus = in.readEnum(UpgradeStatus.class);
this.indexVersions = in.readList(IndexVersion::new);
this.indexInfos = in.readList(IndexInfo::new);
}

public String getFeatureName() {
Expand All @@ -150,16 +162,16 @@ public UpgradeStatus getUpgradeStatus() {
return this.upgradeStatus;
}

public List<IndexVersion> getIndexVersions() {
return this.indexVersions;
public List<IndexInfo> getIndexVersions() {
return this.indexInfos;
}

@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeString(this.featureName);
Version.writeVersion(this.minimumIndexVersion, out);
out.writeEnum(this.upgradeStatus);
out.writeList(this.indexVersions);
out.writeList(this.indexInfos);
}

@Override
Expand All @@ -169,7 +181,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
builder.field("minimum_index_version", this.minimumIndexVersion.toString());
builder.field("upgrade_status", this.upgradeStatus);
builder.startArray("indices");
for (IndexVersion version : this.indexVersions) {
for (IndexInfo version : this.indexInfos) {
builder.value(version);
}
builder.endArray();
Expand All @@ -185,12 +197,12 @@ public boolean equals(Object o) {
return Objects.equals(featureName, that.featureName)
&& Objects.equals(minimumIndexVersion, that.minimumIndexVersion)
&& Objects.equals(upgradeStatus, that.upgradeStatus)
&& Objects.equals(indexVersions, that.indexVersions);
&& Objects.equals(indexInfos, that.indexInfos);
}

@Override
public int hashCode() {
return Objects.hash(featureName, minimumIndexVersion, upgradeStatus, indexVersions);
return Objects.hash(featureName, minimumIndexVersion, upgradeStatus, indexInfos);
}

@Override
Expand All @@ -199,34 +211,45 @@ public String toString() {
"featureName='" + featureName + '\'' +
", minimumIndexVersion='" + minimumIndexVersion + '\'' +
", upgradeStatus='" + upgradeStatus + '\'' +
", indexVersions=" + indexVersions +
", indexVersions=" + indexInfos +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A very tiny nitpick: indexVersions= could be changed to indexInfos=.

'}';
}
}

/**
* A data class that holds an index name and the version of Elasticsearch with which that index was created
*/
public static class IndexVersion implements Writeable, ToXContentObject {
public static class IndexInfo implements Writeable, ToXContentObject {
private static final Map<String, String> STACK_TRACE_ENABLED_PARAMS =
Map.of(ElasticsearchException.REST_EXCEPTION_SKIP_STACK_TRACE, "false");

private final String indexName;
private final Version version;
@Nullable private final Exception exception; // Present if this index failed

/**
* @param indexName Name of the index
* @param version Version of Elasticsearch that created the index
*/
public IndexVersion(String indexName, Version version) {
public IndexInfo(String indexName, Version version, Exception exception) {
this.indexName = indexName;
this.version = version;
this.exception = exception;
}

/**
* @param in A stream input for a serialized index version object
* @throws IOException if we can't deserialize the object
*/
public IndexVersion(StreamInput in) throws IOException {
public IndexInfo(StreamInput in) throws IOException {
this.indexName = in.readString();
this.version = Version.readVersion(in);
boolean hasException = in.readBoolean();
if (hasException) {
this.exception = in.readException();
} else {
this.exception = null;
}
}

public String getIndexName() {
Expand All @@ -237,17 +260,36 @@ public Version getVersion() {
return this.version;
}

public Exception getException() {
return this.exception;
}

@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeString(this.indexName);
Version.writeVersion(this.version, out);
if (exception != null) {
out.writeBoolean(true);
out.writeException(this.exception);
} else {
out.writeBoolean(false);
}
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
Params exceptionParams = new DelegatingMapParams(STACK_TRACE_ENABLED_PARAMS, params);

builder.startObject();
builder.field("index", this.indexName);
builder.field("version", this.version.toString());
if (exception != null) {
builder.startObject("failure_cause");
{
ElasticsearchException.generateFailureXContent(builder, exceptionParams, exception, true);
}
builder.endObject();
}
builder.endObject();
return builder;
}
Expand All @@ -256,7 +298,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
IndexVersion that = (IndexVersion) o;
IndexInfo that = (IndexInfo) o;
return indexName.equals(that.indexName) && version.equals(that.version);
}

Expand Down
Loading