diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index dec60bc76..cdcf934fc 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -19,103 +19,103 @@ jobs: name: Cache shared Docker images runs-on: ubuntu-latest steps: - - name: Login to Docker Hub - if: ${{ !github.event.pull_request.head.repo.fork }} - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - id: cache-check - uses: actions/cache/restore@v4 - env: - DOCKER_CACHE_KEY: docker-images-${{ env.IMG2VEC }}-${{ env.MINIO }}-${{ env.MODEL2VEC }} - with: - path: ${{ env.DOCKER_IMAGES_TAR }} - key: ${{ env.DOCKER_CACHE_KEY }} - lookup-only: true # Only check if cache exists, don't download - - name: Free Disk Space (Ubuntu) - uses: jlumbroso/free-disk-space@v1.3.1 - with: - tool-cache: false - android: true - dotnet: true - haskell: true - large-packages: true - docker-images: false - swap-storage: false - - name: Pull images - if: steps.cache-check.outputs.cache-hit != 'true' - run: | - docker pull $IMG2VEC - docker pull $MINIO - # docker pull $MODEL2VEC - docker save $IMG2VEC $MINIO -o $DOCKER_IMAGES_TAR - - name: Cache images - if: steps.cache-check.outputs.cache-hit != 'true' - uses: actions/cache/save@v4 - env: - DOCKER_CACHE_KEY: docker-images-${{ env.IMG2VEC }}-${{ env.MINIO }}-${{ env.MODEL2VEC }} - with: - path: ${{ env.DOCKER_IMAGES_TAR }} - key: ${{ env.DOCKER_CACHE_KEY }} + - name: Login to Docker Hub + if: ${{ !github.event.pull_request.head.repo.fork }} + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + - id: cache-check + uses: actions/cache/restore@v4 + env: + DOCKER_CACHE_KEY: docker-images-${{ env.IMG2VEC }}-${{ env.MINIO }}-${{ env.MODEL2VEC }} + with: + path: ${{ env.DOCKER_IMAGES_TAR }} + key: ${{ env.DOCKER_CACHE_KEY }} + lookup-only: true # Only check if cache exists, don't download + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@v1.3.1 + with: + tool-cache: false + android: true + dotnet: true + haskell: true + large-packages: true + docker-images: false + swap-storage: false + - name: Pull images + if: steps.cache-check.outputs.cache-hit != 'true' + run: | + docker pull $IMG2VEC + docker pull $MINIO + # docker pull $MODEL2VEC + docker save $IMG2VEC $MINIO -o $DOCKER_IMAGES_TAR + - name: Cache images + if: steps.cache-check.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + env: + DOCKER_CACHE_KEY: docker-images-${{ env.IMG2VEC }}-${{ env.MINIO }}-${{ env.MODEL2VEC }} + with: + path: ${{ env.DOCKER_IMAGES_TAR }} + key: ${{ env.DOCKER_CACHE_KEY }} maven-cache: - name: Cache Maven dependencies - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 - with: - distribution: 'zulu' - java-version: '17' - cache: 'maven' - - run: mvn dependency:go-offline + name: Cache Maven dependencies + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: "zulu" + java-version: "17" + cache: "maven" + - run: mvn dependency:go-offline test: name: Test runs-on: ubuntu-latest - needs: [ docker-cache, maven-cache] + needs: [docker-cache, maven-cache] strategy: fail-fast: false matrix: - WEAVIATE_VERSION: ["1.32.16", "1.33.4", "1.34.0"] + WEAVIATE_VERSION: ["1.32.24", "1.33.11", "1.34.7", "1.35.2"] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - - uses: actions/cache/restore@v4 - env: - DOCKER_CACHE_KEY: docker-images-${{ env.IMG2VEC }}-${{ env.MINIO }}-${{ env.MODEL2VEC }} - with: - path: ${{ env.DOCKER_IMAGES_TAR }} - key: ${{ env.DOCKER_CACHE_KEY }} - - name: Free Disk Space (Ubuntu) - uses: jlumbroso/free-disk-space@v1.3.1 - with: - tool-cache: false - android: true - dotnet: true - haskell: true - large-packages: true - docker-images: false - swap-storage: false - - name: Load Docker images - run: | - if [ -f $DOCKER_IMAGES_TAR ]; then - docker load -i $DOCKER_IMAGES_TAR - fi - - uses: actions/setup-java@v4 - name: Setup JDK - with: - distribution: 'zulu' - java-version: '17' - cache: 'maven' + - uses: actions/cache/restore@v4 + env: + DOCKER_CACHE_KEY: docker-images-${{ env.IMG2VEC }}-${{ env.MINIO }}-${{ env.MODEL2VEC }} + with: + path: ${{ env.DOCKER_IMAGES_TAR }} + key: ${{ env.DOCKER_CACHE_KEY }} + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@v1.3.1 + with: + tool-cache: false + android: true + dotnet: true + haskell: true + large-packages: true + docker-images: false + swap-storage: false + - name: Load Docker images + run: | + if [ -f $DOCKER_IMAGES_TAR ]; then + docker load -i $DOCKER_IMAGES_TAR + fi + - uses: actions/setup-java@v4 + name: Setup JDK + with: + distribution: "zulu" + java-version: "17" + cache: "maven" - - name: Run Tests (v${{ matrix.WEAVIATE_VERSION }}) - env: - OKTA_DUMMY_CI_PW: ${{ secrets.OKTA_DUMMY_CI_PW }} - WCS_DUMMY_CI_PW: ${{ secrets.WCS_DUMMY_CI_PW }} - OKTA_CLIENT_SECRET: ${{ secrets.OKTA_CLIENT_SECRET }} - AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }} - OPENAI_APIKEY: ${{ secrets.OPENAI_APIKEY }} - WEAVIATE_VERSION: ${{ matrix.WEAVIATE_VERSION }} - run: mvn verify -Dgpg.skip + - name: Run Tests (v${{ matrix.WEAVIATE_VERSION }}) + env: + OKTA_DUMMY_CI_PW: ${{ secrets.OKTA_DUMMY_CI_PW }} + WCS_DUMMY_CI_PW: ${{ secrets.WCS_DUMMY_CI_PW }} + OKTA_CLIENT_SECRET: ${{ secrets.OKTA_CLIENT_SECRET }} + AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }} + OPENAI_APIKEY: ${{ secrets.OPENAI_APIKEY }} + WEAVIATE_VERSION: ${{ matrix.WEAVIATE_VERSION }} + run: mvn verify -Dgpg.skip diff --git a/src/it/java/io/weaviate/containers/Weaviate.java b/src/it/java/io/weaviate/containers/Weaviate.java index 31a6076db..0f463e96f 100644 --- a/src/it/java/io/weaviate/containers/Weaviate.java +++ b/src/it/java/io/weaviate/containers/Weaviate.java @@ -26,7 +26,7 @@ public class Weaviate extends WeaviateContainer { public static final String DOCKER_IMAGE = "semitechnologies/weaviate"; - public static final String LATEST_VERSION = Version.V134.semver.toString(); + public static final String LATEST_VERSION = Version.V135.semver.toString(); public static final String VERSION; static { @@ -38,9 +38,10 @@ public class Weaviate extends WeaviateContainer { private final String containerName; public enum Version { - V132(1, 32, 16), - V133(1, 33, 4), - V134(1, 34, 0); + V132(1, 32, 24), + V133(1, 33, 11), + V134(1, 34, 7), + V135(1, 35, 2); public final SemanticVersion semver; @@ -259,6 +260,15 @@ public Builder enableAnonymousAccess(boolean enable) { return this; } + /** User default OIDC provider for integration tests. */ + public Builder withOIDC() { + return withOIDC( + "Peuc12y02UA0eAED1dqSjE5HtGUrpBsx", + "https://auth.weaviate.cloud/Peuc12y02UA0eAED1dqSjE5HtGUrpBsx", + "email", "roles"); + + } + public Builder withOIDC(String clientId, String issuer, String usernameClaim, String groupsClaim) { enableAnonymousAccess(false); environment.put("AUTHENTICATION_OIDC_ENABLED", "true"); diff --git a/src/it/java/io/weaviate/integration/CollectionsITest.java b/src/it/java/io/weaviate/integration/CollectionsITest.java index b3953ab08..8d68bb1c6 100644 --- a/src/it/java/io/weaviate/integration/CollectionsITest.java +++ b/src/it/java/io/weaviate/integration/CollectionsITest.java @@ -13,6 +13,7 @@ import io.weaviate.client6.v1.api.collections.DataType; import io.weaviate.client6.v1.api.collections.Generative; import io.weaviate.client6.v1.api.collections.InvertedIndex; +import io.weaviate.client6.v1.api.collections.ObjectTtl; import io.weaviate.client6.v1.api.collections.Property; import io.weaviate.client6.v1.api.collections.Quantization; import io.weaviate.client6.v1.api.collections.ReferenceProperty; @@ -21,6 +22,7 @@ import io.weaviate.client6.v1.api.collections.config.Shard; import io.weaviate.client6.v1.api.collections.config.ShardStatus; import io.weaviate.client6.v1.api.collections.generative.DummyGenerative; +import io.weaviate.client6.v1.api.collections.query.BaseQueryOptions; import io.weaviate.client6.v1.api.collections.vectorindex.Hnsw; import io.weaviate.client6.v1.api.collections.vectorizers.SelfProvidedVectorizer; import io.weaviate.containers.Container; @@ -275,4 +277,55 @@ public void test_updateGenerative() throws IOException { .extracting(CollectionConfig::generativeModule).isNotNull() .returns(Generative.Kind.DUMMY, Generative::_kind); } + + @Test + public void test_objectTtl() throws IOException { + Weaviate.Version.V135.orSkip(); + + // Arrange + var nsThings = ns("Things"); + + // Act: create collection + var things = client.collections.create(nsThings, + c -> c.objectTtl(ttl -> ttl + .deleteByCreationTime() + .defaultTtlSeconds(120))); + + // Assert: correct Object TTL config + var created = things.config.get(); + + Assertions.assertThat(created).get() + .as("created collection") + .extracting(CollectionConfig::objectTtl).isNotNull() + .returns(true, ObjectTtl::enabled) + .returns(BaseQueryOptions.CREATION_TIME_PROPERTY, ObjectTtl::deleteOn) + .returns(120, ObjectTtl::defaultTtlSeconds); + + // Act: update TTL config + things.config.update( + c -> c.objectTtl(ttl -> ttl + .deleteByUpdateTime() + .defaultTtlSeconds(400))); + + // Assert: correct Object TTL config + var updated = things.config.get(); + + Assertions.assertThat(updated).get() + .as("updated collection") + .extracting(CollectionConfig::objectTtl).isNotNull() + .returns(true, ObjectTtl::enabled) + .returns(BaseQueryOptions.LAST_UPDATE_TIME_PROPERTY, ObjectTtl::deleteOn) + .returns(400, ObjectTtl::defaultTtlSeconds); + + // Act: disable TTL config + things.config.update(c -> c.objectTtl(ttl -> ttl.enabled(false))); + + // Assert: correct Object TTL config + var disabled = things.config.get(); + + Assertions.assertThat(disabled).get() + .as("disabled object TTL") + .extracting(CollectionConfig::objectTtl).isNotNull() + .returns(false, ObjectTtl::enabled); + } } diff --git a/src/it/java/io/weaviate/integration/OIDCSupportITest.java b/src/it/java/io/weaviate/integration/OIDCSupportITest.java index f6d2f3f55..fbbbd8c67 100644 --- a/src/it/java/io/weaviate/integration/OIDCSupportITest.java +++ b/src/it/java/io/weaviate/integration/OIDCSupportITest.java @@ -3,6 +3,7 @@ import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; +import java.time.Duration; import java.util.List; import java.util.UUID; @@ -13,6 +14,7 @@ import io.weaviate.ConcurrentTest; import io.weaviate.client6.v1.api.Authentication; import io.weaviate.client6.v1.internal.TokenProvider; +import io.weaviate.client6.v1.internal.TokenProvider.Token; import io.weaviate.client6.v1.internal.rest.RestTransport; import io.weaviate.containers.Weaviate; @@ -34,9 +36,7 @@ public class OIDCSupportITest extends ConcurrentTest { * Weaviate container that uses WCS-backed OIDC provider. * Supports ResourceOwnerPassword and RefreshToken authentication flows. */ - private static final Weaviate wcsContainer = Weaviate.custom() - .withOIDC("Peuc12y02UA0eAED1dqSjE5HtGUrpBsx", "https://auth.weaviate.cloud/Peuc12y02UA0eAED1dqSjE5HtGUrpBsx", "email", "roles") - .build(); + private static final Weaviate wcsContainer = Weaviate.custom().withOIDC().build(); private static final String OKTA_CLIENT_ID = "0oa7e9ipdkVZRUcxo5d7"; private static final String OKTA_CLIENT_SECRET = System.getenv("OKTA_CLIENT_SECRET"); @@ -76,8 +76,7 @@ public void test_bearerToken() throws Exception { pingWeaviateAsync(wcsContainer, auth); } - // TODO[g-despot] Fix test after release, descope has been deprecated - // @Test + @Test public void test_resourceOwnerPassword() throws Exception { Assume.assumeTrue("WCS_DUMMY_CI_PW is not set", WCS_DUMMY_CI_PW != null && !WCS_DUMMY_CI_PW.isBlank()); Assume.assumeTrue("no internet connection", hasInternetConnection()); @@ -91,9 +90,10 @@ public void test_resourceOwnerPassword() throws Exception { // Get the token obtained by the wrapped TokenProvider. var t = auth.getToken(); - // Now make all tokens expire immediately, forcing the client to refresh.. - // Verify the new token is different from the one before. - auth.setExpiresIn(0); + // Wait for the token to expire. Because we're testing against a live IdP + // and cannot control it at test, all other "mocking" options are more + // intrusive. Verify the new token is different from the one before. + waitForExpiry(t); pingWeaviate(wcsContainer, auth); var newT = auth.getToken(); @@ -116,9 +116,10 @@ public void test_clientCredentials() throws Exception { // Get the token obtained by the wrapped TokenProvider. var t = auth.getToken(); - // Now make all tokens expire immediately, forcing the client to refresh.. - // Verify the new token is different from the one before. - auth.setExpiresIn(0); + // Wait for the token to expire. Because we're testing against a live IdP + // and cannot control it at test, all other "mocking" options are more + // intrusive. Verify the new token is different from the one before. + waitForExpiry(t); pingWeaviate(oktaContainer, auth); var newT = auth.getToken(); @@ -173,6 +174,20 @@ private static boolean ping(String site) { } } + private static void waitForExpiry(Token t) { + if (!t.isValid()) { + return; + } + if (t.neverExpires()) { + throw new IllegalStateException("token never expires"); + } + try { + Thread.sleep(Duration.ofSeconds(t.expiresIn()).toMillis()); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + /** * SpyTokenProvider is an Authentication implementation that spies on the * TokenProvider it creates and can expose tokens generated by it. @@ -191,7 +206,6 @@ static Token stealToken(Authentication auth) throws Exception { return spy.getToken(); } - private Long expiresIn; private Authentication authentication; private TokenProvider tokenProvider; @@ -207,17 +221,7 @@ public TokenProvider getTokenProvider(RestTransport transport) { @Override public Token getToken() { - var t = tokenProvider.getToken(); - if (expiresIn != null) { - t = Token.expireAfter(t.accessToken(), t.refreshToken(), expiresIn); - } - return t; + return tokenProvider.getToken(); } - - /** Expire all tokens in {@code expiresIn} seconds. */ - void setExpiresIn(long expiresIn) { - this.expiresIn = expiresIn; - } - } } diff --git a/src/it/java/io/weaviate/integration/RbacITest.java b/src/it/java/io/weaviate/integration/RbacITest.java index ea61b96e7..55a20ece7 100644 --- a/src/it/java/io/weaviate/integration/RbacITest.java +++ b/src/it/java/io/weaviate/integration/RbacITest.java @@ -49,11 +49,7 @@ public class RbacITest extends ConcurrentTest { .withAdminUsers(ADMIN_USER) .withApiKeys(API_KEY) .withRbac() - .withOIDC( // Enable OIDC to have Weaviate return different user types (db, db_env, oidc) - "wcs", - "https://auth.wcs.api.weaviate.io/auth/realms/SeMI", - "email", - "groups") + .withOIDC() // Enable OIDC to have Weaviate return different user types (db, db_env, oidc) .build(); private static final WeaviateClient client = container diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionConfig.java b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionConfig.java index aabe4a7cf..fa7bf4099 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/CollectionConfig.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/CollectionConfig.java @@ -41,6 +41,7 @@ public record CollectionConfig( @SerializedName("replicationConfig") Replication replication, /** Inverted index configuration. */ @SerializedName("invertedIndexConfig") InvertedIndex invertedIndex, + @SerializedName("objectTtlConfig") ObjectTtl objectTtl, /** Reranker modules. */ List rerankerModules, /** Generative modules. */ @@ -68,6 +69,7 @@ public Builder edit() { .sharding(sharding) .replication(replication) .invertedIndex(invertedIndex) + .objectTtl(objectTtl) .rerankerModules(rerankerModules != null ? rerankerModules : new ArrayList<>()) .generativeModule(generativeModule); } @@ -88,6 +90,7 @@ public CollectionConfig(Builder builder) { builder.sharding, builder.replication, builder.invertedIndex, + builder.objectTtl, builder.rerankerModules, builder.generativeModule); } @@ -104,6 +107,7 @@ public static class Builder implements ObjectBuilder { private Sharding sharding; private Replication replication; private InvertedIndex invertedIndex; + private ObjectTtl objectTtl; private List rerankerModules = new ArrayList<>(); private Generative generativeModule; @@ -188,7 +192,7 @@ public Builder sharding(Sharding sharding) { /** Configure collection's sharding. */ public Builder sharding(Function> fn) { - this.sharding = Sharding.of(fn); + this.sharding(Sharding.of(fn)); return this; } @@ -211,7 +215,7 @@ public Builder replication(Replication replication) { /** Configure replication. */ public Builder replication(Function> fn) { - this.replication = Replication.of(fn); + this.replication(Replication.of(fn)); return this; } @@ -223,7 +227,19 @@ public Builder invertedIndex(InvertedIndex invertedIndex) { /** Change inverted index configurations. */ public Builder invertedIndex(Function> fn) { - this.invertedIndex = InvertedIndex.of(fn); + this.invertedIndex(InvertedIndex.of(fn)); + return this; + } + + /** Change inverted index configurations. */ + public Builder objectTtl(ObjectTtl objectTtl) { + this.objectTtl = objectTtl; + return this; + } + + /** Change object TTL configuration. */ + public Builder objectTtl(Function> fn) { + this.objectTtl(ObjectTtl.of(fn)); return this; } diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/ObjectTtl.java b/src/main/java/io/weaviate/client6/v1/api/collections/ObjectTtl.java new file mode 100644 index 000000000..f8544edf4 --- /dev/null +++ b/src/main/java/io/weaviate/client6/v1/api/collections/ObjectTtl.java @@ -0,0 +1,81 @@ +package io.weaviate.client6.v1.api.collections; + +import java.util.function.Function; + +import com.google.gson.annotations.SerializedName; + +import io.weaviate.client6.v1.api.collections.query.BaseQueryOptions; +import io.weaviate.client6.v1.internal.ObjectBuilder; + +public record ObjectTtl( + @SerializedName("enabled") boolean enabled, + @SerializedName("defaultTtl") Integer defaultTtlSeconds, + @SerializedName("deleteOn") String deleteOn, + @SerializedName("filterExpiredObjects") Boolean filterExpiredObjects) { + + public static ObjectTtl of(Function> fn) { + return fn.apply(new Builder()).build(); + } + + public ObjectTtl(Builder builder) { + this( + builder.enabled, + builder.defaultTtlSeconds, + builder.deleteOn, + builder.filterExpiredObjects); + } + + public static class Builder implements ObjectBuilder { + private boolean enabled = true; + private Integer defaultTtlSeconds; + private String deleteOn; + private Boolean filterExpiredObjects; + + /** Enable / disable object TTL for this collection. */ + public Builder enabled(boolean enabled) { + this.enabled = enabled; + return this; + } + + /** Default TTL for all objects in this collection. */ + public Builder defaultTtlSeconds(int seconds) { + this.defaultTtlSeconds = seconds; + return this; + } + + /** + * If enabled, excludes expired objects from search results. + * Expired objects may be temporarily present until the next deletion cycle. + */ + public Builder filterExpiredObjects(boolean enabled) { + this.filterExpiredObjects = enabled; + return this; + } + + /** + * Measure TTL relative an arbitrary {@link DataType#DATE} + * property on the object. + */ + public Builder deleteByDateProperty(String property) { + this.deleteOn = property; + return this; + } + + /** Measure TTL relative to objects' creation time. */ + public Builder deleteByCreationTime() { + this.deleteOn = BaseQueryOptions.CREATION_TIME_PROPERTY; + return this; + } + + /** Measure TTL relative to objects' last update time. */ + public Builder deleteByUpdateTime() { + this.deleteOn = BaseQueryOptions.LAST_UPDATE_TIME_PROPERTY; + return this; + } + + @Override + public ObjectTtl build() { + return new ObjectTtl(this); + } + } +} diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/config/UpdateCollectionRequest.java b/src/main/java/io/weaviate/client6/v1/api/collections/config/UpdateCollectionRequest.java index b8362ff3f..ea79f8f7c 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/config/UpdateCollectionRequest.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/config/UpdateCollectionRequest.java @@ -9,6 +9,7 @@ import io.weaviate.client6.v1.api.collections.Generative; import io.weaviate.client6.v1.api.collections.InvertedIndex; import io.weaviate.client6.v1.api.collections.MultiTenancy; +import io.weaviate.client6.v1.api.collections.ObjectTtl; import io.weaviate.client6.v1.api.collections.Quantization; import io.weaviate.client6.v1.api.collections.Replication; import io.weaviate.client6.v1.api.collections.Reranker; @@ -110,6 +111,16 @@ public Builder invertedIndex(Function> fn) { + this.newCollection.objectTtl(fn); + return this; + } + public Builder rerankerModules(Reranker... rerankerModules) { this.newCollection.rerankerModules(rerankerModules); return this; diff --git a/src/main/java/io/weaviate/client6/v1/api/collections/query/BaseQueryOptions.java b/src/main/java/io/weaviate/client6/v1/api/collections/query/BaseQueryOptions.java index 81d2c71fb..f16f27544 100644 --- a/src/main/java/io/weaviate/client6/v1/api/collections/query/BaseQueryOptions.java +++ b/src/main/java/io/weaviate/client6/v1/api/collections/query/BaseQueryOptions.java @@ -26,9 +26,9 @@ public record BaseQueryOptions( List returnMetadata, List includeVectors) { - static final String ID_PROPERTY = "_id"; - static final String CREATION_TIME_PROPERTY = "_creationTimeUnix"; - static final String LAST_UPDATE_TIME_PROPERTY = "_lastUpdateTimeUnix"; + public static final String ID_PROPERTY = "_id"; + public static final String CREATION_TIME_PROPERTY = "_creationTimeUnix"; + public static final String LAST_UPDATE_TIME_PROPERTY = "_lastUpdateTimeUnix"; private BaseQueryOptions(Builder, T> builder) { this( diff --git a/src/test/java/io/weaviate/client6/v1/api/WeaviateClientAsyncTest.java b/src/test/java/io/weaviate/client6/v1/api/WeaviateClientAsyncTest.java index 60e46de46..085474273 100644 --- a/src/test/java/io/weaviate/client6/v1/api/WeaviateClientAsyncTest.java +++ b/src/test/java/io/weaviate/client6/v1/api/WeaviateClientAsyncTest.java @@ -14,6 +14,9 @@ public void testFailedConnection() { @Test(expected = WeaviateConnectException.class) public void testFailedConnection_Local() { + // You might see a warning from gRPC saying that the channel has been + // garbage-collected before it was closed. The stack trace will probably + // show that it's related to this test. WeaviateClientAsync.connectToLocal(conn -> conn.port(1234)); } diff --git a/src/test/java/io/weaviate/client6/v1/api/WeaviateClientTest.java b/src/test/java/io/weaviate/client6/v1/api/WeaviateClientTest.java index 900d60bb9..4563dda95 100644 --- a/src/test/java/io/weaviate/client6/v1/api/WeaviateClientTest.java +++ b/src/test/java/io/weaviate/client6/v1/api/WeaviateClientTest.java @@ -14,15 +14,10 @@ public void testFailedConnection() { @Test(expected = WeaviateConnectException.class) public void testFailedConnection_Local() throws Exception { - // This test will fail if SOME Weaviate container is running on your machine - // with default :8080 port exposed. All Testcontainer instances started by - // the client's test suite expose random ports, which will not interferen with - // this test. - // - // You might also see a warning from gRPC saying that the channel has been + // You might see a warning from gRPC saying that the channel has been // garbage-collected before it was closed. The stack trace will probably // show that it's related to this test. - WeaviateClient.connectToLocal(); + WeaviateClient.connectToLocal(conn -> conn.port(1234)); } @Test(expected = WeaviateConnectException.class)