diff --git a/src/main/java/io/weaviate/client/v1/async/backup/api/BackupCanceler.java b/src/main/java/io/weaviate/client/v1/async/backup/api/BackupCanceler.java index dde418ab..1d2fb931 100644 --- a/src/main/java/io/weaviate/client/v1/async/backup/api/BackupCanceler.java +++ b/src/main/java/io/weaviate/client/v1/async/backup/api/BackupCanceler.java @@ -1,15 +1,18 @@ package io.weaviate.client.v1.async.backup.api; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Future; + +import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; +import org.apache.hc.core5.concurrent.FutureCallback; + import io.weaviate.client.Config; import io.weaviate.client.base.AsyncBaseClient; import io.weaviate.client.base.AsyncClientResult; import io.weaviate.client.base.Result; import io.weaviate.client.base.util.UrlEncoder; import io.weaviate.client.v1.auth.provider.AccessTokenProvider; -import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; -import org.apache.hc.core5.concurrent.FutureCallback; - -import java.util.concurrent.Future; /** * BackupCanceler can cancel an in-progress backup by ID. @@ -22,13 +25,14 @@ public class BackupCanceler extends AsyncBaseClient private String backend; private String backupId; + private String bucket; + private String backupPath; public BackupCanceler(CloseableHttpAsyncClient client, Config config, AccessTokenProvider tokenProvider) { super(client, config, tokenProvider); } - public BackupCanceler withBackend(String backend) { this.backend = backend; return this; @@ -39,10 +43,32 @@ public BackupCanceler withBackupId(String backupId) { return this; } + public BackupCanceler withBucket(String bucket) { + this.bucket = bucket; + return this; + } + + public BackupCanceler withPath(String path) { + this.backupPath = path; + return this; + } + @Override public Future> run(FutureCallback> callback) { String path = String.format("/backups/%s/%s", UrlEncoder.encodePathParam(backend), UrlEncoder.encodePathParam(backupId)); + + List queryParams = new ArrayList<>(); + if (this.bucket != null) { + queryParams.add(UrlEncoder.encodeQueryParam("bucket", this.bucket)); + } + if (this.backupPath != null) { + queryParams.add(UrlEncoder.encodeQueryParam("path", this.backupPath)); + } + + if (!queryParams.isEmpty()) { + path += "?" + String.join("&", queryParams); + } return sendDeleteRequest(path, null, Void.class, callback); } } diff --git a/src/main/java/io/weaviate/client/v1/async/backup/api/BackupCreateStatusGetter.java b/src/main/java/io/weaviate/client/v1/async/backup/api/BackupCreateStatusGetter.java index cbad847f..32c65572 100644 --- a/src/main/java/io/weaviate/client/v1/async/backup/api/BackupCreateStatusGetter.java +++ b/src/main/java/io/weaviate/client/v1/async/backup/api/BackupCreateStatusGetter.java @@ -1,5 +1,12 @@ package io.weaviate.client.v1.async.backup.api; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Future; + +import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; +import org.apache.hc.core5.concurrent.FutureCallback; + import io.weaviate.client.Config; import io.weaviate.client.base.AsyncBaseClient; import io.weaviate.client.base.AsyncClientResult; @@ -7,17 +14,14 @@ import io.weaviate.client.base.util.UrlEncoder; import io.weaviate.client.v1.auth.provider.AccessTokenProvider; import io.weaviate.client.v1.backup.model.BackupCreateStatusResponse; -import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; -import org.apache.hc.core5.concurrent.FutureCallback; - -import java.util.concurrent.Future; public class BackupCreateStatusGetter extends AsyncBaseClient implements AsyncClientResult { private String backend; private String backupId; - + private String bucket; + private String backupPath; public BackupCreateStatusGetter(CloseableHttpAsyncClient client, Config config, AccessTokenProvider tokenProvider) { super(client, config, tokenProvider); @@ -34,9 +38,31 @@ public BackupCreateStatusGetter withBackupId(String backupId) { return this; } + public BackupCreateStatusGetter withBucket(String bucket) { + this.bucket = bucket; + return this; + } + + public BackupCreateStatusGetter withPath(String path) { + this.backupPath = path; + return this; + } + @Override public Future> run(FutureCallback> callback) { String path = String.format("/backups/%s/%s", UrlEncoder.encodePathParam(backend), UrlEncoder.encodePathParam(backupId)); + + List queryParams = new ArrayList<>(); + if (this.bucket != null) { + queryParams.add(UrlEncoder.encodeQueryParam("bucket", this.bucket)); + } + if (this.backupPath != null) { + queryParams.add(UrlEncoder.encodeQueryParam("path", this.backupPath)); + } + + if (!queryParams.isEmpty()) { + path += "?" + String.join("&", queryParams); + } return sendGetRequest(path, BackupCreateStatusResponse.class, callback); } } diff --git a/src/main/java/io/weaviate/client/v1/async/backup/api/BackupCreator.java b/src/main/java/io/weaviate/client/v1/async/backup/api/BackupCreator.java index 84487916..b09072f7 100644 --- a/src/main/java/io/weaviate/client/v1/async/backup/api/BackupCreator.java +++ b/src/main/java/io/weaviate/client/v1/async/backup/api/BackupCreator.java @@ -242,6 +242,10 @@ public static class BackupCreateConfig { Integer chunkSize; @SerializedName("CompressionLevel") String compressionLevel; + @SerializedName("Bucket") + String bucket; + @SerializedName("Path") + String path; } public interface BackupCompression { diff --git a/src/main/java/io/weaviate/client/v1/async/backup/api/BackupRestoreStatusGetter.java b/src/main/java/io/weaviate/client/v1/async/backup/api/BackupRestoreStatusGetter.java index 4ef10ce2..e1331cb0 100644 --- a/src/main/java/io/weaviate/client/v1/async/backup/api/BackupRestoreStatusGetter.java +++ b/src/main/java/io/weaviate/client/v1/async/backup/api/BackupRestoreStatusGetter.java @@ -1,5 +1,12 @@ package io.weaviate.client.v1.async.backup.api; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Future; + +import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; +import org.apache.hc.core5.concurrent.FutureCallback; + import io.weaviate.client.Config; import io.weaviate.client.base.AsyncBaseClient; import io.weaviate.client.base.AsyncClientResult; @@ -7,17 +14,14 @@ import io.weaviate.client.base.util.UrlEncoder; import io.weaviate.client.v1.auth.provider.AccessTokenProvider; import io.weaviate.client.v1.backup.model.BackupRestoreStatusResponse; -import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient; -import org.apache.hc.core5.concurrent.FutureCallback; - -import java.util.concurrent.Future; public class BackupRestoreStatusGetter extends AsyncBaseClient implements AsyncClientResult { private String backend; private String backupId; - + private String bucket; + private String backupPath; public BackupRestoreStatusGetter(CloseableHttpAsyncClient client, Config config, AccessTokenProvider tokenProvider) { super(client, config, tokenProvider); @@ -34,10 +38,31 @@ public BackupRestoreStatusGetter withBackupId(String backupId) { return this; } + public BackupRestoreStatusGetter withBucket(String bucket) { + this.bucket = bucket; + return this; + } + + public BackupRestoreStatusGetter withPath(String path) { + this.backupPath = path; + return this; + } @Override public Future> run(FutureCallback> callback) { String path = String.format("/backups/%s/%s/restore", UrlEncoder.encodePathParam(backend), UrlEncoder.encodePathParam(backupId)); + + List queryParams = new ArrayList<>(); + if (this.bucket != null) { + queryParams.add(UrlEncoder.encodeQueryParam("bucket", this.bucket)); + } + if (this.backupPath != null) { + queryParams.add(UrlEncoder.encodeQueryParam("path", this.backupPath)); + } + + if (!queryParams.isEmpty()) { + path += "?" + String.join("&", queryParams); + } return sendGetRequest(path, BackupRestoreStatusResponse.class, callback); } } 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 f4015786..5882b3d7 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 @@ -237,5 +237,9 @@ private static class BackupRestore { public static class BackupRestoreConfig { @SerializedName("CPUPercentage") Integer cpuPercentage; + @SerializedName("Bucket") + String bucket; + @SerializedName("Path") + String path; } } diff --git a/src/main/java/io/weaviate/client/v1/backup/api/BackupCanceler.java b/src/main/java/io/weaviate/client/v1/backup/api/BackupCanceler.java index f8812bc8..15d8890a 100644 --- a/src/main/java/io/weaviate/client/v1/backup/api/BackupCanceler.java +++ b/src/main/java/io/weaviate/client/v1/backup/api/BackupCanceler.java @@ -1,11 +1,15 @@ package io.weaviate.client.v1.backup.api; +import java.util.ArrayList; +import java.util.List; + 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.base.util.UrlEncoder; /** * BackupCanceler can cancel an in-progress backup by ID. @@ -16,6 +20,8 @@ public class BackupCanceler extends BaseClient implements ClientResult { private String backend; private String backupId; + private String bucket; + private String backupPath; public BackupCanceler(HttpClient client, Config config) { super(client, config); @@ -26,6 +32,16 @@ public BackupCanceler withBackend(String backend) { return this; } + public BackupCanceler withBucket(String bucket) { + this.bucket = bucket; + return this; + } + + public BackupCanceler withPath(String path) { + this.backupPath = path; + return this; + } + public BackupCanceler withBackupId(String backupId) { this.backupId = backupId; return this; @@ -38,7 +54,20 @@ public Result run() { } private String path() { - return String.format("/backups/%s/%s", backend, backupId); + String path = String.format("/backups/%s/%s", backend, backupId); + + List queryParams = new ArrayList<>(); + if (this.bucket != null) { + queryParams.add(UrlEncoder.encodeQueryParam("bucket", this.bucket)); + } + if (this.backupPath != null) { + queryParams.add(UrlEncoder.encodeQueryParam("path", this.backupPath)); + } + + if (!queryParams.isEmpty()) { + path += "?" + String.join("&", queryParams); + } + return path; } } diff --git a/src/main/java/io/weaviate/client/v1/backup/api/BackupCreateStatusGetter.java b/src/main/java/io/weaviate/client/v1/backup/api/BackupCreateStatusGetter.java index dafb25c9..b8d59dd8 100644 --- a/src/main/java/io/weaviate/client/v1/backup/api/BackupCreateStatusGetter.java +++ b/src/main/java/io/weaviate/client/v1/backup/api/BackupCreateStatusGetter.java @@ -1,17 +1,23 @@ package io.weaviate.client.v1.backup.api; -import io.weaviate.client.v1.backup.model.BackupCreateStatusResponse; +import java.util.ArrayList; +import java.util.List; + 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.base.util.UrlEncoder; +import io.weaviate.client.v1.backup.model.BackupCreateStatusResponse; public class BackupCreateStatusGetter extends BaseClient implements ClientResult { private String backend; private String backupId; + private String bucket; + private String backupPath; public BackupCreateStatusGetter(HttpClient httpClient, Config config) { super(httpClient, config); @@ -27,6 +33,16 @@ public BackupCreateStatusGetter withBackupId(String backupId) { return this; } + public BackupCreateStatusGetter withBucket(String bucket) { + this.bucket = bucket; + return this; + } + + public BackupCreateStatusGetter withPath(String path) { + this.backupPath = path; + return this; + } + @Override public Result run() { return new Result<>(statusCreate()); @@ -37,6 +53,19 @@ Response statusCreate() { } private String path() { - return String.format("/backups/%s/%s", backend, backupId); + String path = String.format("/backups/%s/%s", backend, backupId); + + List queryParams = new ArrayList<>(); + if (this.bucket != null) { + queryParams.add(UrlEncoder.encodeQueryParam("bucket", this.bucket)); + } + if (this.backupPath != null) { + queryParams.add(UrlEncoder.encodeQueryParam("path", this.backupPath)); + } + + if (!queryParams.isEmpty()) { + path += "?" + String.join("&", queryParams); + } + return path; } } diff --git a/src/main/java/io/weaviate/client/v1/backup/api/BackupCreator.java b/src/main/java/io/weaviate/client/v1/backup/api/BackupCreator.java index f02c7edc..61fe9f4d 100644 --- a/src/main/java/io/weaviate/client/v1/backup/api/BackupCreator.java +++ b/src/main/java/io/weaviate/client/v1/backup/api/BackupCreator.java @@ -150,6 +150,10 @@ public static class BackupCreateConfig { Integer chunkSize; @SerializedName("CompressionLevel") String compressionLevel; + @SerializedName("Bucket") + String bucket; + @SerializedName("Path") + String path; } public interface BackupCompression { diff --git a/src/main/java/io/weaviate/client/v1/backup/api/BackupRestoreStatusGetter.java b/src/main/java/io/weaviate/client/v1/backup/api/BackupRestoreStatusGetter.java index 06ffa72a..3807d4a4 100644 --- a/src/main/java/io/weaviate/client/v1/backup/api/BackupRestoreStatusGetter.java +++ b/src/main/java/io/weaviate/client/v1/backup/api/BackupRestoreStatusGetter.java @@ -1,17 +1,23 @@ package io.weaviate.client.v1.backup.api; -import io.weaviate.client.v1.backup.model.BackupRestoreStatusResponse; +import java.util.ArrayList; +import java.util.List; + 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.base.util.UrlEncoder; +import io.weaviate.client.v1.backup.model.BackupRestoreStatusResponse; public class BackupRestoreStatusGetter extends BaseClient implements ClientResult { private String backend; private String backupId; + private String bucket; + private String backupPath; public BackupRestoreStatusGetter(HttpClient httpClient, Config config) { super(httpClient, config); @@ -27,6 +33,16 @@ public BackupRestoreStatusGetter withBackupId(String backupId) { return this; } + public BackupRestoreStatusGetter withBucket(String bucket) { + this.bucket = bucket; + return this; + } + + public BackupRestoreStatusGetter withPath(String path) { + this.backupPath = path; + return this; + } + @Override public Result run() { return new Result<>(statusRestore()); @@ -37,6 +53,19 @@ Response statusRestore() { } private String path() { - return String.format("/backups/%s/%s/restore", backend, backupId); + String path = String.format("/backups/%s/%s/restore", backend, backupId); + + List queryParams = new ArrayList<>(); + if (this.bucket != null) { + queryParams.add(UrlEncoder.encodeQueryParam("bucket", this.bucket)); + } + if (this.backupPath != null) { + queryParams.add(UrlEncoder.encodeQueryParam("path", this.backupPath)); + } + + if (!queryParams.isEmpty()) { + path += "?" + String.join("&", queryParams); + } + return path; } } 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 77c7ce3f..849ad458 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 @@ -150,5 +150,9 @@ private static class BackupRestore { public static class BackupRestoreConfig { @SerializedName("CPUPercentage") Integer cpuPercentage; + @SerializedName("Bucket") + String bucket; + @SerializedName("Path") + String path; } } diff --git a/src/test/java/io/weaviate/integration/client/WeaviateVersion.java b/src/test/java/io/weaviate/integration/client/WeaviateVersion.java index 72946175..dc37e52f 100644 --- a/src/test/java/io/weaviate/integration/client/WeaviateVersion.java +++ b/src/test/java/io/weaviate/integration/client/WeaviateVersion.java @@ -3,12 +3,12 @@ public class WeaviateVersion { // docker image version - public static final String WEAVIATE_IMAGE = "1.27.0"; + public static final String WEAVIATE_IMAGE = "1.27.7-8f0e033"; // to be set according to weaviate docker image - public static final String EXPECTED_WEAVIATE_VERSION = "1.27.0"; + public static final String EXPECTED_WEAVIATE_VERSION = "1.27.7"; // to be set according to weaviate docker image - public static final String EXPECTED_WEAVIATE_GIT_HASH = "6c571ff"; + public static final String EXPECTED_WEAVIATE_GIT_HASH = "8f0e033"; 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 38b69828..a03baecf 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 @@ -133,6 +133,47 @@ public void shouldCreateAndRestoreBackupWithoutWaiting() throws InterruptedExcep } } + @Test + public void shouldCreateAndRestoreBackupWithDynamicLocation() throws InterruptedException { + String bucket = "test-bucket"; // irrelevant for "filesystem" backend, here only to illustrate + String path = "/custom/backup/location"; + + 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()) + ); + Supplier> supplierCreateStatusResult = createSupplierCreateStatus( + 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()) + ); + Supplier> supplierRestoreStatusResult = createSupplierRestoreStatus( + asyncClient, restoreStatusGetter -> restoreStatusGetter + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withBucket(bucket) + .withPath(path) + ); + + BackupTestSuite.testCreateWithDynamicLocation(supplierCreateResult, supplierCreateStatusResult, + supplierRestoreResult, supplierRestoreStatusResult, + createSupplierDeletePizza(), createSupplierGQLOfClass(), backupId, bucket, path); + } + } + @Test public void shouldCreateAndRestore1Of2Classes() { try (WeaviateAsyncClient asyncClient = client.async()) { 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 086591b1..afdb0be0 100644 --- a/src/test/java/io/weaviate/integration/client/backup/ClientBackupTest.java +++ b/src/test/java/io/weaviate/integration/client/backup/ClientBackupTest.java @@ -3,7 +3,6 @@ import io.weaviate.client.Config; import io.weaviate.client.WeaviateClient; import io.weaviate.client.base.Result; -import io.weaviate.client.v1.async.WeaviateAsyncClient; import io.weaviate.client.v1.backup.api.BackupCreator; import io.weaviate.client.v1.backup.api.BackupRestorer; import io.weaviate.client.v1.backup.model.BackupCreateResponse; @@ -118,6 +117,43 @@ public void shouldCreateAndRestoreBackupWithoutWaiting() throws InterruptedExcep supplierRestoreResult, supplierRestoreStatusResult, supplierDeleteClass, createSupplierGQLOfClass(), backupId); } + @Test + public void shouldCreateAndRestoreBackupWithDynamicLocation() throws InterruptedException { + String bucket = "test-bucket"; // irrelevant for "filesystem" backend, here only to illustrate + 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(); + Supplier> supplierCreateStatusResult = () -> client.backup().createStatusGetter() + .withBackend(BackupTestSuite.BACKEND) + .withBackupId(backupId) + .withBucket(bucket) + .withPath(path) + .run(); + Supplier> supplierDeleteClass = () -> client.schema().classDeleter() + .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(); + + BackupTestSuite.testCreateWithDynamicLocation(supplierCreateResult, supplierCreateStatusResult, + supplierRestoreResult, supplierRestoreStatusResult, supplierDeleteClass, createSupplierGQLOfClass(), backupId, bucket, path); + } + @Test public void shouldCreateAndRestore1Of2Classes() { Supplier> supplierCreateResult = () -> client.backup().creator() 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 752279fd..a8257f16 100644 --- a/src/test/java/io/weaviate/integration/tests/backup/BackupTestSuite.java +++ b/src/test/java/io/weaviate/integration/tests/backup/BackupTestSuite.java @@ -6,6 +6,7 @@ import static org.assertj.core.api.InstanceOfAssertFactories.CHAR_SEQUENCE; import static org.junit.Assume.assumeTrue; +import java.nio.file.Paths; import java.util.List; import java.util.Map; import java.util.concurrent.Callable; @@ -102,6 +103,73 @@ public static void testCreateAndRestoreBackupWithWaiting(Supplier> supplierCreate, + 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"); + + // Wait until created + Result createStatusResult; + while (true) { + createStatusResult = supplierCreateStatus.get(); + + assertThat(createStatusResult.getError()).as("check backup creation status").isNull(); + assertThat(createStatusResult.getResult()).isNotNull() + .returns(backupId, BackupCreateStatusResponse::getId) + .returns(wantFullPath, BackupCreateStatusResponse::getPath) + .extracting(BackupCreateStatusResponse::getStatus) + .isIn(CreateStatus.STARTED, CreateStatus.TRANSFERRING, CreateStatus.TRANSFERRED, CreateStatus.SUCCESS); + + if (CreateStatus.SUCCESS.equals(createStatusResult.getResult().getStatus())) { + break; + } + Thread.sleep(100); + } + + // Delete all data to then restore it from backup. + Result delete = supplierDeleteClass.get(); + assertThat(delete.getError()).as("drop Pizza collection").isNull(); + assertThat(delete.getResult()).isTrue(); + + + Result restoreResult = supplierRestore.get(); + assertThat(restoreResult.getError()).as("restore from backup").isNull(); + assertThat(restoreResult.getResult()).isNotNull() + .returns(backupId, BackupRestoreResponse::getId) + .returns(wantFullPath, BackupRestoreResponse::getPath); + + // Wait until restored + Result restoreStatusResult; + while (true) { + restoreStatusResult = supplierRestoreStatus.get(); + + assertThat(restoreStatusResult.getError()).as("get restore status").isNull(); + assertThat(restoreStatusResult.getResult()).isNotNull() + .returns(backupId, BackupRestoreStatusResponse::getId) + .returns(wantFullPath, BackupRestoreStatusResponse::getPath) + .extracting(BackupRestoreStatusResponse::getStatus) + .isIn(RestoreStatus.STARTED, RestoreStatus.TRANSFERRING, RestoreStatus.TRANSFERRED, RestoreStatus.SUCCESS); + + if (RestoreStatus.SUCCESS.equals(restoreStatusResult.getResult().getStatus())) { + break; + } + Thread.sleep(100); + } + + assertThatAllPizzasExist(supplierGQLOfClass); + } + public static void testCreateAndRestoreBackupWithoutWaiting(Supplier> supplierCreate, Supplier> supplierCreateStatus, Supplier> supplierRestore,