Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions src/it/java/io/weaviate/integration/AliasITest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package io.weaviate.integration;

import java.io.IOException;
import java.util.List;

import org.assertj.core.api.Assertions;
import org.junit.Test;

import io.weaviate.ConcurrentTest;
import io.weaviate.client6.v1.api.WeaviateClient;
import io.weaviate.client6.v1.api.alias.Alias;
import io.weaviate.containers.Container;

public class AliasITest extends ConcurrentTest {
private static WeaviateClient client = Container.WEAVIATE.getClient();

@Test
public void test_aliasLifecycle() throws IOException {
// Arrange
var nsPaulHewson = ns("PaulHewson");
var nsGeorgeBarnes = ns("GeorgeBarnes");
var nsColsonBaker = ns("ColsonBaker");

for (var collection : List.of(nsPaulHewson, nsGeorgeBarnes, nsColsonBaker)) {
client.collections.create(collection);
}

// Act: create aliases
client.alias.create(nsPaulHewson, "Bono");
client.alias.create(nsGeorgeBarnes, "MachineGunKelly");

// Assert: list all
var aliases = client.alias.list();
Assertions.assertThat(aliases).hasSize(2);
Assertions.assertThat(aliases)
.as("created Bono and MachineGunKelly aliases")
.contains(
new Alias(nsPaulHewson, "Bono"),
new Alias(nsGeorgeBarnes, "MachineGunKelly"));

// Act: update aliases
client.alias.update("MachineGunKelly", nsColsonBaker);

// Assert: check MGK points to another collection
var mgk = client.alias.get("MachineGunKelly");
Assertions.assertThat(mgk).get()
.as("updated MachineGunKelly alias")
.returns(nsColsonBaker, Alias::collection);

// Act: delete Bono alias
client.alias.delete("Bono");

// Assert
var paulHewsonAliases = client.alias.list(all -> all.collection(nsPaulHewson));
Assertions.assertThat(paulHewsonAliases)
.as("no aliases once Bono is deleted")
.isEmpty();
}
}
10 changes: 10 additions & 0 deletions src/main/java/io/weaviate/client6/v1/api/WeaviateClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.io.IOException;
import java.util.function.Function;

