use of com.google.spanner.admin.database.v1.RestoreDatabaseMetadata in project java-spanner by googleapis.
the class MockDatabaseAdminServiceImpl method restoreDatabase.
@Override
public void restoreDatabase(RestoreDatabaseRequest request, StreamObserver<Operation> responseObserver) {
requests.add(request);
try {
restoreDatabaseStartupExecutionTime.simulateExecutionTime(exceptions, false, freezeLock);
MockBackup bck = backups.get(request.getBackup());
if (bck != null) {
String name = String.format("%s/databases/%s", request.getParent(), request.getDatabaseId());
MockDatabase db = new MockDatabase(name, bck.ddl, RestoreInfo.newBuilder().setBackupInfo(bck.toBackupInfo()).setSourceType(RestoreSourceType.BACKUP).build());
if (databases.putIfAbsent(name, db) == null) {
bck.referencingDatabases.add(db.name);
Operation optimizeOperation = Operation.newBuilder().setDone(false).setName(operations.generateOperationName(name)).setMetadata(Any.pack(OptimizeRestoredDatabaseMetadata.newBuilder().setName(name).setProgress(OperationProgress.newBuilder().setStartTime(currentTime()).setProgressPercent(0).build()).build())).setResponse(Any.pack(db.toProto())).build();
RestoreDatabaseMetadata metadata = RestoreDatabaseMetadata.newBuilder().setBackupInfo(bck.toBackupInfo()).setName(name).setProgress(OperationProgress.newBuilder().setStartTime(currentTime()).setProgressPercent(0).build()).setOptimizeDatabaseOperationName(optimizeOperation.getName()).setSourceType(RestoreSourceType.BACKUP).build();
Operation operation = Operation.newBuilder().setMetadata(Any.pack(metadata)).setResponse(Any.pack(db.toProto())).setDone(false).setName(operations.generateOperationName(name)).build();
operations.addOperation(operation, new RestoreDatabaseCallable(operation.getName(), name));
operations.addOperation(optimizeOperation, new OptimizeDatabaseCallable(optimizeOperation.getName(), operation.getName(), name));
restoreDatabaseResponseExecutionTime.simulateExecutionTime(exceptions, false, freezeLock);
responseObserver.onNext(operation);
responseObserver.onCompleted();
} else {
responseObserver.onError(Status.ALREADY_EXISTS.asRuntimeException());
}
} else {
responseObserver.onError(Status.NOT_FOUND.asRuntimeException());
}
} catch (Throwable t) {
responseObserver.onError(t);
}
}
use of com.google.spanner.admin.database.v1.RestoreDatabaseMetadata in project java-spanner by googleapis.
the class MockDatabaseAdminServiceImpl method matchesFilter.
private boolean matchesFilter(Object obj, String filter) throws Exception {
if (!Strings.isNullOrEmpty(filter)) {
Set<String> matches = filterMatches.get(filter);
if (matches != null) {
String name = (String) obj.getClass().getMethod("getName").invoke(obj);
return matches.contains(name);
}
if (obj instanceof Operation) {
Operation operation = (Operation) obj;
Pattern pattern = Pattern.compile("(?:\\(metadata.@type:type.googleapis.com/(.*)\\)) AND (?:\\(metadata.(?:name|database):(.*)\\)|\\(name:(.*)/operations/\\))");
Matcher matcher = pattern.matcher(filter);
if (matcher.matches()) {
String type = matcher.group(1);
String objectName = matcher.group(2);
if (objectName == null) {
objectName = matcher.group(3);
}
Any anyMetadata = operation.getMetadata();
if (anyMetadata.getTypeUrl().endsWith(type)) {
if (type.equals(CreateBackupMetadata.getDescriptor().getFullName())) {
CreateBackupMetadata metadata = operation.getMetadata().unpack(CreateBackupMetadata.class);
return metadata.getName().equals(objectName);
} else if (type.equals(CreateDatabaseMetadata.getDescriptor().getFullName())) {
CreateDatabaseMetadata metadata = operation.getMetadata().unpack(CreateDatabaseMetadata.class);
return metadata.getDatabase().equals(objectName);
} else if (type.equals(RestoreDatabaseMetadata.getDescriptor().getFullName())) {
RestoreDatabaseMetadata metadata = operation.getMetadata().unpack(RestoreDatabaseMetadata.class);
return metadata.getName().equals(objectName);
}
}
}
}
return false;
}
return true;
}
use of com.google.spanner.admin.database.v1.RestoreDatabaseMetadata in project java-spanner by googleapis.
the class MockDatabaseAdminServiceImplTest method restoreDatabase.
@Test
public void restoreDatabase() throws InterruptedException, ExecutionException {
createTestDb();
createTestBackup();
RestoreDatabaseRequest request = RestoreDatabaseRequest.newBuilder().setBackup(TEST_BCK_NAME).setDatabaseId("restored-db").setParent(TEST_PARENT).build();
OperationFuture<Database, RestoreDatabaseMetadata> op = client.restoreDatabaseOperationCallable().futureCall(request);
Database restoredDb = op.get();
assertThat(restoredDb.getName()).isEqualTo(String.format("%s/databases/%s", TEST_PARENT, "restored-db"));
assertThat(restoredDb.getRestoreInfo().getBackupInfo().getBackup()).isEqualTo(TEST_BCK_NAME);
assertThat(restoredDb.getRestoreInfo().getBackupInfo().getSourceDatabase()).isEqualTo(TEST_DB_NAME);
}
use of com.google.spanner.admin.database.v1.RestoreDatabaseMetadata 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());
}
Aggregations