Search in sources :

Example 1 with Backup

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");
}
Also used : Backup(com.google.cloud.spanner.Backup) SpannerException(com.google.cloud.spanner.SpannerException) Test(org.junit.Test) SlowTest(com.google.cloud.spanner.SlowTest)

Example 2 with Backup

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);
}
Also used : Backup(com.google.cloud.spanner.Backup) HashSet(java.util.HashSet)

Example 3 with Backup

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);
    }
}
Also used : Backup(com.google.cloud.spanner.Backup) ArrayList(java.util.ArrayList) Stopwatch(com.google.common.base.Stopwatch) Timestamp(com.google.cloud.Timestamp) SpannerOptions(com.google.cloud.spanner.SpannerOptions) Random(java.util.Random) Database(com.google.cloud.spanner.Database) CreateBackupMetadata(com.google.spanner.admin.database.v1.CreateBackupMetadata) DatabaseAdminClient(com.google.cloud.spanner.DatabaseAdminClient) RestoreDatabaseMetadata(com.google.spanner.admin.database.v1.RestoreDatabaseMetadata) SpannerException(com.google.cloud.spanner.SpannerException) CreateDatabaseMetadata(com.google.spanner.admin.database.v1.CreateDatabaseMetadata) ExecutionException(java.util.concurrent.ExecutionException) Spanner(com.google.cloud.spanner.Spanner) Test(org.junit.Test) SlowTest(com.google.cloud.spanner.SlowTest)

Example 4 with Backup

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 + "]");
}
Also used : Backup(com.google.cloud.spanner.Backup) Timestamp(com.google.cloud.Timestamp)

Example 5 with Backup

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 + "]");
    }
}
Also used : Backup(com.google.cloud.spanner.Backup)

Aggregations

Backup (com.google.cloud.spanner.Backup)19 Timestamp (com.google.cloud.Timestamp)13 CreateBackupMetadata (com.google.spanner.admin.database.v1.CreateBackupMetadata)7 SpannerException (com.google.cloud.spanner.SpannerException)6 ExecutionException (java.util.concurrent.ExecutionException)6 Database (com.google.cloud.spanner.Database)5 SlowTest (com.google.cloud.spanner.SlowTest)5 Test (org.junit.Test)5 DatabaseId (com.google.cloud.spanner.DatabaseId)2 InstanceId (com.google.cloud.spanner.InstanceId)2 Operation (com.google.longrunning.Operation)2 CreateDatabaseMetadata (com.google.spanner.admin.database.v1.CreateDatabaseMetadata)2 RestoreDatabaseMetadata (com.google.spanner.admin.database.v1.RestoreDatabaseMetadata)2 OperationSnapshot (com.google.api.gax.longrunning.OperationSnapshot)1 DatabaseAdminClient (com.google.cloud.spanner.DatabaseAdminClient)1 DatabaseClient (com.google.cloud.spanner.DatabaseClient)1 Instance (com.google.cloud.spanner.Instance)1 RestoreInfo (com.google.cloud.spanner.RestoreInfo)1 Spanner (com.google.cloud.spanner.Spanner)1 SpannerOptions (com.google.cloud.spanner.SpannerOptions)1