Browse Source

Make Settings work with different version types (#97506)

This introduces a VersionId interface for objects representing an integer version of some sort. This can then be used generically in Settings (and other situations) for a generic integer version
Simon Cooper 2 years ago
parent
commit
c2d1bbb52f
29 changed files with 129 additions and 79 deletions
  1. 7 4
      server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/create/CloneIndexIT.java
  2. 7 4
      server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/create/ShrinkIndexIT.java
  3. 6 4
      server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/create/SplitIndexIT.java
  4. 1 2
      server/src/internalClusterTest/java/org/elasticsearch/cluster/ClusterStateDiffIT.java
  5. 2 2
      server/src/internalClusterTest/java/org/elasticsearch/indices/mapping/MalformedDynamicTemplateIT.java
  6. 2 1
      server/src/main/java/org/elasticsearch/TransportVersion.java
  7. 7 1
      server/src/main/java/org/elasticsearch/Version.java
  8. 4 6
      server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetadata.java
  9. 3 3
      server/src/main/java/org/elasticsearch/cluster/metadata/MetadataCreateIndexService.java
  10. 19 0
      server/src/main/java/org/elasticsearch/common/VersionId.java
  11. 13 6
      server/src/main/java/org/elasticsearch/common/settings/Setting.java
  12. 20 5
      server/src/main/java/org/elasticsearch/common/settings/Settings.java
  13. 2 1
      server/src/main/java/org/elasticsearch/index/IndexVersion.java
  14. 2 4
      server/src/main/java/org/elasticsearch/index/analysis/AnalysisRegistry.java
  15. 2 2
      server/src/test/java/org/elasticsearch/action/admin/cluster/migration/TransportGetFeatureUpgradeStatusActionTests.java
  16. 1 1
      server/src/test/java/org/elasticsearch/cluster/metadata/HumanReadableIndexSettingsTests.java
  17. 2 5
      server/src/test/java/org/elasticsearch/cluster/metadata/IndexMetadataVerifierTests.java
  18. 7 7
      server/src/test/java/org/elasticsearch/cluster/metadata/MetadataCreateIndexServiceTests.java
  19. 4 4
      server/src/test/java/org/elasticsearch/index/IndexSettingsTests.java
  20. 1 1
      server/src/test/java/org/elasticsearch/index/analysis/PreBuiltAnalyzerTests.java
  21. 2 5
      server/src/test/java/org/elasticsearch/index/engine/InternalEngineTests.java
  22. 1 1
      server/src/test/java/org/elasticsearch/index/mapper/TsidExtractingIdFieldMapperTests.java
  23. 1 1
      server/src/test/java/org/elasticsearch/index/mapper/vectors/SparseVectorFieldMapperTests.java
  24. 3 3
      server/src/test/java/org/elasticsearch/indices/analysis/AnalysisModuleTests.java
  25. 1 1
      server/src/test/java/org/elasticsearch/search/sort/AbstractSortTestCase.java
  26. 1 1
      test/framework/src/main/java/org/elasticsearch/index/mapper/MapperServiceTestCase.java
  27. 1 1
      test/framework/src/main/java/org/elasticsearch/search/geo/BaseShapeIntegTestCase.java
  28. 1 1
      test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java
  29. 6 2
      x-pack/plugin/old-lucene-versions/src/internalClusterTest/java/org/elasticsearch/xpack/lucene/bwc/AbstractArchiveTestCase.java

+ 7 - 4
server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/create/CloneIndexIT.java

@@ -7,16 +7,16 @@
  */
 package org.elasticsearch.action.admin.indices.create;
 
-import org.elasticsearch.Version;
 import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
 import org.elasticsearch.action.admin.indices.shrink.ResizeType;
 import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse;
 import org.elasticsearch.cluster.routing.allocation.decider.EnableAllocationDecider;
 import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.index.IndexVersion;
 import org.elasticsearch.index.query.TermsQueryBuilder;
 import org.elasticsearch.index.seqno.SeqNoStats;
 import org.elasticsearch.test.ESIntegTestCase;
-import org.elasticsearch.test.VersionUtils;
+import org.elasticsearch.test.index.IndexVersionUtils;
 import org.elasticsearch.xcontent.XContentType;
 
 import static org.elasticsearch.action.admin.indices.create.ShrinkIndexIT.assertNoResizeSourceIndexSettings;
@@ -32,7 +32,7 @@ public class CloneIndexIT extends ESIntegTestCase {
     }
 
     public void testCreateCloneIndex() {
-        Version version = VersionUtils.randomIndexCompatibleVersion(random());
+        IndexVersion version = IndexVersionUtils.randomCompatibleVersion(random());
         int numPrimaryShards = randomIntBetween(1, 5);
         prepareCreate("source").setSettings(
             Settings.builder().put(indexSettings()).put("number_of_shards", numPrimaryShards).put("index.version.created", version)
@@ -99,7 +99,10 @@ public class CloneIndexIT extends ESIntegTestCase {
             );
             assertHitCount(client().prepareSearch("source").setSize(size).setQuery(new TermsQueryBuilder("foo", "bar")).get(), docs);
             GetSettingsResponse target = indicesAdmin().prepareGetSettings("target").get();
-            assertEquals(version, target.getIndexToSettings().get("target").getAsVersion("index.version.created", null));
+            assertThat(
+                target.getIndexToSettings().get("target").getAsVersionId("index.version.created", IndexVersion::fromId),
+                equalTo(version)
+            );
         } finally {
             // clean up
             updateClusterSettings(

+ 7 - 4
server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/create/ShrinkIndexIT.java

@@ -13,7 +13,6 @@ import org.apache.lucene.search.SortField;
 import org.apache.lucene.search.SortedSetSelector;
 import org.apache.lucene.search.SortedSetSortField;
 import org.apache.lucene.util.Constants;
-import org.elasticsearch.Version;
 import org.elasticsearch.action.admin.cluster.reroute.ClusterRerouteResponse;
 import org.elasticsearch.action.admin.cluster.state.ClusterStateRequest;
 import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse;
@@ -42,13 +41,14 @@ import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.core.TimeValue;
 import org.elasticsearch.index.Index;
 import org.elasticsearch.index.IndexService;
+import org.elasticsearch.index.IndexVersion;
 import org.elasticsearch.index.engine.SegmentsStats;
 import org.elasticsearch.index.query.TermsQueryBuilder;
 import org.elasticsearch.index.seqno.SeqNoStats;
 import org.elasticsearch.index.shard.IndexShard;
 import org.elasticsearch.indices.IndicesService;
 import org.elasticsearch.test.ESIntegTestCase;
-import org.elasticsearch.test.VersionUtils;
+import org.elasticsearch.test.index.IndexVersionUtils;
 import org.elasticsearch.xcontent.XContentType;
 
 import java.util.Arrays;
@@ -234,7 +234,7 @@ public class ShrinkIndexIT extends ESIntegTestCase {
 
     public void testCreateShrinkIndex() {
         internalCluster().ensureAtLeastNumDataNodes(2);
-        Version version = VersionUtils.randomVersion(random());
+        IndexVersion version = IndexVersionUtils.randomVersion(random());
         prepareCreate("source").setSettings(
             Settings.builder().put(indexSettings()).put("number_of_shards", randomIntBetween(2, 7)).put("index.version.created", version)
         ).get();
@@ -327,7 +327,10 @@ public class ShrinkIndexIT extends ESIntegTestCase {
         assertHitCount(client().prepareSearch("target").setSize(2 * size).setQuery(new TermsQueryBuilder("foo", "bar")).get(), 2 * docs);
         assertHitCount(client().prepareSearch("source").setSize(size).setQuery(new TermsQueryBuilder("foo", "bar")).get(), docs);
         GetSettingsResponse target = indicesAdmin().prepareGetSettings("target").get();
-        assertEquals(version, target.getIndexToSettings().get("target").getAsVersion("index.version.created", null));
+        assertThat(
+            target.getIndexToSettings().get("target").getAsVersionId("index.version.created", IndexVersion::fromId),
+            equalTo(version)
+        );
 
         // clean up
         updateClusterSettings(

+ 6 - 4
server/src/internalClusterTest/java/org/elasticsearch/action/admin/indices/create/SplitIndexIT.java

@@ -14,7 +14,6 @@ import org.apache.lucene.search.SortedSetSelector;
 import org.apache.lucene.search.SortedSetSortField;
 import org.apache.lucene.search.join.ScoreMode;
 import org.apache.lucene.util.Constants;
-import org.elasticsearch.Version;
 import org.elasticsearch.action.admin.cluster.state.ClusterStateRequest;
 import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse;
 import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse;
@@ -45,7 +44,7 @@ import org.elasticsearch.index.seqno.SeqNoStats;
 import org.elasticsearch.index.shard.IndexShard;
 import org.elasticsearch.indices.IndicesService;
 import org.elasticsearch.test.ESIntegTestCase;
-import org.elasticsearch.test.VersionUtils;
+import org.elasticsearch.test.index.IndexVersionUtils;
 import org.elasticsearch.xcontent.XContentType;
 
 import java.io.IOException;
@@ -345,7 +344,7 @@ public class SplitIndexIT extends ESIntegTestCase {
     }
 
     public void testCreateSplitIndex() throws Exception {
-        Version version = VersionUtils.randomIndexCompatibleVersion(random());
+        IndexVersion version = IndexVersionUtils.randomCompatibleVersion(random());
         prepareCreate("source").setSettings(
             Settings.builder().put(indexSettings()).put("number_of_shards", 1).put("index.version.created", version)
         ).get();
@@ -430,7 +429,10 @@ public class SplitIndexIT extends ESIntegTestCase {
             );
             assertHitCount(client().prepareSearch("source").setSize(size).setQuery(new TermsQueryBuilder("foo", "bar")).get(), docs);
             GetSettingsResponse target = indicesAdmin().prepareGetSettings("target").get();
-            assertEquals(version, target.getIndexToSettings().get("target").getAsVersion("index.version.created", null));
+            assertThat(
+                target.getIndexToSettings().get("target").getAsVersionId("index.version.created", IndexVersion::fromId),
+                equalTo(version)
+            );
         } finally {
             // clean up
             updateClusterSettings(

+ 1 - 2
server/src/internalClusterTest/java/org/elasticsearch/cluster/ClusterStateDiffIT.java

@@ -558,8 +558,7 @@ public class ClusterStateDiffIT extends ESIntegTestCase {
                 IndexMetadata.Builder builder = IndexMetadata.builder(name);
                 Settings.Builder settingsBuilder = Settings.builder();
                 setRandomIndexSettings(random(), settingsBuilder);
-                settingsBuilder.put(randomSettings(Settings.EMPTY))
-                    .put(IndexMetadata.SETTING_VERSION_CREATED, randomVersion(random()).id());
+                settingsBuilder.put(randomSettings(Settings.EMPTY)).put(IndexMetadata.SETTING_VERSION_CREATED, randomVersion(random()));
                 builder.settings(settingsBuilder);
                 builder.numberOfShards(randomIntBetween(1, 10)).numberOfReplicas(randomInt(10));
                 int aliasCount = randomInt(10);

+ 2 - 2
server/src/internalClusterTest/java/org/elasticsearch/indices/mapping/MalformedDynamicTemplateIT.java

@@ -54,7 +54,7 @@ public class MalformedDynamicTemplateIT extends ESIntegTestCase {
                 Settings.builder()
                     .put(indexSettings())
                     .put("number_of_shards", 1)
-                    .put("index.version.created", IndexVersionUtils.randomPreviousCompatibleVersion(random(), IndexVersion.V_8_0_0).id())
+                    .put("index.version.created", IndexVersionUtils.randomPreviousCompatibleVersion(random(), IndexVersion.V_8_0_0))
             ).setMapping(mapping).get()
         );
         client().prepareIndex(indexName).setSource("{\"foo\" : \"bar\"}", XContentType.JSON).get();
@@ -64,7 +64,7 @@ public class MalformedDynamicTemplateIT extends ESIntegTestCase {
         MapperParsingException ex = expectThrows(
             MapperParsingException.class,
             () -> prepareCreate("malformed_dynamic_template_8.0").setSettings(
-                Settings.builder().put(indexSettings()).put("number_of_shards", 1).put("index.version.created", IndexVersion.current().id())
+                Settings.builder().put(indexSettings()).put("number_of_shards", 1).put("index.version.created", IndexVersion.current())
             ).setMapping(mapping).get()
         );
         assertThat(ex.getMessage(), containsString("dynamic template [my_template] has invalid content"));

+ 2 - 1
server/src/main/java/org/elasticsearch/TransportVersion.java

@@ -9,6 +9,7 @@
 package org.elasticsearch;
 
 import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.VersionId;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.core.Assertions;
@@ -63,7 +64,7 @@ import java.util.TreeMap;
  * different version value. If you need to know whether the cluster as a whole speaks a new enough {@link TransportVersion} to understand a
  * newly-added feature, use {@link org.elasticsearch.cluster.ClusterState#getMinTransportVersion}.
  */
-public record TransportVersion(int id) implements Comparable<TransportVersion> {
+public record TransportVersion(int id) implements VersionId, Comparable<TransportVersion> {
 
     /*
      * NOTE: IntelliJ lies!

+ 7 - 1
server/src/main/java/org/elasticsearch/Version.java

@@ -9,6 +9,7 @@
 package org.elasticsearch;
 
 import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.VersionId;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.core.Assertions;
@@ -32,7 +33,7 @@ import java.util.NavigableMap;
 import java.util.Objects;
 import java.util.TreeMap;
 
-public class Version implements Comparable<Version>, ToXContentFragment {
+public class Version implements VersionId, Comparable<Version>, ToXContentFragment {
     /*
      * The logic for ID is: XXYYZZAA, where XX is major version, YY is minor version, ZZ is revision, and AA is alpha/beta/rc indicator AA
      * values below 25 are for alpha builder (since 5.0), and above 25 and below 50 are beta builds, and below 99 are RC builds, with 99
@@ -311,6 +312,11 @@ public class Version implements Comparable<Version>, ToXContentFragment {
         this.previousMajorId = major > 0 ? (major - 1) * 1000000 + 99 : major;
     }
 
+    @Override
+    public int id() {
+        return id;
+    }
+
     public boolean after(Version version) {
         return version.id < id;
     }

+ 4 - 6
server/src/main/java/org/elasticsearch/cluster/metadata/IndexMetadata.java

@@ -339,10 +339,10 @@ public class IndexMetadata implements Diffable<IndexMetadata>, ToXContentFragmen
 
     public static final String SETTING_VERSION_CREATED = "index.version.created";
 
-    public static final Setting<IndexVersion> SETTING_INDEX_VERSION_CREATED = new Setting<>(
+    public static final Setting<IndexVersion> SETTING_INDEX_VERSION_CREATED = Setting.versionIdSetting(
         SETTING_VERSION_CREATED,
-        Integer.toString(IndexVersion.ZERO.id()),
-        s -> IndexVersion.fromId(Integer.parseInt(s)),
+        IndexVersion.ZERO,
+        IndexVersion::fromId,
         Property.IndexScope,
         Property.PrivateIndex
     );
@@ -364,12 +364,10 @@ public class IndexMetadata implements Diffable<IndexMetadata>, ToXContentFragmen
     /**
      * See {@link #getCompatibilityVersion()}
      */
-    public static final Setting<IndexVersion> SETTING_INDEX_VERSION_COMPATIBILITY = new Setting<>(
+    public static final Setting<IndexVersion> SETTING_INDEX_VERSION_COMPATIBILITY = Setting.versionIdSetting(
         SETTING_VERSION_COMPATIBILITY,
         SETTING_INDEX_VERSION_CREATED, // fall back to index.version.created
-        s -> IndexVersion.fromId(Integer.parseInt(s)),
         new Setting.Validator<>() {
-
             @Override
             public void validate(final IndexVersion compatibilityVersion) {
 

+ 3 - 3
server/src/main/java/org/elasticsearch/cluster/metadata/MetadataCreateIndexService.java

@@ -1043,7 +1043,7 @@ public class MetadataCreateIndexService {
         if (indexSettingsBuilder.get(IndexMetadata.SETTING_VERSION_CREATED) == null) {
             DiscoveryNodes nodes = currentState.nodes();
             IndexVersion createdVersion = IndexVersion.min(IndexVersion.current(), nodes.getMaxDataNodeCompatibleIndexVersion());
-            indexSettingsBuilder.put(IndexMetadata.SETTING_VERSION_CREATED, createdVersion.id());
+            indexSettingsBuilder.put(IndexMetadata.SETTING_VERSION_CREATED, createdVersion);
         }
         if (INDEX_NUMBER_OF_SHARDS_SETTING.exists(indexSettingsBuilder) == false) {
             indexSettingsBuilder.put(SETTING_NUMBER_OF_SHARDS, INDEX_NUMBER_OF_SHARDS_SETTING.get(settings));
@@ -1574,13 +1574,13 @@ public class MetadataCreateIndexService {
             builder.put(sourceMetadata.getSettings().filter(sourceSettingsPredicate));
         }
 
-        indexSettingsBuilder.put(IndexMetadata.SETTING_VERSION_CREATED, sourceMetadata.getCreationVersion().id())
+        indexSettingsBuilder.put(IndexMetadata.SETTING_VERSION_CREATED, sourceMetadata.getCreationVersion())
             .put(builder.build())
             .put(IndexMetadata.SETTING_ROUTING_PARTITION_SIZE, sourceMetadata.getRoutingPartitionSize())
             .put(IndexMetadata.INDEX_RESIZE_SOURCE_NAME.getKey(), resizeSourceIndex.getName())
             .put(IndexMetadata.INDEX_RESIZE_SOURCE_UUID.getKey(), resizeSourceIndex.getUUID());
         if (sourceMetadata.getSettings().hasValue(IndexMetadata.SETTING_VERSION_COMPATIBILITY)) {
-            indexSettingsBuilder.put(IndexMetadata.SETTING_VERSION_COMPATIBILITY, sourceMetadata.getCompatibilityVersion().id());
+            indexSettingsBuilder.put(IndexMetadata.SETTING_VERSION_COMPATIBILITY, sourceMetadata.getCompatibilityVersion());
         }
     }
 

+ 19 - 0
server/src/main/java/org/elasticsearch/common/VersionId.java

@@ -0,0 +1,19 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+package org.elasticsearch.common;
+
+/**
+ * Indicates a class that represents a version id of some kind
+ */
+public interface VersionId {
+    /**
+     * The version id this object represents
+     */
+    int id();
+}

+ 13 - 6
server/src/main/java/org/elasticsearch/common/settings/Setting.java

@@ -13,6 +13,7 @@ import org.elasticsearch.ElasticsearchException;
 import org.elasticsearch.ElasticsearchParseException;
 import org.elasticsearch.Version;
 import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.VersionId;
 import org.elasticsearch.common.logging.DeprecationCategory;
 import org.elasticsearch.common.regex.Regex;
 import org.elasticsearch.common.unit.ByteSizeValue;
@@ -47,6 +48,7 @@ import java.util.function.BiConsumer;
 import java.util.function.BiFunction;
 import java.util.function.Consumer;
 import java.util.function.Function;
+import java.util.function.IntFunction;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
@@ -1283,17 +1285,22 @@ public class Setting<T> implements ToXContentObject {
         }
     }
 
-    public static Setting<Version> versionSetting(final String key, final Version defaultValue, Property... properties) {
-        return new Setting<>(key, Integer.toString(defaultValue.id), s -> Version.fromId(Integer.parseInt(s)), properties);
+    public static <T extends VersionId> Setting<T> versionIdSetting(
+        String key,
+        T defaultValue,
+        IntFunction<T> parseVersion,
+        Property... properties
+    ) {
+        return new Setting<>(key, Integer.toString(defaultValue.id()), s -> parseVersion.apply(Integer.parseInt(s)), properties);
     }
 
-    public static Setting<Version> versionSetting(
+    public static <T extends VersionId> Setting<T> versionIdSetting(
         final String key,
-        Setting<Version> fallbackSetting,
-        Validator<Version> validator,
+        Setting<T> fallbackSetting,
+        Validator<T> validator,
         Property... properties
     ) {
-        return new Setting<>(key, fallbackSetting, s -> Version.fromId(Integer.parseInt(s)), validator, properties);
+        return new Setting<>(key, fallbackSetting, fallbackSetting.parser, validator, properties);
     }
 
     public static Setting<Float> floatSetting(String key, float defaultValue, Property... properties) {

+ 20 - 5
server/src/main/java/org/elasticsearch/common/settings/Settings.java

@@ -12,12 +12,12 @@ import org.apache.logging.log4j.Level;
 import org.apache.lucene.util.SetOnce;
 import org.elasticsearch.ElasticsearchGenerationException;
 import org.elasticsearch.ElasticsearchParseException;
-import org.elasticsearch.Version;
 import org.elasticsearch.cluster.Diff;
 import org.elasticsearch.cluster.Diffable;
 import org.elasticsearch.cluster.DiffableUtils;
 import org.elasticsearch.common.Numbers;
 import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.VersionId;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.common.io.stream.Writeable;
@@ -63,6 +63,7 @@ import java.util.Set;
 import java.util.TreeMap;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Function;
+import java.util.function.IntFunction;
 import java.util.function.Predicate;
 import java.util.function.UnaryOperator;
 import java.util.stream.Collectors;
@@ -522,13 +523,20 @@ public final class Settings implements ToXContentFragment, Writeable, Diffable<S
     /**
      * Returns a parsed version.
      */
-    public Version getAsVersion(String setting, Version defaultVersion) throws SettingsException {
+    public <T extends VersionId> T getAsVersionId(String setting, IntFunction<T> parseVersion) throws SettingsException {
+        return getAsVersionId(setting, parseVersion, null);
+    }
+
+    /**
+     * Returns a parsed version.
+     */
+    public <T extends VersionId> T getAsVersionId(String setting, IntFunction<T> parseVersion, T defaultVersion) throws SettingsException {
         String sValue = get(setting);
         if (sValue == null) {
             return defaultVersion;
         }
         try {
-            return Version.fromId(Integer.parseInt(sValue));
+            return parseVersion.apply(Integer.parseInt(sValue));
         } catch (Exception e) {
             throw new SettingsException("Failed to parse version setting [" + setting + "] with value [" + sValue + "]", e);
         }
@@ -1028,8 +1036,15 @@ public final class Settings implements ToXContentFragment, Writeable, Diffable<S
             return this;
         }
 
-        public Builder put(String setting, Version version) {
-            put(setting, version.id);
+        /**
+         * Sets the setting with the provided setting key and the {@code VersionId} value.
+         *
+         * @param setting The setting key
+         * @param version The version value
+         * @return The builder
+         */
+        public Builder put(String setting, VersionId version) {
+            put(setting, version.id());
             return this;
         }
 

+ 2 - 1
server/src/main/java/org/elasticsearch/index/IndexVersion.java

@@ -10,6 +10,7 @@ package org.elasticsearch.index;
 
 import org.apache.lucene.util.Version;
 import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.VersionId;
 import org.elasticsearch.common.io.stream.StreamInput;
 import org.elasticsearch.common.io.stream.StreamOutput;
 import org.elasticsearch.core.Assertions;
@@ -61,7 +62,7 @@ import java.util.TreeMap;
  * representing the reverted change. <em>Do not</em> let the index version go backwards, it must <em>always</em> be incremented.
  */
 @SuppressWarnings({"checkstyle:linelength", "deprecation"})
-public record IndexVersion(int id, Version luceneVersion) implements Comparable<IndexVersion>, ToXContentFragment {
+public record IndexVersion(int id, Version luceneVersion) implements VersionId, Comparable<IndexVersion>, ToXContentFragment {
 
     /*
      * NOTE: IntelliJ lies!

+ 2 - 4
server/src/main/java/org/elasticsearch/index/analysis/AnalysisRegistry.java

@@ -93,7 +93,7 @@ public final class AnalysisRegistry implements Closeable {
     private static Settings getSettingsFromIndexSettings(IndexSettings indexSettings, String groupName) {
         Settings settings = indexSettings.getSettings().getAsSettings(groupName);
         if (settings.isEmpty()) {
-            settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, indexSettings.getIndexVersionCreated().id()).build();
+            settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, indexSettings.getIndexVersionCreated()).build();
         }
         return settings;
     }
@@ -463,9 +463,7 @@ public final class AnalysisRegistry implements Closeable {
         Map<String, ? extends AnalysisModule.AnalysisProvider<T>> providerMap,
         Map<String, ? extends AnalysisModule.AnalysisProvider<T>> defaultInstance
     ) throws IOException {
-        Settings defaultSettings = Settings.builder()
-            .put(IndexMetadata.SETTING_VERSION_CREATED, settings.getIndexVersionCreated().id())
-            .build();
+        Settings defaultSettings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, settings.getIndexVersionCreated()).build();
         Map<String, T> factories = new HashMap<>();
         for (Map.Entry<String, Settings> entry : settingsMap.entrySet()) {
             String name = entry.getKey();

+ 2 - 2
server/src/test/java/org/elasticsearch/action/admin/cluster/migration/TransportGetFeatureUpgradeStatusActionTests.java

@@ -79,7 +79,7 @@ public class TransportGetFeatureUpgradeStatusActionTests extends ESTestCase {
 
     private static ClusterState getClusterState() {
         IndexMetadata indexMetadata1 = IndexMetadata.builder(".test-index-1")
-            .settings(Settings.builder().put("index.version.created", IndexVersion.current().id()).build())
+            .settings(Settings.builder().put("index.version.created", IndexVersion.current()).build())
             .numberOfShards(1)
             .numberOfReplicas(0)
             .build();
@@ -88,7 +88,7 @@ public class TransportGetFeatureUpgradeStatusActionTests extends ESTestCase {
         assert Version.CURRENT.major < 9;
 
         IndexMetadata indexMetadata2 = IndexMetadata.builder(".test-index-2")
-            .settings(Settings.builder().put("index.version.created", TEST_OLD_VERSION.id()).build())
+            .settings(Settings.builder().put("index.version.created", TEST_OLD_VERSION).build())
             .numberOfShards(1)
             .numberOfReplicas(0)
             .build();

+ 1 - 1
server/src/test/java/org/elasticsearch/cluster/metadata/HumanReadableIndexSettingsTests.java

@@ -24,7 +24,7 @@ public class HumanReadableIndexSettingsTests extends ESTestCase {
         IndexVersion versionCreated = randomVersion(random());
         long created = System.currentTimeMillis();
         Settings testSettings = Settings.builder()
-            .put(IndexMetadata.SETTING_VERSION_CREATED, versionCreated.id())
+            .put(IndexMetadata.SETTING_VERSION_CREATED, versionCreated)
             .put(IndexMetadata.SETTING_CREATION_DATE, created)
             .build();
 

+ 2 - 5
server/src/test/java/org/elasticsearch/cluster/metadata/IndexMetadataVerifierTests.java

@@ -103,7 +103,7 @@ public class IndexMetadataVerifierTests extends ESTestCase {
         IndexVersion indexCreated = IndexVersion.fromId(randomIntBetween(1000099, minCompat.id() - 1));
         final IndexMetadata metadata = newIndexMeta(
             "foo",
-            Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, indexCreated.id()).build()
+            Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, indexCreated).build()
         );
         String message = expectThrows(
             IllegalStateException.class,
@@ -129,10 +129,7 @@ public class IndexMetadataVerifierTests extends ESTestCase {
         );
 
         indexCreated = IndexVersionUtils.randomVersionBetween(random(), minCompat, IndexVersion.current());
-        IndexMetadata goodMeta = newIndexMeta(
-            "foo",
-            Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, indexCreated.id()).build()
-        );
+        IndexMetadata goodMeta = newIndexMeta("foo", Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, indexCreated).build());
         service.verifyIndexMetadata(goodMeta, IndexVersion.MINIMUM_COMPATIBLE);
     }
 

+ 7 - 7
server/src/test/java/org/elasticsearch/cluster/metadata/MetadataCreateIndexServiceTests.java

@@ -72,7 +72,6 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -375,10 +374,11 @@ public class MetadataCreateIndexServiceTests extends ESTestCase {
     }
 
     public void testPrepareResizeIndexSettings() {
-        final List<Version> versions = Arrays.asList(VersionUtils.randomVersion(random()), VersionUtils.randomVersion(random()));
-        versions.sort(Comparator.comparingLong(l -> l.id));
-        final Version version = versions.get(0);
-        final Version upgraded = versions.get(1);
+        final List<IndexVersion> versions = Stream.of(IndexVersionUtils.randomVersion(random()), IndexVersionUtils.randomVersion(random()))
+            .sorted()
+            .toList();
+        final IndexVersion version = versions.get(0);
+        final IndexVersion upgraded = versions.get(1);
         final Settings.Builder indexSettingsBuilder = Settings.builder()
             .put("index.version.created", version)
             .put("index.similarity.default.type", "BM25")
@@ -401,7 +401,7 @@ public class MetadataCreateIndexServiceTests extends ESTestCase {
                 );
                 assertThat(settings.get("index.routing.allocation.initial_recovery._id"), equalTo("node1"));
                 assertThat(settings.get("index.allocation.max_retries"), nullValue());
-                assertThat(settings.getAsVersion("index.version.created", null), equalTo(version));
+                assertThat(settings.getAsVersionId("index.version.created", IndexVersion::fromId), equalTo(version));
                 assertThat(settings.get("index.soft_deletes.enabled"), equalTo("true"));
             }
         );
@@ -1299,7 +1299,7 @@ public class MetadataCreateIndexServiceTests extends ESTestCase {
         } else {
             settings.put(IndexSettings.INDEX_TRANSLOG_RETENTION_SIZE_SETTING.getKey(), between(1, 128) + "mb");
         }
-        settings.put(SETTING_VERSION_CREATED, IndexVersionUtils.randomPreviousCompatibleVersion(random(), IndexVersion.V_8_0_0).id());
+        settings.put(SETTING_VERSION_CREATED, IndexVersionUtils.randomPreviousCompatibleVersion(random(), IndexVersion.V_8_0_0));
         request.settings(settings.build());
         aggregateIndexSettings(
             ClusterState.EMPTY_STATE,

+ 4 - 4
server/src/test/java/org/elasticsearch/index/IndexSettingsTests.java

@@ -50,7 +50,7 @@ public class IndexSettingsTests extends ESTestCase {
     public void testRunListener() {
         IndexVersion version = IndexVersionUtils.getPreviousVersion();
         Settings theSettings = Settings.builder()
-            .put(IndexMetadata.SETTING_VERSION_CREATED, version.id())
+            .put(IndexMetadata.SETTING_VERSION_CREATED, version)
             .put(IndexMetadata.SETTING_INDEX_UUID, "0xdeadbeef")
             .build();
         final AtomicInteger integer = new AtomicInteger(0);
@@ -76,7 +76,7 @@ public class IndexSettingsTests extends ESTestCase {
     public void testSettingsUpdateValidator() {
         IndexVersion version = IndexVersionUtils.getPreviousVersion();
         Settings theSettings = Settings.builder()
-            .put(IndexMetadata.SETTING_VERSION_CREATED, version.id())
+            .put(IndexMetadata.SETTING_VERSION_CREATED, version)
             .put(IndexMetadata.SETTING_INDEX_UUID, "0xdeadbeef")
             .build();
         final AtomicInteger integer = new AtomicInteger(0);
@@ -147,7 +147,7 @@ public class IndexSettingsTests extends ESTestCase {
 
     public void testSettingsConsistency() {
         IndexVersion version = IndexVersionUtils.getPreviousVersion();
-        IndexMetadata metadata = newIndexMeta("index", Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version.id()).build());
+        IndexMetadata metadata = newIndexMeta("index", Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version).build());
         IndexSettings settings = new IndexSettings(metadata, Settings.EMPTY);
         assertEquals(version, settings.getIndexVersionCreated());
         assertEquals("_na_", settings.getUUID());
@@ -169,7 +169,7 @@ public class IndexSettingsTests extends ESTestCase {
                     "index",
                     Settings.builder()
                         .put(IndexMetadata.SETTING_VERSION_CREATED, version.id())
-                        .put(IndexMetadata.SETTING_VERSION_COMPATIBILITY, IndexVersion.current().id())
+                        .put(IndexMetadata.SETTING_VERSION_COMPATIBILITY, IndexVersion.current())
                         .put("index.test.setting.int", 42)
                         .build()
                 )

+ 1 - 1
server/src/test/java/org/elasticsearch/index/analysis/PreBuiltAnalyzerTests.java

@@ -78,7 +78,7 @@ public class PreBuiltAnalyzerTests extends ESSingleNodeTestCase {
         String analyzerName = randomPreBuiltAnalyzer.name().toLowerCase(Locale.ROOT);
 
         IndexVersion randomVersion = IndexVersionUtils.randomVersion(random());
-        Settings indexSettings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, randomVersion.id()).build();
+        Settings indexSettings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, randomVersion).build();
 
         NamedAnalyzer namedAnalyzer = new PreBuiltAnalyzerProvider(
             analyzerName,

+ 2 - 5
server/src/test/java/org/elasticsearch/index/engine/InternalEngineTests.java

@@ -6698,7 +6698,7 @@ public class InternalEngineTests extends EngineTestCase {
                     .put(defaultSettings.getSettings())
                     .put(
                         IndexMetadata.SETTING_VERSION_CREATED,
-                        IndexVersionUtils.randomPreviousCompatibleVersion(random(), IndexVersion.V_8_0_0).id()
+                        IndexVersionUtils.randomPreviousCompatibleVersion(random(), IndexVersion.V_8_0_0)
                     )
                     .put(IndexSettings.INDEX_SOFT_DELETES_SETTING.getKey(), false)
             )
@@ -6790,10 +6790,7 @@ public class InternalEngineTests extends EngineTestCase {
             lowestCompatiblePreviousVersion,
             IndexVersionUtils.getFirstVersion()
         )) {
-            Settings settings = Settings.builder()
-                .put(indexSettings())
-                .put(IndexMetadata.SETTING_VERSION_CREATED, createdVersion.id())
-                .build();
+            Settings settings = Settings.builder().put(indexSettings()).put(IndexMetadata.SETTING_VERSION_CREATED, createdVersion).build();
             IndexSettings indexSettings = IndexSettingsModule.newIndexSettings("test", settings);
             try (
                 Store store = createStore(indexSettings, newDirectory());

+ 1 - 1
server/src/test/java/org/elasticsearch/index/mapper/TsidExtractingIdFieldMapperTests.java

@@ -539,7 +539,7 @@ public class TsidExtractingIdFieldMapperTests extends MetadataMapperTestCase {
     private Settings indexSettings(IndexVersion version) {
         return Settings.builder()
             .put(IndexSettings.MODE.getKey(), "time_series")
-            .put(IndexMetadata.SETTING_VERSION_CREATED, version.id())
+            .put(IndexMetadata.SETTING_VERSION_CREATED, version)
             .put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, between(1, 100))
             .put(IndexSettings.TIME_SERIES_START_TIME.getKey(), "-9999-01-01T00:00:00Z")
             .put(IndexSettings.TIME_SERIES_END_TIME.getKey(), "9999-01-01T00:00:00Z")

+ 1 - 1
server/src/test/java/org/elasticsearch/index/mapper/vectors/SparseVectorFieldMapperTests.java

@@ -74,7 +74,7 @@ public class SparseVectorFieldMapperTests extends ESSingleNodeTestCase {
 
     public void testSparseVectorWith7xIndex() throws Exception {
         IndexVersion version = IndexVersionUtils.randomPreviousCompatibleVersion(random(), IndexVersion.V_8_0_0);
-        Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version.id()).build();
+        Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version).build();
 
         IndexService indexService = createIndex("index", settings);
         MapperService mapperService = indexService.mapperService();

+ 3 - 3
server/src/test/java/org/elasticsearch/indices/analysis/AnalysisModuleTests.java

@@ -273,7 +273,7 @@ public class AnalysisModuleTests extends ESTestCase {
                 .put("index.analysis.analyzer.lucene_version.char_filter", "lucene_version")
                 .put("index.analysis.analyzer.index_version.tokenizer", "keyword")
                 .put("index.analysis.analyzer.index_version.char_filter", "index_version")
-                .put(IndexMetadata.SETTING_VERSION_CREATED, version.id())
+                .put(IndexMetadata.SETTING_VERSION_CREATED, version)
                 .build()
         );
         assertTokenStreamContents(analyzers.get("no_version").tokenStream("", "test"), new String[] { "testno_version" });
@@ -342,7 +342,7 @@ public class AnalysisModuleTests extends ESTestCase {
                 .put("index.analysis.analyzer.lucene_version.filter", "lucene_version")
                 .put("index.analysis.analyzer.index_version.tokenizer", "standard")
                 .put("index.analysis.analyzer.index_version.filter", "index_version")
-                .put(IndexMetadata.SETTING_VERSION_CREATED, version.id())
+                .put(IndexMetadata.SETTING_VERSION_CREATED, version)
                 .build()
         );
         assertTokenStreamContents(analyzers.get("no_version").tokenStream("", "test"), new String[] { "testno_version" });
@@ -426,7 +426,7 @@ public class AnalysisModuleTests extends ESTestCase {
                 .put("index.analysis.analyzer.no_version.tokenizer", "no_version")
                 .put("index.analysis.analyzer.lucene_version.tokenizer", "lucene_version")
                 .put("index.analysis.analyzer.index_version.tokenizer", "index_version")
-                .put(IndexMetadata.SETTING_VERSION_CREATED, version.id())
+                .put(IndexMetadata.SETTING_VERSION_CREATED, version)
                 .build()
         );
         assertTokenStreamContents(analyzers.get("no_version").tokenStream("", "test"), new String[] { "no_version" });

+ 1 - 1
server/src/test/java/org/elasticsearch/search/sort/AbstractSortTestCase.java

@@ -187,7 +187,7 @@ public abstract class AbstractSortTestCase<T extends SortBuilder<T>> extends EST
         Index index = new Index(randomAlphaOfLengthBetween(1, 10), "_na_");
         IndexSettings idxSettings = IndexSettingsModule.newIndexSettings(
             index,
-            Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersion.current().id()).build()
+            Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, IndexVersion.current()).build()
         );
         BitsetFilterCache bitsetFilterCache = new BitsetFilterCache(idxSettings, mock(BitsetFilterCache.Listener.class));
         BiFunction<MappedFieldType, FieldDataContext, IndexFieldData<?>> indexFieldDataLookup = (fieldType, fdc) -> {

+ 1 - 1
test/framework/src/main/java/org/elasticsearch/index/mapper/MapperServiceTestCase.java

@@ -228,7 +228,7 @@ public abstract class MapperServiceTestCase extends ESTestCase {
     }
 
     protected static IndexSettings createIndexSettings(IndexVersion version, Settings settings) {
-        settings = indexSettings(1, 0).put(settings).put("index.version.created", version.id()).build();
+        settings = indexSettings(1, 0).put(settings).put("index.version.created", version).build();
         IndexMetadata meta = IndexMetadata.builder("index").settings(settings).build();
         return new IndexSettings(meta, settings);
     }

+ 1 - 1
test/framework/src/main/java/org/elasticsearch/search/geo/BaseShapeIntegTestCase.java

@@ -424,7 +424,7 @@ public abstract class BaseShapeIntegTestCase<T extends AbstractGeometryQueryBuil
     public void testBulk() throws Exception {
         byte[] bulkAction = unZipData("/org/elasticsearch/search/geo/gzippedmap.gz");
         IndexVersion version = randomSupportedVersion();
-        Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version.id()).build();
+        Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version).build();
         XContentBuilder xContentBuilder = XContentFactory.jsonBuilder()
             .startObject()
             .startObject("_doc")

+ 1 - 1
test/framework/src/main/java/org/elasticsearch/test/ESTestCase.java

@@ -1301,7 +1301,7 @@ public abstract class ESTestCase extends LuceneTestCase {
 
     /** Return consistent index settings for the provided index version. */
     public static Settings.Builder settings(IndexVersion version) {
-        return Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version.id());
+        return Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, version);
     }
 
     /** Return consistent index settings for the provided index version, shard- and replica-count. */

+ 6 - 2
x-pack/plugin/old-lucene-versions/src/internalClusterTest/java/org/elasticsearch/xpack/lucene/bwc/AbstractArchiveTestCase.java

@@ -7,13 +7,13 @@
 
 package org.elasticsearch.xpack.lucene.bwc;
 
-import org.elasticsearch.Version;
 import org.elasticsearch.cluster.metadata.IndexMetadata;
 import org.elasticsearch.cluster.metadata.RepositoryMetadata;
 import org.elasticsearch.cluster.service.ClusterService;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.util.BigArrays;
 import org.elasticsearch.env.Environment;
+import org.elasticsearch.index.IndexVersion;
 import org.elasticsearch.indices.recovery.RecoverySettings;
 import org.elasticsearch.license.License;
 import org.elasticsearch.license.PostStartTrialAction;
@@ -92,7 +92,11 @@ public abstract class AbstractArchiveTestCase extends AbstractSnapshotIntegTestC
                             .put(
                                 IndexMetadata.SETTING_INDEX_VERSION_CREATED.getKey(),
                                 metadata.settings()
-                                    .getAsVersion("version", randomBoolean() ? Version.fromString("5.0.0") : Version.fromString("6.0.0"))
+                                    .getAsVersionId(
+                                        "version",
+                                        IndexVersion::fromId,
+                                        IndexVersion.fromId(randomBoolean() ? 5000099 : 6000099)
+                                    )
                             )
                     )
                     .build();