Skip to content
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

[Deprecation] Refine Transform Destination Index message #122192

Merged
merged 5 commits into from
Feb 13, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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 @@ -13,6 +13,7 @@
import org.elasticsearch.common.TriFunction;
import org.elasticsearch.common.time.DateFormatter;
import org.elasticsearch.common.time.LegacyFormatNames;
import org.elasticsearch.core.Strings;
import org.elasticsearch.index.IndexModule;
import org.elasticsearch.index.IndexSettings;
import org.elasticsearch.index.IndexVersion;
Expand Down Expand Up @@ -95,25 +96,37 @@ private DeprecationIssue oldIndicesCheck(
IndexVersion currentCompatibilityVersion = indexMetadata.getCompatibilityVersion();
// We intentionally exclude indices that are in data streams because they will be picked up by DataStreamDeprecationChecks
if (DeprecatedIndexPredicate.reindexRequired(indexMetadata, false) && isNotDataStreamIndex(indexMetadata, clusterState)) {
return new DeprecationIssue(
DeprecationIssue.Level.CRITICAL,
"Old index with a compatibility version < 9.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking-changes-9.0.html",
"This index has version: " + currentCompatibilityVersion.toReleaseVersion(),
false,
meta(indexMetadata, indexToTransformIds)
);
var transforms = transformIdsForIndex(indexMetadata, indexToTransformIds);
if (transforms.isEmpty() == false) {
return new DeprecationIssue(
DeprecationIssue.Level.CRITICAL,
"One or more Transforms write to this index with a compatibility version < 9.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-9.0.html"
+ "#breaking_90_transform_destination_index",
Strings.format(
"Transforms [%s] write to this index with version [%s].",
String.join(", ", transforms),
currentCompatibilityVersion.toReleaseVersion()
),
false,
Map.of("reindex_required", true, "transform_ids", transforms)
);
} else {
return new DeprecationIssue(
DeprecationIssue.Level.CRITICAL,
"Old index with a compatibility version < 9.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking-changes-9.0.html",
"This index has version: " + currentCompatibilityVersion.toReleaseVersion(),
false,
Map.of("reindex_required", true)
);
}
}
return null;
}

