44import io .grpc .Deadline ;
55import io .grpc .ManagedChannel ;
66import io .grpc .ManagedChannelBuilder ;
7- import io .qdrant .client .grpc .CollectionsGrpc ;
7+ import io .qdrant .client .grpc .* ;
88import io .qdrant .client .grpc .CollectionsGrpc .CollectionsFutureStub ;
9- import io .qdrant .client .grpc .PointsGrpc ;
109import io .qdrant .client .grpc .PointsGrpc .PointsFutureStub ;
11- import io .qdrant .client .grpc .QdrantGrpc ;
1210import io .qdrant .client .grpc .QdrantGrpc .QdrantFutureStub ;
13- import io .qdrant .client .grpc .SnapshotsGrpc ;
1411import io .qdrant .client .grpc .SnapshotsGrpc .SnapshotsFutureStub ;
1512import java .time .Duration ;
1613import java .util .concurrent .TimeUnit ;
@@ -45,7 +42,7 @@ public class QdrantGrpcClient implements AutoCloseable {
4542 * @return a new instance of {@link Builder}
4643 */
4744 public static Builder newBuilder (ManagedChannel channel ) {
48- return new Builder (channel , false );
45+ return new Builder (channel , false , true );
4946 }
5047
5148 /**
@@ -56,7 +53,21 @@ public static Builder newBuilder(ManagedChannel channel) {
5653 * @return a new instance of {@link Builder}
5754 */
5855 public static Builder newBuilder (ManagedChannel channel , boolean shutdownChannelOnClose ) {
59- return new Builder (channel , shutdownChannelOnClose );
56+ return new Builder (channel , shutdownChannelOnClose , true );
57+ }
58+
59+ /**
60+ * Creates a new builder to build a client.
61+ *
62+ * @param channel The channel for communication.
63+ * @param shutdownChannelOnClose Whether the channel is shutdown on client close.
64+ * @param checkCompatibility Whether to check compatibility between client's and server's
65+ * versions.
66+ * @return a new instance of {@link Builder}
67+ */
68+ public static Builder newBuilder (
69+ ManagedChannel channel , boolean shutdownChannelOnClose , boolean checkCompatibility ) {
70+ return new Builder (channel , shutdownChannelOnClose , checkCompatibility );
6071 }
6172
6273 /**
@@ -66,7 +77,7 @@ public static Builder newBuilder(ManagedChannel channel, boolean shutdownChannel
6677 * @return a new instance of {@link Builder}
6778 */
6879 public static Builder newBuilder (String host ) {
69- return new Builder (host , 6334 , true );
80+ return new Builder (host , 6334 , true , true );
7081 }
7182
7283 /**
@@ -77,7 +88,7 @@ public static Builder newBuilder(String host) {
7788 * @return a new instance of {@link Builder}
7889 */
7990 public static Builder newBuilder (String host , int port ) {
80- return new Builder (host , port , true );
91+ return new Builder (host , port , true , true );
8192 }
8293
8394 /**
@@ -90,7 +101,23 @@ public static Builder newBuilder(String host, int port) {
90101 * @return a new instance of {@link Builder}
91102 */
92103 public static Builder newBuilder (String host , int port , boolean useTransportLayerSecurity ) {
93- return new Builder (host , port , useTransportLayerSecurity );
104+ return new Builder (host , port , useTransportLayerSecurity , true );
105+ }
106+
107+ /**
108+ * Creates a new builder to build a client.
109+ *
110+ * @param host The host to connect to.
111+ * @param port The port to connect to.
112+ * @param useTransportLayerSecurity Whether the client uses Transport Layer Security (TLS) to
113+ * secure communications. Running without TLS should only be used for testing purposes.
114+ * @param checkCompatibility Whether to check compatibility between client's and server's
115+ * versions.
116+ * @return a new instance of {@link Builder}
117+ */
118+ public static Builder newBuilder (
119+ String host , int port , boolean useTransportLayerSecurity , boolean checkCompatibility ) {
120+ return new Builder (host , port , useTransportLayerSecurity , checkCompatibility );
94121 }
95122
96123 /**
@@ -168,17 +195,24 @@ public static class Builder {
168195 @ Nullable private CallCredentials callCredentials ;
169196 @ Nullable private Duration timeout ;
170197
171- Builder (ManagedChannel channel , boolean shutdownChannelOnClose ) {
198+ Builder (ManagedChannel channel , boolean shutdownChannelOnClose , boolean checkCompatibility ) {
172199 this .channel = channel ;
173200 this .shutdownChannelOnClose = shutdownChannelOnClose ;
201+ String clientVersion = Builder .class .getPackage ().getImplementationVersion ();
202+ if (checkCompatibility ) {
203+ checkVersionsCompatibility (clientVersion );
204+ }
174205 }
175206
176- Builder (String host , int port , boolean useTransportLayerSecurity ) {
207+ Builder (String host , int port , boolean useTransportLayerSecurity , boolean checkCompatibility ) {
177208 String clientVersion = Builder .class .getPackage ().getImplementationVersion ();
178209 String javaVersion = System .getProperty ("java.version" );
179210 String userAgent = "java-client/" + clientVersion + " java/" + javaVersion ;
180211 this .channel = createChannel (host , port , useTransportLayerSecurity , userAgent );
181212 this .shutdownChannelOnClose = true ;
213+ if (checkCompatibility ) {
214+ checkVersionsCompatibility (clientVersion );
215+ }
182216 }
183217
184218 /**
@@ -238,5 +272,27 @@ private static ManagedChannel createChannel(
238272
239273 return channelBuilder .build ();
240274 }
275+
276+ private void checkVersionsCompatibility (String clientVersion ) {
277+ try {
278+ String serverVersion =
279+ QdrantGrpc .newBlockingStub (this .channel )
280+ .healthCheck (QdrantOuterClass .HealthCheckRequest .getDefaultInstance ())
281+ .getVersion ();
282+ if (!VersionsCompatibilityChecker .isCompatible (clientVersion , serverVersion )) {
283+ String logMessage =
284+ "Qdrant client version "
285+ + clientVersion
286+ + " is incompatible with server version "
287+ + serverVersion
288+ + ". Major versions should match and minor version difference must not exceed 1. "
289+ + "Set checkCompatibility=false to skip version check." ;
290+ logger .warn (logMessage );
291+ }
292+ } catch (Exception e ) {
293+ logger .warn (
294+ "Failed to obtain server version. Unable to check client-server compatibility. Set checkCompatibility=false to skip version check." );
295+ }
296+ }
241297 }
242298}
0 commit comments