diff --git a/common/src/main/java/com/tc/util/version/DefaultVersionCompatibility.java b/common/src/main/java/com/tc/util/version/DefaultVersionCompatibility.java index c144c5a055..026e47b1f0 100644 --- a/common/src/main/java/com/tc/util/version/DefaultVersionCompatibility.java +++ b/common/src/main/java/com/tc/util/version/DefaultVersionCompatibility.java @@ -27,42 +27,16 @@ public class DefaultVersionCompatibility implements VersionCompatibility { @Override public boolean isCompatibleClientServer(String clientVersion, String serverVersion) { - return isCompatibleClientServer(new Version(clientVersion), new Version(serverVersion)); + return true; } @Override public boolean isCompatibleServerServer(String v1, String v2) { - return isCompatibleServerServer(new Version(v1), new Version(v2)); + return true; } @Override public boolean isCompatibleServerPersistence(String persisted, String current) { - return isCompatibleServerServer(new Version(persisted), new Version(current)); - } - - private boolean isCompatibleClientServer(Version clientVersion, Version serverVersion) { - return isCompatible(clientVersion, serverVersion) && !clientVersion.isNewer(serverVersion, 3); - } - - private boolean isCompatibleServerServer(Version v1, Version v2) { - return isCompatible(v1, v2); - } - - private boolean isCompatibleServerPersistence(Version persisted, Version current) { - if (persisted.major() == current.major() && persisted.minor() == current.minor()) { - return true; - } else { - return current.compareTo(persisted) >= 0; - } - } - - private static boolean isCompatible(Version v1, Version v2) { - if (v1 == null || v2 == null) { throw new NullPointerException(); } - return ((v1.major() == v2.major()) && (v1.minor() == v2.minor())); - } - - public static boolean isNewer(Version v1, Version v2, int depth) { - if (v1 == null || v2 == null) { throw new NullPointerException(); } - return v1.isNewer(v2, depth); + return true; } } diff --git a/common/src/main/java/com/tc/util/version/Version.java b/common/src/main/java/com/tc/util/version/Version.java deleted file mode 100644 index 1a17b3c072..0000000000 --- a/common/src/main/java/com/tc/util/version/Version.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * - * The contents of this file are subject to the Terracotta Public License Version - * 2.0 (the "License"); You may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://terracotta.org/legal/terracotta-public-license. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for - * the specific language governing rights and limitations under the License. - * - * The Covered Software is Terracotta Core. - * - * The Initial Developer of the Covered Software is - * Terracotta, Inc., a Software AG company - * - */ -package com.tc.util.version; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class Version implements Comparable { - // A version: - // \d+ - 1 or more digits - // \. - a dot - // \d+ - 1 or more digits - // \. - a dot - // \d+ - 1 or more digits - // \. - a dot - // \d+ - 1 or more digits - // \. - a dot - // \d+ - 1 or more digits - // _ - an underscore - // \w+ - letters and/or numbers - // - - just a dash - // \w+ - letters and numbers - private static final Pattern VERSION_PATTERN = Pattern.compile("^(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)?)?(?:\\.(\\d+)?)?(?:\\.(\\d+)?)?)?(?:_(\\w+))?(?:-(\\w+))?$"); - - private final int major; - private final int minor; - private final int micro; - private final int patch; - private final int build; - private final String specifier; - private final String qualifier; - - /** - * Throws IllegalArgumentException on bad version string - */ - public Version(String version) { - Matcher m = VERSION_PATTERN.matcher(version); - if (!m.matches()) throw invalidVersion(version); - - major = Integer.parseInt(m.group(1)); - String minorStr = m.group(2); - if (minorStr != null) { - minor = Integer.parseInt(minorStr); - String microStr = m.group(3); - if (microStr != null) { - micro = Integer.parseInt(microStr); - String patchStr = m.group(4); - if (patchStr != null) { - patch = Integer.parseInt(patchStr); - String buildStr = m.group(5); - if (buildStr != null) { - build = Integer.parseInt(buildStr); - } else { - build = 0; - } - } else { - patch = 0; - build = 0; - } - } else { - micro = 0; - patch = 0; - build = 0; - } - } else { - minor = 0; - micro = 0; - patch = 0; - build = 0; - } - specifier = m.group(6); - qualifier = m.group(7); - } - - public static boolean isValidVersionString(String version) { - Matcher m = VERSION_PATTERN.matcher(version); - return m.matches(); - } - - private IllegalArgumentException invalidVersion(String input) { - return new IllegalArgumentException("Invalid version, unable to parse: " + input); - } - - public int major() { - return this.major; - } - - public int minor() { - return this.minor; - } - - public int micro() { - return this.micro; - } - - private int patch() { - return patch; - } - - private int build() { - return build; - } - - /** - * Tests if this Version is newer than Version 'v' up to a maximum 'depth' of digits. - * @param v Version to compare against - * @param depth Maximum number of digits in version string to compare - * @return TRUE if this Version is newer than Version 'v' up to 'depth' digits comparison, FALSE otherwise - */ - public boolean isNewer(Version v, int depth) { - if (v == null) { throw new NullPointerException(); } - if (depth < 1 || depth > 5) {throw new IndexOutOfBoundsException(); } - int[] v1 = {major, minor, micro, patch, build}; - int[] v2 = {v.major, v.minor, v.micro, v.patch, v.build}; - int i = 0; - while (i < depth) { - if (v1[i] > v2[i]) { - return true; - } - if (v1[i] != v2[i]) { - return false; - } - i++; - } - return false; - } - - - - /** - * May be null - */ - public String qualifier() { - return this.qualifier; - } - - public String specifier() { - return specifier; - } - - @Override - public int compareTo(Version otherVersion) { - int majorDiff = major - otherVersion.major(); - if (majorDiff != 0) { return majorDiff; } - - int minorDiff = minor - otherVersion.minor(); - if (minorDiff != 0) { return minorDiff; } - - int microDiff = micro - otherVersion.micro(); - if (microDiff != 0) { return microDiff; } - - int patchDiff = patch - otherVersion.patch(); - if (patchDiff != 0) { return patchDiff; } - - int buildDiff = build - otherVersion.build(); - if (buildDiff != 0) { return buildDiff; } - - if (specifier == null) { - if (otherVersion.specifier != null) { return 1; } - } else if (otherVersion.specifier == null) { - return -1; - } else if (specifier.compareTo(otherVersion.specifier) != 0) { - return specifier.compareTo(otherVersion.specifier); - } - - // Any version with a qualifier is considered "less than" a version without: - // 1.0.0-SNAPSHOT < 1.0.0 - if (qualifier == null) { - if (otherVersion.qualifier != null) { return 1; } - } else if (otherVersion.qualifier == null) { - return -1; - } else { - return qualifier.compareTo(otherVersion.qualifier); - } - - return 0; - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof Version) { - return this.compareTo((Version) obj) == 0; - } else { - return false; - } - } - - @Override - public int hashCode() { - return toString().hashCode(); - } - - @Override - public String toString() { - StringBuilder versionString = new StringBuilder().append(major); - versionString.append(".").append(minor).append(".").append(micro) - .append(".").append(patch).append(".").append(build); - if (specifier != null) { - versionString.append("_" + specifier); - } - if (qualifier != null) { - versionString.append("-" + qualifier); - } - return versionString.toString(); - } -} diff --git a/common/src/main/java/com/tc/util/version/VersionMatcher.java b/common/src/main/java/com/tc/util/version/VersionMatcher.java deleted file mode 100644 index ea766838ef..0000000000 --- a/common/src/main/java/com/tc/util/version/VersionMatcher.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * - * The contents of this file are subject to the Terracotta Public License Version - * 2.0 (the "License"); You may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://terracotta.org/legal/terracotta-public-license. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for - * the specific language governing rights and limitations under the License. - * - * The Covered Software is Terracotta Core. - * - * The Initial Developer of the Covered Software is - * Terracotta, Inc., a Software AG company - * - */ -package com.tc.util.version; - -/** - * This class encapsulates knowledge about whether a particular module or modules are valid within the current tc/api - * version. - */ - -public class VersionMatcher { - - public static final String ANY_VERSION = "*"; - - private final String tcVersion; - - public VersionMatcher(String tcVersion) { - if (tcVersion == null || tcVersion.equals(ANY_VERSION)) { throw new IllegalArgumentException("Invalid tcVersion: " - + tcVersion); } - - this.tcVersion = tcVersion; - } - - /** - * Determine whether a module's tc version matches with the current Terracotta installation's tc - * version. - * - * @param moduleTcVersion is expected to be: * or exact like 3.0.0 - * @return true if module is suitable for this installation - */ - public boolean matches(String moduleTcVersion) { - return tcMatches(moduleTcVersion); - } - - private boolean tcMatches(String moduleTcVersion) { - return ANY_VERSION.equals(moduleTcVersion) /* || tcVersion.equals("[unknown]") */ - || tcVersion.equals(moduleTcVersion); - } - -} diff --git a/common/src/main/java/com/tc/util/version/VersionRange.java b/common/src/main/java/com/tc/util/version/VersionRange.java deleted file mode 100644 index ab13f2886a..0000000000 --- a/common/src/main/java/com/tc/util/version/VersionRange.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * - * The contents of this file are subject to the Terracotta Public License Version - * 2.0 (the "License"); You may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://terracotta.org/legal/terracotta-public-license. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for - * the specific language governing rights and limitations under the License. - * - * The Covered Software is Terracotta Core. - * - * The Initial Developer of the Covered Software is - * Terracotta, Inc., a Software AG company - * - */ -package com.tc.util.version; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class VersionRange { - // A version range: - // ^ - match start at beginning - // [([] - the begin range character - // - see below - // , - just a comma - // - see below - // [\])] - the end range character, does not have to match begin range character - // $ - match must hit end of string - // - // A version: - // \d+ - 1 or more digits - // \. - a dot - // \d+ - 1 or more digits - // \. - a dot - // \d+ - 1 or more digits - // - - just a dash - // \w+ - letters and numbers - private static final String VERSION_PATTERN_STR = "^(\\d+(?:\\.\\d+(?:\\.\\d+(?:-\\w+)?)?)?)$"; - - private static final Pattern SINGLE_COMMA = Pattern.compile("^([^,]+)?,([^,]+)?$"); - private static final Pattern VERSION = Pattern.compile(VERSION_PATTERN_STR); - - private final String minVersion; - private final String maxVersion; - private final boolean minIsInclusive; - private final boolean maxIsInclusive; - - public VersionRange(String versionString) { - if (versionString == null) { throw new NullPointerException(); } - versionString = versionString.trim(); - - if (isRange(versionString)) { - minIsInclusive = versionString.startsWith("["); - maxIsInclusive = versionString.endsWith("]"); - - versionString = versionString.replaceFirst("^[\\[(]", ""); - versionString = versionString.replaceFirst("[\\])]$", ""); - versionString = versionString.trim(); - - if (versionString.endsWith(",")) { - minVersion = verifyVersionFormat(versionString.replaceFirst(",$", "")); - maxVersion = ""; - } else if (versionString.startsWith(",")) { - maxVersion = verifyVersionFormat(versionString.replaceFirst("^,", "")); - minVersion = ""; - } else { - String[] pair = versionString.split(","); - if (pair.length != 2) { throw new AssertionError("Unexpected number of elements (" + pair.length + "): " - + versionString); } - for (int i = 0; i < pair.length; i++) { - pair[i] = pair[i].trim(); - } - - minVersion = verifyVersionFormat(pair[0]); - maxVersion = verifyVersionFormat(pair[1]); - } - } else { - minVersion = verifyVersionFormat(versionString); - maxVersion = verifyVersionFormat(versionString); - minIsInclusive = true; - maxIsInclusive = true; - } - } - - private String verifyVersionFormat(String ver) { - Matcher matcher = VERSION.matcher(ver); - if (matcher.matches()) { return ver; } - - throw new IllegalArgumentException("Unexpected version string format: " + ver); - } - - private boolean isRange(String ver) { - if (ver.startsWith("[") || ver.startsWith("(")) { - if (ver.endsWith("]") || ver.endsWith(")")) { - Matcher matcher = SINGLE_COMMA.matcher(ver); - if (matcher.matches()) { - return true; - } else { - throw new IllegalArgumentException("Apparent version range missing single comma: " + ver); - } - } else { - throw new IllegalArgumentException("Version string missing proper trailing character: " + ver); - } - } - return false; - } - - public String getMinVersion() { - return minVersion; - } - - public String getMaxVersion() { - return maxVersion; - } - - public boolean isMinInclusive() { - return minIsInclusive; - } - - public boolean isMaxInclusive() { - return maxIsInclusive; - } - - public boolean contains(String otherVersionStr) { - if (!Version.isValidVersionString(otherVersionStr)) { - return false; - } - - Version otherVersion = new Version(otherVersionStr); - - int compareMin = isMinUnbounded() ? 1 : otherVersion.compareTo(new Version(minVersion)); - int compareMax = isMaxUnbounded() ? -1 : otherVersion.compareTo(new Version(maxVersion)); - - boolean greaterThanMin = compareMin > 0 || (isMinInclusive() && compareMin == 0); - boolean lessThanMax = compareMax < 0 || (isMaxInclusive() && compareMax == 0); - - return greaterThanMin && lessThanMax; - } - - public boolean isMaxUnbounded() { - return maxVersion.length() == 0; - } - - public boolean isMinUnbounded() { - return minVersion.length() == 0; - } -} diff --git a/common/src/test/java/com/tc/util/version/VersionCompatibilityTest.java b/common/src/test/java/com/tc/util/version/VersionCompatibilityTest.java deleted file mode 100644 index 23c4b0524e..0000000000 --- a/common/src/test/java/com/tc/util/version/VersionCompatibilityTest.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * - * The contents of this file are subject to the Terracotta Public License Version - * 2.0 (the "License"); You may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://terracotta.org/legal/terracotta-public-license. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for - * the specific language governing rights and limitations under the License. - * - * The Covered Software is Terracotta Core. - * - * The Initial Developer of the Covered Software is - * Terracotta, Inc., a Software AG company - * - */ -package com.tc.util.version; - -import junit.framework.TestCase; - -/** - * Version compatibility check is currently disabled. - */ -public class VersionCompatibilityTest extends TestCase { - - private DefaultVersionCompatibility versionCompatibility; - - @Override - protected void setUp() throws Exception { - this.versionCompatibility = new DefaultVersionCompatibility(); - } - - public void testNull() { - try { - versionCompatibility.isCompatibleClientServer(v("1.0.0"), null); - fail(); - } catch (NullPointerException npe) { - // expected - } - - try { - versionCompatibility.isCompatibleClientServer(null, v("1.0.0")); - fail(); - } catch (NullPointerException npe) { - // expected - } - - try { - versionCompatibility.isCompatibleClientServer(null, null); - fail(); - } catch (NullPointerException npe) { - // expected - } - } - - private static Version incrementedVersion(Version base, int majorIncrement, int minorIncrement, int microIncrement) { - return new Version((base.major() + majorIncrement) + "." + - (base.minor() + minorIncrement) + "." + - (base.micro() + microIncrement)); - } - - public void testSame() { - assertTrue(versionCompatibility.isCompatibleClientServer(v("1.0.0"), v("1.0.0"))); - } - - public void testMajorBump() { - assertFalse(versionCompatibility.isCompatibleClientServer(v("1.0.0"), v("2.0.0"))); - } - - public void testMajorDrop() { - assertFalse(versionCompatibility.isCompatibleClientServer(v("2.0.0"), v("1.0.0"))); - } - - public void testMinorBump() { - assertFalse(versionCompatibility.isCompatibleClientServer(v("1.0.0"), v("1.1.0"))); - } - - public void testMinorDrop() { - assertFalse(versionCompatibility.isCompatibleClientServer(v("1.1.0"), v("1.0.0"))); - } - - public void testDotBump() { - assertTrue(versionCompatibility.isCompatibleClientServer(v("1.0.0"), v("1.0.1"))); - } - - public void testDotDrop() { - assertFalse(versionCompatibility.isCompatibleClientServer(v("1.0.1"), v("1.0.0"))); - } - - public void testPatchBump() { - assertTrue(versionCompatibility.isCompatibleClientServer(v("1.0.1.1.134"), v("1.0.1.2.25"))); - } - - public void testPatchDrop() { - assertTrue(versionCompatibility.isCompatibleClientServer(v("1.0.1.1.134"), v("1.0.1.0.25"))); - } - - public void testBuildBump() { - assertTrue(versionCompatibility.isCompatibleClientServer(v("1.0.1.1.134"), v("1.0.1.1.142"))); - } - - public void testBuildDrop() { - assertTrue(versionCompatibility.isCompatibleClientServer(v("1.0.1.1.134"), v("1.0.1.1.25"))); - } - - public void testSpecifierAdd() { - assertTrue(versionCompatibility.isCompatibleClientServer(v("1.0.1.1.134"), v("1.0.1.1.134_fix1"))); - } - - public void testSpecifierDrop() { - assertTrue(versionCompatibility.isCompatibleClientServer(v("1.0.1.1.134_fix1"), v("1.0.1.1.134"))); - } - - public void testSnapshots() { - assertTrue(versionCompatibility.isCompatibleClientServer(v("1.0.0"), v("1.0.0-SNAPSHOT"))); - assertTrue(versionCompatibility.isCompatibleClientServer(v("1.0.0.1.34"), v("1.0.0-SNAPSHOT"))); - assertTrue(versionCompatibility.isCompatibleClientServer(v("1.0.0-SNAPSHOT"), v("1.0.0"))); - assertTrue(versionCompatibility.isCompatibleClientServer(v("1.0.0-SNAPSHOT"), v("1.0.0.1.54"))); - assertTrue(versionCompatibility.isCompatibleClientServer(v("1.0.0-SNAPSHOT"), v("1.0.0-SNAPSHOT"))); - assertTrue(versionCompatibility.isCompatibleClientServer(v("1.0.0"), v("1.0.1-SNAPSHOT"))); - assertTrue(versionCompatibility.isCompatibleClientServer(v("1.0.0-SNAPSHOT"), v("1.0.1"))); - assertTrue(versionCompatibility.isCompatibleClientServer(v("1.0.0-SNAPSHOT"), v("1.0.1-SNAPSHOT"))); - assertFalse(versionCompatibility.isCompatibleClientServer(v("1.0.1"), v("1.0.0-SNAPSHOT"))); - assertFalse(versionCompatibility.isCompatibleClientServer(v("1.0.1-SNAPSHOT"), v("1.0.0"))); - assertFalse(versionCompatibility.isCompatibleClientServer(v("1.0.1-SNAPSHOT"), v("1.0.0-SNAPSHOT"))); - - assertFalse(versionCompatibility.isCompatibleClientServer(v("1.1.0"), v("1.0.0-SNAPSHOT"))); - assertFalse(versionCompatibility.isCompatibleClientServer(v("1.1.0-SNAPSHOT"), v("1.0.0"))); - assertFalse(versionCompatibility.isCompatibleClientServer(v("1.1.0-SNAPSHOT"), v("1.0.0-SNAPSHOT"))); - - assertFalse(versionCompatibility.isCompatibleClientServer(v("2.0.0"), v("1.0.0-SNAPSHOT"))); - assertFalse(versionCompatibility.isCompatibleClientServer(v("2.0.0-SNAPSHOT"), v("1.0.0"))); - assertFalse(versionCompatibility.isCompatibleClientServer(v("2.0.0-SNAPSHOT"), v("1.0.0-SNAPSHOT"))); - } - - private static String v(String version) { - return version; - } - -} diff --git a/common/src/test/java/com/tc/util/version/VersionMatcherTest.java b/common/src/test/java/com/tc/util/version/VersionMatcherTest.java deleted file mode 100644 index aceef7b4e3..0000000000 --- a/common/src/test/java/com/tc/util/version/VersionMatcherTest.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * - * The contents of this file are subject to the Terracotta Public License Version - * 2.0 (the "License"); You may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://terracotta.org/legal/terracotta-public-license. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for - * the specific language governing rights and limitations under the License. - * - * The Covered Software is Terracotta Core. - * - * The Initial Developer of the Covered Software is - * Terracotta, Inc., a Software AG company - * - */ -package com.tc.util.version; - -import org.junit.Assert; - -import com.tc.test.TCTestCase; - -public class VersionMatcherTest extends TCTestCase { - - public void testExactMatch() { - VersionMatcher matcher = new VersionMatcher("3.0.0"); - Assert.assertTrue(matcher.matches("3.0.0")); - } - - public void testExactMisMatch() { - VersionMatcher matcher = new VersionMatcher("3.0.0"); - Assert.assertFalse(matcher.matches("9.9.9")); - } - - public void testTcAny() { - VersionMatcher matcher = new VersionMatcher("3.0.0"); - Assert.assertTrue(matcher.matches("*")); - } - -} diff --git a/common/src/test/java/com/tc/util/version/VersionRangeTest.java b/common/src/test/java/com/tc/util/version/VersionRangeTest.java deleted file mode 100644 index 193cdf63b8..0000000000 --- a/common/src/test/java/com/tc/util/version/VersionRangeTest.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * - * The contents of this file are subject to the Terracotta Public License Version - * 2.0 (the "License"); You may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://terracotta.org/legal/terracotta-public-license. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for - * the specific language governing rights and limitations under the License. - * - * The Covered Software is Terracotta Core. - * - * The Initial Developer of the Covered Software is - * Terracotta, Inc., a Software AG company - * - */ -package com.tc.util.version; - -import junit.framework.TestCase; - -public class VersionRangeTest extends TestCase { - - public void testExact() { - VersionRange r = new VersionRange("1.0.0-SNAPSHOT"); - assertTrue(r.isMinInclusive()); - assertEquals("1.0.0-SNAPSHOT", r.getMinVersion()); - assertEquals("1.0.0-SNAPSHOT", r.getMaxVersion()); - assertTrue(r.isMaxInclusive()); - } - - public void testExactPartial() { - VersionRange r = new VersionRange("1.0"); - assertTrue(r.isMinInclusive()); - assertEquals("1.0", r.getMinVersion()); - assertEquals("1.0", r.getMaxVersion()); - assertTrue(r.isMaxInclusive()); - } - - public void testRange() { - VersionRange r = new VersionRange("[1.0.0-SNAPSHOT,1.1.0-SNAPSHOT)"); - assertTrue(r.isMinInclusive()); - assertEquals("1.0.0-SNAPSHOT", r.getMinVersion()); - assertEquals("1.1.0-SNAPSHOT", r.getMaxVersion()); - assertFalse(r.isMaxInclusive()); - } - - public void testRange2() { - VersionRange r = new VersionRange("(1.0.0-SNAPSHOT,1.1.0-SNAPSHOT]"); - assertFalse(r.isMinInclusive()); - assertEquals("1.0.0-SNAPSHOT", r.getMinVersion()); - assertEquals("1.1.0-SNAPSHOT", r.getMaxVersion()); - assertTrue(r.isMaxInclusive()); - } - - public void testOpenMaxRange() { - VersionRange r = new VersionRange("[1.0.0-SNAPSHOT,]"); - assertEquals("1.0.0-SNAPSHOT", r.getMinVersion()); - assertEquals("", r.getMaxVersion()); - assertTrue(r.isMaxUnbounded()); - assertFalse(r.isMinUnbounded()); - assertTrue(r.isMaxInclusive()); - assertTrue(r.isMinInclusive()); - assertFalse(r.contains("0.0.1")); - assertTrue(r.contains("1.0.0-SNAPSHOT")); - assertTrue(r.contains("1.0.0")); - assertTrue(r.contains("1.0.1")); - assertTrue(r.contains("99.0.0")); - } - - public void testOpenMinRange() { - VersionRange r = new VersionRange("[,1.0.0-SNAPSHOT]"); - assertEquals("1.0.0-SNAPSHOT", r.getMaxVersion()); - assertEquals("", r.getMinVersion()); - assertFalse(r.isMaxUnbounded()); - assertTrue(r.isMinUnbounded()); - assertTrue(r.isMaxInclusive()); - assertTrue(r.isMinInclusive()); - assertTrue(r.contains("0.0.1")); - assertTrue(r.contains("1.0.0-SNAPSHOT")); - assertFalse(r.contains("1.0.0")); - } - - public void testContainsMinInclusiveMaxExclusive() { - VersionRange r = new VersionRange("[1.0.0,1.1.0)"); - assertFalse(r.contains("0.0.2")); - assertFalse(r.contains("1.0.0-SNAPSHOT")); - assertTrue(r.contains("1.0.0")); - assertTrue(r.contains("1.0.1")); - assertTrue(r.contains("1.0.1-SNAPSHOT")); - assertTrue(r.contains("1.1.0-SNAPSHOT")); - assertFalse(r.contains("1.1.0")); - assertFalse(r.contains("1.1.1")); - } - - public void testContainsMinInclusiveMaxExclusiveSnapshot() { - VersionRange r = new VersionRange("[1.0.0-SNAPSHOT,1.1.0-SNAPSHOT)"); - assertFalse(r.contains("0.0.2")); - assertTrue(r.contains("1.0.0-SNAPSHOT")); - assertTrue(r.contains("1.0.1")); - assertTrue(r.contains("1.0.1-SNAPSHOT")); - assertFalse(r.contains("1.1.0-SNAPSHOT")); - assertFalse(r.contains("1.1.0")); - assertFalse(r.contains("1.1.1")); - } - - public void testContainsMaxInclusiveMinExclusiveSnapshot() { - VersionRange r = new VersionRange("(1.0.0-SNAPSHOT,1.1.0-SNAPSHOT]"); - assertFalse(r.contains("0.0.2")); - assertFalse(r.contains("1.0.0-SNAPSHOT")); - assertTrue(r.contains("1.0.1")); - assertTrue(r.contains("1.0.1-SNAPSHOT")); - assertTrue(r.contains("1.1.0-SNAPSHOT")); - assertFalse(r.contains("1.1.0")); - assertFalse(r.contains("1.1.1")); - } -} diff --git a/common/src/test/java/com/tc/util/version/VersionTest.java b/common/src/test/java/com/tc/util/version/VersionTest.java deleted file mode 100644 index 2bb13147bc..0000000000 --- a/common/src/test/java/com/tc/util/version/VersionTest.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * - * The contents of this file are subject to the Terracotta Public License Version - * 2.0 (the "License"); You may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://terracotta.org/legal/terracotta-public-license. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for - * the specific language governing rights and limitations under the License. - * - * The Covered Software is Terracotta Core. - * - * The Initial Developer of the Covered Software is - * Terracotta, Inc., a Software AG company - * - */ -package com.tc.util.version; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import junit.framework.TestCase; - -public class VersionTest extends TestCase { - - private void helpTestParse(String str, int major, int minor, int micro, int patch, int build, String specifier, String qualifier) { - Version v = new Version(str); - assertEquals("major", major, v.major()); - assertEquals("minor", minor, v.minor()); - assertEquals("micro", micro, v.micro()); - assertEquals("specifier", specifier, v.specifier()); - assertEquals("qualifier", qualifier, v.qualifier()); - } - - public void testVersionParse() { - helpTestParse("1", 1, 0, 0, 0, 0, null, null); - helpTestParse("1.2", 1, 2, 0, 0, 0, null, null); - helpTestParse("1.2.3", 1, 2, 3, 0, 0, null, null); - helpTestParse("1.2.3-foo", 1, 2, 3, 0, 0, null, "foo"); - helpTestParse("1.2.3_preview-foo", 1, 2, 3, 0, 0, "preview", "foo"); - helpTestParse("1.2.3_preview", 1, 2, 3, 0, 0, "preview", null); - helpTestParse("4.3.0.0.1", 4, 3, 0, 0, 1, null, null); - } - - @SuppressWarnings("unused") - private void helpTestInvalid(String input) { - try { - new Version(input); - fail("Expected error on invalid input but got none: " + input); - } catch(IllegalArgumentException e) { - // expected - } - } - - public void testVersionInvalid() { - helpTestInvalid("foo"); - helpTestInvalid("1.1.1.SNAPSHOT"); - helpTestInvalid("[1.0.0,1.1.0)"); - helpTestInvalid("1.0.thisdoesntlookright"); - } - - private void helpTestCompare(String s1, String s2, int compareDirection) { - Version v1 = new Version(s1); - Version v2 = new Version(s2); - int compared = v1.compareTo(v2); - int comparedBackwards = v2.compareTo(v1); - - if(compareDirection == 0) { - assertTrue("expected 0, got: " + compared, compared == 0); - assertTrue(comparedBackwards == 0); - } else if(compareDirection < 0) { - assertTrue(compared < 0); - assertTrue(comparedBackwards > 0); - } else { - assertTrue(compared > 0); - assertTrue(comparedBackwards < 0); - } - } - - public void testComparison() { - helpTestCompare("1.0.0", "1.0.0", 0); - helpTestCompare("1.0.0-SNAPSHOT", "1.0.0-SNAPSHOT", 0); - helpTestCompare("1.0.0", "1.0.0-SNAPSHOT", 1); - helpTestCompare("1.0.0", "1.1.0", -1); - helpTestCompare("1.0.1", "1.0.2", -1); - helpTestCompare("1.0.0", "2.0.0", -1); - helpTestCompare("1.2.3", "4.5.6", -1); - helpTestCompare("1.0_preview", "1.0", -1); - helpTestCompare("1.0-SNAPSHOT", "1.0_preview", 1); - helpTestCompare("1.0_preview-SNAPSHOT", "1.0_preview", -1); - helpTestCompare("1.0_preview1", "1.0_preview2", -1); - helpTestCompare("1.0_preview1-SNAPSHOT", "1.0_preview2", -1); - helpTestCompare("1.0_preview2-SNAPSHOT", "1.0_preview1", 1); - helpTestCompare("4.3.1.0.1", "4.3.1.0.2", -1); - helpTestCompare("4.3.0", "4.3.0.0.1", -1); - helpTestCompare("4.3.0.0.256", "4.4.0", -1); - } - - public void testSortList() { - List stuff = new ArrayList(); - stuff.add(new Version("1.2.0")); - stuff.add(new Version("1.1.0-SNAPSHOT")); - stuff.add(new Version("1.1.0")); - stuff.add(new Version("1.0.0")); - stuff.add(new Version("2.1.0")); - stuff.add(new Version("2.1.0-SNAPSHOT")); - stuff.add(new Version("1.1.0_preview")); - Collections.sort(stuff); - assertEquals("[1.0.0.0.0, 1.1.0.0.0_preview, 1.1.0.0.0-SNAPSHOT, 1.1.0.0.0, 1.2.0.0.0, 2.1.0.0.0-SNAPSHOT, 2.1.0.0.0]", stuff.toString()); - } - - public void testIsNewer() { - try { - helpTestIsNewer ("1", "1", 0); - fail("depth must be >= 1 and <= 5"); - } catch(IndexOutOfBoundsException e) { - // expected - } - try { - helpTestIsNewer ("1", "1", 6); - fail("depth must be >= 1 and <= 5"); - } catch(IndexOutOfBoundsException e) { - // expected - } - - assertTrue(helpTestIsNewer("11", "10", 1)); - assertTrue(helpTestIsNewer("11", "10", 2)); - assertTrue(helpTestIsNewer("11", "10", 3)); - assertTrue(helpTestIsNewer("11", "10", 4)); - assertTrue(helpTestIsNewer("11", "10", 5)); - - assertFalse(helpTestIsNewer("11.1", "11.0", 1)); - assertTrue(helpTestIsNewer ("11.2", "11.1", 2)); - assertTrue(helpTestIsNewer ("11.3", "11.2", 3)); - assertTrue(helpTestIsNewer ("11.4", "11.3", 4)); - assertTrue(helpTestIsNewer ("11.5", "11.4", 5)); - - assertFalse(helpTestIsNewer("11.0.1", "11.0.0", 1)); - assertFalse(helpTestIsNewer("11.0.2", "11.0.1", 2)); - assertTrue(helpTestIsNewer ("11.0.3", "11.0.2", 3)); - assertTrue(helpTestIsNewer ("11.0.4", "11.0.3", 4)); - assertTrue(helpTestIsNewer ("11.0.5", "11.0.4", 5)); - - assertFalse(helpTestIsNewer("11.0.0.1", "11.0.0.0", 1)); - assertFalse(helpTestIsNewer("11.0.0.2", "11.0.0.1", 2)); - assertFalse(helpTestIsNewer("11.0.0.3", "11.0.0.2", 3)); - assertTrue(helpTestIsNewer ("11.0.0.4", "11.0.0.3", 4)); - assertTrue(helpTestIsNewer ("11.0.0.5", "11.0.0.4", 5)); - - assertFalse(helpTestIsNewer("11.0.0.0.1", "11.0.0.0.0", 1)); - assertFalse(helpTestIsNewer("11.0.0.0.2", "11.0.0.0.1", 2)); - assertFalse(helpTestIsNewer("11.0.0.0.3", "11.0.0.0.2", 3)); - assertFalse(helpTestIsNewer("11.0.0.0.4", "11.0.0.0.3", 4)); - assertTrue(helpTestIsNewer ("11.0.0.0.5", "11.0.0.0.4", 5)); - - assertFalse(helpTestIsNewer("1.1.1.1.1", "10.10.10.10.10", 1)); - assertFalse(helpTestIsNewer("1.1.1.1.1", "10.10.10.10.10", 2)); - assertFalse(helpTestIsNewer("1.1.1.1.1", "10.10.10.10.10", 3)); - assertFalse(helpTestIsNewer("1.1.1.1.1", "10.10.10.10.10", 4)); - assertFalse(helpTestIsNewer("1.1.1.1.1", "10.10.10.10.10", 5)); - - assertTrue(helpTestIsNewer("10.7.0", "10.3.1.4.11", 3)); - assertFalse(helpTestIsNewer("10.3.1.4.11", "10.7.0", 3)); - } - - private boolean helpTestIsNewer(String s1, String s2, int depth) { - Version v1 = new Version(s1); - Version v2 = new Version(s2); - return v1.isNewer(v2, depth); - } -} diff --git a/tc-messaging/src/main/java/com/tc/net/groups/TCGroupHandshakeMessage.java b/tc-messaging/src/main/java/com/tc/net/groups/TCGroupHandshakeMessage.java index 9f2ad6639a..e4b584a66f 100755 --- a/tc-messaging/src/main/java/com/tc/net/groups/TCGroupHandshakeMessage.java +++ b/tc-messaging/src/main/java/com/tc/net/groups/TCGroupHandshakeMessage.java @@ -18,7 +18,6 @@ */ package com.tc.net.groups; -import com.tc.bytes.TCByteBuffer; import com.tc.io.TCByteBufferInputStream; import com.tc.io.TCByteBufferOutputStream; import com.tc.net.ServerID; diff --git a/tc-server/src/main/java/com/tc/net/groups/TCGroupManagerImpl.java b/tc-server/src/main/java/com/tc/net/groups/TCGroupManagerImpl.java index b00e6e0331..48a98d17bd 100755 --- a/tc-server/src/main/java/com/tc/net/groups/TCGroupManagerImpl.java +++ b/tc-server/src/main/java/com/tc/net/groups/TCGroupManagerImpl.java @@ -105,6 +105,7 @@ import static java.util.stream.Collectors.toSet; import org.terracotta.server.ServerEnv; import com.tc.net.protocol.tcm.TCAction; +import com.tc.productinfo.VersionCompatibility; public class TCGroupManagerImpl implements GroupManager, ChannelManagerEventListener, TopologyListener { @@ -115,6 +116,7 @@ public class TCGroupManagerImpl implements GroupManager, C private final int serverCount; private final String version; + private final VersionCompatibility versioning; private final ServerID thisNodeID; private final int groupPort; private final ConnectionPolicy connectionPolicy; @@ -148,14 +150,14 @@ public class TCGroupManagerImpl implements GroupManager, C * Setup a communication manager which can establish channel from either sides. */ public TCGroupManagerImpl(ServerConfigurationManager configSetupManager, StageManager stageManager, - ServerID thisNodeID, Node thisNode, + ServerID thisNodeID, Node thisNode, VersionCompatibility versioning, WeightGeneratorFactory weightGenerator, BufferManagerFactory bufferManagerFactory, TopologyManager topologyManager) { - this(configSetupManager, new NullConnectionPolicy(), stageManager, thisNodeID, thisNode, weightGenerator, + this(configSetupManager, new NullConnectionPolicy(), stageManager, thisNodeID, thisNode, versioning, weightGenerator, bufferManagerFactory, topologyManager); } public TCGroupManagerImpl(ServerConfigurationManager configSetupManager, ConnectionPolicy connectionPolicy, - StageManager stageManager, ServerID thisNodeID, Node thisNode, + StageManager stageManager, ServerID thisNodeID, Node thisNode, VersionCompatibility versioning, WeightGeneratorFactory weightGenerator, BufferManagerFactory bufferManagerFactory, TopologyManager topologyManager) { this.connectionPolicy = connectionPolicy; @@ -164,6 +166,7 @@ public TCGroupManagerImpl(ServerConfigurationManager configSetupManager, Connect this.bufferManagerFactory = bufferManagerFactory; this.topologyManager = topologyManager; this.version = configSetupManager.getProductInfo().version(); + this.versioning = versioning; ServerConfiguration l2DSOConfig = configSetupManager.getServerConfiguration(); serverCount = configSetupManager.allCurrentlyKnownServers().length; @@ -197,14 +200,15 @@ public boolean isNodeConnected(NodeID sid) { /* * for testing purpose only. Tester needs to do setDiscover(). */ - public TCGroupManagerImpl(ConnectionPolicy connectionPolicy, String hostname, int port, int groupPort, + public TCGroupManagerImpl(ConnectionPolicy connectionPolicy, String hostname, int port, int groupPort, String version, VersionCompatibility versioning, StageManager stageManager, WeightGeneratorFactory weightGenerator, TopologyManager topologyManager) { this.connectionPolicy = connectionPolicy; this.stageManager = stageManager; this.bufferManagerFactory = new ClearTextBufferManagerFactory(); this.topologyManager = topologyManager; this.groupPort = groupPort; - this.version = getVersion(); + this.version = version; + this.versioning = versioning; this.weightGeneratorFactory = weightGenerator; this.serverCount = 0; thisNodeID = new ServerID(new Node(hostname, port).getServerNodeName(), UUID.getUUID().toString().getBytes()); @@ -954,7 +958,7 @@ private synchronized TCGroupHandshakeStateMachine getOrCreateHandshakeStateMachi if (isDebugLogging()) { debugInfo("Creating handshake state machine for channel: " + channel); } - stateMachine = new TCGroupHandshakeStateMachine(this, channel, getNodeID(), weightGeneratorFactory, version); + stateMachine = new TCGroupHandshakeStateMachine(this, channel, getNodeID(), weightGeneratorFactory, version, versioning); channel.addAttachment(HANDSHAKE_STATE_MACHINE_TAG, stateMachine, false); channel.addListener(new HandshakeChannelEventListener(stateMachine)); if (channel.isOpen()) { @@ -1016,6 +1020,7 @@ private static class TCGroupHandshakeStateMachine { private final ServerID localNodeID; private final WeightGeneratorFactory weightGeneratorFactory; private final String version; + private final VersionCompatibility versioning; private HandshakeMonitor current; private ServerID peerNodeID; @@ -1023,12 +1028,13 @@ private static class TCGroupHandshakeStateMachine { private TCGroupMember member; public TCGroupHandshakeStateMachine(TCGroupManagerImpl manager, MessageChannel channel, ServerID localNodeID, - WeightGeneratorFactory weightGeneratorFactory, String version) { + WeightGeneratorFactory weightGeneratorFactory, String version, VersionCompatibility versioning) { this.manager = manager; this.channel = channel; this.localNodeID = localNodeID; this.weightGeneratorFactory = weightGeneratorFactory; this.version = version; + this.versioning = versioning; this.current = STATE_NEW.createMonitor(); this.current.complete(); } @@ -1244,6 +1250,11 @@ public void execute(TCGroupHandshakeMessage msg) { switchToState(STATE_FAILURE); return; } + if (!versioning.isCompatibleServerServer(msg.getVersion(), version)) { + logger.warn("Drop a connection from a server version that is not compatible. peer version: {} local version: {} node: {}", msg.getVersion(), version, peerNodeID); + switchToState(STATE_FAILURE); + return; + } /** * Restore Connection might have happened from the same peer member. Closing down the old and duplicate channel diff --git a/tc-server/src/main/java/com/tc/objectserver/handler/ClientHandshakeHandler.java b/tc-server/src/main/java/com/tc/objectserver/handler/ClientHandshakeHandler.java index 2b4818a6b8..02e36650aa 100644 --- a/tc-server/src/main/java/com/tc/objectserver/handler/ClientHandshakeHandler.java +++ b/tc-server/src/main/java/com/tc/objectserver/handler/ClientHandshakeHandler.java @@ -33,7 +33,6 @@ import com.tc.productinfo.ProductInfo; import com.tc.productinfo.VersionCompatibility; import com.tc.spi.Guardian; -import com.tc.util.version.Version; public class ClientHandshakeHandler extends AbstractEventHandler { @@ -41,27 +40,26 @@ public class ClientHandshakeHandler extends AbstractEventHandler clientHandshake = stageManager.createStage(ServerConfigurationContext.CLIENT_HANDSHAKE_STAGE, ClientHandshakeMessage.class, createHandShakeHandler(entityManager, processTransactionHandler, getVersionCompatibility()), 1, maxStageSize); + final Stage clientHandshake = stageManager.createStage(ServerConfigurationContext.CLIENT_HANDSHAKE_STAGE, ClientHandshakeMessage.class, createHandShakeHandler(entityManager, processTransactionHandler, pInfo.version(), versioning), 1, maxStageSize); Stage hydrator = stageManager.createStage(ServerConfigurationContext.HYDRATE_MESSAGE_STAGE, HydrateContext.class, new HydrateHandler(), L2Utils.getOptimalCommWorkerThreads(), maxStageSize); Stage diagStage = stageManager.createStage(ServerConfigurationContext.MONITOR_STAGE, TCAction.class, new DiagnosticsHandler(this, this.server.getJMX()), 1, 1); @@ -1326,8 +1333,8 @@ public ServerConfigurationManager getConfigSetupManager() { return configSetupManager; } - protected ClientHandshakeHandler createHandShakeHandler(EntityManager entities, ProcessTransactionHandler processTransactionHandler, VersionCompatibility versionCheck) { - return new ClientHandshakeHandler(entities, processTransactionHandler, versionCheck); + protected ClientHandshakeHandler createHandShakeHandler(EntityManager entities, ProcessTransactionHandler processTransactionHandler, String serverVersion, VersionCompatibility versionCheck) { + return new ClientHandshakeHandler(entities, processTransactionHandler, serverVersion, versionCheck); } // for tests only diff --git a/tc-server/src/main/java/com/tc/objectserver/impl/ServerBuilder.java b/tc-server/src/main/java/com/tc/objectserver/impl/ServerBuilder.java index b50b06901f..bb636eb685 100644 --- a/tc-server/src/main/java/com/tc/objectserver/impl/ServerBuilder.java +++ b/tc-server/src/main/java/com/tc/objectserver/impl/ServerBuilder.java @@ -38,13 +38,14 @@ import com.tc.objectserver.core.api.ServerConfigurationContext; import com.tc.objectserver.handshakemanager.ServerClientHandshakeManager; import com.tc.objectserver.persistence.Persistor; +import com.tc.productinfo.VersionCompatibility; import java.io.IOException; public interface ServerBuilder extends PostInit { GroupManager createGroupCommManager(ServerConfigurationManager configManager, - StageManager stageManager, ServerID serverNodeID, + StageManager stageManager, ServerID serverNodeID, VersionCompatibility versioning, StripeIDStateManager stripeStateManager, WeightGeneratorFactory weightGeneratorFactory, BufferManagerFactory bufferManagerFactory, TopologyManager topologyManager); diff --git a/tc-server/src/main/java/com/tc/objectserver/impl/ServerPersistenceVersionChecker.java b/tc-server/src/main/java/com/tc/objectserver/impl/ServerPersistenceVersionChecker.java deleted file mode 100644 index 355b21dc37..0000000000 --- a/tc-server/src/main/java/com/tc/objectserver/impl/ServerPersistenceVersionChecker.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * - * The contents of this file are subject to the Terracotta Public License Version - * 2.0 (the "License"); You may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://terracotta.org/legal/terracotta-public-license. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for - * the specific language governing rights and limitations under the License. - * - * The Covered Software is Terracotta Core. - * - * The Initial Developer of the Covered Software is - * Terracotta, Inc., a Software AG company - * - */ - -package com.tc.objectserver.impl; - -import com.tc.objectserver.persistence.ClusterStatePersistor; -import com.tc.productinfo.ProductInfo; -import com.tc.util.version.Version; - -/** - * @author tim - */ -public class ServerPersistenceVersionChecker { - private final ProductInfo productInfo; - - ServerPersistenceVersionChecker(ProductInfo productInfo) { - this.productInfo = productInfo; - } - - void checkAndBumpPersistedVersion(ClusterStatePersistor clusterStatePersistor) { - Version currentVersion = new Version(productInfo.version()); - Version persistedVersion = clusterStatePersistor.getVersion(); - // only move persisted version forward - if (persistedVersion == null || currentVersion.compareTo(persistedVersion) > 0) { - clusterStatePersistor.setVersion(currentVersion); - } - } -} diff --git a/tc-server/src/main/java/com/tc/objectserver/impl/StandardServerBuilder.java b/tc-server/src/main/java/com/tc/objectserver/impl/StandardServerBuilder.java index 8ba993699d..48c4d84d6b 100644 --- a/tc-server/src/main/java/com/tc/objectserver/impl/StandardServerBuilder.java +++ b/tc-server/src/main/java/com/tc/objectserver/impl/StandardServerBuilder.java @@ -44,6 +44,7 @@ import com.tc.objectserver.core.impl.ServerConfigurationContextImpl; import com.tc.objectserver.handshakemanager.ServerClientHandshakeManager; import com.tc.objectserver.persistence.Persistor; +import com.tc.productinfo.VersionCompatibility; import com.tc.util.Assert; import org.terracotta.persistence.IPlatformPersistence; @@ -61,10 +62,10 @@ public StandardServerBuilder(GroupConfiguration groupConfiguration, Logger logge @Override public GroupManager createGroupCommManager(ServerConfigurationManager configManager, - StageManager stageManager, ServerID serverNodeID, + StageManager stageManager, ServerID serverNodeID, VersionCompatibility versioning, StripeIDStateManager stripeStateManager, WeightGeneratorFactory weightGeneratorFactory, BufferManagerFactory bufferManagerFactory, TopologyManager topologyManager) { - return new TCGroupManagerImpl(configManager, stageManager, serverNodeID, this.groupConfiguration.getCurrentNode(), + return new TCGroupManagerImpl(configManager, stageManager, serverNodeID, this.groupConfiguration.getCurrentNode(), versioning, weightGeneratorFactory, bufferManagerFactory, topologyManager); } diff --git a/tc-server/src/main/java/com/tc/objectserver/persistence/ClusterStatePersistor.java b/tc-server/src/main/java/com/tc/objectserver/persistence/ClusterStatePersistor.java index f8213b2bf2..bd1b647758 100644 --- a/tc-server/src/main/java/com/tc/objectserver/persistence/ClusterStatePersistor.java +++ b/tc-server/src/main/java/com/tc/objectserver/persistence/ClusterStatePersistor.java @@ -21,7 +21,6 @@ import com.tc.l2.state.StateManager; import com.tc.net.StripeID; import com.tc.util.State; -import com.tc.util.version.Version; import java.io.IOException; import java.util.HashMap; import java.util.Map; @@ -83,13 +82,12 @@ public boolean isDBClean() { return s == null || Boolean.valueOf(s); } - public Version getVersion() { - String v = map.get(VERSION_KEY); - return v == null ? null : new Version(v); + public String getVersion() { + return map.get(VERSION_KEY); } - public void setVersion(Version v) { - putAndStore(VERSION_KEY, v.major() + "." + v.minor() + "." + v.micro()); + public void setVersion(String v) { + putAndStore(VERSION_KEY, v); } public void setDBClean(boolean dbClean) { diff --git a/tc-server/src/test/java/com/tc/l2/state/StateManagerImplTest.java b/tc-server/src/test/java/com/tc/l2/state/StateManagerImplTest.java index 97c3871dd7..be8de123af 100644 --- a/tc-server/src/test/java/com/tc/l2/state/StateManagerImplTest.java +++ b/tc-server/src/test/java/com/tc/l2/state/StateManagerImplTest.java @@ -68,6 +68,7 @@ import com.tc.net.ServerID; import com.tc.objectserver.core.impl.ManagementTopologyEventCollector; import com.tc.util.concurrent.ThreadUtil; +import com.tc.util.version.DefaultVersionCompatibility; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.junit.Ignore; @@ -139,7 +140,7 @@ public void setUp() throws Exception { when(clusterStatePersistorMock.isDBClean()).thenReturn(Boolean.TRUE); // tcServers[i] = mock(TCServer.class); stageManagers[i] = new StageManagerImpl(new ThreadGroup("test"), new QueueFactory()); - groupManagers[i] = new TCGroupManagerImpl(new NullConnectionPolicy(), LOCALHOST, ports.get(i).port(), groupPorts.get(i).port(), + groupManagers[i] = new TCGroupManagerImpl(new NullConnectionPolicy(), LOCALHOST, ports.get(i).port(), groupPorts.get(i).port(), "TEST", new DefaultVersionCompatibility(), stageManagers[i], wgf, topologyManager); stateManagers[i] = new StateManagerImpl(tcLogger, groupManagers[i], stageControllers[i], mgmt[i], stageManagers[i], NUM_OF_SERVERS, 5, wgf, mgr, diff --git a/tc-server/src/test/java/com/tc/net/groups/TCGroupManagerImplTest.java b/tc-server/src/test/java/com/tc/net/groups/TCGroupManagerImplTest.java index 42732a98eb..58b99d59e5 100755 --- a/tc-server/src/test/java/com/tc/net/groups/TCGroupManagerImplTest.java +++ b/tc-server/src/test/java/com/tc/net/groups/TCGroupManagerImplTest.java @@ -37,12 +37,14 @@ import com.tc.net.protocol.transport.NullConnectionPolicy; import com.tc.object.session.SessionID; import com.tc.objectserver.impl.TopologyManager; +import com.tc.productinfo.VersionCompatibility; import com.tc.properties.TCPropertiesImpl; import com.tc.test.TCTestCase; import com.tc.util.State; import com.tc.util.UUID; import com.tc.util.concurrent.NoExceptionLinkedQueue; import com.tc.util.runtime.ThreadDump; +import com.tc.util.version.DefaultVersionCompatibility; import org.mockito.Mockito; import org.slf4j.LoggerFactory; @@ -80,8 +82,8 @@ public class TCGroupManagerImplTest extends TCTestCase { private Node nodes[]; private AtomicReference error; private MockStageManagerFactory stages; - - private void setupGroups(int n) throws Exception { + + private void setupGroups(int n, String version, VersionCompatibility versioning) throws Exception { ServerEnv.setDefaultServer(mock(Server.class)); groups = new TCGroupManagerImpl[n]; listeners = new TestGroupMessageListener[n]; @@ -98,8 +100,9 @@ private void setupGroups(int n) throws Exception { } for (int i = 0; i < n; ++i) { groups[i] = new TCGroupManagerImpl(new NullConnectionPolicy(), LOCALHOST, ports.get(i).port(), groupPorts.get(i).port(), - stages.createStageManager(), RandomWeightGenerator.createTestingFactory(2), - mock(TopologyManager.class)); + version, versioning, + stages.createStageManager(), RandomWeightGenerator.createTestingFactory(2), + mock(TopologyManager.class)); groups[i].setDiscover(new TCGroupMemberDiscoveryStatic(groups[i], nodes[i])); groupEventListeners[i] = new TestGroupEventListener(groups[i]); groups[i].registerForGroupEvents(groupEventListeners[i]); @@ -107,6 +110,10 @@ private void setupGroups(int n) throws Exception { listeners[i] = new TestGroupMessageListener(2000); } } + + private void setupGroups(int n) throws Exception { + setupGroups(n, "TEST_VERSION-1.0", new DefaultVersionCompatibility()); + } private void tearGroups() throws Exception { try { @@ -267,158 +274,50 @@ public void testResolveTwoWayConnection() throws Exception { throw e; } } -// -// public void testSendTo() throws Exception { -// setupGroups(2); -// -// TestGroupMessageListener listener1 = new TestGroupMessageListener(2000); -// TestGroupMessageListener listener2 = new TestGroupMessageListener(2000); -// groups[0].registerForMessages(ObjectSyncMessage.class, listener1); -// groups[1].registerForMessages(ObjectSyncMessage.class, listener2); -// -// groups[0].setDiscover(new NullTCGroupMemberDiscovery()); -// groups[1].setDiscover(new NullTCGroupMemberDiscovery()); -// -// Set nodeSet = new HashSet<>(); -// Collections.addAll(nodeSet, nodes); -// NodesStore nodeStore = new NodesStoreImpl(nodeSet); -// groups[0].join(nodes[0], nodeStore); -// groups[1].join(nodes[1], nodeStore); -// -// groups[0].openChannel(LOCALHOST, groupPorts[1], new NullChannelEventListener()); -// Thread.sleep(1000); -// TCGroupMember member0 = getMember(groups[0], 0); -// TCGroupMember member1 = getMember(groups[1], 0); -// -// ObjectSyncMessage sMesg = createTestObjectSyncMessage(); -// groups[0].sendTo(member0.getPeerNodeID(), sMesg); -// ObjectSyncMessage rMesg = (ObjectSyncMessage) listener2.getNextMessageFrom(groups[0].getLocalNodeID()); -// assertTrue(cmpObjectSyncMessage(sMesg, rMesg)); -// -// sMesg = createTestObjectSyncMessage(); -// groups[1].sendTo(member1.getPeerNodeID(), sMesg); -// rMesg = (ObjectSyncMessage) listener1.getNextMessageFrom(groups[1].getLocalNodeID()); -// assertTrue(cmpObjectSyncMessage(sMesg, rMesg)); -// -// tearGroups(); -// } -// -// private ObjectSyncMessage createTestObjectSyncMessage() { -// ObjectIDSet dnaOids = new BitSetObjectIDSet(); -// for (long i = 1; i <= 100; ++i) { -// dnaOids.add(new ObjectID(i)); -// } -// int count = 10; -// TCByteBuffer[] serializedDNAs = new TCByteBuffer[] {}; -// ObjectStringSerializer objectSerializer = new ObjectStringSerializerImpl(); -// Map roots = new HashMap<>(); -// long sID = 10; -// ObjectSyncMessage message = new ObjectSyncMessage(new ServerTransactionID(new ServerID("hello", new byte[] { 34, 33, (byte) 234 }), -// new TransactionID(342)), dnaOids, count, serializedDNAs, -// objectSerializer, roots, sID, ObjectIDSet.EMPTY_OBJECT_ID_SET); -// return (message); -// } -// -// private boolean cmpObjectSyncMessage(ObjectSyncMessage o1, ObjectSyncMessage o2) { -// return ((o1.getDnaCount() == o2.getDnaCount()) && o1.getOids().equals(o2.getOids()) -// && o1.getRootsMap().equals(o2.getRootsMap()) && (o1.getType() == o2.getType()) -// && o1.getMessageID().equals(o2.getMessageID()) && o1.getServerTransactionID() -// .equals(o2.getServerTransactionID())); -// } + + public void testVersionControl() throws Exception { + try { + TCPropertiesImpl.getProperties().overwriteTcPropertiesFromConfig(new HashMap<>()); + VersionCompatibility versioning = mock(VersionCompatibility.class); + when(versioning.isCompatibleServerServer(anyString(), anyString())).thenReturn(false); + setupGroups(2, "TEST-Version-1.0", versioning); + + groups[0].setDiscover(new NullTCGroupMemberDiscovery()); + groups[1].setDiscover(new NullTCGroupMemberDiscovery()); + + Set nodeSet = new HashSet<>(); + Collections.addAll(nodeSet, nodes); + + GroupConfiguration groupConfiguration1 = getGroupConfiguration(nodeSet, nodes[0]); + GroupConfiguration groupConfiguration2 = getGroupConfiguration(nodeSet, nodes[1]); + + groups[0].join(groupConfiguration1); + groups[1].join(groupConfiguration2); + + groups[0].openChannel(LOCALHOST, groupPorts.get(1).port(), new ChannelEventListener() { + @Override + public void notifyChannelEvent(ChannelEvent event) { + System.out.println(event); + } + }); + groups[1].openChannel(LOCALHOST, groupPorts.get(0).port(), new ChannelEventListener() { + @Override + public void notifyChannelEvent(ChannelEvent event) { + System.out.println(event); + } + }); + + assertTrue(groups[0].size() == 0); + assertTrue(groups[1].size() == 0); + } catch (Throwable e) { + e.printStackTrace(); + throw e; + } + } private TCGroupMember getMember(TCGroupManagerImpl mgr, int idx) { return new ArrayList<>(mgr.getMembers()).get(idx); } -// -// public void testJoin() throws Exception { -// int nGrp = 2; -// setupGroups(nGrp); -// -// groups[0].registerForMessages(ObjectSyncMessage.class, listeners[0]); -// groups[1].registerForMessages(ObjectSyncMessage.class, listeners[1]); -// -// Set nodeSet = new HashSet<>(); -// Collections.addAll(nodeSet, nodes); -// NodesStore nodeStore = new NodesStoreImpl(nodeSet); -// groups[0].join(nodes[0], nodeStore); -// groups[1].join(nodes[1], nodeStore); -// waitForMembersToJoin(); -// -// GroupMessage sMesg = createTestObjectSyncMessage(); -// TCGroupMember member = getMember(groups[0], 0); -// groups[0].sendTo(member.getPeerNodeID(), sMesg); -// GroupMessage rMesg = listeners[1].getNextMessageFrom(groups[0].getLocalNodeID()); -// assertTrue(cmpObjectSyncMessage((ObjectSyncMessage) sMesg, (ObjectSyncMessage) rMesg)); -// -// sMesg = createTestObjectSyncMessage(); -// member = getMember(groups[1], 0); -// groups[1].sendTo(member.getPeerNodeID(), sMesg); -// rMesg = listeners[0].getNextMessageFrom(groups[1].getLocalNodeID()); -// assertTrue(cmpObjectSyncMessage((ObjectSyncMessage) sMesg, (ObjectSyncMessage) rMesg)); -// -// tearGroups(); -// } -// -// private GCResultMessage createGCResultMessage() { -// ObjectIDSet oidSet = new BitSetObjectIDSet(); -// for (long i = 1; i <= 100; ++i) { -// oidSet.add(new ObjectID(i)); -// } -// GCResultMessage message = new GCResultMessage(new GarbageCollectionInfo(), oidSet); -// return (message); -// } -// -// private boolean cmpGCResultMessage(GCResultMessage o1, GCResultMessage o2) { -// return (o1.getType() == o2.getType() && o1.getMessageID().equals(o2.getMessageID()) -// && o1.getGCedObjectIDs().equals(o2.getGCedObjectIDs()) && o1.getGCInfo().getGarbageCollectionID().toLong() == o2 -// .getGCInfo().getGarbageCollectionID().toLong()); -// } -// -// public void testSendToAll() throws Exception { -// int nGrp = 5; -// setupGroups(nGrp); -// HashMap listenerMap = new HashMap<>(); -// -// for (int i = 0; i < nGrp; ++i) { -// groups[i].registerForMessages(GCResultMessage.class, listeners[i]); -// listenerMap.put(groups[i].getLocalNodeID(), listeners[i]); -// } -// Set nodeSet = new HashSet<>(); -// Collections.addAll(nodeSet, nodes); -// NodesStore nodeStore = new NodesStoreImpl(nodeSet); -// for (int i = 0; i < nGrp; ++i) { -// groups[i].join(nodes[i], nodeStore); -// } -// waitForMembersToJoin(); -// -// // test with one to one first -// GroupMessage sMesg = createGCResultMessage(); -// TCGroupMember member = getMember(groups[0], 0); -// groups[0].sendTo(member.getPeerNodeID(), sMesg); -// TestGroupMessageListener listener = listenerMap.get(member.getPeerNodeID()); -// GroupMessage rMesg = listener.getNextMessageFrom(groups[0].getLocalNodeID()); -// assertTrue(cmpGCResultMessage((GCResultMessage) sMesg, (GCResultMessage) rMesg)); -// -// sMesg = createGCResultMessage(); -// member = getMember(groups[1], 0); -// groups[1].sendTo(member.getPeerNodeID(), sMesg); -// listener = listenerMap.get(member.getPeerNodeID()); -// rMesg = listener.getNextMessageFrom(groups[1].getLocalNodeID()); -// assertTrue(cmpGCResultMessage((GCResultMessage) sMesg, (GCResultMessage) rMesg)); -// -// // test with broadcast -// sMesg = createGCResultMessage(); -// groups[0].sendAll(sMesg); -// for (int i = 0; i < groups[0].size(); ++i) { -// TCGroupMember m = getMember(groups[0], i); -// TestGroupMessageListener l = listenerMap.get(m.getPeerNodeID()); -// rMesg = l.getNextMessageFrom(groups[0].getLocalNodeID()); -// assertTrue(cmpGCResultMessage((GCResultMessage) sMesg, (GCResultMessage) rMesg)); -// } -// -// ThreadUtil.reallySleep(200); -// tearGroups(); -// } private L2StateMessage createL2StateMessage() { long weights[] = new long[] { 1, 23, 44, 78 }; diff --git a/tc-server/src/test/java/com/tc/net/groups/TCGroupManagerNodeJoinedTest.java b/tc-server/src/test/java/com/tc/net/groups/TCGroupManagerNodeJoinedTest.java index f9a26251ce..97f0ca1ae9 100755 --- a/tc-server/src/test/java/com/tc/net/groups/TCGroupManagerNodeJoinedTest.java +++ b/tc-server/src/test/java/com/tc/net/groups/TCGroupManagerNodeJoinedTest.java @@ -39,6 +39,7 @@ import com.tc.util.concurrent.NoExceptionLinkedQueue; import com.tc.util.concurrent.ThreadUtil; import com.tc.util.runtime.ThreadDumpUtil; +import com.tc.util.version.DefaultVersionCompatibility; import java.io.IOException; import java.net.InetAddress; @@ -115,7 +116,7 @@ private void nodesSetupAndJoined(int nodes) throws Exception { for (int i = 0; i < nodes; ++i) { TCGroupManagerImpl gm = new TCGroupManagerImpl(new NullConnectionPolicy(), allNodes[i].getHost(), - allNodes[i].getPort(), allNodes[i].getGroupPort(), + allNodes[i].getPort(), allNodes[i].getGroupPort(), "TEST", new DefaultVersionCompatibility(), stages.createStageManager(), RandomWeightGenerator.createTestingFactory(2), mock(TopologyManager.class)); @@ -177,7 +178,7 @@ private void nodesSetupAndJoined_DEV3101(int nodes) throws Exception { for (int i = 0; i < nodes; ++i) { TCGroupManagerImpl gm = new TCGroupManagerImpl(new NullConnectionPolicy(), allNodes[i].getHost(), - allNodes[i].getPort(), allNodes[i].getGroupPort(), + allNodes[i].getPort(), allNodes[i].getGroupPort(), "TEST", new DefaultVersionCompatibility(), stages.createStageManager(), RandomWeightGenerator.createTestingFactory(2), mock(TopologyManager.class)); gm.setDiscover(new TCGroupMemberDiscoveryStatic(gm, allNodes[i])); diff --git a/tc-server/src/test/java/com/tc/objectserver/impl/ServerPersistenceVersionCheckerTest.java b/tc-server/src/test/java/com/tc/objectserver/impl/ServerPersistenceVersionCheckerTest.java deleted file mode 100644 index a964091357..0000000000 --- a/tc-server/src/test/java/com/tc/objectserver/impl/ServerPersistenceVersionCheckerTest.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * - * The contents of this file are subject to the Terracotta Public License Version - * 2.0 (the "License"); You may not use this file except in compliance with the - * License. You may obtain a copy of the License at - * - * http://terracotta.org/legal/terracotta-public-license. - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for - * the specific language governing rights and limitations under the License. - * - * The Covered Software is Terracotta Core. - * - * The Initial Developer of the Covered Software is - * Terracotta, Inc., a Software AG company - * - */ - -package com.tc.objectserver.impl; - -import com.tc.objectserver.persistence.ClusterStatePersistor; -import com.tc.productinfo.ProductInfo; -import com.tc.test.TCTestCase; -import com.tc.util.version.Version; -import org.junit.runner.RunWith; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * @author tim - */ -@RunWith(PowerMockRunner.class) -@PrepareForTest({ ProductInfo.class }) -public class ServerPersistenceVersionCheckerTest extends TCTestCase { - private ClusterStatePersistor clusterStatePersistor; - private ServerPersistenceVersionChecker serverPersistenceVersionChecker; - private ProductInfo productInfo; - - @Override - public void setUp() throws Exception { - clusterStatePersistor = mock(ClusterStatePersistor.class); - productInfo = mock(ProductInfo.class); - serverPersistenceVersionChecker = new ServerPersistenceVersionChecker(productInfo); - } - - public void testDotVersionBump() { - persistedVersion("1.0.0"); - currentVersion("1.0.1"); - verifyUpdatedTo("1.0.1"); - } - - public void testDotBumpToSnapshot() { - persistedVersion("1.0.0"); - currentVersion("1.0.1-SNAPSHOT"); - verifyUpdatedTo("1.0.1-SNAPSHOT"); - } - - public void testDotVersionDrop() { - currentVersion("1.0.0"); - persistedVersion("1.0.1"); - verifyNoUpdate(); - } - - public void testMinorVersionBump() { - currentVersion("1.1.0"); - persistedVersion("1.0.0"); - verifyUpdatedTo("1.1.0"); - } - - public void testMinorVersionDrop() { - currentVersion("1.0.0"); - persistedVersion("1.1.0"); - verifyNoUpdate(); - } - - public void testMajorVersionDrop() { - currentVersion("1.0.0"); - persistedVersion("2.0.0"); - verifyNoUpdate(); - } - - public void testMajorVersionBump() { - persistedVersion("1.0.0"); - currentVersion("2.0.0"); - verifyUpdatedTo("2.0.0"); - } - - public void testInitializeVersion() { - persistedVersion(null); - currentVersion("1.0.0"); - verifyUpdatedTo("1.0.0"); - } - - public void testUpdateDotVersion() { - currentVersion("1.0.1"); - persistedVersion("1.0.0"); - verifyUpdatedTo("1.0.1"); - } - - public void testDoNotOverwriteNewerVersion() { - currentVersion("1.0.0"); - persistedVersion("1.0.1"); - verifyNoUpdate(); - } - - private void currentVersion(String v) { - when(productInfo.version()).thenReturn(v); - } - - private void persistedVersion(String v) { - when(clusterStatePersistor.getVersion()).thenReturn(v == null ? null : new Version(v)); - } - - private void verifyUpdatedTo(String v) { - serverPersistenceVersionChecker.checkAndBumpPersistedVersion(clusterStatePersistor); - verify(clusterStatePersistor).setVersion(new Version(v)); - } - - private void verifyNoUpdate() { - serverPersistenceVersionChecker.checkAndBumpPersistedVersion(clusterStatePersistor); - verify(clusterStatePersistor, never()).setVersion(any(Version.class)); - } -}