import io.weaviate.client6.v1.api.alias.WeaviateAliasClient;
import io.weaviate.client6.v1.api.collections.WeaviateCollectionsClient;
import io.weaviate.client6.v1.internal.ObjectBuilder;
import io.weaviate.client6.v1.internal.TokenProvider;
Expand All @@ -20,8 +21,16 @@ public class WeaviateClient implements AutoCloseable {
private final RestTransport restTransport;
private final GrpcTransport grpcTransport;

/**
* Client for {@code /schema} endpoints for managing Weaviate collections.
* See {@link WeaviateCollectionsClient#use} for populating and querying
* collections.
*/
public final WeaviateCollectionsClient collections;

/** Client for {@code /aliases} endpoints for managing collection aliases. */
public final WeaviateAliasClient alias;

public WeaviateClient(Config config) {
this.config = config;

Expand All @@ -46,6 +55,7 @@ public WeaviateClient(Config config) {
this.restTransport = new DefaultRestTransport(restOpt);
this.grpcTransport = new DefaultGrpcTransport(grpcOpt);

this.alias = new WeaviateAliasClient(restTransport);
this.collections = new WeaviateCollectionsClient(restTransport, grpcTransport);
}

Expand Down
11 changes: 11 additions & 0 deletions src/main/java/io/weaviate/client6/v1/api/WeaviateClientAsync.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;

import io.weaviate.client6.v1.api.alias.WeaviateAliasClientAsync;
import io.weaviate.client6.v1.api.collections.WeaviateCollectionsClient;
import io.weaviate.client6.v1.api.collections.WeaviateCollectionsClientAsync;
import io.weaviate.client6.v1.internal.ObjectBuilder;
import io.weaviate.client6.v1.internal.TokenProvider;
Expand All @@ -18,8 +20,16 @@ public class WeaviateClientAsync implements AutoCloseable {
private final RestTransport restTransport;
private final GrpcTransport grpcTransport;

/**
* Client for {@code /schema} endpoints for managing Weaviate collections.
* See {@link WeaviateCollectionsClient#use} for populating and querying
* collections.
*/
public final WeaviateCollectionsClientAsync collections;

/** Client for {@code /aliases} endpoints for managing collection aliases. */
public final WeaviateAliasClientAsync alias;

/**
* This constructor is blocking if {@link Authentication} configured,
* as the client will need to do the initial token exchange.
Expand All @@ -46,6 +56,7 @@ public WeaviateClientAsync(Config config) {
this.restTransport = new DefaultRestTransport(restOpt);
this.grpcTransport = new DefaultGrpcTransport(grpcOpt);

this.alias = new WeaviateAliasClientAsync(restTransport);
this.collections = new WeaviateCollectionsClientAsync(restTransport, grpcTransport);
}

Expand Down
10 changes: 10 additions & 0 deletions src/main/java/io/weaviate/client6/v1/api/alias/Alias.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.weaviate.client6.v1.api.alias;

import com.google.gson.annotations.SerializedName;

public record Alias(
/** Original collection name. */
@SerializedName("class") String collection,
/** Collection alias. */
@SerializedName("alias") String alias) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package io.weaviate.client6.v1.api.alias;

import java.util.Collections;

import io.weaviate.client6.v1.internal.json.JSON;
import io.weaviate.client6.v1.internal.rest.Endpoint;
import io.weaviate.client6.v1.internal.rest.SimpleEndpoint;

public record CreateAliasRequest(Alias alias) {
public final static Endpoint<CreateAliasRequest, Void> _ENDPOINT = SimpleEndpoint.sideEffect(
__ -> "POST",
__ -> "/aliases/",
__ -> Collections.emptyMap(),
request -> JSON.serialize(request.alias));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.weaviate.client6.v1.api.alias;

import java.util.Collections;

import io.weaviate.client6.v1.internal.rest.Endpoint;
import io.weaviate.client6.v1.internal.rest.SimpleEndpoint;

public record DeleteAliasRequest(String alias) {
public final static Endpoint<DeleteAliasRequest, Void> _ENDPOINT = SimpleEndpoint.sideEffect(
__ -> "DELETE",
request -> "/aliases/" + request.alias,
__ -> Collections.emptyMap());
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.weaviate.client6.v1.api.alias;

import java.util.Collections;
import java.util.Optional;

import io.weaviate.client6.v1.internal.json.JSON;
import io.weaviate.client6.v1.internal.rest.Endpoint;
import io.weaviate.client6.v1.internal.rest.OptionalEndpoint;

public record GetAliasRequest(String alias) {
public final static Endpoint<GetAliasRequest, Optional<Alias>> _ENDPOINT = OptionalEndpoint.noBodyOptional(
__ -> "GET",
request -> "/aliases/" + request.alias,
__ -> Collections.emptyMap(),
(statusCode, response) -> JSON.deserialize(response, Alias.class));

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package io.weaviate.client6.v1.api.alias;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

import io.weaviate.client6.v1.internal.ObjectBuilder;
import io.weaviate.client6.v1.internal.json.JSON;
import io.weaviate.client6.v1.internal.rest.Endpoint;
import io.weaviate.client6.v1.internal.rest.SimpleEndpoint;

public record ListAliasRequest(String collection) {
public final static Endpoint<ListAliasRequest, List<Alias>> _ENDPOINT = SimpleEndpoint.noBody(
__ -> "GET",
__ -> "/aliases",
request -> request.collection != null
? Map.of("class", request.collection)
: Collections.emptyMap(),
(statusCode, response) -> JSON.deserialize(response, ListAliasResponse.class).aliases());

/** Create default ListAliasRequest. */
public static ListAliasRequest of() {
return of(ObjectBuilder.identity());
}

/** Create ListAliasRequest with optional parameters. */
public static ListAliasRequest of(Function<Builder, ObjectBuilder<ListAliasRequest>> fn) {
return fn.apply(new Builder()).build();
}

public ListAliasRequest(Builder builder) {
this(builder.collection);
}

public static class Builder implements ObjectBuilder<ListAliasRequest> {
private String collection;

/** Return only aliases which reference this collection. */
public Builder collection(String collection) {
this.collection = collection;
return this;
}

@Override
public ListAliasRequest build() {
return new ListAliasRequest(this);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.weaviate.client6.v1.api.alias;

import java.util.List;

import com.google.gson.annotations.SerializedName;

public record ListAliasResponse(@SerializedName("aliases") List<Alias> aliases) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.weaviate.client6.v1.api.alias;

import java.util.Collections;

import com.google.gson.annotations.SerializedName;

import io.weaviate.client6.v1.internal.json.JSON;
import io.weaviate.client6.v1.internal.rest.Endpoint;
import io.weaviate.client6.v1.internal.rest.SimpleEndpoint;

public record UpdateAliasRequest(String alias, String newTargetCollection) {
public final static Endpoint<UpdateAliasRequest, Void> _ENDPOINT = SimpleEndpoint.sideEffect(
__ -> "PUT",
request -> "/aliases/" + request.alias,
__ -> Collections.emptyMap(),
request -> JSON.serialize(request.toRequestBody()));

private RequestBody toRequestBody() {
return new RequestBody();
}

private class RequestBody {
@SerializedName("class")
private final String collection = UpdateAliasRequest.this.newTargetCollection;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package io.weaviate.client6.v1.api.alias;

import java.io.IOException;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;

import io.weaviate.client6.v1.api.WeaviateApiException;
import io.weaviate.client6.v1.internal.ObjectBuilder;
import io.weaviate.client6.v1.internal.rest.RestTransport;

public class WeaviateAliasClient {
private final RestTransport restTransport;

public WeaviateAliasClient(RestTransport restTransport) {
this.restTransport = restTransport;
}

/**
* Create a new collection alias.
*
* @param collection Original collection name.
* @param alias Collection alias.
* @throws WeaviateApiException in case the server returned with an
* error status code.
* @throws IOException in case the request was not sent successfully
* due to a malformed request, a networking error
* or the server being unavailable.
*/
public void create(String collection, String alias) throws IOException {
create(new Alias(collection, alias));
}

/**
* Create a new collection alias.
*
* @param alias Alias object.
* @throws WeaviateApiException in case the server returned with an
* error status code.
* @throws IOException in case the request was not sent successfully
* due to a malformed request, a networking error
* or the server being unavailable.
*/
public void create(Alias alias) throws IOException {
this.restTransport.performRequest(new CreateAliasRequest(alias), CreateAliasRequest._ENDPOINT);
}

/**
* List all collection aliases defined in the cluster.
*
* @throws WeaviateApiException in case the server returned with an
* error status code.
* @throws IOException in case the request was not sent successfully
* due to a malformed request, a networking error
* or the server being unavailable.
*/
public List<Alias> list() throws IOException {
return list(ListAliasRequest.of());
}

/**
* List all collection aliases defined in the cluster.
*
* @param fn Lambda expression for optional parameters.
* @throws WeaviateApiException in case the server returned with an
* error status code.
* @throws IOException in case the request was not sent successfully
* due to a malformed request, a networking error
* or the server being unavailable.
* @return A list of aliases.
*/
public List<Alias> list(Function<ListAliasRequest.Builder, ObjectBuilder<ListAliasRequest>> fn) throws IOException {
return list(ListAliasRequest.of(fn));
}

private List<Alias> list(ListAliasRequest request) throws IOException {
return this.restTransport.performRequest(request, ListAliasRequest._ENDPOINT);
}

/**
* Get alias by name.
*
* @param alias Collection alias.
* @throws WeaviateApiException in case the server returned with an
* error status code.
* @throws IOException in case the request was not sent successfully
* due to a malformed request, a networking error
* or the server being unavailable.
* @return Alias if one exists and empty {@code Optional} otherwise.
*/
public Optional<Alias> get(String alias) throws IOException {
return this.restTransport.performRequest(new GetAliasRequest(alias), GetAliasRequest._ENDPOINT);
}

/**
* Change which collection this alias references.
*
* @param alias Collection alias.
* @param newTargetCollection Collection name.
* @throws WeaviateApiException in case the server returned with an
* error status code.
* @throws IOException in case the request was not sent successfully
* due to a malformed request, a networking error
* or the server being unavailable.
*/
public void update(String alias, String newTargetCollection) throws IOException {
this.restTransport.performRequest(new UpdateAliasRequest(alias, newTargetCollection),
UpdateAliasRequest._ENDPOINT);
}

/**
* Delete an alias. The previously aliased collection is not affected.
*
* @param alias Collection alias.
* @throws WeaviateApiException in case the server returned with an
* error status code.
* @throws IOException in case the request was not sent successfully
* due to a malformed request, a networking error
* or the server being unavailable.
*/
public void delete(String alias) throws IOException {
this.restTransport.performRequest(new DeleteAliasRequest(alias), DeleteAliasRequest._ENDPOINT);
}
}
Loading