diff --git a/src/main/java/io/weaviate/client/v1/async/backup/api/BackupRestorer.java b/src/main/java/io/weaviate/client/v1/async/backup/api/BackupRestorer.java index 5882b3d7b..20195f44e 100644 --- a/src/main/java/io/weaviate/client/v1/async/backup/api/BackupRestorer.java +++ b/src/main/java/io/weaviate/client/v1/async/backup/api/BackupRestorer.java @@ -1,6 +1,18 @@ package io.weaviate.client.v1.async.backup.api; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; +import java.util.concurrent.Executor; +import java.util.concurrent.Future; + +import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; +import org.apache.hc.core5.concurrent.FutureCallback; +import org.apache.hc.core5.http.HttpStatus; + import com.google.gson.annotations.SerializedName; + import io.weaviate.client.Config; import io.weaviate.client.base.AsyncBaseClient; import io.weaviate.client.base.AsyncClientResult; @@ -13,22 +25,13 @@ import io.weaviate.client.v1.auth.provider.AccessTokenProvider; import io.weaviate.client.v1.backup.model.BackupRestoreResponse; import io.weaviate.client.v1.backup.model.BackupRestoreStatusResponse; +import io.weaviate.client.v1.backup.model.RbacRestoreOption; import io.weaviate.client.v1.backup.model.RestoreStatus; import lombok.Builder; import lombok.Getter; -import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; -import org.apache.hc.core5.concurrent.FutureCallback; -import org.apache.hc.core5.http.HttpStatus; - -import java.util.List; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionException; -import java.util.concurrent.Executor; -import java.util.concurrent.Future; public class BackupRestorer extends AsyncBaseClient - implements AsyncClientResult { + implements AsyncClientResult { private static final long WAIT_INTERVAL = 1000; @@ -41,14 +44,13 @@ public class BackupRestorer extends AsyncBaseClient private boolean waitForCompletion; private final Executor executor; - - public BackupRestorer(CloseableHttpAsyncClient client, Config config, AccessTokenProvider tokenProvider, BackupRestoreStatusGetter statusGetter, Executor executor) { + public BackupRestorer(CloseableHttpAsyncClient client, Config config, AccessTokenProvider tokenProvider, + BackupRestoreStatusGetter statusGetter, Executor executor) { super(client, config, tokenProvider); this.statusGetter = statusGetter; this.executor = executor; } - public BackupRestorer withIncludeClassNames(String... classNames) { this.includeClassNames = classNames; return this; @@ -87,19 +89,20 @@ public Future> run(FutureCallback> restore(FutureCallback> callback) { BackupRestore payload = BackupRestore.builder() - .config(BackupRestoreConfig.builder().build()) - .include(includeClassNames) - .exclude(excludeClassNames) - .config(config) - .build(); - String path = String.format("/backups/%s/%s/restore", UrlEncoder.encodePathParam(backend), UrlEncoder.encodePathParam(backupId)); + .config(BackupRestoreConfig.builder().build()) + .include(includeClassNames) + .exclude(excludeClassNames) + .config(config) + .build(); + String path = String.format("/backups/%s/%s/restore", UrlEncoder.encodePathParam(backend), + UrlEncoder.encodePathParam(backupId)); return sendPostRequest(path, payload, BackupRestoreResponse.class, callback); } - private Future> restoreAndWaitForCompletion(FutureCallback> callback) { + private Future> restoreAndWaitForCompletion( + FutureCallback> callback) { CompletableFuture> future = new CompletableFuture<>(); FutureCallback> internalCallback = new FutureCallback>() { @Override @@ -124,64 +127,65 @@ public void cancelled() { restore(internalCallback); return future.thenCompose(restoreResult -> { - if (restoreResult.hasErrors()) { - return CompletableFuture.completedFuture(restoreResult); - } - return getStatusRecursively(backend, backupId, restoreResult); - }) - .whenComplete((restoreResult, throwable) -> { - if (callback != null) { - if (throwable != null) { - callback.failed((Exception) throwable); - } else { - callback.completed(restoreResult); + if (restoreResult.hasErrors()) { + return CompletableFuture.completedFuture(restoreResult); + } + return getStatusRecursively(backend, backupId, restoreResult); + }) + .whenComplete((restoreResult, throwable) -> { + if (callback != null) { + if (throwable != null) { + callback.failed((Exception) throwable); + } else { + callback.completed(restoreResult); + } } - } - }); + }); } private CompletableFuture> getStatus(String backend, String backupId) { CompletableFuture> future = new CompletableFuture<>(); statusGetter.withBackend(backend).withBackupId(backupId) - .run(new FutureCallback>() { - @Override - public void completed(Result createStatusResult) { - future.complete(createStatusResult); - } + .run(new FutureCallback>() { + @Override + public void completed(Result createStatusResult) { + future.complete(createStatusResult); + } - @Override - public void failed(Exception e) { - future.completeExceptionally(e); - } + @Override + public void failed(Exception e) { + future.completeExceptionally(e); + } - @Override - public void cancelled() { - } - }); + @Override + public void cancelled() { + } + }); return future; } private CompletableFuture> getStatusRecursively(String backend, String backupId, - Result restoreResult) { + Result restoreResult) { return Futures.thenComposeAsync(getStatus(backend, backupId), restoreStatusResult -> { boolean isRunning = Optional.of(restoreStatusResult) - .filter(r -> !r.hasErrors()) - .map(Result::getResult) - .map(BackupRestoreStatusResponse::getStatus) - .filter(status -> { - switch (status) { - case RestoreStatus.SUCCESS: - case RestoreStatus.FAILED: - return false; - default: - return true; - } - }) - .isPresent(); + .filter(r -> !r.hasErrors()) + .map(Result::getResult) + .map(BackupRestoreStatusResponse::getStatus) + .filter(status -> { + switch (status) { + case RestoreStatus.SUCCESS: + case RestoreStatus.FAILED: + return false; + default: + return true; + } + }) + .isPresent(); if (isRunning) { try { - return Futures.supplyDelayed(() -> getStatusRecursively(backend, backupId, restoreResult), WAIT_INTERVAL, executor); + return Futures.supplyDelayed(() -> getStatusRecursively(backend, backupId, restoreResult), WAIT_INTERVAL, + executor); } catch (InterruptedException e) { throw new CompletionException(e); } @@ -191,7 +195,7 @@ private CompletableFuture> getStatusRecursively(St } private Result merge(Result restoreStatusResult, - Result restoreResult) { + Result restoreResult) { BackupRestoreStatusResponse restoreStatusResponse = restoreStatusResult.getResult(); BackupRestoreResponse restoreResponse = restoreResult.getResult(); @@ -215,20 +219,22 @@ private Result merge(Result List messages = error.getMessages(); errorResponse = WeaviateErrorResponse.builder() - .code(statusCode) - .error(messages) - .build(); + .code(statusCode) + .error(messages) + .build(); } return new Result<>(statusCode, merged, errorResponse); } - @Getter @Builder private static class BackupRestore { + @SerializedName("config") BackupRestoreConfig config; + @SerializedName("include") String[] include; + @SerializedName("exclude") String[] exclude; } @@ -241,5 +247,9 @@ public static class BackupRestoreConfig { String bucket; @SerializedName("Path") String path; + @SerializedName("usersOptions") + RbacRestoreOption usersRestore; + @SerializedName("rolesOptions") + RbacRestoreOption rolesRestore; } } diff --git a/src/main/java/io/weaviate/client/v1/backup/api/BackupRestorer.java b/src/main/java/io/weaviate/client/v1/backup/api/BackupRestorer.java index 849ad4585..51e82950f 100644 --- a/src/main/java/io/weaviate/client/v1/backup/api/BackupRestorer.java +++ b/src/main/java/io/weaviate/client/v1/backup/api/BackupRestorer.java @@ -1,17 +1,19 @@ package io.weaviate.client.v1.backup.api; import com.google.gson.annotations.SerializedName; -import io.weaviate.client.v1.backup.model.BackupRestoreResponse; -import io.weaviate.client.v1.backup.model.BackupRestoreStatusResponse; -import io.weaviate.client.v1.backup.model.RestoreStatus; -import lombok.Builder; -import lombok.Getter; + 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.backup.model.BackupRestoreResponse; +import io.weaviate.client.v1.backup.model.BackupRestoreStatusResponse; +import io.weaviate.client.v1.backup.model.RbacRestoreOption; +import io.weaviate.client.v1.backup.model.RestoreStatus; +import lombok.Builder; +import lombok.Getter; public class BackupRestorer extends BaseClient implements ClientResult { @@ -68,11 +70,10 @@ public BackupRestorer withWaitForCompletion(boolean waitForCompletion) { @Override public Result run() { BackupRestore payload = BackupRestore.builder() - .config(BackupRestoreConfig.builder().build()) - .include(includeClassNames) - .exclude(excludeClassNames) - .config(config) - .build(); + .include(includeClassNames) + .exclude(excludeClassNames) + .config(config) + .build(); if (waitForCompletion) { return restoreAndWaitForCompletion(payload); @@ -80,7 +81,6 @@ public Result run() { return restore(payload); } - private Result restore(BackupRestore payload) { Response response = sendPostRequest(path(), payload, BackupRestoreResponse.class); return new Result<>(response); @@ -93,7 +93,7 @@ private Result restoreAndWaitForCompletion(BackupRestore } statusGetter.withBackend(backend).withBackupId(backupId); - while(true) { + while (true) { Response statusResponse = statusGetter.statusRestore(); if (new Result<>(statusResponse).hasErrors()) { return merge(statusResponse, result); @@ -117,7 +117,8 @@ private String path() { return String.format("/backups/%s/%s/restore", backend, backupId); } - private Result merge(Response response, Result result) { + private Result merge(Response response, + Result result) { BackupRestoreStatusResponse statusRestoreResponse = response.getBody(); BackupRestoreResponse restoreResponse = result.getResult(); @@ -136,12 +137,14 @@ private Result merge(Response(response.getStatusCode(), merged, response.getErrors()); } - @Getter @Builder private static class BackupRestore { + @SerializedName("config") BackupRestoreConfig config; + @SerializedName("include") String[] include; + @SerializedName("exclude") String[] exclude; } @@ -154,5 +157,9 @@ public static class BackupRestoreConfig { String bucket; @SerializedName("Path") String path; + @SerializedName("usersOptions") + RbacRestoreOption usersRestore; + @SerializedName("rolesOptions") + RbacRestoreOption rolesRestore; } } diff --git a/src/main/java/io/weaviate/client/v1/backup/model/RbacRestoreOption.java b/src/main/java/io/weaviate/client/v1/backup/model/RbacRestoreOption.java new file mode 100644 index 000000000..30ea9b2bb --- /dev/null +++ b/src/main/java/io/weaviate/client/v1/backup/model/RbacRestoreOption.java @@ -0,0 +1,10 @@ +package io.weaviate.client.v1.backup.model; + +import com.google.gson.annotations.SerializedName; + +public enum RbacRestoreOption { + @SerializedName("noRestore") + NO_RESTORE, + @SerializedName("all") + ALL; +} diff --git a/src/test/java/io/weaviate/integration/client/WeaviateDockerCompose.java b/src/test/java/io/weaviate/integration/client/WeaviateDockerCompose.java index aaa6b5873..5a2d1a165 100644 --- a/src/test/java/io/weaviate/integration/client/WeaviateDockerCompose.java +++ b/src/test/java/io/weaviate/integration/client/WeaviateDockerCompose.java @@ -57,6 +57,7 @@ public Weaviate(String dockerImageName, boolean withOffloadS3) { withEnv("DISABLE_TELEMETRY", "true"); withEnv("PERSISTENCE_FLUSH_IDLE_MEMTABLES_AFTER", "1"); withEnv("ENABLE_MODULES", String.join(",", enableModules)); + withEnv("AUTHENTICATION_DB_USERS_ENABLED", "true"); withCreateContainerCmdModifier(cmd -> cmd.withHostName("weaviate")); } } diff --git a/src/test/java/io/weaviate/integration/client/WeaviateDockerComposeBackup.java b/src/test/java/io/weaviate/integration/client/WeaviateDockerComposeBackup.java new file mode 100644 index 000000000..35f20c089 --- /dev/null +++ b/src/test/java/io/weaviate/integration/client/WeaviateDockerComposeBackup.java @@ -0,0 +1,157 @@ +package io.weaviate.integration.client; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.MinIOContainer; +import org.testcontainers.containers.Network; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.weaviate.WeaviateContainer; + +public class WeaviateDockerComposeBackup implements TestRule { + + public static final String ADMIN_KEY = "admin-key"; + + /** Weaviate Docker image to create a container from. */ + private final String weaviateVersion; + private final boolean withOffloadS3; + + public WeaviateDockerComposeBackup() { + this.weaviateVersion = WeaviateDockerImage.WEAVIATE_DOCKER_IMAGE; + this.withOffloadS3 = false; + } + + public WeaviateDockerComposeBackup(String version) { + this.weaviateVersion = String.format("semitechnologies/weaviate:%s", version); + this.withOffloadS3 = false; + } + + public WeaviateDockerComposeBackup(String version, boolean withOffloadS3) { + this.weaviateVersion = String.format("semitechnologies/weaviate:%s", version); + this.withOffloadS3 = withOffloadS3; + } + + public static class Weaviate extends WeaviateContainer { + public Weaviate(String dockerImageName, boolean withOffloadS3) { + super(dockerImageName); + waitingFor(Wait.forHttp("/v1/.well-known/ready").forPort(8080).forStatusCode(200)); + withNetwork(Network.SHARED); + List enableModules = new ArrayList<>(); + enableModules.add("text2vec-contextionary"); + enableModules.add("backup-filesystem"); + enableModules.add("generative-openai"); + if (withOffloadS3) { + enableModules.add("offload-s3"); + withEnv("OFFLOAD_S3_ENDPOINT", "http://minio:9000"); + withEnv("OFFLOAD_S3_BUCKET_AUTO_CREATE", "true"); + withEnv("AWS_ACCESS_KEY_ID", MinIO.USER); + withEnv("AWS_SECRET_KEY", MinIO.PASSWORD); + } + withEnv("LOG_LEVEL", "debug"); + withEnv("CONTEXTIONARY_URL", "contextionary:9999"); + withEnv("QUERY_DEFAULTS_LIMIT", "25"); + withEnv("DEFAULT_VECTORIZER_MODULE", "text2vec-contextionary"); + withEnv("BACKUP_FILESYSTEM_PATH", "/tmp/backups"); + withEnv("DISABLE_TELEMETRY", "true"); + withEnv("PERSISTENCE_FLUSH_IDLE_MEMTABLES_AFTER", "1"); + withEnv("ENABLE_MODULES", String.join(",", enableModules)); + withCreateContainerCmdModifier(cmd -> cmd.withHostName("weaviate")); + + withEnv("AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED", "false"); + withEnv("AUTHENTICATION_APIKEY_ENABLED", "true"); + withEnv("AUTHENTICATION_APIKEY_ALLOWED_KEYS", ADMIN_KEY + ",custom-key"); + withEnv("AUTHENTICATION_APIKEY_USERS", "admin-user,custom-user"); + withEnv("AUTHORIZATION_ADMIN_USERS", "admin-user"); + withEnv("PERSISTENCE_DATA_PATH", "./data-weaviate-0"); + withEnv("CLUSTER_IN_LOCALHOST", "true"); + withEnv("CLUSTER_GOSSIP_BIND_PORT", "7100"); + withEnv("CLUSTER_DATA_BIND_PORT", "7101"); + withEnv("RAFT_BOOTSTRAP_EXPECT", "1"); + withEnv("AUTHORIZATION_ENABLE_RBAC", "true"); + withEnv("AUTHENTICATION_DB_USERS_ENABLED", "true"); + withEnv("AUTHENTICATION_OIDC_ENABLED", "true"); + withEnv("AUTHENTICATION_OIDC_CLIENT_ID", "wcs"); + withEnv("AUTHENTICATION_OIDC_ISSUER", "https://auth.wcs.api.weaviate.io/auth/realms/SeMI"); + withEnv("AUTHENTICATION_OIDC_USERNAME_CLAIM", "email"); + withEnv("AUTHENTICATION_OIDC_GROUPS_CLAIM", "groups"); + } + } + + public static class Contextionary extends GenericContainer { + public Contextionary() { + super("semitechnologies/contextionary:en0.16.0-v1.2.1"); + withNetwork(Network.SHARED); + withEnv("OCCURRENCE_WEIGHT_LINEAR_FACTOR", "true"); + withEnv("PERSISTENCE_DATA_PATH", "/var/lib/weaviate"); + withEnv("OCCURRENCE_WEIGHT_LINEAR_FACTOR", "0.75"); + withEnv("EXTENSIONS_STORAGE_MODE", "weaviate"); + withEnv("EXTENSIONS_STORAGE_ORIGIN", "http://weaviate:8080"); + withEnv("NEIGHBOR_OCCURRENCE_IGNORE_PERCENTILE", "5"); + withEnv("ENABLE_COMPOUND_SPLITTING", "'false'"); + withCreateContainerCmdModifier(cmd -> cmd.withHostName("contextionary")); + } + } + + public static class MinIO extends MinIOContainer { + private static final String USER = "minioadmin"; + private static final String PASSWORD = "minioadmin"; + + public MinIO() { + super("minio/minio"); + withNetwork(Network.SHARED); + withUserName(USER); + withPassword(PASSWORD); + withCreateContainerCmdModifier(cmd -> cmd.withHostName("minio")); + } + } + + private static Contextionary contextionary; + private static Weaviate weaviate; + private static MinIO minio; + + public void start() { + if (withOffloadS3) { + minio = new MinIO(); + minio.start(); + } + contextionary = new Contextionary(); + contextionary.start(); + weaviate = new Weaviate(this.weaviateVersion, this.withOffloadS3); + weaviate.start(); + } + + public String getHttpHostAddress() { + return weaviate.getHttpHostAddress(); + } + + public String getGrpcHostAddress() { + return weaviate.getGrpcHostAddress(); + } + + public void stop() { + weaviate.stop(); + contextionary.stop(); + if (withOffloadS3) { + minio.stop(); + } + } + + @Override + public Statement apply(Statement base, Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + try { + start(); + base.evaluate(); + } finally { + stop(); + } + } + }; + } +} diff --git a/src/test/java/io/weaviate/integration/client/WeaviateVersion.java b/src/test/java/io/weaviate/integration/client/WeaviateVersion.java index cb76a1227..c87083d70 100644 --- a/src/test/java/io/weaviate/integration/client/WeaviateVersion.java +++ b/src/test/java/io/weaviate/integration/client/WeaviateVersion.java @@ -3,12 +3,13 @@ public class WeaviateVersion { // docker image version - public static final String WEAVIATE_IMAGE = "1.32.0-rc.1-175d482"; + public static final String WEAVIATE_IMAGE = "1.32.0"; // to be set according to weaviate docker image - public static final String EXPECTED_WEAVIATE_VERSION = "1.32.0-rc.1"; + public static final String EXPECTED_WEAVIATE_VERSION = "1.32.0"; // to be set according to weaviate docker image - public static final String EXPECTED_WEAVIATE_GIT_HASH = "175d482"; + public static final String EXPECTED_WEAVIATE_GIT_HASH = "7cebee0"; - private WeaviateVersion() {} + private WeaviateVersion() { + } } diff --git a/src/test/java/io/weaviate/integration/client/async/backup/ClientBackupTest.java b/src/test/java/io/weaviate/integration/client/async/backup/ClientBackupTest.java index a03baecf4..84ecd00a5 100644 --- a/src/test/java/io/weaviate/integration/client/async/backup/ClientBackupTest.java +++ b/src/test/java/io/weaviate/integration/client/async/backup/ClientBackupTest.java @@ -3,11 +3,13 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; +import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; +import org.assertj.core.api.Assertions; import org.jetbrains.annotations.NotNull; import org.junit.After; import org.junit.Before; @@ -17,6 +19,7 @@ import org.junit.rules.TestName; import io.weaviate.client.Config; +import io.weaviate.client.WeaviateAuthClient; import io.weaviate.client.WeaviateClient; import io.weaviate.client.base.Result; import io.weaviate.client.v1.async.WeaviateAsyncClient; @@ -26,13 +29,19 @@ import io.weaviate.client.v1.async.backup.api.BackupGetter; import io.weaviate.client.v1.async.backup.api.BackupRestoreStatusGetter; import io.weaviate.client.v1.async.backup.api.BackupRestorer; +import io.weaviate.client.v1.async.backup.api.BackupRestorer.BackupRestoreConfig; +import io.weaviate.client.v1.auth.exception.AuthException; import io.weaviate.client.v1.backup.model.BackupCreateResponse; import io.weaviate.client.v1.backup.model.BackupCreateStatusResponse; import io.weaviate.client.v1.backup.model.BackupRestoreResponse; import io.weaviate.client.v1.backup.model.BackupRestoreStatusResponse; +import io.weaviate.client.v1.backup.model.RbacRestoreOption; import io.weaviate.client.v1.graphql.model.GraphQLResponse; import io.weaviate.client.v1.graphql.query.fields.Field; -import io.weaviate.integration.client.WeaviateDockerCompose; +import io.weaviate.client.v1.rbac.model.ClusterPermission; +import io.weaviate.client.v1.rbac.model.Permission; +import io.weaviate.client.v1.schema.model.WeaviateClass; +import io.weaviate.integration.client.WeaviateDockerComposeBackup; import io.weaviate.integration.client.WeaviateTestGenerics; import io.weaviate.integration.tests.backup.BackupTestSuite; @@ -49,15 +58,16 @@ public class ClientBackupTest { public TestName currentTest = new TestName(); @ClassRule - public static WeaviateDockerCompose compose = new WeaviateDockerCompose(); + public static WeaviateDockerComposeBackup compose = new WeaviateDockerComposeBackup(); @Before - public void before() { + public void before() throws AuthException { Config config = new Config("http", compose.getHttpHostAddress()); - client = new WeaviateClient(config); + client = WeaviateAuthClient.apiKey(config, WeaviateDockerComposeBackup.ADMIN_KEY); testGenerics.createTestSchemaAndData(client); - backupId = String.format("backup-%s-%s", currentTest.getMethodName().toLowerCase(), rand.nextInt(Integer.MAX_VALUE)); + backupId = String.format("backup-%s-%s", currentTest.getMethodName().toLowerCase(), + rand.nextInt(Integer.MAX_VALUE)); notExistingBackupId = "not-existing-backup-" + backupId; } @@ -66,38 +76,33 @@ public void after() { testGenerics.cleanupWeaviate(client); } - @Test public void shouldCreateAndRestoreBackupWithWaiting() { try (WeaviateAsyncClient asyncClient = client.async()) { Supplier> supplierCreateResult = createSupplierCreate( - asyncClient, creator -> creator - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(true) - ); + asyncClient, creator -> creator + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(true)); Supplier> supplierCreateStatusResult = createSupplierCreateStatus( - asyncClient, createStatusGetter -> createStatusGetter - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - ); + asyncClient, createStatusGetter -> createStatusGetter + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId)); Supplier> supplierRestoreResult = createSupplierRestore( - asyncClient, restorer -> restorer - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(true) - ); + asyncClient, restorer -> restorer + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(true)); Supplier> supplierRestoreStatusResult = createSupplierRestoreStatus( - asyncClient, restoreStatusGetter -> restoreStatusGetter - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - ); + asyncClient, restoreStatusGetter -> restoreStatusGetter + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId)); BackupTestSuite.testCreateAndRestoreBackupWithWaiting(supplierCreateResult, supplierCreateStatusResult, - supplierRestoreResult, supplierRestoreStatusResult, - createSupplierDeletePizza(), createSupplierGQLOfClass(), backupId); + supplierRestoreResult, supplierRestoreStatusResult, + createSupplierDeletePizza(), createSupplierGQLOfClass(), backupId); } } @@ -105,31 +110,27 @@ public void shouldCreateAndRestoreBackupWithWaiting() { public void shouldCreateAndRestoreBackupWithoutWaiting() throws InterruptedException { try (WeaviateAsyncClient asyncClient = client.async()) { Supplier> supplierCreateResult = createSupplierCreate( - asyncClient, creator -> creator - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - ); + asyncClient, creator -> creator + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId)); Supplier> supplierCreateStatusResult = createSupplierCreateStatus( - asyncClient, createStatusGetter -> createStatusGetter - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - ); + asyncClient, createStatusGetter -> createStatusGetter + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId)); Supplier> supplierRestoreResult = createSupplierRestore( - asyncClient, restorer -> restorer - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - ); + asyncClient, restorer -> restorer + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId)); Supplier> supplierRestoreStatusResult = createSupplierRestoreStatus( - asyncClient, restoreStatusGetter -> restoreStatusGetter - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - ); + asyncClient, restoreStatusGetter -> restoreStatusGetter + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId)); BackupTestSuite.testCreateAndRestoreBackupWithoutWaiting(supplierCreateResult, supplierCreateStatusResult, - supplierRestoreResult, supplierRestoreStatusResult, - createSupplierDeletePizza(), createSupplierGQLOfClass(), backupId); + supplierRestoreResult, supplierRestoreStatusResult, + createSupplierDeletePizza(), createSupplierGQLOfClass(), backupId); } } @@ -140,37 +141,33 @@ public void shouldCreateAndRestoreBackupWithDynamicLocation() throws Interrupted try (WeaviateAsyncClient asyncClient = client.async()) { Supplier> supplierCreateResult = createSupplierCreate( - asyncClient, creator -> creator - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withConfig(BackupCreator.BackupCreateConfig.builder().bucket(bucket).path(path).build()) - ); + asyncClient, creator -> creator + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withConfig(BackupCreator.BackupCreateConfig.builder().bucket(bucket).path(path).build())); Supplier> supplierCreateStatusResult = createSupplierCreateStatus( - asyncClient, createStatusGetter -> createStatusGetter - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withBucket(bucket) - .withPath(path) - ); + asyncClient, createStatusGetter -> createStatusGetter + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withBucket(bucket) + .withPath(path)); Supplier> supplierRestoreResult = createSupplierRestore( - asyncClient, restorer -> restorer - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withConfig(BackupRestorer.BackupRestoreConfig.builder().bucket(bucket).path(path).build()) - ); + asyncClient, restorer -> restorer + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withConfig(BackupRestorer.BackupRestoreConfig.builder().bucket(bucket).path(path).build())); Supplier> supplierRestoreStatusResult = createSupplierRestoreStatus( - asyncClient, restoreStatusGetter -> restoreStatusGetter - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withBucket(bucket) - .withPath(path) - ); + asyncClient, restoreStatusGetter -> restoreStatusGetter + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withBucket(bucket) + .withPath(path)); BackupTestSuite.testCreateWithDynamicLocation(supplierCreateResult, supplierCreateStatusResult, - supplierRestoreResult, supplierRestoreStatusResult, - createSupplierDeletePizza(), createSupplierGQLOfClass(), backupId, bucket, path); + supplierRestoreResult, supplierRestoreStatusResult, + createSupplierDeletePizza(), createSupplierGQLOfClass(), backupId, bucket, path); } } @@ -178,59 +175,54 @@ public void shouldCreateAndRestoreBackupWithDynamicLocation() throws Interrupted public void shouldCreateAndRestore1Of2Classes() { try (WeaviateAsyncClient asyncClient = client.async()) { Supplier> supplierCreateResult = createSupplierCreate( - asyncClient, creator -> creator - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(true) - ); + asyncClient, creator -> creator + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(true)); Supplier> supplierCreateStatusResult = createSupplierCreateStatus( - asyncClient, createStatusGetter -> createStatusGetter - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - ); + asyncClient, createStatusGetter -> createStatusGetter + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId)); Supplier> supplierRestoreResult = createSupplierRestore( - asyncClient, restorer -> restorer - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(true) - ); + asyncClient, restorer -> restorer + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(true)); Supplier> supplierRestoreStatusResult = createSupplierRestoreStatus( - asyncClient, restoreStatusGetter -> restoreStatusGetter - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - ); + asyncClient, restoreStatusGetter -> restoreStatusGetter + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId)); BackupTestSuite.testCreateAndRestore1Of2Classes(supplierCreateResult, supplierCreateStatusResult, - supplierRestoreResult, supplierRestoreStatusResult, - createSupplierDeletePizza(), createSupplierGQLOfClass(), backupId); + supplierRestoreResult, supplierRestoreStatusResult, + createSupplierDeletePizza(), createSupplierGQLOfClass(), backupId); } } @Test public void shouldListCreatedBackups() { try (WeaviateAsyncClient asyncClient = client.async()) { - List>> createSuppliers = new ArrayList>>() {{ - this.add(createSupplierCreate( - asyncClient, creator -> creator - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId+"-1") - .withWaitForCompletion(true) - )); - this.add(createSupplierCreate( - asyncClient, creator -> creator - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId+"-2") - .withWaitForCompletion(true) - )); - }}; + List>> createSuppliers = new ArrayList>>() { + { + this.add(createSupplierCreate( + asyncClient, creator -> creator + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId + "-1") + .withWaitForCompletion(true))); + this.add(createSupplierCreate( + asyncClient, creator -> creator + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId + "-2") + .withWaitForCompletion(true))); + } + }; Supplier> supplierGetResult = createSupplierGet( - asyncClient, creator -> creator - .withBackend(BackupTestSuite.BACKEND) - ); + asyncClient, creator -> creator + .withBackend(BackupTestSuite.BACKEND)); BackupTestSuite.testListExistingBackups(createSuppliers, supplierGetResult); } @@ -240,11 +232,10 @@ public void shouldListCreatedBackups() { public void shouldFailOnCreateBackupOnNotExistingBackend() { try (WeaviateAsyncClient asyncClient = client.async()) { Supplier> supplierCreateResult = createSupplierCreate( - asyncClient, creator -> creator - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.NOT_EXISTING_BACKEND) - .withBackupId(backupId) - ); + asyncClient, creator -> creator + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.NOT_EXISTING_BACKEND) + .withBackupId(backupId)); BackupTestSuite.testFailOnCreateBackupOnNotExistingBackend(supplierCreateResult); } @@ -254,10 +245,9 @@ public void shouldFailOnCreateBackupOnNotExistingBackend() { public void shouldFailOnCreateBackupStatusOnNotExistingBackend() { try (WeaviateAsyncClient asyncClient = client.async()) { Supplier> supplierCreateStatusResult = createSupplierCreateStatus( - asyncClient, createStatusGetter -> createStatusGetter - .withBackend(BackupTestSuite.NOT_EXISTING_BACKEND) - .withBackupId(backupId) - ); + asyncClient, createStatusGetter -> createStatusGetter + .withBackend(BackupTestSuite.NOT_EXISTING_BACKEND) + .withBackupId(backupId)); BackupTestSuite.testFailOnCreateBackupStatusOnNotExistingBackend(supplierCreateStatusResult); } @@ -267,11 +257,10 @@ public void shouldFailOnCreateBackupStatusOnNotExistingBackend() { public void shouldFailOnRestoreBackupFromNotExistingBackend() { try (WeaviateAsyncClient asyncClient = client.async()) { Supplier> supplierRestoreResult = createSupplierRestore( - asyncClient, restorer -> restorer - .withIncludeClassNames(BackupTestSuite.NOT_EXISTING_CLASS_NAME) - .withBackend(BackupTestSuite.NOT_EXISTING_BACKEND) - .withBackupId(backupId) - ); + asyncClient, restorer -> restorer + .withIncludeClassNames(BackupTestSuite.NOT_EXISTING_CLASS_NAME) + .withBackend(BackupTestSuite.NOT_EXISTING_BACKEND) + .withBackupId(backupId)); BackupTestSuite.testFailOnRestoreBackupFromNotExistingBackend(supplierRestoreResult); } @@ -281,11 +270,10 @@ public void shouldFailOnRestoreBackupFromNotExistingBackend() { public void shouldFailOnCreateBackupForNotExistingClass() { try (WeaviateAsyncClient asyncClient = client.async()) { Supplier> supplierCreateResult = createSupplierCreate( - asyncClient, creator -> creator - .withIncludeClassNames(BackupTestSuite.NOT_EXISTING_CLASS_NAME) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - ); + asyncClient, creator -> creator + .withIncludeClassNames(BackupTestSuite.NOT_EXISTING_CLASS_NAME) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId)); BackupTestSuite.testFailOnCreateBackupForNotExistingClass(supplierCreateResult); } @@ -295,19 +283,17 @@ public void shouldFailOnCreateBackupForNotExistingClass() { public void shouldFailOnRestoreBackupForExistingClass() { try (WeaviateAsyncClient asyncClient = client.async()) { Supplier> supplierCreateResult = createSupplierCreate( - asyncClient, creator -> creator - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(true) - ); + asyncClient, creator -> creator + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(true)); Supplier> supplierRestoreResult = createSupplierRestore( - asyncClient, restorer -> restorer - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(true) - ); + asyncClient, restorer -> restorer + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(true)); BackupTestSuite.testFailOnRestoreBackupForExistingClass(supplierCreateResult, supplierRestoreResult, backupId); } @@ -317,12 +303,11 @@ public void shouldFailOnRestoreBackupForExistingClass() { public void shouldFailOnCreateOfExistingBackup() { try (WeaviateAsyncClient asyncClient = client.async()) { Supplier> supplierCreateResult = createSupplierCreate( - asyncClient, creator -> creator - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(true) - ); + asyncClient, creator -> creator + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(true)); BackupTestSuite.testFailOnCreateOfExistingBackup(supplierCreateResult, backupId); } @@ -332,10 +317,9 @@ public void shouldFailOnCreateOfExistingBackup() { public void shouldFailOnCreateStatusOfNotExistingBackup() { try (WeaviateAsyncClient asyncClient = client.async()) { Supplier> supplierCreateStatusResult = createSupplierCreateStatus( - asyncClient, createStatusGetter -> createStatusGetter - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(notExistingBackupId) - ); + asyncClient, createStatusGetter -> createStatusGetter + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(notExistingBackupId)); BackupTestSuite.testFailOnCreateStatusOfNotExistingBackup(supplierCreateStatusResult, notExistingBackupId); } @@ -345,11 +329,10 @@ public void shouldFailOnCreateStatusOfNotExistingBackup() { public void shouldFailOnRestoreOfNotExistingBackup() { try (WeaviateAsyncClient asyncClient = client.async()) { Supplier> supplierRestoreResult = createSupplierRestore( - asyncClient, restorer -> restorer - .withIncludeClassNames(BackupTestSuite.NOT_EXISTING_CLASS_NAME) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(notExistingBackupId) - ); + asyncClient, restorer -> restorer + .withIncludeClassNames(BackupTestSuite.NOT_EXISTING_CLASS_NAME) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(notExistingBackupId)); BackupTestSuite.testFailOnRestoreOfNotExistingBackup(supplierRestoreResult, notExistingBackupId); } @@ -359,19 +342,18 @@ public void shouldFailOnRestoreOfNotExistingBackup() { public void shouldFailOnRestoreBackupStatusOfNotStartedRestore() { try (WeaviateAsyncClient asyncClient = client.async()) { Supplier> supplierCreateResult = createSupplierCreate( - asyncClient, creator -> creator - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(true) - ); + asyncClient, creator -> creator + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(true)); Supplier> supplierRestoreStatusResult = createSupplierRestoreStatus( - asyncClient, restoreStatusGetter -> restoreStatusGetter - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - ); + asyncClient, restoreStatusGetter -> restoreStatusGetter + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId)); - BackupTestSuite.testFailOnRestoreBackupStatusOfNotStartedRestore(supplierCreateResult, supplierRestoreStatusResult, backupId); + BackupTestSuite.testFailOnRestoreBackupStatusOfNotStartedRestore(supplierCreateResult, + supplierRestoreStatusResult, backupId); } } @@ -379,13 +361,12 @@ public void shouldFailOnRestoreBackupStatusOfNotStartedRestore() { public void shouldFailOnCreateBackupForBothIncludeAndExcludeClasses() { try (WeaviateAsyncClient asyncClient = client.async()) { Supplier> supplierCreateResult = createSupplierCreate( - asyncClient, creator -> creator - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withExcludeClassNames(BackupTestSuite.CLASS_NAME_SOUP) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(true) - ); + asyncClient, creator -> creator + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withExcludeClassNames(BackupTestSuite.CLASS_NAME_SOUP) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(true)); BackupTestSuite.testFailOnCreateBackupForBothIncludeAndExcludeClasses(supplierCreateResult); } @@ -395,22 +376,21 @@ public void shouldFailOnCreateBackupForBothIncludeAndExcludeClasses() { public void shouldFailOnRestoreBackupForBothIncludeAndExcludeClasses() { try (WeaviateAsyncClient asyncClient = client.async()) { Supplier> supplierCreateResult = createSupplierCreate( - asyncClient, creator -> creator - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA, BackupTestSuite.CLASS_NAME_SOUP) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(true) - ); + asyncClient, creator -> creator + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA, BackupTestSuite.CLASS_NAME_SOUP) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(true)); Supplier> supplierRestoreResult = createSupplierRestore( - asyncClient, restorer -> restorer - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withExcludeClassNames(BackupTestSuite.CLASS_NAME_SOUP) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - ); - - BackupTestSuite.testFailOnRestoreBackupForBothIncludeAndExcludeClasses(supplierCreateResult, supplierRestoreResult, - createSupplierDeletePizza()); + asyncClient, restorer -> restorer + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withExcludeClassNames(BackupTestSuite.CLASS_NAME_SOUP) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId)); + + BackupTestSuite.testFailOnRestoreBackupForBothIncludeAndExcludeClasses(supplierCreateResult, + supplierRestoreResult, + createSupplierDeletePizza()); } } @@ -419,80 +399,76 @@ public void shouldCreateAndRestoreBackupWithWaitingWithConfig() { try (WeaviateAsyncClient asyncClient = client.async()) { // config with too high value Supplier> supplierCreateInvConfigResult = createSupplierCreate( - asyncClient, creator -> { - BackupCreator.BackupCreateConfig invCreateConfig = BackupCreator.BackupCreateConfig.builder() - .cpuPercentage(801) - .build(); - - creator - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withConfig(invCreateConfig) - .withWaitForCompletion(true); - } - ); + asyncClient, creator -> { + BackupCreator.BackupCreateConfig invCreateConfig = BackupCreator.BackupCreateConfig.builder() + .cpuPercentage(801) + .build(); + + creator + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withConfig(invCreateConfig) + .withWaitForCompletion(true); + }); // valid config Supplier> supplierCreateResult = createSupplierCreate( - asyncClient, creator -> { - BackupCreator.BackupCreateConfig createConfig = BackupCreator.BackupCreateConfig.builder() - .cpuPercentage(80) - .chunkSize(512) - .compressionLevel(BackupCreator.BackupCompression.BEST_SPEED) - .build(); - - creator - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withConfig(createConfig) - .withWaitForCompletion(true); - } - ); + asyncClient, creator -> { + BackupCreator.BackupCreateConfig createConfig = BackupCreator.BackupCreateConfig.builder() + .cpuPercentage(80) + .chunkSize(512) + .compressionLevel(BackupCreator.BackupCompression.BEST_SPEED) + .build(); + + creator + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withConfig(createConfig) + .withWaitForCompletion(true); + }); Supplier> supplierCreateStatusResult = createSupplierCreateStatus( - asyncClient, createStatusGetter -> createStatusGetter - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - ); + asyncClient, createStatusGetter -> createStatusGetter + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId)); // config with too high value Supplier> supplierRestoreInvConfigResult = createSupplierRestore( - asyncClient, restorer -> { - BackupRestorer.BackupRestoreConfig invRestoreConfig = BackupRestorer.BackupRestoreConfig.builder() - .cpuPercentage(90) - .build(); - - restorer - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withConfig(invRestoreConfig) - .withWaitForCompletion(true); - } - ); + asyncClient, restorer -> { + BackupRestorer.BackupRestoreConfig invRestoreConfig = BackupRestorer.BackupRestoreConfig.builder() + .cpuPercentage(90) + .build(); + + restorer + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withConfig(invRestoreConfig) + .withWaitForCompletion(true); + }); // valid config Supplier> supplierRestoreResult = createSupplierRestore( - asyncClient, restorer -> { - BackupRestorer.BackupRestoreConfig restoreConfig = BackupRestorer.BackupRestoreConfig.builder() - .cpuPercentage(70) - .build(); - - restorer - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withConfig(restoreConfig) - .withWaitForCompletion(true); - } - ); + asyncClient, restorer -> { + BackupRestorer.BackupRestoreConfig restoreConfig = BackupRestorer.BackupRestoreConfig.builder() + .cpuPercentage(70) + .build(); + + restorer + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withConfig(restoreConfig) + .withWaitForCompletion(true); + }); Supplier> supplierRestoreStatusResult = createSupplierRestoreStatus( - asyncClient, restoreStatusGetter -> restoreStatusGetter - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - ); - - BackupTestSuite.testCreateAndRestoreBackupWithWaitingWithConfig(supplierCreateInvConfigResult, supplierCreateResult, - supplierCreateStatusResult, supplierRestoreInvConfigResult, supplierRestoreResult, supplierRestoreStatusResult, - createSupplierDeletePizza(), createSupplierGQLOfClass(), backupId); + asyncClient, restoreStatusGetter -> restoreStatusGetter + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId)); + + BackupTestSuite.testCreateAndRestoreBackupWithWaitingWithConfig(supplierCreateInvConfigResult, + supplierCreateResult, + supplierCreateStatusResult, supplierRestoreInvConfigResult, supplierRestoreResult, + supplierRestoreStatusResult, + createSupplierDeletePizza(), createSupplierGQLOfClass(), backupId); } } @@ -500,44 +476,123 @@ public void shouldCreateAndRestoreBackupWithWaitingWithConfig() { public void shouldCancelBackup() { try (WeaviateAsyncClient asyncClient = client.async()) { Supplier> supplierCreateResult = createSupplierCreate( - asyncClient, creator -> creator - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(false) // this will allow us to "intercept" the backup in progress + asyncClient, creator -> creator + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(false) // this will allow us to "intercept" the backup in progress ); Supplier> supplierCancelResult = createSupplierCanceler( - asyncClient, canceler -> canceler - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - ); + asyncClient, canceler -> canceler + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId)); Supplier> supplierCreateStatusResult = createSupplierCreateStatus( - asyncClient, createStatusGetter -> createStatusGetter - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - ); + asyncClient, createStatusGetter -> createStatusGetter + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId)); BackupTestSuite.testCancelBackup(supplierCreateResult, supplierCancelResult, supplierCreateStatusResult); } } + @Test + public void shouldRestoreWithRbacOptions() { + final String className = "RolesUsers"; + final String roleName = "restoreRole"; + final String userName = "restoreUser"; + + try (final WeaviateAsyncClient async = client.async()) { + + BackupTestSuite.testBackupRestoreWithRbacOptions(backupId, + // Arrange: create collection, create role, create user; + runnable(() -> { + async.schema().classDeleter().withClassName(className).run().get(); + async.schema().classCreator().withClass(WeaviateClass.builder().className(className).build()).run().get(); + + async.roles().deleter().withName(roleName).run().get(); + Result createRole = async.roles().creator().withName(roleName) + .withPermissions(Permission.cluster(ClusterPermission.Action.READ)).run().get(); + Assertions.assertThat(createRole.getError()).as("create role").isNull(); + + async.users().db().deleter().withUserId(userName).run().get(); + Result createUser = async.users().db().creator().withUserId(userName).run().get(); + Assertions.assertThat(createUser.getError()).as("create user").isNull(); + + return null; // satisfy Callable + }), + runnable(() -> { + async.schema().classDeleter().withClassName(className).run().get(); + async.roles().deleter().withName(roleName).run().get(); + async.users().db().deleter().withUserId(userName).run().get(); + + return null; // satisfy Callable + }), + // Create backup + supplier(() -> async.backup().creator() + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withIncludeClassNames("RolesUsers") + .withWaitForCompletion(true) + .run().get()), + // Restore from backup + supplier(() -> async.backup().restorer() + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withIncludeClassNames("RolesUsers") + .withWaitForCompletion(true) + .withConfig(BackupRestoreConfig.builder() + .usersRestore(RbacRestoreOption.ALL) + .rolesRestore(RbacRestoreOption.ALL) + .build()) + .run().get()), + supplier(() -> async.users().db().getUser().withUserId(userName).run().get()), + supplier(() -> async.roles().getter().withName(roleName).run().get())); + } + } + + @FunctionalInterface + interface ThrowingSupplier { + T get() throws Exception; + } + + /** Convert throwing Callable into a Runnable which does not throw. */ + private static Runnable runnable(Callable c) { + return () -> { + try { + c.call(); + } catch (Exception e) { + throw new RuntimeException(e); + } + }; + } + + /** Convert throwing Supplier into one that does not throw. */ + private static Supplier supplier(ThrowingSupplier s) { + return () -> { + try { + return s.get(); + } catch (Exception e) { + throw new RuntimeException(e); + } + }; + } @NotNull private Supplier> createSupplierDeletePizza() { return () -> client.schema().classDeleter() - .withClassName(BackupTestSuite.CLASS_NAME_PIZZA) - .run(); + .withClassName(BackupTestSuite.CLASS_NAME_PIZZA) + .run(); } @NotNull private Function> createSupplierGQLOfClass() { return (String className) -> client.graphQL().get() - .withClassName(className) - .withFields(Field.builder().name("name").build()) - .run(); + .withClassName(className) + .withFields(Field.builder().name("name").build()) + .run(); } private Supplier> createSupplierCreate(WeaviateAsyncClient asyncClient, - Consumer configure) { + Consumer configure) { return () -> { try { BackupCreator creator = asyncClient.backup().creator(); @@ -550,7 +605,7 @@ private Supplier> createSupplierCreate(WeaviateAsyn } private Supplier> createSupplierGet(WeaviateAsyncClient asyncClient, - Consumer configure) { + Consumer configure) { return () -> { try { BackupGetter getter = asyncClient.backup().getter(); @@ -559,11 +614,11 @@ private Supplier> createSupplierGet(WeaviateAsync } catch (InterruptedException | ExecutionException e) { throw new RuntimeException(e); } - }; + }; } private Supplier> createSupplierCreateStatus(WeaviateAsyncClient asyncClient, - Consumer configure) { + Consumer configure) { return () -> { try { BackupCreateStatusGetter getter = asyncClient.backup().createStatusGetter(); @@ -576,7 +631,7 @@ private Supplier> createSupplierCreateStatus( } private Supplier> createSupplierRestore(WeaviateAsyncClient asyncClient, - Consumer configure) { + Consumer configure) { return () -> { try { BackupRestorer restorer = asyncClient.backup().restorer(); @@ -589,7 +644,7 @@ private Supplier> createSupplierRestore(WeaviateAs } private Supplier> createSupplierRestoreStatus(WeaviateAsyncClient asyncClient, - Consumer configure) { + Consumer configure) { return () -> { try { BackupRestoreStatusGetter getter = asyncClient.backup().restoreStatusGetter(); @@ -602,7 +657,7 @@ private Supplier> createSupplierRestoreStatu } private Supplier> createSupplierCanceler(WeaviateAsyncClient asyncClient, - Consumer configure) { + Consumer configure) { return () -> { try { BackupCanceler canceler = asyncClient.backup().canceler(); diff --git a/src/test/java/io/weaviate/integration/client/backup/ClientBackupTest.java b/src/test/java/io/weaviate/integration/client/backup/ClientBackupTest.java index afdb0be05..a1e721019 100644 --- a/src/test/java/io/weaviate/integration/client/backup/ClientBackupTest.java +++ b/src/test/java/io/weaviate/integration/client/backup/ClientBackupTest.java @@ -1,32 +1,41 @@ package io.weaviate.integration.client.backup; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.function.Function; +import java.util.function.Supplier; + +import org.assertj.core.api.Assertions; +import org.jetbrains.annotations.NotNull; +import org.junit.After; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; + import io.weaviate.client.Config; +import io.weaviate.client.WeaviateAuthClient; import io.weaviate.client.WeaviateClient; import io.weaviate.client.base.Result; +import io.weaviate.client.v1.auth.exception.AuthException; import io.weaviate.client.v1.backup.api.BackupCreator; import io.weaviate.client.v1.backup.api.BackupRestorer; +import io.weaviate.client.v1.backup.api.BackupRestorer.BackupRestoreConfig; import io.weaviate.client.v1.backup.model.BackupCreateResponse; import io.weaviate.client.v1.backup.model.BackupCreateStatusResponse; import io.weaviate.client.v1.backup.model.BackupRestoreResponse; import io.weaviate.client.v1.backup.model.BackupRestoreStatusResponse; +import io.weaviate.client.v1.backup.model.RbacRestoreOption; import io.weaviate.client.v1.graphql.model.GraphQLResponse; import io.weaviate.client.v1.graphql.query.fields.Field; -import io.weaviate.integration.client.WeaviateDockerCompose; +import io.weaviate.client.v1.rbac.model.ClusterPermission; +import io.weaviate.client.v1.rbac.model.Permission; +import io.weaviate.client.v1.schema.model.WeaviateClass; +import io.weaviate.integration.client.WeaviateDockerComposeBackup; import io.weaviate.integration.client.WeaviateTestGenerics; import io.weaviate.integration.tests.backup.BackupTestSuite; -import org.jetbrains.annotations.NotNull; -import org.junit.After; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TestName; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; -import java.util.function.Function; -import java.util.function.Supplier; public class ClientBackupTest { @@ -41,15 +50,16 @@ public class ClientBackupTest { public TestName currentTest = new TestName(); @ClassRule - public static WeaviateDockerCompose compose = new WeaviateDockerCompose(); + public static WeaviateDockerComposeBackup compose = new WeaviateDockerComposeBackup(); @Before - public void before() { + public void before() throws AuthException { Config config = new Config("http", compose.getHttpHostAddress()); - client = new WeaviateClient(config); + client = WeaviateAuthClient.apiKey(config, WeaviateDockerComposeBackup.ADMIN_KEY); testGenerics.createTestSchemaAndData(client); - backupId = String.format("backup-%s-%s", currentTest.getMethodName().toLowerCase(), rand.nextInt(Integer.MAX_VALUE)); + backupId = String.format("backup-%s-%s", currentTest.getMethodName().toLowerCase(), + rand.nextInt(Integer.MAX_VALUE)); notExistingBackupId = "not-existing-backup-" + backupId; } @@ -58,63 +68,64 @@ public void after() { testGenerics.cleanupWeaviate(client); } - @Test public void shouldCreateAndRestoreBackupWithWaiting() { Supplier> supplierCreateResult = () -> client.backup().creator() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(true) - .run(); + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(true) + .run(); Supplier> supplierCreateStatusResult = () -> client.backup().createStatusGetter() - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .run(); + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .run(); Supplier> supplierDeleteClass = () -> client.schema().classDeleter() - .withClassName(BackupTestSuite.CLASS_NAME_PIZZA) - .run(); + .withClassName(BackupTestSuite.CLASS_NAME_PIZZA) + .run(); Supplier> supplierRestoreResult = () -> client.backup().restorer() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(true) - .run(); - Supplier> supplierRestoreStatusResult = () -> client.backup().restoreStatusGetter() - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .run(); + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(true) + .run(); + Supplier> supplierRestoreStatusResult = () -> client.backup() + .restoreStatusGetter() + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .run(); BackupTestSuite.testCreateAndRestoreBackupWithWaiting(supplierCreateResult, supplierCreateStatusResult, - supplierRestoreResult, supplierRestoreStatusResult, supplierDeleteClass, createSupplierGQLOfClass(), backupId); + supplierRestoreResult, supplierRestoreStatusResult, supplierDeleteClass, createSupplierGQLOfClass(), backupId); } @Test public void shouldCreateAndRestoreBackupWithoutWaiting() throws InterruptedException { Supplier> supplierCreateResult = () -> client.backup().creator() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .run(); + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .run(); Supplier> supplierCreateStatusResult = () -> client.backup().createStatusGetter() - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .run(); + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .run(); Supplier> supplierDeleteClass = () -> client.schema().classDeleter() - .withClassName(BackupTestSuite.CLASS_NAME_PIZZA) - .run(); + .withClassName(BackupTestSuite.CLASS_NAME_PIZZA) + .run(); Supplier> supplierRestoreResult = () -> client.backup().restorer() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .run(); - Supplier> supplierRestoreStatusResult = () -> client.backup().restoreStatusGetter() - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .run(); + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .run(); + Supplier> supplierRestoreStatusResult = () -> client.backup() + .restoreStatusGetter() + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .run(); BackupTestSuite.testCreateAndRestoreBackupWithoutWaiting(supplierCreateResult, supplierCreateStatusResult, - supplierRestoreResult, supplierRestoreStatusResult, supplierDeleteClass, createSupplierGQLOfClass(), backupId); + supplierRestoreResult, supplierRestoreStatusResult, supplierDeleteClass, createSupplierGQLOfClass(), backupId); } @Test @@ -123,86 +134,90 @@ public void shouldCreateAndRestoreBackupWithDynamicLocation() throws Interrupted String path = "/custom/backup/location"; Supplier> supplierCreateResult = () -> client.backup().creator() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withConfig(BackupCreator.BackupCreateConfig.builder().bucket(bucket).path(path).build()) - .run(); + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withConfig(BackupCreator.BackupCreateConfig.builder().bucket(bucket).path(path).build()) + .run(); Supplier> supplierCreateStatusResult = () -> client.backup().createStatusGetter() - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withBucket(bucket) - .withPath(path) - .run(); + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withBucket(bucket) + .withPath(path) + .run(); Supplier> supplierDeleteClass = () -> client.schema().classDeleter() - .withClassName(BackupTestSuite.CLASS_NAME_PIZZA) - .run(); + .withClassName(BackupTestSuite.CLASS_NAME_PIZZA) + .run(); Supplier> supplierRestoreResult = () -> client.backup().restorer() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withConfig(BackupRestorer.BackupRestoreConfig.builder().bucket(bucket).path(path).build()) - .run(); - Supplier> supplierRestoreStatusResult = () -> client.backup().restoreStatusGetter() - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withBucket(bucket) - .withPath(path) - .run(); + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withConfig(BackupRestorer.BackupRestoreConfig.builder().bucket(bucket).path(path).build()) + .run(); + Supplier> supplierRestoreStatusResult = () -> client.backup() + .restoreStatusGetter() + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withBucket(bucket) + .withPath(path) + .run(); BackupTestSuite.testCreateWithDynamicLocation(supplierCreateResult, supplierCreateStatusResult, - supplierRestoreResult, supplierRestoreStatusResult, supplierDeleteClass, createSupplierGQLOfClass(), backupId, bucket, path); + supplierRestoreResult, supplierRestoreStatusResult, supplierDeleteClass, createSupplierGQLOfClass(), backupId, + bucket, path); } @Test public void shouldCreateAndRestore1Of2Classes() { Supplier> supplierCreateResult = () -> client.backup().creator() - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(true) - .run(); + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(true) + .run(); Supplier> supplierCreateStatusResult = () -> client.backup().createStatusGetter() - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .run(); + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .run(); Supplier> supplierDeleteClass = () -> client.schema().classDeleter() - .withClassName(BackupTestSuite.CLASS_NAME_PIZZA) - .run(); + .withClassName(BackupTestSuite.CLASS_NAME_PIZZA) + .run(); Supplier> supplierRestoreResult = () -> client.backup().restorer() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(true) - .run(); - Supplier> supplierRestoreStatusResult = () -> client.backup().restoreStatusGetter() - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .run(); + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(true) + .run(); + Supplier> supplierRestoreStatusResult = () -> client.backup() + .restoreStatusGetter() + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .run(); BackupTestSuite.testCreateAndRestore1Of2Classes(supplierCreateResult, supplierCreateStatusResult, - supplierRestoreResult, supplierRestoreStatusResult, supplierDeleteClass, createSupplierGQLOfClass(), backupId); + supplierRestoreResult, supplierRestoreStatusResult, supplierDeleteClass, createSupplierGQLOfClass(), backupId); } @Test public void shouldListCreatedBackups() { - List>> createSuppliers = new ArrayList>>() {{ - this.add(() -> client.backup().creator() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId+"-1") - .withWaitForCompletion(true) - .run() - ); - this.add(() -> client.backup().creator() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId+"-2") - .withWaitForCompletion(true) - .run() - ); - }}; + List>> createSuppliers = new ArrayList>>() { + { + this.add(() -> client.backup().creator() + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId + "-1") + .withWaitForCompletion(true) + .run()); + this.add(() -> client.backup().creator() + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId + "-2") + .withWaitForCompletion(true) + .run()); + } + }; - Supplier> supplierGetResult = () -> client.backup().getter().withBackend(BackupTestSuite.BACKEND).run(); + Supplier> supplierGetResult = () -> client.backup().getter() + .withBackend(BackupTestSuite.BACKEND).run(); BackupTestSuite.testListExistingBackups(createSuppliers, supplierGetResult); } @@ -210,10 +225,10 @@ public void shouldListCreatedBackups() { @Test public void shouldFailOnCreateBackupOnNotExistingBackend() { Supplier> supplierCreateResult = () -> client.backup().creator() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.NOT_EXISTING_BACKEND) - .withBackupId(backupId) - .run(); + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.NOT_EXISTING_BACKEND) + .withBackupId(backupId) + .run(); BackupTestSuite.testFailOnCreateBackupOnNotExistingBackend(supplierCreateResult); } @@ -221,9 +236,9 @@ public void shouldFailOnCreateBackupOnNotExistingBackend() { @Test public void shouldFailOnCreateBackupStatusOnNotExistingBackend() { Supplier> supplierCreateStatusResult = () -> client.backup().createStatusGetter() - .withBackend(BackupTestSuite.NOT_EXISTING_BACKEND) - .withBackupId(backupId) - .run(); + .withBackend(BackupTestSuite.NOT_EXISTING_BACKEND) + .withBackupId(backupId) + .run(); BackupTestSuite.testFailOnCreateBackupStatusOnNotExistingBackend(supplierCreateStatusResult); } @@ -231,10 +246,10 @@ public void shouldFailOnCreateBackupStatusOnNotExistingBackend() { @Test public void shouldFailOnRestoreBackupFromNotExistingBackend() { Supplier> supplierRestoreResult = () -> client.backup().restorer() - .withIncludeClassNames(BackupTestSuite.NOT_EXISTING_CLASS_NAME) - .withBackend(BackupTestSuite.NOT_EXISTING_BACKEND) - .withBackupId(backupId) - .run(); + .withIncludeClassNames(BackupTestSuite.NOT_EXISTING_CLASS_NAME) + .withBackend(BackupTestSuite.NOT_EXISTING_BACKEND) + .withBackupId(backupId) + .run(); BackupTestSuite.testFailOnRestoreBackupFromNotExistingBackend(supplierRestoreResult); } @@ -242,10 +257,10 @@ public void shouldFailOnRestoreBackupFromNotExistingBackend() { @Test public void shouldFailOnCreateBackupForNotExistingClass() { Supplier> supplierCreateResult = () -> client.backup().creator() - .withIncludeClassNames(BackupTestSuite.NOT_EXISTING_CLASS_NAME) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .run(); + .withIncludeClassNames(BackupTestSuite.NOT_EXISTING_CLASS_NAME) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .run(); BackupTestSuite.testFailOnCreateBackupForNotExistingClass(supplierCreateResult); } @@ -253,17 +268,17 @@ public void shouldFailOnCreateBackupForNotExistingClass() { @Test public void shouldFailOnRestoreBackupForExistingClass() { Supplier> supplierCreateResult = () -> client.backup().creator() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(true) - .run(); + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(true) + .run(); Supplier> supplierRestoreResult = () -> client.backup().restorer() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(true) - .run(); + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(true) + .run(); BackupTestSuite.testFailOnRestoreBackupForExistingClass(supplierCreateResult, supplierRestoreResult, backupId); } @@ -271,11 +286,11 @@ public void shouldFailOnRestoreBackupForExistingClass() { @Test public void shouldFailOnCreateOfExistingBackup() { Supplier> supplierCreateResult = () -> client.backup().creator() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(true) - .run(); + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(true) + .run(); BackupTestSuite.testFailOnCreateOfExistingBackup(supplierCreateResult, backupId); } @@ -283,9 +298,9 @@ public void shouldFailOnCreateOfExistingBackup() { @Test public void shouldFailOnCreateStatusOfNotExistingBackup() { Supplier> supplierCreateStatusResult = () -> client.backup().createStatusGetter() - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(notExistingBackupId) - .run(); + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(notExistingBackupId) + .run(); BackupTestSuite.testFailOnCreateStatusOfNotExistingBackup(supplierCreateStatusResult, notExistingBackupId); } @@ -293,10 +308,10 @@ public void shouldFailOnCreateStatusOfNotExistingBackup() { @Test public void shouldFailOnRestoreOfNotExistingBackup() { Supplier> supplierRestoreResult = () -> client.backup().restorer() - .withIncludeClassNames(BackupTestSuite.NOT_EXISTING_CLASS_NAME) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(notExistingBackupId) - .run(); + .withIncludeClassNames(BackupTestSuite.NOT_EXISTING_CLASS_NAME) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(notExistingBackupId) + .run(); BackupTestSuite.testFailOnRestoreOfNotExistingBackup(supplierRestoreResult, notExistingBackupId); } @@ -304,28 +319,30 @@ public void shouldFailOnRestoreOfNotExistingBackup() { @Test public void shouldFailOnRestoreBackupStatusOfNotStartedRestore() { Supplier> supplierCreateResult = () -> client.backup().creator() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(true) - .run(); - Supplier> supplierRestoreStatusResult = () -> client.backup().restoreStatusGetter() - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .run(); - - BackupTestSuite.testFailOnRestoreBackupStatusOfNotStartedRestore(supplierCreateResult, supplierRestoreStatusResult, backupId); + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(true) + .run(); + Supplier> supplierRestoreStatusResult = () -> client.backup() + .restoreStatusGetter() + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .run(); + + BackupTestSuite.testFailOnRestoreBackupStatusOfNotStartedRestore(supplierCreateResult, supplierRestoreStatusResult, + backupId); } @Test public void shouldFailOnCreateBackupForBothIncludeAndExcludeClasses() { Supplier> supplierCreateResult = () -> client.backup().creator() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withExcludeClassNames(BackupTestSuite.CLASS_NAME_SOUP) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(true) - .run(); + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withExcludeClassNames(BackupTestSuite.CLASS_NAME_SOUP) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(true) + .run(); BackupTestSuite.testFailOnCreateBackupForBothIncludeAndExcludeClasses(supplierCreateResult); } @@ -333,23 +350,23 @@ public void shouldFailOnCreateBackupForBothIncludeAndExcludeClasses() { @Test public void shouldFailOnRestoreBackupForBothIncludeAndExcludeClasses() { Supplier> supplierCreateResult = () -> client.backup().creator() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA, BackupTestSuite.CLASS_NAME_SOUP) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(true) - .run(); + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA, BackupTestSuite.CLASS_NAME_SOUP) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(true) + .run(); Supplier> supplierDeleteClass = () -> client.schema().classDeleter() - .withClassName(BackupTestSuite.CLASS_NAME_PIZZA) - .run(); + .withClassName(BackupTestSuite.CLASS_NAME_PIZZA) + .run(); Supplier> supplierRestoreResult = () -> client.backup().restorer() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withExcludeClassNames(BackupTestSuite.CLASS_NAME_SOUP) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .run(); + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withExcludeClassNames(BackupTestSuite.CLASS_NAME_SOUP) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .run(); BackupTestSuite.testFailOnRestoreBackupForBothIncludeAndExcludeClasses(supplierCreateResult, supplierRestoreResult, - supplierDeleteClass); + supplierDeleteClass); } @Test @@ -357,102 +374,151 @@ public void shouldCreateAndRestoreBackupWithWaitingWithConfig() { // config with too high value Supplier> supplierCreateInvConfigResult = () -> { BackupCreator.BackupCreateConfig config = BackupCreator.BackupCreateConfig.builder() - .cpuPercentage(801) - .build(); + .cpuPercentage(801) + .build(); return client.backup().creator() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withConfig(config) - .withWaitForCompletion(true) - .run(); + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withConfig(config) + .withWaitForCompletion(true) + .run(); }; // valid config Supplier> supplierCreateResult = () -> { BackupCreator.BackupCreateConfig config = BackupCreator.BackupCreateConfig.builder() - .cpuPercentage(80) - .chunkSize(512) - .compressionLevel(BackupCreator.BackupCompression.BEST_SPEED) - .build(); + .cpuPercentage(80) + .chunkSize(512) + .compressionLevel(BackupCreator.BackupCompression.BEST_SPEED) + .build(); return client.backup().creator() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withConfig(config) + .withWaitForCompletion(true) + .run(); + }; + Supplier> supplierCreateStatusResult = () -> client.backup().createStatusGetter() .withBackend(BackupTestSuite.BACKEND) .withBackupId(backupId) - .withConfig(config) - .withWaitForCompletion(true) .run(); - }; - Supplier> supplierCreateStatusResult = () -> client.backup().createStatusGetter() - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .run(); Supplier> supplierDeleteClass = () -> client.schema().classDeleter() - .withClassName(BackupTestSuite.CLASS_NAME_PIZZA) - .run(); + .withClassName(BackupTestSuite.CLASS_NAME_PIZZA) + .run(); // config with too high value Supplier> supplierRestoreInvConfigResult = () -> { BackupRestorer.BackupRestoreConfig restoreConfig = BackupRestorer.BackupRestoreConfig.builder() - .cpuPercentage(90) - .build(); + .cpuPercentage(90) + .build(); return client.backup().restorer() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withConfig(restoreConfig) - .withWaitForCompletion(true) - .run(); + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withConfig(restoreConfig) + .withWaitForCompletion(true) + .run(); }; // valid config Supplier> supplierRestoreResult = () -> { BackupRestorer.BackupRestoreConfig restoreConfig = BackupRestorer.BackupRestoreConfig.builder() - .cpuPercentage(70) - .build(); + .cpuPercentage(70) + .build(); return client.backup().restorer() - .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withIncludeClassNames(BackupTestSuite.CLASS_NAME_PIZZA) + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withConfig(restoreConfig) + .withWaitForCompletion(true) + .run(); + }; + Supplier> supplierRestoreStatusResult = () -> client.backup() + .restoreStatusGetter() .withBackend(BackupTestSuite.BACKEND) .withBackupId(backupId) - .withConfig(restoreConfig) - .withWaitForCompletion(true) .run(); - }; - Supplier> supplierRestoreStatusResult = () -> client.backup().restoreStatusGetter() - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .run(); BackupTestSuite.testCreateAndRestoreBackupWithWaitingWithConfig(supplierCreateInvConfigResult, supplierCreateResult, - supplierCreateStatusResult, supplierRestoreInvConfigResult, supplierRestoreResult, supplierRestoreStatusResult, - supplierDeleteClass, createSupplierGQLOfClass(), backupId); + supplierCreateStatusResult, supplierRestoreInvConfigResult, supplierRestoreResult, supplierRestoreStatusResult, + supplierDeleteClass, createSupplierGQLOfClass(), backupId); } @Test public void shouldCancelBackup() { Supplier> supplierCreateResult = () -> client.backup().creator() - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .withWaitForCompletion(false) // this will allow us to "intercept" the backup in progress - .run(); + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withWaitForCompletion(false) // this will allow us to "intercept" the backup in progress + .run(); Supplier> supplierCancelResult = () -> client.backup().canceler() - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .run(); + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .run(); Supplier> supplierCreateStatusResult = () -> client.backup().createStatusGetter() - .withBackend(BackupTestSuite.BACKEND) - .withBackupId(backupId) - .run(); + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .run(); BackupTestSuite.testCancelBackup(supplierCreateResult, supplierCancelResult, supplierCreateStatusResult); } + @Test + public void shouldRestoreWithRbacOptions() { + final String className = "RolesUsers"; + final String roleName = "restoreRole"; + final String userName = "restoreUser"; + + BackupTestSuite.testBackupRestoreWithRbacOptions(backupId, + // Arrange: create collection, create role, create user; + () -> { + client.schema().classDeleter().withClassName(className).run(); + client.schema().classCreator().withClass(WeaviateClass.builder().className(className).build()).run(); + + client.roles().deleter().withName(roleName).run(); + Result createRole = client.roles().creator().withName(roleName) + .withPermissions(Permission.cluster(ClusterPermission.Action.READ)).run(); + Assertions.assertThat(createRole.getError()).as("create role").isNull(); + + client.users().db().deleter().withUserId(userName).run(); + Result createUser = client.users().db().creator().withUserId(userName).run(); + Assertions.assertThat(createUser.getError()).as("create user").isNull(); + }, + () -> { + client.schema().classDeleter().withClassName(className).run(); + client.roles().deleter().withName(roleName).run(); + client.users().db().deleter().withUserId(userName).run(); + }, + // Create backup + () -> client.backup().creator() + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withIncludeClassNames("RolesUsers") + .withWaitForCompletion(true) + .run(), + // Restore from backup + () -> client.backup().restorer() + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withIncludeClassNames("RolesUsers") + .withWaitForCompletion(true) + .withConfig(BackupRestoreConfig.builder() + .usersRestore(RbacRestoreOption.ALL) + .rolesRestore(RbacRestoreOption.ALL) + .build()) + .run(), + () -> client.users().db().getUser().withUserId(userName).run(), + () -> client.roles().getter().withName(roleName).run()); + } + @NotNull private Function> createSupplierGQLOfClass() { return (String className) -> client.graphQL().get() - .withClassName(className) - .withFields(Field.builder().name("name").build()) - .run(); + .withClassName(className) + .withFields(Field.builder().name("name").build()) + .run(); } } diff --git a/src/test/java/io/weaviate/integration/tests/backup/BackupTestSuite.java b/src/test/java/io/weaviate/integration/tests/backup/BackupTestSuite.java index f648a8166..d68c9aa6d 100644 --- a/src/test/java/io/weaviate/integration/tests/backup/BackupTestSuite.java +++ b/src/test/java/io/weaviate/integration/tests/backup/BackupTestSuite.java @@ -27,6 +27,8 @@ import io.weaviate.client.v1.backup.model.CreateStatus; import io.weaviate.client.v1.backup.model.RestoreStatus; import io.weaviate.client.v1.graphql.model.GraphQLResponse; +import io.weaviate.client.v1.rbac.model.Role; +import io.weaviate.client.v1.users.model.UserDb; public class BackupTestSuite { @@ -38,12 +40,12 @@ public class BackupTestSuite { public static final String NOT_EXISTING_BACKEND = "not-existing-backend"; public static void testCreateAndRestoreBackupWithWaiting(Supplier> supplierCreate, - Supplier> supplierCreateStatus, - Supplier> supplierRestore, - Supplier> supplierRestoreStatus, - Supplier> supplierDeleteClass, - Function> supplierGQLOfClass, - String backupId) { + Supplier> supplierCreateStatus, + Supplier> supplierRestore, + Supplier> supplierRestoreStatus, + Supplier> supplierDeleteClass, + Function> supplierGQLOfClass, + String backupId) { assertThatAllPizzasExist(supplierGQLOfClass); // Create backup @@ -51,12 +53,12 @@ public static void testCreateAndRestoreBackupWithWaiting(Supplier delete = supplierDeleteClass.get(); @@ -82,12 +84,12 @@ public static void testCreateAndRestoreBackupWithWaiting(Supplier> supplierCreate, - Supplier> supplierCreateStatus, - Supplier> supplierRestore, - Supplier> supplierRestoreStatus, - Supplier> supplierDeleteClass, - Function> supplierGQLOfClass, - String backupId, String bucket, String path) throws InterruptedException { + Supplier> supplierCreateStatus, + Supplier> supplierRestore, + Supplier> supplierRestoreStatus, + Supplier> supplierDeleteClass, + Function> supplierGQLOfClass, + String backupId, String bucket, String path) throws InterruptedException { assertThatAllPizzasExist(supplierGQLOfClass); String wantFullPath = Paths.get(path, backupId).toString(); Result createResult = supplierCreate.get(); assertThat(createResult.getError()).as("create backup").isNull(); assertThat(createResult.getResult()).isNotNull() - .returns(backupId, BackupCreateResponse::getId) - .returns(wantFullPath, BackupCreateResponse::getPath).as("path in BackupCreateResponse"); + .returns(backupId, BackupCreateResponse::getId) + .returns(wantFullPath, BackupCreateResponse::getPath).as("path in BackupCreateResponse"); // Wait until created Result createStatusResult; @@ -126,10 +128,10 @@ public static void testCreateWithDynamicLocation(Supplier restoreResult = supplierRestore.get(); assertThat(restoreResult.getError()).as("restore from backup").isNull(); assertThat(restoreResult.getResult()).isNotNull() - .returns(backupId, BackupRestoreResponse::getId) - .returns(wantFullPath, BackupRestoreResponse::getPath); + .returns(backupId, BackupRestoreResponse::getId) + .returns(wantFullPath, BackupRestoreResponse::getPath); // Wait until restored Result restoreStatusResult; @@ -156,10 +157,10 @@ public static void testCreateWithDynamicLocation(Supplier> supplierCreate, - Supplier> supplierCreateStatus, - Supplier> supplierRestore, - Supplier> supplierRestoreStatus, - Supplier> supplierDeleteClass, - Function> supplierGQLOfClass, - String backupId) throws InterruptedException { + Supplier> supplierCreateStatus, + Supplier> supplierRestore, + Supplier> supplierRestoreStatus, + Supplier> supplierDeleteClass, + Function> supplierGQLOfClass, + String backupId) throws InterruptedException { assertThatAllPizzasExist(supplierGQLOfClass); // Start creating backup @@ -184,12 +185,12 @@ public static void testCreateAndRestoreBackupWithoutWaiting(Supplier createStatusResult; @@ -198,13 +199,12 @@ public static void testCreateAndRestoreBackupWithoutWaiting(Supplier restoreStatusResult; @@ -239,13 +239,12 @@ public static void testCreateAndRestoreBackupWithoutWaiting(Supplier> supplierCreate, - Supplier> supplierCreateStatus, - Supplier> supplierRestore, - Supplier> supplierRestoreStatus, - Supplier> supplierDeleteClass, - Function> supplierGQLOfClass, - String backupId) { + Supplier> supplierCreateStatus, + Supplier> supplierRestore, + Supplier> supplierRestoreStatus, + Supplier> supplierDeleteClass, + Function> supplierGQLOfClass, + String backupId) { assertThatAllPizzasExist(supplierGQLOfClass); assertThatAllSoupsExist(supplierGQLOfClass); @@ -271,13 +270,13 @@ public static void testCreateAndRestore1Of2Classes(Supplier delete = supplierDeleteClass.get(); @@ -304,12 +303,12 @@ public static void testCreateAndRestore1Of2Classes(Supplier>> createSuppliers, - Supplier> supplierGet) { + Supplier> supplierGet) { // Create backups createSuppliers.forEach(Supplier::get); @@ -337,7 +336,7 @@ public static void testListExistingBackups(List> supplierCreate) { @@ -345,35 +344,37 @@ public static void testFailOnCreateBackupOnNotExistingBackend(Supplier ((WeaviateErrorMessage) msg).getMessage()) - .first().asInstanceOf(CHAR_SEQUENCE).contains(NOT_EXISTING_BACKEND); + .returns(HttpStatus.SC_UNPROCESSABLE_ENTITY, WeaviateError::getStatusCode) + .extracting(WeaviateError::getMessages).asList() + .hasSizeGreaterThan(0) + .extracting(msg -> ((WeaviateErrorMessage) msg).getMessage()) + .first().asInstanceOf(CHAR_SEQUENCE).contains(NOT_EXISTING_BACKEND); } - public static void testFailOnCreateBackupStatusOnNotExistingBackend(Supplier> supplierCreateStatus) { + public static void testFailOnCreateBackupStatusOnNotExistingBackend( + Supplier> supplierCreateStatus) { Result createStatusResult = supplierCreateStatus.get(); assertThat(createStatusResult.hasErrors()).isTrue(); assertThat(createStatusResult.getError()).isNotNull() - .returns(HttpStatus.SC_UNPROCESSABLE_ENTITY, WeaviateError::getStatusCode) - .extracting(WeaviateError::getMessages).asList() - .hasSizeGreaterThan(0) - .extracting(msg -> ((WeaviateErrorMessage) msg).getMessage()) - .first().asInstanceOf(CHAR_SEQUENCE).contains(NOT_EXISTING_BACKEND); + .returns(HttpStatus.SC_UNPROCESSABLE_ENTITY, WeaviateError::getStatusCode) + .extracting(WeaviateError::getMessages).asList() + .hasSizeGreaterThan(0) + .extracting(msg -> ((WeaviateErrorMessage) msg).getMessage()) + .first().asInstanceOf(CHAR_SEQUENCE).contains(NOT_EXISTING_BACKEND); } - public static void testFailOnRestoreBackupFromNotExistingBackend(Supplier> supplierRestore) { + public static void testFailOnRestoreBackupFromNotExistingBackend( + Supplier> supplierRestore) { Result restoreResult = supplierRestore.get(); assertThat(restoreResult.hasErrors()).isTrue(); assertThat(restoreResult.getError()).isNotNull() - .returns(HttpStatus.SC_UNPROCESSABLE_ENTITY, WeaviateError::getStatusCode) - .extracting(WeaviateError::getMessages).asList() - .hasSizeGreaterThan(0) - .extracting(msg -> ((WeaviateErrorMessage) msg).getMessage()) - .first().asInstanceOf(CHAR_SEQUENCE).contains(NOT_EXISTING_BACKEND); + .returns(HttpStatus.SC_UNPROCESSABLE_ENTITY, WeaviateError::getStatusCode) + .extracting(WeaviateError::getMessages).asList() + .hasSizeGreaterThan(0) + .extracting(msg -> ((WeaviateErrorMessage) msg).getMessage()) + .first().asInstanceOf(CHAR_SEQUENCE).contains(NOT_EXISTING_BACKEND); } public static void testFailOnCreateBackupForNotExistingClass(Supplier> supplierCreate) { @@ -381,16 +382,16 @@ public static void testFailOnCreateBackupForNotExistingClass(Supplier ((WeaviateErrorMessage) msg).getMessage()) - .first().asInstanceOf(CHAR_SEQUENCE).contains(NOT_EXISTING_CLASS_NAME); + .returns(HttpStatus.SC_UNPROCESSABLE_ENTITY, WeaviateError::getStatusCode) + .extracting(WeaviateError::getMessages).asList() + .hasSizeGreaterThan(0) + .extracting(msg -> ((WeaviateErrorMessage) msg).getMessage()) + .first().asInstanceOf(CHAR_SEQUENCE).contains(NOT_EXISTING_CLASS_NAME); } public static void testFailOnRestoreBackupForExistingClass(Supplier> supplierCreate, - Supplier> supplierRestore, - String backupId) { + Supplier> supplierRestore, + String backupId) { Result createResult = supplierCreate.get(); assertThat(createResult.hasErrors()).isFalse(); @@ -399,15 +400,16 @@ public static void testFailOnRestoreBackupForExistingClass(Supplier> supplierCreate, - String backupId) { + String backupId) { Result createResult = supplierCreate.get(); assertThat(createResult.hasErrors()).isFalse(); @@ -416,42 +418,44 @@ public static void testFailOnCreateOfExistingBackup(Supplier ((WeaviateErrorMessage) msg).getMessage()) - .first().asInstanceOf(CHAR_SEQUENCE).contains(backupId); + .returns(HttpStatus.SC_UNPROCESSABLE_ENTITY, WeaviateError::getStatusCode) + .extracting(WeaviateError::getMessages).asList() + .hasSizeGreaterThan(0) + .extracting(msg -> ((WeaviateErrorMessage) msg).getMessage()) + .first().asInstanceOf(CHAR_SEQUENCE).contains(backupId); } - public static void testFailOnCreateStatusOfNotExistingBackup(Supplier> supplierCreateStatus, - String backupId) { + public static void testFailOnCreateStatusOfNotExistingBackup( + Supplier> supplierCreateStatus, + String backupId) { Result createStatusResult = supplierCreateStatus.get(); assertThat(createStatusResult.hasErrors()).isTrue(); assertThat(createStatusResult.getError()).isNotNull() - .returns(HttpStatus.SC_NOT_FOUND, WeaviateError::getStatusCode) - .extracting(WeaviateError::getMessages).asList() - .hasSizeGreaterThan(0) - .extracting(msg -> ((WeaviateErrorMessage) msg).getMessage()) - .first().asInstanceOf(CHAR_SEQUENCE).contains(backupId); + .returns(HttpStatus.SC_NOT_FOUND, WeaviateError::getStatusCode) + .extracting(WeaviateError::getMessages).asList() + .hasSizeGreaterThan(0) + .extracting(msg -> ((WeaviateErrorMessage) msg).getMessage()) + .first().asInstanceOf(CHAR_SEQUENCE).contains(backupId); } public static void testFailOnRestoreOfNotExistingBackup(Supplier> supplierRestore, - String backupId) { + String backupId) { Result restoreResult = supplierRestore.get(); assertThat(restoreResult.hasErrors()).isTrue(); assertThat(restoreResult.getError()).isNotNull() - .returns(HttpStatus.SC_NOT_FOUND, WeaviateError::getStatusCode) - .extracting(WeaviateError::getMessages).asList() - .hasSizeGreaterThan(0) - .extracting(msg -> ((WeaviateErrorMessage) msg).getMessage()) - .first().asInstanceOf(CHAR_SEQUENCE).contains(backupId); + .returns(HttpStatus.SC_NOT_FOUND, WeaviateError::getStatusCode) + .extracting(WeaviateError::getMessages).asList() + .hasSizeGreaterThan(0) + .extracting(msg -> ((WeaviateErrorMessage) msg).getMessage()) + .first().asInstanceOf(CHAR_SEQUENCE).contains(backupId); } - public static void testFailOnRestoreBackupStatusOfNotStartedRestore(Supplier> supplierCreate, - Supplier> supplierRestoreStatus, - String backupId) { + public static void testFailOnRestoreBackupStatusOfNotStartedRestore( + Supplier> supplierCreate, + Supplier> supplierRestoreStatus, + String backupId) { Result createResult = supplierCreate.get(); assertThat(createResult.hasErrors()).isFalse(); @@ -460,28 +464,30 @@ public static void testFailOnRestoreBackupStatusOfNotStartedRestore(Supplier ((WeaviateErrorMessage) msg).getMessage()) - .first().asInstanceOf(CHAR_SEQUENCE).contains(backupId); + .returns(HttpStatus.SC_NOT_FOUND, WeaviateError::getStatusCode) + .extracting(WeaviateError::getMessages).asList() + .hasSizeGreaterThan(0) + .extracting(msg -> ((WeaviateErrorMessage) msg).getMessage()) + .first().asInstanceOf(CHAR_SEQUENCE).contains(backupId); } - public static void testFailOnCreateBackupForBothIncludeAndExcludeClasses(Supplier> supplierCreate) { + public static void testFailOnCreateBackupForBothIncludeAndExcludeClasses( + Supplier> supplierCreate) { Result createResult = supplierCreate.get(); assertThat(createResult.hasErrors()).isTrue(); assertThat(createResult.getError()).isNotNull() - .returns(HttpStatus.SC_UNPROCESSABLE_ENTITY, WeaviateError::getStatusCode) - .extracting(WeaviateError::getMessages).asList() - .hasSizeGreaterThan(0) - .extracting(msg -> ((WeaviateErrorMessage) msg).getMessage()) - .first().asInstanceOf(CHAR_SEQUENCE).contains("include").contains("exclude"); + .returns(HttpStatus.SC_UNPROCESSABLE_ENTITY, WeaviateError::getStatusCode) + .extracting(WeaviateError::getMessages).asList() + .hasSizeGreaterThan(0) + .extracting(msg -> ((WeaviateErrorMessage) msg).getMessage()) + .first().asInstanceOf(CHAR_SEQUENCE).contains("include").contains("exclude"); } - public static void testFailOnRestoreBackupForBothIncludeAndExcludeClasses(Supplier> supplierCreate, - Supplier> supplierRestore, - Supplier> supplierDeleteClass) { + public static void testFailOnRestoreBackupForBothIncludeAndExcludeClasses( + Supplier> supplierCreate, + Supplier> supplierRestore, + Supplier> supplierDeleteClass) { // Create backup Result createResult = supplierCreate.get(); @@ -497,43 +503,45 @@ public static void testFailOnRestoreBackupForBothIncludeAndExcludeClasses(Suppli assertThat(restoreResult.hasErrors()).isTrue(); assertThat(restoreResult.getError()).isNotNull() - .returns(HttpStatus.SC_UNPROCESSABLE_ENTITY, WeaviateError::getStatusCode) - .extracting(WeaviateError::getMessages).asList() - .hasSizeGreaterThan(0) - .extracting(msg -> ((WeaviateErrorMessage) msg).getMessage()) - .first().asInstanceOf(CHAR_SEQUENCE).contains("include").contains("exclude"); + .returns(HttpStatus.SC_UNPROCESSABLE_ENTITY, WeaviateError::getStatusCode) + .extracting(WeaviateError::getMessages).asList() + .hasSizeGreaterThan(0) + .extracting(msg -> ((WeaviateErrorMessage) msg).getMessage()) + .first().asInstanceOf(CHAR_SEQUENCE).contains("include").contains("exclude"); } - public static void testCreateAndRestoreBackupWithWaitingWithConfig(Supplier> supplierCreateInvConfig, - Supplier> supplierCreate, - Supplier> supplierCreateStatus, - Supplier> supplierRestoreInvConfig, - Supplier> supplierRestore, - Supplier> supplierRestoreStatus, - Supplier> supplierDeleteClass, - Function> supplierGQLOfClass, - String backupId) { + public static void testCreateAndRestoreBackupWithWaitingWithConfig( + Supplier> supplierCreateInvConfig, + Supplier> supplierCreate, + Supplier> supplierCreateStatus, + Supplier> supplierRestoreInvConfig, + Supplier> supplierRestore, + Supplier> supplierRestoreStatus, + Supplier> supplierDeleteClass, + Function> supplierGQLOfClass, + String backupId) { assertThatAllPizzasExist(supplierGQLOfClass); // Try to create with too high value Result createResult = supplierCreateInvConfig.get(); assertThat(createResult).isNotNull() - .extracting(Result::getError).isNotNull() - .extracting(WeaviateError::getMessages) - .satisfies(errors -> assertThat(errors.stream().filter(m -> m.getMessage().contains("CPUPercentage")).count()).isGreaterThanOrEqualTo(1)); + .extracting(Result::getError).isNotNull() + .extracting(WeaviateError::getMessages) + .satisfies(errors -> assertThat(errors.stream().filter(m -> m.getMessage().contains("CPUPercentage")).count()) + .isGreaterThanOrEqualTo(1)); // Create backup createResult = supplierCreate.get(); assertThat(createResult.hasErrors()).isFalse(); assertThat(createResult.getResult()).isNotNull() - .returns(backupId, BackupCreateResponse::getId) - .returns(new String[]{CLASS_NAME_PIZZA}, BackupCreateResponse::getClassNames) - .returns(DOCKER_COMPOSE_BACKUPS_DIR + "/" + backupId, BackupCreateResponse::getPath) - .returns(BACKEND, BackupCreateResponse::getBackend) - .returns(CreateStatus.SUCCESS, BackupCreateResponse::getStatus) - .returns(null, BackupCreateResponse::getError); + .returns(backupId, BackupCreateResponse::getId) + .returns(new String[] { CLASS_NAME_PIZZA }, BackupCreateResponse::getClassNames) + .returns(DOCKER_COMPOSE_BACKUPS_DIR + "/" + backupId, BackupCreateResponse::getPath) + .returns(BACKEND, BackupCreateResponse::getBackend) + .returns(CreateStatus.SUCCESS, BackupCreateResponse::getStatus) + .returns(null, BackupCreateResponse::getError); assertThatAllPizzasExist(supplierGQLOfClass); @@ -542,11 +550,11 @@ public static void testCreateAndRestoreBackupWithWaitingWithConfig(Supplier delete = supplierDeleteClass.get(); @@ -554,26 +562,26 @@ public static void testCreateAndRestoreBackupWithWaitingWithConfig(Supplier restoreResult = supplierRestoreInvConfig.get(); assertThat(restoreResult).isNotNull() - .extracting(Result::getError).isNotNull() - .extracting(WeaviateError::getMessages).isNotNull() - .satisfies(errors -> assertThat(errors.stream().filter(m -> m.getMessage().contains("CPUPercentage")).count()).isGreaterThanOrEqualTo(1)); + .extracting(Result::getError).isNotNull() + .extracting(WeaviateError::getMessages).isNotNull() + .satisfies(errors -> assertThat(errors.stream().filter(m -> m.getMessage().contains("CPUPercentage")).count()) + .isGreaterThanOrEqualTo(1)); // Restore backup restoreResult = supplierRestore.get(); assertThat(restoreResult.hasErrors()).isFalse(); assertThat(restoreResult.getResult()).isNotNull() - .returns(backupId, BackupRestoreResponse::getId) - .returns(new String[]{CLASS_NAME_PIZZA}, BackupRestoreResponse::getClassNames) - .returns(DOCKER_COMPOSE_BACKUPS_DIR + "/" + backupId, BackupRestoreResponse::getPath) - .returns(BACKEND, BackupRestoreResponse::getBackend) - .returns(RestoreStatus.SUCCESS, BackupRestoreResponse::getStatus) - .returns(null, BackupRestoreResponse::getError); + .returns(backupId, BackupRestoreResponse::getId) + .returns(new String[] { CLASS_NAME_PIZZA }, BackupRestoreResponse::getClassNames) + .returns(DOCKER_COMPOSE_BACKUPS_DIR + "/" + backupId, BackupRestoreResponse::getPath) + .returns(BACKEND, BackupRestoreResponse::getBackend) + .returns(RestoreStatus.SUCCESS, BackupRestoreResponse::getStatus) + .returns(null, BackupRestoreResponse::getError); assertThatAllPizzasExist(supplierGQLOfClass); @@ -582,16 +590,16 @@ public static void testCreateAndRestoreBackupWithWaitingWithConfig(Supplier> supplierCreate, - Supplier> supplierCancel, - Supplier> supplierCreateStatus) { + Supplier> supplierCancel, + Supplier> supplierCreateStatus) { Result createResult = supplierCreate.get(); assertThat(createResult.getError()).as("start backup").isNull(); @@ -601,8 +609,39 @@ public static void testCancelBackup(Supplier> suppl waitForCreateStatus(supplierCreateStatus, CreateStatus.CANCELED); } + public static void testBackupRestoreWithRbacOptions(String backupId, + Runnable arrange, + Runnable delete, + Supplier> supplierCreate, + Supplier> supplierRestore, + Supplier> supplierUser, + Supplier> supplierRole) { + + // Arrange + arrange.run(); + + // Act + Result createBackup = supplierCreate.get(); + assertThat(createBackup.getError()).as("create backup").isNull(); + assertThat(createBackup.getResult().getStatus()) + .as("create backup status: " + createBackup.getResult().getError()).isEqualTo("SUCCESS"); + + delete.run(); + + Result restoreBackup = supplierRestore.get(); + assertThat(restoreBackup.getError()).as("restore backup").isNull(); + assertThat(restoreBackup.getResult().getStatus()) + .as("restore backup status: " + restoreBackup.getResult().getError()).isEqualTo("SUCCESS"); + + // Assert + assertThat(supplierUser.get().getResult()).as("get restored user").isNotNull(); + assertThat(supplierRole.get().getResult()).as("get restored role").isNotNull(); + + } + private static void assertThatAllPizzasExist(Function> supplierGQLOfClass) { - assertThatAllFoodObjectsExist(supplierGQLOfClass, "Pizza", "Quattro Formaggi", "Frutti di Mare", "Hawaii", "Doener"); + assertThatAllFoodObjectsExist(supplierGQLOfClass, "Pizza", "Quattro Formaggi", "Frutti di Mare", "Hawaii", + "Doener"); } private static void assertThatAllSoupsExist(Function> supplierGQLOfClass) { @@ -610,27 +649,31 @@ private static void assertThatAllSoupsExist(Function> supplierGQLOfClass, - String className, String... names) { + String className, String... names) { Result result = supplierGQLOfClass.apply(className); assertThat(result.hasErrors()).isFalse(); assertThat(result.getResult()).isNotNull() - .extracting(GraphQLResponse::getData).isInstanceOf(Map.class) - .extracting(data -> ((Map) data).get("Get")).isInstanceOf(Map.class) - .extracting(get -> ((Map) get).get(className)).asList() - .hasSize(names.length).hasOnlyElementsOfType(Map.class) - .extracting(pizza -> ((Map) pizza).get("name")).hasOnlyElementsOfType(String.class) - .extracting(name -> (String) name) - .containsExactlyInAnyOrder(names); + .extracting(GraphQLResponse::getData).isInstanceOf(Map.class) + .extracting(data -> ((Map) data).get("Get")).isInstanceOf(Map.class) + .extracting(get -> ((Map) get).get(className)).asList() + .hasSize(names.length).hasOnlyElementsOfType(Map.class) + .extracting(pizza -> ((Map) pizza).get("name")).hasOnlyElementsOfType(String.class) + .extracting(name -> (String) name) + .containsExactlyInAnyOrder(names); } /** - * Periodically polls backup creation status until it reaches the desired ({@code want}) state or the deadline expires. + * Periodically polls backup creation status until it reaches the desired + * ({@code want}) state or the deadline expires. * - *
Interval: 100ms - *
Timeout: 5s + *
+ * Interval: 100ms + *
+ * Timeout: 5s */ - private static void waitForCreateStatus(Supplier> supplierCreateStatus, String want) { + private static void waitForCreateStatus(Supplier> supplierCreateStatus, + String want) { final int MAX_RETRIES = 5_000 / 100; AtomicReference status = new AtomicReference<>(""); @@ -659,17 +702,18 @@ private static void waitForCreateStatus(Supplier - * We assume that in such cases the server will return an response with body "not implemented"; + * We assume that in such cases the server will return an response with body + * "not implemented"; * this is not a good reason to fail the client's test. + * * @param result Any Result object from a request. */ private static void skipIfNotImplemented(Result result) { if (result.hasErrors()) { assumeTrue( - "this operation is not implemented on the server", - result.getError().getMessages().stream() - .noneMatch(err -> err.getMessage().toLowerCase().contains("not implemented")) - ); + "this operation is not implemented on the server", + result.getError().getMessages().stream() + .noneMatch(err -> err.getMessage().toLowerCase().contains("not implemented"))); } } }