use of com.google.cloud.spanner.Backup in project java-spanner by googleapis.
the class ITBackupTest method test03_Delete.
@Test
public void test03_Delete() throws InterruptedException {
Assert.assertFalse("No backups created", backups.isEmpty());
String backupId = backups.get(0);
waitForDbOperations(backupId);
// Get the backup.
logger.info(String.format("Fetching backup %s", backupId));
Backup backup = instance.getBackup(backupId);
// Delete it.
logger.info(String.format("Deleting backup %s", backupId));
backup.delete();
// Try to get it again. This should cause a NOT_FOUND error.
logger.info(String.format("Fetching non-existent backup %s", backupId));
SpannerException exception = assertThrows(SpannerException.class, () -> instance.getBackup(backupId));
assertEquals(ErrorCode.NOT_FOUND, exception.getErrorCode());
// Try to delete the non-existent backup. This should be a no-op.
logger.info(String.format("Deleting non-existent backup %s", backupId));
backup.delete();
logger.info("Finished delete tests");
}
use of com.google.cloud.spanner.Backup in project java-spanner by googleapis.
the class ITBackupTest method testPagination.
private void testPagination() {
logger.info("Listing backups using pagination");
// First get all current backups without using pagination so we can compare that list with
// the same list when pagination fails.
List<Backup> initialBackups = Lists.newArrayList(dbAdminClient.listBackups(instanceId).iterateAll());
int numBackups = 0;
logger.info("Fetching first page");
Page<Backup> page = dbAdminClient.listBackups(instanceId, Options.pageSize(1));
assertEquals(1, Iterables.size(page.getValues()));
numBackups++;
assertTrue(page.hasNextPage());
Set<String> seenPageTokens = new HashSet<>();
seenPageTokens.add("");
while (page.hasNextPage()) {
logger.info(String.format("Fetching page %d with page token %s", numBackups + 1, page.getNextPageToken()));
// The backend should not return the same page token twice.
if (seenPageTokens.contains(page.getNextPageToken())) {
// This should not happen, so to try to figure out why we list all the backups here to see
// if there's anything that we can figure out from the list of backups now compared with
// the initial list (for example that a new backup has been added while we were iterating).
logger.info("Pagination of backups failed. Initial list of backups was:");
for (Backup backup : initialBackups) {
logger.info(backup.getId().toString());
}
logger.info("Current list of backups is:");
List<Backup> currentBackups = Lists.newArrayList(dbAdminClient.listBackups(instanceId).iterateAll());
for (Backup backup : currentBackups) {
logger.info(backup.getId().toString());
}
}
assertFalse(Iterables.contains(seenPageTokens, page.getNextPageToken()));
seenPageTokens.add(page.getNextPageToken());
page = dbAdminClient.listBackups(instanceId, Options.pageToken(page.getNextPageToken()), Options.pageSize(1));
assertEquals(1, Iterables.size(page.getValues()));
numBackups++;
}
assertTrue(numBackups >= 1);
}
use of com.google.cloud.spanner.Backup 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.cloud.spanner.Backup in project java-spanner by googleapis.
the class SpannerSample method updateBackup.
// [END spanner_restore_backup]
// [START spanner_update_backup]
static void updateBackup(DatabaseAdminClient dbAdminClient, BackupId backupId) {
// Get current backup metadata.
Backup backup = dbAdminClient.newBackupBuilder(backupId).build().reload();
// Add 30 days to the expire time.
// Expire time must be within 366 days of the create time of the backup.
Timestamp expireTime = Timestamp.ofTimeMicroseconds(TimeUnit.SECONDS.toMicros(backup.getExpireTime().getSeconds()) + TimeUnit.NANOSECONDS.toMicros(backup.getExpireTime().getNanos()) + TimeUnit.DAYS.toMicros(30L));
System.out.println(String.format("Updating expire time of backup [%s] to %s...", backupId.toString(), LocalDateTime.ofEpochSecond(expireTime.getSeconds(), expireTime.getNanos(), OffsetDateTime.now().getOffset()).toString()));
// Update expire time.
backup = backup.toBuilder().setExpireTime(expireTime).build();
backup.updateExpireTime();
System.out.println("Updated backup [" + backupId + "]");
}
use of com.google.cloud.spanner.Backup in project java-spanner by googleapis.
the class SpannerSample method deleteBackup.
// [END spanner_update_backup]
// [START spanner_delete_backup]
static void deleteBackup(DatabaseAdminClient dbAdminClient, BackupId backupId) {
Backup backup = dbAdminClient.newBackupBuilder(backupId).build();
// Delete the backup.
System.out.println("Deleting backup [" + backupId + "]...");
backup.delete();
// Verify that the backup is deleted.
if (backup.exists()) {
System.out.println("Delete backup [" + backupId + "] failed");
throw new RuntimeException("Delete backup [" + backupId + "] failed");
} else {
System.out.println("Deleted backup [" + backupId + "]");
}
}
Aggregations