use of com.google.spanner.admin.database.v1.RestoreDatabaseMetadata in project java-spanner by googleapis.
the class MockDatabaseAdminServiceImplTest method restoreDatabaseAlreadyExists.
@Test
public void restoreDatabaseAlreadyExists() throws InterruptedException, ExecutionException {
createTestDb();
createTestBackup();
RestoreDatabaseRequest request = RestoreDatabaseRequest.newBuilder().setBackup(TEST_BCK_NAME).setDatabaseId("test-db").setParent(TEST_PARENT).build();
OperationFuture<Database, RestoreDatabaseMetadata> op = client.restoreDatabaseOperationCallable().futureCall(request);
exception.expect(ApiExceptionMatcher.forCode(StatusCode.Code.ALREADY_EXISTS));
op.get();
}
use of com.google.spanner.admin.database.v1.RestoreDatabaseMetadata in project java-spanner by googleapis.
the class MockDatabaseAdminServiceImplTest method restoreDatabaseNotFound.
@Test
public void restoreDatabaseNotFound() throws InterruptedException, ExecutionException {
createTestDb();
RestoreDatabaseRequest request = RestoreDatabaseRequest.newBuilder().setBackup(TEST_BCK_NAME).setDatabaseId("restored-db").setParent(TEST_PARENT).build();
OperationFuture<Database, RestoreDatabaseMetadata> op = client.restoreDatabaseOperationCallable().futureCall(request);
exception.expect(ApiExceptionMatcher.forCode(StatusCode.Code.NOT_FOUND));
op.get();
}
use of com.google.spanner.admin.database.v1.RestoreDatabaseMetadata in project java-spanner by googleapis.
the class ITBackupTest method test02_RetryNonIdempotentRpcsReturningLongRunningOperations.
@Test
public void test02_RetryNonIdempotentRpcsReturningLongRunningOperations() throws Exception {
assumeFalse("Querying long-running operations is not supported on the emulator", isUsingEmulator());
// RPCs that return a long-running operation such as CreateDatabase, CreateBackup and
// RestoreDatabase are non-idempotent and can normally not be automatically retried in case of a
// transient failure. The client library will however automatically query the backend to check
// whether the corresponding operation was started or not, and if it was, it will pick up the
// existing operation. If no operation is found, a new RPC call will be executed to start the
// operation.
List<Database> databases = new ArrayList<>();
String initialDatabaseId;
Timestamp initialDbCreateTime;
// CreateDatabase
InjectErrorInterceptorProvider createDbInterceptor = new InjectErrorInterceptorProvider("CreateDatabase");
SpannerOptions options = testHelper.getOptions().toBuilder().setInterceptorProvider(createDbInterceptor).build();
try (Spanner spanner = options.getService()) {
initialDatabaseId = testHelper.getUniqueDatabaseId();
DatabaseAdminClient client = spanner.getDatabaseAdminClient();
OperationFuture<Database, CreateDatabaseMetadata> op = client.createDatabase(testHelper.getInstanceId().getInstance(), initialDatabaseId, Collections.emptyList());
databases.add(op.get(DATABASE_TIMEOUT_MINUTES, TimeUnit.MINUTES));
// Keep track of the original create time of this database, as we will drop this database
// later and create another one with the exact same name. That means that the ListOperations
// call will return at least two CreateDatabase operations. The retry logic should always
// pick the last one.
initialDbCreateTime = op.get(DATABASE_TIMEOUT_MINUTES, TimeUnit.MINUTES).getCreateTime();
// Assert that the CreateDatabase RPC was called only once, and that the operation tracking
// was resumed through a GetOperation call.
assertEquals(1, createDbInterceptor.methodCount.get());
assertTrue(createDbInterceptor.getOperationCount.get() >= 1);
}
// CreateBackup
InjectErrorInterceptorProvider createBackupInterceptor = new InjectErrorInterceptorProvider("CreateBackup");
options = testHelper.getOptions().toBuilder().setInterceptorProvider(createBackupInterceptor).build();
String backupId = String.format("test-bck-%08d", new Random().nextInt(100000000));
try (Spanner spanner = options.getService()) {
String databaseId = databases.get(0).getId().getDatabase();
DatabaseAdminClient client = spanner.getDatabaseAdminClient();
OperationFuture<Backup, CreateBackupMetadata> op = client.createBackup(testHelper.getInstanceId().getInstance(), backupId, databaseId, Timestamp.ofTimeSecondsAndNanos(Timestamp.now().getSeconds() + TimeUnit.SECONDS.convert(7L, TimeUnit.DAYS), 0));
Stopwatch watch = Stopwatch.createStarted();
while (createBackupInterceptor.methodCount.get() < 1 && createBackupInterceptor.getOperationCount.get() < 1 && watch.elapsed(TimeUnit.SECONDS) < 120) {
// noinspection BusyWait
Thread.sleep(5000L);
}
client.cancelOperation(op.getName());
// Assert that the CreateBackup RPC was called only once, and that the operation tracking
// was resumed through a GetOperation call.
assertEquals(1, createBackupInterceptor.methodCount.get());
assertTrue(createBackupInterceptor.getOperationCount.get() >= 1);
}
// RestoreBackup
if (!backups.isEmpty()) {
InjectErrorInterceptorProvider restoreBackupInterceptor = new InjectErrorInterceptorProvider("RestoreDatabase");
options = testHelper.getOptions().toBuilder().setInterceptorProvider(restoreBackupInterceptor).build();
try (Spanner spanner = options.getService()) {
String restoredDbId = testHelper.getUniqueDatabaseId();
DatabaseAdminClient client = spanner.getDatabaseAdminClient();
OperationFuture<Database, RestoreDatabaseMetadata> op = client.restoreDatabase(testHelper.getInstanceId().getInstance(), backups.get(0), testHelper.getInstanceId().getInstance(), restoredDbId);
Stopwatch watch = Stopwatch.createStarted();
while (restoreBackupInterceptor.methodCount.get() < 1 && restoreBackupInterceptor.getOperationCount.get() < 1 && watch.elapsed(TimeUnit.SECONDS) < 120) {
// noinspection BusyWait
Thread.sleep(5000L);
}
try {
client.cancelOperation(op.getName());
} catch (SpannerException | ExecutionException e) {
// Ignore, this can happen, as the restore operation sometimes fails to start if there
// is already a restore operation running on the instance.
}
// Assert that the RestoreDatabase RPC was called only once, and that the operation
// tracking was resumed through a GetOperation call.
assertEquals(1, restoreBackupInterceptor.methodCount.get());
assertTrue(restoreBackupInterceptor.getOperationCount.get() >= 1);
}
}
// Create another database with the exact same name as the first database.
createDbInterceptor = new InjectErrorInterceptorProvider("CreateDatabase");
options = testHelper.getOptions().toBuilder().setInterceptorProvider(createDbInterceptor).build();
try (Spanner spanner = options.getService()) {
DatabaseAdminClient client = spanner.getDatabaseAdminClient();
// First drop the initial database.
client.dropDatabase(testHelper.getInstanceId().getInstance(), initialDatabaseId);
// Now re-create a database with the exact same name.
OperationFuture<Database, CreateDatabaseMetadata> op = client.createDatabase(testHelper.getInstanceId().getInstance(), initialDatabaseId, Collections.emptyList());
// Check that the second database was created and has a greater creation time than the
// first.
Timestamp secondCreationTime = op.get(DATABASE_TIMEOUT_MINUTES, TimeUnit.MINUTES).getCreateTime();
// TODO: Change this to greaterThan when the create time of a database is reported back by
// the server.
assertTrue(secondCreationTime.compareTo(initialDbCreateTime) >= 0);
// Assert that the CreateDatabase RPC was called only once, and that the operation tracking
// was resumed through a GetOperation call.
assertEquals(1, createDbInterceptor.methodCount.get());
assertTrue(createDbInterceptor.getOperationCount.get() >= 1);
}
}
use of com.google.spanner.admin.database.v1.RestoreDatabaseMetadata in project java-spanner by googleapis.
the class SpannerSample method restoreBackup.
// [END spanner_list_backups]
// [START spanner_restore_backup]
static void restoreBackup(DatabaseAdminClient dbAdminClient, BackupId backupId, DatabaseId sourceDatabaseId, DatabaseId restoreToDatabase) {
Backup backup = dbAdminClient.newBackupBuilder(backupId).build();
// Initiate the request which returns an OperationFuture.
System.out.println(String.format("Restoring backup [%s] to database [%s]...", backup.getId().toString(), restoreToDatabase.toString()));
try {
OperationFuture<Database, RestoreDatabaseMetadata> op = backup.restore(restoreToDatabase);
// Wait until the database has been restored.
Database db = op.get();
// Refresh database metadata and get the restore info.
RestoreInfo restore = db.reload().getRestoreInfo();
Timestamp versionTime = Timestamp.fromProto(restore.getProto().getBackupInfo().getVersionTime());
System.out.println("Restored database [" + restore.getSourceDatabase().getName() + "] from [" + restore.getBackup().getName() + "] with version time [" + versionTime + "]");
} catch (ExecutionException e) {
throw SpannerExceptionFactory.newSpannerException(e.getCause());
} catch (InterruptedException e) {
throw SpannerExceptionFactory.propagateInterrupt(e);
}
}
use of com.google.spanner.admin.database.v1.RestoreDatabaseMetadata in project java-spanner by googleapis.
the class RestoreBackupWithEncryptionKey method restoreBackupWithEncryptionKey.
static Void restoreBackupWithEncryptionKey(DatabaseAdminClient adminClient, String projectId, String instanceId, String backupId, String restoreId, String kmsKeyName) {
final Restore restore = adminClient.newRestoreBuilder(BackupId.of(projectId, instanceId, backupId), DatabaseId.of(projectId, instanceId, restoreId)).setEncryptionConfig(EncryptionConfigs.customerManagedEncryption(kmsKeyName)).build();
final OperationFuture<Database, RestoreDatabaseMetadata> operation = adminClient.restoreDatabase(restore);
Database database;
try {
System.out.println("Waiting for operation to complete...");
database = operation.get();
} catch (ExecutionException e) {
// If the operation failed during execution, expose the cause.
throw SpannerExceptionFactory.asSpannerException(e.getCause());
} catch (InterruptedException e) {
// and the thread is interrupted, either before or during the activity.
throw SpannerExceptionFactory.propagateInterrupt(e);
}
System.out.printf("Database %s restored to %s from backup %s using encryption key %s%n", database.getRestoreInfo().getSourceDatabase(), database.getId(), database.getRestoreInfo().getBackup(), database.getEncryptionConfig().getKmsKeyName());
return null;
}
Aggregations