private Map<String, Object> meta(IndexMetadata indexMetadata, Map<String, List<String>> indexToTransformIds) {
var transforms = indexToTransformIds.getOrDefault(indexMetadata.getIndex().getName(), List.of());
if (transforms.isEmpty()) {
return Map.of("reindex_required", true);
} else {
return Map.of("reindex_required", true, "transform_ids", transforms);
}
private List<String> transformIdsForIndex(IndexMetadata indexMetadata, Map<String, List<String>> indexToTransformIds) {
return indexToTransformIds.getOrDefault(indexMetadata.getIndex().getName(), List.of());
}

private DeprecationIssue ignoredOldIndicesCheck(
Expand All @@ -124,16 +137,33 @@ private DeprecationIssue ignoredOldIndicesCheck(
IndexVersion currentCompatibilityVersion = indexMetadata.getCompatibilityVersion();
// We intentionally exclude indices that are in data streams because they will be picked up by DataStreamDeprecationChecks
if (DeprecatedIndexPredicate.reindexRequired(indexMetadata, true) && isNotDataStreamIndex(indexMetadata, clusterState)) {
return new DeprecationIssue(
DeprecationIssue.Level.WARNING,
"Old index with a compatibility version < 9.0 Has Been Ignored",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking-changes-9.0.html",
"This read-only index has version: "
+ currentCompatibilityVersion.toReleaseVersion()
+ " and will be supported as read-only in 9.0",
false,
meta(indexMetadata, indexToTransformIds)
);
var transforms = transformIdsForIndex(indexMetadata, indexToTransformIds);
if (transforms.isEmpty() == false) {
return new DeprecationIssue(
DeprecationIssue.Level.WARNING,
Copy link
Member Author

Choose a reason for hiding this comment

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

This is probably fine as a warning - this message is emitted when there is a write block on the index, which will pause the transform indefinitely. The Transform will be effectively disabled anyway, and the user should probably delete or reset the Transform (which we can put in the link)

"One or more Transforms write to this old index with a compatibility version < 9.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-9.0.html"
+ "#breaking_90_transform_destination_index",
Strings.format(
"Transforms [%s] write to this index with version [%s] and cannot be supported as read-only in 9.0",
Copy link
Contributor

@rudolf rudolf Feb 11, 2025

Choose a reason for hiding this comment

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

I'm not sure a user would know what to do after reading this. It sounds a bit like if they upgrade to 9.0 their cluster might break because this incompatible index isn't ignored and "cannot be supported as read-only in 9.0" Whereas I think we want the takeaway from this message to be "it's fine, you can upgrade, but just beaware that your transforms aren't working"

Maybe something like:

This read-only index was created in version 7.17 and will be supported as a read-only index in 9.0. The following transforms are no longer able to write to this index [%s].

Copy link
Contributor

@szabosteve szabosteve Feb 11, 2025

Choose a reason for hiding this comment

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

I agree to change the messaging based on @rudolf's input above. I'm not familiar with the subject, but would it be possible to add something actionable to the end of the message, something that the user can do to mitigate/solve the issue? For example:

This index was created in version 7.17 and will be supported as a read-only index in 9.0. The following transforms are no longer able to write to this index [%s]. Refer to the migration guide to learn more about how to handle your transforms destination indices."

String.join(", ", transforms),
currentCompatibilityVersion.toReleaseVersion()
),
false,
Map.of("reindex_required", true, "transform_ids", transforms)
);
} else {
return new DeprecationIssue(
DeprecationIssue.Level.WARNING,
"Old index with a compatibility version < 9.0 Has Been Ignored",
Copy link
Contributor

Choose a reason for hiding this comment

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

Why capital letters in "Has Been Ignored"?

Copy link
Member Author

Choose a reason for hiding this comment

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

I do not know, that's what previously existed. We can edit it probably?

"https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking-changes-9.0.html",
"This read-only index has version: "
+ currentCompatibilityVersion.toReleaseVersion()
+ " and will be supported as read-only in 9.0",
false,
Map.of("reindex_required", true)
);
}
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,10 @@ public void testOldTransformIndicesCheck() {
.build();
var expected = new DeprecationIssue(
DeprecationIssue.Level.CRITICAL,
"Old index with a compatibility version < 9.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking-changes-9.0.html",
"This index has version: " + OLD_VERSION.toReleaseVersion(),
"One or more Transforms write to this index with a compatibility version < 9.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-9.0.html"
+ "#breaking_90_transform_destination_index",
"Transforms [test-transform] write to this index with version [" + OLD_VERSION.toReleaseVersion() + "].",
false,
Map.of("reindex_required", true, "transform_ids", List.of("test-transform"))
);
Expand All @@ -124,9 +125,10 @@ public void testOldIndicesCheckWithMultipleTransforms() {
.build();
var expected = new DeprecationIssue(
DeprecationIssue.Level.CRITICAL,
"Old index with a compatibility version < 9.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking-changes-9.0.html",
"This index has version: " + OLD_VERSION.toReleaseVersion(),
"One or more Transforms write to this index with a compatibility version < 9.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-9.0.html"
+ "#breaking_90_transform_destination_index",
"Transforms [test-transform1, test-transform2] write to this index with version [" + OLD_VERSION.toReleaseVersion() + "].",
false,
Map.of("reindex_required", true, "transform_ids", List.of("test-transform1", "test-transform2"))
);
Expand All @@ -150,9 +152,10 @@ public void testMultipleOldIndicesCheckWithTransforms() {
List.of(
new DeprecationIssue(
DeprecationIssue.Level.CRITICAL,
"Old index with a compatibility version < 9.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking-changes-9.0.html",
"This index has version: " + OLD_VERSION.toReleaseVersion(),
"One or more Transforms write to this index with a compatibility version < 9.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-9.0.html"
+ "#breaking_90_transform_destination_index",
"Transforms [test-transform1] write to this index with version [" + OLD_VERSION.toReleaseVersion() + "].",
false,
Map.of("reindex_required", true, "transform_ids", List.of("test-transform1"))
)
Expand All @@ -161,9 +164,10 @@ public void testMultipleOldIndicesCheckWithTransforms() {
List.of(
new DeprecationIssue(
DeprecationIssue.Level.CRITICAL,
"Old index with a compatibility version < 9.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/breaking-changes-9.0.html",
"This index has version: " + OLD_VERSION.toReleaseVersion(),
"One or more Transforms write to this index with a compatibility version < 9.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-9.0.html"
+ "#breaking_90_transform_destination_index",
"Transforms [test-transform2] write to this index with version [" + OLD_VERSION.toReleaseVersion() + "].",
false,
Map.of("reindex_required", true, "transform_ids", List.of("test-transform2"))
)
Expand Down Expand Up @@ -256,13 +260,7 @@ public void testOldIndicesCheckSnapshotIgnored() {
}

public void testOldIndicesIgnoredWarningCheck() {
Settings.Builder settings = settings(OLD_VERSION).put(MetadataIndexStateService.VERIFIED_READ_ONLY_SETTING.getKey(), true);
IndexMetadata indexMetadata = IndexMetadata.builder("test")
.settings(settings)
.numberOfShards(1)
.numberOfReplicas(0)
.state(indexMetdataState)
.build();
IndexMetadata indexMetadata = readonlyIndexMetadata("test", OLD_VERSION);
ClusterState clusterState = ClusterState.builder(ClusterState.EMPTY_STATE)
.metadata(Metadata.builder().put(indexMetadata, true))
.blocks(clusterBlocksForIndices(indexMetadata))
Expand All @@ -284,6 +282,107 @@ public void testOldIndicesIgnoredWarningCheck() {
assertEquals(List.of(expected), issuesByIndex.get("test"));
}

private IndexMetadata readonlyIndexMetadata(String indexName, IndexVersion indexVersion) {
Settings.Builder settings = settings(indexVersion).put(MetadataIndexStateService.VERIFIED_READ_ONLY_SETTING.getKey(), true);
return IndexMetadata.builder(indexName).settings(settings).numberOfShards(1).numberOfReplicas(0).state(indexMetdataState).build();
}

public void testOldTransformIndicesIgnoredCheck() {
var checker = new IndexDeprecationChecker(indexNameExpressionResolver);
var indexMetadata = readonlyIndexMetadata("test", OLD_VERSION);
var clusterState = ClusterState.builder(ClusterState.EMPTY_STATE)
.metadata(Metadata.builder().put(indexMetadata, true))
.blocks(clusterBlocksForIndices(indexMetadata))
.build();
var expected = new DeprecationIssue(
DeprecationIssue.Level.WARNING,
"One or more Transforms write to this old index with a compatibility version < 9.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-9.0.html"
+ "#breaking_90_transform_destination_index",
"Transforms [test-transform] write to this index with version ["
+ OLD_VERSION.toReleaseVersion()
+ "] and cannot be supported as read-only in 9.0",
false,
Map.of("reindex_required", true, "transform_ids", List.of("test-transform"))
);
var issuesByIndex = checker.check(
clusterState,
new DeprecationInfoAction.Request(TimeValue.THIRTY_SECONDS),
createContextWithTransformConfigs(Map.of("test", List.of("test-transform")))
);
assertEquals(singletonList(expected), issuesByIndex.get("test"));
}

public void testOldIndicesIgnoredCheckWithMultipleTransforms() {
var indexMetadata = readonlyIndexMetadata("test", OLD_VERSION);
var clusterState = ClusterState.builder(ClusterState.EMPTY_STATE)
.metadata(Metadata.builder().put(indexMetadata, true))
.blocks(clusterBlocksForIndices(indexMetadata))
.build();
var expected = new DeprecationIssue(
DeprecationIssue.Level.WARNING,
"One or more Transforms write to this old index with a compatibility version < 9.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-9.0.html"
+ "#breaking_90_transform_destination_index",
"Transforms [test-transform1, test-transform2] write to this index with version ["
+ OLD_VERSION.toReleaseVersion()
+ "] and cannot be supported as read-only in 9.0",
false,
Map.of("reindex_required", true, "transform_ids", List.of("test-transform1", "test-transform2"))
);
var issuesByIndex = checker.check(
clusterState,
new DeprecationInfoAction.Request(TimeValue.THIRTY_SECONDS),
createContextWithTransformConfigs(Map.of("test", List.of("test-transform1", "test-transform2")))
);
assertEquals(singletonList(expected), issuesByIndex.get("test"));
}

public void testMultipleOldIndicesIgnoredCheckWithTransforms() {
var indexMetadata1 = readonlyIndexMetadata("test1", OLD_VERSION);
var indexMetadata2 = readonlyIndexMetadata("test2", OLD_VERSION);
var clusterState = ClusterState.builder(ClusterState.EMPTY_STATE)
.metadata(Metadata.builder().put(indexMetadata1, true).put(indexMetadata2, true))
.blocks(clusterBlocksForIndices(indexMetadata1, indexMetadata2))
.build();
var expected = Map.of(
"test1",
List.of(
new DeprecationIssue(
DeprecationIssue.Level.WARNING,
"One or more Transforms write to this old index with a compatibility version < 9.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-9.0.html"
+ "#breaking_90_transform_destination_index",
"Transforms [test-transform1] write to this index with version ["
+ OLD_VERSION.toReleaseVersion()
+ "] and cannot be supported as read-only in 9.0",
false,
Map.of("reindex_required", true, "transform_ids", List.of("test-transform1"))
)
),
"test2",
List.of(
new DeprecationIssue(
DeprecationIssue.Level.WARNING,
"One or more Transforms write to this old index with a compatibility version < 9.0",
"https://www.elastic.co/guide/en/elasticsearch/reference/master/migrating-9.0.html"
+ "#breaking_90_transform_destination_index",
"Transforms [test-transform2] write to this index with version ["
+ OLD_VERSION.toReleaseVersion()
+ "] and cannot be supported as read-only in 9.0",
false,
Map.of("reindex_required", true, "transform_ids", List.of("test-transform2"))
)
)
);
var issuesByIndex = checker.check(
clusterState,
new DeprecationInfoAction.Request(TimeValue.THIRTY_SECONDS),
createContextWithTransformConfigs(Map.of("test1", List.of("test-transform1"), "test2", List.of("test-transform2")))
);
assertEquals(expected, issuesByIndex);
}

public void testTranslogRetentionSettings() {
Settings.Builder settings = settings(IndexVersion.current());
settings.put(IndexSettings.INDEX_TRANSLOG_RETENTION_AGE_SETTING.getKey(), randomPositiveTimeValue());
Expand Down