use of com.google.spanner.admin.database.v1.Database in project java-spanner by googleapis.
the class ITBackupTest method test01_Backups.
@Test
public void test01_Backups() throws InterruptedException, ExecutionException, TimeoutException {
final String databaseId = testHelper.getUniqueDatabaseId() + "_db1";
final Database sourceDatabase = dbAdminClient.newDatabaseBuilder(DatabaseId.of(projectId, instanceId, databaseId)).setEncryptionConfig(EncryptionConfigs.customerManagedEncryption(keyName)).build();
logger.info(String.format("Creating test database %s", databaseId));
OperationFuture<Database, CreateDatabaseMetadata> createDatabaseOperation = dbAdminClient.createDatabase(sourceDatabase, Collections.singletonList("CREATE TABLE FOO (ID INT64, NAME STRING(100)) PRIMARY KEY (ID)"));
// Make sure the database has been created before we try to create a backup.
Database database = createDatabaseOperation.get(DATABASE_TIMEOUT_MINUTES, TimeUnit.MINUTES);
databases.add(database.getId().getDatabase());
// Insert some data to make sure the backup will have a size>0.
DatabaseClient client = testHelper.getDatabaseClient(database);
client.writeAtLeastOnce(Collections.singletonList(Mutation.newInsertOrUpdateBuilder("FOO").set("ID").to(1L).set("NAME").to("TEST").build()));
// Verifies that the database encryption has been properly set
testDatabaseEncryption(database, keyName);
// Verifies that the database dialect has been properly set
testDatabaseDialect(database, Dialect.GOOGLE_STANDARD_SQL);
// Create a backup of the database.
String backupId = testHelper.getUniqueBackupId() + "_bck1";
Timestamp expireTime = afterDays(7);
Timestamp versionTime = getCurrentTimestamp(client);
logger.info(String.format("Creating backup %s", backupId));
// This backup has the version time specified as the server's current timestamp
// This backup is encrypted with a customer managed key
// The expiry time is 7 days in the future.
final Backup backupToCreate = dbAdminClient.newBackupBuilder(BackupId.of(projectId, instanceId, backupId)).setDatabase(database.getId()).setExpireTime(expireTime).setVersionTime(versionTime).setExpireTime(expireTime).setEncryptionConfig(EncryptionConfigs.customerManagedEncryption(keyName)).build();
OperationFuture<Backup, CreateBackupMetadata> operation = dbAdminClient.createBackup(backupToCreate);
backups.add(backupId);
// Execute metadata tests as part of this integration test to reduce total execution time.
testMetadata(operation, backupId, database);
// Ensure that the backup has been created before we proceed.
logger.info("Waiting for backup operation to finish");
Backup backup = operation.get(BACKUP_TIMEOUT_MINUTES, TimeUnit.MINUTES);
// Verifies that backup version time is the specified one
testBackupVersionTime(backup, versionTime);
// Verifies that backup encryption has been properly set
testBackupEncryption(backup, keyName);
// Insert some more data into the database to get a timestamp from the server.
Timestamp commitTs = client.writeAtLeastOnce(Collections.singletonList(Mutation.newInsertOrUpdateBuilder("FOO").set("ID").to(2L).set("NAME").to("TEST2").build()));
// Test listing operations.
// List all backups.
logger.info("Listing all backups");
assertTrue(Iterables.contains(instance.listBackups().iterateAll(), backup));
// List all backups whose names contain 'bck1'.
logger.info("Listing backups with name bck1");
assertTrue(Iterables.elementsEqual(dbAdminClient.listBackups(instanceId, Options.filter(String.format("name:%s", backup.getId().getName()))).iterateAll(), Collections.singleton(backup)));
logger.info("Listing ready backups");
Iterable<Backup> readyBackups = dbAdminClient.listBackups(instanceId, Options.filter("state:READY")).iterateAll();
assertTrue(Iterables.contains(readyBackups, backup));
// List all backups for databases whose names contain 'db1'.
logger.info("Listing backups for database db1");
assertTrue(Iterables.elementsEqual(dbAdminClient.listBackups(instanceId, Options.filter(String.format("database:%s", database.getId().getName()))).iterateAll(), Collections.singleton(backup)));
// List all backups that were created before a certain time.
Timestamp ts = Timestamp.ofTimeSecondsAndNanos(commitTs.getSeconds(), 0);
logger.info(String.format("Listing backups created before %s", ts));
assertTrue(Iterables.contains(dbAdminClient.listBackups(instanceId, Options.filter(String.format("create_time<\"%s\"", ts))).iterateAll(), backup));
// List all backups with a size > 0.
logger.info("Listing backups with size>0");
assertTrue(Iterables.contains(dbAdminClient.listBackups(instanceId, Options.filter("size_bytes>0")).iterateAll(), backup));
// Test pagination.
testPagination();
logger.info("Finished listBackup tests");
// Execute other tests as part of this integration test to reduce total execution time.
testGetBackup(database, backupId, expireTime);
testUpdateBackup(backup);
testCreateInvalidExpirationDate(database);
testRestore(backup, versionTime, keyName);
testCancelBackupOperation(database);
// Finished all tests.
logger.info("Finished all backup tests");
}
use of com.google.spanner.admin.database.v1.Database in project java-spanner by googleapis.
the class ITBackupTest method testCreateInvalidExpirationDate.
private void testCreateInvalidExpirationDate(Database database) {
// This is not allowed, the expiration date must be at least 6 hours in the future.
Timestamp expireTime = daysAgo(1);
String backupId = testHelper.getUniqueBackupId();
logger.info(String.format("Creating backup %s with invalid expiration date", backupId));
OperationFuture<Backup, CreateBackupMetadata> op = dbAdminClient.createBackup(instanceId, backupId, database.getId().getDatabase(), expireTime);
backups.add(backupId);
ExecutionException executionException = assertThrows(ExecutionException.class, op::get);
Throwable cause = executionException.getCause();
assertEquals(SpannerException.class, cause.getClass());
SpannerException spannerException = (SpannerException) cause;
assertEquals(ErrorCode.INVALID_ARGUMENT, spannerException.getErrorCode());
}
use of com.google.spanner.admin.database.v1.Database in project java-spanner by googleapis.
the class ITBackupTest method testCancelBackupOperation.
private void testCancelBackupOperation(Database database) throws InterruptedException, ExecutionException {
Timestamp expireTime = afterDays(7);
String backupId = testHelper.getUniqueBackupId();
logger.info(String.format("Starting to create backup %s", backupId));
OperationFuture<Backup, CreateBackupMetadata> op = dbAdminClient.createBackup(instanceId, backupId, database.getId().getDatabase(), expireTime);
backups.add(backupId);
// Cancel the backup operation.
logger.info(String.format("Cancelling the creation of backup %s", backupId));
dbAdminClient.cancelOperation(op.getName());
logger.info("Fetching backup operations");
boolean operationFound = false;
for (Operation operation : dbAdminClient.listBackupOperations(instanceId, Options.filter(String.format("name:%s", op.getName()))).iterateAll()) {
assertEquals(Code.CANCELLED.value(), operation.getError().getCode());
operationFound = true;
}
assertTrue(operationFound);
logger.info("Finished cancel test");
}
use of com.google.spanner.admin.database.v1.Database in project java-spanner by googleapis.
the class ITBackupTest method testRestore.
private void testRestore(Backup backup, Timestamp versionTime, String expectedKey) throws InterruptedException, ExecutionException {
// Restore the backup to a new database.
String restoredDb = testHelper.getUniqueDatabaseId();
String restoreOperationName;
OperationFuture<Database, RestoreDatabaseMetadata> restoreOperation;
int attempts = 0;
while (true) {
try {
logger.info(String.format("Restoring backup %s to database %s", backup.getId().getBackup(), restoredDb));
final Restore restore = dbAdminClient.newRestoreBuilder(backup.getId(), DatabaseId.of(projectId, instanceId, restoredDb)).setEncryptionConfig(EncryptionConfigs.customerManagedEncryption(expectedKey)).build();
restoreOperation = dbAdminClient.restoreDatabase(restore);
restoreOperationName = restoreOperation.getName();
break;
} catch (ExecutionException e) {
if (e.getCause() instanceof FailedPreconditionException && e.getCause().getMessage().contains("Please retry the operation once the pending restores complete")) {
attempts++;
if (attempts == 10) {
logger.info("Restore operation failed 10 times because of other pending restores. Skipping restore test.");
return;
}
// wait and then retry.
logger.info(String.format("Restoring backup %s to database %s must wait because of other pending restore operation", backup.getId().getBackup(), restoredDb));
// noinspection BusyWait
Thread.sleep(60_000L);
} else {
throw e;
}
}
}
databases.add(restoredDb);
logger.info(String.format("Restore operation %s running", restoreOperationName));
RestoreDatabaseMetadata metadata = restoreOperation.getMetadata().get();
assertEquals(backup.getId().getName(), metadata.getBackupInfo().getBackup());
assertEquals(RestoreSourceType.BACKUP, metadata.getSourceType());
assertEquals(DatabaseId.of(testHelper.getInstanceId(), restoredDb).getName(), metadata.getName());
assertEquals(versionTime, Timestamp.fromProto(metadata.getBackupInfo().getVersionTime()));
// Ensure the operations show up in the right collections.
// TODO: Re-enable when it is clear why this fails on the CI environment.
// verifyRestoreOperations(backupOp.getName(), restoreOperationName);
// Wait until the restore operation has finished successfully.
Database database = restoreOperation.get();
assertEquals(restoredDb, database.getId().getDatabase());
// Reloads the database
final Database reloadedDatabase = database.reload();
assertNotNull(reloadedDatabase.getProto());
assertEquals(versionTime, Timestamp.fromProto(reloadedDatabase.getProto().getRestoreInfo().getBackupInfo().getVersionTime()));
testDatabaseEncryption(reloadedDatabase, expectedKey);
testDatabaseDialect(reloadedDatabase, Dialect.GOOGLE_STANDARD_SQL);
// Restoring the backup to an existing database should fail.
logger.info(String.format("Restoring backup %s to existing database %s", backup.getId().getBackup(), restoredDb));
ExecutionException executionException = assertThrows(ExecutionException.class, () -> backup.restore(DatabaseId.of(testHelper.getInstanceId(), restoredDb)).get());
assertEquals(SpannerException.class, executionException.getCause().getClass());
SpannerException spannerException = (SpannerException) executionException.getCause();
assertEquals(ErrorCode.ALREADY_EXISTS, spannerException.getErrorCode());
}
use of com.google.spanner.admin.database.v1.Database in project java-spanner by googleapis.
the class CreateDatabaseWithDefaultLeaderSample method createDatabaseWithDefaultLeader.
static void createDatabaseWithDefaultLeader(String projectId, String instanceId, String databaseId, String defaultLeader) {
try (Spanner spanner = SpannerOptions.newBuilder().setProjectId(projectId).build().getService()) {
final DatabaseAdminClient databaseAdminClient = spanner.getDatabaseAdminClient();
final OperationFuture<Database, CreateDatabaseMetadata> operation = databaseAdminClient.createDatabase(instanceId, databaseId, Arrays.asList("CREATE TABLE Singers (" + " SingerId INT64 NOT NULL," + " FirstName STRING(1024)," + " LastName STRING(1024)," + " SingerInfo BYTES(MAX)" + ") PRIMARY KEY (SingerId)", "CREATE TABLE Albums (" + " SingerId INT64 NOT NULL," + " AlbumId INT64 NOT NULL," + " AlbumTitle STRING(MAX)" + ") PRIMARY KEY (SingerId, AlbumId)," + " INTERLEAVE IN PARENT Singers ON DELETE CASCADE", "ALTER DATABASE " + "`" + databaseId + "`" + " SET OPTIONS ( default_leader = '" + defaultLeader + "' )"));
final Database database = operation.get();
System.out.println("Created database [" + database.getId() + "]");
System.out.println("\tDefault leader: " + database.getDefaultLeader());
} catch (ExecutionException e) {
// If the operation failed during execution, expose the cause.
throw (SpannerException) e.getCause();
} catch (InterruptedException e) {
// and the thread is interrupted, either before or during the activity.
throw SpannerExceptionFactory.propagateInterrupt(e);
}
}
Aggregations