From 2d716ad9e2cd997eaa1ad8273cbf91a0691deb6d Mon Sep 17 00:00:00 2001 From: Nick Knize Date: Mon, 4 Apr 2022 14:01:04 -0500 Subject: [PATCH] [Version] Don't spoof major for 3.0+ clusters (#2722) Changes version comparison logic to only translate major version when comparing with legacy 7x versions. This is needed beginning in 2.0 so that when running 2.0+ versions in bwc mode for 3.0+ upgrades, node versions no longer have to translate major version or spoof to legacy versions. Signed-off-by: Nicholas Walter Knize --- .../src/main/java/org/opensearch/Version.java | 42 ++++++++++--------- .../org/opensearch/LegacyESVersionTests.java | 4 +- .../java/org/opensearch/VersionTests.java | 20 +++++++++ 3 files changed, 45 insertions(+), 21 deletions(-) diff --git a/server/src/main/java/org/opensearch/Version.java b/server/src/main/java/org/opensearch/Version.java index cd0bf7b8d8174..7ccf4449436cd 100644 --- a/server/src/main/java/org/opensearch/Version.java +++ b/server/src/main/java/org/opensearch/Version.java @@ -279,11 +279,16 @@ public boolean onOrBefore(Version version) { return version.id >= id; } - // LegacyESVersion major 7 is equivalent to Version major 1 public int compareMajor(Version other) { - int m = major == 1 ? 7 : major == 2 ? 8 : major; - int om = other.major == 1 ? 7 : other.major == 2 ? 8 : other.major; - return Integer.compare(m, om); + // comparing Legacy 7x for bwc + // todo: remove the following when removing legacy support in 3.0.0 + if (major == 7 || other.major == 7) { + // opensearch v1.x and v2.x need major translation to compare w/ legacy versions + int m = major == 1 ? 7 : major == 2 ? 8 : major; + int om = other.major == 1 ? 7 : other.major == 2 ? 8 : other.major; + return Integer.compare(m, om); + } + return Integer.compare(major, other.major); } @Override @@ -339,12 +344,9 @@ protected Version computeMinCompatVersion() { } else if (major == 6) { // force the minimum compatibility for version 6 to 5.6 since we don't reference version 5 anymore return LegacyESVersion.fromId(5060099); - } - /* - * TODO - uncomment this logic from OpenSearch version 3 onwards - * - else if (major >= 3) { + } else if (major >= 3 && major < 5) { // all major versions from 3 onwards are compatible with last minor series of the previous major + // todo: remove 5 check when removing LegacyESVersionTests Version bwcVersion = null; for (int i = DeclaredVersionsHolder.DECLARED_VERSIONS.size() - 1; i >= 0; i--) { @@ -358,7 +360,6 @@ else if (major >= 3) { } return bwcVersion == null ? this : bwcVersion; } - */ return Version.min(this, fromId(maskId((int) major * 1000000 + 0 * 10000 + 99))); } @@ -396,6 +397,10 @@ private Version computeMinIndexCompatVersion() { bwcMajor = major - 1; } final int bwcMinor = 0; + if (major == 3) { + return Version.min(this, fromId((bwcMajor * 1000000 + bwcMinor * 10000 + 99) ^ MASK)); + } + // todo remove below when LegacyESVersion is removed in 3.0 return Version.min(this, fromId((bwcMajor * 1000000 + bwcMinor * 10000 + 99))); } @@ -409,16 +414,15 @@ public boolean isCompatible(Version version) { // OpenSearch version 2 is the functional equivalent of predecessor unreleased version "8" // todo refactor this logic after removing deprecated features int a = major; - if (major == 1) { - a = 7; - } else if (major == 2) { - a = 8; - } int b = version.major; - if (version.major == 1) { - b = 7; - } else if (version.major == 2) { - b = 8; + + if (a == 7 || b == 7) { + if (major <= 2) { + a += 6; // for legacy compatibility up to version 2.x (to compare minCompat) + } + if (version.major <= 2) { + b += 6; // for legacy compatibility up to version 2.x (to compare minCompat) + } } assert compatible == false || Math.max(a, b) - Math.min(a, b) <= 1; diff --git a/server/src/test/java/org/opensearch/LegacyESVersionTests.java b/server/src/test/java/org/opensearch/LegacyESVersionTests.java index 8fb3636dd8b2c..d59f5e38a4ed7 100644 --- a/server/src/test/java/org/opensearch/LegacyESVersionTests.java +++ b/server/src/test/java/org/opensearch/LegacyESVersionTests.java @@ -63,8 +63,8 @@ public void testVersionComparison() { // compare opensearch version to LegacyESVersion assertThat(Version.V_1_0_0.compareMajor(LegacyESVersion.V_7_0_0), is(0)); - assertThat(Version.V_1_0_0.compareMajor(LegacyESVersion.fromString("6.3.0")), is(1)); - assertThat(LegacyESVersion.fromString("6.3.0").compareMajor(Version.V_1_0_0), is(-1)); + assertThat(Version.V_2_0_0.compareMajor(LegacyESVersion.fromString("7.3.0")), is(1)); + assertThat(LegacyESVersion.fromString("7.3.0").compareMajor(Version.V_2_0_0), is(-1)); } public void testMin() { diff --git a/server/src/test/java/org/opensearch/VersionTests.java b/server/src/test/java/org/opensearch/VersionTests.java index beff71eceab0d..c2566e83dd9b6 100644 --- a/server/src/test/java/org/opensearch/VersionTests.java +++ b/server/src/test/java/org/opensearch/VersionTests.java @@ -245,6 +245,26 @@ public void testOpenSearchMinIndexCompatVersion() { assertEquals(expected.revision, actual.revision); } + /** test first version of opensearch compatibility that does not support legacy versions */ + public void testOpenSearchPreLegacyRemoval() { + Version opensearchVersion = Version.fromString("3.0.0"); + int opensearchMajor = opensearchVersion.major; + List candidates = VersionUtils.allOpenSearchVersions(); + Version expectedMinIndexCompat = VersionUtils.getFirstVersionOfMajor(candidates, opensearchMajor - 1); + Version actualMinIndexCompat = opensearchVersion.minimumIndexCompatibilityVersion(); + + Version expectedMinCompat = VersionUtils.lastFirstReleasedMinorFromMajor(VersionUtils.allOpenSearchVersions(), opensearchMajor - 1); + Version actualMinCompat = opensearchVersion.minimumCompatibilityVersion(); + // since some legacy versions still support build (alpha, beta, RC) we check major minor revision only + assertEquals(expectedMinIndexCompat.major, actualMinIndexCompat.major); + assertEquals(expectedMinIndexCompat.minor, actualMinIndexCompat.minor); + assertEquals(expectedMinIndexCompat.revision, actualMinIndexCompat.revision); + + assertEquals(expectedMinCompat.major, actualMinCompat.major); + assertEquals(expectedMinCompat.minor, actualMinCompat.minor); + assertEquals(expectedMinCompat.revision, actualMinCompat.revision); + } + public void testToString() { assertEquals("2.0.0-beta1", Version.fromString("2.0.0-beta1").toString()); assertEquals("5.0.0-alpha1", Version.fromId(5000001).toString());