[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 <nknize@apache.org>
This commit is contained in:
Nick Knize 2022-04-04 14:01:04 -05:00 committed by GitHub
parent 719c92a505
commit 2d716ad9e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 21 deletions

View File

@ -279,12 +279,17 @@ public class Version implements Comparable<Version>, ToXContentFragment {
return version.id >= id; return version.id >= id;
} }
// LegacyESVersion major 7 is equivalent to Version major 1
public int compareMajor(Version other) { public int compareMajor(Version other) {
// 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 m = major == 1 ? 7 : major == 2 ? 8 : major;
int om = other.major == 1 ? 7 : other.major == 2 ? 8 : other.major; int om = other.major == 1 ? 7 : other.major == 2 ? 8 : other.major;
return Integer.compare(m, om); return Integer.compare(m, om);
} }
return Integer.compare(major, other.major);
}
@Override @Override
public int compareTo(Version other) { public int compareTo(Version other) {
@ -339,12 +344,9 @@ public class Version implements Comparable<Version>, ToXContentFragment {
} else if (major == 6) { } else if (major == 6) {
// force the minimum compatibility for version 6 to 5.6 since we don't reference version 5 anymore // force the minimum compatibility for version 6 to 5.6 since we don't reference version 5 anymore
return LegacyESVersion.fromId(5060099); return LegacyESVersion.fromId(5060099);
} } else if (major >= 3 && major < 5) {
/*
* TODO - uncomment this logic from OpenSearch version 3 onwards
*
else if (major >= 3) {
// all major versions from 3 onwards are compatible with last minor series of the previous major // 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; Version bwcVersion = null;
for (int i = DeclaredVersionsHolder.DECLARED_VERSIONS.size() - 1; i >= 0; i--) { for (int i = DeclaredVersionsHolder.DECLARED_VERSIONS.size() - 1; i >= 0; i--) {
@ -358,7 +360,6 @@ public class Version implements Comparable<Version>, ToXContentFragment {
} }
return bwcVersion == null ? this : bwcVersion; return bwcVersion == null ? this : bwcVersion;
} }
*/
return Version.min(this, fromId(maskId((int) major * 1000000 + 0 * 10000 + 99))); return Version.min(this, fromId(maskId((int) major * 1000000 + 0 * 10000 + 99)));
} }
@ -396,6 +397,10 @@ public class Version implements Comparable<Version>, ToXContentFragment {
bwcMajor = major - 1; bwcMajor = major - 1;
} }
final int bwcMinor = 0; 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))); return Version.min(this, fromId((bwcMajor * 1000000 + bwcMinor * 10000 + 99)));
} }
@ -409,16 +414,15 @@ public class Version implements Comparable<Version>, ToXContentFragment {
// OpenSearch version 2 is the functional equivalent of predecessor unreleased version "8" // OpenSearch version 2 is the functional equivalent of predecessor unreleased version "8"
// todo refactor this logic after removing deprecated features // todo refactor this logic after removing deprecated features
int a = major; int a = major;
if (major == 1) {
a = 7;
} else if (major == 2) {
a = 8;
}
int b = version.major; int b = version.major;
if (version.major == 1) {
b = 7; if (a == 7 || b == 7) {
} else if (version.major == 2) { if (major <= 2) {
b = 8; 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; assert compatible == false || Math.max(a, b) - Math.min(a, b) <= 1;

View File

@ -63,8 +63,8 @@ public class LegacyESVersionTests extends OpenSearchTestCase {
// compare opensearch version to LegacyESVersion // 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.V_7_0_0), is(0));
assertThat(Version.V_1_0_0.compareMajor(LegacyESVersion.fromString("6.3.0")), is(1)); assertThat(Version.V_2_0_0.compareMajor(LegacyESVersion.fromString("7.3.0")), is(1));
assertThat(LegacyESVersion.fromString("6.3.0").compareMajor(Version.V_1_0_0), is(-1)); assertThat(LegacyESVersion.fromString("7.3.0").compareMajor(Version.V_2_0_0), is(-1));
} }
public void testMin() { public void testMin() {

View File

@ -245,6 +245,26 @@ public class VersionTests extends OpenSearchTestCase {
assertEquals(expected.revision, actual.revision); 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<Version> 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() { public void testToString() {
assertEquals("2.0.0-beta1", Version.fromString("2.0.0-beta1").toString()); assertEquals("2.0.0-beta1", Version.fromString("2.0.0-beta1").toString());
assertEquals("5.0.0-alpha1", Version.fromId(5000001).toString()); assertEquals("5.0.0-alpha1", Version.fromId(5000001).toString());