From 3f718cb41564dd0a1a5a93a6a1f283167c4a906b Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Wed, 9 Jul 2025 13:56:39 +0200 Subject: [PATCH 1/8] feat: add aliases namespace to sync client --- .../io/weaviate/client/WeaviateClient.java | 5 +++ .../weaviate/client/v1/aliases/Aliases.java | 39 ++++++++++++++++++ .../client/v1/aliases/api/AliasAllGetter.java | 36 +++++++++++++++++ .../client/v1/aliases/api/AliasCreator.java | 34 ++++++++++++++++ .../client/v1/aliases/api/AliasDeleter.java | 27 +++++++++++++ .../client/v1/aliases/api/AliasGetter.java | 26 ++++++++++++ .../client/v1/aliases/api/AliasUpdater.java | 40 +++++++++++++++++++ .../client/v1/aliases/model/Alias.java | 15 +++++++ 8 files changed, 222 insertions(+) create mode 100644 src/main/java/io/weaviate/client/v1/aliases/Aliases.java create mode 100644 src/main/java/io/weaviate/client/v1/aliases/api/AliasAllGetter.java create mode 100644 src/main/java/io/weaviate/client/v1/aliases/api/AliasCreator.java create mode 100644 src/main/java/io/weaviate/client/v1/aliases/api/AliasDeleter.java create mode 100644 src/main/java/io/weaviate/client/v1/aliases/api/AliasGetter.java create mode 100644 src/main/java/io/weaviate/client/v1/aliases/api/AliasUpdater.java create mode 100644 src/main/java/io/weaviate/client/v1/aliases/model/Alias.java diff --git a/src/main/java/io/weaviate/client/WeaviateClient.java b/src/main/java/io/weaviate/client/WeaviateClient.java index dcd9f3fed..87d64801a 100644 --- a/src/main/java/io/weaviate/client/WeaviateClient.java +++ b/src/main/java/io/weaviate/client/WeaviateClient.java @@ -8,6 +8,7 @@ import io.weaviate.client.base.util.DbVersionProvider; import io.weaviate.client.base.util.DbVersionSupport; import io.weaviate.client.base.util.GrpcVersionSupport; +import io.weaviate.client.v1.aliases.Aliases; import io.weaviate.client.v1.async.WeaviateAsyncClient; import io.weaviate.client.v1.auth.provider.AccessTokenProvider; import io.weaviate.client.v1.backup.Backup; @@ -111,6 +112,10 @@ public Users users() { return new Users(httpClient, config); } + public Aliases aliases() { + return new Aliases(httpClient, config); + } + private DbVersionProvider initDbVersionProvider() { MetaGetter metaGetter = new Misc(httpClient, config, null).metaGetter(); DbVersionProvider.VersionGetter getter = () -> Optional.ofNullable(metaGetter.run()) diff --git a/src/main/java/io/weaviate/client/v1/aliases/Aliases.java b/src/main/java/io/weaviate/client/v1/aliases/Aliases.java new file mode 100644 index 000000000..dd6b15642 --- /dev/null +++ b/src/main/java/io/weaviate/client/v1/aliases/Aliases.java @@ -0,0 +1,39 @@ +package io.weaviate.client.v1.aliases; + +import io.weaviate.client.Config; +import io.weaviate.client.base.http.HttpClient; +import io.weaviate.client.v1.aliases.api.AliasAllGetter; +import io.weaviate.client.v1.aliases.api.AliasCreator; +import io.weaviate.client.v1.aliases.api.AliasDeleter; +import io.weaviate.client.v1.aliases.api.AliasGetter; +import io.weaviate.client.v1.aliases.api.AliasUpdater; + +public class Aliases { + private final Config config; + private final HttpClient httpClient; + + public Aliases(HttpClient httpClient, Config config) { + this.config = config; + this.httpClient = httpClient; + } + + public AliasCreator creator() { + return new AliasCreator(httpClient, config); + } + + public AliasGetter getter() { + return new AliasGetter(httpClient, config); + } + + public AliasAllGetter allGetter() { + return new AliasAllGetter(httpClient, config); + } + + public AliasDeleter deleter() { + return new AliasDeleter(httpClient, config); + } + + public Object updater() { + return new AliasUpdater(httpClient, config); + } +} diff --git a/src/main/java/io/weaviate/client/v1/aliases/api/AliasAllGetter.java b/src/main/java/io/weaviate/client/v1/aliases/api/AliasAllGetter.java new file mode 100644 index 000000000..195c46bc2 --- /dev/null +++ b/src/main/java/io/weaviate/client/v1/aliases/api/AliasAllGetter.java @@ -0,0 +1,36 @@ +package io.weaviate.client.v1.aliases.api; + +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import io.weaviate.client.Config; +import io.weaviate.client.base.BaseClient; +import io.weaviate.client.base.ClientResult; +import io.weaviate.client.base.Response; +import io.weaviate.client.base.Result; +import io.weaviate.client.base.http.HttpClient; +import io.weaviate.client.v1.aliases.api.AliasAllGetter.ResponseBody; +import io.weaviate.client.v1.aliases.model.Alias; + +public class AliasAllGetter extends BaseClient implements ClientResult> { + public AliasAllGetter(HttpClient httpClient, Config config) { + super(httpClient, config); + } + + static class ResponseBody { + List aliases; + } + + @Override + public Result> run() { + Response resp = sendGetRequest("/aliases", ResponseBody.class); + if (resp.getErrors() != null) { + return new Result<>(resp, null); + } + Map aliases = resp.getBody().aliases.stream() + .collect(Collectors.toMap(Alias::getAlias, Function.identity())); + return new Result<>(resp, aliases); + } +} diff --git a/src/main/java/io/weaviate/client/v1/aliases/api/AliasCreator.java b/src/main/java/io/weaviate/client/v1/aliases/api/AliasCreator.java new file mode 100644 index 000000000..aa123c392 --- /dev/null +++ b/src/main/java/io/weaviate/client/v1/aliases/api/AliasCreator.java @@ -0,0 +1,34 @@ +package io.weaviate.client.v1.aliases.api; + +import io.weaviate.client.Config; +import io.weaviate.client.base.BaseClient; +import io.weaviate.client.base.ClientResult; +import io.weaviate.client.base.Response; +import io.weaviate.client.base.Result; +import io.weaviate.client.base.http.HttpClient; +import io.weaviate.client.v1.aliases.model.Alias; + +public class AliasCreator extends BaseClient implements ClientResult { + private String className; + private String alias; + + public AliasCreator(HttpClient httpClient, Config config) { + super(httpClient, config); + } + + public AliasCreator withClassName(String className) { + this.className = className; + return this; + } + + public AliasCreator withAlias(String alias) { + this.alias = alias; + return this; + } + + @Override + public Result run() { + Response resp = sendPostRequest("/aliases", new Alias(className, alias), Void.class); + return Result.voidToBoolean(resp); + } +} diff --git a/src/main/java/io/weaviate/client/v1/aliases/api/AliasDeleter.java b/src/main/java/io/weaviate/client/v1/aliases/api/AliasDeleter.java new file mode 100644 index 000000000..0bed20b3b --- /dev/null +++ b/src/main/java/io/weaviate/client/v1/aliases/api/AliasDeleter.java @@ -0,0 +1,27 @@ +package io.weaviate.client.v1.aliases.api; + +import io.weaviate.client.Config; +import io.weaviate.client.base.BaseClient; +import io.weaviate.client.base.ClientResult; +import io.weaviate.client.base.Response; +import io.weaviate.client.base.Result; +import io.weaviate.client.base.http.HttpClient; + +public class AliasDeleter extends BaseClient implements ClientResult { + private String alias; + + public AliasDeleter(HttpClient httpClient, Config config) { + super(httpClient, config); + } + + public AliasDeleter withAlias(String alias) { + this.alias = alias; + return this; + } + + @Override + public Result run() { + Response resp = sendDeleteRequest("/aliases/" + alias, null, Void.class); + return Result.voidToBoolean(resp); + } +} diff --git a/src/main/java/io/weaviate/client/v1/aliases/api/AliasGetter.java b/src/main/java/io/weaviate/client/v1/aliases/api/AliasGetter.java new file mode 100644 index 000000000..b3a8f9aca --- /dev/null +++ b/src/main/java/io/weaviate/client/v1/aliases/api/AliasGetter.java @@ -0,0 +1,26 @@ +package io.weaviate.client.v1.aliases.api; + +import io.weaviate.client.Config; +import io.weaviate.client.base.BaseClient; +import io.weaviate.client.base.ClientResult; +import io.weaviate.client.base.Result; +import io.weaviate.client.base.http.HttpClient; +import io.weaviate.client.v1.aliases.model.Alias; + +public class AliasGetter extends BaseClient implements ClientResult { + private String alias; + + public AliasGetter(HttpClient httpClient, Config config) { + super(httpClient, config); + } + + public AliasGetter withAlias(String alias) { + this.alias = alias; + return this; + } + + @Override + public Result run() { + return new Result<>(sendGetRequest("/aliases/" + alias, Alias.class)); + } +} diff --git a/src/main/java/io/weaviate/client/v1/aliases/api/AliasUpdater.java b/src/main/java/io/weaviate/client/v1/aliases/api/AliasUpdater.java new file mode 100644 index 000000000..8eea4a90f --- /dev/null +++ b/src/main/java/io/weaviate/client/v1/aliases/api/AliasUpdater.java @@ -0,0 +1,40 @@ +package io.weaviate.client.v1.aliases.api; + +import com.google.gson.annotations.SerializedName; + +import io.weaviate.client.Config; +import io.weaviate.client.base.BaseClient; +import io.weaviate.client.base.ClientResult; +import io.weaviate.client.base.Response; +import io.weaviate.client.base.Result; +import io.weaviate.client.base.http.HttpClient; + +public class AliasUpdater extends BaseClient implements ClientResult { + private String className; + private String alias; + + public AliasUpdater(HttpClient httpClient, Config config) { + super(httpClient, config); + } + + public AliasUpdater withAlias(String alias) { + this.alias = alias; + return this; + } + + public AliasUpdater withNewClassName(String className) { + this.className = className; + return this; + } + + class Body { + @SerializedName("class") + String className = AliasUpdater.this.className; + } + + @Override + public Result run() { + Response resp = sendPutRequest("/aliases/" + alias, new Body(), Void.class); + return Result.voidToBoolean(resp); + } +} diff --git a/src/main/java/io/weaviate/client/v1/aliases/model/Alias.java b/src/main/java/io/weaviate/client/v1/aliases/model/Alias.java new file mode 100644 index 000000000..456d7de50 --- /dev/null +++ b/src/main/java/io/weaviate/client/v1/aliases/model/Alias.java @@ -0,0 +1,15 @@ +package io.weaviate.client.v1.aliases.model; + +import com.google.gson.annotations.SerializedName; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public class Alias { + @SerializedName("class") + private final String collection; + @SerializedName("alias") + private final String alias; +} From db5902e6aebc1ce0459682229a95e6989d1f657f Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Wed, 9 Jul 2025 14:36:36 +0200 Subject: [PATCH 2/8] feat: add aliases namespace to async client --- .../weaviate/client/base/AsyncBaseClient.java | 36 ++++++++----- .../client/v1/async/WeaviateAsyncClient.java | 5 ++ .../client/v1/async/aliases/Aliases.java | 39 +++++++++++++++ .../v1/async/aliases/api/AliasAllGetter.java | 50 +++++++++++++++++++ .../v1/async/aliases/api/AliasCreator.java | 38 ++++++++++++++ .../v1/async/aliases/api/AliasDeleter.java | 31 ++++++++++++ .../v1/async/aliases/api/AliasGetter.java | 31 ++++++++++++ .../v1/async/aliases/api/AliasUpdater.java | 44 ++++++++++++++++ 8 files changed, 262 insertions(+), 12 deletions(-) create mode 100644 src/main/java/io/weaviate/client/v1/async/aliases/Aliases.java create mode 100644 src/main/java/io/weaviate/client/v1/async/aliases/api/AliasAllGetter.java create mode 100644 src/main/java/io/weaviate/client/v1/async/aliases/api/AliasCreator.java create mode 100644 src/main/java/io/weaviate/client/v1/async/aliases/api/AliasDeleter.java create mode 100644 src/main/java/io/weaviate/client/v1/async/aliases/api/AliasGetter.java create mode 100644 src/main/java/io/weaviate/client/v1/async/aliases/api/AliasUpdater.java diff --git a/src/main/java/io/weaviate/client/base/AsyncBaseClient.java b/src/main/java/io/weaviate/client/base/AsyncBaseClient.java index 2bc88b713..4b22e365c 100644 --- a/src/main/java/io/weaviate/client/base/AsyncBaseClient.java +++ b/src/main/java/io/weaviate/client/base/AsyncBaseClient.java @@ -30,39 +30,48 @@ protected Future> sendGetRequest(String endpoint, Class classOfT, F return sendRequest(endpoint, null, "GET", classOfT, callback, null); } - protected Future> sendGetRequest(String endpoint, FutureCallback> callback, ResponseParser parser) { + protected Future> sendGetRequest(String endpoint, FutureCallback> callback, + ResponseParser parser) { return sendRequest(endpoint, null, "GET", null, callback, parser); } - protected Future> sendPostRequest(String endpoint, Object payload, Class classOfT, FutureCallback> callback) { + protected Future> sendPostRequest(String endpoint, Object payload, Class classOfT, + FutureCallback> callback) { return sendRequest(endpoint, payload, "POST", classOfT, callback, null); } - protected Future> sendPostRequest(String endpoint, Object payload, FutureCallback> callback, ResponseParser parser) { + protected Future> sendPostRequest(String endpoint, Object payload, FutureCallback> callback, + ResponseParser parser) { return sendRequest(endpoint, payload, "POST", null, callback, parser); } - protected Future> sendPutRequest(String endpoint, Object payload, Class classOfT, FutureCallback> callback) { + protected Future> sendPutRequest(String endpoint, Object payload, Class classOfT, + FutureCallback> callback) { return sendRequest(endpoint, payload, "PUT", classOfT, callback, null); } - protected Future> sendPutRequest(String endpoint, Object payload, FutureCallback> callback, ResponseParser parser) { + protected Future> sendPutRequest(String endpoint, Object payload, FutureCallback> callback, + ResponseParser parser) { return sendRequest(endpoint, payload, "PUT", null, callback, parser); } - protected Future> sendPatchRequest(String endpoint, Object payload, Class classOfT, FutureCallback> callback) { + protected Future> sendPatchRequest(String endpoint, Object payload, Class classOfT, + FutureCallback> callback) { return sendRequest(endpoint, payload, "PATCH", classOfT, callback, null); } - protected Future> sendPatchRequest(String endpoint, Object payload, FutureCallback> callback, ResponseParser parser) { + protected Future> sendPatchRequest(String endpoint, Object payload, FutureCallback> callback, + ResponseParser parser) { return sendRequest(endpoint, payload, "PATCH", null, callback, parser); } - protected Future> sendDeleteRequest(String endpoint, Object payload, Class classOfT, FutureCallback> callback) { + protected Future> sendDeleteRequest(String endpoint, Object payload, Class classOfT, + FutureCallback> callback) { return sendRequest(endpoint, payload, "DELETE", classOfT, callback, null); } - protected Future> sendDeleteRequest(String endpoint, Object payload, FutureCallback> callback, ResponseParser parser) { + protected Future> sendDeleteRequest(String endpoint, Object payload, FutureCallback> callback, + ResponseParser parser) { return sendRequest(endpoint, payload, "DELETE", null, callback, parser); } @@ -70,12 +79,15 @@ protected Future> sendHeadRequest(String endpoint, Class classOfT, return sendRequest(endpoint, null, "HEAD", classOfT, callback, null); } - protected Future> sendHeadRequest(String endpoint, FutureCallback> callback, ResponseParser parser) { + protected Future> sendHeadRequest(String endpoint, FutureCallback> callback, + ResponseParser parser) { return sendRequest(endpoint, null, "HEAD", null, callback, parser); } - private Future> sendRequest(String endpoint, Object payload, String method, Class classOfT, FutureCallback> callback, ResponseParser parser) { - return client.execute(SimpleRequestProducer.create(getRequest(endpoint, payload, method)), new WeaviateResponseConsumer<>(classOfT, parser), callback); + private Future> sendRequest(String endpoint, Object payload, String method, Class classOfT, + FutureCallback> callback, ResponseParser parser) { + return client.execute(SimpleRequestProducer.create(getRequest(endpoint, payload, method)), + new WeaviateResponseConsumer<>(classOfT, parser), callback); } protected SimpleHttpRequest getRequest(String endpoint, Object payload, String method) { diff --git a/src/main/java/io/weaviate/client/v1/async/WeaviateAsyncClient.java b/src/main/java/io/weaviate/client/v1/async/WeaviateAsyncClient.java index c19826587..c0d4a8331 100644 --- a/src/main/java/io/weaviate/client/v1/async/WeaviateAsyncClient.java +++ b/src/main/java/io/weaviate/client/v1/async/WeaviateAsyncClient.java @@ -12,6 +12,7 @@ import io.weaviate.client.base.util.DbVersionProvider; import io.weaviate.client.base.util.DbVersionSupport; import io.weaviate.client.base.util.GrpcVersionSupport; +import io.weaviate.client.v1.async.aliases.Aliases; import io.weaviate.client.v1.async.backup.Backup; import io.weaviate.client.v1.async.batch.Batch; import io.weaviate.client.v1.async.classifications.Classifications; @@ -84,6 +85,10 @@ public Users users() { return new Users(client, config, tokenProvider); } + public Aliases aliases() { + return new Aliases(client, config, tokenProvider); + } + private DbVersionProvider initDbVersionProvider() { DbVersionProvider.VersionGetter getter = () -> Optional.ofNullable(this.getMeta()) .filter(result -> !result.hasErrors()) diff --git a/src/main/java/io/weaviate/client/v1/async/aliases/Aliases.java b/src/main/java/io/weaviate/client/v1/async/aliases/Aliases.java new file mode 100644 index 000000000..cbec3d380 --- /dev/null +++ b/src/main/java/io/weaviate/client/v1/async/aliases/Aliases.java @@ -0,0 +1,39 @@ +package io.weaviate.client.v1.async.aliases; + +import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; + +import io.weaviate.client.Config; +import io.weaviate.client.v1.async.aliases.api.AliasAllGetter; +import io.weaviate.client.v1.async.aliases.api.AliasCreator; +import io.weaviate.client.v1.async.aliases.api.AliasDeleter; +import io.weaviate.client.v1.async.aliases.api.AliasGetter; +import io.weaviate.client.v1.async.aliases.api.AliasUpdater; +import io.weaviate.client.v1.auth.provider.AccessTokenProvider; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class Aliases { + private final CloseableHttpAsyncClient client; + private final Config config; + private final AccessTokenProvider tokenProvider; + + public AliasCreator creator() { + return new AliasCreator(client, config, tokenProvider); + } + + public AliasGetter getter() { + return new AliasGetter(client, config, tokenProvider); + } + + public AliasAllGetter allGetter() { + return new AliasAllGetter(client, config, tokenProvider); + } + + public AliasDeleter deleter() { + return new AliasDeleter(client, config, tokenProvider); + } + + public Object updater() { + return new AliasUpdater(client, config, tokenProvider); + } +} diff --git a/src/main/java/io/weaviate/client/v1/async/aliases/api/AliasAllGetter.java b/src/main/java/io/weaviate/client/v1/async/aliases/api/AliasAllGetter.java new file mode 100644 index 000000000..a876aeb64 --- /dev/null +++ b/src/main/java/io/weaviate/client/v1/async/aliases/api/AliasAllGetter.java @@ -0,0 +1,50 @@ +package io.weaviate.client.v1.async.aliases.api; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.Future; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; +import org.apache.hc.core5.concurrent.FutureCallback; +import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.HttpResponse; + +import io.weaviate.client.Config; +import io.weaviate.client.base.AsyncBaseClient; +import io.weaviate.client.base.AsyncClientResult; +import io.weaviate.client.base.Response; +import io.weaviate.client.base.Result; +import io.weaviate.client.base.http.async.ResponseParser; +import io.weaviate.client.v1.aliases.model.Alias; +import io.weaviate.client.v1.auth.provider.AccessTokenProvider; + +public class AliasAllGetter extends AsyncBaseClient> + implements AsyncClientResult> { + + public AliasAllGetter(CloseableHttpAsyncClient httpClient, Config config, AccessTokenProvider tokenProvider) { + super(httpClient, config, tokenProvider); + } + + @Override + public Future>> run(FutureCallback>> callback) { + return sendGetRequest("/aliases", callback, new ResponseParser>() { + + class ResponseBody { + List aliases; + } + + @Override + public Result> parse(HttpResponse response, String body, ContentType contentType) { + Response resp = serializer.toResponse(response.getCode(), body, ResponseBody.class); + if (resp.getErrors() != null) { + return new Result<>(resp, null); + } + Map aliases = resp.getBody().aliases.stream() + .collect(Collectors.toMap(Alias::getAlias, Function.identity())); + return new Result<>(resp, aliases); + } + }); + } +} diff --git a/src/main/java/io/weaviate/client/v1/async/aliases/api/AliasCreator.java b/src/main/java/io/weaviate/client/v1/async/aliases/api/AliasCreator.java new file mode 100644 index 000000000..cbfa5d4a4 --- /dev/null +++ b/src/main/java/io/weaviate/client/v1/async/aliases/api/AliasCreator.java @@ -0,0 +1,38 @@ +package io.weaviate.client.v1.async.aliases.api; + +import java.util.concurrent.Future; + +import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; +import org.apache.hc.core5.concurrent.FutureCallback; + +import io.weaviate.client.Config; +import io.weaviate.client.base.AsyncBaseClient; +import io.weaviate.client.base.AsyncClientResult; +import io.weaviate.client.base.Result; +import io.weaviate.client.v1.aliases.model.Alias; +import io.weaviate.client.v1.auth.provider.AccessTokenProvider; + +public class AliasCreator extends AsyncBaseClient implements AsyncClientResult { + private String className; + private String alias; + + public AliasCreator(CloseableHttpAsyncClient httpClient, Config config, AccessTokenProvider tokenProvider) { + super(httpClient, config, tokenProvider); + } + + public AliasCreator withClassName(String className) { + this.className = className; + return this; + } + + public AliasCreator withAlias(String alias) { + this.alias = alias; + return this; + } + + @Override + public Future> run(FutureCallback> callback) { + return sendPostRequest("/aliases", new Alias(className, alias), + callback, Result.voidToBooleanParser()); + } +} diff --git a/src/main/java/io/weaviate/client/v1/async/aliases/api/AliasDeleter.java b/src/main/java/io/weaviate/client/v1/async/aliases/api/AliasDeleter.java new file mode 100644 index 000000000..0180e5add --- /dev/null +++ b/src/main/java/io/weaviate/client/v1/async/aliases/api/AliasDeleter.java @@ -0,0 +1,31 @@ +package io.weaviate.client.v1.async.aliases.api; + +import java.util.concurrent.Future; + +import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; +import org.apache.hc.core5.concurrent.FutureCallback; + +import io.weaviate.client.Config; +import io.weaviate.client.base.AsyncBaseClient; +import io.weaviate.client.base.AsyncClientResult; +import io.weaviate.client.base.Result; +import io.weaviate.client.v1.auth.provider.AccessTokenProvider; + +public class AliasDeleter extends AsyncBaseClient implements AsyncClientResult { + private String alias; + + public AliasDeleter(CloseableHttpAsyncClient httpClient, Config config, AccessTokenProvider tokenProvider) { + super(httpClient, config, tokenProvider); + } + + public AliasDeleter withAlias(String alias) { + this.alias = alias; + return this; + } + + @Override + public Future> run(FutureCallback> callback) { + return sendDeleteRequest("/aliases/" + alias, null, + callback, Result.voidToBooleanParser()); + } +} diff --git a/src/main/java/io/weaviate/client/v1/async/aliases/api/AliasGetter.java b/src/main/java/io/weaviate/client/v1/async/aliases/api/AliasGetter.java new file mode 100644 index 000000000..bc06fd843 --- /dev/null +++ b/src/main/java/io/weaviate/client/v1/async/aliases/api/AliasGetter.java @@ -0,0 +1,31 @@ +package io.weaviate.client.v1.async.aliases.api; + +import java.util.concurrent.Future; + +import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; +import org.apache.hc.core5.concurrent.FutureCallback; + +import io.weaviate.client.Config; +import io.weaviate.client.base.AsyncBaseClient; +import io.weaviate.client.base.AsyncClientResult; +import io.weaviate.client.base.Result; +import io.weaviate.client.v1.aliases.model.Alias; +import io.weaviate.client.v1.auth.provider.AccessTokenProvider; + +public class AliasGetter extends AsyncBaseClient implements AsyncClientResult { + private String alias; + + public AliasGetter(CloseableHttpAsyncClient httpClient, Config config, AccessTokenProvider tokenProvider) { + super(httpClient, config, tokenProvider); + } + + public AliasGetter withAlias(String alias) { + this.alias = alias; + return this; + } + + @Override + public Future> run(FutureCallback> callback) { + return sendGetRequest("/aliases/" + alias, Alias.class, callback); + } +} diff --git a/src/main/java/io/weaviate/client/v1/async/aliases/api/AliasUpdater.java b/src/main/java/io/weaviate/client/v1/async/aliases/api/AliasUpdater.java new file mode 100644 index 000000000..06e373e43 --- /dev/null +++ b/src/main/java/io/weaviate/client/v1/async/aliases/api/AliasUpdater.java @@ -0,0 +1,44 @@ +package io.weaviate.client.v1.async.aliases.api; + +import java.util.concurrent.Future; + +import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; +import org.apache.hc.core5.concurrent.FutureCallback; + +import com.google.gson.annotations.SerializedName; + +import io.weaviate.client.Config; +import io.weaviate.client.base.AsyncBaseClient; +import io.weaviate.client.base.AsyncClientResult; +import io.weaviate.client.base.Result; +import io.weaviate.client.v1.auth.provider.AccessTokenProvider; + +public class AliasUpdater extends AsyncBaseClient implements AsyncClientResult { + private String className; + private String alias; + + public AliasUpdater(CloseableHttpAsyncClient httpClient, Config config, AccessTokenProvider tokenProvider) { + super(httpClient, config, tokenProvider); + } + + public AliasUpdater withAlias(String alias) { + this.alias = alias; + return this; + } + + public AliasUpdater withNewClassName(String className) { + this.className = className; + return this; + } + + class Body { + @SerializedName("class") + String className = AliasUpdater.this.className; + } + + @Override + public Future> run(FutureCallback> callback) { + return sendPutRequest("/aliases/" + alias, new Body(), + callback, Result.voidToBooleanParser()); + } +} From 20fece78fa894d463ba6c6a9016bf4463381d553 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Wed, 9 Jul 2025 15:07:47 +0200 Subject: [PATCH 3/8] test: add integration tests for alias management --- .../weaviate/client/base/AsyncBaseClient.java | 10 +- .../weaviate/client/v1/aliases/Aliases.java | 2 +- .../client/v1/aliases/model/Alias.java | 4 +- .../client/v1/async/aliases/Aliases.java | 2 +- .../client/aliases/ClientAliasesTest.java | 85 +++++++++++++++++ .../async/aliases/ClientAliasesTest.java | 93 +++++++++++++++++++ 6 files changed, 189 insertions(+), 7 deletions(-) create mode 100644 src/test/java/io/weaviate/integration/client/aliases/ClientAliasesTest.java create mode 100644 src/test/java/io/weaviate/integration/client/async/aliases/ClientAliasesTest.java diff --git a/src/main/java/io/weaviate/client/base/AsyncBaseClient.java b/src/main/java/io/weaviate/client/base/AsyncBaseClient.java index 4b22e365c..399afbf0f 100644 --- a/src/main/java/io/weaviate/client/base/AsyncBaseClient.java +++ b/src/main/java/io/weaviate/client/base/AsyncBaseClient.java @@ -1,11 +1,8 @@ package io.weaviate.client.base; -import io.weaviate.client.Config; -import io.weaviate.client.base.http.async.ResponseParser; -import io.weaviate.client.base.http.async.WeaviateResponseConsumer; -import io.weaviate.client.v1.auth.provider.AccessTokenProvider; import java.util.Map; import java.util.concurrent.Future; + import org.apache.hc.client5.http.async.methods.SimpleHttpRequest; import org.apache.hc.client5.http.async.methods.SimpleRequestProducer; import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; @@ -13,6 +10,11 @@ import org.apache.hc.core5.http.ContentType; import org.apache.hc.core5.http.HttpHeaders; +import io.weaviate.client.Config; +import io.weaviate.client.base.http.async.ResponseParser; +import io.weaviate.client.base.http.async.WeaviateResponseConsumer; +import io.weaviate.client.v1.auth.provider.AccessTokenProvider; + public abstract class AsyncBaseClient { protected final CloseableHttpAsyncClient client; private final Config config; diff --git a/src/main/java/io/weaviate/client/v1/aliases/Aliases.java b/src/main/java/io/weaviate/client/v1/aliases/Aliases.java index dd6b15642..aac69243b 100644 --- a/src/main/java/io/weaviate/client/v1/aliases/Aliases.java +++ b/src/main/java/io/weaviate/client/v1/aliases/Aliases.java @@ -33,7 +33,7 @@ public AliasDeleter deleter() { return new AliasDeleter(httpClient, config); } - public Object updater() { + public AliasUpdater updater() { return new AliasUpdater(httpClient, config); } } diff --git a/src/main/java/io/weaviate/client/v1/aliases/model/Alias.java b/src/main/java/io/weaviate/client/v1/aliases/model/Alias.java index 456d7de50..b6c99816f 100644 --- a/src/main/java/io/weaviate/client/v1/aliases/model/Alias.java +++ b/src/main/java/io/weaviate/client/v1/aliases/model/Alias.java @@ -2,14 +2,16 @@ import com.google.gson.annotations.SerializedName; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.RequiredArgsConstructor; @Getter @RequiredArgsConstructor +@EqualsAndHashCode public class Alias { @SerializedName("class") - private final String collection; + private final String className; @SerializedName("alias") private final String alias; } diff --git a/src/main/java/io/weaviate/client/v1/async/aliases/Aliases.java b/src/main/java/io/weaviate/client/v1/async/aliases/Aliases.java index cbec3d380..ee56fc2b6 100644 --- a/src/main/java/io/weaviate/client/v1/async/aliases/Aliases.java +++ b/src/main/java/io/weaviate/client/v1/async/aliases/Aliases.java @@ -33,7 +33,7 @@ public AliasDeleter deleter() { return new AliasDeleter(client, config, tokenProvider); } - public Object updater() { + public AliasUpdater updater() { return new AliasUpdater(client, config, tokenProvider); } } diff --git a/src/test/java/io/weaviate/integration/client/aliases/ClientAliasesTest.java b/src/test/java/io/weaviate/integration/client/aliases/ClientAliasesTest.java new file mode 100644 index 000000000..1d5c89ed6 --- /dev/null +++ b/src/test/java/io/weaviate/integration/client/aliases/ClientAliasesTest.java @@ -0,0 +1,85 @@ +package io.weaviate.integration.client.aliases; + +import static org.junit.jupiter.api.Assumptions.assumeTrue; + +import java.util.HashMap; +import java.util.Map; + +import org.assertj.core.api.Assertions; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; + +import io.weaviate.client.Config; +import io.weaviate.client.WeaviateClient; +import io.weaviate.client.base.Result; +import io.weaviate.client.v1.aliases.model.Alias; +import io.weaviate.client.v1.schema.model.WeaviateClass; +import io.weaviate.integration.client.WeaviateDockerCompose; + +public class ClientAliasesTest { + private WeaviateClient client; + + @ClassRule + public static WeaviateDockerCompose compose = new WeaviateDockerCompose(); + + @Before + public void before() { + Config config = new Config("http", compose.getHttpHostAddress()); + client = new WeaviateClient(config); + } + + @Test + public void shouldManageAliases() { + // Arrange + Result createdPaul = client.schema().classCreator().withClass(WeaviateClass.builder() + .className("PaulHewson").build()).run(); + assumeTrue(createdPaul.getResult(), "created PaulHewson collection"); + + Result createdGeorge = client.schema().classCreator().withClass(WeaviateClass.builder() + .className("GeorgeBarnes").build()).run(); + assumeTrue(createdGeorge.getResult(), "created GeorgeBarnes collection"); + + // Act: create alias + client.aliases().creator().withClassName("PaulHewson").withAlias("Bono").run(); + client.aliases().creator().withClassName("GeorgeBarnes").withAlias("MachineGunKelly").run(); + + // Assert: get all + Result> all = client.aliases().allGetter().run(); + + Assertions.assertThat(all.getError()).isNull(); + Assertions.assertThat(all.getResult()) + .as("fetched all aliases") + .containsAllEntriesOf(new HashMap() { + { + put("Bono", new Alias("PaulHewson", "Bono")); + put("MachineGunKelly", new Alias("GeorgeBarnes", "MachineGunKelly")); + } + }); + + // Act: update + Result createdMGK = client.schema().classCreator().withClass(WeaviateClass.builder() + .className("ColsonBaker").build()).run(); + assumeTrue(createdMGK.getResult(), "created ColsonBaker collection"); + + client.aliases().updater().withAlias("MachineGunKelly").withNewClassName("ColsonBaker").run(); + + // Assert: get one + Result mgk = client.aliases().getter().withAlias("MachineGunKelly").run(); + + Assertions.assertThat(mgk.getResult()) + .as("MachineGunKelly alias points to ColsonBaker") + .returns("MachineGunKelly", Alias::getAlias) + .returns("ColsonBaker", Alias::getClassName); + + // Act: delete + client.aliases().deleter().withAlias("Bono").run(); + + // Assert + Result bono = client.aliases().getter().withAlias("Bono").run(); + Assertions.assertThat(bono) + .as("Bono alias deleted") + .returns(null, Result::getResult) + .extracting(Result::getError).isNull(); + } +} diff --git a/src/test/java/io/weaviate/integration/client/async/aliases/ClientAliasesTest.java b/src/test/java/io/weaviate/integration/client/async/aliases/ClientAliasesTest.java new file mode 100644 index 000000000..2ffbb7c4d --- /dev/null +++ b/src/test/java/io/weaviate/integration/client/async/aliases/ClientAliasesTest.java @@ -0,0 +1,93 @@ +package io.weaviate.integration.client.async.aliases; + +import static org.junit.jupiter.api.Assumptions.assumeTrue; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; + +import org.assertj.core.api.Assertions; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; + +import io.weaviate.client.Config; +import io.weaviate.client.WeaviateClient; +import io.weaviate.client.base.Result; +import io.weaviate.client.v1.aliases.model.Alias; +import io.weaviate.client.v1.async.WeaviateAsyncClient; +import io.weaviate.client.v1.schema.model.WeaviateClass; +import io.weaviate.integration.client.WeaviateDockerCompose; + +public class ClientAliasesTest { + private WeaviateAsyncClient client; + + @ClassRule + public static WeaviateDockerCompose compose = new WeaviateDockerCompose(); + + @Before + public void before() { + Config config = new Config("http", compose.getHttpHostAddress()); + client = new WeaviateClient(config).async(); + } + + @After + public void after() { + client.close(); + } + + @Test + public void shouldManageAliases() throws InterruptedException, ExecutionException { + // Arrange + Result createdPaul = client.schema().classCreator().withClass(WeaviateClass.builder() + .className("PaulHewson").build()).run().get(); + assumeTrue(createdPaul.getResult(), "created PaulHewson collection"); + + Result createdGeorge = client.schema().classCreator().withClass(WeaviateClass.builder() + .className("GeorgeBarnes").build()).run().get(); + assumeTrue(createdGeorge.getResult(), "created GeorgeBarnes collection"); + + // Act: create alias + client.aliases().creator().withClassName("PaulHewson").withAlias("Bono").run().get(); + client.aliases().creator().withClassName("GeorgeBarnes").withAlias("MachineGunKelly").run().get(); + + // Assert: get all + Result> all = client.aliases().allGetter().run().get(); + + Assertions.assertThat(all.getError()).isNull(); + Assertions.assertThat(all.getResult()) + .as("fetched all aliases") + .containsAllEntriesOf(new HashMap() { + { + put("Bono", new Alias("PaulHewson", "Bono")); + put("MachineGunKelly", new Alias("GeorgeBarnes", "MachineGunKelly")); + } + }); + + // Act: update + Result createdMGK = client.schema().classCreator().withClass(WeaviateClass.builder() + .className("ColsonBaker").build()).run().get(); + assumeTrue(createdMGK.getResult(), "created ColsonBaker collection"); + + client.aliases().updater().withAlias("MachineGunKelly").withNewClassName("ColsonBaker").run().get(); + + // Assert: get one + Result mgk = client.aliases().getter().withAlias("MachineGunKelly").run().get(); + + Assertions.assertThat(mgk.getResult()) + .as("MachineGunKelly alias points to ColsonBaker") + .returns("MachineGunKelly", Alias::getAlias) + .returns("ColsonBaker", Alias::getClassName); + + // Act: delete + client.aliases().deleter().withAlias("Bono").run().get(); + + // Assert + Result bono = client.aliases().getter().withAlias("Bono").run().get(); + Assertions.assertThat(bono) + .as("Bono alias deleted") + .returns(null, Result::getResult) + .extracting(Result::getError).isNull(); + } +} From 0098862e48eaea80c6d3590eacd3e7f4edbfe016 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Thu, 10 Jul 2025 09:52:45 +0200 Subject: [PATCH 4/8] feat: add AliasesPermission to RBAC --- .../v1/rbac/api/WeaviatePermission.java | 6 +++- .../v1/rbac/model/AliasesPermission.java | 31 +++++++++++++++++++ .../client/v1/rbac/model/Permission.java | 19 ++++++++++-- .../v1/rbac/api/WeaviatePermissionTest.java | 6 ++++ .../client/v1/rbac/model/PermissionTest.java | 6 ++++ .../tests/rbac/ClientRbacTestSuite.java | 3 ++ 6 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 src/main/java/io/weaviate/client/v1/rbac/model/AliasesPermission.java diff --git a/src/main/java/io/weaviate/client/v1/rbac/api/WeaviatePermission.java b/src/main/java/io/weaviate/client/v1/rbac/api/WeaviatePermission.java index 976f1da91..65f6fe13d 100644 --- a/src/main/java/io/weaviate/client/v1/rbac/api/WeaviatePermission.java +++ b/src/main/java/io/weaviate/client/v1/rbac/api/WeaviatePermission.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.List; +import io.weaviate.client.v1.rbac.model.AliasesPermission; import io.weaviate.client.v1.rbac.model.BackupsPermission; import io.weaviate.client.v1.rbac.model.CollectionsPermission; import io.weaviate.client.v1.rbac.model.DataPermission; @@ -25,6 +26,7 @@ @ToString public class WeaviatePermission { String action; + AliasesPermission aliases; BackupsPermission backups; CollectionsPermission collections; DataPermission data; @@ -39,7 +41,9 @@ public WeaviatePermission(String action) { public

> WeaviatePermission(String action, Permission

perm) { this.action = action; - if (perm instanceof BackupsPermission) { + if (perm instanceof AliasesPermission) { + this.aliases = (AliasesPermission) perm; + } else if (perm instanceof BackupsPermission) { this.backups = (BackupsPermission) perm; } else if (perm instanceof CollectionsPermission) { this.collections = (CollectionsPermission) perm; diff --git a/src/main/java/io/weaviate/client/v1/rbac/model/AliasesPermission.java b/src/main/java/io/weaviate/client/v1/rbac/model/AliasesPermission.java new file mode 100644 index 000000000..b43909356 --- /dev/null +++ b/src/main/java/io/weaviate/client/v1/rbac/model/AliasesPermission.java @@ -0,0 +1,31 @@ +package io.weaviate.client.v1.rbac.model; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@Getter +@EqualsAndHashCode(callSuper = true) +public class AliasesPermission extends Permission { + final String alias; + + public AliasesPermission(String alias, Action... actions) { + super(actions); + this.alias = alias; + } + + AliasesPermission(String alias, String action) { + this(alias, RbacAction.fromString(Action.class, action)); + } + + @AllArgsConstructor + public enum Action implements RbacAction { + CREATE("create_aliases"), + READ("read_aliases"), + UPDATE("update_aliases"), + DELETE("delete_aliases"); + + @Getter + private final String value; + } +} diff --git a/src/main/java/io/weaviate/client/v1/rbac/model/Permission.java b/src/main/java/io/weaviate/client/v1/rbac/model/Permission.java index 769cbf6b0..4e1691b6e 100644 --- a/src/main/java/io/weaviate/client/v1/rbac/model/Permission.java +++ b/src/main/java/io/weaviate/client/v1/rbac/model/Permission.java @@ -66,7 +66,9 @@ private WeaviatePermission toWeaviate(String action) { */ public static Permission fromWeaviate(WeaviatePermission perm) { String action = perm.getAction(); - if (perm.getBackups() != null) { + if (perm.getAliases() != null) { + return new AliasesPermission(perm.getAliases().getAlias(), action); + } else if (perm.getBackups() != null) { return new BackupsPermission(perm.getBackups().getCollection(), action); } else if (perm.getCollections() != null) { return new CollectionsPermission(perm.getCollections().getCollection(), action); @@ -126,11 +128,22 @@ private Key(Object object) { return result.values().stream().collect(Collectors.toList()); } + /** + * Create {@link AliasesPermission} for a alias. + *

+ * Example: + * {@code Permission.backups("Pizza", AliasPermission.Action.MANAGE) } + */ + public static AliasesPermission alias(String alias, AliasesPermission.Action... actions) { + checkDeprecation(actions); + return new AliasesPermission(alias, actions); + } + /** * Create {@link BackupsPermission} for a collection. *

* Example: - * {@code Permission.backups(BackupsPermission.Action.MANAGE, "Pizza") } + * {@code Permission.backups("Pizza", BackupsPermission.Action.MANAGE) } */ public static BackupsPermission backups(String collection, BackupsPermission.Action... actions) { checkDeprecation(actions); @@ -140,7 +153,7 @@ public static BackupsPermission backups(String collection, BackupsPermission.Act /** * Create {@link ClusterPermission} permission. *

- * Example: {@code Permission.cluster(ClusterPermission.Action.READ, "Pizza") } + * Example: {@code Permission.cluster(ClusterPermission.Action.READ) } */ public static ClusterPermission cluster(ClusterPermission.Action... actions) { checkDeprecation(actions); diff --git a/src/test/java/io/weaviate/client/v1/rbac/api/WeaviatePermissionTest.java b/src/test/java/io/weaviate/client/v1/rbac/api/WeaviatePermissionTest.java index 8fc41d604..f3028bbaa 100644 --- a/src/test/java/io/weaviate/client/v1/rbac/api/WeaviatePermissionTest.java +++ b/src/test/java/io/weaviate/client/v1/rbac/api/WeaviatePermissionTest.java @@ -6,6 +6,7 @@ import org.junit.Test; +import io.weaviate.client.v1.rbac.model.AliasesPermission; import io.weaviate.client.v1.rbac.model.BackupsPermission; import io.weaviate.client.v1.rbac.model.ClusterPermission; import io.weaviate.client.v1.rbac.model.CollectionsPermission; @@ -26,6 +27,10 @@ public class WeaviatePermissionTest { @Test public void testMergedPermissions() { WeaviatePermission[] apiPermissions = { + // Create and delete PizzaAlias alias + new WeaviatePermission("create_alias", new AliasesPermission("PizzaAlias")), + new WeaviatePermission("delete_alias", new AliasesPermission("PizzaAlias")), + // Manage Pizza backups new WeaviatePermission("manage_backups", new BackupsPermission("Pizza")), @@ -70,6 +75,7 @@ public void testMergedPermissions() { }; Permission[] libraryPermissions = { + new AliasesPermission("PizzaAlias", AliasesPermission.Action.CREATE, AliasesPermission.Action.DELETE), new BackupsPermission("Pizza", BackupsPermission.Action.MANAGE), new DataPermission("Pizza", DataPermission.Action.MANAGE, DataPermission.Action.READ), new DataPermission("Songs", DataPermission.Action.UPDATE, DataPermission.Action.DELETE), diff --git a/src/test/java/io/weaviate/client/v1/rbac/model/PermissionTest.java b/src/test/java/io/weaviate/client/v1/rbac/model/PermissionTest.java index 1d1f3689e..07a5823ec 100644 --- a/src/test/java/io/weaviate/client/v1/rbac/model/PermissionTest.java +++ b/src/test/java/io/weaviate/client/v1/rbac/model/PermissionTest.java @@ -23,6 +23,7 @@ @RunWith(JParamsTestRunner.class) public class PermissionTest { public static Object[][] serializationTestCases() { + AliasesPermission alias = new AliasesPermission("PizzaAlias", AliasesPermission.Action.CREATE); BackupsPermission backups = new BackupsPermission("Pizza", BackupsPermission.Action.MANAGE); DataPermission data = new DataPermission("Pizza", DataPermission.Action.MANAGE); NodesPermission nodes = new NodesPermission("Pizza", NodesPermission.Action.READ); @@ -33,6 +34,11 @@ public static Object[][] serializationTestCases() { UsersPermission users = new UsersPermission(UsersPermission.Action.READ); return new Object[][] { + { + "alias permission", + (Supplier>) () -> alias, + new WeaviatePermission("create_backups", alias), + }, { "backup permission", (Supplier>) () -> backups, diff --git a/src/test/java/io/weaviate/integration/tests/rbac/ClientRbacTestSuite.java b/src/test/java/io/weaviate/integration/tests/rbac/ClientRbacTestSuite.java index 651df45b2..01333df2f 100644 --- a/src/test/java/io/weaviate/integration/tests/rbac/ClientRbacTestSuite.java +++ b/src/test/java/io/weaviate/integration/tests/rbac/ClientRbacTestSuite.java @@ -24,6 +24,7 @@ import io.weaviate.client.Config; import io.weaviate.client.base.Result; +import io.weaviate.client.v1.rbac.model.AliasesPermission; import io.weaviate.client.v1.rbac.model.BackupsPermission; import io.weaviate.client.v1.rbac.model.ClusterPermission; import io.weaviate.client.v1.rbac.model.CollectionsPermission; @@ -133,8 +134,10 @@ public void testCreate(String _name, Supplier rbac) { Rbac roles = rbac.get(); String myRole = roleName("VectorOwner"); String myCollection = "Pizza"; + String myCollectionAlias = "PizzaAlias"; Permission[] wantPermissions = new Permission[] { + Permission.alias(myCollectionAlias, AliasesPermission.Action.CREATE), Permission.backups(myCollection, BackupsPermission.Action.MANAGE), Permission.cluster(ClusterPermission.Action.READ), Permission.nodes(myCollection, NodesPermission.Action.READ), From 165058f020048f0ca5650da2d058d86e6e4f4490 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Thu, 10 Jul 2025 09:57:44 +0200 Subject: [PATCH 5/8] chore: rename Permission.alias -> Permission.aliases --- .../java/io/weaviate/client/v1/rbac/model/Permission.java | 4 ++-- .../weaviate/integration/tests/rbac/ClientRbacTestSuite.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/weaviate/client/v1/rbac/model/Permission.java b/src/main/java/io/weaviate/client/v1/rbac/model/Permission.java index 4e1691b6e..acf9350d6 100644 --- a/src/main/java/io/weaviate/client/v1/rbac/model/Permission.java +++ b/src/main/java/io/weaviate/client/v1/rbac/model/Permission.java @@ -132,9 +132,9 @@ private Key(Object object) { * Create {@link AliasesPermission} for a alias. *

* Example: - * {@code Permission.backups("Pizza", AliasPermission.Action.MANAGE) } + * {@code Permission.aliases("PizzaAlias", AliasPermission.Action.CREATE) } */ - public static AliasesPermission alias(String alias, AliasesPermission.Action... actions) { + public static AliasesPermission aliases(String alias, AliasesPermission.Action... actions) { checkDeprecation(actions); return new AliasesPermission(alias, actions); } diff --git a/src/test/java/io/weaviate/integration/tests/rbac/ClientRbacTestSuite.java b/src/test/java/io/weaviate/integration/tests/rbac/ClientRbacTestSuite.java index 01333df2f..9cd7e4c07 100644 --- a/src/test/java/io/weaviate/integration/tests/rbac/ClientRbacTestSuite.java +++ b/src/test/java/io/weaviate/integration/tests/rbac/ClientRbacTestSuite.java @@ -137,7 +137,7 @@ public void testCreate(String _name, Supplier rbac) { String myCollectionAlias = "PizzaAlias"; Permission[] wantPermissions = new Permission[] { - Permission.alias(myCollectionAlias, AliasesPermission.Action.CREATE), + Permission.aliases(myCollectionAlias, AliasesPermission.Action.CREATE), Permission.backups(myCollection, BackupsPermission.Action.MANAGE), Permission.cluster(ClusterPermission.Action.READ), Permission.nodes(myCollection, NodesPermission.Action.READ), From 8783c8b6f9786c828be09ea48fdd9f099ad2982a Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Thu, 10 Jul 2025 10:26:39 +0200 Subject: [PATCH 6/8] test: fix expected action value --- .../weaviate/client/v1/rbac/api/WeaviatePermissionTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/io/weaviate/client/v1/rbac/api/WeaviatePermissionTest.java b/src/test/java/io/weaviate/client/v1/rbac/api/WeaviatePermissionTest.java index f3028bbaa..2b67413c7 100644 --- a/src/test/java/io/weaviate/client/v1/rbac/api/WeaviatePermissionTest.java +++ b/src/test/java/io/weaviate/client/v1/rbac/api/WeaviatePermissionTest.java @@ -28,8 +28,8 @@ public class WeaviatePermissionTest { public void testMergedPermissions() { WeaviatePermission[] apiPermissions = { // Create and delete PizzaAlias alias - new WeaviatePermission("create_alias", new AliasesPermission("PizzaAlias")), - new WeaviatePermission("delete_alias", new AliasesPermission("PizzaAlias")), + new WeaviatePermission("create_aliases", new AliasesPermission("PizzaAlias")), + new WeaviatePermission("delete_aliases", new AliasesPermission("PizzaAlias")), // Manage Pizza backups new WeaviatePermission("manage_backups", new BackupsPermission("Pizza")), From 3861e7e8aacb0597b9c4badf7c12cd16fbb729e9 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Thu, 10 Jul 2025 10:31:13 +0200 Subject: [PATCH 7/8] chore: implement review feedback 1. Rename client.aliases() -> client.alias() Same for AliasesPermission and Permission.aliases: convert them to singular. 2. Add optional query parameter in 'get all' method to only fetch aliases declared for a collection. --- .../io/weaviate/client/WeaviateClient.java | 2 +- .../client/v1/aliases/api/AliasAllGetter.java | 11 +++++++++- .../client/v1/async/WeaviateAsyncClient.java | 2 +- .../v1/async/aliases/api/AliasAllGetter.java | 10 ++++++++- .../v1/rbac/api/WeaviatePermission.java | 8 +++---- ...esPermission.java => AliasPermission.java} | 6 +++--- .../client/v1/rbac/model/Permission.java | 10 ++++----- .../v1/rbac/api/WeaviatePermissionTest.java | 8 +++---- .../client/v1/rbac/model/PermissionTest.java | 2 +- .../client/aliases/ClientAliasesTest.java | 21 ++++++++++++------- .../async/aliases/ClientAliasesTest.java | 21 ++++++++++++------- .../tests/rbac/ClientRbacTestSuite.java | 4 ++-- 12 files changed, 68 insertions(+), 37 deletions(-) rename src/main/java/io/weaviate/client/v1/rbac/model/{AliasesPermission.java => AliasPermission.java} (74%) diff --git a/src/main/java/io/weaviate/client/WeaviateClient.java b/src/main/java/io/weaviate/client/WeaviateClient.java index 87d64801a..c12a58fc5 100644 --- a/src/main/java/io/weaviate/client/WeaviateClient.java +++ b/src/main/java/io/weaviate/client/WeaviateClient.java @@ -112,7 +112,7 @@ public Users users() { return new Users(httpClient, config); } - public Aliases aliases() { + public Aliases alias() { return new Aliases(httpClient, config); } diff --git a/src/main/java/io/weaviate/client/v1/aliases/api/AliasAllGetter.java b/src/main/java/io/weaviate/client/v1/aliases/api/AliasAllGetter.java index 195c46bc2..92d59652d 100644 --- a/src/main/java/io/weaviate/client/v1/aliases/api/AliasAllGetter.java +++ b/src/main/java/io/weaviate/client/v1/aliases/api/AliasAllGetter.java @@ -15,17 +15,26 @@ import io.weaviate.client.v1.aliases.model.Alias; public class AliasAllGetter extends BaseClient implements ClientResult> { + private String className; + public AliasAllGetter(HttpClient httpClient, Config config) { super(httpClient, config); } + /** List aliases defined for this class. */ + public AliasAllGetter withClassName(String className) { + this.className = className; + return this; + } + static class ResponseBody { List aliases; } @Override public Result> run() { - Response resp = sendGetRequest("/aliases", ResponseBody.class); + String path = "/aliases" + (className != null ? "?class=" + className : ""); + Response resp = sendGetRequest(path, ResponseBody.class); if (resp.getErrors() != null) { return new Result<>(resp, null); } diff --git a/src/main/java/io/weaviate/client/v1/async/WeaviateAsyncClient.java b/src/main/java/io/weaviate/client/v1/async/WeaviateAsyncClient.java index c0d4a8331..b8a31f94e 100644 --- a/src/main/java/io/weaviate/client/v1/async/WeaviateAsyncClient.java +++ b/src/main/java/io/weaviate/client/v1/async/WeaviateAsyncClient.java @@ -85,7 +85,7 @@ public Users users() { return new Users(client, config, tokenProvider); } - public Aliases aliases() { + public Aliases alias() { return new Aliases(client, config, tokenProvider); } diff --git a/src/main/java/io/weaviate/client/v1/async/aliases/api/AliasAllGetter.java b/src/main/java/io/weaviate/client/v1/async/aliases/api/AliasAllGetter.java index a876aeb64..76abe57f6 100644 --- a/src/main/java/io/weaviate/client/v1/async/aliases/api/AliasAllGetter.java +++ b/src/main/java/io/weaviate/client/v1/async/aliases/api/AliasAllGetter.java @@ -22,14 +22,22 @@ public class AliasAllGetter extends AsyncBaseClient> implements AsyncClientResult> { + private String className; public AliasAllGetter(CloseableHttpAsyncClient httpClient, Config config, AccessTokenProvider tokenProvider) { super(httpClient, config, tokenProvider); } + /** List aliases defined for this class. */ + public AliasAllGetter withClassName(String className) { + this.className = className; + return this; + } + @Override public Future>> run(FutureCallback>> callback) { - return sendGetRequest("/aliases", callback, new ResponseParser>() { + String path = "/aliases" + (className != null ? "?class=" + className : ""); + return sendGetRequest(path, callback, new ResponseParser>() { class ResponseBody { List aliases; diff --git a/src/main/java/io/weaviate/client/v1/rbac/api/WeaviatePermission.java b/src/main/java/io/weaviate/client/v1/rbac/api/WeaviatePermission.java index 65f6fe13d..b4cf28317 100644 --- a/src/main/java/io/weaviate/client/v1/rbac/api/WeaviatePermission.java +++ b/src/main/java/io/weaviate/client/v1/rbac/api/WeaviatePermission.java @@ -3,7 +3,7 @@ import java.util.ArrayList; import java.util.List; -import io.weaviate.client.v1.rbac.model.AliasesPermission; +import io.weaviate.client.v1.rbac.model.AliasPermission; import io.weaviate.client.v1.rbac.model.BackupsPermission; import io.weaviate.client.v1.rbac.model.CollectionsPermission; import io.weaviate.client.v1.rbac.model.DataPermission; @@ -26,7 +26,7 @@ @ToString public class WeaviatePermission { String action; - AliasesPermission aliases; + AliasPermission aliases; BackupsPermission backups; CollectionsPermission collections; DataPermission data; @@ -41,8 +41,8 @@ public WeaviatePermission(String action) { public

> WeaviatePermission(String action, Permission

perm) { this.action = action; - if (perm instanceof AliasesPermission) { - this.aliases = (AliasesPermission) perm; + if (perm instanceof AliasPermission) { + this.aliases = (AliasPermission) perm; } else if (perm instanceof BackupsPermission) { this.backups = (BackupsPermission) perm; } else if (perm instanceof CollectionsPermission) { diff --git a/src/main/java/io/weaviate/client/v1/rbac/model/AliasesPermission.java b/src/main/java/io/weaviate/client/v1/rbac/model/AliasPermission.java similarity index 74% rename from src/main/java/io/weaviate/client/v1/rbac/model/AliasesPermission.java rename to src/main/java/io/weaviate/client/v1/rbac/model/AliasPermission.java index b43909356..99e7f4a8c 100644 --- a/src/main/java/io/weaviate/client/v1/rbac/model/AliasesPermission.java +++ b/src/main/java/io/weaviate/client/v1/rbac/model/AliasPermission.java @@ -6,15 +6,15 @@ @Getter @EqualsAndHashCode(callSuper = true) -public class AliasesPermission extends Permission { +public class AliasPermission extends Permission { final String alias; - public AliasesPermission(String alias, Action... actions) { + public AliasPermission(String alias, Action... actions) { super(actions); this.alias = alias; } - AliasesPermission(String alias, String action) { + AliasPermission(String alias, String action) { this(alias, RbacAction.fromString(Action.class, action)); } diff --git a/src/main/java/io/weaviate/client/v1/rbac/model/Permission.java b/src/main/java/io/weaviate/client/v1/rbac/model/Permission.java index acf9350d6..70976837e 100644 --- a/src/main/java/io/weaviate/client/v1/rbac/model/Permission.java +++ b/src/main/java/io/weaviate/client/v1/rbac/model/Permission.java @@ -67,7 +67,7 @@ private WeaviatePermission toWeaviate(String action) { public static Permission fromWeaviate(WeaviatePermission perm) { String action = perm.getAction(); if (perm.getAliases() != null) { - return new AliasesPermission(perm.getAliases().getAlias(), action); + return new AliasPermission(perm.getAliases().getAlias(), action); } else if (perm.getBackups() != null) { return new BackupsPermission(perm.getBackups().getCollection(), action); } else if (perm.getCollections() != null) { @@ -129,14 +129,14 @@ private Key(Object object) { } /** - * Create {@link AliasesPermission} for a alias. + * Create {@link AliasPermission} for an alias. *

* Example: - * {@code Permission.aliases("PizzaAlias", AliasPermission.Action.CREATE) } + * {@code Permission.alias("PizzaAlias", AliasPermission.Action.CREATE) } */ - public static AliasesPermission aliases(String alias, AliasesPermission.Action... actions) { + public static AliasPermission alias(String alias, AliasPermission.Action... actions) { checkDeprecation(actions); - return new AliasesPermission(alias, actions); + return new AliasPermission(alias, actions); } /** diff --git a/src/test/java/io/weaviate/client/v1/rbac/api/WeaviatePermissionTest.java b/src/test/java/io/weaviate/client/v1/rbac/api/WeaviatePermissionTest.java index 2b67413c7..344b6992b 100644 --- a/src/test/java/io/weaviate/client/v1/rbac/api/WeaviatePermissionTest.java +++ b/src/test/java/io/weaviate/client/v1/rbac/api/WeaviatePermissionTest.java @@ -6,7 +6,7 @@ import org.junit.Test; -import io.weaviate.client.v1.rbac.model.AliasesPermission; +import io.weaviate.client.v1.rbac.model.AliasPermission; import io.weaviate.client.v1.rbac.model.BackupsPermission; import io.weaviate.client.v1.rbac.model.ClusterPermission; import io.weaviate.client.v1.rbac.model.CollectionsPermission; @@ -28,8 +28,8 @@ public class WeaviatePermissionTest { public void testMergedPermissions() { WeaviatePermission[] apiPermissions = { // Create and delete PizzaAlias alias - new WeaviatePermission("create_aliases", new AliasesPermission("PizzaAlias")), - new WeaviatePermission("delete_aliases", new AliasesPermission("PizzaAlias")), + new WeaviatePermission("create_aliases", new AliasPermission("PizzaAlias")), + new WeaviatePermission("delete_aliases", new AliasPermission("PizzaAlias")), // Manage Pizza backups new WeaviatePermission("manage_backups", new BackupsPermission("Pizza")), @@ -75,7 +75,7 @@ public void testMergedPermissions() { }; Permission[] libraryPermissions = { - new AliasesPermission("PizzaAlias", AliasesPermission.Action.CREATE, AliasesPermission.Action.DELETE), + new AliasPermission("PizzaAlias", AliasPermission.Action.CREATE, AliasPermission.Action.DELETE), new BackupsPermission("Pizza", BackupsPermission.Action.MANAGE), new DataPermission("Pizza", DataPermission.Action.MANAGE, DataPermission.Action.READ), new DataPermission("Songs", DataPermission.Action.UPDATE, DataPermission.Action.DELETE), diff --git a/src/test/java/io/weaviate/client/v1/rbac/model/PermissionTest.java b/src/test/java/io/weaviate/client/v1/rbac/model/PermissionTest.java index 07a5823ec..b1b358b80 100644 --- a/src/test/java/io/weaviate/client/v1/rbac/model/PermissionTest.java +++ b/src/test/java/io/weaviate/client/v1/rbac/model/PermissionTest.java @@ -23,7 +23,7 @@ @RunWith(JParamsTestRunner.class) public class PermissionTest { public static Object[][] serializationTestCases() { - AliasesPermission alias = new AliasesPermission("PizzaAlias", AliasesPermission.Action.CREATE); + AliasPermission alias = new AliasPermission("PizzaAlias", AliasPermission.Action.CREATE); BackupsPermission backups = new BackupsPermission("Pizza", BackupsPermission.Action.MANAGE); DataPermission data = new DataPermission("Pizza", DataPermission.Action.MANAGE); NodesPermission nodes = new NodesPermission("Pizza", NodesPermission.Action.READ); diff --git a/src/test/java/io/weaviate/integration/client/aliases/ClientAliasesTest.java b/src/test/java/io/weaviate/integration/client/aliases/ClientAliasesTest.java index 1d5c89ed6..83f0f96d2 100644 --- a/src/test/java/io/weaviate/integration/client/aliases/ClientAliasesTest.java +++ b/src/test/java/io/weaviate/integration/client/aliases/ClientAliasesTest.java @@ -6,6 +6,7 @@ import java.util.Map; import org.assertj.core.api.Assertions; +import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.Before; import org.junit.ClassRule; import org.junit.Test; @@ -41,11 +42,11 @@ public void shouldManageAliases() { assumeTrue(createdGeorge.getResult(), "created GeorgeBarnes collection"); // Act: create alias - client.aliases().creator().withClassName("PaulHewson").withAlias("Bono").run(); - client.aliases().creator().withClassName("GeorgeBarnes").withAlias("MachineGunKelly").run(); + client.alias().creator().withClassName("PaulHewson").withAlias("Bono").run(); + client.alias().creator().withClassName("GeorgeBarnes").withAlias("MachineGunKelly").run(); // Assert: get all - Result> all = client.aliases().allGetter().run(); + Result> all = client.alias().allGetter().run(); Assertions.assertThat(all.getError()).isNull(); Assertions.assertThat(all.getResult()) @@ -62,21 +63,27 @@ public void shouldManageAliases() { .className("ColsonBaker").build()).run(); assumeTrue(createdMGK.getResult(), "created ColsonBaker collection"); - client.aliases().updater().withAlias("MachineGunKelly").withNewClassName("ColsonBaker").run(); + client.alias().updater().withAlias("MachineGunKelly").withNewClassName("ColsonBaker").run(); // Assert: get one - Result mgk = client.aliases().getter().withAlias("MachineGunKelly").run(); + Result mgk = client.alias().getter().withAlias("MachineGunKelly").run(); Assertions.assertThat(mgk.getResult()) .as("MachineGunKelly alias points to ColsonBaker") .returns("MachineGunKelly", Alias::getAlias) .returns("ColsonBaker", Alias::getClassName); + Result> colsonAliases = client.alias().allGetter().withClassName("ColsonBaker").run(); + Assertions.assertThat(colsonAliases.getResult()) + .containsOnlyKeys("MachineGunKelly") + .extracting(Map::values, InstanceOfAssertFactories.collection(Alias.class)) + .extracting(Alias::getClassName).containsOnly("ColsonBaker"); + // Act: delete - client.aliases().deleter().withAlias("Bono").run(); + client.alias().deleter().withAlias("Bono").run(); // Assert - Result bono = client.aliases().getter().withAlias("Bono").run(); + Result bono = client.alias().getter().withAlias("Bono").run(); Assertions.assertThat(bono) .as("Bono alias deleted") .returns(null, Result::getResult) diff --git a/src/test/java/io/weaviate/integration/client/async/aliases/ClientAliasesTest.java b/src/test/java/io/weaviate/integration/client/async/aliases/ClientAliasesTest.java index 2ffbb7c4d..9a071151a 100644 --- a/src/test/java/io/weaviate/integration/client/async/aliases/ClientAliasesTest.java +++ b/src/test/java/io/weaviate/integration/client/async/aliases/ClientAliasesTest.java @@ -7,6 +7,7 @@ import java.util.concurrent.ExecutionException; import org.assertj.core.api.Assertions; +import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.After; import org.junit.Before; import org.junit.ClassRule; @@ -49,11 +50,11 @@ public void shouldManageAliases() throws InterruptedException, ExecutionExceptio assumeTrue(createdGeorge.getResult(), "created GeorgeBarnes collection"); // Act: create alias - client.aliases().creator().withClassName("PaulHewson").withAlias("Bono").run().get(); - client.aliases().creator().withClassName("GeorgeBarnes").withAlias("MachineGunKelly").run().get(); + client.alias().creator().withClassName("PaulHewson").withAlias("Bono").run().get(); + client.alias().creator().withClassName("GeorgeBarnes").withAlias("MachineGunKelly").run().get(); // Assert: get all - Result> all = client.aliases().allGetter().run().get(); + Result> all = client.alias().allGetter().run().get(); Assertions.assertThat(all.getError()).isNull(); Assertions.assertThat(all.getResult()) @@ -70,21 +71,27 @@ public void shouldManageAliases() throws InterruptedException, ExecutionExceptio .className("ColsonBaker").build()).run().get(); assumeTrue(createdMGK.getResult(), "created ColsonBaker collection"); - client.aliases().updater().withAlias("MachineGunKelly").withNewClassName("ColsonBaker").run().get(); + client.alias().updater().withAlias("MachineGunKelly").withNewClassName("ColsonBaker").run().get(); // Assert: get one - Result mgk = client.aliases().getter().withAlias("MachineGunKelly").run().get(); + Result mgk = client.alias().getter().withAlias("MachineGunKelly").run().get(); Assertions.assertThat(mgk.getResult()) .as("MachineGunKelly alias points to ColsonBaker") .returns("MachineGunKelly", Alias::getAlias) .returns("ColsonBaker", Alias::getClassName); + Result> colsonAliases = client.alias().allGetter().withClassName("ColsonBaker").run().get(); + Assertions.assertThat(colsonAliases.getResult()) + .containsOnlyKeys("MachineGunKelly") + .extracting(Map::values, InstanceOfAssertFactories.collection(Alias.class)) + .extracting(Alias::getClassName).containsOnly("ColsonBaker"); + // Act: delete - client.aliases().deleter().withAlias("Bono").run().get(); + client.alias().deleter().withAlias("Bono").run().get(); // Assert - Result bono = client.aliases().getter().withAlias("Bono").run().get(); + Result bono = client.alias().getter().withAlias("Bono").run().get(); Assertions.assertThat(bono) .as("Bono alias deleted") .returns(null, Result::getResult) diff --git a/src/test/java/io/weaviate/integration/tests/rbac/ClientRbacTestSuite.java b/src/test/java/io/weaviate/integration/tests/rbac/ClientRbacTestSuite.java index 9cd7e4c07..b61f5c199 100644 --- a/src/test/java/io/weaviate/integration/tests/rbac/ClientRbacTestSuite.java +++ b/src/test/java/io/weaviate/integration/tests/rbac/ClientRbacTestSuite.java @@ -24,7 +24,7 @@ import io.weaviate.client.Config; import io.weaviate.client.base.Result; -import io.weaviate.client.v1.rbac.model.AliasesPermission; +import io.weaviate.client.v1.rbac.model.AliasPermission; import io.weaviate.client.v1.rbac.model.BackupsPermission; import io.weaviate.client.v1.rbac.model.ClusterPermission; import io.weaviate.client.v1.rbac.model.CollectionsPermission; @@ -137,7 +137,7 @@ public void testCreate(String _name, Supplier rbac) { String myCollectionAlias = "PizzaAlias"; Permission[] wantPermissions = new Permission[] { - Permission.aliases(myCollectionAlias, AliasesPermission.Action.CREATE), + Permission.alias(myCollectionAlias, AliasPermission.Action.CREATE), Permission.backups(myCollection, BackupsPermission.Action.MANAGE), Permission.cluster(ClusterPermission.Action.READ), Permission.nodes(myCollection, NodesPermission.Action.READ), From 70733c7d46af37d8c9625169084461de72aaee15 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Thu, 10 Jul 2025 11:52:58 +0200 Subject: [PATCH 8/8] fix: typo in tests --- .../java/io/weaviate/client/v1/rbac/model/PermissionTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/io/weaviate/client/v1/rbac/model/PermissionTest.java b/src/test/java/io/weaviate/client/v1/rbac/model/PermissionTest.java index b1b358b80..62320a328 100644 --- a/src/test/java/io/weaviate/client/v1/rbac/model/PermissionTest.java +++ b/src/test/java/io/weaviate/client/v1/rbac/model/PermissionTest.java @@ -37,7 +37,7 @@ public static Object[][] serializationTestCases() { { "alias permission", (Supplier>) () -> alias, - new WeaviatePermission("create_backups", alias), + new WeaviatePermission("create_aliases", alias), }, { "backup permission",