From 80a8936c55ae333628e392a9a012313f50938328 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Mon, 18 Aug 2025 12:34:31 +0200 Subject: [PATCH 01/10] feat: apply default consistencyLevel to queries --- .../v1/api/collections/CollectionHandle.java | 42 +++++++--- .../collections/CollectionHandleAsync.java | 31 +++++++- .../collections/CollectionHandleDefaults.java | 45 +++++++++++ .../WeaviateCollectionsClient.java | 19 ++++- .../WeaviateCollectionsClientAsync.java | 13 +++- .../collections/data/WeaviateDataClient.java | 40 ++++++---- .../data/WeaviateDataClientAsync.java | 41 ++++++---- .../query/AbstractQueryClient.java | 78 +++++++++++++------ .../query/WeaviateQueryClient.java | 13 +++- .../query/WeaviateQueryClientAsync.java | 13 +++- .../CollectionHandleDefaultsTest.java | 52 +++++++++++++ 11 files changed, 315 insertions(+), 72 deletions(-) create mode 100644 src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleDefaults.java create mode 100644 src/test/java/io/weaviate/client6/v1/api/collections/CollectionHandleDefaultsTest.java diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandle.java b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandle.java index fb262cbc2..4233da870 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandle.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandle.java @@ -7,34 +7,50 @@ import io.weaviate.client6.v1.api.collections.config.WeaviateConfigClient; import io.weaviate.client6.v1.api.collections.data.WeaviateDataClient; import io.weaviate.client6.v1.api.collections.pagination.Paginator; +import io.weaviate.client6.v1.api.collections.query.ConsistencyLevel; import io.weaviate.client6.v1.api.collections.query.WeaviateQueryClient; import io.weaviate.client6.v1.internal.ObjectBuilder; import io.weaviate.client6.v1.internal.grpc.GrpcTransport; import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; import io.weaviate.client6.v1.internal.rest.RestTransport; -public class CollectionHandle { +public class CollectionHandle { public final WeaviateConfigClient config; - public final WeaviateDataClient data; - public final WeaviateQueryClient query; + public final WeaviateDataClient data; + public final WeaviateQueryClient query; public final WeaviateAggregateClient aggregate; + private final CollectionHandleDefaults defaults; + public CollectionHandle( RestTransport restTransport, GrpcTransport grpcTransport, - CollectionDescriptor collectionDescriptor) { - + CollectionDescriptor collectionDescriptor, + CollectionHandleDefaults defaults) { this.config = new WeaviateConfigClient(collectionDescriptor, restTransport, grpcTransport); - this.data = new WeaviateDataClient<>(collectionDescriptor, restTransport, grpcTransport); - this.query = new WeaviateQueryClient<>(collectionDescriptor, grpcTransport); this.aggregate = new WeaviateAggregateClient(collectionDescriptor, grpcTransport); + this.query = new WeaviateQueryClient<>(collectionDescriptor, grpcTransport, defaults); + this.data = new WeaviateDataClient<>(collectionDescriptor, restTransport, grpcTransport, query); + + this.defaults = defaults; + } + + /** Copy constructor that sets new defaults. */ + private CollectionHandle(CollectionHandle c, CollectionHandleDefaults defaults) { + this.config = c.config; + this.aggregate = c.aggregate; + this.query = new WeaviateQueryClient<>(c.query, defaults); + this.data = new WeaviateDataClient<>(c.data, query); + + this.defaults = defaults; } - public Paginator paginate() { + public Paginator paginate() { return Paginator.of(this.query); } - public Paginator paginate(Function, ObjectBuilder>> fn) { + public Paginator paginate( + Function, ObjectBuilder>> fn) { return Paginator.of(this.query, fn); } @@ -57,4 +73,12 @@ public Paginator paginate(Function, ObjectBuilder all.includeTotalCount(true)).totalCount(); } + + public ConsistencyLevel consistencyLevel() { + return defaults.consistencyLevel(); + } + + public CollectionHandle withConsistencyLevel(ConsistencyLevel consistencyLevel) { + return new CollectionHandle<>(this, CollectionHandleDefaults.of(def -> def.consistencyLevel(consistencyLevel))); + } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleAsync.java b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleAsync.java index 9a646d518..997067799 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleAsync.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleAsync.java @@ -9,6 +9,7 @@ import io.weaviate.client6.v1.api.collections.config.WeaviateConfigClientAsync; import io.weaviate.client6.v1.api.collections.data.WeaviateDataClientAsync; import io.weaviate.client6.v1.api.collections.pagination.AsyncPaginator; +import io.weaviate.client6.v1.api.collections.query.ConsistencyLevel; import io.weaviate.client6.v1.api.collections.query.WeaviateQueryClientAsync; import io.weaviate.client6.v1.internal.ObjectBuilder; import io.weaviate.client6.v1.internal.grpc.GrpcTransport; @@ -21,15 +22,30 @@ public class CollectionHandleAsync { public final WeaviateQueryClientAsync query; public final WeaviateAggregateClientAsync aggregate; + private final CollectionHandleDefaults defaults; + public CollectionHandleAsync( RestTransport restTransport, GrpcTransport grpcTransport, - CollectionDescriptor collectionDescriptor) { + CollectionDescriptor collectionDescriptor, + CollectionHandleDefaults defaults) { this.config = new WeaviateConfigClientAsync(collectionDescriptor, restTransport, grpcTransport); - this.data = new WeaviateDataClientAsync<>(collectionDescriptor, restTransport, grpcTransport); - this.query = new WeaviateQueryClientAsync<>(collectionDescriptor, grpcTransport); this.aggregate = new WeaviateAggregateClientAsync(collectionDescriptor, grpcTransport); + this.query = new WeaviateQueryClientAsync<>(collectionDescriptor, grpcTransport, defaults); + this.data = new WeaviateDataClientAsync<>(collectionDescriptor, restTransport, grpcTransport, query); + + this.defaults = defaults; + } + + /** Copy constructor that sets new defaults. */ + private CollectionHandleAsync(CollectionHandleAsync c, CollectionHandleDefaults defaults) { + this.config = c.config; + this.aggregate = c.aggregate; + this.query = new WeaviateQueryClientAsync<>(c.query, defaults); + this.data = new WeaviateDataClientAsync<>(c.data, query); + + this.defaults = defaults; } public AsyncPaginator paginate() { @@ -64,4 +80,13 @@ public CompletableFuture size() { return this.aggregate.overAll(all -> all.includeTotalCount(true)) .thenApply(AggregateResponse::totalCount); } + + public ConsistencyLevel consistencyLevel() { + return defaults.consistencyLevel(); + } + + public CollectionHandleAsync withConsistencyLevel(ConsistencyLevel consistencyLevel) { + return new CollectionHandleAsync<>(this, CollectionHandleDefaults.of( + def -> def.consistencyLevel(consistencyLevel))); + } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleDefaults.java b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleDefaults.java new file mode 100644 index 000000000..b1b549d1e --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleDefaults.java @@ -0,0 +1,45 @@ +package io.weaviate.client6.v1.api.collections; + +import java.util.function.Function; + +import io.weaviate.client6.v1.api.collections.query.ConsistencyLevel; +import io.weaviate.client6.v1.internal.ObjectBuilder; + +public record CollectionHandleDefaults(ConsistencyLevel consistencyLevel) { + /** + * Set default values for query / aggregation requests. + * + * @return CollectionHandleDefaults derived from applying {@code fn} to + * {@link Builder}. + */ + public static CollectionHandleDefaults of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + /** + * Empty collection defaults. + * + * @return An tucked builder that does not leaves all defaults unset. + */ + public static Function> none() { + return ObjectBuilder.identity(); + } + + public CollectionHandleDefaults(Builder builder) { + this(builder.consistencyLevel); + } + + public static final class Builder implements ObjectBuilder { + private ConsistencyLevel consistencyLevel; + + public Builder consistencyLevel(ConsistencyLevel consistencyLevel) { + this.consistencyLevel = consistencyLevel; + return this; + } + + @Override + public CollectionHandleDefaults build() { + return new CollectionHandleDefaults(this); + } + } +} diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/WeaviateCollectionsClient.java b/src/main/java/io/weaviate/client6/v1/api/collections/WeaviateCollectionsClient.java index d8c175692..f71d7e9e9 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/WeaviateCollectionsClient.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/WeaviateCollectionsClient.java @@ -29,7 +29,24 @@ public WeaviateCollectionsClient(RestTransport restTransport, GrpcTransport grpc * properties. */ public CollectionHandle> use(String collectionName) { - return new CollectionHandle<>(restTransport, grpcTransport, CollectionDescriptor.ofMap(collectionName)); + return use(collectionName, CollectionHandleDefaults.none()); + } + + /** + * Obtain a handle to send requests to a particular collection. + * The returned object is thread-safe. + * + * @return a handle for a collection with {@code Map} + * properties. + */ + public CollectionHandle> use( + String collectionName, + Function> fn) { + return new CollectionHandle<>( + restTransport, + grpcTransport, + CollectionDescriptor.ofMap(collectionName), + CollectionHandleDefaults.of(fn)); } /** diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/WeaviateCollectionsClientAsync.java b/src/main/java/io/weaviate/client6/v1/api/collections/WeaviateCollectionsClientAsync.java index d357d56cc..4fc449cf1 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/WeaviateCollectionsClientAsync.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/WeaviateCollectionsClientAsync.java @@ -22,8 +22,17 @@ public WeaviateCollectionsClientAsync(RestTransport restTransport, GrpcTransport } public CollectionHandleAsync> use(String collectionName) { - return new CollectionHandleAsync<>(restTransport, grpcTransport, - CollectionDescriptor.ofMap(collectionName)); + return use(collectionName, CollectionHandleDefaults.none()); + } + + public CollectionHandleAsync> use( + String collectionName, + Function> fn) { + return new CollectionHandleAsync<>( + restTransport, + grpcTransport, + CollectionDescriptor.ofMap(collectionName), + CollectionHandleDefaults.of(fn)); } public CompletableFuture create(String name) { diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClient.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClient.java index cb0771e0f..891db15e6 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClient.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClient.java @@ -15,46 +15,54 @@ import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; import io.weaviate.client6.v1.internal.rest.RestTransport; -public class WeaviateDataClient { +public class WeaviateDataClient { private final RestTransport restTransport; private final GrpcTransport grpcTransport; - private final CollectionDescriptor collectionDescriptor; + private final CollectionDescriptor collectionDescriptor; - private final WeaviateQueryClient query; + private final WeaviateQueryClient query; - public WeaviateDataClient(CollectionDescriptor collectionDescriptor, RestTransport restTransport, - GrpcTransport grpcTransport) { + public WeaviateDataClient(CollectionDescriptor collectionDescriptor, RestTransport restTransport, + GrpcTransport grpcTransport, WeaviateQueryClient query) { this.restTransport = restTransport; this.grpcTransport = grpcTransport; this.collectionDescriptor = collectionDescriptor; - this.query = new WeaviateQueryClient<>(collectionDescriptor, grpcTransport); + this.query = query; + } + /** Copy constructor that updates the {@link #query} to use new defaults. */ + public WeaviateDataClient(WeaviateDataClient c, WeaviateQueryClient query) { + this.restTransport = c.restTransport; + this.grpcTransport = c.grpcTransport; + this.collectionDescriptor = c.collectionDescriptor; + this.query = query; } - public WeaviateObject insert(T properties) throws IOException { + public WeaviateObject insert(PropertiesT properties) throws IOException { return insert(InsertObjectRequest.of(collectionDescriptor.name(), properties)); } - public WeaviateObject insert(T properties, - Function, ObjectBuilder>> fn) + public WeaviateObject insert(PropertiesT properties, + Function, ObjectBuilder>> fn) throws IOException { return insert(InsertObjectRequest.of(collectionDescriptor.name(), properties, fn)); } @SafeVarargs - public final InsertManyResponse insertMany(T... objects) { + public final InsertManyResponse insertMany(PropertiesT... objects) { return insertMany(InsertManyRequest.of(objects)); } - public InsertManyResponse insertMany(List> objects) { + public InsertManyResponse insertMany(List> objects) { return insertMany(new InsertManyRequest<>(objects)); } - public InsertManyResponse insertMany(InsertManyRequest request) { + public InsertManyResponse insertMany(InsertManyRequest request) { return this.grpcTransport.performRequest(request, InsertManyRequest.rpc(request.objects(), collectionDescriptor)); } - public WeaviateObject insert(InsertObjectRequest request) throws IOException { + public WeaviateObject insert(InsertObjectRequest request) + throws IOException { return this.restTransport.performRequest(request, InsertObjectRequest.endpoint(collectionDescriptor)); } @@ -62,13 +70,15 @@ public boolean exists(String uuid) throws IOException { return this.query.byId(uuid).isPresent(); } - public void update(String uuid, Function, ObjectBuilder>> fn) + public void update(String uuid, + Function, ObjectBuilder>> fn) throws IOException { this.restTransport.performRequest(UpdateObjectRequest.of(collectionDescriptor.name(), uuid, fn), UpdateObjectRequest.endpoint(collectionDescriptor)); } - public void replace(String uuid, Function, ObjectBuilder>> fn) + public void replace(String uuid, + Function, ObjectBuilder>> fn) throws IOException { this.restTransport.performRequest(ReplaceObjectRequest.of(collectionDescriptor.name(), uuid, fn), ReplaceObjectRequest.endpoint(collectionDescriptor)); diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientAsync.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientAsync.java index 506020b4b..197b0077d 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientAsync.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientAsync.java @@ -18,46 +18,57 @@ import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; import io.weaviate.client6.v1.internal.rest.RestTransport; -public class WeaviateDataClientAsync { +public class WeaviateDataClientAsync { private final RestTransport restTransport; private final GrpcTransport grpcTransport; - private final CollectionDescriptor collectionDescriptor; + private final CollectionDescriptor collectionDescriptor; - private final WeaviateQueryClientAsync query; + private final WeaviateQueryClientAsync query; - public WeaviateDataClientAsync(CollectionDescriptor collectionDescriptor, RestTransport restTransport, - GrpcTransport grpcTransport) { + public WeaviateDataClientAsync(CollectionDescriptor collectionDescriptor, RestTransport restTransport, + GrpcTransport grpcTransport, WeaviateQueryClientAsync query) { this.restTransport = restTransport; this.grpcTransport = grpcTransport; this.collectionDescriptor = collectionDescriptor; - this.query = new WeaviateQueryClientAsync<>(collectionDescriptor, grpcTransport); + this.query = query; } - public CompletableFuture> insert(T properties) throws IOException { + /** Copy constructor that updates the {@link #query} to use new defaults. */ + public WeaviateDataClientAsync(WeaviateDataClientAsync c, WeaviateQueryClientAsync query) { + this.restTransport = c.restTransport; + this.grpcTransport = c.grpcTransport; + this.collectionDescriptor = c.collectionDescriptor; + this.query = query; + } + + public CompletableFuture> insert(PropertiesT properties) + throws IOException { return insert(InsertObjectRequest.of(collectionDescriptor.name(), properties)); } - public CompletableFuture> insert(T properties, - Function, ObjectBuilder>> fn) + public CompletableFuture> insert(PropertiesT properties, + Function, ObjectBuilder>> fn) throws IOException { return insert(InsertObjectRequest.of(collectionDescriptor.name(), properties, fn)); } - public CompletableFuture> insert(InsertObjectRequest request) + public CompletableFuture> insert( + InsertObjectRequest request) throws IOException { return this.restTransport.performRequestAsync(request, InsertObjectRequest.endpoint(collectionDescriptor)); } @SafeVarargs - public final CompletableFuture insertMany(T... objects) { + public final CompletableFuture insertMany(PropertiesT... objects) { return insertMany(InsertManyRequest.of(objects)); } - public CompletableFuture insertMany(List> objects) { + public CompletableFuture insertMany( + List> objects) { return insertMany(new InsertManyRequest<>(objects)); } - public CompletableFuture insertMany(InsertManyRequest request) { + public CompletableFuture insertMany(InsertManyRequest request) { return this.grpcTransport.performRequestAsync(request, InsertManyRequest.rpc(request.objects(), collectionDescriptor)); } @@ -67,14 +78,14 @@ public CompletableFuture exists(String uuid) { } public CompletableFuture update(String uuid, - Function, ObjectBuilder>> fn) + Function, ObjectBuilder>> fn) throws IOException { return this.restTransport.performRequestAsync(UpdateObjectRequest.of(collectionDescriptor.name(), uuid, fn), UpdateObjectRequest.endpoint(collectionDescriptor)); } public CompletableFuture replace(String uuid, - Function, ObjectBuilder>> fn) + Function, ObjectBuilder>> fn) throws IOException { return this.restTransport.performRequestAsync(ReplaceObjectRequest.of(collectionDescriptor.name(), uuid, fn), ReplaceObjectRequest.endpoint(collectionDescriptor)); diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java index 0db66bd6b..8867e55d1 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java @@ -4,6 +4,8 @@ import java.util.Optional; import java.util.function.Function; +import io.weaviate.client6.v1.api.collections.CollectionHandle; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; import io.weaviate.client6.v1.internal.ObjectBuilder; import io.weaviate.client6.v1.internal.grpc.GrpcTransport; import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; @@ -12,9 +14,19 @@ abstract class AbstractQueryClient collection; protected final GrpcTransport grpcTransport; - AbstractQueryClient(CollectionDescriptor collection, GrpcTransport grpcTransport) { + private final CollectionHandleDefaults defaults; + + AbstractQueryClient(CollectionDescriptor collection, GrpcTransport grpcTransport, + CollectionHandleDefaults defaults) { this.collection = collection; this.grpcTransport = grpcTransport; + this.defaults = defaults; + } + + /** Copy constructor that sets new defaults. */ + AbstractQueryClient(AbstractQueryClient qc, + CollectionHandleDefaults defaults) { + this(qc.collection, qc.grpcTransport, defaults); } protected abstract SingleT byId(ById byId); @@ -23,6 +35,18 @@ abstract class AbstractQueryClient> Function> applyDefaults( + Function> fn) { + return ObjectBuilder.partial(fn, b -> b.consistencyLevel(defaults.consistencyLevel())); + } + // Fetch by ID -------------------------------------------------------------- public SingleT byId(String uuid) { @@ -30,9 +54,17 @@ public SingleT byId(String uuid) { } public SingleT byId(String uuid, Function> fn) { + // Collection handle defaults (consistencyLevel / tenant) are irrelevant for + // by-ID lookup. Do not `applyDefaults` to `fn`. return byId(ById.of(uuid, fn)); } + /** + * Retrieve the first result from query response if any. + * + * @param objects A list of objects, normally {@link QueryResponse#objects}. + * @return An object from the list or empty {@link Optional}. + */ protected final Optional optionalFirst(List objects) { return objects.isEmpty() ? Optional.empty() : Optional.ofNullable(objects.get(0)); } @@ -63,7 +95,7 @@ public ResponseT bm25(String query) { } public ResponseT bm25(String query, Function> fn) { - return bm25(Bm25.of(query, fn)); + return bm25(Bm25.of(query, applyDefaults(fn))); } public ResponseT bm25(Bm25 query) { @@ -75,7 +107,7 @@ public GroupedResponseT bm25(String query, GroupBy groupBy) { } public GroupedResponseT bm25(String query, Function> fn, GroupBy groupBy) { - return bm25(Bm25.of(query, fn), groupBy); + return bm25(Bm25.of(query, applyDefaults(fn)), groupBy); } public GroupedResponseT bm25(Bm25 query, GroupBy groupBy) { @@ -89,7 +121,7 @@ public ResponseT hybrid(String query) { } public ResponseT hybrid(String query, Function> fn) { - return hybrid(Hybrid.of(query, fn)); + return hybrid(Hybrid.of(query, applyDefaults(fn))); } public ResponseT hybrid(Hybrid query) { @@ -101,7 +133,7 @@ public GroupedResponseT hybrid(String query, GroupBy groupBy) { } public GroupedResponseT hybrid(String query, Function> fn, GroupBy groupBy) { - return hybrid(Hybrid.of(query, fn), groupBy); + return hybrid(Hybrid.of(query, applyDefaults(fn)), groupBy); } public GroupedResponseT hybrid(Hybrid query, GroupBy groupBy) { @@ -115,7 +147,7 @@ public ResponseT nearVector(float[] vector) { } public ResponseT nearVector(float[] vector, Function> fn) { - return nearVector(NearVector.of(vector, fn)); + return nearVector(NearVector.of(vector, applyDefaults(fn))); } public ResponseT nearVector(NearVector query) { @@ -128,7 +160,7 @@ public GroupedResponseT nearVector(float[] vector, GroupBy groupBy) { public GroupedResponseT nearVector(float[] vector, Function> fn, GroupBy groupBy) { - return nearVector(NearVector.of(vector, fn), groupBy); + return nearVector(NearVector.of(vector, applyDefaults(fn)), groupBy); } public GroupedResponseT nearVector(NearVector query, GroupBy groupBy) { @@ -142,7 +174,7 @@ public ResponseT nearObject(String uuid) { } public ResponseT nearObject(String uuid, Function> fn) { - return nearObject(NearObject.of(uuid, fn)); + return nearObject(NearObject.of(uuid, applyDefaults(fn))); } public ResponseT nearObject(NearObject query) { @@ -155,7 +187,7 @@ public GroupedResponseT nearObject(String uuid, GroupBy groupBy) { public GroupedResponseT nearObject(String uuid, Function> fn, GroupBy groupBy) { - return nearObject(NearObject.of(uuid, fn), groupBy); + return nearObject(NearObject.of(uuid, applyDefaults(fn)), groupBy); } public GroupedResponseT nearObject(NearObject query, GroupBy groupBy) { @@ -169,11 +201,11 @@ public ResponseT nearText(String... text) { } public ResponseT nearText(String text, Function> fn) { - return nearText(NearText.of(text, fn)); + return nearText(NearText.of(text, applyDefaults(fn))); } public ResponseT nearText(List text, Function> fn) { - return nearText(NearText.of(text, fn)); + return nearText(NearText.of(text, applyDefaults(fn))); } public ResponseT nearText(NearText query) { @@ -209,7 +241,7 @@ public ResponseT nearImage(String image) { } public ResponseT nearImage(String image, Function> fn) { - return nearImage(NearImage.of(image, fn)); + return nearImage(NearImage.of(image, applyDefaults(fn))); } public ResponseT nearImage(NearImage query) { @@ -222,7 +254,7 @@ public GroupedResponseT nearImage(String image, GroupBy groupBy) { public GroupedResponseT nearImage(String image, Function> fn, GroupBy groupBy) { - return nearImage(NearImage.of(image, fn), groupBy); + return nearImage(NearImage.of(image, applyDefaults(fn)), groupBy); } public GroupedResponseT nearImage(NearImage query, GroupBy groupBy) { @@ -236,7 +268,7 @@ public ResponseT nearAudio(String audio) { } public ResponseT nearAudio(String audio, Function> fn) { - return nearAudio(NearAudio.of(audio, fn)); + return nearAudio(NearAudio.of(audio, applyDefaults(fn))); } public ResponseT nearAudio(NearAudio query) { @@ -249,7 +281,7 @@ public GroupedResponseT nearAudio(String audio, GroupBy groupBy) { public GroupedResponseT nearAudio(String audio, Function> fn, GroupBy groupBy) { - return nearAudio(NearAudio.of(audio, fn), groupBy); + return nearAudio(NearAudio.of(audio, applyDefaults(fn)), groupBy); } public GroupedResponseT nearAudio(NearAudio query, GroupBy groupBy) { @@ -263,7 +295,7 @@ public ResponseT nearVideo(String video) { } public ResponseT nearVideo(String video, Function> fn) { - return nearVideo(NearVideo.of(video, fn)); + return nearVideo(NearVideo.of(video, applyDefaults(fn))); } public ResponseT nearVideo(NearVideo query) { @@ -276,7 +308,7 @@ public GroupedResponseT nearVideo(String video, GroupBy groupBy) { public GroupedResponseT nearVideo(String video, Function> fn, GroupBy groupBy) { - return nearVideo(NearVideo.of(video, fn), groupBy); + return nearVideo(NearVideo.of(video, applyDefaults(fn)), groupBy); } public GroupedResponseT nearVideo(NearVideo query, GroupBy groupBy) { @@ -290,7 +322,7 @@ public ResponseT nearThermal(String thermal) { } public ResponseT nearThermal(String thermal, Function> fn) { - return nearThermal(NearThermal.of(thermal, fn)); + return nearThermal(NearThermal.of(thermal, applyDefaults(fn))); } public ResponseT nearThermal(NearThermal query) { @@ -303,7 +335,7 @@ public GroupedResponseT nearThermal(String thermal, GroupBy groupBy) { public GroupedResponseT nearThermal(String thermal, Function> fn, GroupBy groupBy) { - return nearThermal(NearThermal.of(thermal, fn), groupBy); + return nearThermal(NearThermal.of(thermal, applyDefaults(fn)), groupBy); } public GroupedResponseT nearThermal(NearThermal query, GroupBy groupBy) { @@ -317,7 +349,7 @@ public ResponseT nearDepth(String depth) { } public ResponseT nearDepth(String depth, Function> fn) { - return nearDepth(NearDepth.of(depth, fn)); + return nearDepth(NearDepth.of(depth, applyDefaults(fn))); } public ResponseT nearDepth(NearDepth query) { @@ -330,7 +362,7 @@ public GroupedResponseT nearDepth(String depth, GroupBy groupBy) { public GroupedResponseT nearDepth(String depth, Function> fn, GroupBy groupBy) { - return nearDepth(NearDepth.of(depth, fn), groupBy); + return nearDepth(NearDepth.of(depth, applyDefaults(fn)), groupBy); } public GroupedResponseT nearDepth(NearDepth query, GroupBy groupBy) { @@ -344,7 +376,7 @@ public ResponseT nearImu(String imu) { } public ResponseT nearImu(String imu, Function> fn) { - return nearImu(NearImu.of(imu, fn)); + return nearImu(NearImu.of(imu, applyDefaults(fn))); } public ResponseT nearImu(NearImu query) { @@ -357,7 +389,7 @@ public GroupedResponseT nearImu(String imu, GroupBy groupBy) { public GroupedResponseT nearImu(String imu, Function> fn, GroupBy groupBy) { - return nearImu(NearImu.of(imu, fn), groupBy); + return nearImu(NearImu.of(imu, applyDefaults(fn)), groupBy); } public GroupedResponseT nearImu(NearImu query, GroupBy groupBy) { diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClient.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClient.java index 54801ca12..1fc48e7a4 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClient.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClient.java @@ -2,6 +2,7 @@ import java.util.Optional; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.internal.grpc.GrpcTransport; import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; @@ -10,8 +11,16 @@ public class WeaviateQueryClient extends AbstractQueryClient>, QueryResponse, QueryResponseGrouped> { - public WeaviateQueryClient(CollectionDescriptor collection, GrpcTransport grpcTransport) { - super(collection, grpcTransport); + public WeaviateQueryClient( + CollectionDescriptor collection, + GrpcTransport grpcTransport, + CollectionHandleDefaults defaults) { + super(collection, grpcTransport, defaults); + } + + /** Copy constructor that sets new defaults. */ + public WeaviateQueryClient(WeaviateQueryClient qc, CollectionHandleDefaults defaults) { + super(qc, defaults); } @Override diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientAsync.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientAsync.java index e8415314f..03c3fcbd5 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientAsync.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientAsync.java @@ -3,6 +3,7 @@ import java.util.Optional; import java.util.concurrent.CompletableFuture; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.internal.grpc.GrpcTransport; import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; @@ -11,8 +12,16 @@ public class WeaviateQueryClientAsync extends AbstractQueryClient>>, CompletableFuture>, CompletableFuture>> { - public WeaviateQueryClientAsync(CollectionDescriptor collection, GrpcTransport grpcTransport) { - super(collection, grpcTransport); + public WeaviateQueryClientAsync( + CollectionDescriptor collection, + GrpcTransport grpcTransport, + CollectionHandleDefaults defaults) { + super(collection, grpcTransport, defaults); + } + + /** Copy constructor that sets new defaults. */ + public WeaviateQueryClientAsync(WeaviateQueryClientAsync qc, CollectionHandleDefaults defaults) { + super(qc, defaults); } @Override diff --git a/src/test/java/io/weaviate/client6/v1/api/collections/CollectionHandleDefaultsTest.java b/src/test/java/io/weaviate/client6/v1/api/collections/CollectionHandleDefaultsTest.java new file mode 100644 index 000000000..1c1d1683f --- /dev/null +++ b/src/test/java/io/weaviate/client6/v1/api/collections/CollectionHandleDefaultsTest.java @@ -0,0 +1,52 @@ +package io.weaviate.client6.v1.api.collections; + +import java.util.Map; + +import org.assertj.core.api.Assertions; +import org.junit.Test; + +import io.weaviate.client6.v1.api.collections.query.ConsistencyLevel; +import io.weaviate.client6.v1.internal.ObjectBuilder; +import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; + +public class CollectionHandleDefaultsTest { + private static final CollectionDescriptor> DESCRIPTOR = CollectionDescriptor.ofMap("Things"); + + /** CollectionHandle with no defaults. */ + private static final CollectionHandle> HANDLE_NONE = new CollectionHandle<>( + null, null, + DESCRIPTOR, CollectionHandleDefaults.of(ObjectBuilder.identity())); + + /** CollectionHandleAsync with no defaults. */ + private static final CollectionHandleAsync> HANDLE_NONE_ASYNC = new CollectionHandleAsync<>( + null, null, + DESCRIPTOR, CollectionHandleDefaults.of(ObjectBuilder.identity())); + + /** All defaults are {@code null} if none were set. */ + @Test + public void test_defaults() { + Assertions.assertThat(HANDLE_NONE.consistencyLevel()).isNull(); + } + + /** + * {@link CollectionHandle#withConsistencyLevel} should create a copy with + * different defaults but not modify the original. + */ + @Test + public void test_withConsistencyLevel() { + var handle = HANDLE_NONE.withConsistencyLevel(ConsistencyLevel.QUORUM); + Assertions.assertThat(handle.consistencyLevel()).isEqualTo(ConsistencyLevel.QUORUM); + Assertions.assertThat(HANDLE_NONE.consistencyLevel()).isNull(); + } + + /** + * {@link CollectionHandleAsync#withConsistencyLevel} should create a copy with + * different defaults but not modify the original. + */ + @Test + public void test_withConsistencyLevel_async() { + var handle = HANDLE_NONE_ASYNC.withConsistencyLevel(ConsistencyLevel.QUORUM); + Assertions.assertThat(handle.consistencyLevel()).isEqualTo(ConsistencyLevel.QUORUM); + Assertions.assertThat(HANDLE_NONE_ASYNC.consistencyLevel()).isNull(); + } +} From ede84ab1a5f4c9b639c95ff146d333f3599ca20a Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Mon, 18 Aug 2025 13:25:43 +0200 Subject: [PATCH 02/10] fix: set consistencyLevel for pre-built QueryOperators E.g., when nearText is called with NearText.of() instead of a 'String queryTerm', consistencyLevel must be added on the RPC level. --- .../api/collections/query/AbstractQueryClient.java | 2 +- .../v1/api/collections/query/QueryOperator.java | 13 +++++++++++++ .../v1/api/collections/query/QueryRequest.java | 11 +++++++---- .../api/collections/query/WeaviateQueryClient.java | 6 +++--- .../collections/query/WeaviateQueryClientAsync.java | 6 +++--- 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java index 8867e55d1..77f17c389 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java @@ -14,7 +14,7 @@ abstract class AbstractQueryClient collection; protected final GrpcTransport grpcTransport; - private final CollectionHandleDefaults defaults; + protected final CollectionHandleDefaults defaults; AbstractQueryClient(CollectionDescriptor collection, GrpcTransport grpcTransport, CollectionHandleDefaults defaults) { diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryOperator.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryOperator.java index d7a3e4bb2..204c83a1e 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryOperator.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryOperator.java @@ -1,7 +1,20 @@ package io.weaviate.client6.v1.api.collections.query; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoSearchGet; interface QueryOperator { + /** Append QueryOperator to the request message. */ void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req); + + /** + * Append QueryOperator to the request message and apply default parameters. + * Implementations generally shouldn't override this method. + */ + default void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req, CollectionHandleDefaults defaults) { + appendTo(req); + if (!req.hasConsistencyLevel() && defaults.consistencyLevel() != null) { + defaults.consistencyLevel().appendTo(req); + } + } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryRequest.java index 22ebbfa7c..84d216812 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryRequest.java @@ -9,6 +9,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; import io.weaviate.client6.v1.api.collections.ObjectMetadata; import io.weaviate.client6.v1.api.collections.Vectors; import io.weaviate.client6.v1.api.collections.WeaviateObject; @@ -24,7 +25,8 @@ public record QueryRequest(QueryOperator operator, GroupBy groupBy) { static Rpc, WeaviateProtoSearchGet.SearchReply> rpc( - CollectionDescriptor collection) { + CollectionDescriptor collection, + CollectionHandleDefaults defaults) { return Rpc.of( request -> { var message = WeaviateProtoSearchGet.SearchRequest.newBuilder(); @@ -32,7 +34,7 @@ static Rpc Rpc Rpc, WeaviateProtoSearchGet.SearchReply> grouped( - CollectionDescriptor collection) { - var rpc = rpc(collection); + CollectionDescriptor collection, + CollectionHandleDefaults defaults) { + var rpc = rpc(collection, defaults); return Rpc.of( request -> rpc.marshal(request), reply -> { diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClient.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClient.java index 1fc48e7a4..0a51731b9 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClient.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClient.java @@ -26,7 +26,7 @@ public WeaviateQueryClient(WeaviateQueryClient qc, CollectionHandleDefaults d @Override protected Optional> byId(ById byId) { var request = new QueryRequest(byId, null); - var result = this.grpcTransport.performRequest(request, QueryRequest.rpc(collection)); + var result = this.grpcTransport.performRequest(request, QueryRequest.rpc(collection, defaults)); return optionalFirst(result.objects()); } @@ -34,13 +34,13 @@ protected Optional> byId(ById byId) { @Override protected final QueryResponse performRequest(QueryOperator operator) { var request = new QueryRequest(operator, null); - return this.grpcTransport.performRequest(request, QueryRequest.rpc(collection)); + return this.grpcTransport.performRequest(request, QueryRequest.rpc(collection, defaults)); } @Override protected final QueryResponseGrouped performRequest(QueryOperator operator, GroupBy groupBy) { var request = new QueryRequest(operator, groupBy); - return this.grpcTransport.performRequest(request, QueryRequest.grouped(collection)); + return this.grpcTransport.performRequest(request, QueryRequest.grouped(collection, defaults)); } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientAsync.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientAsync.java index 03c3fcbd5..f971a39e0 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientAsync.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientAsync.java @@ -28,20 +28,20 @@ public WeaviateQueryClientAsync(WeaviateQueryClientAsync qc, CollectionHandle protected CompletableFuture>> byId( ById byId) { var request = new QueryRequest(byId, null); - var result = this.grpcTransport.performRequestAsync(request, QueryRequest.rpc(collection)); + var result = this.grpcTransport.performRequestAsync(request, QueryRequest.rpc(collection, defaults)); return result.thenApply(r -> optionalFirst(r.objects())); } @Override protected final CompletableFuture> performRequest(QueryOperator operator) { var request = new QueryRequest(operator, null); - return this.grpcTransport.performRequestAsync(request, QueryRequest.rpc(collection)); + return this.grpcTransport.performRequestAsync(request, QueryRequest.rpc(collection, defaults)); } @Override protected final CompletableFuture> performRequest(QueryOperator operator, GroupBy groupBy) { var request = new QueryRequest(operator, groupBy); - return this.grpcTransport.performRequestAsync(request, QueryRequest.grouped(collection)); + return this.grpcTransport.performRequestAsync(request, QueryRequest.grouped(collection, defaults)); } } From ca05c311c01481dfcd7beae26a1290be47fa1cc6 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Mon, 18 Aug 2025 13:44:57 +0200 Subject: [PATCH 03/10] test: dry test setup --- .../v1/api/collections/CollectionHandleDefaultsTest.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/test/java/io/weaviate/client6/v1/api/collections/CollectionHandleDefaultsTest.java b/src/test/java/io/weaviate/client6/v1/api/collections/CollectionHandleDefaultsTest.java index 1c1d1683f..1c0d7aff2 100644 --- a/src/test/java/io/weaviate/client6/v1/api/collections/CollectionHandleDefaultsTest.java +++ b/src/test/java/io/weaviate/client6/v1/api/collections/CollectionHandleDefaultsTest.java @@ -11,16 +11,15 @@ public class CollectionHandleDefaultsTest { private static final CollectionDescriptor> DESCRIPTOR = CollectionDescriptor.ofMap("Things"); + private static final CollectionHandleDefaults NONE_DEFAULTS = CollectionHandleDefaults.of(ObjectBuilder.identity()); /** CollectionHandle with no defaults. */ private static final CollectionHandle> HANDLE_NONE = new CollectionHandle<>( - null, null, - DESCRIPTOR, CollectionHandleDefaults.of(ObjectBuilder.identity())); + null, null, DESCRIPTOR, NONE_DEFAULTS); /** CollectionHandleAsync with no defaults. */ private static final CollectionHandleAsync> HANDLE_NONE_ASYNC = new CollectionHandleAsync<>( - null, null, - DESCRIPTOR, CollectionHandleDefaults.of(ObjectBuilder.identity())); + null, null, DESCRIPTOR, NONE_DEFAULTS); /** All defaults are {@code null} if none were set. */ @Test From 4c881a59c405f2fd36e1d4f31d5b09ab98668ea3 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Tue, 19 Aug 2025 14:36:45 +0200 Subject: [PATCH 04/10] refactor: apply defaults at marshal --- .../query/AbstractQueryClient.java | 57 +++++++------------ 1 file changed, 22 insertions(+), 35 deletions(-) diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java index 77f17c389..b822c0d03 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java @@ -4,7 +4,6 @@ import java.util.Optional; import java.util.function.Function; -import io.weaviate.client6.v1.api.collections.CollectionHandle; import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; import io.weaviate.client6.v1.internal.ObjectBuilder; import io.weaviate.client6.v1.internal.grpc.GrpcTransport; @@ -35,18 +34,6 @@ abstract class AbstractQueryClient> Function> applyDefaults( - Function> fn) { - return ObjectBuilder.partial(fn, b -> b.consistencyLevel(defaults.consistencyLevel())); - } - // Fetch by ID -------------------------------------------------------------- public SingleT byId(String uuid) { @@ -95,7 +82,7 @@ public ResponseT bm25(String query) { } public ResponseT bm25(String query, Function> fn) { - return bm25(Bm25.of(query, applyDefaults(fn))); + return bm25(Bm25.of(query, fn)); } public ResponseT bm25(Bm25 query) { @@ -107,7 +94,7 @@ public GroupedResponseT bm25(String query, GroupBy groupBy) { } public GroupedResponseT bm25(String query, Function> fn, GroupBy groupBy) { - return bm25(Bm25.of(query, applyDefaults(fn)), groupBy); + return bm25(Bm25.of(query, fn), groupBy); } public GroupedResponseT bm25(Bm25 query, GroupBy groupBy) { @@ -121,7 +108,7 @@ public ResponseT hybrid(String query) { } public ResponseT hybrid(String query, Function> fn) { - return hybrid(Hybrid.of(query, applyDefaults(fn))); + return hybrid(Hybrid.of(query, fn)); } public ResponseT hybrid(Hybrid query) { @@ -133,7 +120,7 @@ public GroupedResponseT hybrid(String query, GroupBy groupBy) { } public GroupedResponseT hybrid(String query, Function> fn, GroupBy groupBy) { - return hybrid(Hybrid.of(query, applyDefaults(fn)), groupBy); + return hybrid(Hybrid.of(query, fn), groupBy); } public GroupedResponseT hybrid(Hybrid query, GroupBy groupBy) { @@ -147,7 +134,7 @@ public ResponseT nearVector(float[] vector) { } public ResponseT nearVector(float[] vector, Function> fn) { - return nearVector(NearVector.of(vector, applyDefaults(fn))); + return nearVector(NearVector.of(vector, fn)); } public ResponseT nearVector(NearVector query) { @@ -160,7 +147,7 @@ public GroupedResponseT nearVector(float[] vector, GroupBy groupBy) { public GroupedResponseT nearVector(float[] vector, Function> fn, GroupBy groupBy) { - return nearVector(NearVector.of(vector, applyDefaults(fn)), groupBy); + return nearVector(NearVector.of(vector, fn), groupBy); } public GroupedResponseT nearVector(NearVector query, GroupBy groupBy) { @@ -174,7 +161,7 @@ public ResponseT nearObject(String uuid) { } public ResponseT nearObject(String uuid, Function> fn) { - return nearObject(NearObject.of(uuid, applyDefaults(fn))); + return nearObject(NearObject.of(uuid, fn)); } public ResponseT nearObject(NearObject query) { @@ -187,7 +174,7 @@ public GroupedResponseT nearObject(String uuid, GroupBy groupBy) { public GroupedResponseT nearObject(String uuid, Function> fn, GroupBy groupBy) { - return nearObject(NearObject.of(uuid, applyDefaults(fn)), groupBy); + return nearObject(NearObject.of(uuid, fn), groupBy); } public GroupedResponseT nearObject(NearObject query, GroupBy groupBy) { @@ -201,11 +188,11 @@ public ResponseT nearText(String... text) { } public ResponseT nearText(String text, Function> fn) { - return nearText(NearText.of(text, applyDefaults(fn))); + return nearText(NearText.of(text, fn)); } public ResponseT nearText(List text, Function> fn) { - return nearText(NearText.of(text, applyDefaults(fn))); + return nearText(NearText.of(text, fn)); } public ResponseT nearText(NearText query) { @@ -241,7 +228,7 @@ public ResponseT nearImage(String image) { } public ResponseT nearImage(String image, Function> fn) { - return nearImage(NearImage.of(image, applyDefaults(fn))); + return nearImage(NearImage.of(image, fn)); } public ResponseT nearImage(NearImage query) { @@ -254,7 +241,7 @@ public GroupedResponseT nearImage(String image, GroupBy groupBy) { public GroupedResponseT nearImage(String image, Function> fn, GroupBy groupBy) { - return nearImage(NearImage.of(image, applyDefaults(fn)), groupBy); + return nearImage(NearImage.of(image, fn), groupBy); } public GroupedResponseT nearImage(NearImage query, GroupBy groupBy) { @@ -268,7 +255,7 @@ public ResponseT nearAudio(String audio) { } public ResponseT nearAudio(String audio, Function> fn) { - return nearAudio(NearAudio.of(audio, applyDefaults(fn))); + return nearAudio(NearAudio.of(audio, fn)); } public ResponseT nearAudio(NearAudio query) { @@ -281,7 +268,7 @@ public GroupedResponseT nearAudio(String audio, GroupBy groupBy) { public GroupedResponseT nearAudio(String audio, Function> fn, GroupBy groupBy) { - return nearAudio(NearAudio.of(audio, applyDefaults(fn)), groupBy); + return nearAudio(NearAudio.of(audio, fn), groupBy); } public GroupedResponseT nearAudio(NearAudio query, GroupBy groupBy) { @@ -295,7 +282,7 @@ public ResponseT nearVideo(String video) { } public ResponseT nearVideo(String video, Function> fn) { - return nearVideo(NearVideo.of(video, applyDefaults(fn))); + return nearVideo(NearVideo.of(video, fn)); } public ResponseT nearVideo(NearVideo query) { @@ -308,7 +295,7 @@ public GroupedResponseT nearVideo(String video, GroupBy groupBy) { public GroupedResponseT nearVideo(String video, Function> fn, GroupBy groupBy) { - return nearVideo(NearVideo.of(video, applyDefaults(fn)), groupBy); + return nearVideo(NearVideo.of(video, fn), groupBy); } public GroupedResponseT nearVideo(NearVideo query, GroupBy groupBy) { @@ -322,7 +309,7 @@ public ResponseT nearThermal(String thermal) { } public ResponseT nearThermal(String thermal, Function> fn) { - return nearThermal(NearThermal.of(thermal, applyDefaults(fn))); + return nearThermal(NearThermal.of(thermal, fn)); } public ResponseT nearThermal(NearThermal query) { @@ -335,7 +322,7 @@ public GroupedResponseT nearThermal(String thermal, GroupBy groupBy) { public GroupedResponseT nearThermal(String thermal, Function> fn, GroupBy groupBy) { - return nearThermal(NearThermal.of(thermal, applyDefaults(fn)), groupBy); + return nearThermal(NearThermal.of(thermal, fn), groupBy); } public GroupedResponseT nearThermal(NearThermal query, GroupBy groupBy) { @@ -349,7 +336,7 @@ public ResponseT nearDepth(String depth) { } public ResponseT nearDepth(String depth, Function> fn) { - return nearDepth(NearDepth.of(depth, applyDefaults(fn))); + return nearDepth(NearDepth.of(depth, fn)); } public ResponseT nearDepth(NearDepth query) { @@ -362,7 +349,7 @@ public GroupedResponseT nearDepth(String depth, GroupBy groupBy) { public GroupedResponseT nearDepth(String depth, Function> fn, GroupBy groupBy) { - return nearDepth(NearDepth.of(depth, applyDefaults(fn)), groupBy); + return nearDepth(NearDepth.of(depth, fn), groupBy); } public GroupedResponseT nearDepth(NearDepth query, GroupBy groupBy) { @@ -376,7 +363,7 @@ public ResponseT nearImu(String imu) { } public ResponseT nearImu(String imu, Function> fn) { - return nearImu(NearImu.of(imu, applyDefaults(fn))); + return nearImu(NearImu.of(imu, fn)); } public ResponseT nearImu(NearImu query) { @@ -389,7 +376,7 @@ public GroupedResponseT nearImu(String imu, GroupBy groupBy) { public GroupedResponseT nearImu(String imu, Function> fn, GroupBy groupBy) { - return nearImu(NearImu.of(imu, applyDefaults(fn)), groupBy); + return nearImu(NearImu.of(imu, fn), groupBy); } public GroupedResponseT nearImu(NearImu query, GroupBy groupBy) { From 239837cc78e033bc61a60e3662bba1287b763571 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Tue, 19 Aug 2025 14:56:47 +0200 Subject: [PATCH 05/10] feat: make delete/insertMany consistencyLevel-aware --- .../v1/api/collections/CollectionHandle.java | 4 ++-- .../collections/CollectionHandleAsync.java | 4 ++-- .../collections/data/DeleteManyRequest.java | 7 +++++- .../collections/data/InsertManyRequest.java | 8 ++++++- .../collections/data/WeaviateDataClient.java | 22 +++++++++++++------ .../data/WeaviateDataClientAsync.java | 21 ++++++++++++------ .../collections/query/ConsistencyLevel.java | 12 +++++++++- 7 files changed, 57 insertions(+), 21 deletions(-) diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandle.java b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandle.java index 4233da870..c5b081e02 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandle.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandle.java @@ -30,7 +30,7 @@ public CollectionHandle( this.config = new WeaviateConfigClient(collectionDescriptor, restTransport, grpcTransport); this.aggregate = new WeaviateAggregateClient(collectionDescriptor, grpcTransport); this.query = new WeaviateQueryClient<>(collectionDescriptor, grpcTransport, defaults); - this.data = new WeaviateDataClient<>(collectionDescriptor, restTransport, grpcTransport, query); + this.data = new WeaviateDataClient<>(collectionDescriptor, restTransport, grpcTransport, defaults); this.defaults = defaults; } @@ -40,7 +40,7 @@ private CollectionHandle(CollectionHandle c, CollectionHandleDefaul this.config = c.config; this.aggregate = c.aggregate; this.query = new WeaviateQueryClient<>(c.query, defaults); - this.data = new WeaviateDataClient<>(c.data, query); + this.data = new WeaviateDataClient<>(c.data, defaults); this.defaults = defaults; } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleAsync.java b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleAsync.java index 997067799..2cd669ebf 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleAsync.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleAsync.java @@ -33,7 +33,7 @@ public CollectionHandleAsync( this.config = new WeaviateConfigClientAsync(collectionDescriptor, restTransport, grpcTransport); this.aggregate = new WeaviateAggregateClientAsync(collectionDescriptor, grpcTransport); this.query = new WeaviateQueryClientAsync<>(collectionDescriptor, grpcTransport, defaults); - this.data = new WeaviateDataClientAsync<>(collectionDescriptor, restTransport, grpcTransport, query); + this.data = new WeaviateDataClientAsync<>(collectionDescriptor, restTransport, grpcTransport, defaults); this.defaults = defaults; } @@ -43,7 +43,7 @@ private CollectionHandleAsync(CollectionHandleAsync c, CollectionHa this.config = c.config; this.aggregate = c.aggregate; this.query = new WeaviateQueryClientAsync<>(c.query, defaults); - this.data = new WeaviateDataClientAsync<>(c.data, query); + this.data = new WeaviateDataClientAsync<>(c.data, defaults); this.defaults = defaults; } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/DeleteManyRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/DeleteManyRequest.java index fe4788481..e8067545f 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/DeleteManyRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/DeleteManyRequest.java @@ -2,6 +2,7 @@ import java.util.function.Function; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; import io.weaviate.client6.v1.api.collections.query.Where; import io.weaviate.client6.v1.internal.ObjectBuilder; import io.weaviate.client6.v1.internal.grpc.ByteStringUtil; @@ -15,7 +16,8 @@ public record DeleteManyRequest(Where where, Boolean verbose, Boolean dryRun) { public static Rpc rpc( - CollectionDescriptor collectionDescriptor) { + CollectionDescriptor collectionDescriptor, + CollectionHandleDefaults defaults) { return Rpc .of( request -> { @@ -28,6 +30,9 @@ public static Rpc InsertManyRequest of(T... properties) { public static Rpc, WeaviateProtoBatch.BatchObjectsRequest, InsertManyResponse, WeaviateProtoBatch.BatchObjectsReply> rpc( List> insertObjects, - CollectionDescriptor collectionsDescriptor) { + CollectionDescriptor collectionsDescriptor, + CollectionHandleDefaults defaults) { return Rpc.of( request -> { var message = WeaviateProtoBatch.BatchObjectsRequest.newBuilder(); @@ -48,6 +50,10 @@ public static Rpc, WeaviateProtoBatch.BatchObjectsReque return batchObject.build(); }).toList(); + if (defaults.consistencyLevel() != null) { + defaults.consistencyLevel().appendTo(message); + } + message.addAllObjects(batch); return message.build(); }, diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClient.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClient.java index 891db15e6..e720f62b8 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClient.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClient.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.function.Function; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; import io.weaviate.client6.v1.api.collections.ObjectMetadata; import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.api.collections.query.WeaviateQueryClient; @@ -21,21 +22,27 @@ public class WeaviateDataClient { private final CollectionDescriptor collectionDescriptor; private final WeaviateQueryClient query; + private final CollectionHandleDefaults defaults; - public WeaviateDataClient(CollectionDescriptor collectionDescriptor, RestTransport restTransport, - GrpcTransport grpcTransport, WeaviateQueryClient query) { + public WeaviateDataClient( + CollectionDescriptor collectionDescriptor, + RestTransport restTransport, + GrpcTransport grpcTransport, + CollectionHandleDefaults defaults) { this.restTransport = restTransport; this.grpcTransport = grpcTransport; this.collectionDescriptor = collectionDescriptor; - this.query = query; + this.query = new WeaviateQueryClient<>(collectionDescriptor, grpcTransport, defaults); + this.defaults = defaults; } /** Copy constructor that updates the {@link #query} to use new defaults. */ - public WeaviateDataClient(WeaviateDataClient c, WeaviateQueryClient query) { + public WeaviateDataClient(WeaviateDataClient c, CollectionHandleDefaults defaults) { this.restTransport = c.restTransport; this.grpcTransport = c.grpcTransport; this.collectionDescriptor = c.collectionDescriptor; - this.query = query; + this.query = new WeaviateQueryClient<>(collectionDescriptor, grpcTransport, defaults); + this.defaults = defaults; } public WeaviateObject insert(PropertiesT properties) throws IOException { @@ -58,7 +65,8 @@ public InsertManyResponse insertMany(List request) { - return this.grpcTransport.performRequest(request, InsertManyRequest.rpc(request.objects(), collectionDescriptor)); + return this.grpcTransport.performRequest(request, + InsertManyRequest.rpc(request.objects(), collectionDescriptor, defaults)); } public WeaviateObject insert(InsertObjectRequest request) @@ -107,7 +115,7 @@ public DeleteManyResponse deleteMany(Where where, } public DeleteManyResponse deleteMany(DeleteManyRequest request) throws IOException { - return this.grpcTransport.performRequest(request, DeleteManyRequest.rpc(collectionDescriptor)); + return this.grpcTransport.performRequest(request, DeleteManyRequest.rpc(collectionDescriptor, defaults)); } public void referenceAdd(String fromUuid, String fromProperty, Reference reference) throws IOException { diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientAsync.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientAsync.java index 197b0077d..7acd187c4 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientAsync.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientAsync.java @@ -8,6 +8,7 @@ import java.util.concurrent.CompletableFuture; import java.util.function.Function; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; import io.weaviate.client6.v1.api.collections.ObjectMetadata; import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.api.collections.query.WeaviateQueryClientAsync; @@ -24,21 +25,27 @@ public class WeaviateDataClientAsync { private final CollectionDescriptor collectionDescriptor; private final WeaviateQueryClientAsync query; + private final CollectionHandleDefaults defaults; - public WeaviateDataClientAsync(CollectionDescriptor collectionDescriptor, RestTransport restTransport, - GrpcTransport grpcTransport, WeaviateQueryClientAsync query) { + public WeaviateDataClientAsync( + CollectionDescriptor collectionDescriptor, + RestTransport restTransport, + GrpcTransport grpcTransport, + CollectionHandleDefaults defaults) { this.restTransport = restTransport; this.grpcTransport = grpcTransport; this.collectionDescriptor = collectionDescriptor; - this.query = query; + this.query = new WeaviateQueryClientAsync<>(collectionDescriptor, grpcTransport, defaults); + this.defaults = defaults; } /** Copy constructor that updates the {@link #query} to use new defaults. */ - public WeaviateDataClientAsync(WeaviateDataClientAsync c, WeaviateQueryClientAsync query) { + public WeaviateDataClientAsync(WeaviateDataClientAsync c, CollectionHandleDefaults defaults) { this.restTransport = c.restTransport; this.grpcTransport = c.grpcTransport; this.collectionDescriptor = c.collectionDescriptor; - this.query = query; + this.query = new WeaviateQueryClientAsync<>(collectionDescriptor, grpcTransport, defaults); + this.defaults = defaults; } public CompletableFuture> insert(PropertiesT properties) @@ -70,7 +77,7 @@ public CompletableFuture insertMany( public CompletableFuture insertMany(InsertManyRequest request) { return this.grpcTransport.performRequestAsync(request, - InsertManyRequest.rpc(request.objects(), collectionDescriptor)); + InsertManyRequest.rpc(request.objects(), collectionDescriptor, defaults)); } public CompletableFuture exists(String uuid) { @@ -114,7 +121,7 @@ public CompletableFuture deleteMany(Where where, } public CompletableFuture deleteMany(DeleteManyRequest request) throws IOException { - return this.grpcTransport.performRequestAsync(request, DeleteManyRequest.rpc(collectionDescriptor)); + return this.grpcTransport.performRequestAsync(request, DeleteManyRequest.rpc(collectionDescriptor, defaults)); } public CompletableFuture referenceAdd(String fromUuid, String fromProperty, Reference reference) { diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/ConsistencyLevel.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/ConsistencyLevel.java index 27cd30221..a73e38e45 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/ConsistencyLevel.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/ConsistencyLevel.java @@ -1,6 +1,8 @@ package io.weaviate.client6.v1.api.collections.query; import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBase; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBatch; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBatchDelete; import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoSearchGet; public enum ConsistencyLevel { @@ -14,7 +16,15 @@ public enum ConsistencyLevel { this.consistencyLevel = consistencyLevel; } - final void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req) { + public final void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req) { + req.setConsistencyLevel(consistencyLevel); + } + + public final void appendTo(WeaviateProtoBatchDelete.BatchDeleteRequest.Builder req) { + req.setConsistencyLevel(consistencyLevel); + } + + public final void appendTo(WeaviateProtoBatch.BatchObjectsRequest.Builder req) { req.setConsistencyLevel(consistencyLevel); } } From c35233041dc619512de5fd7e4348bbe69e959ee0 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Wed, 20 Aug 2025 12:45:01 +0200 Subject: [PATCH 06/10] feat: add default consistencyLevel to all methods in 'data' namespace --- .../collections/CollectionHandleDefaults.java | 168 ++++++++++++++++++ .../collections/data/DeleteManyRequest.java | 80 ++++----- .../collections/data/DeleteObjectRequest.java | 20 ++- .../collections/data/InsertManyRequest.java | 89 +++++----- .../collections/data/InsertObjectRequest.java | 27 +-- .../data/ReferenceAddManyRequest.java | 40 +++-- .../collections/data/ReferenceAddRequest.java | 19 +- .../data/ReferenceDeleteRequest.java | 18 +- .../data/ReferenceReplaceRequest.java | 18 +- .../data/ReplaceObjectRequest.java | 20 ++- .../collections/data/UpdateObjectRequest.java | 20 ++- .../collections/data/WeaviateDataClient.java | 49 +++-- .../data/WeaviateDataClientAsync.java | 68 ++++--- .../query/AbstractQueryClient.java | 10 +- .../collections/query/ConsistencyLevel.java | 15 +- .../query/WeaviateQueryClient.java | 2 +- .../query/WeaviateQueryClientAsync.java | 2 +- .../v1/internal/rest/BooleanEndpoint.java | 2 +- .../internal/rest/DefaultRestTransport.java | 25 +-- .../client6/v1/internal/rest/Endpoint.java | 2 +- .../v1/internal/rest/EndpointBase.java | 19 +- .../v1/internal/rest/OptionalEndpoint.java | 4 +- .../v1/internal/rest/SimpleEndpoint.java | 8 +- .../client6/v1/internal/rest/UrlEncoder.java | 27 +++ .../data/WeaviateDataClientTest.java | 164 +++++++++++++++++ .../client6/v1/internal/json/JSONTest.java | 1 + .../testutil/transport/MockGrpcTransport.java | 56 ++++++ .../testutil/transport/MockRestTransport.java | 55 ++++++ 28 files changed, 778 insertions(+), 250 deletions(-) create mode 100644 src/main/java/io/weaviate/client6/v1/internal/rest/UrlEncoder.java create mode 100644 src/test/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientTest.java create mode 100644 src/test/java/io/weaviate/testutil/transport/MockGrpcTransport.java create mode 100644 src/test/java/io/weaviate/testutil/transport/MockRestTransport.java diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleDefaults.java b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleDefaults.java index b1b549d1e..88e6c467f 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleDefaults.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleDefaults.java @@ -1,11 +1,26 @@ package io.weaviate.client6.v1.api.collections; +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiFunction; import java.util.function.Function; +import com.google.common.util.concurrent.ListenableFuture; + import io.weaviate.client6.v1.api.collections.query.ConsistencyLevel; import io.weaviate.client6.v1.internal.ObjectBuilder; +import io.weaviate.client6.v1.internal.grpc.Rpc; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateGrpc.WeaviateBlockingStub; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateGrpc.WeaviateFutureStub; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBatch; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBatchDelete; +import io.weaviate.client6.v1.internal.rest.Endpoint; +import io.weaviate.client6.v1.internal.rest.EndpointBase; +import io.weaviate.client6.v1.internal.rest.JsonEndpoint; public record CollectionHandleDefaults(ConsistencyLevel consistencyLevel) { + private static final String CONSISTENCY_LEVEL = "consistency_level"; + /** * Set default values for query / aggregation requests. * @@ -32,6 +47,7 @@ public CollectionHandleDefaults(Builder builder) { public static final class Builder implements ObjectBuilder { private ConsistencyLevel consistencyLevel; + /** Set default consistency level for this collection handle. */ public Builder consistencyLevel(ConsistencyLevel consistencyLevel) { this.consistencyLevel = consistencyLevel; return this; @@ -42,4 +58,156 @@ public CollectionHandleDefaults build() { return new CollectionHandleDefaults(this); } } + + public Endpoint endpoint(Endpoint ep, + Function, ObjectBuilder>> fn) { + return fn.apply(new EndpointBuilder<>(ep)).build(); + } + + public Rpc rpc( + Rpc rpc) { + return new ContextRpc<>(rpc); + } + + /** Which part of the request a parameter should be added to. */ + public static enum Location { + /** Query string. */ + QUERY, + /** + * Request body. {@code RequestT} must implement {@link WithDefaults} for the + * changes to be applied. + */ + BODY; + } + + public static interface WithDefaults> { + ConsistencyLevel consistencyLevel(); + + SelfT withConsistencyLevel(ConsistencyLevel consistencyLevel); + } + + private class ContextEndpoint extends EndpointBase + implements JsonEndpoint { + + private final Location consistencyLevelLoc; + private final Endpoint endpoint; + + ContextEndpoint(EndpointBuilder builder) { + super(builder.endpoint::method, + builder.endpoint::requestUrl, + builder.endpoint::queryParameters, + builder.endpoint::body); + this.consistencyLevelLoc = builder.consistencyLevelLoc; + this.endpoint = builder.endpoint; + } + + /** Return consistencyLevel of the enclosing CollectionHandleDefaults object. */ + private ConsistencyLevel consistencyLevel() { + return CollectionHandleDefaults.this.consistencyLevel; + } + + @Override + public Map queryParameters(RequestT request) { + // Copy the map, as it's most likely unmodifiable. + var query = new HashMap<>(super.queryParameters(request)); + if (consistencyLevel() != null && consistencyLevelLoc == Location.QUERY) { + query.putIfAbsent(CONSISTENCY_LEVEL, consistencyLevel()); + } + return query; + } + + @SuppressWarnings("unchecked") + @Override + public String body(RequestT request) { + if (request instanceof WithDefaults wd) { + if (wd.consistencyLevel() == null) { + wd = wd.withConsistencyLevel(consistencyLevel()); + } + // This cast is safe as long as `wd` returns its own type, + // which it does as per the interface contract. + request = (RequestT) wd; + } + return super.body(request); + } + + @Override + public ResponseT deserializeResponse(int statusCode, String responseBody) { + return EndpointBase.deserializeResponse(endpoint, statusCode, responseBody); + } + } + + /** + * EndpointBuilder configures how CollectionHandleDefautls + * are added to a REST request. + */ + public class EndpointBuilder implements ObjectBuilder> { + private final Endpoint endpoint; + + private Location consistencyLevelLoc; + + EndpointBuilder(Endpoint ep) { + this.endpoint = ep; + } + + /** Control which part of the request to add default consistency level to. */ + public EndpointBuilder consistencyLevel(Location loc) { + this.consistencyLevelLoc = loc; + return this; + } + + @Override + public Endpoint build() { + return new ContextEndpoint<>(this); + } + } + + private class ContextRpc + implements Rpc { + + private final Rpc rpc; + + ContextRpc(Rpc rpc) { + this.rpc = rpc; + } + + /** Return consistencyLevel of the enclosing CollectionHandleDefaults object. */ + private ConsistencyLevel consistencyLevel() { + return CollectionHandleDefaults.this.consistencyLevel; + } + + @SuppressWarnings("unchecked") + @Override + public RequestM marshal(RequestT request) { + var message = rpc.marshal(request); + if (message instanceof WeaviateProtoBatchDelete.BatchDeleteRequest msg) { + var b = msg.toBuilder(); + if (!msg.hasConsistencyLevel() && consistencyLevel() != null) { + consistencyLevel().appendTo(b); + return (RequestM) b.build(); + } + } else if (message instanceof WeaviateProtoBatch.BatchObjectsRequest msg) { + var b = msg.toBuilder(); + if (!msg.hasConsistencyLevel() && consistencyLevel() != null) { + consistencyLevel().appendTo(b); + return (RequestM) b.build(); + } + } + return message; + } + + @Override + public ResponseT unmarshal(ReplyM reply) { + return rpc.unmarshal(reply); + } + + @Override + public BiFunction method() { + return rpc.method(); + } + + @Override + public BiFunction> methodAsync() { + return rpc.methodAsync(); + } + } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/DeleteManyRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/DeleteManyRequest.java index e8067545f..5cbb64465 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/DeleteManyRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/DeleteManyRequest.java @@ -16,48 +16,46 @@ public record DeleteManyRequest(Where where, Boolean verbose, Boolean dryRun) { public static Rpc rpc( - CollectionDescriptor collectionDescriptor, + CollectionDescriptor collection, CollectionHandleDefaults defaults) { - return Rpc - .of( - request -> { - var message = WeaviateProtoBatchDelete.BatchDeleteRequest.newBuilder(); - message.setCollection(collectionDescriptor.name()); - - if (request.verbose != null) { - message.setVerbose(request.verbose); - } - if (request.dryRun != null) { - message.setDryRun(request.dryRun); - } - if (defaults.consistencyLevel() != null) { - defaults.consistencyLevel().appendTo(message); - } - - var filters = WeaviateProtoBase.Filters.newBuilder(); - request.where.appendTo(filters); - message.setFilters(filters); - - return message.build(); - }, - reply -> { - var objects = reply.getObjectsList() - .stream() - .map(obj -> new DeleteManyResponse.DeletedObject( - ByteStringUtil.decodeUuid(obj.getUuid()).toString(), - obj.getSuccessful(), - obj.getError())) - .toList(); - - return new DeleteManyResponse( - reply.getTook(), - reply.getFailed(), - reply.getMatches(), - reply.getSuccessful(), - objects); - }, - () -> WeaviateBlockingStub::batchDelete, - () -> WeaviateFutureStub::batchDelete); + return defaults.rpc( + Rpc + .of( + request -> { + var message = WeaviateProtoBatchDelete.BatchDeleteRequest.newBuilder(); + message.setCollection(collection.name()); + + if (request.verbose != null) { + message.setVerbose(request.verbose); + } + if (request.dryRun != null) { + message.setDryRun(request.dryRun); + } + + var filters = WeaviateProtoBase.Filters.newBuilder(); + request.where.appendTo(filters); + message.setFilters(filters); + + return message.build(); + }, + reply -> { + var objects = reply.getObjectsList() + .stream() + .map(obj -> new DeleteManyResponse.DeletedObject( + ByteStringUtil.decodeUuid(obj.getUuid()).toString(), + obj.getSuccessful(), + obj.getError())) + .toList(); + + return new DeleteManyResponse( + reply.getTook(), + reply.getFailed(), + reply.getMatches(), + reply.getSuccessful(), + objects); + }, + () -> WeaviateBlockingStub::batchDelete, + () -> WeaviateFutureStub::batchDelete)); } public static DeleteManyRequest of(Where where) { diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/DeleteObjectRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/DeleteObjectRequest.java index 217a27682..ecb2adb2d 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/DeleteObjectRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/DeleteObjectRequest.java @@ -2,13 +2,23 @@ import java.util.Collections; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults.Location; +import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; import io.weaviate.client6.v1.internal.rest.Endpoint; import io.weaviate.client6.v1.internal.rest.SimpleEndpoint; -public record DeleteObjectRequest(String collectionName, String uuid) { +public record DeleteObjectRequest(String uuid) { - public static final Endpoint _ENDPOINT = SimpleEndpoint.sideEffect( - request -> "DELETE", - request -> "/objects/" + request.collectionName + "/" + request.uuid, - request -> Collections.emptyMap()); + public static final Endpoint endpoint( + CollectionDescriptor collection, + CollectionHandleDefaults defaults) { + return defaults.endpoint( + SimpleEndpoint.sideEffect( + request -> "DELETE", + request -> "/objects/" + collection.name() + "/" + request.uuid, + request -> Collections.emptyMap()), + add -> add + .consistencyLevel(Location.QUERY)); + } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/InsertManyRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/InsertManyRequest.java index 062e720e0..d270fa336 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/InsertManyRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/InsertManyRequest.java @@ -40,53 +40,50 @@ public static Rpc, WeaviateProtoBatch.BatchObjectsReque List> insertObjects, CollectionDescriptor collectionsDescriptor, CollectionHandleDefaults defaults) { - return Rpc.of( - request -> { - var message = WeaviateProtoBatch.BatchObjectsRequest.newBuilder(); - - var batch = request.objects.stream().map(obj -> { - var batchObject = WeaviateProtoBatch.BatchObject.newBuilder(); - buildObject(batchObject, obj, collectionsDescriptor); - return batchObject.build(); - }).toList(); - - if (defaults.consistencyLevel() != null) { - defaults.consistencyLevel().appendTo(message); - } - - message.addAllObjects(batch); - return message.build(); - }, - response -> { - var insertErrors = response.getErrorsList(); - - var responses = new ArrayList(insertObjects.size()); - var errors = new ArrayList(insertErrors.size()); - var uuids = new ArrayList(); - - var failed = insertErrors.stream() - .collect(Collectors.toMap(err -> err.getIndex(), err -> err.getError())); - - var iter = insertObjects.listIterator(); - while (iter.hasNext()) { - var idx = iter.nextIndex(); - var next = iter.next(); - var uuid = next.metadata() != null ? next.metadata().uuid() : null; - - if (failed.containsKey(idx)) { - var err = failed.get(idx); - errors.add(err); - responses.add(new InsertManyResponse.InsertObject(uuid, false, err)); - } else { - uuids.add(uuid); - responses.add(new InsertManyResponse.InsertObject(uuid, true, null)); - } - } + return defaults.rpc( + Rpc.of( + request -> { + var message = WeaviateProtoBatch.BatchObjectsRequest.newBuilder(); + + var batch = request.objects.stream().map(obj -> { + var batchObject = WeaviateProtoBatch.BatchObject.newBuilder(); + buildObject(batchObject, obj, collectionsDescriptor); + return batchObject.build(); + }).toList(); + + message.addAllObjects(batch); + return message.build(); + }, + response -> { + var insertErrors = response.getErrorsList(); + + var responses = new ArrayList(insertObjects.size()); + var errors = new ArrayList(insertErrors.size()); + var uuids = new ArrayList(); + + var failed = insertErrors.stream() + .collect(Collectors.toMap(err -> err.getIndex(), err -> err.getError())); + + var iter = insertObjects.listIterator(); + while (iter.hasNext()) { + var idx = iter.nextIndex(); + var next = iter.next(); + var uuid = next.metadata() != null ? next.metadata().uuid() : null; + + if (failed.containsKey(idx)) { + var err = failed.get(idx); + errors.add(err); + responses.add(new InsertManyResponse.InsertObject(uuid, false, err)); + } else { + uuids.add(uuid); + responses.add(new InsertManyResponse.InsertObject(uuid, true, null)); + } + } - return new InsertManyResponse(response.getTook(), responses, uuids, errors); - }, - () -> WeaviateBlockingStub::batchObjects, - () -> WeaviateFutureStub::batchObjects); + return new InsertManyResponse(response.getTook(), responses, uuids, errors); + }, + () -> WeaviateBlockingStub::batchObjects, + () -> WeaviateFutureStub::batchObjects)); } public static void buildObject(WeaviateProtoBatch.BatchObject.Builder object, diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/InsertObjectRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/InsertObjectRequest.java index b1b460b11..97fecddc8 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/InsertObjectRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/InsertObjectRequest.java @@ -5,6 +5,8 @@ import com.google.gson.reflect.TypeToken; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults.Location; import io.weaviate.client6.v1.api.collections.ObjectMetadata; import io.weaviate.client6.v1.api.collections.Vectors; import io.weaviate.client6.v1.api.collections.WeaviateObject; @@ -18,16 +20,20 @@ public record InsertObjectRequest(WeaviateObject Endpoint, WeaviateObject> endpoint( - CollectionDescriptor descriptor) { - return new SimpleEndpoint<>( - request -> "POST", - request -> "/objects/", - request -> Collections.emptyMap(), - request -> JSON.serialize(request.object, TypeToken.getParameterized( - WeaviateObject.class, descriptor.typeToken().getType(), Reference.class, ObjectMetadata.class)), - (statusCode, response) -> JSON.deserialize(response, - (TypeToken>) TypeToken.getParameterized( - WeaviateObject.class, descriptor.typeToken().getType(), Object.class, ObjectMetadata.class))); + CollectionDescriptor collection, + CollectionHandleDefaults defaults) { + return defaults.endpoint( + new SimpleEndpoint<>( + request -> "POST", + request -> "/objects/", + request -> Collections.emptyMap(), + request -> JSON.serialize(request.object, TypeToken.getParameterized( + WeaviateObject.class, collection.typeToken().getType(), Reference.class, ObjectMetadata.class)), + (statusCode, response) -> JSON.deserialize(response, + (TypeToken>) TypeToken.getParameterized( + WeaviateObject.class, collection.typeToken().getType(), Object.class, ObjectMetadata.class))), + add -> add + .consistencyLevel(Location.QUERY)); } public static InsertObjectRequest of(String collectionName, T properties) { @@ -72,4 +78,5 @@ public InsertObjectRequest build() { return new InsertObjectRequest<>(this); } } + } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/ReferenceAddManyRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/ReferenceAddManyRequest.java index 0530d23e9..72b673bba 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/ReferenceAddManyRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/ReferenceAddManyRequest.java @@ -4,6 +4,8 @@ import java.util.Collections; import java.util.List; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults.Location; import io.weaviate.client6.v1.internal.json.JSON; import io.weaviate.client6.v1.internal.rest.Endpoint; import io.weaviate.client6.v1.internal.rest.SimpleEndpoint; @@ -11,24 +13,28 @@ public record ReferenceAddManyRequest(List references) { public static final Endpoint endpoint( - List references) { - return new SimpleEndpoint<>( - request -> "POST", - request -> "/batch/references", - request -> Collections.emptyMap(), - request -> JSON.serialize(request.references), - (statusCode, response) -> { - var result = JSON.deserialize(response, ReferenceAddManyResponse.class); - var errors = new ArrayList(); + List references, + CollectionHandleDefaults defaults) { + return defaults.endpoint( + new SimpleEndpoint<>( + request -> "POST", + request -> "/batch/references", + request -> Collections.emptyMap(), + request -> JSON.serialize(request.references), + (statusCode, response) -> { + var result = JSON.deserialize(response, ReferenceAddManyResponse.class); + var errors = new ArrayList(); - for (var err : result.errors()) { - errors.add(new ReferenceAddManyResponse.BatchError( - err.message(), - references.get(err.referenceIndex()), - err.referenceIndex())); - } - return new ReferenceAddManyResponse(errors); - }); + for (var err : result.errors()) { + errors.add(new ReferenceAddManyResponse.BatchError( + err.message(), + references.get(err.referenceIndex()), + err.referenceIndex())); + } + return new ReferenceAddManyResponse(errors); + }), + add -> add + .consistencyLevel(Location.QUERY)); } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/ReferenceAddRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/ReferenceAddRequest.java index 5da29e0fe..5fea35c24 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/ReferenceAddRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/ReferenceAddRequest.java @@ -2,6 +2,8 @@ import java.util.Collections; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults.Location; import io.weaviate.client6.v1.internal.json.JSON; import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; import io.weaviate.client6.v1.internal.rest.Endpoint; @@ -10,11 +12,16 @@ public record ReferenceAddRequest(String fromUuid, String fromProperty, Reference reference) { public static final Endpoint endpoint( - CollectionDescriptor descriptor) { - return SimpleEndpoint.sideEffect( - request -> "POST", - request -> "/objects/" + descriptor.name() + "/" + request.fromUuid + "/references/" + request.fromProperty, - request -> Collections.emptyMap(), - request -> JSON.serialize(request.reference)); + CollectionDescriptor descriptor, + CollectionHandleDefaults defautls) { + return defautls.endpoint( + SimpleEndpoint.sideEffect( + request -> "POST", + request -> "/objects/" + descriptor.name() + "/" + request.fromUuid + "/references/" + request.fromProperty, + request -> Collections.emptyMap(), + request -> JSON.serialize(request.reference)), + add -> add + .consistencyLevel(Location.QUERY)); + } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/ReferenceDeleteRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/ReferenceDeleteRequest.java index f7f037e23..5038e0812 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/ReferenceDeleteRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/ReferenceDeleteRequest.java @@ -2,6 +2,8 @@ import java.util.Collections; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults.Location; import io.weaviate.client6.v1.internal.json.JSON; import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; import io.weaviate.client6.v1.internal.rest.Endpoint; @@ -10,11 +12,15 @@ public record ReferenceDeleteRequest(String fromUuid, String fromProperty, Reference reference) { public static final Endpoint endpoint( - CollectionDescriptor descriptor) { - return SimpleEndpoint.sideEffect( - request -> "DELETE", - request -> "/objects/" + descriptor.name() + "/" + request.fromUuid + "/references/" + request.fromProperty, - request -> Collections.emptyMap(), - request -> JSON.serialize(request.reference)); + CollectionDescriptor descriptor, + CollectionHandleDefaults defaults) { + return defaults.endpoint( + SimpleEndpoint.sideEffect( + request -> "DELETE", + request -> "/objects/" + descriptor.name() + "/" + request.fromUuid + "/references/" + request.fromProperty, + request -> Collections.emptyMap(), + request -> JSON.serialize(request.reference)), + add -> add + .consistencyLevel(Location.QUERY)); } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/ReferenceReplaceRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/ReferenceReplaceRequest.java index 746fe6966..8d8aaf1e2 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/ReferenceReplaceRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/ReferenceReplaceRequest.java @@ -3,6 +3,8 @@ import java.util.Collections; import java.util.List; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults.Location; import io.weaviate.client6.v1.internal.json.JSON; import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; import io.weaviate.client6.v1.internal.rest.Endpoint; @@ -11,11 +13,15 @@ public record ReferenceReplaceRequest(String fromUuid, String fromProperty, Reference reference) { public static final Endpoint endpoint( - CollectionDescriptor descriptor) { - return SimpleEndpoint.sideEffect( - request -> "PUT", - request -> "/objects/" + descriptor.name() + "/" + request.fromUuid + "/references/" + request.fromProperty, - request -> Collections.emptyMap(), - request -> JSON.serialize(List.of(request.reference))); + CollectionDescriptor descriptor, + CollectionHandleDefaults defaults) { + return defaults.endpoint( + SimpleEndpoint.sideEffect( + request -> "PUT", + request -> "/objects/" + descriptor.name() + "/" + request.fromUuid + "/references/" + request.fromProperty, + request -> Collections.emptyMap(), + request -> JSON.serialize(List.of(request.reference))), + add -> add + .consistencyLevel(Location.QUERY)); } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/ReplaceObjectRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/ReplaceObjectRequest.java index 09704839b..1ecb5455c 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/ReplaceObjectRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/ReplaceObjectRequest.java @@ -5,6 +5,8 @@ import com.google.gson.reflect.TypeToken; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults.Location; import io.weaviate.client6.v1.api.collections.ObjectMetadata; import io.weaviate.client6.v1.api.collections.Vectors; import io.weaviate.client6.v1.api.collections.WeaviateObject; @@ -16,13 +18,17 @@ public record ReplaceObjectRequest(WeaviateObject object) { - static final Endpoint, Void> endpoint(CollectionDescriptor collectionDescriptor) { - return SimpleEndpoint.sideEffect( - request -> "PUT", - request -> "/objects/" + collectionDescriptor.name() + "/" + request.object.metadata().uuid(), - request -> Collections.emptyMap(), - request -> JSON.serialize(request.object, TypeToken.getParameterized( - WeaviateObject.class, collectionDescriptor.typeToken().getType(), Reference.class, ObjectMetadata.class))); + static final Endpoint, Void> endpoint(CollectionDescriptor collection, + CollectionHandleDefaults defaults) { + return defaults.endpoint( + SimpleEndpoint.sideEffect( + request -> "PUT", + request -> "/objects/" + collection.name() + "/" + request.object.metadata().uuid(), + request -> Collections.emptyMap(), + request -> JSON.serialize(request.object, TypeToken.getParameterized( + WeaviateObject.class, collection.typeToken().getType(), Reference.class, ObjectMetadata.class))), + add -> add + .consistencyLevel(Location.QUERY)); } public static ReplaceObjectRequest of(String collectionName, String uuid, diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/UpdateObjectRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/UpdateObjectRequest.java index f1f64022d..28423c752 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/UpdateObjectRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/UpdateObjectRequest.java @@ -5,6 +5,8 @@ import com.google.gson.reflect.TypeToken; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults.Location; import io.weaviate.client6.v1.api.collections.ObjectMetadata; import io.weaviate.client6.v1.api.collections.Vectors; import io.weaviate.client6.v1.api.collections.WeaviateObject; @@ -16,13 +18,17 @@ public record UpdateObjectRequest(WeaviateObject object) { - static final Endpoint, Void> endpoint(CollectionDescriptor collectionDescriptor) { - return SimpleEndpoint.sideEffect( - request -> "PATCH", - request -> "/objects/" + collectionDescriptor.name() + "/" + request.object.metadata().uuid(), - request -> Collections.emptyMap(), - request -> JSON.serialize(request.object, TypeToken.getParameterized( - WeaviateObject.class, collectionDescriptor.typeToken().getType(), Reference.class, ObjectMetadata.class))); + static final Endpoint, Void> endpoint(CollectionDescriptor collection, + CollectionHandleDefaults defaults) { + return defaults.endpoint( + SimpleEndpoint.sideEffect( + request -> "PATCH", + request -> "/objects/" + collection.name() + "/" + request.object.metadata().uuid(), + request -> Collections.emptyMap(), + request -> JSON.serialize(request.object, TypeToken.getParameterized( + WeaviateObject.class, collection.typeToken().getType(), Reference.class, ObjectMetadata.class))), + add -> add + .consistencyLevel(Location.QUERY)); } public static UpdateObjectRequest of(String collectionName, String uuid, diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClient.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClient.java index e720f62b8..6cda6883c 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClient.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClient.java @@ -19,7 +19,7 @@ public class WeaviateDataClient { private final RestTransport restTransport; private final GrpcTransport grpcTransport; - private final CollectionDescriptor collectionDescriptor; + private final CollectionDescriptor collection; private final WeaviateQueryClient query; private final CollectionHandleDefaults defaults; @@ -31,7 +31,7 @@ public WeaviateDataClient( CollectionHandleDefaults defaults) { this.restTransport = restTransport; this.grpcTransport = grpcTransport; - this.collectionDescriptor = collectionDescriptor; + this.collection = collectionDescriptor; this.query = new WeaviateQueryClient<>(collectionDescriptor, grpcTransport, defaults); this.defaults = defaults; } @@ -40,19 +40,19 @@ public WeaviateDataClient( public WeaviateDataClient(WeaviateDataClient c, CollectionHandleDefaults defaults) { this.restTransport = c.restTransport; this.grpcTransport = c.grpcTransport; - this.collectionDescriptor = c.collectionDescriptor; - this.query = new WeaviateQueryClient<>(collectionDescriptor, grpcTransport, defaults); + this.collection = c.collection; + this.query = new WeaviateQueryClient<>(collection, grpcTransport, defaults); this.defaults = defaults; } public WeaviateObject insert(PropertiesT properties) throws IOException { - return insert(InsertObjectRequest.of(collectionDescriptor.name(), properties)); + return insert(InsertObjectRequest.of(collection.name(), properties)); } public WeaviateObject insert(PropertiesT properties, Function, ObjectBuilder>> fn) throws IOException { - return insert(InsertObjectRequest.of(collectionDescriptor.name(), properties, fn)); + return insert(InsertObjectRequest.of(collection.name(), properties, fn)); } @SafeVarargs @@ -66,63 +66,62 @@ public InsertManyResponse insertMany(List request) { return this.grpcTransport.performRequest(request, - InsertManyRequest.rpc(request.objects(), collectionDescriptor, defaults)); + InsertManyRequest.rpc(request.objects(), collection, defaults)); } public WeaviateObject insert(InsertObjectRequest request) throws IOException { - return this.restTransport.performRequest(request, InsertObjectRequest.endpoint(collectionDescriptor)); + return this.restTransport.performRequest(request, InsertObjectRequest.endpoint(collection, defaults)); } - public boolean exists(String uuid) throws IOException { + public boolean exists(String uuid) { return this.query.byId(uuid).isPresent(); } public void update(String uuid, Function, ObjectBuilder>> fn) throws IOException { - this.restTransport.performRequest(UpdateObjectRequest.of(collectionDescriptor.name(), uuid, fn), - UpdateObjectRequest.endpoint(collectionDescriptor)); + this.restTransport.performRequest(UpdateObjectRequest.of(collection.name(), uuid, fn), + UpdateObjectRequest.endpoint(collection, defaults)); } public void replace(String uuid, Function, ObjectBuilder>> fn) throws IOException { - this.restTransport.performRequest(ReplaceObjectRequest.of(collectionDescriptor.name(), uuid, fn), - ReplaceObjectRequest.endpoint(collectionDescriptor)); + this.restTransport.performRequest(ReplaceObjectRequest.of(collection.name(), uuid, fn), + ReplaceObjectRequest.endpoint(collection, defaults)); } public void delete(String uuid) throws IOException { - this.restTransport.performRequest(new DeleteObjectRequest(collectionDescriptor.name(), uuid), - DeleteObjectRequest._ENDPOINT); + this.restTransport.performRequest(new DeleteObjectRequest(uuid), + DeleteObjectRequest.endpoint(collection, defaults)); } - public DeleteManyResponse deleteMany(String... uuids) throws IOException { + public DeleteManyResponse deleteMany(String... uuids) { var either = Arrays.stream(uuids) .map(uuid -> (WhereOperand) Where.uuid().eq(uuid)) .toList(); return deleteMany(DeleteManyRequest.of(Where.or(either))); } - public DeleteManyResponse deleteMany(Where where) throws IOException { + public DeleteManyResponse deleteMany(Where where) { return deleteMany(DeleteManyRequest.of(where)); } public DeleteManyResponse deleteMany(Where where, - Function> fn) - throws IOException { + Function> fn) { return deleteMany(DeleteManyRequest.of(where, fn)); } - public DeleteManyResponse deleteMany(DeleteManyRequest request) throws IOException { - return this.grpcTransport.performRequest(request, DeleteManyRequest.rpc(collectionDescriptor, defaults)); + public DeleteManyResponse deleteMany(DeleteManyRequest request) { + return this.grpcTransport.performRequest(request, DeleteManyRequest.rpc(collection, defaults)); } public void referenceAdd(String fromUuid, String fromProperty, Reference reference) throws IOException { for (var uuid : reference.uuids()) { var singleRef = new Reference(reference.collection(), uuid); this.restTransport.performRequest(new ReferenceAddRequest(fromUuid, fromProperty, singleRef), - ReferenceAddRequest.endpoint(collectionDescriptor)); + ReferenceAddRequest.endpoint(collection, defaults)); } } @@ -132,14 +131,14 @@ public ReferenceAddManyResponse referenceAddMany(BatchReference... references) t public ReferenceAddManyResponse referenceAddMany(List references) throws IOException { return this.restTransport.performRequest(new ReferenceAddManyRequest(references), - ReferenceAddManyRequest.endpoint(references)); + ReferenceAddManyRequest.endpoint(references, defaults)); } public void referenceDelete(String fromUuid, String fromProperty, Reference reference) throws IOException { for (var uuid : reference.uuids()) { var singleRef = new Reference(reference.collection(), uuid); this.restTransport.performRequest(new ReferenceDeleteRequest(fromUuid, fromProperty, singleRef), - ReferenceDeleteRequest.endpoint(collectionDescriptor)); + ReferenceDeleteRequest.endpoint(collection, defaults)); } } @@ -147,7 +146,7 @@ public void referenceReplace(String fromUuid, String fromProperty, Reference ref for (var uuid : reference.uuids()) { var singleRef = new Reference(reference.collection(), uuid); this.restTransport.performRequest(new ReferenceReplaceRequest(fromUuid, fromProperty, singleRef), - ReferenceReplaceRequest.endpoint(collectionDescriptor)); + ReferenceReplaceRequest.endpoint(collection, defaults)); } } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientAsync.java b/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientAsync.java index 7acd187c4..f85696a5f 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientAsync.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientAsync.java @@ -1,6 +1,5 @@ package io.weaviate.client6.v1.api.collections.data; -import java.io.IOException; import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -22,7 +21,7 @@ public class WeaviateDataClientAsync { private final RestTransport restTransport; private final GrpcTransport grpcTransport; - private final CollectionDescriptor collectionDescriptor; + private final CollectionDescriptor collection; private final WeaviateQueryClientAsync query; private final CollectionHandleDefaults defaults; @@ -34,7 +33,7 @@ public WeaviateDataClientAsync( CollectionHandleDefaults defaults) { this.restTransport = restTransport; this.grpcTransport = grpcTransport; - this.collectionDescriptor = collectionDescriptor; + this.collection = collectionDescriptor; this.query = new WeaviateQueryClientAsync<>(collectionDescriptor, grpcTransport, defaults); this.defaults = defaults; } @@ -43,26 +42,23 @@ public WeaviateDataClientAsync( public WeaviateDataClientAsync(WeaviateDataClientAsync c, CollectionHandleDefaults defaults) { this.restTransport = c.restTransport; this.grpcTransport = c.grpcTransport; - this.collectionDescriptor = c.collectionDescriptor; - this.query = new WeaviateQueryClientAsync<>(collectionDescriptor, grpcTransport, defaults); + this.collection = c.collection; + this.query = new WeaviateQueryClientAsync<>(collection, grpcTransport, defaults); this.defaults = defaults; } - public CompletableFuture> insert(PropertiesT properties) - throws IOException { - return insert(InsertObjectRequest.of(collectionDescriptor.name(), properties)); + public CompletableFuture> insert(PropertiesT properties) { + return insert(InsertObjectRequest.of(collection.name(), properties)); } public CompletableFuture> insert(PropertiesT properties, - Function, ObjectBuilder>> fn) - throws IOException { - return insert(InsertObjectRequest.of(collectionDescriptor.name(), properties, fn)); + Function, ObjectBuilder>> fn) { + return insert(InsertObjectRequest.of(collection.name(), properties, fn)); } public CompletableFuture> insert( - InsertObjectRequest request) - throws IOException { - return this.restTransport.performRequestAsync(request, InsertObjectRequest.endpoint(collectionDescriptor)); + InsertObjectRequest request) { + return this.restTransport.performRequestAsync(request, InsertObjectRequest.endpoint(collection, defaults)); } @SafeVarargs @@ -77,7 +73,7 @@ public CompletableFuture insertMany( public CompletableFuture insertMany(InsertManyRequest request) { return this.grpcTransport.performRequestAsync(request, - InsertManyRequest.rpc(request.objects(), collectionDescriptor, defaults)); + InsertManyRequest.rpc(request.objects(), collection, defaults)); } public CompletableFuture exists(String uuid) { @@ -85,68 +81,64 @@ public CompletableFuture exists(String uuid) { } public CompletableFuture update(String uuid, - Function, ObjectBuilder>> fn) - throws IOException { - return this.restTransport.performRequestAsync(UpdateObjectRequest.of(collectionDescriptor.name(), uuid, fn), - UpdateObjectRequest.endpoint(collectionDescriptor)); + Function, ObjectBuilder>> fn) { + return this.restTransport.performRequestAsync(UpdateObjectRequest.of(collection.name(), uuid, fn), + UpdateObjectRequest.endpoint(collection, defaults)); } public CompletableFuture replace(String uuid, - Function, ObjectBuilder>> fn) - throws IOException { - return this.restTransport.performRequestAsync(ReplaceObjectRequest.of(collectionDescriptor.name(), uuid, fn), - ReplaceObjectRequest.endpoint(collectionDescriptor)); + Function, ObjectBuilder>> fn) { + return this.restTransport.performRequestAsync(ReplaceObjectRequest.of(collection.name(), uuid, fn), + ReplaceObjectRequest.endpoint(collection, defaults)); } public CompletableFuture delete(String uuid) { - return this.restTransport.performRequestAsync(new DeleteObjectRequest(collectionDescriptor.name(), uuid), - DeleteObjectRequest._ENDPOINT); + return this.restTransport.performRequestAsync(new DeleteObjectRequest(uuid), + DeleteObjectRequest.endpoint(collection, defaults)); } - public CompletableFuture deleteMany(String... uuids) throws IOException { + public CompletableFuture deleteMany(String... uuids) { var either = Arrays.stream(uuids) .map(uuid -> (WhereOperand) Where.uuid().eq(uuid)) .toList(); return deleteMany(DeleteManyRequest.of(Where.or(either))); } - public CompletableFuture deleteMany(Where where) throws IOException { + public CompletableFuture deleteMany(Where where) { return deleteMany(DeleteManyRequest.of(where)); } public CompletableFuture deleteMany(Where where, - Function> fn) - throws IOException { + Function> fn) { return deleteMany(DeleteManyRequest.of(where, fn)); } - public CompletableFuture deleteMany(DeleteManyRequest request) throws IOException { - return this.grpcTransport.performRequestAsync(request, DeleteManyRequest.rpc(collectionDescriptor, defaults)); + public CompletableFuture deleteMany(DeleteManyRequest request) { + return this.grpcTransport.performRequestAsync(request, DeleteManyRequest.rpc(collection, defaults)); } public CompletableFuture referenceAdd(String fromUuid, String fromProperty, Reference reference) { return forEachAsync(reference.uuids(), uuid -> { var singleRef = new Reference(reference.collection(), (String) uuid); return this.restTransport.performRequestAsync(new ReferenceAddRequest(fromUuid, fromProperty, singleRef), - ReferenceAddRequest.endpoint(collectionDescriptor)); + ReferenceAddRequest.endpoint(collection, defaults)); }); } - public CompletableFuture referenceAddMany(BatchReference... references) throws IOException { + public CompletableFuture referenceAddMany(BatchReference... references) { return referenceAddMany(Arrays.asList(references)); } - public CompletableFuture referenceAddMany(List references) - throws IOException { + public CompletableFuture referenceAddMany(List references) { return this.restTransport.performRequestAsync(new ReferenceAddManyRequest(references), - ReferenceAddManyRequest.endpoint(references)); + ReferenceAddManyRequest.endpoint(references, defaults)); } public CompletableFuture referenceDelete(String fromUuid, String fromProperty, Reference reference) { return forEachAsync(reference.uuids(), uuid -> { var singleRef = new Reference(reference.collection(), (String) uuid); return this.restTransport.performRequestAsync(new ReferenceDeleteRequest(fromUuid, fromProperty, singleRef), - ReferenceDeleteRequest.endpoint(collectionDescriptor)); + ReferenceDeleteRequest.endpoint(collection, defaults)); }); } @@ -154,7 +146,7 @@ public CompletableFuture referenceReplace(String fromUuid, String fromProp return forEachAsync(reference.uuids(), uuid -> { var singleRef = new Reference(reference.collection(), (String) uuid); return this.restTransport.performRequestAsync(new ReferenceReplaceRequest(fromUuid, fromProperty, singleRef), - ReferenceReplaceRequest.endpoint(collectionDescriptor)); + ReferenceReplaceRequest.endpoint(collection, defaults)); }); } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java index b822c0d03..589a7f685 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java @@ -5,6 +5,7 @@ import java.util.function.Function; import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; +import io.weaviate.client6.v1.api.collections.WeaviateObject; import io.weaviate.client6.v1.internal.ObjectBuilder; import io.weaviate.client6.v1.internal.grpc.GrpcTransport; import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; @@ -49,11 +50,14 @@ public SingleT byId(String uuid, Function> fn) /** * Retrieve the first result from query response if any. * - * @param objects A list of objects, normally {@link QueryResponse#objects}. + * @param response Query response. * @return An object from the list or empty {@link Optional}. */ - protected final Optional optionalFirst(List objects) { - return objects.isEmpty() ? Optional.empty() : Optional.ofNullable(objects.get(0)); + protected final Optional> optionalFirst(QueryResponse response) { + return response == null || response.objects().isEmpty() + ? Optional.empty() + : Optional.ofNullable(response.objects().get(0)); + } // Object queries ----------------------------------------------------------- diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/ConsistencyLevel.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/ConsistencyLevel.java index a73e38e45..5ed88258f 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/ConsistencyLevel.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/ConsistencyLevel.java @@ -6,14 +6,16 @@ import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoSearchGet; public enum ConsistencyLevel { - ONE(WeaviateProtoBase.ConsistencyLevel.CONSISTENCY_LEVEL_ONE), - QUORUM(WeaviateProtoBase.ConsistencyLevel.CONSISTENCY_LEVEL_ONE), - ALL(WeaviateProtoBase.ConsistencyLevel.CONSISTENCY_LEVEL_ONE); + ONE(WeaviateProtoBase.ConsistencyLevel.CONSISTENCY_LEVEL_ONE, "ONE"), + QUORUM(WeaviateProtoBase.ConsistencyLevel.CONSISTENCY_LEVEL_ONE, "QUORUM"), + ALL(WeaviateProtoBase.ConsistencyLevel.CONSISTENCY_LEVEL_ONE, "ALL"); private final WeaviateProtoBase.ConsistencyLevel consistencyLevel; + private final String queryParameter; - ConsistencyLevel(WeaviateProtoBase.ConsistencyLevel consistencyLevel) { + ConsistencyLevel(WeaviateProtoBase.ConsistencyLevel consistencyLevel, String queryParameter) { this.consistencyLevel = consistencyLevel; + this.queryParameter = queryParameter; } public final void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req) { @@ -27,4 +29,9 @@ public final void appendTo(WeaviateProtoBatchDelete.BatchDeleteRequest.Builder r public final void appendTo(WeaviateProtoBatch.BatchObjectsRequest.Builder req) { req.setConsistencyLevel(consistencyLevel); } + + @Override + public String toString() { + return queryParameter; + } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClient.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClient.java index 0a51731b9..b80640b4a 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClient.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClient.java @@ -27,7 +27,7 @@ public WeaviateQueryClient(WeaviateQueryClient qc, CollectionHandleDefaults d protected Optional> byId(ById byId) { var request = new QueryRequest(byId, null); var result = this.grpcTransport.performRequest(request, QueryRequest.rpc(collection, defaults)); - return optionalFirst(result.objects()); + return optionalFirst(result); } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientAsync.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientAsync.java index f971a39e0..0c195e80d 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientAsync.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientAsync.java @@ -29,7 +29,7 @@ protected CompletableFuture>> ById byId) { var request = new QueryRequest(byId, null); var result = this.grpcTransport.performRequestAsync(request, QueryRequest.rpc(collection, defaults)); - return result.thenApply(r -> optionalFirst(r.objects())); + return result.thenApply(this::optionalFirst); } @Override diff --git a/src/main/java/io/weaviate/client6/v1/internal/rest/BooleanEndpoint.java b/src/main/java/io/weaviate/client6/v1/internal/rest/BooleanEndpoint.java index b0b20665e..a4e29b20f 100644 --- a/src/main/java/io/weaviate/client6/v1/internal/rest/BooleanEndpoint.java +++ b/src/main/java/io/weaviate/client6/v1/internal/rest/BooleanEndpoint.java @@ -8,7 +8,7 @@ public class BooleanEndpoint extends EndpointBase { public BooleanEndpoint( Function method, Function requestUrl, - Function> queryParameters, + Function> queryParameters, Function body) { super(method, requestUrl, queryParameters, body); } diff --git a/src/main/java/io/weaviate/client6/v1/internal/rest/DefaultRestTransport.java b/src/main/java/io/weaviate/client6/v1/internal/rest/DefaultRestTransport.java index bcd5a07ab..99d5bcb42 100644 --- a/src/main/java/io/weaviate/client6/v1/internal/rest/DefaultRestTransport.java +++ b/src/main/java/io/weaviate/client6/v1/internal/rest/DefaultRestTransport.java @@ -75,6 +75,12 @@ public DefaultRestTransport(RestTransportOptions transportOptions) { this.httpClientAsync.start(); } + private String uri(Endpoint ep, RequestT req) { + return transportOptions.baseUrl() + + ep.requestUrl(req) + + UrlEncoder.encodeQuery(ep.queryParameters(req)); + } + @Override public ResponseT performRequest(RequestT request, Endpoint endpoint) @@ -86,7 +92,7 @@ public ResponseT performRequest(RequestT reque private ClassicHttpRequest prepareClassicRequest(RequestT request, Endpoint endpoint) { var method = endpoint.method(request); - var uri = transportOptions.baseUrl() + endpoint.requestUrl(request); + var uri = uri(endpoint, request); // TODO: apply options; var req = ClassicRequestBuilder.create(method).setUri(uri); @@ -138,8 +144,7 @@ public void cancelled() { private SimpleHttpRequest prepareSimpleRequest(RequestT request, Endpoint endpoint) { var method = endpoint.method(request); - var uri = transportOptions.baseUrl() + endpoint.requestUrl(request); - // TODO: apply options; + var uri = uri(endpoint, request); var body = endpoint.body(request); var req = SimpleHttpRequest.create(method, uri); @@ -166,19 +171,7 @@ private ResponseT _handleResponse(Endpoint endpoint, S var message = endpoint.deserializeError(statusCode, body); throw WeaviateApiException.http(method, url, statusCode, message); } - - if (endpoint instanceof JsonEndpoint json) { - @SuppressWarnings("unchecked") - ResponseT response = (ResponseT) json.deserializeResponse(statusCode, body); - return response; - } else if (endpoint instanceof BooleanEndpoint bool) { - @SuppressWarnings("unchecked") - ResponseT response = (ResponseT) ((Boolean) bool.getResult(statusCode)); - return response; - } - - // TODO: make it a WeaviateTransportException - throw new RuntimeException("Unhandled endpoint type " + endpoint.getClass().getSimpleName()); + return EndpointBase.deserializeResponse(endpoint, statusCode, body); } @Override diff --git a/src/main/java/io/weaviate/client6/v1/internal/rest/Endpoint.java b/src/main/java/io/weaviate/client6/v1/internal/rest/Endpoint.java index 52cc37c3b..6e1e33760 100644 --- a/src/main/java/io/weaviate/client6/v1/internal/rest/Endpoint.java +++ b/src/main/java/io/weaviate/client6/v1/internal/rest/Endpoint.java @@ -10,7 +10,7 @@ public interface Endpoint { String body(RequestT request); - Map queryParameters(RequestT request); + Map queryParameters(RequestT request); /** Should this status code be considered an error? */ boolean isError(int statusCode); diff --git a/src/main/java/io/weaviate/client6/v1/internal/rest/EndpointBase.java b/src/main/java/io/weaviate/client6/v1/internal/rest/EndpointBase.java index 2ebe61d6d..d38622915 100644 --- a/src/main/java/io/weaviate/client6/v1/internal/rest/EndpointBase.java +++ b/src/main/java/io/weaviate/client6/v1/internal/rest/EndpointBase.java @@ -14,7 +14,7 @@ public abstract class EndpointBase implements Endpoint method; protected final Function requestUrl; protected final Function body; - protected final Function> queryParameters; + protected final Function> queryParameters; @SuppressWarnings("unchecked") protected static Function nullBody() { @@ -24,7 +24,7 @@ protected static Function nullBody() { public EndpointBase( Function method, Function requestUrl, - Function> queryParameters, + Function> queryParameters, Function body) { this.method = method; this.requestUrl = requestUrl; @@ -43,7 +43,7 @@ public String requestUrl(RequestT request) { } @Override - public Map queryParameters(RequestT request) { + public Map queryParameters(RequestT request) { return queryParameters.apply(request); } @@ -67,6 +67,19 @@ public String deserializeError(int statusCode, String responseBody) { return response.errors.get(0).text(); } + @SuppressWarnings("unchecked") + public static ResponseT deserializeResponse(Endpoint endpoint, int statusCode, + String responseBody) { + if (endpoint instanceof JsonEndpoint json) { + return (ResponseT) json.deserializeResponse(statusCode, responseBody); + } else if (endpoint instanceof BooleanEndpoint bool) { + return (ResponseT) ((Boolean) bool.getResult(statusCode)); + } + + // TODO: make it a WeaviateTransportException + throw new RuntimeException("Unhandled endpoint type " + endpoint.getClass().getSimpleName()); + } + static record ErrorResponse(@SerializedName("error") List errors) { private static record ErrorMessage(@SerializedName("message") String text) { } diff --git a/src/main/java/io/weaviate/client6/v1/internal/rest/OptionalEndpoint.java b/src/main/java/io/weaviate/client6/v1/internal/rest/OptionalEndpoint.java index 0b6052573..c3863bf97 100644 --- a/src/main/java/io/weaviate/client6/v1/internal/rest/OptionalEndpoint.java +++ b/src/main/java/io/weaviate/client6/v1/internal/rest/OptionalEndpoint.java @@ -10,7 +10,7 @@ public class OptionalEndpoint extends SimpleEndpoint OptionalEndpoint noBodyOptional( Function method, Function requestUrl, - Function> queryParameters, + Function> queryParameters, BiFunction deserializeResponse) { return new OptionalEndpoint<>(method, requestUrl, queryParameters, nullBody(), deserializeResponse); } @@ -18,7 +18,7 @@ public static OptionalEndpoint noBody public OptionalEndpoint( Function method, Function requestUrl, - Function> queryParameters, + Function> queryParameters, Function body, BiFunction deserializeResponse) { super(method, requestUrl, queryParameters, body, optional(deserializeResponse)); diff --git a/src/main/java/io/weaviate/client6/v1/internal/rest/SimpleEndpoint.java b/src/main/java/io/weaviate/client6/v1/internal/rest/SimpleEndpoint.java index 9f5c6fa9c..963cf4e3a 100644 --- a/src/main/java/io/weaviate/client6/v1/internal/rest/SimpleEndpoint.java +++ b/src/main/java/io/weaviate/client6/v1/internal/rest/SimpleEndpoint.java @@ -17,7 +17,7 @@ protected static BiFunction nullResponse() { public static SimpleEndpoint noBody( Function method, Function requestUrl, - Function> queryParameters, + Function> queryParameters, BiFunction deserializeResponse) { return new SimpleEndpoint<>(method, requestUrl, queryParameters, nullBody(), deserializeResponse); } @@ -25,7 +25,7 @@ public static SimpleEndpoint noBody( public static SimpleEndpoint sideEffect( Function method, Function requestUrl, - Function> queryParameters, + Function> queryParameters, Function body) { return new SimpleEndpoint<>(method, requestUrl, queryParameters, body, nullResponse()); } @@ -33,14 +33,14 @@ public static SimpleEndpoint sideEffect( public static SimpleEndpoint sideEffect( Function method, Function requestUrl, - Function> queryParameters) { + Function> queryParameters) { return new SimpleEndpoint<>(method, requestUrl, queryParameters, nullBody(), nullResponse()); } public SimpleEndpoint( Function method, Function requestUrl, - Function> queryParameters, + Function> queryParameters, Function body, BiFunction deserializeResponse) { super(method, requestUrl, queryParameters, body); diff --git a/src/main/java/io/weaviate/client6/v1/internal/rest/UrlEncoder.java b/src/main/java/io/weaviate/client6/v1/internal/rest/UrlEncoder.java new file mode 100644 index 000000000..9c0f5f6ee --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/internal/rest/UrlEncoder.java @@ -0,0 +1,27 @@ +package io.weaviate.client6.v1.internal.rest; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.Map; +import java.util.stream.Collectors; + +public final class UrlEncoder { + + private static String encodeValue(Object value) { + try { + return URLEncoder.encode(value.toString(), StandardCharsets.UTF_8.toString()); + } catch (UnsupportedEncodingException e) { + throw new AssertionError(e); // should never happen with a standard encoding + } + } + + public static String encodeQuery(Map queryParams) { + if (queryParams == null || queryParams.isEmpty()) { + return ""; + } + return queryParams.entrySet().stream() + .map(qp -> qp.getKey() + "=" + encodeValue(qp.getValue())) + .collect(Collectors.joining("&", "?", "")); + } +} diff --git a/src/test/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientTest.java b/src/test/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientTest.java new file mode 100644 index 000000000..0e9ae3baa --- /dev/null +++ b/src/test/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientTest.java @@ -0,0 +1,164 @@ +package io.weaviate.client6.v1.api.collections.data; + +import java.util.Map; + +import org.assertj.core.api.Assertions; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +import com.google.gson.JsonParser; +import com.jparams.junit4.JParamsTestRunner; +import com.jparams.junit4.data.DataMethod; +import com.jparams.junit4.description.Name; + +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults.Location; +import io.weaviate.client6.v1.api.collections.query.ConsistencyLevel; +import io.weaviate.client6.v1.internal.ObjectBuilder; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBase; +import io.weaviate.client6.v1.internal.json.JSON; +import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; +import io.weaviate.testutil.transport.MockGrpcTransport; +import io.weaviate.testutil.transport.MockRestTransport; + +@RunWith(JParamsTestRunner.class) +public class WeaviateDataClientTest { + private static MockRestTransport rest; + private static MockGrpcTransport grpc; + + @BeforeClass + public static void setUp() { + rest = new MockRestTransport(); + grpc = new MockGrpcTransport(); + } + + @AfterClass + public static void tearDown() throws Exception { + rest.close(); + grpc.close(); + } + + @FunctionalInterface + interface Act { + void apply(WeaviateDataClient> client) throws Exception; + } + + public static Object[][] restTestCases() { + return new Object[][] { + { + "insert single object", + ConsistencyLevel.ONE, Location.QUERY, + (Act) client -> client.insert(Map.of()), + }, + { + "replace single object", + ConsistencyLevel.ONE, Location.QUERY, + (Act) client -> client.replace("test-uuid", ObjectBuilder.identity()), + }, + { + "update single object", + ConsistencyLevel.ONE, Location.QUERY, + (Act) client -> client.update("test-uuid", ObjectBuilder.identity()), + }, + { + "delete by id", + ConsistencyLevel.ONE, Location.QUERY, + (Act) client -> client.delete("test-uuid"), + }, + { + "add reference", + ConsistencyLevel.ONE, Location.QUERY, + (Act) client -> client.referenceAdd("from-uuid", "from_property", Reference.uuids("to-uuid")), + }, + { + "add reference many", + ConsistencyLevel.ONE, Location.QUERY, + (Act) client -> client.referenceAddMany(), + }, + { + "replace reference", + ConsistencyLevel.ONE, Location.QUERY, + (Act) client -> client.referenceReplace("from-uuid", "from_property", Reference.uuids("to-uuid")), + }, + { + "delete reference", + ConsistencyLevel.ONE, Location.QUERY, + (Act) client -> client.referenceDelete("from-uuid", "from_property", Reference.uuids("to-uuid")), + }, + }; + } + + @Name("0") + @DataMethod(source = WeaviateDataClientTest.class, method = "restTestCases") + @Test + public void test_collectionHandleDefaults_rest(String __, ConsistencyLevel cl, Location clLoc, Act act) + throws Exception { + // Arrange + var collection = CollectionDescriptor.ofMap("Things"); + var defaults = new CollectionHandleDefaults(cl); + var client = new WeaviateDataClient>( + collection, rest, null, defaults); + + // Act + act.apply(client); + + // Assert + rest.assertNext((method, requestUrl, body, query) -> { + switch (clLoc) { + case QUERY: + Assertions.assertThat(query).containsEntry("consistency_level", defaults.consistencyLevel()); + break; + case BODY: + assertJsonHasValue(body, "consistency_level", defaults.consistencyLevel()); + } + }); + } + + private void assertJsonHasValue(String json, String key, T value) { + var gotJson = JsonParser.parseString(json).getAsJsonObject(); + Assertions.assertThat(gotJson.has(key)) + .describedAs("missing key \"%s\" in %s", key, json) + .isTrue(); + + var wantValue = JsonParser.parseString(JSON.serialize(value)); + Assertions.assertThat(gotJson.get(key)).isEqualTo(wantValue); + } + + public static Object[][] grpcTestCases() { + return new Object[][] { + { + "object exists", + (Act) client -> client.exists("test-uuid"), + }, + { + "insert many", + (Act) client -> client.insertMany(), + }, + { + "delete many", + (Act) client -> client.deleteMany(), + }, + }; + } + + @Name("0") + @DataMethod(source = WeaviateDataClientTest.class, method = "grpcTestCases") + @Test + public void test_collectionHandleDefaults_grpc(String __, Act act) + throws Exception { + // Arrange + var collection = CollectionDescriptor.ofMap("Things"); + var defaults = new CollectionHandleDefaults(ConsistencyLevel.ONE); + var client = new WeaviateDataClient>( + collection, null, grpc, defaults); + + // Act + act.apply(client); + + // Assert + grpc.assertNext(json -> assertJsonHasValue(json, "consistencyLevel", + WeaviateProtoBase.ConsistencyLevel.CONSISTENCY_LEVEL_ONE.toString())); + } +} diff --git a/src/test/java/io/weaviate/client6/v1/internal/json/JSONTest.java b/src/test/java/io/weaviate/client6/v1/internal/json/JSONTest.java index 56e189f2e..45607c4f4 100644 --- a/src/test/java/io/weaviate/client6/v1/internal/json/JSONTest.java +++ b/src/test/java/io/weaviate/client6/v1/internal/json/JSONTest.java @@ -345,6 +345,7 @@ public void test_serialize(Object cls, Object in, String want) { } + @FunctionalInterface private interface CustomAssert extends BiConsumer { } diff --git a/src/test/java/io/weaviate/testutil/transport/MockGrpcTransport.java b/src/test/java/io/weaviate/testutil/transport/MockGrpcTransport.java new file mode 100644 index 000000000..cb504d01b --- /dev/null +++ b/src/test/java/io/weaviate/testutil/transport/MockGrpcTransport.java @@ -0,0 +1,56 @@ +package io.weaviate.testutil.transport; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.MessageOrBuilder; +import com.google.protobuf.util.JsonFormat; + +import io.weaviate.client6.v1.internal.grpc.GrpcTransport; +import io.weaviate.client6.v1.internal.grpc.Rpc; + +public class MockGrpcTransport implements GrpcTransport { + + @FunctionalInterface + public interface AssertFunction { + void apply(String json); + } + + private List requests = new ArrayList<>(); + + public void assertNext(AssertFunction... assertions) { + var assertN = Math.min(assertions.length, requests.size()); + for (var i = 0; i < assertN; i++) { + var req = requests.get(i); + String json; + try { + json = JsonFormat.printer().print(req); + } catch (InvalidProtocolBufferException e) { + throw new RuntimeException(e); + } + assertions[i].apply(json); + } + requests.clear(); + } + + @Override + public ResponseT performRequest(RequestT request, + Rpc rpc) { + requests.add((MessageOrBuilder) rpc.marshal(request)); + return null; + } + + @Override + public CompletableFuture performRequestAsync(RequestT request, + Rpc rpc) { + requests.add((MessageOrBuilder) rpc.marshal(request)); + return null; + } + + @Override + public void close() throws IOException { + } +} diff --git a/src/test/java/io/weaviate/testutil/transport/MockRestTransport.java b/src/test/java/io/weaviate/testutil/transport/MockRestTransport.java new file mode 100644 index 000000000..c3cdf1234 --- /dev/null +++ b/src/test/java/io/weaviate/testutil/transport/MockRestTransport.java @@ -0,0 +1,55 @@ +package io.weaviate.testutil.transport; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; + +import io.weaviate.client6.v1.internal.rest.Endpoint; +import io.weaviate.client6.v1.internal.rest.RestTransport; + +public class MockRestTransport implements RestTransport { + + private record Request(String method, String requestUrl, String body, + Map queryParameters) { + + Request(RequestT req, Endpoint ep) { + this(ep.method(req), ep.requestUrl(req), ep.body(req), ep.queryParameters(req)); + } + } + + @FunctionalInterface + public interface AssertFunction { + void apply(String method, String requestUrl, String body, Map queryParameters); + } + + private List> requests = new ArrayList<>(); + + public void assertNext(AssertFunction... assertions) { + var assertN = Math.min(assertions.length, requests.size()); + for (var i = 0; i < assertN; i++) { + var req = requests.get(i); + assertions[i].apply(req.method, req.requestUrl, req.body, req.queryParameters); + } + requests.clear(); + } + + @Override + public ResponseT performRequest(RequestT request, + Endpoint endpoint) throws IOException { + requests.add(new Request<>(request, endpoint)); + return null; + } + + @Override + public CompletableFuture performRequestAsync(RequestT request, + Endpoint endpoint) { + requests.add(new Request<>(request, endpoint)); + return null; + } + + @Override + public void close() throws IOException { + } +} From fae80887a7fb24c69ef282fbabec478e6b5958fa Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Wed, 20 Aug 2025 15:19:09 +0200 Subject: [PATCH 07/10] feat: set default consistency in all 'query' requests --- .../v1/api/collections/CollectionHandle.java | 2 +- .../collections/CollectionHandleAsync.java | 2 +- .../collections/CollectionHandleDefaults.java | 12 +- .../aggregate/AbstractAggregateClient.java | 8 +- .../aggregate/WeaviateAggregateClient.java | 8 +- .../WeaviateAggregateClientAsync.java | 8 +- .../query/AbstractQueryClient.java | 1 - .../query/WeaviateQueryClientTest.java | 126 ++++++++++++++++++ 8 files changed, 157 insertions(+), 10 deletions(-) create mode 100644 src/test/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientTest.java diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandle.java b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandle.java index c5b081e02..c4c49737c 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandle.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandle.java @@ -28,7 +28,7 @@ public CollectionHandle( CollectionDescriptor collectionDescriptor, CollectionHandleDefaults defaults) { this.config = new WeaviateConfigClient(collectionDescriptor, restTransport, grpcTransport); - this.aggregate = new WeaviateAggregateClient(collectionDescriptor, grpcTransport); + this.aggregate = new WeaviateAggregateClient(collectionDescriptor, grpcTransport, defaults); this.query = new WeaviateQueryClient<>(collectionDescriptor, grpcTransport, defaults); this.data = new WeaviateDataClient<>(collectionDescriptor, restTransport, grpcTransport, defaults); diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleAsync.java b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleAsync.java index 2cd669ebf..dccc85dcd 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleAsync.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleAsync.java @@ -31,7 +31,7 @@ public CollectionHandleAsync( CollectionHandleDefaults defaults) { this.config = new WeaviateConfigClientAsync(collectionDescriptor, restTransport, grpcTransport); - this.aggregate = new WeaviateAggregateClientAsync(collectionDescriptor, grpcTransport); + this.aggregate = new WeaviateAggregateClientAsync(collectionDescriptor, grpcTransport, defaults); this.query = new WeaviateQueryClientAsync<>(collectionDescriptor, grpcTransport, defaults); this.data = new WeaviateDataClientAsync<>(collectionDescriptor, restTransport, grpcTransport, defaults); diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleDefaults.java b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleDefaults.java index 88e6c467f..5512b491d 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleDefaults.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionHandleDefaults.java @@ -14,6 +14,7 @@ import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateGrpc.WeaviateFutureStub; import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBatch; import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBatchDelete; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoSearchGet; import io.weaviate.client6.v1.internal.rest.Endpoint; import io.weaviate.client6.v1.internal.rest.EndpointBase; import io.weaviate.client6.v1.internal.rest.JsonEndpoint; @@ -179,19 +180,26 @@ private ConsistencyLevel consistencyLevel() { @Override public RequestM marshal(RequestT request) { var message = rpc.marshal(request); - if (message instanceof WeaviateProtoBatchDelete.BatchDeleteRequest msg) { + if (message instanceof WeaviateProtoBatch.BatchObjectsRequest msg) { var b = msg.toBuilder(); if (!msg.hasConsistencyLevel() && consistencyLevel() != null) { consistencyLevel().appendTo(b); return (RequestM) b.build(); } - } else if (message instanceof WeaviateProtoBatch.BatchObjectsRequest msg) { + } else if (message instanceof WeaviateProtoBatchDelete.BatchDeleteRequest msg) { + var b = msg.toBuilder(); + if (!msg.hasConsistencyLevel() && consistencyLevel() != null) { + consistencyLevel().appendTo(b); + return (RequestM) b.build(); + } + } else if (message instanceof WeaviateProtoSearchGet.SearchRequest msg) { var b = msg.toBuilder(); if (!msg.hasConsistencyLevel() && consistencyLevel() != null) { consistencyLevel().appendTo(b); return (RequestM) b.build(); } } + return message; } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AbstractAggregateClient.java b/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AbstractAggregateClient.java index 4258947bd..3b557a244 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AbstractAggregateClient.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/AbstractAggregateClient.java @@ -3,6 +3,7 @@ import java.util.List; import java.util.function.Function; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; import io.weaviate.client6.v1.api.collections.query.Hybrid; import io.weaviate.client6.v1.api.collections.query.NearAudio; import io.weaviate.client6.v1.api.collections.query.NearDepth; @@ -20,10 +21,15 @@ abstract class AbstractAggregateClient { protected final CollectionDescriptor collection; protected final GrpcTransport transport; + protected final CollectionHandleDefaults defaults; - AbstractAggregateClient(CollectionDescriptor collection, GrpcTransport transport) { + AbstractAggregateClient( + CollectionDescriptor collection, + GrpcTransport transport, + CollectionHandleDefaults defaults) { this.transport = transport; this.collection = collection; + this.defaults = defaults; } protected abstract ResponseT performRequest(Aggregation aggregation); diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/WeaviateAggregateClient.java b/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/WeaviateAggregateClient.java index 8f61720f4..aeb769e76 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/WeaviateAggregateClient.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/WeaviateAggregateClient.java @@ -1,12 +1,16 @@ package io.weaviate.client6.v1.api.collections.aggregate; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; import io.weaviate.client6.v1.internal.grpc.GrpcTransport; import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; public class WeaviateAggregateClient extends AbstractAggregateClient { - public WeaviateAggregateClient(CollectionDescriptor collection, GrpcTransport transport) { - super(collection, transport); + public WeaviateAggregateClient( + CollectionDescriptor collection, + GrpcTransport transport, + CollectionHandleDefaults defaults) { + super(collection, transport, defaults); } protected final AggregateResponse performRequest(Aggregation aggregation) { diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/WeaviateAggregateClientAsync.java b/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/WeaviateAggregateClientAsync.java index cdb138867..5a87cfdbc 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/WeaviateAggregateClientAsync.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/aggregate/WeaviateAggregateClientAsync.java @@ -2,14 +2,18 @@ import java.util.concurrent.CompletableFuture; +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; import io.weaviate.client6.v1.internal.grpc.GrpcTransport; import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; public class WeaviateAggregateClientAsync extends AbstractAggregateClient, CompletableFuture> { - public WeaviateAggregateClientAsync(CollectionDescriptor collection, GrpcTransport transport) { - super(collection, transport); + public WeaviateAggregateClientAsync( + CollectionDescriptor collection, + GrpcTransport transport, + CollectionHandleDefaults defaults) { + super(collection, transport, defaults); } protected final CompletableFuture performRequest(Aggregation aggregation) { diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java index 589a7f685..e24fbadcb 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/AbstractQueryClient.java @@ -13,7 +13,6 @@ abstract class AbstractQueryClient { protected final CollectionDescriptor collection; protected final GrpcTransport grpcTransport; - protected final CollectionHandleDefaults defaults; AbstractQueryClient(CollectionDescriptor collection, GrpcTransport grpcTransport, diff --git a/src/test/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientTest.java b/src/test/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientTest.java new file mode 100644 index 000000000..1145a25fc --- /dev/null +++ b/src/test/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientTest.java @@ -0,0 +1,126 @@ +package io.weaviate.client6.v1.api.collections.query; + +import java.util.Map; + +import org.assertj.core.api.Assertions; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +import com.google.gson.JsonParser; +import com.jparams.junit4.JParamsTestRunner; +import com.jparams.junit4.data.DataMethod; +import com.jparams.junit4.description.Name; + +import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; +import io.weaviate.client6.v1.internal.ObjectBuilder; +import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoBase; +import io.weaviate.client6.v1.internal.json.JSON; +import io.weaviate.client6.v1.internal.orm.CollectionDescriptor; +import io.weaviate.testutil.transport.MockGrpcTransport; + +@RunWith(JParamsTestRunner.class) +public class WeaviateQueryClientTest { + private static MockGrpcTransport grpc; + + @BeforeClass + public static void setUp() { + grpc = new MockGrpcTransport(); + } + + @AfterClass + public static void tearDown() throws Exception { + grpc.close(); + } + + @FunctionalInterface + interface Act { + void apply(WeaviateQueryClient> client) throws Exception; + } + + private void assertJsonHasValue(String json, String key, T value) { + var gotJson = JsonParser.parseString(json).getAsJsonObject(); + Assertions.assertThat(gotJson.has(key)) + .describedAs("missing key \"%s\" in %s", key, json) + .isTrue(); + + var wantValue = JsonParser.parseString(JSON.serialize(value)); + Assertions.assertThat(gotJson.get(key)).isEqualTo(wantValue); + } + + public static Object[][] grpcTestCases() { + return new Object[][] { + { + "get by id", + (Act) client -> client.byId("test-uuid") + }, + { + "fetch objects", + (Act) client -> client.fetchObjects(ObjectBuilder.identity()), + }, + { + "bm25", + (Act) client -> client.bm25("red ballon"), + }, + { + "hybrid", + (Act) client -> client.hybrid("red ballon"), + }, + { + "nearVector", + (Act) client -> client.nearVector(new float[] {}), + }, + { + "nearText", + (Act) client -> client.nearText("weather in Arizona"), + }, + { + "nearObject", + (Act) client -> client.nearObject("test-uuid"), + }, + { + "nearImage", + (Act) client -> client.nearImage("img.jpeg"), + }, + { + "nearAudio", + (Act) client -> client.nearAudio("song.mp3"), + }, + { + "nearVideo", + (Act) client -> client.nearVideo("clip.mp4"), + }, + { + "nearDepth", + (Act) client -> client.nearDepth("20.000 leagues"), + }, + { + "nearThermal", + (Act) client -> client.nearThermal("Fahrenheit 451"), + }, + { + "nearImu", + (Act) client -> client.nearImu("6 m/s"), + }, + }; + } + + @Name("0") + @DataMethod(source = WeaviateQueryClientTest.class, method = "grpcTestCases") + @Test + public void test_collectionHandleDefaults_grpc(String __, Act act) + throws Exception { + // Arrange + var collection = CollectionDescriptor.ofMap("Things"); + var defaults = new CollectionHandleDefaults(ConsistencyLevel.ONE); + var client = new WeaviateQueryClient>(collection, grpc, defaults); + + // Act + act.apply(client); + + // Assert + grpc.assertNext(json -> assertJsonHasValue(json, "consistencyLevel", + WeaviateProtoBase.ConsistencyLevel.CONSISTENCY_LEVEL_ONE.toString())); + } +} From 1a4aa2bed02023ab3d7a09562a6586b49f2991c0 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Wed, 20 Aug 2025 16:26:30 +0200 Subject: [PATCH 08/10] chore: remove unused imports --- .../java/io/weaviate/client6/v1/api/collections/Vectorizer.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/Vectorizer.java b/src/main/java/io/weaviate/client6/v1/api/collections/Vectorizer.java index b5b6c68bb..b0cc27d2e 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/Vectorizer.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/Vectorizer.java @@ -3,7 +3,6 @@ import java.io.IOException; import java.util.EnumMap; import java.util.Map; -import java.util.function.Function; import com.google.gson.Gson; import com.google.gson.JsonObject; @@ -20,7 +19,6 @@ import io.weaviate.client6.v1.api.collections.vectorizers.NoneVectorizer; import io.weaviate.client6.v1.api.collections.vectorizers.Text2VecContextionaryVectorizer; import io.weaviate.client6.v1.api.collections.vectorizers.Text2VecWeaviateVectorizer; -import io.weaviate.client6.v1.internal.ObjectBuilder; import io.weaviate.client6.v1.internal.json.JsonEnum; public interface Vectorizer { From 423268cd7e5147b9ab4a9cfc7bfec9cc5a0d9777 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Wed, 20 Aug 2025 17:03:55 +0200 Subject: [PATCH 09/10] chore: format test cases --- .../data/WeaviateDataClientTest.java | 15 +---- .../query/WeaviateQueryClientTest.java | 65 ++++--------------- 2 files changed, 16 insertions(+), 64 deletions(-) diff --git a/src/test/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientTest.java b/src/test/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientTest.java index 0e9ae3baa..aecffae65 100644 --- a/src/test/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientTest.java +++ b/src/test/java/io/weaviate/client6/v1/api/collections/data/WeaviateDataClientTest.java @@ -128,18 +128,9 @@ private void assertJsonHasValue(String json, String key, T value) { public static Object[][] grpcTestCases() { return new Object[][] { - { - "object exists", - (Act) client -> client.exists("test-uuid"), - }, - { - "insert many", - (Act) client -> client.insertMany(), - }, - { - "delete many", - (Act) client -> client.deleteMany(), - }, + { "object exists", (Act) client -> client.exists("test-uuid") }, + { "insert many", (Act) client -> client.insertMany() }, + { "delete many", (Act) client -> client.deleteMany() }, }; } diff --git a/src/test/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientTest.java b/src/test/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientTest.java index 1145a25fc..aef374385 100644 --- a/src/test/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientTest.java +++ b/src/test/java/io/weaviate/client6/v1/api/collections/query/WeaviateQueryClientTest.java @@ -51,58 +51,19 @@ private void assertJsonHasValue(String json, String key, T value) { public static Object[][] grpcTestCases() { return new Object[][] { - { - "get by id", - (Act) client -> client.byId("test-uuid") - }, - { - "fetch objects", - (Act) client -> client.fetchObjects(ObjectBuilder.identity()), - }, - { - "bm25", - (Act) client -> client.bm25("red ballon"), - }, - { - "hybrid", - (Act) client -> client.hybrid("red ballon"), - }, - { - "nearVector", - (Act) client -> client.nearVector(new float[] {}), - }, - { - "nearText", - (Act) client -> client.nearText("weather in Arizona"), - }, - { - "nearObject", - (Act) client -> client.nearObject("test-uuid"), - }, - { - "nearImage", - (Act) client -> client.nearImage("img.jpeg"), - }, - { - "nearAudio", - (Act) client -> client.nearAudio("song.mp3"), - }, - { - "nearVideo", - (Act) client -> client.nearVideo("clip.mp4"), - }, - { - "nearDepth", - (Act) client -> client.nearDepth("20.000 leagues"), - }, - { - "nearThermal", - (Act) client -> client.nearThermal("Fahrenheit 451"), - }, - { - "nearImu", - (Act) client -> client.nearImu("6 m/s"), - }, + { "get by id", (Act) client -> client.byId("test-uuid") }, + { "fetch objects", (Act) client -> client.fetchObjects(ObjectBuilder.identity()) }, + { "bm25", (Act) client -> client.bm25("red ballon") }, + { "hybrid", (Act) client -> client.hybrid("red ballon") }, + { "nearVector", (Act) client -> client.nearVector(new float[] {}) }, + { "nearText", (Act) client -> client.nearText("weather in Arizona") }, + { "nearObject", (Act) client -> client.nearObject("test-uuid") }, + { "nearImage", (Act) client -> client.nearImage("img.jpeg") }, + { "nearAudio", (Act) client -> client.nearAudio("song.mp3") }, + { "nearVideo", (Act) client -> client.nearVideo("clip.mp4") }, + { "nearDepth", (Act) client -> client.nearDepth("20.000 leagues") }, + { "nearThermal", (Act) client -> client.nearThermal("Fahrenheit 451") }, + { "nearImu", (Act) client -> client.nearImu("6 m/s") }, }; } From 39a60aaf2e22f63a25893b3d22a7a39ffa4bac9d Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Wed, 20 Aug 2025 17:26:13 +0200 Subject: [PATCH 10/10] refactor: add consistencyLevel via defaults::rpc utility --- .../v1/api/collections/query/QueryOperator.java | 12 ------------ .../v1/api/collections/query/QueryRequest.java | 6 +++--- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryOperator.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryOperator.java index 204c83a1e..a3844b4eb 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryOperator.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryOperator.java @@ -1,20 +1,8 @@ package io.weaviate.client6.v1.api.collections.query; -import io.weaviate.client6.v1.api.collections.CollectionHandleDefaults; import io.weaviate.client6.v1.internal.grpc.protocol.WeaviateProtoSearchGet; interface QueryOperator { /** Append QueryOperator to the request message. */ void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req); - - /** - * Append QueryOperator to the request message and apply default parameters. - * Implementations generally shouldn't override this method. - */ - default void appendTo(WeaviateProtoSearchGet.SearchRequest.Builder req, CollectionHandleDefaults defaults) { - appendTo(req); - if (!req.hasConsistencyLevel() && defaults.consistencyLevel() != null) { - defaults.consistencyLevel().appendTo(req); - } - } } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryRequest.java index 84d216812..9d1911286 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/QueryRequest.java @@ -27,14 +27,14 @@ public record QueryRequest(QueryOperator operator, GroupBy groupBy) { static Rpc, WeaviateProtoSearchGet.SearchReply> rpc( CollectionDescriptor collection, CollectionHandleDefaults defaults) { - return Rpc.of( + return defaults.rpc(Rpc.of( request -> { var message = WeaviateProtoSearchGet.SearchRequest.newBuilder(); message.setUses127Api(true); message.setUses125Api(true); message.setUses123Api(true); message.setCollection(collection.name()); - request.operator.appendTo(message, defaults); + request.operator.appendTo(message); if (request.groupBy != null) { request.groupBy.appendTo(message); } @@ -50,7 +50,7 @@ static Rpc(objects); }, () -> WeaviateBlockingStub::search, - () -> WeaviateFutureStub::search); + () -> WeaviateFutureStub::search)); } static Rpc, WeaviateProtoSearchGet.SearchReply> grouped(