-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
238 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
96 changes: 96 additions & 0 deletions
96
src/main/java/io/qdrant/client/VersionsCompatibilityChecker.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package io.qdrant.client; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
class Version { | ||
private final int major; | ||
private final int minor; | ||
private final String rest; | ||
|
||
public Version(int major, int minor, String rest) { | ||
this.major = major; | ||
this.minor = minor; | ||
this.rest = rest; | ||
} | ||
|
||
public int getMajor() { | ||
return major; | ||
} | ||
|
||
public int getMinor() { | ||
return minor; | ||
} | ||
|
||
public String getRest() { | ||
return rest; | ||
} | ||
} | ||
|
||
/** Utility class to check compatibility between server's and client's versions. */ | ||
public class VersionsCompatibilityChecker { | ||
private static final Logger logger = LoggerFactory.getLogger(VersionsCompatibilityChecker.class); | ||
|
||
/** Default constructor. */ | ||
public VersionsCompatibilityChecker() {} | ||
|
||
private static Version parseVersion(String version) throws IllegalArgumentException { | ||
if (version.isEmpty()) { | ||
throw new IllegalArgumentException("Version is None"); | ||
} | ||
|
||
try { | ||
String[] parts = version.split("\\."); | ||
int major = parts.length > 0 ? Integer.parseInt(parts[0]) : 0; | ||
int minor = parts.length > 1 ? Integer.parseInt(parts[1]) : 0; | ||
String rest = | ||
parts.length > 2 | ||
? String.join(".", new ArrayList<>(Arrays.asList(parts).subList(2, parts.length))) | ||
: ""; | ||
|
||
return new Version(major, minor, rest); | ||
} catch (Exception e) { | ||
throw new IllegalArgumentException( | ||
"Unable to parse version, expected format: x.y.z, found: " + version, e); | ||
} | ||
} | ||
|
||
/** | ||
* Compares server's and client's versions. | ||
* | ||
* @param clientVersion The client's version. | ||
* @param serverVersion The server's version. | ||
* @return True if the versions are compatible, false otherwise. | ||
*/ | ||
public static boolean isCompatible(String clientVersion, String serverVersion) { | ||
if (clientVersion.isEmpty()) { | ||
logger.warn("Unable to compare with client version {}", clientVersion); | ||
return false; | ||
} | ||
|
||
if (serverVersion.isEmpty()) { | ||
logger.warn("Unable to compare with server version {}", serverVersion); | ||
return false; | ||
} | ||
|
||
if (clientVersion.equals(serverVersion)) { | ||
return true; | ||
} | ||
|
||
try { | ||
Version parsedServerVersion = parseVersion(serverVersion); | ||
Version parsedClientVersion = parseVersion(clientVersion); | ||
|
||
int majorDiff = Math.abs(parsedServerVersion.getMajor() - parsedClientVersion.getMajor()); | ||
if (majorDiff >= 1) { | ||
return false; | ||
} | ||
return Math.abs(parsedServerVersion.getMinor() - parsedClientVersion.getMinor()) <= 1; | ||
} catch (IllegalArgumentException e) { | ||
logger.warn("Unable to compare versions: {}", e.getMessage()); | ||
return false; | ||
} | ||
} | ||
} |
75 changes: 75 additions & 0 deletions
75
src/test/java/io/qdrant/client/VersionsCompatibilityCheckerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package io.qdrant.client; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertThrows; | ||
|
||
import java.lang.reflect.InvocationTargetException; | ||
import java.lang.reflect.Method; | ||
import java.util.stream.Stream; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.MethodSource; | ||
|
||
public class VersionsCompatibilityCheckerTest { | ||
private static Stream<Object[]> validVersionProvider() { | ||
return Stream.of( | ||
new Object[] {"1.2.3", 1, 2, "3"}, | ||
new Object[] {"1.2.3-alpha", 1, 2, "3-alpha"}, | ||
new Object[] {"1.2", 1, 2, ""}, | ||
new Object[] {"1", 1, 0, ""}, | ||
new Object[] {"1.", 1, 0, ""}); | ||
} | ||
|
||
@ParameterizedTest | ||
@MethodSource("validVersionProvider") | ||
public void testParseVersion_validVersion( | ||
String versionStr, int expectedMajor, int expectedMinor, String expectedRest) | ||
throws Exception { | ||
Method method = | ||
VersionsCompatibilityChecker.class.getDeclaredMethod("parseVersion", String.class); | ||
method.setAccessible(true); | ||
Version version = (Version) method.invoke(null, versionStr); | ||
assertEquals(expectedMajor, version.getMajor()); | ||
assertEquals(expectedMinor, version.getMinor()); | ||
assertEquals(expectedRest, version.getRest()); | ||
} | ||
|
||
private static Stream<String> invalidVersionProvider() { | ||
return Stream.of("v1.12.0", "", ".1", ".1.", "1.null.1", "null.0.1", null); | ||
} | ||
|
||
@ParameterizedTest | ||
@MethodSource("invalidVersionProvider") | ||
public void testParseVersion_invalidVersion(String versionStr) throws Exception { | ||
Method method = | ||
VersionsCompatibilityChecker.class.getDeclaredMethod("parseVersion", String.class); | ||
method.setAccessible(true); | ||
assertThrows( | ||
InvocationTargetException.class, | ||
() -> method.invoke(null, versionStr)); | ||
} | ||
|
||
private static Stream<Object[]> versionCompatibilityProvider() { | ||
return Stream.of( | ||
new Object[] {"1.9.3.dev0", "2.8.1.dev12-something", false}, | ||
new Object[] {"1.9", "2.8", false}, | ||
new Object[] {"1", "2", false}, | ||
new Object[] {"1.9.0", "2.9.0", false}, | ||
new Object[] {"1.1.0", "1.2.9", true}, | ||
new Object[] {"1.2.7", "1.1.8.dev0", true}, | ||
new Object[] {"1.2.1", "1.2.29", true}, | ||
new Object[] {"1.2.0", "1.2.0", true}, | ||
new Object[] {"1.2.0", "1.4.0", false}, | ||
new Object[] {"1.4.0", "1.2.0", false}, | ||
new Object[] {"1.9.0", "3.7.0", false}, | ||
new Object[] {"3.0.0", "1.0.0", false}, | ||
new Object[] {"", "1.0.0", false}, | ||
new Object[] {"1.0.0", "", false}, | ||
new Object[] {"", "", false}); | ||
} | ||
|
||
@ParameterizedTest | ||
@MethodSource("versionCompatibilityProvider") | ||
public void testIsCompatible(String clientVersion, String serverVersion, boolean expected) { | ||
assertEquals(expected, VersionsCompatibilityChecker.isCompatible(clientVersion, serverVersion)); | ||
} | ||
} |